aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAmos <48657826+Mauler125@users.noreply.github.com>2022-03-02 23:44:27 +0100
committerAmos <48657826+Mauler125@users.noreply.github.com>2022-03-02 23:44:27 +0100
commit5e3b22e336217dd2b0aec771ce80b69caa07d571 (patch)
treeac7b21e816b818e1dcdc724fa56d3fa1f4cfd0b1
parent62e137b32ad7c601b2db37e69b9f435a7dbc730d (diff)
downloadNorthstarLauncher-5e3b22e336217dd2b0aec771ce80b69caa07d571.tar.gz
NorthstarLauncher-5e3b22e336217dd2b0aec771ce80b69caa07d571.zip
Add 'protobuf' library to project
Library is configured to compile as 'lite'.
-rw-r--r--NorthstarDedicatedTest/include/.clang-format4
-rw-r--r--NorthstarDedicatedTest/include/protobuf/any.cc83
-rw-r--r--NorthstarDedicatedTest/include/protobuf/any.h156
-rw-r--r--NorthstarDedicatedTest/include/protobuf/any.pb.cc352
-rw-r--r--NorthstarDedicatedTest/include/protobuf/any.pb.h391
-rw-r--r--NorthstarDedicatedTest/include/protobuf/any.proto158
-rw-r--r--NorthstarDedicatedTest/include/protobuf/any_lite.cc99
-rw-r--r--NorthstarDedicatedTest/include/protobuf/any_test.cc184
-rw-r--r--NorthstarDedicatedTest/include/protobuf/any_test.proto44
-rw-r--r--NorthstarDedicatedTest/include/protobuf/api.pb.cc1291
-rw-r--r--NorthstarDedicatedTest/include/protobuf/api.pb.h1448
-rw-r--r--NorthstarDedicatedTest/include/protobuf/api.proto208
-rw-r--r--NorthstarDedicatedTest/include/protobuf/arena.cc511
-rw-r--r--NorthstarDedicatedTest/include/protobuf/arena.h821
-rw-r--r--NorthstarDedicatedTest/include/protobuf/arena_impl.h562
-rw-r--r--NorthstarDedicatedTest/include/protobuf/arena_test_util.cc50
-rw-r--r--NorthstarDedicatedTest/include/protobuf/arena_test_util.h126
-rw-r--r--NorthstarDedicatedTest/include/protobuf/arena_unittest.cc1557
-rw-r--r--NorthstarDedicatedTest/include/protobuf/arenastring.cc286
-rw-r--r--NorthstarDedicatedTest/include/protobuf/arenastring.h420
-rw-r--r--NorthstarDedicatedTest/include/protobuf/arenastring_unittest.cc157
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/annotation_test_util.cc168
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/annotation_test_util.h115
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/code_generator.cc137
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/code_generator.h206
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/command_line_interface.cc2616
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/command_line_interface.h462
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/command_line_interface_unittest.cc2760
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc195
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_enum.cc438
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_enum.h105
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_enum_field.cc406
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_enum_field.h115
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_extension.cc189
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_extension.h95
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_field.cc391
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_field.h242
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_file.cc1419
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_file.h208
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_generator.cc271
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_generator.h106
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_helpers.cc1497
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_helpers.h971
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_map_field.cc334
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_map_field.h78
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_message.cc4584
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_message.h231
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_message_field.cc892
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_message_field.h144
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_message_layout_helper.h64
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_move_unittest.cc169
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_names.h96
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_options.h95
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_padding_optimizer.cc228
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_padding_optimizer.h65
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_parse_function_generator.cc1303
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_parse_function_generator.h199
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_plugin_unittest.cc236
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_primitive_field.cc505
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_primitive_field.h116
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_service.cc327
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_service.h122
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_string_field.cc915
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_string_field.h127
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_test_bad_identifiers.proto184
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_test_large_enum_value.proto43
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_unittest.cc134
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_unittest.h51
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_unittest.inc2234
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/cpp/metadata_test.cc161
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_bootstrap_unittest.cc194
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_doc_comment.cc116
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_doc_comment.h51
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_enum.cc99
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_enum.h66
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_enum_field.cc135
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_enum_field.h83
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_field_base.cc459
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_field_base.h111
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_generator.cc112
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_generator.h70
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_generator_unittest.cc70
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_helpers.cc592
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_helpers.h195
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_map_field.cc152
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_map_field.h75
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_message.cc779
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_message.h94
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_message_field.cc293
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_message_field.h93
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_names.h109
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_options.h81
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_primitive_field.cc349
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_primitive_field.h97
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_reflection_class.cc330
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_reflection_class.h75
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_repeated_enum_field.cc148
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_repeated_enum_field.h79
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_repeated_message_field.cc174
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_repeated_message_field.h79
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_repeated_primitive_field.cc145
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_repeated_primitive_field.h75
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_source_generator_base.cc75
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_source_generator_base.h71
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_wrapper_field.cc308
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_wrapper_field.h99
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/importer.cc524
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/importer.h336
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/importer_unittest.cc548
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/java/java_context.cc202
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/java/java_context.h113
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/java/java_doc_comment.cc435
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/java/java_doc_comment.h101
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/java/java_doc_comment_unittest.cc67
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/java/java_enum.cc391
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/java/java_enum.h100
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/java/java_enum_field.cc1176
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/java/java_enum_field.h161
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/java/java_enum_field_lite.cc918
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/java/java_enum_field_lite.h140
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/java/java_enum_lite.cc235
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/java/java_enum_lite.h98
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/java/java_extension.cc172
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/java/java_extension.h115
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/java/java_extension_lite.cc115
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/java/java_extension_lite.h75
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/java/java_field.cc312
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/java/java_field.h191
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/java/java_file.cc734
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/java/java_file.h125
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/java/java_generator.cc211
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/java/java_generator.h76
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/java/java_generator_factory.cc86
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/java/java_generator_factory.h103
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/java/java_helpers.cc1100
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/java/java_helpers.h459
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/java/java_kotlin_generator.cc162
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/java/java_kotlin_generator.h72
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/java/java_map_field.cc876
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/java/java_map_field.h82
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/java/java_map_field_lite.cc909
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/java/java_map_field_lite.h74
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/java/java_message.cc1729
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/java/java_message.h153
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/java/java_message_builder.cc712
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/java/java_message_builder.h89
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/java/java_message_builder_lite.cc151
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/java/java_message_builder_lite.h86
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/java/java_message_field.cc1494
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/java/java_message_field.h179
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/java/java_message_field_lite.cc884
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/java/java_message_field_lite.h140
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/java/java_message_lite.cc977
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/java/java_message_lite.h86
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/java/java_name_resolver.cc380
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/java/java_name_resolver.h153
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/java/java_names.h100
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/java/java_options.h73
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/java/java_plugin_unittest.cc119
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/java/java_primitive_field.cc1111
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/java/java_primitive_field.h162
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/java/java_primitive_field_lite.cc779
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/java/java_primitive_field_lite.h141
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/java/java_service.cc474
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/java/java_service.h139
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/java/java_shared_code_generator.cc198
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/java/java_shared_code_generator.h90
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/java/java_string_field.cc1190
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/java/java_string_field.h160
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/java/java_string_field_lite.cc864
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/java/java_string_field_lite.h139
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/js/js_generator.cc3941
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/js/js_generator.h336
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/js/well_known_types_embed.cc270
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/js/well_known_types_embed.h43
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/main.cc113
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/mock_code_generator.cc384
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/mock_code_generator.h136
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_enum.cc260
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_enum.h71
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_enum_field.cc149
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_enum_field.h80
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_extension.cc156
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_extension.h67
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_field.cc475
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_field.h194
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_file.cc610
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_file.h82
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_generator.cc276
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_generator.h79
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_helpers.cc1960
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_helpers.h347
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_helpers_unittest.cc385
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_map_field.cc189
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_map_field.h71
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_message.cc636
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_message.h99
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_message_field.cc107
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_message_field.h87
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_nsobject_methods.h197
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_oneof.cc140
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_oneof.h76
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_primitive_field.cc190
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_primitive_field.h95
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/package_info.h63
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/parser.cc2445
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/parser.h603
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/parser_unittest.cc3681
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/php/php_generator.cc2325
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/php/php_generator.h92
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/plugin.cc200
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/plugin.h95
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/plugin.pb.cc1584
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/plugin.pb.h1909
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/plugin.proto183
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/python/python_generator.cc1577
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/python/python_generator.h193
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/python/python_plugin_unittest.cc161
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generated_code.proto70
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generated_code_pb.rb79
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generated_code_proto2.proto71
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generated_code_proto2_import.proto5
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generated_code_proto2_pb.rb80
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generated_pkg_explicit.proto9
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generated_pkg_explicit_legacy.proto9
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generated_pkg_explicit_legacy_pb.rb20
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generated_pkg_explicit_pb.rb20
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generated_pkg_implicit.proto7
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generated_pkg_implicit_pb.rb20
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generator.cc575
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generator.h67
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generator_unittest.cc145
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/scc.h164
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/subprocess.cc475
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/subprocess.h113
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/test_plugin.cc61
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/zip_output_unittest.sh100
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/zip_writer.cc195
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/zip_writer.h65
-rw-r--r--NorthstarDedicatedTest/include/protobuf/descriptor.cc8025
-rw-r--r--NorthstarDedicatedTest/include/protobuf/descriptor.h2417
-rw-r--r--NorthstarDedicatedTest/include/protobuf/descriptor.pb.cc11125
-rw-r--r--NorthstarDedicatedTest/include/protobuf/descriptor.pb.h14766
-rw-r--r--NorthstarDedicatedTest/include/protobuf/descriptor.proto911
-rw-r--r--NorthstarDedicatedTest/include/protobuf/descriptor_database.cc1031
-rw-r--r--NorthstarDedicatedTest/include/protobuf/descriptor_database.h391
-rw-r--r--NorthstarDedicatedTest/include/protobuf/descriptor_database_unittest.cc805
-rw-r--r--NorthstarDedicatedTest/include/protobuf/descriptor_unittest.cc8336
-rw-r--r--NorthstarDedicatedTest/include/protobuf/drop_unknown_fields_test.cc83
-rw-r--r--NorthstarDedicatedTest/include/protobuf/duration.pb.cc300
-rw-r--r--NorthstarDedicatedTest/include/protobuf/duration.pb.h285
-rw-r--r--NorthstarDedicatedTest/include/protobuf/duration.proto116
-rw-r--r--NorthstarDedicatedTest/include/protobuf/dynamic_message.cc859
-rw-r--r--NorthstarDedicatedTest/include/protobuf/dynamic_message.h225
-rw-r--r--NorthstarDedicatedTest/include/protobuf/dynamic_message_unittest.cc327
-rw-r--r--NorthstarDedicatedTest/include/protobuf/empty.pb.cc122
-rw-r--r--NorthstarDedicatedTest/include/protobuf/empty.pb.h207
-rw-r--r--NorthstarDedicatedTest/include/protobuf/empty.proto52
-rw-r--r--NorthstarDedicatedTest/include/protobuf/explicitly_constructed.h91
-rw-r--r--NorthstarDedicatedTest/include/protobuf/extension_set.cc2255
-rw-r--r--NorthstarDedicatedTest/include/protobuf/extension_set.h1560
-rw-r--r--NorthstarDedicatedTest/include/protobuf/extension_set_heavy.cc546
-rw-r--r--NorthstarDedicatedTest/include/protobuf/extension_set_inl.h276
-rw-r--r--NorthstarDedicatedTest/include/protobuf/extension_set_unittest.cc1338
-rw-r--r--NorthstarDedicatedTest/include/protobuf/field_access_listener.h172
-rw-r--r--NorthstarDedicatedTest/include/protobuf/field_mask.pb.cc276
-rw-r--r--NorthstarDedicatedTest/include/protobuf/field_mask.pb.h324
-rw-r--r--NorthstarDedicatedTest/include/protobuf/field_mask.proto245
-rw-r--r--NorthstarDedicatedTest/include/protobuf/generated_enum_reflection.h98
-rw-r--r--NorthstarDedicatedTest/include/protobuf/generated_enum_util.cc95
-rw-r--r--NorthstarDedicatedTest/include/protobuf/generated_enum_util.h83
-rw-r--r--NorthstarDedicatedTest/include/protobuf/generated_message_bases.cc125
-rw-r--r--NorthstarDedicatedTest/include/protobuf/generated_message_bases.h87
-rw-r--r--NorthstarDedicatedTest/include/protobuf/generated_message_reflection.cc3041
-rw-r--r--NorthstarDedicatedTest/include/protobuf/generated_message_reflection.h362
-rw-r--r--NorthstarDedicatedTest/include/protobuf/generated_message_reflection_unittest.cc1319
-rw-r--r--NorthstarDedicatedTest/include/protobuf/generated_message_table_driven.cc103
-rw-r--r--NorthstarDedicatedTest/include/protobuf/generated_message_table_driven.h351
-rw-r--r--NorthstarDedicatedTest/include/protobuf/generated_message_table_driven_lite.cc106
-rw-r--r--NorthstarDedicatedTest/include/protobuf/generated_message_table_driven_lite.h874
-rw-r--r--NorthstarDedicatedTest/include/protobuf/generated_message_tctable_decl.h139
-rw-r--r--NorthstarDedicatedTest/include/protobuf/generated_message_tctable_full.cc53
-rw-r--r--NorthstarDedicatedTest/include/protobuf/generated_message_tctable_impl.h302
-rw-r--r--NorthstarDedicatedTest/include/protobuf/generated_message_tctable_impl.inc92
-rw-r--r--NorthstarDedicatedTest/include/protobuf/generated_message_tctable_lite.cc456
-rw-r--r--NorthstarDedicatedTest/include/protobuf/generated_message_util.cc779
-rw-r--r--NorthstarDedicatedTest/include/protobuf/generated_message_util.h213
-rw-r--r--NorthstarDedicatedTest/include/protobuf/has_bits.h116
-rw-r--r--NorthstarDedicatedTest/include/protobuf/implicit_weak_message.cc67
-rw-r--r--NorthstarDedicatedTest/include/protobuf/implicit_weak_message.h186
-rw-r--r--NorthstarDedicatedTest/include/protobuf/inlined_string_field.cc110
-rw-r--r--NorthstarDedicatedTest/include/protobuf/inlined_string_field.h384
-rw-r--r--NorthstarDedicatedTest/include/protobuf/inlined_string_field_unittest.cc286
-rw-r--r--NorthstarDedicatedTest/include/protobuf/io/coded_stream.cc978
-rw-r--r--NorthstarDedicatedTest/include/protobuf/io/coded_stream.h1775
-rw-r--r--NorthstarDedicatedTest/include/protobuf/io/coded_stream_unittest.cc1346
-rw-r--r--NorthstarDedicatedTest/include/protobuf/io/gzip_stream.cc333
-rw-r--r--NorthstarDedicatedTest/include/protobuf/io/gzip_stream.h202
-rw-r--r--NorthstarDedicatedTest/include/protobuf/io/gzip_stream_unittest.sh44
-rw-r--r--NorthstarDedicatedTest/include/protobuf/io/io_win32.cc470
-rw-r--r--NorthstarDedicatedTest/include/protobuf/io/io_win32.h139
-rw-r--r--NorthstarDedicatedTest/include/protobuf/io/io_win32_unittest.cc631
-rw-r--r--NorthstarDedicatedTest/include/protobuf/io/package_info.h53
-rw-r--r--NorthstarDedicatedTest/include/protobuf/io/printer.cc400
-rw-r--r--NorthstarDedicatedTest/include/protobuf/io/printer.h385
-rw-r--r--NorthstarDedicatedTest/include/protobuf/io/printer_unittest.cc735
-rw-r--r--NorthstarDedicatedTest/include/protobuf/io/strtod.cc82
-rw-r--r--NorthstarDedicatedTest/include/protobuf/io/strtod.h55
-rw-r--r--NorthstarDedicatedTest/include/protobuf/io/tokenizer.cc1185
-rw-r--r--NorthstarDedicatedTest/include/protobuf/io/tokenizer.h440
-rw-r--r--NorthstarDedicatedTest/include/protobuf/io/tokenizer_unittest.cc1073
-rw-r--r--NorthstarDedicatedTest/include/protobuf/io/zero_copy_stream.cc55
-rw-r--r--NorthstarDedicatedTest/include/protobuf/io/zero_copy_stream.h253
-rw-r--r--NorthstarDedicatedTest/include/protobuf/io/zero_copy_stream_impl.cc372
-rw-r--r--NorthstarDedicatedTest/include/protobuf/io/zero_copy_stream_impl.h327
-rw-r--r--NorthstarDedicatedTest/include/protobuf/io/zero_copy_stream_impl_lite.cc467
-rw-r--r--NorthstarDedicatedTest/include/protobuf/io/zero_copy_stream_impl_lite.h408
-rw-r--r--NorthstarDedicatedTest/include/protobuf/io/zero_copy_stream_unittest.cc1088
-rw-r--r--NorthstarDedicatedTest/include/protobuf/libprotobuf.vcxproj192
-rw-r--r--NorthstarDedicatedTest/include/protobuf/libprotobuf.vcxproj.filters294
-rw-r--r--NorthstarDedicatedTest/include/protobuf/lite_arena_unittest.cc90
-rw-r--r--NorthstarDedicatedTest/include/protobuf/lite_unittest.cc1272
-rw-r--r--NorthstarDedicatedTest/include/protobuf/map.cc41
-rw-r--r--NorthstarDedicatedTest/include/protobuf/map.h1377
-rw-r--r--NorthstarDedicatedTest/include/protobuf/map_entry.h160
-rw-r--r--NorthstarDedicatedTest/include/protobuf/map_entry_lite.h654
-rw-r--r--NorthstarDedicatedTest/include/protobuf/map_field.cc647
-rw-r--r--NorthstarDedicatedTest/include/protobuf/map_field.h923
-rw-r--r--NorthstarDedicatedTest/include/protobuf/map_field_inl.h375
-rw-r--r--NorthstarDedicatedTest/include/protobuf/map_field_lite.h184
-rw-r--r--NorthstarDedicatedTest/include/protobuf/map_field_test.cc527
-rw-r--r--NorthstarDedicatedTest/include/protobuf/map_lite_test_util.cc93
-rw-r--r--NorthstarDedicatedTest/include/protobuf/map_lite_test_util.h80
-rw-r--r--NorthstarDedicatedTest/include/protobuf/map_lite_unittest.proto127
-rw-r--r--NorthstarDedicatedTest/include/protobuf/map_proto2_unittest.proto91
-rw-r--r--NorthstarDedicatedTest/include/protobuf/map_test.cc63
-rw-r--r--NorthstarDedicatedTest/include/protobuf/map_test.inc3874
-rw-r--r--NorthstarDedicatedTest/include/protobuf/map_test_util.h46
-rw-r--r--NorthstarDedicatedTest/include/protobuf/map_test_util.inc271
-rw-r--r--NorthstarDedicatedTest/include/protobuf/map_test_util_impl.h476
-rw-r--r--NorthstarDedicatedTest/include/protobuf/map_type_handler.h691
-rw-r--r--NorthstarDedicatedTest/include/protobuf/map_unittest.proto125
-rw-r--r--NorthstarDedicatedTest/include/protobuf/message.cc400
-rw-r--r--NorthstarDedicatedTest/include/protobuf/message.h1487
-rw-r--r--NorthstarDedicatedTest/include/protobuf/message_lite.cc595
-rw-r--r--NorthstarDedicatedTest/include/protobuf/message_lite.h593
-rw-r--r--NorthstarDedicatedTest/include/protobuf/message_unittest.cc48
-rw-r--r--NorthstarDedicatedTest/include/protobuf/message_unittest.inc897
-rw-r--r--NorthstarDedicatedTest/include/protobuf/metadata.h36
-rw-r--r--NorthstarDedicatedTest/include/protobuf/metadata_lite.h270
-rw-r--r--NorthstarDedicatedTest/include/protobuf/no_field_presence_test.cc575
-rw-r--r--NorthstarDedicatedTest/include/protobuf/package_info.h66
-rw-r--r--NorthstarDedicatedTest/include/protobuf/parse_context.cc559
-rw-r--r--NorthstarDedicatedTest/include/protobuf/parse_context.h938
-rw-r--r--NorthstarDedicatedTest/include/protobuf/port.h40
-rw-r--r--NorthstarDedicatedTest/include/protobuf/port_def.inc824
-rw-r--r--NorthstarDedicatedTest/include/protobuf/port_undef.inc145
-rw-r--r--NorthstarDedicatedTest/include/protobuf/preserve_unknown_enum_test.cc290
-rw-r--r--NorthstarDedicatedTest/include/protobuf/proto3_arena_lite_unittest.cc152
-rw-r--r--NorthstarDedicatedTest/include/protobuf/proto3_arena_unittest.cc632
-rw-r--r--NorthstarDedicatedTest/include/protobuf/proto3_lite_unittest.cc43
-rw-r--r--NorthstarDedicatedTest/include/protobuf/proto3_lite_unittest.inc146
-rw-r--r--NorthstarDedicatedTest/include/protobuf/reflection.h568
-rw-r--r--NorthstarDedicatedTest/include/protobuf/reflection_internal.h364
-rw-r--r--NorthstarDedicatedTest/include/protobuf/reflection_ops.cc454
-rw-r--r--NorthstarDedicatedTest/include/protobuf/reflection_ops.h91
-rw-r--r--NorthstarDedicatedTest/include/protobuf/reflection_ops_unittest.cc546
-rw-r--r--NorthstarDedicatedTest/include/protobuf/reflection_tester.cc1673
-rw-r--r--NorthstarDedicatedTest/include/protobuf/reflection_tester.h122
-rw-r--r--NorthstarDedicatedTest/include/protobuf/repeated_field.cc60
-rw-r--r--NorthstarDedicatedTest/include/protobuf/repeated_field.h1057
-rw-r--r--NorthstarDedicatedTest/include/protobuf/repeated_field_reflection_unittest.cc708
-rw-r--r--NorthstarDedicatedTest/include/protobuf/repeated_field_unittest.cc2187
-rw-r--r--NorthstarDedicatedTest/include/protobuf/repeated_ptr_field.cc157
-rw-r--r--NorthstarDedicatedTest/include/protobuf/repeated_ptr_field.h2014
-rw-r--r--NorthstarDedicatedTest/include/protobuf/service.cc45
-rw-r--r--NorthstarDedicatedTest/include/protobuf/service.h293
-rw-r--r--NorthstarDedicatedTest/include/protobuf/source_context.pb.cc289
-rw-r--r--NorthstarDedicatedTest/include/protobuf/source_context.pb.h290
-rw-r--r--NorthstarDedicatedTest/include/protobuf/source_context.proto48
-rw-r--r--NorthstarDedicatedTest/include/protobuf/string_member_robber.h38
-rw-r--r--NorthstarDedicatedTest/include/protobuf/struct.pb.cc1048
-rw-r--r--NorthstarDedicatedTest/include/protobuf/struct.pb.h1182
-rw-r--r--NorthstarDedicatedTest/include/protobuf/struct.proto95
-rw-r--r--NorthstarDedicatedTest/include/protobuf/stubs/bytestream.cc194
-rw-r--r--NorthstarDedicatedTest/include/protobuf/stubs/bytestream.h351
-rw-r--r--NorthstarDedicatedTest/include/protobuf/stubs/bytestream_unittest.cc146
-rw-r--r--NorthstarDedicatedTest/include/protobuf/stubs/callback.h583
-rw-r--r--NorthstarDedicatedTest/include/protobuf/stubs/casts.h138
-rw-r--r--NorthstarDedicatedTest/include/protobuf/stubs/common.cc324
-rw-r--r--NorthstarDedicatedTest/include/protobuf/stubs/common.h201
-rw-r--r--NorthstarDedicatedTest/include/protobuf/stubs/common_unittest.cc358
-rw-r--r--NorthstarDedicatedTest/include/protobuf/stubs/hash.h114
-rw-r--r--NorthstarDedicatedTest/include/protobuf/stubs/int128.cc192
-rw-r--r--NorthstarDedicatedTest/include/protobuf/stubs/int128.h387
-rw-r--r--NorthstarDedicatedTest/include/protobuf/stubs/int128_unittest.cc511
-rw-r--r--NorthstarDedicatedTest/include/protobuf/stubs/logging.h239
-rw-r--r--NorthstarDedicatedTest/include/protobuf/stubs/macros.h93
-rw-r--r--NorthstarDedicatedTest/include/protobuf/stubs/map_util.h769
-rw-r--r--NorthstarDedicatedTest/include/protobuf/stubs/mathutil.h162
-rw-r--r--NorthstarDedicatedTest/include/protobuf/stubs/mutex.h218
-rw-r--r--NorthstarDedicatedTest/include/protobuf/stubs/once.h55
-rw-r--r--NorthstarDedicatedTest/include/protobuf/stubs/platform_macros.h138
-rw-r--r--NorthstarDedicatedTest/include/protobuf/stubs/port.h413
-rw-r--r--NorthstarDedicatedTest/include/protobuf/stubs/status.cc262
-rw-r--r--NorthstarDedicatedTest/include/protobuf/stubs/status.h196
-rw-r--r--NorthstarDedicatedTest/include/protobuf/stubs/status_macros.h89
-rw-r--r--NorthstarDedicatedTest/include/protobuf/stubs/status_test.cc278
-rw-r--r--NorthstarDedicatedTest/include/protobuf/stubs/statusor.cc48
-rw-r--r--NorthstarDedicatedTest/include/protobuf/stubs/statusor.h253
-rw-r--r--NorthstarDedicatedTest/include/protobuf/stubs/statusor_test.cc272
-rw-r--r--NorthstarDedicatedTest/include/protobuf/stubs/stl_util.h85
-rw-r--r--NorthstarDedicatedTest/include/protobuf/stubs/stringpiece.cc256
-rw-r--r--NorthstarDedicatedTest/include/protobuf/stubs/stringpiece.h402
-rw-r--r--NorthstarDedicatedTest/include/protobuf/stubs/stringpiece_unittest.cc695
-rw-r--r--NorthstarDedicatedTest/include/protobuf/stubs/stringprintf.cc175
-rw-r--r--NorthstarDedicatedTest/include/protobuf/stubs/stringprintf.h85
-rw-r--r--NorthstarDedicatedTest/include/protobuf/stubs/stringprintf_unittest.cc155
-rw-r--r--NorthstarDedicatedTest/include/protobuf/stubs/structurally_valid.cc615
-rw-r--r--NorthstarDedicatedTest/include/protobuf/stubs/structurally_valid_unittest.cc71
-rw-r--r--NorthstarDedicatedTest/include/protobuf/stubs/strutil.cc2479
-rw-r--r--NorthstarDedicatedTest/include/protobuf/stubs/strutil.h950
-rw-r--r--NorthstarDedicatedTest/include/protobuf/stubs/strutil_unittest.cc884
-rw-r--r--NorthstarDedicatedTest/include/protobuf/stubs/substitute.cc136
-rw-r--r--NorthstarDedicatedTest/include/protobuf/stubs/substitute.h178
-rw-r--r--NorthstarDedicatedTest/include/protobuf/stubs/template_util.h138
-rw-r--r--NorthstarDedicatedTest/include/protobuf/stubs/template_util_unittest.cc130
-rw-r--r--NorthstarDedicatedTest/include/protobuf/stubs/time.cc365
-rw-r--r--NorthstarDedicatedTest/include/protobuf/stubs/time.h80
-rw-r--r--NorthstarDedicatedTest/include/protobuf/stubs/time_test.cc261
-rw-r--r--NorthstarDedicatedTest/include/protobuf/test_messages_proto2.proto292
-rw-r--r--NorthstarDedicatedTest/include/protobuf/test_messages_proto3.proto289
-rw-r--r--NorthstarDedicatedTest/include/protobuf/test_util.cc47
-rw-r--r--NorthstarDedicatedTest/include/protobuf/test_util.h1257
-rw-r--r--NorthstarDedicatedTest/include/protobuf/test_util.inc2406
-rw-r--r--NorthstarDedicatedTest/include/protobuf/test_util2.h82
-rw-r--r--NorthstarDedicatedTest/include/protobuf/test_util_lite.cc1970
-rw-r--r--NorthstarDedicatedTest/include/protobuf/test_util_lite.h101
-rw-r--r--NorthstarDedicatedTest/include/protobuf/testdata/bad_utf8_string1
-rw-r--r--NorthstarDedicatedTest/include/protobuf/testdata/golden_messagebin0 -> 531 bytes
-rw-r--r--NorthstarDedicatedTest/include/protobuf/testdata/golden_message_mapsbin0 -> 13619 bytes
-rw-r--r--NorthstarDedicatedTest/include/protobuf/testdata/golden_message_oneof_implementedbin0 -> 515 bytes
-rw-r--r--NorthstarDedicatedTest/include/protobuf/testdata/golden_message_proto3bin0 -> 248 bytes
-rw-r--r--NorthstarDedicatedTest/include/protobuf/testdata/golden_packed_fields_messagebin0 -> 142 bytes
-rw-r--r--NorthstarDedicatedTest/include/protobuf/testdata/map_test_data.txt140
-rw-r--r--NorthstarDedicatedTest/include/protobuf/testdata/text_format_unittest_data.txt134
-rw-r--r--NorthstarDedicatedTest/include/protobuf/testdata/text_format_unittest_data_oneof_implemented.txt129
-rw-r--r--NorthstarDedicatedTest/include/protobuf/testdata/text_format_unittest_data_pointy.txt134
-rw-r--r--NorthstarDedicatedTest/include/protobuf/testdata/text_format_unittest_data_pointy_oneof.txt129
-rw-r--r--NorthstarDedicatedTest/include/protobuf/testdata/text_format_unittest_extensions_data.txt134
-rw-r--r--NorthstarDedicatedTest/include/protobuf/testdata/text_format_unittest_extensions_data_pointy.txt134
-rw-r--r--NorthstarDedicatedTest/include/protobuf/testing/file.cc215
-rw-r--r--NorthstarDedicatedTest/include/protobuf/testing/file.h107
-rw-r--r--NorthstarDedicatedTest/include/protobuf/testing/googletest.cc302
-rw-r--r--NorthstarDedicatedTest/include/protobuf/testing/googletest.h104
-rw-r--r--NorthstarDedicatedTest/include/protobuf/testing/zcgunzip.cc84
-rw-r--r--NorthstarDedicatedTest/include/protobuf/testing/zcgzip.cc87
-rw-r--r--NorthstarDedicatedTest/include/protobuf/text_format.cc2728
-rw-r--r--NorthstarDedicatedTest/include/protobuf/text_format.h687
-rw-r--r--NorthstarDedicatedTest/include/protobuf/text_format_unittest.cc2400
-rw-r--r--NorthstarDedicatedTest/include/protobuf/timestamp.pb.cc300
-rw-r--r--NorthstarDedicatedTest/include/protobuf/timestamp.pb.h285
-rw-r--r--NorthstarDedicatedTest/include/protobuf/timestamp.proto147
-rw-r--r--NorthstarDedicatedTest/include/protobuf/type.pb.cc2133
-rw-r--r--NorthstarDedicatedTest/include/protobuf/type.pb.h2581
-rw-r--r--NorthstarDedicatedTest/include/protobuf/type.proto187
-rw-r--r--NorthstarDedicatedTest/include/protobuf/unittest.proto1158
-rw-r--r--NorthstarDedicatedTest/include/protobuf/unittest_arena.proto43
-rw-r--r--NorthstarDedicatedTest/include/protobuf/unittest_custom_options.proto464
-rw-r--r--NorthstarDedicatedTest/include/protobuf/unittest_drop_unknown_fields.proto58
-rw-r--r--NorthstarDedicatedTest/include/protobuf/unittest_embed_optimize_for.proto51
-rw-r--r--NorthstarDedicatedTest/include/protobuf/unittest_empty.proto38
-rw-r--r--NorthstarDedicatedTest/include/protobuf/unittest_enormous_descriptor.proto1048
-rw-r--r--NorthstarDedicatedTest/include/protobuf/unittest_import.proto73
-rw-r--r--NorthstarDedicatedTest/include/protobuf/unittest_import_lite.proto52
-rw-r--r--NorthstarDedicatedTest/include/protobuf/unittest_import_public.proto41
-rw-r--r--NorthstarDedicatedTest/include/protobuf/unittest_import_public_lite.proto43
-rw-r--r--NorthstarDedicatedTest/include/protobuf/unittest_lazy_dependencies.proto75
-rw-r--r--NorthstarDedicatedTest/include/protobuf/unittest_lazy_dependencies_custom_option.proto67
-rw-r--r--NorthstarDedicatedTest/include/protobuf/unittest_lazy_dependencies_enum.proto61
-rw-r--r--NorthstarDedicatedTest/include/protobuf/unittest_lite.proto501
-rw-r--r--NorthstarDedicatedTest/include/protobuf/unittest_lite_imports_nonlite.proto47
-rw-r--r--NorthstarDedicatedTest/include/protobuf/unittest_mset.proto84
-rw-r--r--NorthstarDedicatedTest/include/protobuf/unittest_mset_wire_format.proto52
-rw-r--r--NorthstarDedicatedTest/include/protobuf/unittest_no_field_presence.proto138
-rw-r--r--NorthstarDedicatedTest/include/protobuf/unittest_no_generic_services.proto54
-rw-r--r--NorthstarDedicatedTest/include/protobuf/unittest_optimize_for.proto67
-rw-r--r--NorthstarDedicatedTest/include/protobuf/unittest_preserve_unknown_enum.proto71
-rw-r--r--NorthstarDedicatedTest/include/protobuf/unittest_preserve_unknown_enum2.proto50
-rw-r--r--NorthstarDedicatedTest/include/protobuf/unittest_proto3.proto228
-rw-r--r--NorthstarDedicatedTest/include/protobuf/unittest_proto3_arena.proto235
-rw-r--r--NorthstarDedicatedTest/include/protobuf/unittest_proto3_arena_lite.proto205
-rw-r--r--NorthstarDedicatedTest/include/protobuf/unittest_proto3_lite.proto204
-rw-r--r--NorthstarDedicatedTest/include/protobuf/unittest_proto3_optional.proto100
-rw-r--r--NorthstarDedicatedTest/include/protobuf/unittest_well_known_types.proto114
-rw-r--r--NorthstarDedicatedTest/include/protobuf/unknown_field_set.cc334
-rw-r--r--NorthstarDedicatedTest/include/protobuf/unknown_field_set.h411
-rw-r--r--NorthstarDedicatedTest/include/protobuf/unknown_field_set_unittest.cc652
-rw-r--r--NorthstarDedicatedTest/include/protobuf/util/delimited_message_util.cc127
-rw-r--r--NorthstarDedicatedTest/include/protobuf/util/delimited_message_util.h108
-rw-r--r--NorthstarDedicatedTest/include/protobuf/util/delimited_message_util_test.cc116
-rw-r--r--NorthstarDedicatedTest/include/protobuf/util/field_comparator.cc210
-rw-r--r--NorthstarDedicatedTest/include/protobuf/util/field_comparator.h285
-rw-r--r--NorthstarDedicatedTest/include/protobuf/util/field_comparator_test.cc495
-rw-r--r--NorthstarDedicatedTest/include/protobuf/util/field_mask_util.cc720
-rw-r--r--NorthstarDedicatedTest/include/protobuf/util/field_mask_util.h262
-rw-r--r--NorthstarDedicatedTest/include/protobuf/util/field_mask_util_test.cc836
-rw-r--r--NorthstarDedicatedTest/include/protobuf/util/internal/constants.h101
-rw-r--r--NorthstarDedicatedTest/include/protobuf/util/internal/datapiece.cc423
-rw-r--r--NorthstarDedicatedTest/include/protobuf/util/internal/datapiece.h218
-rw-r--r--NorthstarDedicatedTest/include/protobuf/util/internal/default_value_objectwriter.cc642
-rw-r--r--NorthstarDedicatedTest/include/protobuf/util/internal/default_value_objectwriter.h332
-rw-r--r--NorthstarDedicatedTest/include/protobuf/util/internal/default_value_objectwriter_test.cc191
-rw-r--r--NorthstarDedicatedTest/include/protobuf/util/internal/error_listener.cc42
-rw-r--r--NorthstarDedicatedTest/include/protobuf/util/internal/error_listener.h109
-rw-r--r--NorthstarDedicatedTest/include/protobuf/util/internal/expecting_objectwriter.h250
-rw-r--r--NorthstarDedicatedTest/include/protobuf/util/internal/field_mask_utility.cc218
-rw-r--r--NorthstarDedicatedTest/include/protobuf/util/internal/field_mask_utility.h74
-rw-r--r--NorthstarDedicatedTest/include/protobuf/util/internal/json_escaping.cc372
-rw-r--r--NorthstarDedicatedTest/include/protobuf/util/internal/json_escaping.h98
-rw-r--r--NorthstarDedicatedTest/include/protobuf/util/internal/json_objectwriter.cc190
-rw-r--r--NorthstarDedicatedTest/include/protobuf/util/internal/json_objectwriter.h278
-rw-r--r--NorthstarDedicatedTest/include/protobuf/util/internal/json_objectwriter_test.cc315
-rw-r--r--NorthstarDedicatedTest/include/protobuf/util/internal/json_stream_parser.cc995
-rw-r--r--NorthstarDedicatedTest/include/protobuf/util/internal/json_stream_parser.h349
-rw-r--r--NorthstarDedicatedTest/include/protobuf/util/internal/json_stream_parser_test.cc979
-rw-r--r--NorthstarDedicatedTest/include/protobuf/util/internal/location_tracker.h69
-rw-r--r--NorthstarDedicatedTest/include/protobuf/util/internal/mock_error_listener.h68
-rw-r--r--NorthstarDedicatedTest/include/protobuf/util/internal/object_location_tracker.h64
-rw-r--r--NorthstarDedicatedTest/include/protobuf/util/internal/object_source.h85
-rw-r--r--NorthstarDedicatedTest/include/protobuf/util/internal/object_writer.cc93
-rw-r--r--NorthstarDedicatedTest/include/protobuf/util/internal/object_writer.h151
-rw-r--r--NorthstarDedicatedTest/include/protobuf/util/internal/proto_writer.cc825
-rw-r--r--NorthstarDedicatedTest/include/protobuf/util/internal/proto_writer.h388
-rw-r--r--NorthstarDedicatedTest/include/protobuf/util/internal/protostream_objectsource.cc1112
-rw-r--r--NorthstarDedicatedTest/include/protobuf/util/internal/protostream_objectsource.h328
-rw-r--r--NorthstarDedicatedTest/include/protobuf/util/internal/protostream_objectsource_test.cc1165
-rw-r--r--NorthstarDedicatedTest/include/protobuf/util/internal/protostream_objectwriter.cc1400
-rw-r--r--NorthstarDedicatedTest/include/protobuf/util/internal/protostream_objectwriter.h452
-rw-r--r--NorthstarDedicatedTest/include/protobuf/util/internal/protostream_objectwriter_test.cc3032
-rw-r--r--NorthstarDedicatedTest/include/protobuf/util/internal/structured_objectwriter.h120
-rw-r--r--NorthstarDedicatedTest/include/protobuf/util/internal/testdata/anys.proto118
-rw-r--r--NorthstarDedicatedTest/include/protobuf/util/internal/testdata/books.proto251
-rw-r--r--NorthstarDedicatedTest/include/protobuf/util/internal/testdata/default_value.proto170
-rw-r--r--NorthstarDedicatedTest/include/protobuf/util/internal/testdata/default_value_test.proto53
-rw-r--r--NorthstarDedicatedTest/include/protobuf/util/internal/testdata/field_mask.proto71
-rw-r--r--NorthstarDedicatedTest/include/protobuf/util/internal/testdata/maps.proto148
-rw-r--r--NorthstarDedicatedTest/include/protobuf/util/internal/testdata/oneofs.proto77
-rw-r--r--NorthstarDedicatedTest/include/protobuf/util/internal/testdata/proto3.proto42
-rw-r--r--NorthstarDedicatedTest/include/protobuf/util/internal/testdata/struct.proto117
-rw-r--r--NorthstarDedicatedTest/include/protobuf/util/internal/testdata/timestamp_duration.proto80
-rw-r--r--NorthstarDedicatedTest/include/protobuf/util/internal/testdata/wrappers.proto100
-rw-r--r--NorthstarDedicatedTest/include/protobuf/util/internal/type_info.cc182
-rw-r--r--NorthstarDedicatedTest/include/protobuf/util/internal/type_info.h97
-rw-r--r--NorthstarDedicatedTest/include/protobuf/util/internal/type_info_test_helper.cc132
-rw-r--r--NorthstarDedicatedTest/include/protobuf/util/internal/type_info_test_helper.h96
-rw-r--r--NorthstarDedicatedTest/include/protobuf/util/internal/utility.cc416
-rw-r--r--NorthstarDedicatedTest/include/protobuf/util/internal/utility.h204
-rw-r--r--NorthstarDedicatedTest/include/protobuf/util/json_format.proto140
-rw-r--r--NorthstarDedicatedTest/include/protobuf/util/json_format_proto3.proto194
-rw-r--r--NorthstarDedicatedTest/include/protobuf/util/json_util.cc282
-rw-r--r--NorthstarDedicatedTest/include/protobuf/util/json_util.h204
-rw-r--r--NorthstarDedicatedTest/include/protobuf/util/json_util_test.cc668
-rw-r--r--NorthstarDedicatedTest/include/protobuf/util/message_differencer.cc2222
-rw-r--r--NorthstarDedicatedTest/include/protobuf/util/message_differencer.h976
-rw-r--r--NorthstarDedicatedTest/include/protobuf/util/message_differencer_unittest.cc3812
-rw-r--r--NorthstarDedicatedTest/include/protobuf/util/message_differencer_unittest.proto79
-rw-r--r--NorthstarDedicatedTest/include/protobuf/util/package_info.h46
-rw-r--r--NorthstarDedicatedTest/include/protobuf/util/time_util.cc511
-rw-r--r--NorthstarDedicatedTest/include/protobuf/util/time_util.h313
-rw-r--r--NorthstarDedicatedTest/include/protobuf/util/time_util_test.cc384
-rw-r--r--NorthstarDedicatedTest/include/protobuf/util/type_resolver.h76
-rw-r--r--NorthstarDedicatedTest/include/protobuf/util/type_resolver_util.cc370
-rw-r--r--NorthstarDedicatedTest/include/protobuf/util/type_resolver_util.h57
-rw-r--r--NorthstarDedicatedTest/include/protobuf/util/type_resolver_util_test.cc438
-rw-r--r--NorthstarDedicatedTest/include/protobuf/version.rc45
-rw-r--r--NorthstarDedicatedTest/include/protobuf/well_known_types_unittest.cc60
-rw-r--r--NorthstarDedicatedTest/include/protobuf/wire_format.cc1751
-rw-r--r--NorthstarDedicatedTest/include/protobuf/wire_format.h414
-rw-r--r--NorthstarDedicatedTest/include/protobuf/wire_format_lite.cc784
-rw-r--r--NorthstarDedicatedTest/include/protobuf/wire_format_lite.h1915
-rw-r--r--NorthstarDedicatedTest/include/protobuf/wire_format_unittest.cc70
-rw-r--r--NorthstarDedicatedTest/include/protobuf/wire_format_unittest.inc1585
-rw-r--r--NorthstarDedicatedTest/include/protobuf/wrappers.pb.cc1955
-rw-r--r--NorthstarDedicatedTest/include/protobuf/wrappers.pb.h1734
-rw-r--r--NorthstarDedicatedTest/include/protobuf/wrappers.proto123
-rw-r--r--R2Northstar.sln31
587 files changed, 295374 insertions, 0 deletions
diff --git a/NorthstarDedicatedTest/include/.clang-format b/NorthstarDedicatedTest/include/.clang-format
new file mode 100644
index 00000000..fa2f6250
--- /dev/null
+++ b/NorthstarDedicatedTest/include/.clang-format
@@ -0,0 +1,4 @@
+{
+ "DisableFormat": true,
+ "SortIncludes": "Never"
+}
diff --git a/NorthstarDedicatedTest/include/protobuf/any.cc b/NorthstarDedicatedTest/include/protobuf/any.cc
new file mode 100644
index 00000000..a492d8b8
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/any.cc
@@ -0,0 +1,83 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <any.h>
+
+#include <arenastring.h>
+#include <descriptor.h>
+#include <generated_message_util.h>
+#include <message.h>
+
+#include <port_def.inc>
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+bool AnyMetadata::PackFrom(Arena* arena, const Message& message) {
+ return PackFrom(arena, message, kTypeGoogleApisComPrefix);
+}
+
+bool AnyMetadata::PackFrom(Arena* arena, const Message& message,
+ StringPiece type_url_prefix) {
+ type_url_->Set(
+ &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyString(),
+ GetTypeUrl(message.GetDescriptor()->full_name(), type_url_prefix), arena);
+ return message.SerializeToString(
+ value_->Mutable(ArenaStringPtr::EmptyDefault{}, arena));
+}
+
+bool AnyMetadata::UnpackTo(Message* message) const {
+ if (!InternalIs(message->GetDescriptor()->full_name())) {
+ return false;
+ }
+ return message->ParseFromString(value_->Get());
+}
+
+bool GetAnyFieldDescriptors(const Message& message,
+ const FieldDescriptor** type_url_field,
+ const FieldDescriptor** value_field) {
+ const Descriptor* descriptor = message.GetDescriptor();
+ if (descriptor->full_name() != kAnyFullTypeName) {
+ return false;
+ }
+ *type_url_field = descriptor->FindFieldByNumber(1);
+ *value_field = descriptor->FindFieldByNumber(2);
+ return (*type_url_field != nullptr &&
+ (*type_url_field)->type() == FieldDescriptor::TYPE_STRING &&
+ *value_field != nullptr &&
+ (*value_field)->type() == FieldDescriptor::TYPE_BYTES);
+}
+
+} // namespace internal
+} // namespace protobuf
+} // namespace google
+
+#include <port_undef.inc>
diff --git a/NorthstarDedicatedTest/include/protobuf/any.h b/NorthstarDedicatedTest/include/protobuf/any.h
new file mode 100644
index 00000000..3745d2c8
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/any.h
@@ -0,0 +1,156 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef GOOGLE_PROTOBUF_ANY_H__
+#define GOOGLE_PROTOBUF_ANY_H__
+
+#include <string>
+
+#include <stubs/common.h>
+#include <arenastring.h>
+#include <message_lite.h>
+
+#include <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:
+// google::protobuf::Any() // static method on the generated message type.
+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 <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_ANY_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/any.pb.cc b/NorthstarDedicatedTest/include/protobuf/any.pb.cc
new file mode 100644
index 00000000..a1ec2391
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/any.pb.cc
@@ -0,0 +1,352 @@
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+// source: google/protobuf/any.proto
+
+#include <any.pb.h>
+
+#include <algorithm>
+
+#include <io/coded_stream.h>
+#include <extension_set.h>
+#include <wire_format_lite.h>
+#include <descriptor.h>
+#include <generated_message_reflection.h>
+#include <reflection_ops.h>
+#include <wire_format.h>
+// @@protoc_insertion_point(includes)
+#include <port_def.inc>
+
+PROTOBUF_PRAGMA_INIT_SEG
+PROTOBUF_NAMESPACE_OPEN
+constexpr Any::Any(
+ ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized)
+ : type_url_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string)
+ , value_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string)
+ , _any_metadata_(&type_url_, &value_){}
+struct AnyDefaultTypeInternal {
+ constexpr AnyDefaultTypeInternal()
+ : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {}
+ ~AnyDefaultTypeInternal() {}
+ union {
+ Any _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT AnyDefaultTypeInternal _Any_default_instance_;
+PROTOBUF_NAMESPACE_CLOSE
+static ::PROTOBUF_NAMESPACE_ID::Metadata file_level_metadata_google_2fprotobuf_2fany_2eproto[1];
+static constexpr ::PROTOBUF_NAMESPACE_ID::EnumDescriptor const** file_level_enum_descriptors_google_2fprotobuf_2fany_2eproto = nullptr;
+static constexpr ::PROTOBUF_NAMESPACE_ID::ServiceDescriptor const** file_level_service_descriptors_google_2fprotobuf_2fany_2eproto = nullptr;
+
+const 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, type_url_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Any, value_),
+};
+static const ::PROTOBUF_NAMESPACE_ID::internal::MigrationSchema schemas[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = {
+ { 0, -1, -1, sizeof(::PROTOBUF_NAMESPACE_ID::Any)},
+};
+
+static ::PROTOBUF_NAMESPACE_ID::Message const * const file_default_instances[] = {
+ reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_Any_default_instance_),
+};
+
+const char descriptor_table_protodef_google_2fprotobuf_2fany_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) =
+ "\n\031google/protobuf/any.proto\022\017google.prot"
+ "obuf\"&\n\003Any\022\020\n\010type_url\030\001 \001(\t\022\r\n\005value\030\002"
+ " \001(\014Bv\n\023com.google.protobufB\010AnyProtoP\001Z"
+ ",google.golang.org/protobuf/types/known/"
+ "anypb\242\002\003GPB\252\002\036Google.Protobuf.WellKnownT"
+ "ypesb\006proto3"
+ ;
+static ::PROTOBUF_NAMESPACE_ID::internal::once_flag descriptor_table_google_2fprotobuf_2fany_2eproto_once;
+const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fany_2eproto = {
+ false, false, 212, descriptor_table_protodef_google_2fprotobuf_2fany_2eproto, "google/protobuf/any.proto",
+ &descriptor_table_google_2fprotobuf_2fany_2eproto_once, nullptr, 0, 1,
+ schemas, file_default_instances, TableStruct_google_2fprotobuf_2fany_2eproto::offsets,
+ file_level_metadata_google_2fprotobuf_2fany_2eproto, file_level_enum_descriptors_google_2fprotobuf_2fany_2eproto, file_level_service_descriptors_google_2fprotobuf_2fany_2eproto,
+};
+PROTOBUF_ATTRIBUTE_WEAK const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable* descriptor_table_google_2fprotobuf_2fany_2eproto_getter() {
+ return &descriptor_table_google_2fprotobuf_2fany_2eproto;
+}
+
+// Force running AddDescriptors() at dynamic initialization time.
+PROTOBUF_ATTRIBUTE_INIT_PRIORITY static ::PROTOBUF_NAMESPACE_ID::internal::AddDescriptorsRunner dynamic_init_dummy_google_2fprotobuf_2fany_2eproto(&descriptor_table_google_2fprotobuf_2fany_2eproto);
+PROTOBUF_NAMESPACE_OPEN
+
+// ===================================================================
+
+bool Any::GetAnyFieldDescriptors(
+ const ::PROTOBUF_NAMESPACE_ID::Message& message,
+ const ::PROTOBUF_NAMESPACE_ID::FieldDescriptor** type_url_field,
+ const ::PROTOBUF_NAMESPACE_ID::FieldDescriptor** value_field) {
+ return ::PROTOBUF_NAMESPACE_ID::internal::GetAnyFieldDescriptors(
+ message, type_url_field, value_field);
+}
+bool Any::ParseAnyTypeUrl(
+ ::PROTOBUF_NAMESPACE_ID::ConstStringParam type_url,
+ std::string* full_type_name) {
+ return ::PROTOBUF_NAMESPACE_ID::internal::ParseAnyTypeUrl(type_url,
+ full_type_name);
+}
+
+class Any::_Internal {
+ public:
+};
+
+Any::Any(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned)
+ : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned),
+ _any_metadata_(&type_url_, &value_) {
+ SharedCtor();
+ if (!is_message_owned) {
+ RegisterArenaDtor(arena);
+ }
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.Any)
+}
+Any::Any(const Any& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message(),
+ _any_metadata_(&type_url_, &value_) {
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ type_url_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ type_url_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (!from._internal_type_url().empty()) {
+ type_url_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_type_url(),
+ GetArenaForAllocation());
+ }
+ value_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (!from._internal_value().empty()) {
+ value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_value(),
+ GetArenaForAllocation());
+ }
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.Any)
+}
+
+inline void Any::SharedCtor() {
+type_url_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ type_url_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+value_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+}
+
+Any::~Any() {
+ // @@protoc_insertion_point(destructor:google.protobuf.Any)
+ if (GetArenaForAllocation() != nullptr) return;
+ SharedDtor();
+ _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+inline void Any::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+ type_url_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ value_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+}
+
+void Any::ArenaDtor(void* object) {
+ Any* _this = reinterpret_cast< Any* >(object);
+ (void)_this;
+}
+void Any::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) {
+}
+void Any::SetCachedSize(int size) const {
+ _cached_size_.Set(size);
+}
+
+void Any::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.Any)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ type_url_.ClearToEmpty();
+ value_.ClearToEmpty();
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* Any::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag);
+ switch (tag >> 3) {
+ // string type_url = 1;
+ case 1:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 10)) {
+ auto str = _internal_mutable_type_url();
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx);
+ CHK_(::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.Any.type_url"));
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // bytes value = 2;
+ case 2:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 18)) {
+ auto str = _internal_mutable_value();
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx);
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ default:
+ goto handle_unusual;
+ } // switch
+ handle_unusual:
+ if ((tag == 0) || ((tag & 7) == 4)) {
+ CHK_(ptr);
+ ctx->SetLastTag(tag);
+ goto message_done;
+ }
+ ptr = UnknownFieldParse(
+ tag,
+ _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(),
+ ptr, ctx);
+ CHK_(ptr != nullptr);
+ } // while
+message_done:
+ return ptr;
+failure:
+ ptr = nullptr;
+ goto message_done;
+#undef CHK_
+}
+
+uint8_t* Any::_InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const {
+ // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Any)
+ 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 = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray(
+ _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Any)
+ return target;
+}
+
+size_t Any::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.Any)
+ size_t total_size = 0;
+
+ 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, &_cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData Any::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck,
+ Any::MergeImpl
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*Any::GetClassData() const { return &_class_data_; }
+
+void Any::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to,
+ const ::PROTOBUF_NAMESPACE_ID::Message& from) {
+ static_cast<Any *>(to)->MergeFrom(
+ static_cast<const Any &>(from));
+}
+
+
+void Any::MergeFrom(const Any& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Any)
+ GOOGLE_DCHECK_NE(&from, this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ if (!from._internal_type_url().empty()) {
+ _internal_set_type_url(from._internal_type_url());
+ }
+ if (!from._internal_value().empty()) {
+ _internal_set_value(from._internal_value());
+ }
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+}
+
+void Any::CopyFrom(const Any& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.Any)
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+bool Any::IsInitialized() const {
+ return true;
+}
+
+void Any::InternalSwap(Any* other) {
+ using std::swap;
+ auto* lhs_arena = GetArenaForAllocation();
+ auto* rhs_arena = other->GetArenaForAllocation();
+ _internal_metadata_.InternalSwap(&other->_internal_metadata_);
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(),
+ &type_url_, lhs_arena,
+ &other->type_url_, rhs_arena
+ );
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(),
+ &value_, lhs_arena,
+ &other->value_, rhs_arena
+ );
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata Any::GetMetadata() const {
+ return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(
+ &descriptor_table_google_2fprotobuf_2fany_2eproto_getter, &descriptor_table_google_2fprotobuf_2fany_2eproto_once,
+ file_level_metadata_google_2fprotobuf_2fany_2eproto[0]);
+}
+
+// @@protoc_insertion_point(namespace_scope)
+PROTOBUF_NAMESPACE_CLOSE
+PROTOBUF_NAMESPACE_OPEN
+template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::Any* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::Any >(Arena* arena) {
+ return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::Any >(arena);
+}
+PROTOBUF_NAMESPACE_CLOSE
+
+// @@protoc_insertion_point(global_scope)
+#include <port_undef.inc>
diff --git a/NorthstarDedicatedTest/include/protobuf/any.pb.h b/NorthstarDedicatedTest/include/protobuf/any.pb.h
new file mode 100644
index 00000000..47513dba
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/any.pb.h
@@ -0,0 +1,391 @@
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+// source: google/protobuf/any.proto
+
+#ifndef GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fany_2eproto
+#define GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fany_2eproto
+
+#include <limits>
+#include <string>
+
+#include <port_def.inc>
+#if PROTOBUF_VERSION < 3019000
+#error This file was generated by a newer version of protoc which is
+#error incompatible with your Protocol Buffer headers. Please update
+#error your headers.
+#endif
+#if 3019004 < 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 <port_undef.inc>
+#include <io/coded_stream.h>
+#include <arena.h>
+#include <arenastring.h>
+#include <generated_message_table_driven.h>
+#include <generated_message_util.h>
+#include <metadata_lite.h>
+#include <generated_message_reflection.h>
+#include <message.h>
+#include <repeated_field.h> // IWYU pragma: export
+#include <extension_set.h> // IWYU pragma: export
+#include <unknown_field_set.h>
+// @@protoc_insertion_point(includes)
+#include <port_def.inc>
+#define PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fany_2eproto PROTOBUF_EXPORT
+PROTOBUF_NAMESPACE_OPEN
+namespace internal {
+class AnyMetadata;
+} // namespace internal
+PROTOBUF_NAMESPACE_CLOSE
+
+// Internal implementation detail -- do not use these members.
+struct PROTOBUF_EXPORT TableStruct_google_2fprotobuf_2fany_2eproto {
+ static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTableField entries[]
+ PROTOBUF_SECTION_VARIABLE(protodesc_cold);
+ static const ::PROTOBUF_NAMESPACE_ID::internal::AuxiliaryParseTableField aux[]
+ PROTOBUF_SECTION_VARIABLE(protodesc_cold);
+ static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTable schema[1]
+ PROTOBUF_SECTION_VARIABLE(protodesc_cold);
+ static const ::PROTOBUF_NAMESPACE_ID::internal::FieldMetadata field_metadata[];
+ static const ::PROTOBUF_NAMESPACE_ID::internal::SerializationTable serialization_table[];
+ static const 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 constexpr Any(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
+
+ Any(const Any& from);
+ Any(Any&& from) noexcept
+ : Any() {
+ *this = ::std::move(from);
+ }
+
+ inline Any& operator=(const Any& from) {
+ CopyFrom(from);
+ return *this;
+ }
+ inline Any& operator=(Any&& from) noexcept {
+ if (this == &from) return *this;
+ if (GetOwningArena() == from.GetOwningArena()
+ #ifdef PROTOBUF_FORCE_COPY_IN_MOVE
+ && GetOwningArena() != nullptr
+ #endif // !PROTOBUF_FORCE_COPY_IN_MOVE
+ ) {
+ InternalSwap(&from);
+ } else {
+ CopyFrom(from);
+ }
+ return *this;
+ }
+
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
+ return GetDescriptor();
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
+ return default_instance().GetMetadata().descriptor;
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
+ return default_instance().GetMetadata().reflection;
+ }
+ static const Any& default_instance() {
+ return *internal_default_instance();
+ }
+ static inline const Any* internal_default_instance() {
+ return reinterpret_cast<const Any*>(
+ &_Any_default_instance_);
+ }
+ static constexpr int kIndexInFileMessages =
+ 0;
+
+ // implements Any -----------------------------------------------
+
+ bool PackFrom(const ::PROTOBUF_NAMESPACE_ID::Message& message) {
+ return _any_metadata_.PackFrom(GetArena(), message);
+ }
+ bool PackFrom(const ::PROTOBUF_NAMESPACE_ID::Message& message,
+ ::PROTOBUF_NAMESPACE_ID::ConstStringParam type_url_prefix) {
+ return _any_metadata_.PackFrom(GetArena(), message, type_url_prefix);
+ }
+ bool UnpackTo(::PROTOBUF_NAMESPACE_ID::Message* message) const {
+ return _any_metadata_.UnpackTo(message);
+ }
+ static bool GetAnyFieldDescriptors(
+ const ::PROTOBUF_NAMESPACE_ID::Message& message,
+ const ::PROTOBUF_NAMESPACE_ID::FieldDescriptor** type_url_field,
+ const ::PROTOBUF_NAMESPACE_ID::FieldDescriptor** value_field);
+ template <typename T, class = typename std::enable_if<!std::is_convertible<T, const ::PROTOBUF_NAMESPACE_ID::Message&>::value>::type>
+ bool PackFrom(const T& message) {
+ return _any_metadata_.PackFrom<T>(GetArena(), message);
+ }
+ template <typename T, class = typename std::enable_if<!std::is_convertible<T, const ::PROTOBUF_NAMESPACE_ID::Message&>::value>::type>
+ bool PackFrom(const T& message,
+ ::PROTOBUF_NAMESPACE_ID::ConstStringParam type_url_prefix) {
+ return _any_metadata_.PackFrom<T>(GetArena(), message, type_url_prefix);}
+ template <typename T, class = typename std::enable_if<!std::is_convertible<T, const ::PROTOBUF_NAMESPACE_ID::Message&>::value>::type>
+ bool UnpackTo(T* message) const {
+ return _any_metadata_.UnpackTo<T>(message);
+ }
+ template<typename T> bool Is() const {
+ return _any_metadata_.Is<T>();
+ }
+ static bool ParseAnyTypeUrl(::PROTOBUF_NAMESPACE_ID::ConstStringParam type_url,
+ 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);
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from);
+ public:
+ PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+ bool IsInitialized() const final;
+
+ size_t ByteSizeLong() const final;
+ const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
+ uint8_t* _InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
+ int GetCachedSize() const final { return _cached_size_.Get(); }
+
+ private:
+ void SharedCtor();
+ void SharedDtor();
+ void SetCachedSize(int size) const final;
+ void InternalSwap(Any* other);
+
+ private:
+ friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
+ static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
+ return "google.protobuf.Any";
+ }
+ protected:
+ explicit Any(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned = false);
+ private:
+ static void ArenaDtor(void* object);
+ inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
+ public:
+
+ static const ClassData _class_data_;
+ const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;
+
+ ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;
+
+ // nested types ----------------------------------------------------
+
+ // accessors -------------------------------------------------------
+
+ enum : int {
+ kTypeUrlFieldNumber = 1,
+ kValueFieldNumber = 2,
+ };
+ // string type_url = 1;
+ void clear_type_url();
+ const 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_;
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr type_url_;
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr value_;
+ mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
+ ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata _any_metadata_;
+ friend struct ::TableStruct_google_2fprotobuf_2fany_2eproto;
+};
+// ===================================================================
+
+
+// ===================================================================
+
+#ifdef __GNUC__
+ #pragma GCC diagnostic push
+ #pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#endif // __GNUC__
+// Any
+
+// string type_url = 1;
+inline void Any::clear_type_url() {
+ type_url_.ClearToEmpty();
+}
+inline const 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) {
+
+ type_url_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
+ // @@protoc_insertion_point(field_set:google.protobuf.Any.type_url)
+}
+inline 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 type_url_.Get();
+}
+inline void Any::_internal_set_type_url(const std::string& value) {
+
+ type_url_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation());
+}
+inline std::string* Any::_internal_mutable_type_url() {
+
+ return type_url_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation());
+}
+inline std::string* Any::release_type_url() {
+ // @@protoc_insertion_point(field_release:google.protobuf.Any.type_url)
+ return type_url_.Release(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
+}
+inline void Any::set_allocated_type_url(std::string* type_url) {
+ if (type_url != nullptr) {
+
+ } else {
+
+ }
+ type_url_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), type_url,
+ GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (type_url_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
+ type_url_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.Any.type_url)
+}
+
+// bytes value = 2;
+inline void Any::clear_value() {
+ value_.ClearToEmpty();
+}
+inline const 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) {
+
+ value_.SetBytes(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, 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 value_.Get();
+}
+inline void Any::_internal_set_value(const std::string& value) {
+
+ value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation());
+}
+inline std::string* Any::_internal_mutable_value() {
+
+ return value_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation());
+}
+inline std::string* Any::release_value() {
+ // @@protoc_insertion_point(field_release:google.protobuf.Any.value)
+ return value_.Release(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
+}
+inline void Any::set_allocated_value(std::string* value) {
+ if (value != nullptr) {
+
+ } else {
+
+ }
+ value_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value,
+ GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (value_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
+ value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.Any.value)
+}
+
+#ifdef __GNUC__
+ #pragma GCC diagnostic pop
+#endif // __GNUC__
+
+// @@protoc_insertion_point(namespace_scope)
+
+PROTOBUF_NAMESPACE_CLOSE
+
+// @@protoc_insertion_point(global_scope)
+
+#include <port_undef.inc>
+#endif // GOOGLE_PROTOBUF_INCLUDED_GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fany_2eproto
diff --git a/NorthstarDedicatedTest/include/protobuf/any.proto b/NorthstarDedicatedTest/include/protobuf/any.proto
new file mode 100644
index 00000000..6ed8a23c
--- /dev/null
+++ b/NorthstarDedicatedTest/include/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/NorthstarDedicatedTest/include/protobuf/any_lite.cc b/NorthstarDedicatedTest/include/protobuf/any_lite.cc
new file mode 100644
index 00000000..9ac54862
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/any_lite.cc
@@ -0,0 +1,99 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <any.h>
+
+#include <io/zero_copy_stream_impl_lite.h>
+#include <arenastring.h>
+#include <generated_message_util.h>
+#include <stubs/strutil.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(&::google::protobuf::internal::GetEmptyString(),
+ GetTypeUrl(type_name, type_url_prefix), arena);
+ return message.SerializeToString(
+ value_->Mutable(ArenaStringPtr::EmptyDefault{}, arena));
+}
+
+bool AnyMetadata::InternalUnpackTo(StringPiece type_name,
+ MessageLite* message) const {
+ if (!InternalIs(type_name)) {
+ return false;
+ }
+ return message->ParseFromString(value_->Get());
+}
+
+bool AnyMetadata::InternalIs(StringPiece type_name) const {
+ StringPiece type_url = type_url_->Get();
+ return type_url.size() >= type_name.size() + 1 &&
+ type_url[type_url.size() - type_name.size() - 1] == '/' &&
+ HasSuffixString(type_url, type_name);
+}
+
+bool ParseAnyTypeUrl(StringPiece type_url, 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/NorthstarDedicatedTest/include/protobuf/any_test.cc b/NorthstarDedicatedTest/include/protobuf/any_test.cc
new file mode 100644
index 00000000..27cca96b
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/any_test.cc
@@ -0,0 +1,184 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <any_test.pb.h>
+#include <unittest.pb.h>
+#include <gtest/gtest.h>
+
+
+// Must be included last.
+#include <port_def.inc>
+
+namespace google {
+namespace protobuf {
+namespace {
+
+TEST(AnyMetadataTest, ConstInit) {
+ PROTOBUF_CONSTINIT static internal::AnyMetadata metadata(nullptr, nullptr);
+ (void)metadata;
+}
+
+TEST(AnyTest, TestPackAndUnpack) {
+ protobuf_unittest::TestAny submessage;
+ submessage.set_int32_value(12345);
+ protobuf_unittest::TestAny message;
+ ASSERT_TRUE(message.mutable_any_value()->PackFrom(submessage));
+
+ std::string data = message.SerializeAsString();
+
+ ASSERT_TRUE(message.ParseFromString(data));
+ EXPECT_TRUE(message.has_any_value());
+ submessage.Clear();
+ ASSERT_TRUE(message.any_value().UnpackTo(&submessage));
+ EXPECT_EQ(12345, submessage.int32_value());
+}
+
+TEST(AnyTest, TestPackFromSerializationExceedsSizeLimit) {
+ protobuf_unittest::TestAny submessage;
+ submessage.mutable_text()->resize(INT_MAX, 'a');
+ protobuf_unittest::TestAny message;
+ EXPECT_FALSE(message.mutable_any_value()->PackFrom(submessage));
+}
+
+TEST(AnyTest, TestUnpackWithTypeMismatch) {
+ protobuf_unittest::TestAny payload;
+ payload.set_int32_value(13);
+ google::protobuf::Any any;
+ any.PackFrom(payload);
+
+ // Attempt to unpack into the wrong type.
+ protobuf_unittest::TestAllTypes dest;
+ EXPECT_FALSE(any.UnpackTo(&dest));
+}
+
+TEST(AnyTest, TestPackAndUnpackAny) {
+ // We can pack a Any message inside another Any message.
+ protobuf_unittest::TestAny submessage;
+ submessage.set_int32_value(12345);
+ google::protobuf::Any any;
+ any.PackFrom(submessage);
+ protobuf_unittest::TestAny message;
+ message.mutable_any_value()->PackFrom(any);
+
+ std::string data = message.SerializeAsString();
+
+ ASSERT_TRUE(message.ParseFromString(data));
+ EXPECT_TRUE(message.has_any_value());
+ any.Clear();
+ submessage.Clear();
+ ASSERT_TRUE(message.any_value().UnpackTo(&any));
+ ASSERT_TRUE(any.UnpackTo(&submessage));
+ EXPECT_EQ(12345, submessage.int32_value());
+}
+
+TEST(AnyTest, TestPackWithCustomTypeUrl) {
+ protobuf_unittest::TestAny submessage;
+ submessage.set_int32_value(12345);
+ google::protobuf::Any any;
+ // Pack with a custom type URL prefix.
+ any.PackFrom(submessage, "type.myservice.com");
+ EXPECT_EQ("type.myservice.com/protobuf_unittest.TestAny", any.type_url());
+ // Pack with a custom type URL prefix ending with '/'.
+ any.PackFrom(submessage, "type.myservice.com/");
+ EXPECT_EQ("type.myservice.com/protobuf_unittest.TestAny", any.type_url());
+ // Pack with an empty type URL prefix.
+ any.PackFrom(submessage, "");
+ EXPECT_EQ("/protobuf_unittest.TestAny", any.type_url());
+
+ // Test unpacking the type.
+ submessage.Clear();
+ EXPECT_TRUE(any.UnpackTo(&submessage));
+ EXPECT_EQ(12345, submessage.int32_value());
+}
+
+TEST(AnyTest, TestIs) {
+ protobuf_unittest::TestAny submessage;
+ submessage.set_int32_value(12345);
+ google::protobuf::Any any;
+ any.PackFrom(submessage);
+ ASSERT_TRUE(any.ParseFromString(any.SerializeAsString()));
+ EXPECT_TRUE(any.Is<protobuf_unittest::TestAny>());
+ EXPECT_FALSE(any.Is<google::protobuf::Any>());
+
+ protobuf_unittest::TestAny message;
+ message.mutable_any_value()->PackFrom(any);
+ ASSERT_TRUE(message.ParseFromString(message.SerializeAsString()));
+ EXPECT_FALSE(message.any_value().Is<protobuf_unittest::TestAny>());
+ EXPECT_TRUE(message.any_value().Is<google::protobuf::Any>());
+
+ any.set_type_url("/protobuf_unittest.TestAny");
+ EXPECT_TRUE(any.Is<protobuf_unittest::TestAny>());
+ // The type URL must contain at least one "/".
+ any.set_type_url("protobuf_unittest.TestAny");
+ EXPECT_FALSE(any.Is<protobuf_unittest::TestAny>());
+ // The type name after the slash must be fully qualified.
+ any.set_type_url("/TestAny");
+ EXPECT_FALSE(any.Is<protobuf_unittest::TestAny>());
+}
+
+TEST(AnyTest, MoveConstructor) {
+ protobuf_unittest::TestAny payload;
+ payload.set_int32_value(12345);
+
+ google::protobuf::Any src;
+ src.PackFrom(payload);
+
+ const char* type_url = src.type_url().data();
+
+ google::protobuf::Any dst(std::move(src));
+ EXPECT_EQ(type_url, dst.type_url().data());
+ payload.Clear();
+ ASSERT_TRUE(dst.UnpackTo(&payload));
+ EXPECT_EQ(12345, payload.int32_value());
+}
+
+TEST(AnyTest, MoveAssignment) {
+ protobuf_unittest::TestAny payload;
+ payload.set_int32_value(12345);
+
+ google::protobuf::Any src;
+ src.PackFrom(payload);
+
+ const char* type_url = src.type_url().data();
+
+ google::protobuf::Any dst;
+ dst = std::move(src);
+ EXPECT_EQ(type_url, dst.type_url().data());
+ payload.Clear();
+ ASSERT_TRUE(dst.UnpackTo(&payload));
+ EXPECT_EQ(12345, payload.int32_value());
+}
+
+
+} // namespace
+} // namespace protobuf
+} // namespace google
+
+#include <port_undef.inc>
diff --git a/NorthstarDedicatedTest/include/protobuf/any_test.proto b/NorthstarDedicatedTest/include/protobuf/any_test.proto
new file mode 100644
index 00000000..256035b4
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/any_test.proto
@@ -0,0 +1,44 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 protobuf_unittest;
+
+import "google/protobuf/any.proto";
+
+option java_outer_classname = "TestAnyProto";
+
+message TestAny {
+ int32 int32_value = 1;
+ google.protobuf.Any any_value = 2;
+ repeated google.protobuf.Any repeated_any_value = 3;
+ string text = 4;
+}
diff --git a/NorthstarDedicatedTest/include/protobuf/api.pb.cc b/NorthstarDedicatedTest/include/protobuf/api.pb.cc
new file mode 100644
index 00000000..a485aa1b
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/api.pb.cc
@@ -0,0 +1,1291 @@
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+// source: google/protobuf/api.proto
+
+#include <api.pb.h>
+
+#include <algorithm>
+
+#include <io/coded_stream.h>
+#include <extension_set.h>
+#include <wire_format_lite.h>
+#include <descriptor.h>
+#include <generated_message_reflection.h>
+#include <reflection_ops.h>
+#include <wire_format.h>
+// @@protoc_insertion_point(includes)
+#include <port_def.inc>
+
+PROTOBUF_PRAGMA_INIT_SEG
+PROTOBUF_NAMESPACE_OPEN
+constexpr Api::Api(
+ ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized)
+ : methods_()
+ , options_()
+ , mixins_()
+ , name_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string)
+ , version_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string)
+ , source_context_(nullptr)
+ , syntax_(0)
+{}
+struct ApiDefaultTypeInternal {
+ constexpr ApiDefaultTypeInternal()
+ : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {}
+ ~ApiDefaultTypeInternal() {}
+ union {
+ Api _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT ApiDefaultTypeInternal _Api_default_instance_;
+constexpr Method::Method(
+ ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized)
+ : options_()
+ , name_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string)
+ , request_type_url_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string)
+ , response_type_url_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string)
+ , request_streaming_(false)
+ , response_streaming_(false)
+ , syntax_(0)
+{}
+struct MethodDefaultTypeInternal {
+ constexpr MethodDefaultTypeInternal()
+ : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {}
+ ~MethodDefaultTypeInternal() {}
+ union {
+ Method _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT MethodDefaultTypeInternal _Method_default_instance_;
+constexpr Mixin::Mixin(
+ ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized)
+ : name_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string)
+ , root_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string){}
+struct MixinDefaultTypeInternal {
+ constexpr MixinDefaultTypeInternal()
+ : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {}
+ ~MixinDefaultTypeInternal() {}
+ union {
+ Mixin _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT MixinDefaultTypeInternal _Mixin_default_instance_;
+PROTOBUF_NAMESPACE_CLOSE
+static ::PROTOBUF_NAMESPACE_ID::Metadata file_level_metadata_google_2fprotobuf_2fapi_2eproto[3];
+static constexpr ::PROTOBUF_NAMESPACE_ID::EnumDescriptor const** file_level_enum_descriptors_google_2fprotobuf_2fapi_2eproto = nullptr;
+static constexpr ::PROTOBUF_NAMESPACE_ID::ServiceDescriptor const** file_level_service_descriptors_google_2fprotobuf_2fapi_2eproto = nullptr;
+
+const 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, name_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Api, methods_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Api, options_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Api, version_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Api, source_context_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Api, mixins_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Api, syntax_),
+ ~0u, // no _has_bits_
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Method, _internal_metadata_),
+ ~0u, // no _extensions_
+ ~0u, // no _oneof_case_
+ ~0u, // no _weak_field_map_
+ ~0u, // no _inlined_string_donated_
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Method, name_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Method, request_type_url_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Method, request_streaming_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Method, response_type_url_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Method, response_streaming_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Method, options_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Method, syntax_),
+ ~0u, // no _has_bits_
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Mixin, _internal_metadata_),
+ ~0u, // no _extensions_
+ ~0u, // no _oneof_case_
+ ~0u, // no _weak_field_map_
+ ~0u, // no _inlined_string_donated_
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Mixin, name_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Mixin, root_),
+};
+static const ::PROTOBUF_NAMESPACE_ID::internal::MigrationSchema schemas[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = {
+ { 0, -1, -1, sizeof(::PROTOBUF_NAMESPACE_ID::Api)},
+ { 13, -1, -1, sizeof(::PROTOBUF_NAMESPACE_ID::Method)},
+ { 26, -1, -1, sizeof(::PROTOBUF_NAMESPACE_ID::Mixin)},
+};
+
+static ::PROTOBUF_NAMESPACE_ID::Message const * const file_default_instances[] = {
+ reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_Api_default_instance_),
+ reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_Method_default_instance_),
+ reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_Mixin_default_instance_),
+};
+
+const char descriptor_table_protodef_google_2fprotobuf_2fapi_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) =
+ "\n\031google/protobuf/api.proto\022\017google.prot"
+ "obuf\032$google/protobuf/source_context.pro"
+ "to\032\032google/protobuf/type.proto\"\201\002\n\003Api\022\014"
+ "\n\004name\030\001 \001(\t\022(\n\007methods\030\002 \003(\0132\027.google.p"
+ "rotobuf.Method\022(\n\007options\030\003 \003(\0132\027.google"
+ ".protobuf.Option\022\017\n\007version\030\004 \001(\t\0226\n\016sou"
+ "rce_context\030\005 \001(\0132\036.google.protobuf.Sour"
+ "ceContext\022&\n\006mixins\030\006 \003(\0132\026.google.proto"
+ "buf.Mixin\022\'\n\006syntax\030\007 \001(\0162\027.google.proto"
+ "buf.Syntax\"\325\001\n\006Method\022\014\n\004name\030\001 \001(\t\022\030\n\020r"
+ "equest_type_url\030\002 \001(\t\022\031\n\021request_streami"
+ "ng\030\003 \001(\010\022\031\n\021response_type_url\030\004 \001(\t\022\032\n\022r"
+ "esponse_streaming\030\005 \001(\010\022(\n\007options\030\006 \003(\013"
+ "2\027.google.protobuf.Option\022\'\n\006syntax\030\007 \001("
+ "\0162\027.google.protobuf.Syntax\"#\n\005Mixin\022\014\n\004n"
+ "ame\030\001 \001(\t\022\014\n\004root\030\002 \001(\tBv\n\023com.google.pr"
+ "otobufB\010ApiProtoP\001Z,google.golang.org/pr"
+ "otobuf/types/known/apipb\242\002\003GPB\252\002\036Google."
+ "Protobuf.WellKnownTypesb\006proto3"
+ ;
+static const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable*const descriptor_table_google_2fprotobuf_2fapi_2eproto_deps[2] = {
+ &::descriptor_table_google_2fprotobuf_2fsource_5fcontext_2eproto,
+ &::descriptor_table_google_2fprotobuf_2ftype_2eproto,
+};
+static ::PROTOBUF_NAMESPACE_ID::internal::once_flag descriptor_table_google_2fprotobuf_2fapi_2eproto_once;
+const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fapi_2eproto = {
+ false, false, 751, descriptor_table_protodef_google_2fprotobuf_2fapi_2eproto, "google/protobuf/api.proto",
+ &descriptor_table_google_2fprotobuf_2fapi_2eproto_once, descriptor_table_google_2fprotobuf_2fapi_2eproto_deps, 2, 3,
+ schemas, file_default_instances, TableStruct_google_2fprotobuf_2fapi_2eproto::offsets,
+ file_level_metadata_google_2fprotobuf_2fapi_2eproto, file_level_enum_descriptors_google_2fprotobuf_2fapi_2eproto, file_level_service_descriptors_google_2fprotobuf_2fapi_2eproto,
+};
+PROTOBUF_ATTRIBUTE_WEAK const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable* descriptor_table_google_2fprotobuf_2fapi_2eproto_getter() {
+ return &descriptor_table_google_2fprotobuf_2fapi_2eproto;
+}
+
+// Force running AddDescriptors() at dynamic initialization time.
+PROTOBUF_ATTRIBUTE_INIT_PRIORITY static ::PROTOBUF_NAMESPACE_ID::internal::AddDescriptorsRunner dynamic_init_dummy_google_2fprotobuf_2fapi_2eproto(&descriptor_table_google_2fprotobuf_2fapi_2eproto);
+PROTOBUF_NAMESPACE_OPEN
+
+// ===================================================================
+
+class Api::_Internal {
+ public:
+ static const ::PROTOBUF_NAMESPACE_ID::SourceContext& source_context(const Api* msg);
+};
+
+const ::PROTOBUF_NAMESPACE_ID::SourceContext&
+Api::_Internal::source_context(const Api* msg) {
+ return *msg->source_context_;
+}
+void Api::clear_options() {
+ options_.Clear();
+}
+void Api::clear_source_context() {
+ if (GetArenaForAllocation() == nullptr && source_context_ != nullptr) {
+ delete source_context_;
+ }
+ source_context_ = nullptr;
+}
+Api::Api(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned)
+ : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned),
+ methods_(arena),
+ options_(arena),
+ mixins_(arena) {
+ SharedCtor();
+ if (!is_message_owned) {
+ RegisterArenaDtor(arena);
+ }
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.Api)
+}
+Api::Api(const Api& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message(),
+ methods_(from.methods_),
+ options_(from.options_),
+ mixins_(from.mixins_) {
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (!from._internal_name().empty()) {
+ name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_name(),
+ GetArenaForAllocation());
+ }
+ version_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ version_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (!from._internal_version().empty()) {
+ version_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_version(),
+ GetArenaForAllocation());
+ }
+ if (from._internal_has_source_context()) {
+ source_context_ = new ::PROTOBUF_NAMESPACE_ID::SourceContext(*from.source_context_);
+ } else {
+ source_context_ = nullptr;
+ }
+ syntax_ = from.syntax_;
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.Api)
+}
+
+inline void Api::SharedCtor() {
+name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+version_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ version_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+::memset(reinterpret_cast<char*>(this) + static_cast<size_t>(
+ reinterpret_cast<char*>(&source_context_) - reinterpret_cast<char*>(this)),
+ 0, static_cast<size_t>(reinterpret_cast<char*>(&syntax_) -
+ reinterpret_cast<char*>(&source_context_)) + sizeof(syntax_));
+}
+
+Api::~Api() {
+ // @@protoc_insertion_point(destructor:google.protobuf.Api)
+ if (GetArenaForAllocation() != nullptr) return;
+ SharedDtor();
+ _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+inline void Api::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+ name_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ version_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ if (this != internal_default_instance()) delete source_context_;
+}
+
+void Api::ArenaDtor(void* object) {
+ Api* _this = reinterpret_cast< Api* >(object);
+ (void)_this;
+}
+void Api::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) {
+}
+void Api::SetCachedSize(int size) const {
+ _cached_size_.Set(size);
+}
+
+void Api::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.Api)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ methods_.Clear();
+ options_.Clear();
+ mixins_.Clear();
+ name_.ClearToEmpty();
+ version_.ClearToEmpty();
+ if (GetArenaForAllocation() == nullptr && source_context_ != nullptr) {
+ delete source_context_;
+ }
+ source_context_ = nullptr;
+ syntax_ = 0;
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* Api::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag);
+ switch (tag >> 3) {
+ // string name = 1;
+ case 1:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 10)) {
+ auto str = _internal_mutable_name();
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx);
+ CHK_(::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.Api.name"));
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // repeated .google.protobuf.Method methods = 2;
+ case 2:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 18)) {
+ ptr -= 1;
+ do {
+ ptr += 1;
+ ptr = ctx->ParseMessage(_internal_add_methods(), ptr);
+ CHK_(ptr);
+ if (!ctx->DataAvailable(ptr)) break;
+ } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<18>(ptr));
+ } else
+ goto handle_unusual;
+ continue;
+ // repeated .google.protobuf.Option options = 3;
+ case 3:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 26)) {
+ ptr -= 1;
+ do {
+ ptr += 1;
+ ptr = ctx->ParseMessage(_internal_add_options(), ptr);
+ CHK_(ptr);
+ if (!ctx->DataAvailable(ptr)) break;
+ } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<26>(ptr));
+ } else
+ goto handle_unusual;
+ continue;
+ // string version = 4;
+ case 4:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 34)) {
+ auto str = _internal_mutable_version();
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx);
+ CHK_(::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.Api.version"));
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // .google.protobuf.SourceContext source_context = 5;
+ case 5:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 42)) {
+ ptr = ctx->ParseMessage(_internal_mutable_source_context(), ptr);
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // repeated .google.protobuf.Mixin mixins = 6;
+ case 6:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 50)) {
+ ptr -= 1;
+ do {
+ ptr += 1;
+ ptr = ctx->ParseMessage(_internal_add_mixins(), ptr);
+ CHK_(ptr);
+ if (!ctx->DataAvailable(ptr)) break;
+ } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<50>(ptr));
+ } else
+ goto handle_unusual;
+ continue;
+ // .google.protobuf.Syntax syntax = 7;
+ case 7:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 56)) {
+ 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 int i = 0,
+ n = static_cast<unsigned int>(this->_internal_methods_size()); i < n; i++) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(2, this->_internal_methods(i), target, stream);
+ }
+
+ // repeated .google.protobuf.Option options = 3;
+ for (unsigned int i = 0,
+ n = static_cast<unsigned int>(this->_internal_options_size()); i < n; i++) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(3, this->_internal_options(i), target, stream);
+ }
+
+ // string version = 4;
+ if (!this->_internal_version().empty()) {
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::VerifyUtf8String(
+ this->_internal_version().data(), static_cast<int>(this->_internal_version().length()),
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SERIALIZE,
+ "google.protobuf.Api.version");
+ target = stream->WriteStringMaybeAliased(
+ 4, this->_internal_version(), target);
+ }
+
+ // .google.protobuf.SourceContext source_context = 5;
+ if (this->_internal_has_source_context()) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(
+ 5, _Internal::source_context(this), target, stream);
+ }
+
+ // repeated .google.protobuf.Mixin mixins = 6;
+ for (unsigned int i = 0,
+ n = static_cast<unsigned int>(this->_internal_mixins_size()); i < n; i++) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(6, this->_internal_mixins(i), target, stream);
+ }
+
+ // .google.protobuf.Syntax syntax = 7;
+ if (this->_internal_syntax() != 0) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteEnumToArray(
+ 7, this->_internal_syntax(), target);
+ }
+
+ if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray(
+ _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Api)
+ return target;
+}
+
+size_t Api::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.Api)
+ size_t total_size = 0;
+
+ 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->methods_) {
+ total_size +=
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg);
+ }
+
+ // repeated .google.protobuf.Option options = 3;
+ total_size += 1UL * this->_internal_options_size();
+ for (const auto& msg : this->options_) {
+ total_size +=
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg);
+ }
+
+ // repeated .google.protobuf.Mixin mixins = 6;
+ total_size += 1UL * this->_internal_mixins_size();
+ for (const auto& msg : this->mixins_) {
+ total_size +=
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg);
+ }
+
+ // string name = 1;
+ if (!this->_internal_name().empty()) {
+ total_size += 1 +
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
+ this->_internal_name());
+ }
+
+ // string version = 4;
+ if (!this->_internal_version().empty()) {
+ total_size += 1 +
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
+ this->_internal_version());
+ }
+
+ // .google.protobuf.SourceContext source_context = 5;
+ if (this->_internal_has_source_context()) {
+ total_size += 1 +
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(
+ *source_context_);
+ }
+
+ // .google.protobuf.Syntax syntax = 7;
+ if (this->_internal_syntax() != 0) {
+ total_size += 1 +
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::EnumSize(this->_internal_syntax());
+ }
+
+ return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData Api::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck,
+ Api::MergeImpl
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*Api::GetClassData() const { return &_class_data_; }
+
+void Api::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to,
+ const ::PROTOBUF_NAMESPACE_ID::Message& from) {
+ static_cast<Api *>(to)->MergeFrom(
+ static_cast<const Api &>(from));
+}
+
+
+void Api::MergeFrom(const Api& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Api)
+ GOOGLE_DCHECK_NE(&from, this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ methods_.MergeFrom(from.methods_);
+ options_.MergeFrom(from.options_);
+ mixins_.MergeFrom(from.mixins_);
+ if (!from._internal_name().empty()) {
+ _internal_set_name(from._internal_name());
+ }
+ if (!from._internal_version().empty()) {
+ _internal_set_version(from._internal_version());
+ }
+ if (from._internal_has_source_context()) {
+ _internal_mutable_source_context()->::PROTOBUF_NAMESPACE_ID::SourceContext::MergeFrom(from._internal_source_context());
+ }
+ if (from._internal_syntax() != 0) {
+ _internal_set_syntax(from._internal_syntax());
+ }
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+}
+
+void Api::CopyFrom(const Api& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.Api)
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+bool Api::IsInitialized() const {
+ return true;
+}
+
+void Api::InternalSwap(Api* other) {
+ using std::swap;
+ auto* lhs_arena = GetArenaForAllocation();
+ auto* rhs_arena = other->GetArenaForAllocation();
+ _internal_metadata_.InternalSwap(&other->_internal_metadata_);
+ methods_.InternalSwap(&other->methods_);
+ options_.InternalSwap(&other->options_);
+ mixins_.InternalSwap(&other->mixins_);
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(),
+ &name_, lhs_arena,
+ &other->name_, rhs_arena
+ );
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(),
+ &version_, lhs_arena,
+ &other->version_, rhs_arena
+ );
+ ::PROTOBUF_NAMESPACE_ID::internal::memswap<
+ PROTOBUF_FIELD_OFFSET(Api, syntax_)
+ + sizeof(Api::syntax_)
+ - PROTOBUF_FIELD_OFFSET(Api, source_context_)>(
+ reinterpret_cast<char*>(&source_context_),
+ reinterpret_cast<char*>(&other->source_context_));
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata Api::GetMetadata() const {
+ return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(
+ &descriptor_table_google_2fprotobuf_2fapi_2eproto_getter, &descriptor_table_google_2fprotobuf_2fapi_2eproto_once,
+ file_level_metadata_google_2fprotobuf_2fapi_2eproto[0]);
+}
+
+// ===================================================================
+
+class Method::_Internal {
+ public:
+};
+
+void Method::clear_options() {
+ options_.Clear();
+}
+Method::Method(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned)
+ : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned),
+ options_(arena) {
+ SharedCtor();
+ if (!is_message_owned) {
+ RegisterArenaDtor(arena);
+ }
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.Method)
+}
+Method::Method(const Method& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message(),
+ options_(from.options_) {
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (!from._internal_name().empty()) {
+ name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_name(),
+ GetArenaForAllocation());
+ }
+ request_type_url_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ request_type_url_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (!from._internal_request_type_url().empty()) {
+ request_type_url_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_request_type_url(),
+ GetArenaForAllocation());
+ }
+ response_type_url_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ response_type_url_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (!from._internal_response_type_url().empty()) {
+ response_type_url_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_response_type_url(),
+ GetArenaForAllocation());
+ }
+ ::memcpy(&request_streaming_, &from.request_streaming_,
+ static_cast<size_t>(reinterpret_cast<char*>(&syntax_) -
+ reinterpret_cast<char*>(&request_streaming_)) + sizeof(syntax_));
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.Method)
+}
+
+inline void Method::SharedCtor() {
+name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+request_type_url_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ request_type_url_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+response_type_url_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ response_type_url_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+::memset(reinterpret_cast<char*>(this) + static_cast<size_t>(
+ reinterpret_cast<char*>(&request_streaming_) - reinterpret_cast<char*>(this)),
+ 0, static_cast<size_t>(reinterpret_cast<char*>(&syntax_) -
+ reinterpret_cast<char*>(&request_streaming_)) + sizeof(syntax_));
+}
+
+Method::~Method() {
+ // @@protoc_insertion_point(destructor:google.protobuf.Method)
+ if (GetArenaForAllocation() != nullptr) return;
+ SharedDtor();
+ _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+inline void Method::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+ name_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ request_type_url_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ response_type_url_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+}
+
+void Method::ArenaDtor(void* object) {
+ Method* _this = reinterpret_cast< Method* >(object);
+ (void)_this;
+}
+void Method::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) {
+}
+void Method::SetCachedSize(int size) const {
+ _cached_size_.Set(size);
+}
+
+void Method::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.Method)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ options_.Clear();
+ name_.ClearToEmpty();
+ request_type_url_.ClearToEmpty();
+ response_type_url_.ClearToEmpty();
+ ::memset(&request_streaming_, 0, static_cast<size_t>(
+ reinterpret_cast<char*>(&syntax_) -
+ reinterpret_cast<char*>(&request_streaming_)) + sizeof(syntax_));
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* Method::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag);
+ switch (tag >> 3) {
+ // string name = 1;
+ case 1:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 10)) {
+ auto str = _internal_mutable_name();
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx);
+ CHK_(::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.Method.name"));
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // string request_type_url = 2;
+ case 2:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 18)) {
+ auto str = _internal_mutable_request_type_url();
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx);
+ CHK_(::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.Method.request_type_url"));
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // bool request_streaming = 3;
+ case 3:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 24)) {
+ request_streaming_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr);
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // string response_type_url = 4;
+ case 4:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 34)) {
+ auto str = _internal_mutable_response_type_url();
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx);
+ CHK_(::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.Method.response_type_url"));
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // bool response_streaming = 5;
+ case 5:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 40)) {
+ response_streaming_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr);
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // repeated .google.protobuf.Option options = 6;
+ case 6:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 50)) {
+ ptr -= 1;
+ do {
+ ptr += 1;
+ ptr = ctx->ParseMessage(_internal_add_options(), ptr);
+ CHK_(ptr);
+ if (!ctx->DataAvailable(ptr)) break;
+ } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<50>(ptr));
+ } else
+ goto handle_unusual;
+ continue;
+ // .google.protobuf.Syntax syntax = 7;
+ case 7:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 56)) {
+ 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 = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBoolToArray(3, this->_internal_request_streaming(), target);
+ }
+
+ // string response_type_url = 4;
+ if (!this->_internal_response_type_url().empty()) {
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::VerifyUtf8String(
+ this->_internal_response_type_url().data(), static_cast<int>(this->_internal_response_type_url().length()),
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SERIALIZE,
+ "google.protobuf.Method.response_type_url");
+ target = stream->WriteStringMaybeAliased(
+ 4, this->_internal_response_type_url(), target);
+ }
+
+ // bool response_streaming = 5;
+ if (this->_internal_response_streaming() != 0) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBoolToArray(5, this->_internal_response_streaming(), target);
+ }
+
+ // repeated .google.protobuf.Option options = 6;
+ for (unsigned int i = 0,
+ n = static_cast<unsigned int>(this->_internal_options_size()); i < n; i++) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(6, this->_internal_options(i), target, stream);
+ }
+
+ // .google.protobuf.Syntax syntax = 7;
+ if (this->_internal_syntax() != 0) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteEnumToArray(
+ 7, this->_internal_syntax(), target);
+ }
+
+ if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray(
+ _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Method)
+ return target;
+}
+
+size_t Method::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.Method)
+ size_t total_size = 0;
+
+ 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->options_) {
+ total_size +=
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg);
+ }
+
+ // string name = 1;
+ if (!this->_internal_name().empty()) {
+ total_size += 1 +
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
+ this->_internal_name());
+ }
+
+ // string request_type_url = 2;
+ if (!this->_internal_request_type_url().empty()) {
+ total_size += 1 +
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
+ this->_internal_request_type_url());
+ }
+
+ // string response_type_url = 4;
+ if (!this->_internal_response_type_url().empty()) {
+ total_size += 1 +
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
+ this->_internal_response_type_url());
+ }
+
+ // bool request_streaming = 3;
+ if (this->_internal_request_streaming() != 0) {
+ total_size += 1 + 1;
+ }
+
+ // bool response_streaming = 5;
+ if (this->_internal_response_streaming() != 0) {
+ total_size += 1 + 1;
+ }
+
+ // .google.protobuf.Syntax syntax = 7;
+ if (this->_internal_syntax() != 0) {
+ total_size += 1 +
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::EnumSize(this->_internal_syntax());
+ }
+
+ return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData Method::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck,
+ Method::MergeImpl
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*Method::GetClassData() const { return &_class_data_; }
+
+void Method::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to,
+ const ::PROTOBUF_NAMESPACE_ID::Message& from) {
+ static_cast<Method *>(to)->MergeFrom(
+ static_cast<const Method &>(from));
+}
+
+
+void Method::MergeFrom(const Method& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Method)
+ GOOGLE_DCHECK_NE(&from, this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ options_.MergeFrom(from.options_);
+ if (!from._internal_name().empty()) {
+ _internal_set_name(from._internal_name());
+ }
+ if (!from._internal_request_type_url().empty()) {
+ _internal_set_request_type_url(from._internal_request_type_url());
+ }
+ if (!from._internal_response_type_url().empty()) {
+ _internal_set_response_type_url(from._internal_response_type_url());
+ }
+ if (from._internal_request_streaming() != 0) {
+ _internal_set_request_streaming(from._internal_request_streaming());
+ }
+ if (from._internal_response_streaming() != 0) {
+ _internal_set_response_streaming(from._internal_response_streaming());
+ }
+ if (from._internal_syntax() != 0) {
+ _internal_set_syntax(from._internal_syntax());
+ }
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+}
+
+void Method::CopyFrom(const Method& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.Method)
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+bool Method::IsInitialized() const {
+ return true;
+}
+
+void Method::InternalSwap(Method* other) {
+ using std::swap;
+ auto* lhs_arena = GetArenaForAllocation();
+ auto* rhs_arena = other->GetArenaForAllocation();
+ _internal_metadata_.InternalSwap(&other->_internal_metadata_);
+ options_.InternalSwap(&other->options_);
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(),
+ &name_, lhs_arena,
+ &other->name_, rhs_arena
+ );
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(),
+ &request_type_url_, lhs_arena,
+ &other->request_type_url_, rhs_arena
+ );
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(),
+ &response_type_url_, lhs_arena,
+ &other->response_type_url_, rhs_arena
+ );
+ ::PROTOBUF_NAMESPACE_ID::internal::memswap<
+ PROTOBUF_FIELD_OFFSET(Method, syntax_)
+ + sizeof(Method::syntax_)
+ - PROTOBUF_FIELD_OFFSET(Method, request_streaming_)>(
+ reinterpret_cast<char*>(&request_streaming_),
+ reinterpret_cast<char*>(&other->request_streaming_));
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata Method::GetMetadata() const {
+ return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(
+ &descriptor_table_google_2fprotobuf_2fapi_2eproto_getter, &descriptor_table_google_2fprotobuf_2fapi_2eproto_once,
+ file_level_metadata_google_2fprotobuf_2fapi_2eproto[1]);
+}
+
+// ===================================================================
+
+class Mixin::_Internal {
+ public:
+};
+
+Mixin::Mixin(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned)
+ : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) {
+ SharedCtor();
+ if (!is_message_owned) {
+ RegisterArenaDtor(arena);
+ }
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.Mixin)
+}
+Mixin::Mixin(const Mixin& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message() {
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (!from._internal_name().empty()) {
+ name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_name(),
+ GetArenaForAllocation());
+ }
+ root_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ root_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (!from._internal_root().empty()) {
+ root_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_root(),
+ GetArenaForAllocation());
+ }
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.Mixin)
+}
+
+inline void Mixin::SharedCtor() {
+name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+root_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ root_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+}
+
+Mixin::~Mixin() {
+ // @@protoc_insertion_point(destructor:google.protobuf.Mixin)
+ if (GetArenaForAllocation() != nullptr) return;
+ SharedDtor();
+ _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+inline void Mixin::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+ name_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ root_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+}
+
+void Mixin::ArenaDtor(void* object) {
+ Mixin* _this = reinterpret_cast< Mixin* >(object);
+ (void)_this;
+}
+void Mixin::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) {
+}
+void Mixin::SetCachedSize(int size) const {
+ _cached_size_.Set(size);
+}
+
+void Mixin::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.Mixin)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ name_.ClearToEmpty();
+ root_.ClearToEmpty();
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* Mixin::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag);
+ switch (tag >> 3) {
+ // string name = 1;
+ case 1:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 10)) {
+ auto str = _internal_mutable_name();
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx);
+ CHK_(::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.Mixin.name"));
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // string root = 2;
+ case 2:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 18)) {
+ auto str = _internal_mutable_root();
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx);
+ CHK_(::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.Mixin.root"));
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ default:
+ goto handle_unusual;
+ } // switch
+ handle_unusual:
+ if ((tag == 0) || ((tag & 7) == 4)) {
+ CHK_(ptr);
+ ctx->SetLastTag(tag);
+ goto message_done;
+ }
+ ptr = UnknownFieldParse(
+ tag,
+ _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(),
+ ptr, ctx);
+ CHK_(ptr != nullptr);
+ } // while
+message_done:
+ return ptr;
+failure:
+ ptr = nullptr;
+ goto message_done;
+#undef CHK_
+}
+
+uint8_t* Mixin::_InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const {
+ // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Mixin)
+ 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 = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray(
+ _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Mixin)
+ return target;
+}
+
+size_t Mixin::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.Mixin)
+ size_t total_size = 0;
+
+ 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, &_cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData Mixin::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck,
+ Mixin::MergeImpl
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*Mixin::GetClassData() const { return &_class_data_; }
+
+void Mixin::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to,
+ const ::PROTOBUF_NAMESPACE_ID::Message& from) {
+ static_cast<Mixin *>(to)->MergeFrom(
+ static_cast<const Mixin &>(from));
+}
+
+
+void Mixin::MergeFrom(const Mixin& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Mixin)
+ GOOGLE_DCHECK_NE(&from, this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ if (!from._internal_name().empty()) {
+ _internal_set_name(from._internal_name());
+ }
+ if (!from._internal_root().empty()) {
+ _internal_set_root(from._internal_root());
+ }
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+}
+
+void Mixin::CopyFrom(const Mixin& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.Mixin)
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+bool Mixin::IsInitialized() const {
+ return true;
+}
+
+void Mixin::InternalSwap(Mixin* other) {
+ using std::swap;
+ auto* lhs_arena = GetArenaForAllocation();
+ auto* rhs_arena = other->GetArenaForAllocation();
+ _internal_metadata_.InternalSwap(&other->_internal_metadata_);
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(),
+ &name_, lhs_arena,
+ &other->name_, rhs_arena
+ );
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(),
+ &root_, lhs_arena,
+ &other->root_, rhs_arena
+ );
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata Mixin::GetMetadata() const {
+ return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(
+ &descriptor_table_google_2fprotobuf_2fapi_2eproto_getter, &descriptor_table_google_2fprotobuf_2fapi_2eproto_once,
+ file_level_metadata_google_2fprotobuf_2fapi_2eproto[2]);
+}
+
+// @@protoc_insertion_point(namespace_scope)
+PROTOBUF_NAMESPACE_CLOSE
+PROTOBUF_NAMESPACE_OPEN
+template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::Api* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::Api >(Arena* arena) {
+ return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::Api >(arena);
+}
+template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::Method* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::Method >(Arena* arena) {
+ return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::Method >(arena);
+}
+template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::Mixin* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::Mixin >(Arena* arena) {
+ return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::Mixin >(arena);
+}
+PROTOBUF_NAMESPACE_CLOSE
+
+// @@protoc_insertion_point(global_scope)
+#include <port_undef.inc>
diff --git a/NorthstarDedicatedTest/include/protobuf/api.pb.h b/NorthstarDedicatedTest/include/protobuf/api.pb.h
new file mode 100644
index 00000000..3980f677
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/api.pb.h
@@ -0,0 +1,1448 @@
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+// source: google/protobuf/api.proto
+
+#ifndef GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fapi_2eproto
+#define GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fapi_2eproto
+
+#include <limits>
+#include <string>
+
+#include <port_def.inc>
+#if PROTOBUF_VERSION < 3019000
+#error This file was generated by a newer version of protoc which is
+#error incompatible with your Protocol Buffer headers. Please update
+#error your headers.
+#endif
+#if 3019004 < 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 <port_undef.inc>
+#include <io/coded_stream.h>
+#include <arena.h>
+#include <arenastring.h>
+#include <generated_message_table_driven.h>
+#include <generated_message_util.h>
+#include <metadata_lite.h>
+#include <generated_message_reflection.h>
+#include <message.h>
+#include <repeated_field.h> // IWYU pragma: export
+#include <extension_set.h> // IWYU pragma: export
+#include <unknown_field_set.h>
+#include <source_context.pb.h>
+#include <type.pb.h>
+// @@protoc_insertion_point(includes)
+#include <port_def.inc>
+#define PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fapi_2eproto PROTOBUF_EXPORT
+PROTOBUF_NAMESPACE_OPEN
+namespace internal {
+class AnyMetadata;
+} // namespace internal
+PROTOBUF_NAMESPACE_CLOSE
+
+// Internal implementation detail -- do not use these members.
+struct PROTOBUF_EXPORT TableStruct_google_2fprotobuf_2fapi_2eproto {
+ static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTableField entries[]
+ PROTOBUF_SECTION_VARIABLE(protodesc_cold);
+ static const ::PROTOBUF_NAMESPACE_ID::internal::AuxiliaryParseTableField aux[]
+ PROTOBUF_SECTION_VARIABLE(protodesc_cold);
+ static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTable schema[3]
+ PROTOBUF_SECTION_VARIABLE(protodesc_cold);
+ static const ::PROTOBUF_NAMESPACE_ID::internal::FieldMetadata field_metadata[];
+ static const ::PROTOBUF_NAMESPACE_ID::internal::SerializationTable serialization_table[];
+ static const 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 constexpr Api(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
+
+ Api(const Api& from);
+ Api(Api&& from) noexcept
+ : Api() {
+ *this = ::std::move(from);
+ }
+
+ inline Api& operator=(const Api& from) {
+ CopyFrom(from);
+ return *this;
+ }
+ inline Api& operator=(Api&& from) noexcept {
+ if (this == &from) return *this;
+ if (GetOwningArena() == from.GetOwningArena()
+ #ifdef PROTOBUF_FORCE_COPY_IN_MOVE
+ && GetOwningArena() != nullptr
+ #endif // !PROTOBUF_FORCE_COPY_IN_MOVE
+ ) {
+ InternalSwap(&from);
+ } else {
+ CopyFrom(from);
+ }
+ return *this;
+ }
+
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
+ return GetDescriptor();
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
+ return default_instance().GetMetadata().descriptor;
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
+ return default_instance().GetMetadata().reflection;
+ }
+ static const Api& default_instance() {
+ return *internal_default_instance();
+ }
+ static inline const Api* internal_default_instance() {
+ return reinterpret_cast<const Api*>(
+ &_Api_default_instance_);
+ }
+ static constexpr int kIndexInFileMessages =
+ 0;
+
+ friend void swap(Api& a, Api& b) {
+ a.Swap(&b);
+ }
+ inline void Swap(Api* other) {
+ if (other == this) return;
+ #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() != nullptr &&
+ GetOwningArena() == other->GetOwningArena()) {
+ #else // PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() == other->GetOwningArena()) {
+ #endif // !PROTOBUF_FORCE_COPY_IN_SWAP
+ InternalSwap(other);
+ } else {
+ ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
+ }
+ }
+ void UnsafeArenaSwap(Api* other) {
+ if (other == this) return;
+ GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena());
+ InternalSwap(other);
+ }
+
+ // implements Message ----------------------------------------------
+
+ Api* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
+ return CreateMaybeMessage<Api>(arena);
+ }
+ using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
+ void CopyFrom(const Api& from);
+ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
+ void MergeFrom(const Api& from);
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from);
+ public:
+ PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+ bool IsInitialized() const final;
+
+ size_t ByteSizeLong() const final;
+ const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
+ uint8_t* _InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
+ int GetCachedSize() const final { return _cached_size_.Get(); }
+
+ private:
+ void SharedCtor();
+ void SharedDtor();
+ void SetCachedSize(int size) const final;
+ void InternalSwap(Api* other);
+
+ private:
+ friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
+ static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
+ return "google.protobuf.Api";
+ }
+ protected:
+ explicit Api(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned = false);
+ private:
+ static void ArenaDtor(void* object);
+ inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
+ public:
+
+ static const ClassData _class_data_;
+ const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;
+
+ ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;
+
+ // nested types ----------------------------------------------------
+
+ // accessors -------------------------------------------------------
+
+ enum : int {
+ kMethodsFieldNumber = 2,
+ kOptionsFieldNumber = 3,
+ kMixinsFieldNumber = 6,
+ kNameFieldNumber = 1,
+ kVersionFieldNumber = 4,
+ kSourceContextFieldNumber = 5,
+ kSyntaxFieldNumber = 7,
+ };
+ // repeated .google.protobuf.Method methods = 2;
+ int methods_size() const;
+ private:
+ int _internal_methods_size() const;
+ public:
+ void clear_methods();
+ ::PROTOBUF_NAMESPACE_ID::Method* mutable_methods(int index);
+ ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Method >*
+ mutable_methods();
+ private:
+ const ::PROTOBUF_NAMESPACE_ID::Method& _internal_methods(int index) const;
+ ::PROTOBUF_NAMESPACE_ID::Method* _internal_add_methods();
+ public:
+ const ::PROTOBUF_NAMESPACE_ID::Method& methods(int index) const;
+ ::PROTOBUF_NAMESPACE_ID::Method* add_methods();
+ const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Method >&
+ methods() const;
+
+ // repeated .google.protobuf.Option options = 3;
+ int options_size() const;
+ private:
+ int _internal_options_size() const;
+ public:
+ void clear_options();
+ ::PROTOBUF_NAMESPACE_ID::Option* mutable_options(int index);
+ ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Option >*
+ mutable_options();
+ private:
+ const ::PROTOBUF_NAMESPACE_ID::Option& _internal_options(int index) const;
+ ::PROTOBUF_NAMESPACE_ID::Option* _internal_add_options();
+ public:
+ const ::PROTOBUF_NAMESPACE_ID::Option& options(int index) const;
+ ::PROTOBUF_NAMESPACE_ID::Option* add_options();
+ const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Option >&
+ options() const;
+
+ // repeated .google.protobuf.Mixin mixins = 6;
+ int mixins_size() const;
+ private:
+ int _internal_mixins_size() const;
+ public:
+ void clear_mixins();
+ ::PROTOBUF_NAMESPACE_ID::Mixin* mutable_mixins(int index);
+ ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Mixin >*
+ mutable_mixins();
+ private:
+ const ::PROTOBUF_NAMESPACE_ID::Mixin& _internal_mixins(int index) const;
+ ::PROTOBUF_NAMESPACE_ID::Mixin* _internal_add_mixins();
+ public:
+ const ::PROTOBUF_NAMESPACE_ID::Mixin& mixins(int index) const;
+ ::PROTOBUF_NAMESPACE_ID::Mixin* add_mixins();
+ const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Mixin >&
+ mixins() const;
+
+ // string name = 1;
+ void clear_name();
+ const 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_;
+ ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Method > methods_;
+ ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Option > options_;
+ ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Mixin > mixins_;
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr name_;
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr version_;
+ ::PROTOBUF_NAMESPACE_ID::SourceContext* source_context_;
+ int syntax_;
+ mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
+ friend struct ::TableStruct_google_2fprotobuf_2fapi_2eproto;
+};
+// -------------------------------------------------------------------
+
+class PROTOBUF_EXPORT Method final :
+ public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Method) */ {
+ public:
+ inline Method() : Method(nullptr) {}
+ ~Method() override;
+ explicit constexpr Method(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
+
+ Method(const Method& from);
+ Method(Method&& from) noexcept
+ : Method() {
+ *this = ::std::move(from);
+ }
+
+ inline Method& operator=(const Method& from) {
+ CopyFrom(from);
+ return *this;
+ }
+ inline Method& operator=(Method&& from) noexcept {
+ if (this == &from) return *this;
+ if (GetOwningArena() == from.GetOwningArena()
+ #ifdef PROTOBUF_FORCE_COPY_IN_MOVE
+ && GetOwningArena() != nullptr
+ #endif // !PROTOBUF_FORCE_COPY_IN_MOVE
+ ) {
+ InternalSwap(&from);
+ } else {
+ CopyFrom(from);
+ }
+ return *this;
+ }
+
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
+ return GetDescriptor();
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
+ return default_instance().GetMetadata().descriptor;
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
+ return default_instance().GetMetadata().reflection;
+ }
+ static const Method& default_instance() {
+ return *internal_default_instance();
+ }
+ static inline const Method* internal_default_instance() {
+ return reinterpret_cast<const Method*>(
+ &_Method_default_instance_);
+ }
+ static constexpr int kIndexInFileMessages =
+ 1;
+
+ friend void swap(Method& a, Method& b) {
+ a.Swap(&b);
+ }
+ inline void Swap(Method* other) {
+ if (other == this) return;
+ #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() != nullptr &&
+ GetOwningArena() == other->GetOwningArena()) {
+ #else // PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() == other->GetOwningArena()) {
+ #endif // !PROTOBUF_FORCE_COPY_IN_SWAP
+ InternalSwap(other);
+ } else {
+ ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
+ }
+ }
+ void UnsafeArenaSwap(Method* other) {
+ if (other == this) return;
+ GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena());
+ InternalSwap(other);
+ }
+
+ // implements Message ----------------------------------------------
+
+ Method* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
+ return CreateMaybeMessage<Method>(arena);
+ }
+ using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
+ void CopyFrom(const Method& from);
+ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
+ void MergeFrom(const Method& from);
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from);
+ public:
+ PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+ bool IsInitialized() const final;
+
+ size_t ByteSizeLong() const final;
+ const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
+ uint8_t* _InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
+ int GetCachedSize() const final { return _cached_size_.Get(); }
+
+ private:
+ void SharedCtor();
+ void SharedDtor();
+ void SetCachedSize(int size) const final;
+ void InternalSwap(Method* other);
+
+ private:
+ friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
+ static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
+ return "google.protobuf.Method";
+ }
+ protected:
+ explicit Method(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned = false);
+ private:
+ static void ArenaDtor(void* object);
+ inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
+ public:
+
+ static const ClassData _class_data_;
+ const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;
+
+ ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;
+
+ // nested types ----------------------------------------------------
+
+ // accessors -------------------------------------------------------
+
+ enum : int {
+ kOptionsFieldNumber = 6,
+ kNameFieldNumber = 1,
+ kRequestTypeUrlFieldNumber = 2,
+ kResponseTypeUrlFieldNumber = 4,
+ kRequestStreamingFieldNumber = 3,
+ kResponseStreamingFieldNumber = 5,
+ kSyntaxFieldNumber = 7,
+ };
+ // repeated .google.protobuf.Option options = 6;
+ int options_size() const;
+ private:
+ int _internal_options_size() const;
+ public:
+ void clear_options();
+ ::PROTOBUF_NAMESPACE_ID::Option* mutable_options(int index);
+ ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Option >*
+ mutable_options();
+ private:
+ const ::PROTOBUF_NAMESPACE_ID::Option& _internal_options(int index) const;
+ ::PROTOBUF_NAMESPACE_ID::Option* _internal_add_options();
+ public:
+ const ::PROTOBUF_NAMESPACE_ID::Option& options(int index) const;
+ ::PROTOBUF_NAMESPACE_ID::Option* add_options();
+ const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Option >&
+ options() const;
+
+ // string name = 1;
+ void clear_name();
+ const 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_;
+ ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Option > options_;
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr name_;
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr request_type_url_;
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr response_type_url_;
+ bool request_streaming_;
+ bool response_streaming_;
+ int syntax_;
+ mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
+ friend struct ::TableStruct_google_2fprotobuf_2fapi_2eproto;
+};
+// -------------------------------------------------------------------
+
+class PROTOBUF_EXPORT Mixin final :
+ public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Mixin) */ {
+ public:
+ inline Mixin() : Mixin(nullptr) {}
+ ~Mixin() override;
+ explicit constexpr Mixin(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
+
+ Mixin(const Mixin& from);
+ Mixin(Mixin&& from) noexcept
+ : Mixin() {
+ *this = ::std::move(from);
+ }
+
+ inline Mixin& operator=(const Mixin& from) {
+ CopyFrom(from);
+ return *this;
+ }
+ inline Mixin& operator=(Mixin&& from) noexcept {
+ if (this == &from) return *this;
+ if (GetOwningArena() == from.GetOwningArena()
+ #ifdef PROTOBUF_FORCE_COPY_IN_MOVE
+ && GetOwningArena() != nullptr
+ #endif // !PROTOBUF_FORCE_COPY_IN_MOVE
+ ) {
+ InternalSwap(&from);
+ } else {
+ CopyFrom(from);
+ }
+ return *this;
+ }
+
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
+ return GetDescriptor();
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
+ return default_instance().GetMetadata().descriptor;
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
+ return default_instance().GetMetadata().reflection;
+ }
+ static const Mixin& default_instance() {
+ return *internal_default_instance();
+ }
+ static inline const Mixin* internal_default_instance() {
+ return reinterpret_cast<const Mixin*>(
+ &_Mixin_default_instance_);
+ }
+ static constexpr int kIndexInFileMessages =
+ 2;
+
+ friend void swap(Mixin& a, Mixin& b) {
+ a.Swap(&b);
+ }
+ inline void Swap(Mixin* other) {
+ if (other == this) return;
+ #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() != nullptr &&
+ GetOwningArena() == other->GetOwningArena()) {
+ #else // PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() == other->GetOwningArena()) {
+ #endif // !PROTOBUF_FORCE_COPY_IN_SWAP
+ InternalSwap(other);
+ } else {
+ ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
+ }
+ }
+ void UnsafeArenaSwap(Mixin* other) {
+ if (other == this) return;
+ GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena());
+ InternalSwap(other);
+ }
+
+ // implements Message ----------------------------------------------
+
+ Mixin* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
+ return CreateMaybeMessage<Mixin>(arena);
+ }
+ using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
+ void CopyFrom(const Mixin& from);
+ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
+ void MergeFrom(const Mixin& from);
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from);
+ public:
+ PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+ bool IsInitialized() const final;
+
+ size_t ByteSizeLong() const final;
+ const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
+ uint8_t* _InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
+ int GetCachedSize() const final { return _cached_size_.Get(); }
+
+ private:
+ void SharedCtor();
+ void SharedDtor();
+ void SetCachedSize(int size) const final;
+ void InternalSwap(Mixin* other);
+
+ private:
+ friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
+ static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
+ return "google.protobuf.Mixin";
+ }
+ protected:
+ explicit Mixin(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned = false);
+ private:
+ static void ArenaDtor(void* object);
+ inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
+ public:
+
+ static const ClassData _class_data_;
+ const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;
+
+ ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;
+
+ // nested types ----------------------------------------------------
+
+ // accessors -------------------------------------------------------
+
+ enum : int {
+ kNameFieldNumber = 1,
+ kRootFieldNumber = 2,
+ };
+ // string name = 1;
+ void clear_name();
+ const 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_;
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr name_;
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr root_;
+ mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
+ friend struct ::TableStruct_google_2fprotobuf_2fapi_2eproto;
+};
+// ===================================================================
+
+
+// ===================================================================
+
+#ifdef __GNUC__
+ #pragma GCC diagnostic push
+ #pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#endif // __GNUC__
+// Api
+
+// string name = 1;
+inline void Api::clear_name() {
+ name_.ClearToEmpty();
+}
+inline const 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) {
+
+ name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, 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 name_.Get();
+}
+inline void Api::_internal_set_name(const std::string& value) {
+
+ name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation());
+}
+inline std::string* Api::_internal_mutable_name() {
+
+ return name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation());
+}
+inline std::string* Api::release_name() {
+ // @@protoc_insertion_point(field_release:google.protobuf.Api.name)
+ return name_.Release(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
+}
+inline void Api::set_allocated_name(std::string* name) {
+ if (name != nullptr) {
+
+ } else {
+
+ }
+ name_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), name,
+ GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (name_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
+ name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.Api.name)
+}
+
+// repeated .google.protobuf.Method methods = 2;
+inline int Api::_internal_methods_size() const {
+ return methods_.size();
+}
+inline int Api::methods_size() const {
+ return _internal_methods_size();
+}
+inline void Api::clear_methods() {
+ methods_.Clear();
+}
+inline ::PROTOBUF_NAMESPACE_ID::Method* Api::mutable_methods(int index) {
+ // @@protoc_insertion_point(field_mutable:google.protobuf.Api.methods)
+ return methods_.Mutable(index);
+}
+inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Method >*
+Api::mutable_methods() {
+ // @@protoc_insertion_point(field_mutable_list:google.protobuf.Api.methods)
+ return &methods_;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::Method& Api::_internal_methods(int index) const {
+ return methods_.Get(index);
+}
+inline const ::PROTOBUF_NAMESPACE_ID::Method& Api::methods(int index) const {
+ // @@protoc_insertion_point(field_get:google.protobuf.Api.methods)
+ return _internal_methods(index);
+}
+inline ::PROTOBUF_NAMESPACE_ID::Method* Api::_internal_add_methods() {
+ return methods_.Add();
+}
+inline ::PROTOBUF_NAMESPACE_ID::Method* Api::add_methods() {
+ ::PROTOBUF_NAMESPACE_ID::Method* _add = _internal_add_methods();
+ // @@protoc_insertion_point(field_add:google.protobuf.Api.methods)
+ return _add;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Method >&
+Api::methods() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.Api.methods)
+ return methods_;
+}
+
+// repeated .google.protobuf.Option options = 3;
+inline int Api::_internal_options_size() const {
+ return options_.size();
+}
+inline int Api::options_size() const {
+ return _internal_options_size();
+}
+inline ::PROTOBUF_NAMESPACE_ID::Option* Api::mutable_options(int index) {
+ // @@protoc_insertion_point(field_mutable:google.protobuf.Api.options)
+ return options_.Mutable(index);
+}
+inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Option >*
+Api::mutable_options() {
+ // @@protoc_insertion_point(field_mutable_list:google.protobuf.Api.options)
+ return &options_;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::Option& Api::_internal_options(int index) const {
+ return options_.Get(index);
+}
+inline const ::PROTOBUF_NAMESPACE_ID::Option& Api::options(int index) const {
+ // @@protoc_insertion_point(field_get:google.protobuf.Api.options)
+ return _internal_options(index);
+}
+inline ::PROTOBUF_NAMESPACE_ID::Option* Api::_internal_add_options() {
+ return options_.Add();
+}
+inline ::PROTOBUF_NAMESPACE_ID::Option* Api::add_options() {
+ ::PROTOBUF_NAMESPACE_ID::Option* _add = _internal_add_options();
+ // @@protoc_insertion_point(field_add:google.protobuf.Api.options)
+ return _add;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Option >&
+Api::options() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.Api.options)
+ return options_;
+}
+
+// string version = 4;
+inline void Api::clear_version() {
+ version_.ClearToEmpty();
+}
+inline const 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) {
+
+ version_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, 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 version_.Get();
+}
+inline void Api::_internal_set_version(const std::string& value) {
+
+ version_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation());
+}
+inline std::string* Api::_internal_mutable_version() {
+
+ return version_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation());
+}
+inline std::string* Api::release_version() {
+ // @@protoc_insertion_point(field_release:google.protobuf.Api.version)
+ return version_.Release(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
+}
+inline void Api::set_allocated_version(std::string* version) {
+ if (version != nullptr) {
+
+ } else {
+
+ }
+ version_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), version,
+ GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (version_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
+ version_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.Api.version)
+}
+
+// .google.protobuf.SourceContext source_context = 5;
+inline bool Api::_internal_has_source_context() const {
+ return this != internal_default_instance() && source_context_ != nullptr;
+}
+inline bool Api::has_source_context() const {
+ return _internal_has_source_context();
+}
+inline const ::PROTOBUF_NAMESPACE_ID::SourceContext& Api::_internal_source_context() const {
+ const ::PROTOBUF_NAMESPACE_ID::SourceContext* p = source_context_;
+ return p != nullptr ? *p : reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::SourceContext&>(
+ ::PROTOBUF_NAMESPACE_ID::_SourceContext_default_instance_);
+}
+inline const ::PROTOBUF_NAMESPACE_ID::SourceContext& Api::source_context() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.Api.source_context)
+ return _internal_source_context();
+}
+inline void Api::unsafe_arena_set_allocated_source_context(
+ ::PROTOBUF_NAMESPACE_ID::SourceContext* source_context) {
+ if (GetArenaForAllocation() == nullptr) {
+ delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(source_context_);
+ }
+ source_context_ = source_context;
+ if (source_context) {
+
+ } else {
+
+ }
+ // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.Api.source_context)
+}
+inline ::PROTOBUF_NAMESPACE_ID::SourceContext* Api::release_source_context() {
+
+ ::PROTOBUF_NAMESPACE_ID::SourceContext* temp = source_context_;
+ source_context_ = nullptr;
+#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE
+ auto* old = reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(temp);
+ temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
+ if (GetArenaForAllocation() == nullptr) { delete old; }
+#else // PROTOBUF_FORCE_COPY_IN_RELEASE
+ if (GetArenaForAllocation() != nullptr) {
+ temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
+ }
+#endif // !PROTOBUF_FORCE_COPY_IN_RELEASE
+ return temp;
+}
+inline ::PROTOBUF_NAMESPACE_ID::SourceContext* Api::unsafe_arena_release_source_context() {
+ // @@protoc_insertion_point(field_release:google.protobuf.Api.source_context)
+
+ ::PROTOBUF_NAMESPACE_ID::SourceContext* temp = source_context_;
+ source_context_ = nullptr;
+ return temp;
+}
+inline ::PROTOBUF_NAMESPACE_ID::SourceContext* Api::_internal_mutable_source_context() {
+
+ if (source_context_ == nullptr) {
+ auto* p = CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::SourceContext>(GetArenaForAllocation());
+ source_context_ = p;
+ }
+ return source_context_;
+}
+inline ::PROTOBUF_NAMESPACE_ID::SourceContext* Api::mutable_source_context() {
+ ::PROTOBUF_NAMESPACE_ID::SourceContext* _msg = _internal_mutable_source_context();
+ // @@protoc_insertion_point(field_mutable:google.protobuf.Api.source_context)
+ return _msg;
+}
+inline void Api::set_allocated_source_context(::PROTOBUF_NAMESPACE_ID::SourceContext* source_context) {
+ ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaForAllocation();
+ if (message_arena == nullptr) {
+ delete reinterpret_cast< ::PROTOBUF_NAMESPACE_ID::MessageLite*>(source_context_);
+ }
+ if (source_context) {
+ ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
+ ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper<
+ ::PROTOBUF_NAMESPACE_ID::MessageLite>::GetOwningArena(
+ reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(source_context));
+ if (message_arena != submessage_arena) {
+ source_context = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
+ message_arena, source_context, submessage_arena);
+ }
+
+ } else {
+
+ }
+ source_context_ = source_context;
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.Api.source_context)
+}
+
+// repeated .google.protobuf.Mixin mixins = 6;
+inline int Api::_internal_mixins_size() const {
+ return mixins_.size();
+}
+inline int Api::mixins_size() const {
+ return _internal_mixins_size();
+}
+inline void Api::clear_mixins() {
+ mixins_.Clear();
+}
+inline ::PROTOBUF_NAMESPACE_ID::Mixin* Api::mutable_mixins(int index) {
+ // @@protoc_insertion_point(field_mutable:google.protobuf.Api.mixins)
+ return mixins_.Mutable(index);
+}
+inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Mixin >*
+Api::mutable_mixins() {
+ // @@protoc_insertion_point(field_mutable_list:google.protobuf.Api.mixins)
+ return &mixins_;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::Mixin& Api::_internal_mixins(int index) const {
+ return mixins_.Get(index);
+}
+inline const ::PROTOBUF_NAMESPACE_ID::Mixin& Api::mixins(int index) const {
+ // @@protoc_insertion_point(field_get:google.protobuf.Api.mixins)
+ return _internal_mixins(index);
+}
+inline ::PROTOBUF_NAMESPACE_ID::Mixin* Api::_internal_add_mixins() {
+ return mixins_.Add();
+}
+inline ::PROTOBUF_NAMESPACE_ID::Mixin* Api::add_mixins() {
+ ::PROTOBUF_NAMESPACE_ID::Mixin* _add = _internal_add_mixins();
+ // @@protoc_insertion_point(field_add:google.protobuf.Api.mixins)
+ return _add;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Mixin >&
+Api::mixins() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.Api.mixins)
+ return mixins_;
+}
+
+// .google.protobuf.Syntax syntax = 7;
+inline void Api::clear_syntax() {
+ syntax_ = 0;
+}
+inline ::PROTOBUF_NAMESPACE_ID::Syntax Api::_internal_syntax() const {
+ return static_cast< ::PROTOBUF_NAMESPACE_ID::Syntax >(syntax_);
+}
+inline ::PROTOBUF_NAMESPACE_ID::Syntax Api::syntax() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.Api.syntax)
+ return _internal_syntax();
+}
+inline void Api::_internal_set_syntax(::PROTOBUF_NAMESPACE_ID::Syntax value) {
+
+ syntax_ = value;
+}
+inline void Api::set_syntax(::PROTOBUF_NAMESPACE_ID::Syntax value) {
+ _internal_set_syntax(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.Api.syntax)
+}
+
+// -------------------------------------------------------------------
+
+// Method
+
+// string name = 1;
+inline void Method::clear_name() {
+ name_.ClearToEmpty();
+}
+inline const 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) {
+
+ name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, 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 name_.Get();
+}
+inline void Method::_internal_set_name(const std::string& value) {
+
+ name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation());
+}
+inline std::string* Method::_internal_mutable_name() {
+
+ return name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation());
+}
+inline std::string* Method::release_name() {
+ // @@protoc_insertion_point(field_release:google.protobuf.Method.name)
+ return name_.Release(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
+}
+inline void Method::set_allocated_name(std::string* name) {
+ if (name != nullptr) {
+
+ } else {
+
+ }
+ name_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), name,
+ GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (name_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
+ name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.Method.name)
+}
+
+// string request_type_url = 2;
+inline void Method::clear_request_type_url() {
+ request_type_url_.ClearToEmpty();
+}
+inline const 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) {
+
+ request_type_url_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
+ // @@protoc_insertion_point(field_set:google.protobuf.Method.request_type_url)
+}
+inline 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 request_type_url_.Get();
+}
+inline void Method::_internal_set_request_type_url(const std::string& value) {
+
+ request_type_url_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation());
+}
+inline std::string* Method::_internal_mutable_request_type_url() {
+
+ return request_type_url_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation());
+}
+inline std::string* Method::release_request_type_url() {
+ // @@protoc_insertion_point(field_release:google.protobuf.Method.request_type_url)
+ return request_type_url_.Release(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
+}
+inline void Method::set_allocated_request_type_url(std::string* request_type_url) {
+ if (request_type_url != nullptr) {
+
+ } else {
+
+ }
+ request_type_url_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), request_type_url,
+ GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (request_type_url_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
+ request_type_url_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.Method.request_type_url)
+}
+
+// bool request_streaming = 3;
+inline void Method::clear_request_streaming() {
+ request_streaming_ = false;
+}
+inline bool Method::_internal_request_streaming() const {
+ return request_streaming_;
+}
+inline bool Method::request_streaming() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.Method.request_streaming)
+ return _internal_request_streaming();
+}
+inline void Method::_internal_set_request_streaming(bool value) {
+
+ request_streaming_ = value;
+}
+inline void Method::set_request_streaming(bool value) {
+ _internal_set_request_streaming(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.Method.request_streaming)
+}
+
+// string response_type_url = 4;
+inline void Method::clear_response_type_url() {
+ response_type_url_.ClearToEmpty();
+}
+inline const 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) {
+
+ response_type_url_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
+ // @@protoc_insertion_point(field_set:google.protobuf.Method.response_type_url)
+}
+inline 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 response_type_url_.Get();
+}
+inline void Method::_internal_set_response_type_url(const std::string& value) {
+
+ response_type_url_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation());
+}
+inline std::string* Method::_internal_mutable_response_type_url() {
+
+ return response_type_url_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation());
+}
+inline std::string* Method::release_response_type_url() {
+ // @@protoc_insertion_point(field_release:google.protobuf.Method.response_type_url)
+ return response_type_url_.Release(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
+}
+inline void Method::set_allocated_response_type_url(std::string* response_type_url) {
+ if (response_type_url != nullptr) {
+
+ } else {
+
+ }
+ response_type_url_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), response_type_url,
+ GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (response_type_url_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
+ response_type_url_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.Method.response_type_url)
+}
+
+// bool response_streaming = 5;
+inline void Method::clear_response_streaming() {
+ response_streaming_ = false;
+}
+inline bool Method::_internal_response_streaming() const {
+ return response_streaming_;
+}
+inline bool Method::response_streaming() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.Method.response_streaming)
+ return _internal_response_streaming();
+}
+inline void Method::_internal_set_response_streaming(bool value) {
+
+ response_streaming_ = value;
+}
+inline void Method::set_response_streaming(bool value) {
+ _internal_set_response_streaming(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.Method.response_streaming)
+}
+
+// repeated .google.protobuf.Option options = 6;
+inline int Method::_internal_options_size() const {
+ return options_.size();
+}
+inline int Method::options_size() const {
+ return _internal_options_size();
+}
+inline ::PROTOBUF_NAMESPACE_ID::Option* Method::mutable_options(int index) {
+ // @@protoc_insertion_point(field_mutable:google.protobuf.Method.options)
+ return options_.Mutable(index);
+}
+inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Option >*
+Method::mutable_options() {
+ // @@protoc_insertion_point(field_mutable_list:google.protobuf.Method.options)
+ return &options_;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::Option& Method::_internal_options(int index) const {
+ return options_.Get(index);
+}
+inline const ::PROTOBUF_NAMESPACE_ID::Option& Method::options(int index) const {
+ // @@protoc_insertion_point(field_get:google.protobuf.Method.options)
+ return _internal_options(index);
+}
+inline ::PROTOBUF_NAMESPACE_ID::Option* Method::_internal_add_options() {
+ return options_.Add();
+}
+inline ::PROTOBUF_NAMESPACE_ID::Option* Method::add_options() {
+ ::PROTOBUF_NAMESPACE_ID::Option* _add = _internal_add_options();
+ // @@protoc_insertion_point(field_add:google.protobuf.Method.options)
+ return _add;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Option >&
+Method::options() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.Method.options)
+ return options_;
+}
+
+// .google.protobuf.Syntax syntax = 7;
+inline void Method::clear_syntax() {
+ syntax_ = 0;
+}
+inline ::PROTOBUF_NAMESPACE_ID::Syntax Method::_internal_syntax() const {
+ return static_cast< ::PROTOBUF_NAMESPACE_ID::Syntax >(syntax_);
+}
+inline ::PROTOBUF_NAMESPACE_ID::Syntax Method::syntax() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.Method.syntax)
+ return _internal_syntax();
+}
+inline void Method::_internal_set_syntax(::PROTOBUF_NAMESPACE_ID::Syntax value) {
+
+ syntax_ = value;
+}
+inline void Method::set_syntax(::PROTOBUF_NAMESPACE_ID::Syntax value) {
+ _internal_set_syntax(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.Method.syntax)
+}
+
+// -------------------------------------------------------------------
+
+// Mixin
+
+// string name = 1;
+inline void Mixin::clear_name() {
+ name_.ClearToEmpty();
+}
+inline const 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) {
+
+ name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, 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 name_.Get();
+}
+inline void Mixin::_internal_set_name(const std::string& value) {
+
+ name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation());
+}
+inline std::string* Mixin::_internal_mutable_name() {
+
+ return name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation());
+}
+inline std::string* Mixin::release_name() {
+ // @@protoc_insertion_point(field_release:google.protobuf.Mixin.name)
+ return name_.Release(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
+}
+inline void Mixin::set_allocated_name(std::string* name) {
+ if (name != nullptr) {
+
+ } else {
+
+ }
+ name_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), name,
+ GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (name_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
+ name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.Mixin.name)
+}
+
+// string root = 2;
+inline void Mixin::clear_root() {
+ root_.ClearToEmpty();
+}
+inline const 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) {
+
+ root_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, 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 root_.Get();
+}
+inline void Mixin::_internal_set_root(const std::string& value) {
+
+ root_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation());
+}
+inline std::string* Mixin::_internal_mutable_root() {
+
+ return root_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation());
+}
+inline std::string* Mixin::release_root() {
+ // @@protoc_insertion_point(field_release:google.protobuf.Mixin.root)
+ return root_.Release(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
+}
+inline void Mixin::set_allocated_root(std::string* root) {
+ if (root != nullptr) {
+
+ } else {
+
+ }
+ root_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), root,
+ GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (root_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
+ root_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.Mixin.root)
+}
+
+#ifdef __GNUC__
+ #pragma GCC diagnostic pop
+#endif // __GNUC__
+// -------------------------------------------------------------------
+
+// -------------------------------------------------------------------
+
+
+// @@protoc_insertion_point(namespace_scope)
+
+PROTOBUF_NAMESPACE_CLOSE
+
+// @@protoc_insertion_point(global_scope)
+
+#include <port_undef.inc>
+#endif // GOOGLE_PROTOBUF_INCLUDED_GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fapi_2eproto
diff --git a/NorthstarDedicatedTest/include/protobuf/api.proto b/NorthstarDedicatedTest/include/protobuf/api.proto
new file mode 100644
index 00000000..3d598fc8
--- /dev/null
+++ b/NorthstarDedicatedTest/include/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/NorthstarDedicatedTest/include/protobuf/arena.cc b/NorthstarDedicatedTest/include/protobuf/arena.cc
new file mode 100644
index 00000000..4053ef55
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/arena.cc
@@ -0,0 +1,511 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <arena.h>
+
+#include <algorithm>
+#include <atomic>
+#include <cstddef>
+#include <cstdint>
+#include <limits>
+#include <typeinfo>
+
+#include <arena_impl.h>
+
+#include <stubs/mutex.h>
+#ifdef ADDRESS_SANITIZER
+#include <sanitizer/asan_interface.h>
+#endif // ADDRESS_SANITIZER
+
+#include <port_def.inc>
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+static SerialArena::Memory AllocateMemory(const AllocationPolicy* policy_ptr,
+ size_t last_size, size_t min_bytes) {
+ AllocationPolicy policy; // default policy
+ if (policy_ptr) policy = *policy_ptr;
+ size_t size;
+ if (last_size != 0) {
+ // Double the current block size, up to a limit.
+ auto max_size = policy.max_block_size;
+ size = std::min(2 * last_size, max_size);
+ } else {
+ size = policy.start_block_size;
+ }
+ // Verify that min_bytes + kBlockHeaderSize won't overflow.
+ GOOGLE_CHECK_LE(min_bytes,
+ std::numeric_limits<size_t>::max() - SerialArena::kBlockHeaderSize);
+ size = std::max(size, SerialArena::kBlockHeaderSize + min_bytes);
+
+ void* mem;
+ if (policy.block_alloc == nullptr) {
+ mem = ::operator new(size);
+ } else {
+ mem = policy.block_alloc(size);
+ }
+ return {mem, size};
+}
+
+class GetDeallocator {
+ public:
+ GetDeallocator(const AllocationPolicy* policy, size_t* space_allocated)
+ : dealloc_(policy ? policy->block_dealloc : nullptr),
+ space_allocated_(space_allocated) {}
+
+ void operator()(SerialArena::Memory mem) const {
+#ifdef ADDRESS_SANITIZER
+ // This memory was provided by the underlying allocator as unpoisoned,
+ // so return it in an unpoisoned state.
+ ASAN_UNPOISON_MEMORY_REGION(mem.ptr, mem.size);
+#endif // ADDRESS_SANITIZER
+ if (dealloc_) {
+ dealloc_(mem.ptr, mem.size);
+ } else {
+#if defined(__GXX_DELETE_WITH_SIZE__) || defined(__cpp_sized_deallocation)
+ ::operator delete(mem.ptr, mem.size);
+#else
+ ::operator delete(mem.ptr);
+#endif
+ }
+ *space_allocated_ += mem.size;
+ }
+
+ private:
+ void (*dealloc_)(void*, size_t);
+ size_t* space_allocated_;
+};
+
+SerialArena::SerialArena(Block* b, void* owner) : space_allocated_(b->size) {
+ owner_ = owner;
+ head_ = b;
+ ptr_ = b->Pointer(kBlockHeaderSize + ThreadSafeArena::kSerialArenaSize);
+ limit_ = b->Pointer(b->size & static_cast<size_t>(-8));
+}
+
+SerialArena* SerialArena::New(Memory mem, void* owner) {
+ GOOGLE_DCHECK_LE(kBlockHeaderSize + ThreadSafeArena::kSerialArenaSize, mem.size);
+
+ auto b = new (mem.ptr) Block{nullptr, mem.size};
+ return new (b->Pointer(kBlockHeaderSize)) SerialArena(b, owner);
+}
+
+template <typename Deallocator>
+SerialArena::Memory SerialArena::Free(Deallocator deallocator) {
+ Block* b = head_;
+ Memory mem = {b, b->size};
+ while (b->next) {
+ b = b->next; // We must first advance before deleting this block
+ deallocator(mem);
+ mem = {b, b->size};
+ }
+ return mem;
+}
+
+PROTOBUF_NOINLINE
+std::pair<void*, SerialArena::CleanupNode*>
+SerialArena::AllocateAlignedWithCleanupFallback(
+ size_t n, const AllocationPolicy* policy) {
+ AllocateNewBlock(n + kCleanupSize, policy);
+ return AllocateFromExistingWithCleanupFallback(n);
+}
+
+PROTOBUF_NOINLINE
+void* SerialArena::AllocateAlignedFallback(size_t n,
+ const AllocationPolicy* policy) {
+ AllocateNewBlock(n, policy);
+ return AllocateFromExisting(n);
+}
+
+void SerialArena::AllocateNewBlock(size_t n, const AllocationPolicy* policy) {
+ // Sync limit to block
+ head_->start = reinterpret_cast<CleanupNode*>(limit_);
+
+ // Record how much used in this block.
+ space_used_ += ptr_ - head_->Pointer(kBlockHeaderSize);
+
+ auto mem = AllocateMemory(policy, head_->size, n);
+ // We don't want to emit an expensive RMW instruction that requires
+ // exclusive access to a cacheline. Hence we write it in terms of a
+ // regular add.
+ auto relaxed = std::memory_order_relaxed;
+ space_allocated_.store(space_allocated_.load(relaxed) + mem.size, relaxed);
+ head_ = new (mem.ptr) Block{head_, mem.size};
+ ptr_ = head_->Pointer(kBlockHeaderSize);
+ limit_ = head_->Pointer(head_->size);
+
+#ifdef ADDRESS_SANITIZER
+ ASAN_POISON_MEMORY_REGION(ptr_, limit_ - ptr_);
+#endif // ADDRESS_SANITIZER
+}
+
+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
+}
+
+void ThreadSafeArena::SetInitialBlock(void* mem, size_t size) {
+ SerialArena* serial = SerialArena::New({mem, size}, &thread_cache());
+ serial->set_next(NULL);
+ threads_.store(serial, std::memory_order_relaxed);
+ CacheSerialArena(serial);
+}
+
+ThreadSafeArena::~ThreadSafeArena() {
+ // Have to do this in a first pass, because some of the destructors might
+ // refer to memory in other blocks.
+ CleanupList();
+
+ size_t space_allocated = 0;
+ auto mem = Free(&space_allocated);
+
+ // Policy is about to get deleted.
+ auto* p = alloc_policy_.get();
+ ArenaMetricsCollector* collector = p ? p->metrics_collector : nullptr;
+
+ if (alloc_policy_.is_user_owned_initial_block()) {
+ space_allocated += mem.size;
+ } else {
+ GetDeallocator(alloc_policy_.get(), &space_allocated)(mem);
+ }
+
+ if (collector) collector->OnDestroy(space_allocated);
+}
+
+SerialArena::Memory ThreadSafeArena::Free(size_t* space_allocated) {
+ SerialArena::Memory mem = {nullptr, 0};
+ auto deallocator = GetDeallocator(alloc_policy_.get(), space_allocated);
+ PerSerialArena([deallocator, &mem](SerialArena* a) {
+ if (mem.ptr) deallocator(mem);
+ mem = a->Free(deallocator);
+ });
+ return mem;
+}
+
+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);
+
+ 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);
+
+ SerialArena* head = threads_.load(std::memory_order_relaxed);
+ do {
+ serial->set_next(head);
+ } while (!threads_.compare_exchange_weak(
+ head, serial, std::memory_order_release, std::memory_order_relaxed));
+ }
+
+ CacheSerialArena(serial);
+ return serial;
+}
+
+} // namespace internal
+
+PROTOBUF_FUNC_ALIGN(32)
+void* Arena::AllocateAlignedNoHook(size_t n) {
+ return impl_.AllocateAligned(n, nullptr);
+}
+
+PROTOBUF_FUNC_ALIGN(32)
+void* Arena::AllocateAlignedWithHook(size_t n, const std::type_info* type) {
+ return impl_.AllocateAligned(n, type);
+}
+
+PROTOBUF_FUNC_ALIGN(32)
+std::pair<void*, internal::SerialArena::CleanupNode*>
+Arena::AllocateAlignedWithCleanup(size_t n, const std::type_info* type) {
+ return impl_.AllocateAlignedWithCleanup(n, type);
+}
+
+} // namespace protobuf
+} // namespace google
+
+#include <port_undef.inc>
diff --git a/NorthstarDedicatedTest/include/protobuf/arena.h b/NorthstarDedicatedTest/include/protobuf/arena.h
new file mode 100644
index 00000000..18d2ed93
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/arena.h
@@ -0,0 +1,821 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// This file defines an Arena allocator for better allocation performance.
+
+#ifndef GOOGLE_PROTOBUF_ARENA_H__
+#define GOOGLE_PROTOBUF_ARENA_H__
+
+
+#include <limits>
+#include <type_traits>
+#include <utility>
+#ifdef max
+#undef max // Visual Studio defines this macro
+#endif
+#if defined(_MSC_VER) && !defined(_LIBCPP_STD_VER) && !_HAS_EXCEPTIONS
+// Work around bugs in MSVC <typeinfo> header when _HAS_EXCEPTIONS=0.
+#include <exception>
+#include <typeinfo>
+namespace std {
+using type_info = ::type_info;
+}
+#else
+#include <typeinfo>
+#endif
+
+#include <type_traits>
+#include <arena_impl.h>
+#include <port.h>
+
+#include <port_def.inc>
+
+#ifdef SWIG
+#error "You cannot SWIG proto headers"
+#endif
+
+namespace google {
+namespace protobuf {
+
+struct ArenaOptions; // defined below
+class Arena; // defined below
+class Message; // defined in message.h
+class MessageLite;
+template <typename Key, typename T>
+class Map;
+
+namespace arena_metrics {
+
+void EnableArenaMetrics(ArenaOptions* options);
+
+} // namespace arena_metrics
+
+namespace TestUtil {
+class ReflectionTester; // defined in test_util.h
+} // namespace TestUtil
+
+namespace internal {
+
+struct ArenaStringPtr; // defined in arenastring.h
+class InlinedStringField; // defined in inlined_string_field.h
+class LazyField; // defined in lazy_field.h
+class EpsCopyInputStream; // defined in parse_context.h
+
+template <typename Type>
+class GenericTypeHandler; // defined in repeated_field.h
+
+inline PROTOBUF_ALWAYS_INLINE
+void* AlignTo(void* ptr, size_t align) {
+ return reinterpret_cast<void*>(
+ (reinterpret_cast<uintptr_t>(ptr) + align - 1) & (~align + 1));
+}
+
+// Templated cleanup methods.
+template <typename T>
+void arena_destruct_object(void* object) {
+ reinterpret_cast<T*>(object)->~T();
+}
+
+template <bool destructor_skippable, typename T>
+struct ObjectDestructor {
+ constexpr static void (*destructor)(void*) = &arena_destruct_object<T>;
+};
+
+template <typename T>
+struct ObjectDestructor<true, T> {
+ constexpr static void (*destructor)(void*) = nullptr;
+};
+
+template <typename T>
+void arena_delete_object(void* object) {
+ delete reinterpret_cast<T*>(object);
+}
+} // namespace internal
+
+// ArenaOptions provides optional additional parameters to arena construction
+// that control its block-allocation behavior.
+struct ArenaOptions {
+ // This defines the size of the first block requested from the system malloc.
+ // Subsequent block sizes will increase in a geometric series up to a maximum.
+ size_t start_block_size;
+
+ // This defines the maximum block size requested from system malloc (unless an
+ // individual arena allocation request occurs with a size larger than this
+ // maximum). Requested block sizes increase up to this value, then remain
+ // here.
+ size_t max_block_size;
+
+ // An initial block of memory for the arena to use, or NULL for none. If
+ // provided, the block must live at least as long as the arena itself. The
+ // creator of the Arena retains ownership of the block after the Arena is
+ // destroyed.
+ char* initial_block;
+
+ // The size of the initial block, if provided.
+ size_t initial_block_size;
+
+ // A function pointer to an alloc method that returns memory blocks of size
+ // requested. By default, it contains a ptr to the malloc function.
+ //
+ // NOTE: block_alloc and dealloc functions are expected to behave like
+ // malloc and free, including Asan poisoning.
+ void* (*block_alloc)(size_t);
+ // A function pointer to a dealloc method that takes ownership of the blocks
+ // from the arena. By default, it contains a ptr to a wrapper function that
+ // calls free.
+ void (*block_dealloc)(void*, size_t);
+
+ ArenaOptions()
+ : start_block_size(internal::AllocationPolicy::kDefaultStartBlockSize),
+ max_block_size(internal::AllocationPolicy::kDefaultMaxBlockSize),
+ initial_block(NULL),
+ initial_block_size(0),
+ block_alloc(nullptr),
+ block_dealloc(nullptr),
+ make_metrics_collector(nullptr) {}
+
+ private:
+ // If make_metrics_collector is not nullptr, it will be called at Arena init
+ // time. It may return a pointer to a collector instance that will be notified
+ // of interesting events related to the arena.
+ internal::ArenaMetricsCollector* (*make_metrics_collector)();
+
+ internal::ArenaMetricsCollector* MetricsCollector() const {
+ return make_metrics_collector ? (*make_metrics_collector)() : nullptr;
+ }
+
+ internal::AllocationPolicy AllocationPolicy() const {
+ internal::AllocationPolicy res;
+ res.start_block_size = start_block_size;
+ res.max_block_size = max_block_size;
+ res.block_alloc = block_alloc;
+ res.block_dealloc = block_dealloc;
+ res.metrics_collector = MetricsCollector();
+ return res;
+ }
+
+ friend void arena_metrics::EnableArenaMetrics(ArenaOptions*);
+
+ friend class Arena;
+ friend class ArenaOptionsTestFriend;
+};
+
+// Support for non-RTTI environments. (The metrics hooks API uses type
+// information.)
+#if PROTOBUF_RTTI
+#define RTTI_TYPE_ID(type) (&typeid(type))
+#else
+#define RTTI_TYPE_ID(type) (NULL)
+#endif
+
+// Arena allocator. Arena allocation replaces ordinary (heap-based) allocation
+// with new/delete, and improves performance by aggregating allocations into
+// larger blocks and freeing allocations all at once. Protocol messages are
+// allocated on an arena by using Arena::CreateMessage<T>(Arena*), below, and
+// are automatically freed when the arena is destroyed.
+//
+// This is a thread-safe implementation: multiple threads may allocate from the
+// arena concurrently. Destruction is not thread-safe and the destructing
+// thread must synchronize with users of the arena first.
+//
+// An arena provides two allocation interfaces: CreateMessage<T>, which works
+// for arena-enabled proto2 message types as well as other types that satisfy
+// the appropriate protocol (described below), and Create<T>, which works for
+// any arbitrary type T. CreateMessage<T> is better when the type T supports it,
+// because this interface (i) passes the arena pointer to the created object so
+// that its sub-objects and internal allocations can use the arena too, and (ii)
+// elides the object's destructor call when possible. Create<T> does not place
+// any special requirements on the type T, and will invoke the object's
+// destructor when the arena is destroyed.
+//
+// The arena message allocation protocol, required by
+// CreateMessage<T>(Arena* arena, Args&&... args), is as follows:
+//
+// - The type T must have (at least) two constructors: a constructor callable
+// with `args` (without `arena`), called when a T is allocated on the heap;
+// and a constructor callable with `Arena* arena, Args&&... args`, called when
+// a T is allocated on an arena. If the second constructor is called with a
+// NULL arena pointer, it must be equivalent to invoking the first
+// (`args`-only) constructor.
+//
+// - The type T must have a particular type trait: a nested type
+// |InternalArenaConstructable_|. This is usually a typedef to |void|. If no
+// such type trait exists, then the instantiation CreateMessage<T> will fail
+// to compile.
+//
+// - The type T *may* have the type trait |DestructorSkippable_|. If this type
+// trait is present in the type, then its destructor will not be called if and
+// only if it was passed a non-NULL arena pointer. If this type trait is not
+// present on the type, then its destructor is always called when the
+// containing arena is destroyed.
+//
+// This protocol is implemented by all arena-enabled proto2 message classes as
+// well as protobuf container types like RepeatedPtrField and Map. The protocol
+// is internal to protobuf and is not guaranteed to be stable. Non-proto types
+// should not rely on this protocol.
+class PROTOBUF_EXPORT PROTOBUF_ALIGNAS(8) Arena 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)...);
+ }
+
+ // 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 {
+ public:
+ // Provides access to protected GetOwningArena to generated messages.
+ static Arena* GetOwningArena(const T* p) { return p->GetOwningArena(); }
+
+ // Provides access to protected GetArenaForAllocation to generated messages.
+ static Arena* GetArenaForAllocation(const T* p) {
+ return GetArenaForAllocationInternal(
+ p, std::is_convertible<T*, MessageLite*>());
+ }
+
+ // Creates message-owned arena.
+ static Arena* CreateMessageOwnedArena() {
+ return new Arena(internal::MessageOwned{});
+ }
+
+ // Checks whether the given arena is message-owned.
+ static bool IsMessageOwnedArena(Arena* arena) {
+ return arena->IsMessageOwned();
+ }
+
+ private:
+ static Arena* GetArenaForAllocationInternal(
+ const T* p, std::true_type /*is_derived_from<MessageLite>*/) {
+ return p->GetArenaForAllocation();
+ }
+
+ static Arena* GetArenaForAllocationInternal(
+ const T* p, std::false_type /*is_derived_from<MessageLite>*/) {
+ return GetArenaForAllocationForNonMessage(
+ p, typename is_arena_constructable::type());
+ }
+
+ static Arena* GetArenaForAllocationForNonMessage(
+ const T* p, std::true_type /*is_arena_constructible*/) {
+ return p->GetArena();
+ }
+
+ static Arena* GetArenaForAllocationForNonMessage(
+ const T* p, std::false_type /*is_arena_constructible*/) {
+ return GetArenaForAllocationForNonMessageNonArenaConstructible(
+ p, typename has_get_arena::type());
+ }
+
+ static Arena* GetArenaForAllocationForNonMessageNonArenaConstructible(
+ const T* p, std::true_type /*has_get_arena*/) {
+ return p->GetArena();
+ }
+
+ static Arena* GetArenaForAllocationForNonMessageNonArenaConstructible(
+ const T* /* p */, std::false_type /*has_get_arena*/) {
+ return nullptr;
+ }
+
+ template <typename U>
+ static char DestructorSkippable(const typename U::DestructorSkippable_*);
+ template <typename U>
+ static double DestructorSkippable(...);
+
+ typedef std::integral_constant<
+ bool, sizeof(DestructorSkippable<T>(static_cast<const T*>(0))) ==
+ sizeof(char) ||
+ std::is_trivially_destructible<T>::value>
+ is_destructor_skippable;
+
+ template <typename U>
+ static char ArenaConstructable(
+ const typename U::InternalArenaConstructable_*);
+ template <typename U>
+ static double ArenaConstructable(...);
+
+ typedef std::integral_constant<bool, sizeof(ArenaConstructable<T>(
+ static_cast<const T*>(0))) ==
+ sizeof(char)>
+ is_arena_constructable;
+
+ template <typename U,
+ typename std::enable_if<
+ std::is_same<Arena*, decltype(std::declval<const U>()
+ .GetArena())>::value,
+ int>::type = 0>
+ static char HasGetArena(decltype(&U::GetArena));
+ template <typename U>
+ static double HasGetArena(...);
+
+ typedef std::integral_constant<bool, sizeof(HasGetArena<T>(nullptr)) ==
+ sizeof(char)>
+ has_get_arena;
+
+ template <typename... Args>
+ static T* Construct(void* ptr, Args&&... args) {
+ return new (ptr) T(static_cast<Args&&>(args)...);
+ }
+
+ static inline PROTOBUF_ALWAYS_INLINE T* New() {
+ return new T(nullptr);
+ }
+
+ static Arena* GetArena(const T* p) { return p->GetArena(); }
+
+ friend class Arena;
+ friend class TestUtil::ReflectionTester;
+ };
+
+ // Helper typetraits that indicates support for arenas in a type T at compile
+ // time. This is public only to allow construction of higher-level templated
+ // utilities.
+ //
+ // is_arena_constructable<T>::value is true if the message type T has arena
+ // support enabled, and false otherwise.
+ //
+ // is_destructor_skippable<T>::value is true if the message type T has told
+ // the arena that it is safe to skip the destructor, and false otherwise.
+ //
+ // This is inside Arena because only Arena has the friend relationships
+ // necessary to see the underlying generated code traits.
+ template <typename T>
+ struct is_arena_constructable : InternalHelper<T>::is_arena_constructable {};
+ template <typename T>
+ struct is_destructor_skippable : InternalHelper<T>::is_destructor_skippable {
+ };
+
+ private:
+ internal::ThreadSafeArena impl_;
+
+ template <typename T>
+ struct has_get_arena : InternalHelper<T>::has_get_arena {};
+
+ // Constructor solely used by message-owned arena.
+ inline Arena(internal::MessageOwned) : impl_(internal::MessageOwned{}) {}
+
+ // Checks whether this arena is message-owned.
+ PROTOBUF_ALWAYS_INLINE bool IsMessageOwned() const {
+ return impl_.IsMessageOwned();
+ }
+
+ template <typename T, typename... Args>
+ PROTOBUF_NDEBUG_INLINE static T* CreateMessageInternal(Arena* arena,
+ Args&&... args) {
+ static_assert(
+ InternalHelper<T>::is_arena_constructable::value,
+ "CreateMessage can only construct types that are ArenaConstructable");
+ if (arena == NULL) {
+ return new T(nullptr, static_cast<Args&&>(args)...);
+ } else {
+ return arena->DoCreateMessage<T>(static_cast<Args&&>(args)...);
+ }
+ }
+
+ // This specialization for no arguments is necessary, because its behavior is
+ // slightly different. When the arena pointer is nullptr, it calls T()
+ // instead of T(nullptr).
+ template <typename T>
+ PROTOBUF_NDEBUG_INLINE static T* CreateMessageInternal(Arena* arena) {
+ static_assert(
+ InternalHelper<T>::is_arena_constructable::value,
+ "CreateMessage can only construct types that are ArenaConstructable");
+ if (arena == NULL) {
+ // Generated arena constructor T(Arena*) is protected. Call via
+ // InternalHelper.
+ return InternalHelper<T>::New();
+ } else {
+ return arena->DoCreateMessage<T>();
+ }
+ }
+
+ // Allocate and also optionally call collector with the allocated type info
+ // when allocation recording is enabled.
+ PROTOBUF_NDEBUG_INLINE void* AllocateInternal(size_t size, size_t align,
+ void (*destructor)(void*),
+ const std::type_info* type) {
+ // Monitor allocation if needed.
+ if (destructor == nullptr) {
+ return AllocateAlignedWithHook(size, align, type);
+ } else {
+ if (align <= 8) {
+ auto res = AllocateAlignedWithCleanup(internal::AlignUpTo8(size), type);
+ res.second->elem = res.first;
+ res.second->cleanup = destructor;
+ return res.first;
+ } else {
+ auto res = AllocateAlignedWithCleanup(size + align - 8, type);
+ auto ptr = internal::AlignTo(res.first, align);
+ res.second->elem = ptr;
+ res.second->cleanup = destructor;
+ return ptr;
+ }
+ }
+ }
+
+ // CreateMessage<T> requires that T supports arenas, but this private method
+ // works whether or not T supports arenas. These are not exposed to user code
+ // as it can cause confusing API usages, and end up having double free in
+ // user code. These are used only internally from LazyField and Repeated
+ // fields, since they are designed to work in all mode combinations.
+ template <typename Msg, typename... Args>
+ PROTOBUF_ALWAYS_INLINE static Msg* DoCreateMaybeMessage(Arena* arena,
+ std::true_type,
+ Args&&... args) {
+ return CreateMessageInternal<Msg>(arena, std::forward<Args>(args)...);
+ }
+
+ template <typename T, typename... Args>
+ PROTOBUF_ALWAYS_INLINE static T* DoCreateMaybeMessage(Arena* arena,
+ std::false_type,
+ Args&&... args) {
+ return Create<T>(arena, std::forward<Args>(args)...);
+ }
+
+ template <typename T, typename... Args>
+ PROTOBUF_ALWAYS_INLINE static T* CreateMaybeMessage(Arena* arena,
+ Args&&... args) {
+ return DoCreateMaybeMessage<T>(arena, is_arena_constructable<T>(),
+ std::forward<Args>(args)...);
+ }
+
+ // Just allocate the required size for the given type assuming the
+ // type has a trivial constructor.
+ template <typename T>
+ PROTOBUF_NDEBUG_INLINE T* CreateInternalRawArray(size_t num_elements) {
+ GOOGLE_CHECK_LE(num_elements, std::numeric_limits<size_t>::max() / sizeof(T))
+ << "Requested size is too large to fit into size_t.";
+ // We count on compiler to realize that if sizeof(T) is a multiple of
+ // 8 AlignUpTo can be elided.
+ const size_t n = sizeof(T) * num_elements;
+ return static_cast<T*>(
+ AllocateAlignedWithHook(n, alignof(T), RTTI_TYPE_ID(T)));
+ }
+
+ template <typename T, typename... Args>
+ PROTOBUF_NDEBUG_INLINE T* DoCreateMessage(Args&&... args) {
+ return InternalHelper<T>::Construct(
+ AllocateInternal(sizeof(T), alignof(T),
+ internal::ObjectDestructor<
+ InternalHelper<T>::is_destructor_skippable::value,
+ T>::destructor,
+ RTTI_TYPE_ID(T)),
+ this, std::forward<Args>(args)...);
+ }
+
+ // CreateInArenaStorage is used to implement map field. Without it,
+ // Map need to call generated message's protected arena constructor,
+ // which needs to declare Map as friend of generated message.
+ template <typename T, typename... Args>
+ static void CreateInArenaStorage(T* ptr, Arena* arena, Args&&... args) {
+ CreateInArenaStorageInternal(ptr, arena,
+ typename is_arena_constructable<T>::type(),
+ std::forward<Args>(args)...);
+ if (arena != nullptr) {
+ RegisterDestructorInternal(
+ ptr, arena,
+ typename InternalHelper<T>::is_destructor_skippable::type());
+ }
+ }
+
+ template <typename T, typename... Args>
+ static void CreateInArenaStorageInternal(T* ptr, Arena* arena,
+ std::true_type, Args&&... args) {
+ InternalHelper<T>::Construct(ptr, arena, std::forward<Args>(args)...);
+ }
+ template <typename T, typename... Args>
+ static void CreateInArenaStorageInternal(T* ptr, Arena* /* arena */,
+ std::false_type, Args&&... args) {
+ new (ptr) T(std::forward<Args>(args)...);
+ }
+
+ template <typename T>
+ static void RegisterDestructorInternal(T* /* ptr */, Arena* /* arena */,
+ std::true_type) {}
+ template <typename T>
+ static void RegisterDestructorInternal(T* ptr, Arena* arena,
+ std::false_type) {
+ arena->OwnDestructor(ptr);
+ }
+
+ // These implement Create(). The second parameter has type 'true_type' if T is
+ // a subtype of Message and 'false_type' otherwise.
+ template <typename T, typename... Args>
+ PROTOBUF_ALWAYS_INLINE static T* CreateInternal(Arena* arena, std::true_type,
+ Args&&... args) {
+ if (arena == nullptr) {
+ return new T(std::forward<Args>(args)...);
+ } else {
+ auto destructor =
+ internal::ObjectDestructor<std::is_trivially_destructible<T>::value,
+ T>::destructor;
+ T* result =
+ new (arena->AllocateInternal(sizeof(T), alignof(T), destructor,
+ RTTI_TYPE_ID(T)))
+ T(std::forward<Args>(args)...);
+ return result;
+ }
+ }
+ template <typename T, typename... Args>
+ PROTOBUF_ALWAYS_INLINE static T* CreateInternal(Arena* arena, std::false_type,
+ Args&&... args) {
+ if (arena == nullptr) {
+ return new T(std::forward<Args>(args)...);
+ } else {
+ auto destructor =
+ internal::ObjectDestructor<std::is_trivially_destructible<T>::value,
+ T>::destructor;
+ return new (arena->AllocateInternal(sizeof(T), alignof(T), destructor,
+ RTTI_TYPE_ID(T)))
+ T(std::forward<Args>(args)...);
+ }
+ }
+
+ // These implement Own(), which registers an object for deletion (destructor
+ // call and operator delete()). The second parameter has type 'true_type' if T
+ // is a subtype of Message and 'false_type' otherwise. Collapsing
+ // all template instantiations to one for generic Message reduces code size,
+ // using the virtual destructor instead.
+ template <typename T>
+ PROTOBUF_ALWAYS_INLINE void OwnInternal(T* object, std::true_type) {
+ if (object != NULL) {
+ impl_.AddCleanup(object, &internal::arena_delete_object<MessageLite>);
+ }
+ }
+ template <typename T>
+ PROTOBUF_ALWAYS_INLINE void OwnInternal(T* object, std::false_type) {
+ if (object != NULL) {
+ impl_.AddCleanup(object, &internal::arena_delete_object<T>);
+ }
+ }
+
+ // Implementation for GetArena(). Only message objects with
+ // InternalArenaConstructable_ tags can be associated with an arena, and such
+ // objects must implement a GetArena() method.
+ template <typename T, typename std::enable_if<
+ is_arena_constructable<T>::value, int>::type = 0>
+ PROTOBUF_ALWAYS_INLINE static Arena* GetArenaInternal(const T* value) {
+ return InternalHelper<T>::GetArena(value);
+ }
+ template <typename T,
+ typename std::enable_if<!is_arena_constructable<T>::value &&
+ has_get_arena<T>::value,
+ int>::type = 0>
+ PROTOBUF_ALWAYS_INLINE static Arena* GetArenaInternal(const T* value) {
+ return value->GetArena();
+ }
+ template <typename T,
+ typename std::enable_if<!is_arena_constructable<T>::value &&
+ !has_get_arena<T>::value,
+ int>::type = 0>
+ PROTOBUF_ALWAYS_INLINE static Arena* GetArenaInternal(const T* value) {
+ (void)value;
+ return nullptr;
+ }
+
+ template <typename T>
+ PROTOBUF_ALWAYS_INLINE static Arena* GetOwningArena(const T* value) {
+ return GetOwningArenaInternal(
+ value, std::is_convertible<T*, MessageLite*>());
+ }
+
+ // Implementation for GetOwningArena(). All and only message objects have
+ // GetOwningArena() method.
+ template <typename T>
+ PROTOBUF_ALWAYS_INLINE static Arena* GetOwningArenaInternal(
+ const T* value, std::true_type) {
+ return InternalHelper<T>::GetOwningArena(value);
+ }
+ template <typename T>
+ PROTOBUF_ALWAYS_INLINE static Arena* GetOwningArenaInternal(
+ const T* /* value */, std::false_type) {
+ return nullptr;
+ }
+
+ // For friends of arena.
+ void* AllocateAligned(size_t n, size_t align = 8) {
+ if (align <= 8) {
+ return AllocateAlignedNoHook(internal::AlignUpTo8(n));
+ } else {
+ // We are wasting space by over allocating align - 8 bytes. Compared
+ // to a dedicated function that takes current alignment in consideration.
+ // Such a scheme would only waste (align - 8)/2 bytes on average, but
+ // requires a dedicated function in the outline arena allocation
+ // functions. Possibly re-evaluate tradeoffs later.
+ return internal::AlignTo(AllocateAlignedNoHook(n + align - 8), align);
+ }
+ }
+
+ void* AllocateAlignedWithHook(size_t n, size_t align,
+ const std::type_info* type) {
+ if (align <= 8) {
+ return AllocateAlignedWithHook(internal::AlignUpTo8(n), type);
+ } else {
+ // We are wasting space by over allocating align - 8 bytes. Compared
+ // to a dedicated function that takes current alignment in consideration.
+ // Such a schemee would only waste (align - 8)/2 bytes on average, but
+ // requires a dedicated function in the outline arena allocation
+ // functions. Possibly re-evaluate tradeoffs later.
+ return internal::AlignTo(AllocateAlignedWithHook(n + align - 8, type),
+ align);
+ }
+ }
+
+ void* AllocateAlignedNoHook(size_t n);
+ void* AllocateAlignedWithHook(size_t n, const std::type_info* type);
+ std::pair<void*, internal::SerialArena::CleanupNode*>
+ AllocateAlignedWithCleanup(size_t n, const std::type_info* type);
+
+ template <typename Type>
+ friend class internal::GenericTypeHandler;
+ friend struct internal::ArenaStringPtr; // For AllocateAligned.
+ friend class internal::InlinedStringField; // For AllocateAligned.
+ friend class internal::LazyField; // For CreateMaybeMessage.
+ friend class internal::EpsCopyInputStream; // For parser performance
+ friend class MessageLite;
+ template <typename Key, typename T>
+ friend class Map;
+};
+
+// Defined above for supporting environments without RTTI.
+#undef RTTI_TYPE_ID
+
+} // namespace protobuf
+} // namespace google
+
+#include <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_ARENA_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/arena_impl.h b/NorthstarDedicatedTest/include/protobuf/arena_impl.h
new file mode 100644
index 00000000..dba1c302
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/arena_impl.h
@@ -0,0 +1,562 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// This file defines an Arena allocator for better allocation performance.
+
+#ifndef GOOGLE_PROTOBUF_ARENA_IMPL_H__
+#define GOOGLE_PROTOBUF_ARENA_IMPL_H__
+
+#include <atomic>
+#include <limits>
+#include <typeinfo>
+
+#include <stubs/common.h>
+#include <stubs/logging.h>
+
+#ifdef ADDRESS_SANITIZER
+#include <sanitizer/asan_interface.h>
+#endif // ADDRESS_SANITIZER
+
+#include <port_def.inc>
+
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+inline constexpr size_t AlignUpTo8(size_t n) {
+ // Align n to next multiple of 8 (from Hacker's Delight, Chapter 3.)
+ return (n + 7) & static_cast<size_t>(-8);
+}
+
+using LifecycleIdAtomic = 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_;
+};
+
+// 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) { return n <= static_cast<size_t>(limit_ - ptr_); }
+
+ void* AllocateAligned(size_t n, const AllocationPolicy* policy) {
+ GOOGLE_DCHECK_EQ(internal::AlignUpTo8(n), n); // Must be already aligned.
+ GOOGLE_DCHECK_GE(limit_, ptr_);
+ if (PROTOBUF_PREDICT_FALSE(!HasSpace(n))) {
+ return AllocateAlignedFallback(n, policy);
+ }
+ return AllocateFromExisting(n);
+ }
+
+ private:
+ void* AllocateFromExisting(size_t n) {
+ void* ret = ptr_;
+ ptr_ += n;
+#ifdef ADDRESS_SANITIZER
+ ASAN_UNPOISON_MEMORY_REGION(ret, n);
+#endif // ADDRESS_SANITIZER
+ return ret;
+ }
+
+ public:
+ // Allocate space if the current region provides enough space.
+ bool MaybeAllocateAligned(size_t n, void** out) {
+ GOOGLE_DCHECK_EQ(internal::AlignUpTo8(n), n); // Must be already aligned.
+ GOOGLE_DCHECK_GE(limit_, ptr_);
+ if (PROTOBUF_PREDICT_FALSE(!HasSpace(n))) return false;
+ *out = AllocateFromExisting(n);
+ return true;
+ }
+
+ std::pair<void*, CleanupNode*> AllocateAlignedWithCleanup(
+ size_t n, const AllocationPolicy* policy) {
+ GOOGLE_DCHECK_EQ(internal::AlignUpTo8(n), n); // Must be already aligned.
+ if (PROTOBUF_PREDICT_FALSE(!HasSpace(n + kCleanupSize))) {
+ return AllocateAlignedWithCleanupFallback(n, policy);
+ }
+ return AllocateFromExistingWithCleanupFallback(n);
+ }
+
+ private:
+ std::pair<void*, CleanupNode*> AllocateFromExistingWithCleanupFallback(
+ size_t n) {
+ void* ret = ptr_;
+ ptr_ += n;
+ limit_ -= kCleanupSize;
+#ifdef ADDRESS_SANITIZER
+ ASAN_UNPOISON_MEMORY_REGION(ret, n);
+ ASAN_UNPOISON_MEMORY_REGION(limit_, kCleanupSize);
+#endif // ADDRESS_SANITIZER
+ return CreatePair(ret, reinterpret_cast<CleanupNode*>(limit_));
+ }
+
+ public:
+ void AddCleanup(void* elem, void (*cleanup)(void*),
+ const AllocationPolicy* policy) {
+ auto res = AllocateAlignedWithCleanup(0, policy);
+ res.second->elem = elem;
+ res.second->cleanup = cleanup;
+ }
+
+ void* owner() const { return owner_; }
+ SerialArena* next() const { return next_; }
+ void set_next(SerialArena* next) { next_ = next; }
+
+ private:
+ friend class ThreadSafeArena;
+ friend class ArenaBenchmark;
+
+ // Creates a new SerialArena inside mem using the remaining memory as for
+ // future allocations.
+ static SerialArena* New(SerialArena::Memory mem, void* owner);
+ // Free SerialArena returning the memory passed in to New
+ template <typename Deallocator>
+ Memory Free(Deallocator deallocator);
+
+ // Blocks are variable length malloc-ed objects. The following structure
+ // describes the common header for all blocks.
+ struct Block {
+ Block(Block* next, size_t size) : next(next), size(size), start(nullptr) {}
+
+ char* Pointer(size_t n) {
+ GOOGLE_DCHECK(n <= size);
+ return reinterpret_cast<char*>(this) + n;
+ }
+
+ Block* const next;
+ const size_t size;
+ CleanupNode* start;
+ // data follows
+ };
+
+ void* owner_; // &ThreadCache of this thread;
+ Block* head_; // Head of linked list of blocks.
+ SerialArena* next_; // Next SerialArena in this linked list.
+ size_t space_used_ = 0; // Necessary for metrics.
+ std::atomic<size_t> space_allocated_;
+
+ // Next pointer to allocate from. Always 8-byte aligned. Points inside
+ // head_ (and head_->pos will always be non-canonical). We keep these
+ // here to reduce indirection.
+ char* ptr_;
+ char* limit_;
+
+ // Constructor is private as only New() should be used.
+ inline SerialArena(Block* b, void* owner);
+ void* AllocateAlignedFallback(size_t n, const AllocationPolicy* policy);
+ std::pair<void*, CleanupNode*> AllocateAlignedWithCleanupFallback(
+ size_t n, const AllocationPolicy* policy);
+ void AllocateNewBlock(size_t n, const AllocationPolicy* policy);
+
+ std::pair<void*, CleanupNode*> CreatePair(void* ptr, CleanupNode* node) {
+ return {ptr, node};
+ }
+
+ public:
+ static constexpr size_t kBlockHeaderSize = AlignUpTo8(sizeof(Block));
+ static constexpr size_t kCleanupSize = AlignUpTo8(sizeof(CleanupNode));
+};
+
+// Tag type used to invoke the constructor of message-owned arena.
+// Only message-owned arenas use this constructor for creation.
+// Such constructors are internal implementation details of the library.
+struct MessageOwned {
+ explicit MessageOwned() = default;
+};
+
+// This class provides the core Arena memory allocation library. Different
+// implementations only need to implement the public interface below.
+// Arena is not a template type as that would only be useful if all protos
+// in turn would be templates, which will/cannot happen. However separating
+// the memory allocation part from the cruft of the API users expect we can
+// use #ifdef the select the best implementation based on hardware / OS.
+class PROTOBUF_EXPORT ThreadSafeArena {
+ public:
+ ThreadSafeArena() { Init(); }
+
+ // Constructor solely used by message-owned arena.
+ ThreadSafeArena(internal::MessageOwned) : tag_and_id_(kMessageOwnedArena) {
+ Init();
+ }
+
+ ThreadSafeArena(char* mem, size_t size) { InitializeFrom(mem, size); }
+
+ explicit ThreadSafeArena(void* mem, size_t size,
+ const AllocationPolicy& policy) {
+ InitializeWithPolicy(mem, size, policy);
+ }
+
+ // Destructor deletes all owned heap allocated objects, and destructs objects
+ // that have non-trivial destructors, except for proto2 message objects whose
+ // destructors can be skipped. Also, frees all blocks except the initial block
+ // if it was passed in.
+ ~ThreadSafeArena();
+
+ uint64_t Reset();
+
+ uint64_t SpaceAllocated() const;
+ uint64_t SpaceUsed() const;
+
+ void* AllocateAligned(size_t n, const std::type_info* type) {
+ SerialArena* arena;
+ if (PROTOBUF_PREDICT_TRUE(!alloc_policy_.should_record_allocs() &&
+ GetSerialArenaFast(&arena))) {
+ return arena->AllocateAligned(n, AllocPolicy());
+ } else {
+ return AllocateAlignedFallback(n, type);
+ }
+ }
+
+ // This function allocates n bytes if the common happy case is true and
+ // returns true. Otherwise does nothing and returns false. This strange
+ // semantics is necessary to allow callers to program functions that only
+ // have fallback function calls in tail position. This substantially improves
+ // code for the happy path.
+ PROTOBUF_NDEBUG_INLINE bool MaybeAllocateAligned(size_t n, void** out) {
+ SerialArena* a;
+ if (PROTOBUF_PREDICT_TRUE(!alloc_policy_.should_record_allocs() &&
+ GetSerialArenaFromThreadCache(&a))) {
+ return a->MaybeAllocateAligned(n, out);
+ }
+ return false;
+ }
+
+ std::pair<void*, SerialArena::CleanupNode*> AllocateAlignedWithCleanup(
+ size_t n, const std::type_info* type);
+
+ // Add object pointer and cleanup function pointer to the list.
+ void AddCleanup(void* elem, void (*cleanup)(void*));
+
+ // Checks whether this arena is message-owned.
+ PROTOBUF_ALWAYS_INLINE bool IsMessageOwned() const {
+ return tag_and_id_ & kMessageOwnedArena;
+ }
+
+ private:
+ // Unique for each arena. Changes on Reset().
+ 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.
+
+ // 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 != NULL && serial->owner() == tc)) {
+ *arena = serial;
+ return true;
+ }
+ return false;
+ }
+
+ PROTOBUF_NDEBUG_INLINE bool GetSerialArenaFromThreadCache(
+ SerialArena** arena) {
+ // If this thread already owns a block in this arena then try to use that.
+ // This fast path optimizes the case where multiple threads allocate from
+ // the same arena.
+ ThreadCache* tc = &thread_cache();
+ if (PROTOBUF_PREDICT_TRUE(tc->last_lifecycle_id_seen == tag_and_id_)) {
+ *arena = tc->last_serial_arena;
+ return true;
+ }
+ return false;
+ }
+ SerialArena* GetSerialArenaFallback(void* me);
+
+ template <typename Functor>
+ void PerSerialArena(Functor fn) {
+ // By omitting an Acquire barrier we ensure that any user code that doesn't
+ // properly synchronize Reset() or the destructor will throw a TSAN warning.
+ SerialArena* serial = threads_.load(std::memory_order_relaxed);
+
+ for (; serial; serial = serial->next()) fn(serial);
+ }
+
+ // Releases all memory except the first block which it returns. The first
+ // block might be owned by the user and thus need some extra checks before
+ // deleting.
+ SerialArena::Memory Free(size_t* space_allocated);
+
+#ifdef _MSC_VER
+#pragma warning(disable : 4324)
+#endif
+ struct alignas(64) ThreadCache {
+#if defined(GOOGLE_PROTOBUF_NO_THREADLOCAL)
+ // If we are using the ThreadLocalStorage class to store the ThreadCache,
+ // then the ThreadCache's default constructor has to be responsible for
+ // initializing it.
+ ThreadCache()
+ : next_lifecycle_id(0),
+ last_lifecycle_id_seen(-1),
+ last_serial_arena(NULL) {}
+#endif
+
+ // Number of per-thread lifecycle IDs to reserve. Must be power of two.
+ // To reduce contention on a global atomic, each thread reserves a batch of
+ // IDs. The following number is calculated based on a stress test with
+ // ~6500 threads all frequently allocating a new arena.
+ static constexpr size_t kPerThreadIds = 256;
+ // Next lifecycle ID available to this thread. We need to reserve a new
+ // batch, if `next_lifecycle_id & (kPerThreadIds - 1) == 0`.
+ 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(64) CacheAlignedLifecycleIdGenerator {
+ std::atomic<LifecycleIdAtomic> id;
+ };
+ static CacheAlignedLifecycleIdGenerator lifecycle_id_generator_;
+#if defined(GOOGLE_PROTOBUF_NO_THREADLOCAL)
+ // iOS does not support __thread keyword so we use a custom thread local
+ // storage class we implemented.
+ static ThreadCache& thread_cache();
+#elif defined(PROTOBUF_USE_DLLS)
+ // Thread local variables cannot be exposed through DLL interface but we can
+ // wrap them in static functions.
+ static ThreadCache& thread_cache();
+#else
+ static PROTOBUF_THREAD_LOCAL ThreadCache thread_cache_;
+ static ThreadCache& thread_cache() { return thread_cache_; }
+#endif
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ThreadSafeArena);
+ // All protos have pointers back to the arena hence Arena must have
+ // pointer stability.
+ ThreadSafeArena(ThreadSafeArena&&) = delete;
+ ThreadSafeArena& operator=(ThreadSafeArena&&) = delete;
+
+ public:
+ // kBlockHeaderSize is sizeof(Block), aligned up to the nearest multiple of 8
+ // to protect the invariant that pos is always at a multiple of 8.
+ static constexpr size_t kBlockHeaderSize = SerialArena::kBlockHeaderSize;
+ static constexpr size_t kSerialArenaSize =
+ (sizeof(SerialArena) + 7) & static_cast<size_t>(-8);
+ static_assert(kBlockHeaderSize % 8 == 0,
+ "kBlockHeaderSize must be a multiple of 8.");
+ static_assert(kSerialArenaSize % 8 == 0,
+ "kSerialArenaSize must be a multiple of 8.");
+};
+
+} // namespace internal
+} // namespace protobuf
+} // namespace google
+
+#include <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_ARENA_IMPL_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/arena_test_util.cc b/NorthstarDedicatedTest/include/protobuf/arena_test_util.cc
new file mode 100644
index 00000000..b15a3e54
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/arena_test_util.cc
@@ -0,0 +1,50 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 <arena_test_util.h>
+#include <stubs/logging.h>
+#include <stubs/common.h>
+
+
+#define EXPECT_EQ GOOGLE_CHECK_EQ
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+NoHeapChecker::~NoHeapChecker() {
+ capture_alloc.Unhook();
+ EXPECT_EQ(0, capture_alloc.alloc_count());
+ EXPECT_EQ(0, capture_alloc.free_count());
+}
+
+} // namespace internal
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/arena_test_util.h b/NorthstarDedicatedTest/include/protobuf/arena_test_util.h
new file mode 100644
index 00000000..7b7cc98f
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/arena_test_util.h
@@ -0,0 +1,126 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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_ARENA_TEST_UTIL_H__
+#define GOOGLE_PROTOBUF_ARENA_TEST_UTIL_H__
+
+#include <stubs/logging.h>
+#include <stubs/common.h>
+#include <io/coded_stream.h>
+#include <io/zero_copy_stream_impl_lite.h>
+#include <arena.h>
+
+namespace google {
+namespace protobuf {
+
+template <typename T, bool use_arena>
+void TestParseCorruptedString(const T& message) {
+ int success_count = 0;
+ std::string s;
+ {
+ // Map order is not deterministic. To make the test deterministic we want
+ // to serialize the proto deterministically.
+ io::StringOutputStream output(&s);
+ io::CodedOutputStream out(&output);
+ out.SetSerializationDeterministic(true);
+ message.SerializePartialToCodedStream(&out);
+ }
+ const int kMaxIters = 900;
+ const int stride = s.size() <= kMaxIters ? 1 : s.size() / kMaxIters;
+ const int start = stride == 1 || use_arena ? 0 : (stride + 1) / 2;
+ for (int i = start; i < s.size(); i += stride) {
+ for (int c = 1 + (i % 17); c < 256; c += 2 * c + (i & 3)) {
+ s[i] ^= c;
+ Arena arena;
+ T* message = Arena::CreateMessage<T>(use_arena ? &arena : nullptr);
+ if (message->ParseFromString(s)) {
+ ++success_count;
+ }
+ if (!use_arena) {
+ delete message;
+ }
+ s[i] ^= c; // Restore s to its original state.
+ }
+ }
+ // This next line is a low bar. But getting through the test without crashing
+ // due to use-after-free or other bugs is a big part of what we're checking.
+ GOOGLE_CHECK_GT(success_count, 0);
+}
+
+namespace internal {
+
+class NoHeapChecker {
+ public:
+ NoHeapChecker() { capture_alloc.Hook(); }
+ ~NoHeapChecker();
+
+ private:
+ class NewDeleteCapture {
+ public:
+ // TODO(xiaofeng): Implement this for opensource protobuf.
+ void Hook() {}
+ void Unhook() {}
+ int alloc_count() { return 0; }
+ int free_count() { return 0; }
+ } capture_alloc;
+};
+
+// Owns the internal T only if it's not owned by an arena.
+// T needs to be arena constructible and destructor skippable.
+template <typename T>
+class ArenaHolder {
+ public:
+ explicit ArenaHolder(Arena* arena)
+ : field_(Arena::CreateMessage<T>(arena)),
+ owned_by_arena_(arena != nullptr) {
+ GOOGLE_DCHECK(google::protobuf::Arena::is_arena_constructable<T>::value);
+ GOOGLE_DCHECK(google::protobuf::Arena::is_destructor_skippable<T>::value);
+ }
+
+ ~ArenaHolder() {
+ if (!owned_by_arena_) {
+ delete field_;
+ }
+ }
+
+ T* get() { return field_; }
+ T* operator->() { return field_; }
+ T& operator*() { return *field_; }
+
+ private:
+ T* field_;
+ bool owned_by_arena_;
+};
+
+} // namespace internal
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_ARENA_TEST_UTIL_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/arena_unittest.cc b/NorthstarDedicatedTest/include/protobuf/arena_unittest.cc
new file mode 100644
index 00000000..e7a88e5b
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/arena_unittest.cc
@@ -0,0 +1,1557 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 <arena.h>
+
+#include <algorithm>
+#include <cstddef>
+#include <cstring>
+#include <memory>
+#include <string>
+#include <type_traits>
+#include <typeinfo>
+#include <vector>
+
+#include <stubs/logging.h>
+#include <stubs/common.h>
+#include <arena_test_util.h>
+#include <test_util.h>
+#include <unittest.pb.h>
+#include <unittest_arena.pb.h>
+#include <io/coded_stream.h>
+#include <io/zero_copy_stream_impl_lite.h>
+#include <descriptor.h>
+#include <extension_set.h>
+#include <message.h>
+#include <message_lite.h>
+#include <repeated_field.h>
+#include <unknown_field_set.h>
+#include <wire_format_lite.h>
+#include <gtest/gtest.h>
+#include <stubs/strutil.h>
+
+
+// Must be included last
+#include <port_def.inc>
+
+using proto2_arena_unittest::ArenaMessage;
+using protobuf_unittest::TestAllExtensions;
+using protobuf_unittest::TestAllTypes;
+using protobuf_unittest::TestEmptyMessage;
+using protobuf_unittest::TestOneof2;
+
+namespace google {
+namespace protobuf {
+
+class Notifier {
+ public:
+ Notifier() : count_(0) {}
+ void Notify() { count_++; }
+ int GetCount() { return count_; }
+
+ private:
+ int count_;
+};
+
+class SimpleDataType {
+ public:
+ SimpleDataType() : notifier_(NULL) {}
+ void SetNotifier(Notifier* notifier) { notifier_ = notifier; }
+ virtual ~SimpleDataType() {
+ if (notifier_ != NULL) {
+ notifier_->Notify();
+ }
+ };
+
+ private:
+ Notifier* notifier_;
+};
+
+// A simple class that does not allow copying and so cannot be used as a
+// parameter type without "const &".
+class PleaseDontCopyMe {
+ public:
+ explicit PleaseDontCopyMe(int value) : value_(value) {}
+
+ int value() const { return value_; }
+
+ private:
+ int value_;
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(PleaseDontCopyMe);
+};
+
+// A class that takes four different types as constructor arguments.
+class MustBeConstructedWithOneThroughFour {
+ public:
+ MustBeConstructedWithOneThroughFour(int one, const char* two,
+ const std::string& three,
+ const PleaseDontCopyMe* four)
+ : one_(one), two_(two), three_(three), four_(four) {}
+
+ int one_;
+ const char* const two_;
+ std::string three_;
+ const PleaseDontCopyMe* four_;
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MustBeConstructedWithOneThroughFour);
+};
+
+// A class that takes eight different types as constructor arguments.
+class MustBeConstructedWithOneThroughEight {
+ public:
+ MustBeConstructedWithOneThroughEight(int one, const char* two,
+ const std::string& three,
+ const PleaseDontCopyMe* four, int five,
+ const char* six,
+ const std::string& seven,
+ const std::string& eight)
+ : one_(one),
+ two_(two),
+ three_(three),
+ four_(four),
+ five_(five),
+ six_(six),
+ seven_(seven),
+ eight_(eight) {}
+
+ int one_;
+ const char* const two_;
+ std::string three_;
+ const PleaseDontCopyMe* four_;
+ int five_;
+ const char* const six_;
+ std::string seven_;
+ std::string eight_;
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MustBeConstructedWithOneThroughEight);
+};
+
+TEST(ArenaTest, ArenaConstructable) {
+ EXPECT_TRUE(Arena::is_arena_constructable<TestAllTypes>::type::value);
+ EXPECT_TRUE(Arena::is_arena_constructable<const TestAllTypes>::type::value);
+ EXPECT_FALSE(Arena::is_arena_constructable<Arena>::type::value);
+}
+
+TEST(ArenaTest, DestructorSkippable) {
+ EXPECT_TRUE(Arena::is_destructor_skippable<TestAllTypes>::type::value);
+ EXPECT_TRUE(Arena::is_destructor_skippable<const TestAllTypes>::type::value);
+ EXPECT_FALSE(Arena::is_destructor_skippable<Arena>::type::value);
+}
+
+TEST(ArenaTest, BasicCreate) {
+ Arena arena;
+ EXPECT_TRUE(Arena::Create<int32_t>(&arena) != NULL);
+ EXPECT_TRUE(Arena::Create<int64_t>(&arena) != NULL);
+ EXPECT_TRUE(Arena::Create<float>(&arena) != NULL);
+ EXPECT_TRUE(Arena::Create<double>(&arena) != NULL);
+ EXPECT_TRUE(Arena::Create<std::string>(&arena) != NULL);
+ arena.Own(new int32_t);
+ arena.Own(new int64_t);
+ arena.Own(new float);
+ arena.Own(new double);
+ arena.Own(new std::string);
+ arena.Own<int>(NULL);
+ Notifier notifier;
+ SimpleDataType* data = Arena::Create<SimpleDataType>(&arena);
+ data->SetNotifier(&notifier);
+ data = new SimpleDataType;
+ data->SetNotifier(&notifier);
+ arena.Own(data);
+ arena.Reset();
+ EXPECT_EQ(2, notifier.GetCount());
+}
+
+TEST(ArenaTest, CreateAndConstCopy) {
+ Arena arena;
+ const std::string s("foo");
+ const std::string* s_copy = Arena::Create<std::string>(&arena, s);
+ EXPECT_TRUE(s_copy != NULL);
+ EXPECT_EQ("foo", s);
+ EXPECT_EQ("foo", *s_copy);
+}
+
+TEST(ArenaTest, CreateAndNonConstCopy) {
+ Arena arena;
+ std::string s("foo");
+ const std::string* s_copy = Arena::Create<std::string>(&arena, s);
+ EXPECT_TRUE(s_copy != NULL);
+ EXPECT_EQ("foo", s);
+ EXPECT_EQ("foo", *s_copy);
+}
+
+TEST(ArenaTest, CreateAndMove) {
+ Arena arena;
+ std::string s("foo");
+ const std::string* s_move = Arena::Create<std::string>(&arena, std::move(s));
+ EXPECT_TRUE(s_move != NULL);
+ EXPECT_TRUE(s.empty()); // NOLINT
+ EXPECT_EQ("foo", *s_move);
+}
+
+TEST(ArenaTest, CreateWithFourConstructorArguments) {
+ Arena arena;
+ const std::string three("3");
+ const PleaseDontCopyMe four(4);
+ const MustBeConstructedWithOneThroughFour* new_object =
+ Arena::Create<MustBeConstructedWithOneThroughFour>(&arena, 1, "2", three,
+ &four);
+ EXPECT_TRUE(new_object != NULL);
+ ASSERT_EQ(1, new_object->one_);
+ ASSERT_STREQ("2", new_object->two_);
+ ASSERT_EQ("3", new_object->three_);
+ ASSERT_EQ(4, new_object->four_->value());
+}
+
+TEST(ArenaTest, CreateWithEightConstructorArguments) {
+ Arena arena;
+ const std::string three("3");
+ const PleaseDontCopyMe four(4);
+ const std::string seven("7");
+ const std::string eight("8");
+ const MustBeConstructedWithOneThroughEight* new_object =
+ Arena::Create<MustBeConstructedWithOneThroughEight>(
+ &arena, 1, "2", three, &four, 5, "6", seven, eight);
+ EXPECT_TRUE(new_object != NULL);
+ ASSERT_EQ(1, new_object->one_);
+ ASSERT_STREQ("2", new_object->two_);
+ ASSERT_EQ("3", new_object->three_);
+ ASSERT_EQ(4, new_object->four_->value());
+ ASSERT_EQ(5, new_object->five_);
+ ASSERT_STREQ("6", new_object->six_);
+ ASSERT_EQ("7", new_object->seven_);
+ ASSERT_EQ("8", new_object->eight_);
+}
+
+class PleaseMoveMe {
+ public:
+ explicit PleaseMoveMe(const std::string& value) : value_(value) {}
+ PleaseMoveMe(PleaseMoveMe&&) = default;
+ PleaseMoveMe(const PleaseMoveMe&) = delete;
+
+ const std::string& value() const { return value_; }
+
+ private:
+ std::string value_;
+};
+
+TEST(ArenaTest, CreateWithMoveArguments) {
+ Arena arena;
+ PleaseMoveMe one("1");
+ const PleaseMoveMe* new_object =
+ Arena::Create<PleaseMoveMe>(&arena, std::move(one));
+ EXPECT_TRUE(new_object);
+ ASSERT_EQ("1", new_object->value());
+}
+
+TEST(ArenaTest, InitialBlockTooSmall) {
+ // Construct a small blocks of memory to be used by the arena allocator; then,
+ // allocate an object which will not fit in the initial block.
+ for (int size = 0; size <= Arena::kBlockOverhead + 32; size++) {
+ std::vector<char> arena_block(size);
+ ArenaOptions options;
+ options.initial_block = arena_block.data();
+ options.initial_block_size = arena_block.size();
+
+ // Try sometimes with non-default block sizes so that we exercise paths
+ // with and without ArenaImpl::Options.
+ if ((size % 2) != 0) {
+ options.start_block_size += 8;
+ }
+
+ Arena arena(options);
+
+ char* p = Arena::CreateArray<char>(&arena, 96);
+ uintptr_t allocation = reinterpret_cast<uintptr_t>(p);
+
+ // Ensure that the arena allocator did not return memory pointing into the
+ // initial block of memory.
+ uintptr_t arena_start = reinterpret_cast<uintptr_t>(arena_block.data());
+ uintptr_t arena_end = arena_start + arena_block.size();
+ EXPECT_FALSE(allocation >= arena_start && allocation < arena_end);
+
+ // Write to the memory we allocated; this should (but is not guaranteed to)
+ // trigger a check for heap corruption if the object was allocated from the
+ // initially-provided block.
+ memset(p, '\0', 96);
+ }
+}
+
+TEST(ArenaTest, Parsing) {
+ TestAllTypes original;
+ TestUtil::SetAllFields(&original);
+
+ // Test memory leak.
+ Arena arena;
+ TestAllTypes* arena_message = Arena::CreateMessage<TestAllTypes>(&arena);
+ arena_message->ParseFromString(original.SerializeAsString());
+ TestUtil::ExpectAllFieldsSet(*arena_message);
+
+ // Test that string fields have nul terminator bytes (earlier bug).
+ EXPECT_EQ(strlen(original.optional_string().c_str()),
+ strlen(arena_message->optional_string().c_str()));
+}
+
+TEST(ArenaTest, UnknownFields) {
+ TestAllTypes original;
+ TestUtil::SetAllFields(&original);
+
+ // Test basic parsing into (populating) and reading out of unknown fields on
+ // an arena.
+ Arena arena;
+ TestEmptyMessage* arena_message =
+ Arena::CreateMessage<TestEmptyMessage>(&arena);
+ arena_message->ParseFromString(original.SerializeAsString());
+
+ TestAllTypes copied;
+ copied.ParseFromString(arena_message->SerializeAsString());
+ TestUtil::ExpectAllFieldsSet(copied);
+
+ // Exercise UFS manual manipulation (setters).
+ arena_message = Arena::CreateMessage<TestEmptyMessage>(&arena);
+ arena_message->mutable_unknown_fields()->AddVarint(
+ TestAllTypes::kOptionalInt32FieldNumber, 42);
+ copied.Clear();
+ copied.ParseFromString(arena_message->SerializeAsString());
+ EXPECT_TRUE(copied.has_optional_int32());
+ EXPECT_EQ(42, copied.optional_int32());
+
+ // Exercise UFS swap path.
+ TestEmptyMessage* arena_message_2 =
+ Arena::CreateMessage<TestEmptyMessage>(&arena);
+ arena_message_2->Swap(arena_message);
+ copied.Clear();
+ copied.ParseFromString(arena_message_2->SerializeAsString());
+ EXPECT_TRUE(copied.has_optional_int32());
+ EXPECT_EQ(42, copied.optional_int32());
+
+ // Test field manipulation.
+ TestEmptyMessage* arena_message_3 =
+ Arena::CreateMessage<TestEmptyMessage>(&arena);
+ arena_message_3->mutable_unknown_fields()->AddVarint(1000, 42);
+ arena_message_3->mutable_unknown_fields()->AddFixed32(1001, 42);
+ arena_message_3->mutable_unknown_fields()->AddFixed64(1002, 42);
+ arena_message_3->mutable_unknown_fields()->AddLengthDelimited(1003);
+ arena_message_3->mutable_unknown_fields()->DeleteSubrange(0, 2);
+ arena_message_3->mutable_unknown_fields()->DeleteByNumber(1002);
+ arena_message_3->mutable_unknown_fields()->DeleteByNumber(1003);
+ EXPECT_TRUE(arena_message_3->unknown_fields().empty());
+}
+
+TEST(ArenaTest, Swap) {
+ Arena arena1;
+ Arena arena2;
+ TestAllTypes* arena1_message;
+ TestAllTypes* arena2_message;
+
+ // Case 1: Swap(), no UFS on either message, both messages on different
+ // arenas. Arena pointers should remain the same after swap.
+ arena1_message = Arena::CreateMessage<TestAllTypes>(&arena1);
+ arena2_message = Arena::CreateMessage<TestAllTypes>(&arena2);
+ arena1_message->Swap(arena2_message);
+ EXPECT_EQ(&arena1, arena1_message->GetArena());
+ EXPECT_EQ(&arena2, arena2_message->GetArena());
+
+ // Case 2: Swap(), UFS on one message, both messages on different arenas.
+ arena1_message = Arena::CreateMessage<TestAllTypes>(&arena1);
+ arena2_message = Arena::CreateMessage<TestAllTypes>(&arena2);
+ arena1_message->mutable_unknown_fields()->AddVarint(1, 42);
+ arena1_message->Swap(arena2_message);
+ EXPECT_EQ(&arena1, arena1_message->GetArena());
+ EXPECT_EQ(&arena2, arena2_message->GetArena());
+ EXPECT_EQ(0, arena1_message->unknown_fields().field_count());
+ EXPECT_EQ(1, arena2_message->unknown_fields().field_count());
+ EXPECT_EQ(42, arena2_message->unknown_fields().field(0).varint());
+
+ // Case 3: Swap(), UFS on both messages, both messages on different arenas.
+ arena1_message = Arena::CreateMessage<TestAllTypes>(&arena1);
+ arena2_message = Arena::CreateMessage<TestAllTypes>(&arena2);
+ arena1_message->mutable_unknown_fields()->AddVarint(1, 42);
+ arena2_message->mutable_unknown_fields()->AddVarint(2, 84);
+ arena1_message->Swap(arena2_message);
+ EXPECT_EQ(&arena1, arena1_message->GetArena());
+ EXPECT_EQ(&arena2, arena2_message->GetArena());
+ EXPECT_EQ(1, arena1_message->unknown_fields().field_count());
+ EXPECT_EQ(1, arena2_message->unknown_fields().field_count());
+ EXPECT_EQ(84, arena1_message->unknown_fields().field(0).varint());
+ EXPECT_EQ(42, arena2_message->unknown_fields().field(0).varint());
+}
+
+TEST(ArenaTest, ReflectionSwapFields) {
+ Arena arena1;
+ Arena arena2;
+ TestAllTypes* arena1_message;
+ TestAllTypes* arena2_message;
+
+ // Case 1: messages on different arenas, only one message is set.
+ arena1_message = Arena::CreateMessage<TestAllTypes>(&arena1);
+ arena2_message = Arena::CreateMessage<TestAllTypes>(&arena2);
+ TestUtil::SetAllFields(arena1_message);
+ const Reflection* reflection = arena1_message->GetReflection();
+ std::vector<const FieldDescriptor*> fields;
+ reflection->ListFields(*arena1_message, &fields);
+ reflection->SwapFields(arena1_message, arena2_message, fields);
+ EXPECT_EQ(&arena1, arena1_message->GetArena());
+ EXPECT_EQ(&arena2, arena2_message->GetArena());
+ std::string output;
+ arena1_message->SerializeToString(&output);
+ EXPECT_EQ(0, output.size());
+ TestUtil::ExpectAllFieldsSet(*arena2_message);
+ reflection->SwapFields(arena1_message, arena2_message, fields);
+ arena2_message->SerializeToString(&output);
+ EXPECT_EQ(0, output.size());
+ TestUtil::ExpectAllFieldsSet(*arena1_message);
+
+ // Case 2: messages on different arenas, both messages are set.
+ arena1_message = Arena::CreateMessage<TestAllTypes>(&arena1);
+ arena2_message = Arena::CreateMessage<TestAllTypes>(&arena2);
+ TestUtil::SetAllFields(arena1_message);
+ TestUtil::SetAllFields(arena2_message);
+ reflection->SwapFields(arena1_message, arena2_message, fields);
+ EXPECT_EQ(&arena1, arena1_message->GetArena());
+ EXPECT_EQ(&arena2, arena2_message->GetArena());
+ TestUtil::ExpectAllFieldsSet(*arena1_message);
+ TestUtil::ExpectAllFieldsSet(*arena2_message);
+
+ // Case 3: messages on different arenas with different lifetimes.
+ arena1_message = Arena::CreateMessage<TestAllTypes>(&arena1);
+ {
+ Arena arena3;
+ TestAllTypes* arena3_message = Arena::CreateMessage<TestAllTypes>(&arena3);
+ TestUtil::SetAllFields(arena3_message);
+ reflection->SwapFields(arena1_message, arena3_message, fields);
+ }
+ TestUtil::ExpectAllFieldsSet(*arena1_message);
+
+ // Case 4: one message on arena, the other on heap.
+ arena1_message = Arena::CreateMessage<TestAllTypes>(&arena1);
+ TestAllTypes message;
+ TestUtil::SetAllFields(arena1_message);
+ reflection->SwapFields(arena1_message, &message, fields);
+ EXPECT_EQ(&arena1, arena1_message->GetArena());
+ EXPECT_EQ(nullptr, message.GetArena());
+ arena1_message->SerializeToString(&output);
+ EXPECT_EQ(0, output.size());
+ TestUtil::ExpectAllFieldsSet(message);
+}
+
+TEST(ArenaTest, SetAllocatedMessage) {
+ Arena arena;
+ TestAllTypes* arena_message = Arena::CreateMessage<TestAllTypes>(&arena);
+ TestAllTypes::NestedMessage* nested = new TestAllTypes::NestedMessage;
+ nested->set_bb(118);
+ arena_message->set_allocated_optional_nested_message(nested);
+ EXPECT_EQ(118, arena_message->optional_nested_message().bb());
+}
+
+TEST(ArenaTest, ReleaseMessage) {
+ Arena arena;
+ TestAllTypes* arena_message = Arena::CreateMessage<TestAllTypes>(&arena);
+ arena_message->mutable_optional_nested_message()->set_bb(118);
+ std::unique_ptr<TestAllTypes::NestedMessage> nested(
+ arena_message->release_optional_nested_message());
+ EXPECT_EQ(118, nested->bb());
+
+ TestAllTypes::NestedMessage* released_null =
+ arena_message->release_optional_nested_message();
+ EXPECT_EQ(NULL, released_null);
+}
+
+TEST(ArenaTest, SetAllocatedString) {
+ Arena arena;
+ TestAllTypes* arena_message = Arena::CreateMessage<TestAllTypes>(&arena);
+ std::string* allocated_str = new std::string("hello");
+ arena_message->set_allocated_optional_string(allocated_str);
+ EXPECT_EQ("hello", arena_message->optional_string());
+}
+
+TEST(ArenaTest, ReleaseString) {
+ Arena arena;
+ TestAllTypes* arena_message = Arena::CreateMessage<TestAllTypes>(&arena);
+ arena_message->set_optional_string("hello");
+ std::unique_ptr<std::string> released_str(
+ arena_message->release_optional_string());
+ EXPECT_EQ("hello", *released_str);
+
+ // Test default value.
+}
+
+
+TEST(ArenaTest, SwapBetweenArenasWithAllFieldsSet) {
+ Arena arena1;
+ TestAllTypes* arena1_message = Arena::CreateMessage<TestAllTypes>(&arena1);
+ {
+ Arena arena2;
+ TestAllTypes* arena2_message = Arena::CreateMessage<TestAllTypes>(&arena2);
+ TestUtil::SetAllFields(arena2_message);
+ arena2_message->Swap(arena1_message);
+ std::string output;
+ arena2_message->SerializeToString(&output);
+ EXPECT_EQ(0, output.size());
+ }
+ TestUtil::ExpectAllFieldsSet(*arena1_message);
+}
+
+TEST(ArenaTest, SwapBetweenArenaAndNonArenaWithAllFieldsSet) {
+ TestAllTypes non_arena_message;
+ TestUtil::SetAllFields(&non_arena_message);
+ {
+ Arena arena2;
+ TestAllTypes* arena2_message = Arena::CreateMessage<TestAllTypes>(&arena2);
+ TestUtil::SetAllFields(arena2_message);
+ arena2_message->Swap(&non_arena_message);
+ TestUtil::ExpectAllFieldsSet(*arena2_message);
+ TestUtil::ExpectAllFieldsSet(non_arena_message);
+ }
+}
+
+TEST(ArenaTest, UnsafeArenaSwap) {
+ Arena shared_arena;
+ TestAllTypes* message1 = Arena::CreateMessage<TestAllTypes>(&shared_arena);
+ TestAllTypes* message2 = Arena::CreateMessage<TestAllTypes>(&shared_arena);
+ TestUtil::SetAllFields(message1);
+ message1->UnsafeArenaSwap(message2);
+ TestUtil::ExpectAllFieldsSet(*message2);
+}
+
+TEST(ArenaTest, SwapBetweenArenasUsingReflection) {
+ Arena arena1;
+ TestAllTypes* arena1_message = Arena::CreateMessage<TestAllTypes>(&arena1);
+ {
+ Arena arena2;
+ TestAllTypes* arena2_message = Arena::CreateMessage<TestAllTypes>(&arena2);
+ TestUtil::SetAllFields(arena2_message);
+ const Reflection* r = arena2_message->GetReflection();
+ r->Swap(arena1_message, arena2_message);
+ std::string output;
+ arena2_message->SerializeToString(&output);
+ EXPECT_EQ(0, output.size());
+ }
+ TestUtil::ExpectAllFieldsSet(*arena1_message);
+}
+
+TEST(ArenaTest, SwapBetweenArenaAndNonArenaUsingReflection) {
+ TestAllTypes non_arena_message;
+ TestUtil::SetAllFields(&non_arena_message);
+ {
+ Arena arena2;
+ TestAllTypes* arena2_message = Arena::CreateMessage<TestAllTypes>(&arena2);
+ TestUtil::SetAllFields(arena2_message);
+ const Reflection* r = arena2_message->GetReflection();
+ r->Swap(&non_arena_message, arena2_message);
+ TestUtil::ExpectAllFieldsSet(*arena2_message);
+ TestUtil::ExpectAllFieldsSet(non_arena_message);
+ }
+}
+
+TEST(ArenaTest, ReleaseFromArenaMessageMakesCopy) {
+ TestAllTypes::NestedMessage* nested_msg = NULL;
+ std::string* nested_string = NULL;
+ {
+ Arena arena;
+ TestAllTypes* arena_message = Arena::CreateMessage<TestAllTypes>(&arena);
+ arena_message->mutable_optional_nested_message()->set_bb(42);
+ *arena_message->mutable_optional_string() = "Hello";
+ nested_msg = arena_message->release_optional_nested_message();
+ nested_string = arena_message->release_optional_string();
+ }
+ EXPECT_EQ(42, nested_msg->bb());
+ EXPECT_EQ("Hello", *nested_string);
+ delete nested_msg;
+ delete nested_string;
+}
+
+#if PROTOBUF_RTTI
+TEST(ArenaTest, ReleaseFromArenaMessageUsingReflectionMakesCopy) {
+ TestAllTypes::NestedMessage* nested_msg = NULL;
+ // Note: no string: reflection API only supports releasing submessages.
+ {
+ Arena arena;
+ TestAllTypes* arena_message = Arena::CreateMessage<TestAllTypes>(&arena);
+ arena_message->mutable_optional_nested_message()->set_bb(42);
+ const Reflection* r = arena_message->GetReflection();
+ const FieldDescriptor* f = arena_message->GetDescriptor()->FindFieldByName(
+ "optional_nested_message");
+ nested_msg = static_cast<TestAllTypes::NestedMessage*>(
+ r->ReleaseMessage(arena_message, f));
+ }
+ EXPECT_EQ(42, nested_msg->bb());
+ delete nested_msg;
+}
+#endif // PROTOBUF_RTTI
+
+TEST(ArenaTest, SetAllocatedAcrossArenas) {
+ Arena arena1;
+ TestAllTypes* arena1_message = Arena::CreateMessage<TestAllTypes>(&arena1);
+ TestAllTypes::NestedMessage* heap_submessage =
+ new TestAllTypes::NestedMessage();
+ heap_submessage->set_bb(42);
+ arena1_message->set_allocated_optional_nested_message(heap_submessage);
+ // Should keep same object and add to arena's Own()-list.
+ EXPECT_EQ(heap_submessage, arena1_message->mutable_optional_nested_message());
+ {
+ Arena arena2;
+ TestAllTypes::NestedMessage* arena2_submessage =
+ Arena::CreateMessage<TestAllTypes::NestedMessage>(&arena2);
+ arena2_submessage->set_bb(42);
+#ifdef PROTOBUF_HAS_DEATH_TEST
+ EXPECT_DEBUG_DEATH(arena1_message->set_allocated_optional_nested_message(
+ arena2_submessage),
+ "submessage_arena");
+#endif
+ EXPECT_NE(arena2_submessage,
+ arena1_message->mutable_optional_nested_message());
+ }
+
+ TestAllTypes::NestedMessage* arena1_submessage =
+ Arena::CreateMessage<TestAllTypes::NestedMessage>(&arena1);
+ arena1_submessage->set_bb(42);
+ TestAllTypes* heap_message = new TestAllTypes;
+#ifdef PROTOBUF_HAS_DEATH_TEST
+ EXPECT_DEBUG_DEATH(
+ heap_message->set_allocated_optional_nested_message(arena1_submessage),
+ "submessage_arena");
+#endif
+ EXPECT_NE(arena1_submessage, heap_message->mutable_optional_nested_message());
+ delete heap_message;
+}
+
+TEST(ArenaTest, UnsafeArenaSetAllocatedAcrossArenas) {
+ Arena arena1;
+ TestAllTypes* arena1_message = Arena::CreateMessage<TestAllTypes>(&arena1);
+ {
+ Arena arena2;
+ TestAllTypes::NestedMessage* arena2_submessage =
+ Arena::CreateMessage<TestAllTypes::NestedMessage>(&arena2);
+ arena2_submessage->set_bb(42);
+ arena1_message->unsafe_arena_set_allocated_optional_nested_message(
+ arena2_submessage);
+ EXPECT_EQ(arena2_submessage,
+ arena1_message->mutable_optional_nested_message());
+ EXPECT_EQ(arena2_submessage,
+ arena1_message->unsafe_arena_release_optional_nested_message());
+ }
+
+ TestAllTypes::NestedMessage* arena1_submessage =
+ Arena::CreateMessage<TestAllTypes::NestedMessage>(&arena1);
+ arena1_submessage->set_bb(42);
+ TestAllTypes* heap_message = new TestAllTypes;
+ heap_message->unsafe_arena_set_allocated_optional_nested_message(
+ arena1_submessage);
+ EXPECT_EQ(arena1_submessage, heap_message->mutable_optional_nested_message());
+ EXPECT_EQ(arena1_submessage,
+ heap_message->unsafe_arena_release_optional_nested_message());
+ delete heap_message;
+}
+
+TEST(ArenaTest, SetAllocatedAcrossArenasWithReflection) {
+ // Same as above, with reflection.
+ Arena arena1;
+ TestAllTypes* arena1_message = Arena::CreateMessage<TestAllTypes>(&arena1);
+ const Reflection* r = arena1_message->GetReflection();
+ const Descriptor* d = arena1_message->GetDescriptor();
+ const FieldDescriptor* msg_field =
+ d->FindFieldByName("optional_nested_message");
+ TestAllTypes::NestedMessage* heap_submessage =
+ new TestAllTypes::NestedMessage();
+ heap_submessage->set_bb(42);
+ r->SetAllocatedMessage(arena1_message, heap_submessage, msg_field);
+ // Should keep same object and add to arena's Own()-list.
+ EXPECT_EQ(heap_submessage, arena1_message->mutable_optional_nested_message());
+ {
+ Arena arena2;
+ TestAllTypes::NestedMessage* arena2_submessage =
+ Arena::CreateMessage<TestAllTypes::NestedMessage>(&arena2);
+ arena2_submessage->set_bb(42);
+#ifdef PROTOBUF_HAS_DEATH_TEST
+ EXPECT_DEBUG_DEATH(
+ r->SetAllocatedMessage(arena1_message, arena2_submessage, msg_field),
+ "GetOwningArena");
+#endif
+ EXPECT_NE(arena2_submessage,
+ arena1_message->mutable_optional_nested_message());
+ }
+
+ TestAllTypes::NestedMessage* arena1_submessage =
+ Arena::CreateMessage<TestAllTypes::NestedMessage>(&arena1);
+ arena1_submessage->set_bb(42);
+ TestAllTypes* heap_message = new TestAllTypes;
+#ifdef PROTOBUF_HAS_DEATH_TEST
+ EXPECT_DEBUG_DEATH(
+ r->SetAllocatedMessage(heap_message, arena1_submessage, msg_field),
+ "GetOwningArena");
+#endif
+ EXPECT_NE(arena1_submessage, heap_message->mutable_optional_nested_message());
+ delete heap_message;
+}
+
+TEST(ArenaTest, UnsafeArenaSetAllocatedAcrossArenasWithReflection) {
+ // Same as above, with reflection.
+ Arena arena1;
+ TestAllTypes* arena1_message = Arena::CreateMessage<TestAllTypes>(&arena1);
+ const Reflection* r = arena1_message->GetReflection();
+ const Descriptor* d = arena1_message->GetDescriptor();
+ const FieldDescriptor* msg_field =
+ d->FindFieldByName("optional_nested_message");
+ {
+ Arena arena2;
+ TestAllTypes::NestedMessage* arena2_submessage =
+ Arena::CreateMessage<TestAllTypes::NestedMessage>(&arena2);
+ arena2_submessage->set_bb(42);
+ r->UnsafeArenaSetAllocatedMessage(arena1_message, arena2_submessage,
+ msg_field);
+ EXPECT_EQ(arena2_submessage,
+ arena1_message->mutable_optional_nested_message());
+ EXPECT_EQ(arena2_submessage,
+ arena1_message->unsafe_arena_release_optional_nested_message());
+ }
+
+ TestAllTypes::NestedMessage* arena1_submessage =
+ Arena::CreateMessage<TestAllTypes::NestedMessage>(&arena1);
+ arena1_submessage->set_bb(42);
+ TestAllTypes* heap_message = new TestAllTypes;
+ r->UnsafeArenaSetAllocatedMessage(heap_message, arena1_submessage, msg_field);
+ EXPECT_EQ(arena1_submessage, heap_message->mutable_optional_nested_message());
+ EXPECT_EQ(arena1_submessage,
+ heap_message->unsafe_arena_release_optional_nested_message());
+ delete heap_message;
+}
+
+TEST(ArenaTest, AddAllocatedWithReflection) {
+ Arena arena1;
+ ArenaMessage* arena1_message = Arena::CreateMessage<ArenaMessage>(&arena1);
+ const Reflection* r = arena1_message->GetReflection();
+ const Descriptor* d = arena1_message->GetDescriptor();
+ // Message with cc_enable_arenas = true;
+ const FieldDescriptor* fd = d->FindFieldByName("repeated_nested_message");
+ r->AddMessage(arena1_message, fd);
+ r->AddMessage(arena1_message, fd);
+ r->AddMessage(arena1_message, fd);
+ EXPECT_EQ(3, r->FieldSize(*arena1_message, fd));
+}
+
+TEST(ArenaTest, RepeatedPtrFieldAddClearedTest) {
+#ifndef PROTOBUF_FUTURE_BREAKING_CHANGES
+ {
+ RepeatedPtrField<TestAllTypes> repeated_field;
+ EXPECT_TRUE(repeated_field.empty());
+ EXPECT_EQ(0, repeated_field.size());
+ // Ownership is passed to repeated_field.
+ TestAllTypes* cleared = new TestAllTypes();
+ repeated_field.AddCleared(cleared);
+ EXPECT_TRUE(repeated_field.empty());
+ EXPECT_EQ(0, repeated_field.size());
+ }
+#endif // !PROTOBUF_FUTURE_BREAKING_CHANGES
+ {
+ RepeatedPtrField<TestAllTypes> repeated_field;
+ EXPECT_TRUE(repeated_field.empty());
+ EXPECT_EQ(0, repeated_field.size());
+ // Ownership is passed to repeated_field.
+ TestAllTypes* cleared = new TestAllTypes();
+ repeated_field.AddAllocated(cleared);
+ EXPECT_FALSE(repeated_field.empty());
+ EXPECT_EQ(1, repeated_field.size());
+ }
+}
+
+TEST(ArenaTest, AddAllocatedToRepeatedField) {
+ // Heap->arena case.
+ Arena arena1;
+ TestAllTypes* arena1_message = Arena::CreateMessage<TestAllTypes>(&arena1);
+ for (int i = 0; i < 10; i++) {
+ TestAllTypes::NestedMessage* heap_submessage =
+ new TestAllTypes::NestedMessage();
+ heap_submessage->set_bb(42);
+ arena1_message->mutable_repeated_nested_message()->AddAllocated(
+ heap_submessage);
+ // Should not copy object -- will use arena_->Own().
+ EXPECT_EQ(heap_submessage, &arena1_message->repeated_nested_message(i));
+ EXPECT_EQ(42, arena1_message->repeated_nested_message(i).bb());
+ }
+
+ // Arena1->Arena2 case.
+ arena1_message->Clear();
+ for (int i = 0; i < 10; i++) {
+ Arena arena2;
+ TestAllTypes::NestedMessage* arena2_submessage =
+ Arena::CreateMessage<TestAllTypes::NestedMessage>(&arena2);
+ arena2_submessage->set_bb(42);
+#ifdef PROTOBUF_HAS_DEATH_TEST
+ EXPECT_DEBUG_DEATH(
+ arena1_message->mutable_repeated_nested_message()->AddAllocated(
+ arena2_submessage),
+ "value_arena");
+#endif
+ // Should not receive object.
+ EXPECT_TRUE(arena1_message->repeated_nested_message().empty());
+ }
+
+ // Arena->heap case.
+ TestAllTypes* heap_message = new TestAllTypes;
+ for (int i = 0; i < 10; i++) {
+ Arena arena2;
+ TestAllTypes::NestedMessage* arena2_submessage =
+ Arena::CreateMessage<TestAllTypes::NestedMessage>(&arena2);
+ arena2_submessage->set_bb(42);
+#ifdef PROTOBUF_HAS_DEATH_TEST
+ EXPECT_DEBUG_DEATH(
+ heap_message->mutable_repeated_nested_message()->AddAllocated(
+ arena2_submessage),
+ "value_arena");
+#endif
+ // Should not receive object.
+ EXPECT_TRUE(heap_message->repeated_nested_message().empty());
+ }
+ delete heap_message;
+
+ // Heap->arena case for strings (which are not arena-allocated).
+ arena1_message->Clear();
+ for (int i = 0; i < 10; i++) {
+ std::string* s = new std::string("Test");
+ arena1_message->mutable_repeated_string()->AddAllocated(s);
+ // Should not copy.
+ EXPECT_EQ(s, &arena1_message->repeated_string(i));
+ EXPECT_EQ("Test", arena1_message->repeated_string(i));
+ }
+}
+
+TEST(ArenaTest, UnsafeArenaAddAllocatedToRepeatedField) {
+ // Heap->arena case.
+ Arena arena1;
+ TestAllTypes* arena1_message = Arena::CreateMessage<TestAllTypes>(&arena1);
+ {
+ auto* heap_submessage = new TestAllTypes::NestedMessage;
+ arena1_message->mutable_repeated_nested_message()->UnsafeArenaAddAllocated(
+ heap_submessage);
+ // Should not copy object.
+ EXPECT_EQ(heap_submessage, &arena1_message->repeated_nested_message(0));
+ EXPECT_EQ(heap_submessage, arena1_message->mutable_repeated_nested_message()
+ ->UnsafeArenaReleaseLast());
+ delete heap_submessage;
+ }
+
+ // Arena1->Arena2 case.
+ arena1_message->Clear();
+ {
+ Arena arena2;
+ TestAllTypes::NestedMessage* arena2_submessage =
+ Arena::CreateMessage<TestAllTypes::NestedMessage>(&arena2);
+ arena2_submessage->set_bb(42);
+ arena1_message->mutable_repeated_nested_message()->UnsafeArenaAddAllocated(
+ arena2_submessage);
+ // Should own object.
+ EXPECT_EQ(arena2_submessage, &arena1_message->repeated_nested_message(0));
+ EXPECT_EQ(arena2_submessage,
+ arena1_message->mutable_repeated_nested_message()
+ ->UnsafeArenaReleaseLast());
+ }
+
+ // Arena->heap case.
+ TestAllTypes* heap_message = new TestAllTypes;
+ {
+ Arena arena2;
+ TestAllTypes::NestedMessage* arena2_submessage =
+ Arena::CreateMessage<TestAllTypes::NestedMessage>(&arena2);
+ arena2_submessage->set_bb(42);
+ heap_message->mutable_repeated_nested_message()->UnsafeArenaAddAllocated(
+ arena2_submessage);
+ // Should own object.
+ EXPECT_EQ(arena2_submessage, &heap_message->repeated_nested_message(0));
+ EXPECT_EQ(arena2_submessage, heap_message->mutable_repeated_nested_message()
+ ->UnsafeArenaReleaseLast());
+ }
+ delete heap_message;
+
+ // Heap->arena case for strings (which are not arena-allocated).
+ arena1_message->Clear();
+ {
+ std::string* s = new std::string("Test");
+ arena1_message->mutable_repeated_string()->UnsafeArenaAddAllocated(s);
+ // Should not copy.
+ EXPECT_EQ(s, &arena1_message->repeated_string(0));
+ EXPECT_EQ("Test", arena1_message->repeated_string(0));
+ delete arena1_message->mutable_repeated_string()->UnsafeArenaReleaseLast();
+ }
+}
+
+TEST(ArenaTest, AddAllocatedToRepeatedFieldViaReflection) {
+ // Heap->arena case.
+ Arena arena1;
+ TestAllTypes* arena1_message = Arena::CreateMessage<TestAllTypes>(&arena1);
+ const Reflection* r = arena1_message->GetReflection();
+ const Descriptor* d = arena1_message->GetDescriptor();
+ const FieldDescriptor* fd = d->FindFieldByName("repeated_nested_message");
+ for (int i = 0; i < 10; i++) {
+ TestAllTypes::NestedMessage* heap_submessage =
+ new TestAllTypes::NestedMessage;
+ heap_submessage->set_bb(42);
+ r->AddAllocatedMessage(arena1_message, fd, heap_submessage);
+ // Should not copy object -- will use arena_->Own().
+ EXPECT_EQ(heap_submessage, &arena1_message->repeated_nested_message(i));
+ EXPECT_EQ(42, arena1_message->repeated_nested_message(i).bb());
+ }
+
+ // Arena1->Arena2 case.
+ arena1_message->Clear();
+ for (int i = 0; i < 10; i++) {
+ Arena arena2;
+ TestAllTypes::NestedMessage* arena2_submessage =
+ Arena::CreateMessage<TestAllTypes::NestedMessage>(&arena2);
+ arena2_submessage->set_bb(42);
+#ifdef PROTOBUF_HAS_DEATH_TEST
+ EXPECT_DEBUG_DEATH(
+ r->AddAllocatedMessage(arena1_message, fd, arena2_submessage),
+ "value_arena");
+#endif
+ // Should not receive object.
+ EXPECT_TRUE(arena1_message->repeated_nested_message().empty());
+ }
+
+ // Arena->heap case.
+ TestAllTypes* heap_message = new TestAllTypes;
+ for (int i = 0; i < 10; i++) {
+ Arena arena2;
+ TestAllTypes::NestedMessage* arena2_submessage =
+ Arena::CreateMessage<TestAllTypes::NestedMessage>(&arena2);
+ arena2_submessage->set_bb(42);
+#ifdef PROTOBUF_HAS_DEATH_TEST
+ EXPECT_DEBUG_DEATH(
+ r->AddAllocatedMessage(heap_message, fd, arena2_submessage),
+ "value_arena");
+#endif
+ // Should not receive object.
+ EXPECT_TRUE(heap_message->repeated_nested_message().empty());
+ }
+ delete heap_message;
+}
+
+TEST(ArenaTest, ReleaseLastRepeatedField) {
+ // Release from arena-allocated repeated field and ensure that returned object
+ // is heap-allocated.
+ Arena arena;
+ TestAllTypes* arena_message = Arena::CreateMessage<TestAllTypes>(&arena);
+ for (int i = 0; i < 10; i++) {
+ TestAllTypes::NestedMessage* nested =
+ Arena::CreateMessage<TestAllTypes::NestedMessage>(&arena);
+ nested->set_bb(42);
+ arena_message->mutable_repeated_nested_message()->AddAllocated(nested);
+ }
+
+ for (int i = 0; i < 10; i++) {
+ const TestAllTypes::NestedMessage* orig_submessage =
+ &arena_message->repeated_nested_message(10 - 1 - i); // last element
+ TestAllTypes::NestedMessage* released =
+ arena_message->mutable_repeated_nested_message()->ReleaseLast();
+ EXPECT_NE(released, orig_submessage);
+ EXPECT_EQ(42, released->bb());
+ delete released;
+ }
+
+ // Test UnsafeArenaReleaseLast().
+ for (int i = 0; i < 10; i++) {
+ TestAllTypes::NestedMessage* nested =
+ Arena::CreateMessage<TestAllTypes::NestedMessage>(&arena);
+ nested->set_bb(42);
+ arena_message->mutable_repeated_nested_message()->AddAllocated(nested);
+ }
+
+ for (int i = 0; i < 10; i++) {
+ const TestAllTypes::NestedMessage* orig_submessage =
+ &arena_message->repeated_nested_message(10 - 1 - i); // last element
+ TestAllTypes::NestedMessage* released =
+ arena_message->mutable_repeated_nested_message()
+ ->UnsafeArenaReleaseLast();
+ EXPECT_EQ(released, orig_submessage);
+ EXPECT_EQ(42, released->bb());
+ // no delete -- |released| is on the arena.
+ }
+
+ // Test string case as well. ReleaseLast() in this case must copy the
+ // string, even though it was originally heap-allocated and its pointer
+ // was simply appended to the repeated field's internal vector, because the
+ // string was placed on the arena's destructor list and cannot be removed
+ // from that list (so the arena permanently owns the original instance).
+ arena_message->Clear();
+ for (int i = 0; i < 10; i++) {
+ std::string* s = new std::string("Test");
+ arena_message->mutable_repeated_string()->AddAllocated(s);
+ }
+ for (int i = 0; i < 10; i++) {
+ const std::string* orig_element =
+ &arena_message->repeated_string(10 - 1 - i);
+ std::string* released =
+ arena_message->mutable_repeated_string()->ReleaseLast();
+ EXPECT_NE(released, orig_element);
+ EXPECT_EQ("Test", *released);
+ delete released;
+ }
+}
+
+TEST(ArenaTest, UnsafeArenaAddAllocated) {
+ Arena arena;
+ TestAllTypes* message = Arena::CreateMessage<TestAllTypes>(&arena);
+ for (int i = 0; i < 10; i++) {
+ std::string* arena_string = Arena::Create<std::string>(&arena);
+ message->mutable_repeated_string()->UnsafeArenaAddAllocated(arena_string);
+ EXPECT_EQ(arena_string, message->mutable_repeated_string(i));
+ }
+}
+
+TEST(ArenaTest, OneofMerge) {
+ Arena arena;
+ TestAllTypes* message0 = Arena::CreateMessage<TestAllTypes>(&arena);
+ TestAllTypes* message1 = Arena::CreateMessage<TestAllTypes>(&arena);
+
+ message0->set_oneof_string("x");
+ ASSERT_TRUE(message0->has_oneof_string());
+ message1->set_oneof_string("y");
+ ASSERT_TRUE(message1->has_oneof_string());
+ EXPECT_EQ("x", message0->oneof_string());
+ EXPECT_EQ("y", message1->oneof_string());
+ message0->MergeFrom(*message1);
+ EXPECT_EQ("y", message0->oneof_string());
+ EXPECT_EQ("y", message1->oneof_string());
+}
+
+TEST(ArenaTest, ArenaOneofReflection) {
+ Arena arena;
+ TestAllTypes* message = Arena::CreateMessage<TestAllTypes>(&arena);
+ const Descriptor* desc = message->GetDescriptor();
+ const Reflection* refl = message->GetReflection();
+
+ const FieldDescriptor* string_field = desc->FindFieldByName("oneof_string");
+ const FieldDescriptor* msg_field =
+ desc->FindFieldByName("oneof_nested_message");
+ const OneofDescriptor* oneof = desc->FindOneofByName("oneof_field");
+
+ refl->SetString(message, string_field, "Test value");
+ EXPECT_TRUE(refl->HasOneof(*message, oneof));
+ refl->ClearOneof(message, oneof);
+ EXPECT_FALSE(refl->HasOneof(*message, oneof));
+
+ Message* submsg = refl->MutableMessage(message, msg_field);
+ EXPECT_TRUE(refl->HasOneof(*message, oneof));
+ refl->ClearOneof(message, oneof);
+ EXPECT_FALSE(refl->HasOneof(*message, oneof));
+ refl->MutableMessage(message, msg_field);
+ EXPECT_TRUE(refl->HasOneof(*message, oneof));
+ submsg = refl->ReleaseMessage(message, msg_field);
+ EXPECT_FALSE(refl->HasOneof(*message, oneof));
+ EXPECT_TRUE(submsg->GetArena() == NULL);
+ delete submsg;
+}
+
+void TestSwapRepeatedField(Arena* arena1, Arena* arena2) {
+ // Test "safe" (copying) semantics for direct Swap() on RepeatedPtrField
+ // between arenas.
+ RepeatedPtrField<TestAllTypes> field1(arena1);
+ RepeatedPtrField<TestAllTypes> field2(arena2);
+ for (int i = 0; i < 10; i++) {
+ TestAllTypes* t = Arena::CreateMessage<TestAllTypes>(arena1);
+ t->set_optional_string("field1");
+ t->set_optional_int32(i);
+ if (arena1 != NULL) {
+ field1.UnsafeArenaAddAllocated(t);
+ } else {
+ field1.AddAllocated(t);
+ }
+ }
+ for (int i = 0; i < 5; i++) {
+ TestAllTypes* t = Arena::CreateMessage<TestAllTypes>(arena2);
+ t->set_optional_string("field2");
+ t->set_optional_int32(i);
+ if (arena2 != NULL) {
+ field2.UnsafeArenaAddAllocated(t);
+ } else {
+ field2.AddAllocated(t);
+ }
+ }
+ field1.Swap(&field2);
+ EXPECT_EQ(5, field1.size());
+ EXPECT_EQ(10, field2.size());
+ EXPECT_TRUE(std::string("field1") == field2.Get(0).optional_string());
+ EXPECT_TRUE(std::string("field2") == field1.Get(0).optional_string());
+ // Ensure that fields retained their original order:
+ for (int i = 0; i < field1.size(); i++) {
+ EXPECT_EQ(i, field1.Get(i).optional_int32());
+ }
+ for (int i = 0; i < field2.size(); i++) {
+ EXPECT_EQ(i, field2.Get(i).optional_int32());
+ }
+}
+
+TEST(ArenaTest, SwapRepeatedField) {
+ Arena arena;
+ TestSwapRepeatedField(&arena, &arena);
+}
+
+TEST(ArenaTest, SwapRepeatedFieldWithDifferentArenas) {
+ Arena arena1;
+ Arena arena2;
+ TestSwapRepeatedField(&arena1, &arena2);
+}
+
+TEST(ArenaTest, SwapRepeatedFieldWithNoArenaOnRightHandSide) {
+ Arena arena;
+ TestSwapRepeatedField(&arena, NULL);
+}
+
+TEST(ArenaTest, SwapRepeatedFieldWithNoArenaOnLeftHandSide) {
+ Arena arena;
+ TestSwapRepeatedField(NULL, &arena);
+}
+
+TEST(ArenaTest, ExtensionsOnArena) {
+ Arena arena;
+ // Ensure no leaks.
+ TestAllExtensions* message_ext =
+ Arena::CreateMessage<TestAllExtensions>(&arena);
+ message_ext->SetExtension(protobuf_unittest::optional_int32_extension, 42);
+ message_ext->SetExtension(protobuf_unittest::optional_string_extension,
+ std::string("test"));
+ message_ext
+ ->MutableExtension(protobuf_unittest::optional_nested_message_extension)
+ ->set_bb(42);
+}
+
+TEST(ArenaTest, RepeatedFieldOnArena) {
+ // Preallocate an initial arena block to avoid mallocs during hooked region.
+ std::vector<char> arena_block(1024 * 1024);
+ Arena arena(arena_block.data(), arena_block.size());
+
+ {
+ internal::NoHeapChecker no_heap;
+
+ // Fill some repeated fields on the arena to test for leaks. Also verify no
+ // memory allocations.
+ RepeatedField<int32_t> repeated_int32(&arena);
+ RepeatedPtrField<TestAllTypes> repeated_message(&arena);
+ for (int i = 0; i < 100; i++) {
+ repeated_int32.Add(42);
+ repeated_message.Add()->set_optional_int32(42);
+ EXPECT_EQ(&arena, repeated_message.Get(0).GetArena());
+ const TestAllTypes* msg_in_repeated_field = &repeated_message.Get(0);
+ TestAllTypes* msg = repeated_message.UnsafeArenaReleaseLast();
+ EXPECT_EQ(msg_in_repeated_field, msg);
+ }
+
+ // UnsafeArenaExtractSubrange (i) should not leak and (ii) should return
+ // on-arena pointers.
+ for (int i = 0; i < 10; i++) {
+ repeated_message.Add()->set_optional_int32(42);
+ }
+ TestAllTypes* extracted_messages[5];
+ repeated_message.UnsafeArenaExtractSubrange(0, 5, extracted_messages);
+ EXPECT_EQ(&arena, repeated_message.Get(0).GetArena());
+ EXPECT_EQ(5, repeated_message.size());
+ }
+
+ // Now, outside the scope of the NoHeapChecker, test ExtractSubrange's copying
+ // semantics.
+ {
+ RepeatedPtrField<TestAllTypes> repeated_message(&arena);
+ for (int i = 0; i < 100; i++) {
+ repeated_message.Add()->set_optional_int32(42);
+ }
+
+ TestAllTypes* extracted_messages[5];
+ // ExtractSubrange should copy to the heap.
+ repeated_message.ExtractSubrange(0, 5, extracted_messages);
+ EXPECT_EQ(NULL, extracted_messages[0]->GetArena());
+ // We need to free the heap-allocated messages to prevent a leak.
+ for (int i = 0; i < 5; i++) {
+ delete extracted_messages[i];
+ extracted_messages[i] = NULL;
+ }
+ }
+
+ // Now check that we can create RepeatedFields/RepeatedPtrFields themselves on
+ // the arena. They have the necessary type traits so that they can behave like
+ // messages in this way. This is useful for higher-level generic templated
+ // code that may allocate messages or repeated fields of messages on an arena.
+ {
+ RepeatedPtrField<TestAllTypes>* repeated_ptr_on_arena =
+ Arena::CreateMessage<RepeatedPtrField<TestAllTypes> >(&arena);
+ for (int i = 0; i < 10; i++) {
+ // Add some elements and let the leak-checker ensure that everything is
+ // freed.
+ repeated_ptr_on_arena->Add();
+ }
+
+ RepeatedField<int>* repeated_int_on_arena =
+ Arena::CreateMessage<RepeatedField<int> >(&arena);
+ for (int i = 0; i < 100; i++) {
+ repeated_int_on_arena->Add(i);
+ }
+
+ }
+
+ arena.Reset();
+}
+
+
+#if PROTOBUF_RTTI
+TEST(ArenaTest, MutableMessageReflection) {
+ Arena arena;
+ TestAllTypes* message = Arena::CreateMessage<TestAllTypes>(&arena);
+ const Reflection* r = message->GetReflection();
+ const Descriptor* d = message->GetDescriptor();
+ const FieldDescriptor* field = d->FindFieldByName("optional_nested_message");
+ TestAllTypes::NestedMessage* submessage =
+ static_cast<TestAllTypes::NestedMessage*>(
+ r->MutableMessage(message, field));
+ TestAllTypes::NestedMessage* submessage_expected =
+ message->mutable_optional_nested_message();
+
+ EXPECT_EQ(submessage_expected, submessage);
+ EXPECT_EQ(&arena, submessage->GetArena());
+
+ const FieldDescriptor* oneof_field =
+ d->FindFieldByName("oneof_nested_message");
+ submessage = static_cast<TestAllTypes::NestedMessage*>(
+ r->MutableMessage(message, oneof_field));
+ submessage_expected = message->mutable_oneof_nested_message();
+
+ EXPECT_EQ(submessage_expected, submessage);
+ EXPECT_EQ(&arena, submessage->GetArena());
+}
+#endif // PROTOBUF_RTTI
+
+
+void FillArenaAwareFields(TestAllTypes* message) {
+ std::string test_string = "hello world";
+ message->set_optional_int32(42);
+ message->set_optional_string(test_string);
+ message->set_optional_bytes(test_string);
+ message->mutable_optional_nested_message()->set_bb(42);
+
+ message->set_oneof_uint32(42);
+ message->mutable_oneof_nested_message()->set_bb(42);
+ message->set_oneof_string(test_string);
+ message->set_oneof_bytes(test_string);
+
+ message->add_repeated_int32(42);
+ // No repeated string: not yet arena-aware.
+ message->add_repeated_nested_message()->set_bb(42);
+ message->mutable_optional_lazy_message()->set_bb(42);
+}
+
+// Test: no allocations occur on heap while touching all supported field types.
+TEST(ArenaTest, NoHeapAllocationsTest) {
+ // Allocate a large initial block to avoid mallocs during hooked test.
+ std::vector<char> arena_block(128 * 1024);
+ ArenaOptions options;
+ options.initial_block = &arena_block[0];
+ options.initial_block_size = arena_block.size();
+ Arena arena(options);
+
+ {
+
+ TestAllTypes* message = Arena::CreateMessage<TestAllTypes>(&arena);
+ FillArenaAwareFields(message);
+ }
+
+ arena.Reset();
+}
+
+TEST(ArenaTest, ParseCorruptedString) {
+ TestAllTypes message;
+ TestUtil::SetAllFields(&message);
+ TestParseCorruptedString<TestAllTypes, true>(message);
+ TestParseCorruptedString<TestAllTypes, false>(message);
+}
+
+#if PROTOBUF_RTTI
+// Test construction on an arena via generic MessageLite interface. We should be
+// able to successfully deserialize on the arena without incurring heap
+// allocations, i.e., everything should still be arena-allocation-aware.
+TEST(ArenaTest, MessageLiteOnArena) {
+ std::vector<char> arena_block(128 * 1024);
+ ArenaOptions options;
+ options.initial_block = &arena_block[0];
+ options.initial_block_size = arena_block.size();
+ Arena arena(options);
+ const MessageLite* prototype = &TestAllTypes::default_instance();
+
+ TestAllTypes initial_message;
+ FillArenaAwareFields(&initial_message);
+ std::string serialized;
+ initial_message.SerializeToString(&serialized);
+
+ {
+
+ MessageLite* generic_message = prototype->New(&arena);
+ EXPECT_TRUE(generic_message != NULL);
+ EXPECT_EQ(&arena, generic_message->GetArena());
+ EXPECT_TRUE(generic_message->ParseFromString(serialized));
+ TestAllTypes* deserialized = static_cast<TestAllTypes*>(generic_message);
+ EXPECT_EQ(42, deserialized->optional_int32());
+ }
+
+ arena.Reset();
+}
+#endif // PROTOBUF_RTTI
+
+// RepeatedField should support non-POD types, and invoke constructors and
+// destructors appropriately, because it's used this way by lots of other code
+// (even if this was not its original intent).
+TEST(ArenaTest, RepeatedFieldWithNonPODType) {
+ {
+ RepeatedField<std::string> field_on_heap;
+ for (int i = 0; i < 100; i++) {
+ *field_on_heap.Add() = "test string long enough to exceed inline buffer";
+ }
+ }
+ {
+ Arena arena;
+ RepeatedField<std::string> field_on_arena(&arena);
+ for (int i = 0; i < 100; i++) {
+ *field_on_arena.Add() = "test string long enough to exceed inline buffer";
+ }
+ }
+}
+
+// Align n to next multiple of 8
+uint64_t Align8(uint64_t n) { return (n + 7) & -8; }
+
+TEST(ArenaTest, SpaceAllocated_and_Used) {
+ Arena arena_1;
+ EXPECT_EQ(0, arena_1.SpaceAllocated());
+ EXPECT_EQ(0, arena_1.SpaceUsed());
+ EXPECT_EQ(0, arena_1.Reset());
+ Arena::CreateArray<char>(&arena_1, 320);
+ // Arena will allocate slightly more than 320 for the block headers.
+ EXPECT_LE(320, arena_1.SpaceAllocated());
+ EXPECT_EQ(Align8(320), arena_1.SpaceUsed());
+ EXPECT_LE(320, arena_1.Reset());
+
+ // Test with initial block.
+ std::vector<char> arena_block(1024);
+ ArenaOptions options;
+ options.start_block_size = 256;
+ options.max_block_size = 8192;
+ options.initial_block = &arena_block[0];
+ options.initial_block_size = arena_block.size();
+ Arena arena_2(options);
+ EXPECT_EQ(1024, arena_2.SpaceAllocated());
+ EXPECT_EQ(0, arena_2.SpaceUsed());
+ EXPECT_EQ(1024, arena_2.Reset());
+ Arena::CreateArray<char>(&arena_2, 55);
+ EXPECT_EQ(1024, arena_2.SpaceAllocated());
+ EXPECT_EQ(Align8(55), arena_2.SpaceUsed());
+ EXPECT_EQ(1024, arena_2.Reset());
+}
+
+TEST(ArenaTest, BlockSizeDoubling) {
+ Arena arena;
+ EXPECT_EQ(0, arena.SpaceUsed());
+ EXPECT_EQ(0, arena.SpaceAllocated());
+
+ // Allocate something to get initial block size.
+ Arena::CreateArray<char>(&arena, 1);
+ auto first_block_size = arena.SpaceAllocated();
+
+ // Keep allocating until space used increases.
+ while (arena.SpaceAllocated() == first_block_size) {
+ Arena::CreateArray<char>(&arena, 1);
+ }
+ ASSERT_GT(arena.SpaceAllocated(), first_block_size);
+ auto second_block_size = (arena.SpaceAllocated() - first_block_size);
+
+ EXPECT_EQ(second_block_size, 2*first_block_size);
+}
+
+TEST(ArenaTest, Alignment) {
+ Arena arena;
+ for (int i = 0; i < 200; i++) {
+ void* p = Arena::CreateArray<char>(&arena, i);
+ GOOGLE_CHECK_EQ(reinterpret_cast<uintptr_t>(p) % 8, 0) << i << ": " << p;
+ }
+}
+
+TEST(ArenaTest, BlockSizeSmallerThanAllocation) {
+ for (size_t i = 0; i <= 8; ++i) {
+ ArenaOptions opt;
+ opt.start_block_size = opt.max_block_size = i;
+ Arena arena(opt);
+
+ *Arena::Create<int64_t>(&arena) = 42;
+ EXPECT_GE(arena.SpaceAllocated(), 8);
+ EXPECT_EQ(8, arena.SpaceUsed());
+
+ *Arena::Create<int64_t>(&arena) = 42;
+ EXPECT_GE(arena.SpaceAllocated(), 16);
+ EXPECT_EQ(16, arena.SpaceUsed());
+ }
+}
+
+TEST(ArenaTest, GetArenaShouldReturnTheArenaForArenaAllocatedMessages) {
+ Arena arena;
+ ArenaMessage* message = Arena::CreateMessage<ArenaMessage>(&arena);
+ const ArenaMessage* const_pointer_to_message = message;
+ EXPECT_EQ(&arena, Arena::GetArena(message));
+ EXPECT_EQ(&arena, Arena::GetArena(const_pointer_to_message));
+
+ // Test that the Message* / MessageLite* specialization SFINAE works.
+ const Message* const_pointer_to_message_type = message;
+ EXPECT_EQ(&arena, Arena::GetArena(const_pointer_to_message_type));
+ const MessageLite* const_pointer_to_message_lite_type = message;
+ EXPECT_EQ(&arena, Arena::GetArena(const_pointer_to_message_lite_type));
+}
+
+TEST(ArenaTest, GetArenaShouldReturnNullForNonArenaAllocatedMessages) {
+ ArenaMessage message;
+ const ArenaMessage* const_pointer_to_message = &message;
+ EXPECT_EQ(NULL, Arena::GetArena(&message));
+ EXPECT_EQ(NULL, Arena::GetArena(const_pointer_to_message));
+}
+
+TEST(ArenaTest, GetArenaShouldReturnNullForNonArenaCompatibleTypes) {
+ // Test that GetArena returns nullptr for types that have a GetArena method
+ // that doesn't return Arena*.
+ struct {
+ int GetArena() const { return 0; }
+ } has_get_arena_method_wrong_return_type;
+ EXPECT_EQ(nullptr, Arena::GetArena(&has_get_arena_method_wrong_return_type));
+
+ // Test that GetArena returns nullptr for types that have a GetArena alias.
+ struct {
+ using GetArena = Arena*;
+ GetArena unused;
+ } has_get_arena_alias;
+ EXPECT_EQ(nullptr, Arena::GetArena(&has_get_arena_alias));
+
+ // Test that GetArena returns nullptr for types that have a GetArena data
+ // member.
+ struct {
+ Arena GetArena;
+ } has_get_arena_data_member;
+ EXPECT_EQ(nullptr, Arena::GetArena(&has_get_arena_data_member));
+}
+
+TEST(ArenaTest, AddCleanup) {
+ Arena arena;
+ for (int i = 0; i < 100; i++) {
+ arena.Own(new int);
+ }
+}
+
+namespace {
+uint32_t hooks_num_init = 0;
+uint32_t hooks_num_allocations = 0;
+uint32_t hooks_num_reset = 0;
+uint32_t hooks_num_destruct = 0;
+
+void ClearHookCounts() {
+ hooks_num_init = 0;
+ hooks_num_allocations = 0;
+ hooks_num_reset = 0;
+ hooks_num_destruct = 0;
+}
+} // namespace
+
+// A helper utility class that handles arena callbacks.
+class ArenaOptionsTestFriend final : public internal::ArenaMetricsCollector {
+ public:
+ static internal::ArenaMetricsCollector* NewWithAllocs() {
+ return new ArenaOptionsTestFriend(true);
+ }
+
+ static internal::ArenaMetricsCollector* NewWithoutAllocs() {
+ return new ArenaOptionsTestFriend(false);
+ }
+
+ static void Enable(ArenaOptions* options) {
+ ClearHookCounts();
+ options->make_metrics_collector = &ArenaOptionsTestFriend::NewWithAllocs;
+ }
+
+ static void EnableWithoutAllocs(ArenaOptions* options) {
+ ClearHookCounts();
+ options->make_metrics_collector = &ArenaOptionsTestFriend::NewWithoutAllocs;
+ }
+
+ explicit ArenaOptionsTestFriend(bool record_allocs)
+ : ArenaMetricsCollector(record_allocs) {
+ ++hooks_num_init;
+ }
+ void OnDestroy(uint64_t space_allocated) override {
+ ++hooks_num_destruct;
+ delete this;
+ }
+ void OnReset(uint64_t space_allocated) override { ++hooks_num_reset; }
+ void OnAlloc(const std::type_info* allocated_type,
+ uint64_t alloc_size) override {
+ ++hooks_num_allocations;
+ }
+};
+
+// Test the hooks are correctly called.
+TEST(ArenaTest, ArenaHooksSanity) {
+ ArenaOptions options;
+ ArenaOptionsTestFriend::Enable(&options);
+
+ // Scope for defining the arena
+ {
+ Arena arena(options);
+ EXPECT_EQ(1, hooks_num_init);
+ EXPECT_EQ(0, hooks_num_allocations);
+ Arena::Create<uint64_t>(&arena);
+ if (std::is_trivially_destructible<uint64_t>::value) {
+ EXPECT_EQ(1, hooks_num_allocations);
+ } else {
+ EXPECT_EQ(2, hooks_num_allocations);
+ }
+ arena.Reset();
+ arena.Reset();
+ EXPECT_EQ(2, hooks_num_reset);
+ }
+ EXPECT_EQ(2, hooks_num_reset);
+ EXPECT_EQ(1, hooks_num_destruct);
+}
+
+// Test that allocation hooks are not called when we don't need them.
+TEST(ArenaTest, ArenaHooksWhenAllocationsNotNeeded) {
+ ArenaOptions options;
+ ArenaOptionsTestFriend::EnableWithoutAllocs(&options);
+
+ Arena arena(options);
+ EXPECT_EQ(0, hooks_num_allocations);
+ Arena::Create<uint64_t>(&arena);
+ EXPECT_EQ(0, hooks_num_allocations);
+}
+
+
+} // namespace protobuf
+} // namespace google
+
+#include <port_undef.inc>
diff --git a/NorthstarDedicatedTest/include/protobuf/arenastring.cc b/NorthstarDedicatedTest/include/protobuf/arenastring.cc
new file mode 100644
index 00000000..622a31ce
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/arenastring.cc
@@ -0,0 +1,286 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <arenastring.h>
+
+#include <stubs/logging.h>
+#include <stubs/common.h>
+#include <parse_context.h>
+#include <io/coded_stream.h>
+#include <message_lite.h>
+#include <stubs/mutex.h>
+#include <stubs/strutil.h>
+#include <stubs/stl_util.h>
+
+// clang-format off
+#include <port_def.inc>
+// clang-format on
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+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;
+}
+
+
+std::string* ArenaStringPtr::SetAndReturnNewString() {
+ std::string* new_string = new std::string();
+ tagged_ptr_.Set(new_string);
+ return new_string;
+}
+
+void ArenaStringPtr::DestroyNoArenaSlowPath() { delete UnsafeMutablePointer(); }
+
+void ArenaStringPtr::Set(const std::string* default_value,
+ ConstStringParam value, ::google::protobuf::Arena* arena) {
+ if (IsDefault(default_value)) {
+ tagged_ptr_.Set(Arena::Create<std::string>(arena, value));
+ } else {
+ UnsafeMutablePointer()->assign(value.data(), value.length());
+ }
+}
+
+void ArenaStringPtr::Set(const std::string* default_value, std::string&& value,
+ ::google::protobuf::Arena* arena) {
+ if (IsDefault(default_value)) {
+ if (arena == nullptr) {
+ tagged_ptr_.Set(new std::string(std::move(value)));
+ } else {
+ tagged_ptr_.Set(Arena::Create<std::string>(arena, std::move(value)));
+ }
+ } else if (IsDonatedString()) {
+ std::string* current = tagged_ptr_.Get();
+ auto* s = new (current) std::string(std::move(value));
+ arena->OwnDestructor(s);
+ tagged_ptr_.Set(s);
+ } else /* !IsDonatedString() */ {
+ *UnsafeMutablePointer() = std::move(value);
+ }
+}
+
+void ArenaStringPtr::Set(EmptyDefault, ConstStringParam value,
+ ::google::protobuf::Arena* arena) {
+ Set(&GetEmptyStringAlreadyInited(), value, arena);
+}
+
+void ArenaStringPtr::Set(EmptyDefault, std::string&& value,
+ ::google::protobuf::Arena* arena) {
+ Set(&GetEmptyStringAlreadyInited(), std::move(value), arena);
+}
+
+void ArenaStringPtr::Set(NonEmptyDefault, ConstStringParam value,
+ ::google::protobuf::Arena* arena) {
+ Set(nullptr, value, arena);
+}
+
+void ArenaStringPtr::Set(NonEmptyDefault, std::string&& value,
+ ::google::protobuf::Arena* arena) {
+ Set(nullptr, std::move(value), arena);
+}
+
+std::string* ArenaStringPtr::Mutable(EmptyDefault, ::google::protobuf::Arena* arena) {
+ if (!IsDonatedString() && !IsDefault(&GetEmptyStringAlreadyInited())) {
+ return UnsafeMutablePointer();
+ } else {
+ return MutableSlow(arena);
+ }
+}
+
+std::string* ArenaStringPtr::Mutable(const LazyString& default_value,
+ ::google::protobuf::Arena* arena) {
+ if (!IsDonatedString() && !IsDefault(nullptr)) {
+ return UnsafeMutablePointer();
+ } else {
+ return MutableSlow(arena, default_value);
+ }
+}
+
+std::string* ArenaStringPtr::MutableNoCopy(const std::string* default_value,
+ ::google::protobuf::Arena* arena) {
+ if (!IsDonatedString() && !IsDefault(default_value)) {
+ return UnsafeMutablePointer();
+ } else {
+ GOOGLE_DCHECK(IsDefault(default_value));
+ // Allocate empty. The contents are not relevant.
+ std::string* new_string = Arena::Create<std::string>(arena);
+ tagged_ptr_.Set(new_string);
+ return new_string;
+ }
+}
+
+template <typename... Lazy>
+std::string* ArenaStringPtr::MutableSlow(::google::protobuf::Arena* arena,
+ const Lazy&... lazy_default) {
+ const std::string* const default_value =
+ sizeof...(Lazy) == 0 ? &GetEmptyStringAlreadyInited() : nullptr;
+ GOOGLE_DCHECK(IsDefault(default_value));
+ std::string* new_string =
+ Arena::Create<std::string>(arena, lazy_default.get()...);
+ tagged_ptr_.Set(new_string);
+ return new_string;
+}
+
+std::string* ArenaStringPtr::Release(const std::string* default_value,
+ ::google::protobuf::Arena* arena) {
+ if (IsDefault(default_value)) {
+ return nullptr;
+ } else {
+ return ReleaseNonDefault(default_value, arena);
+ }
+}
+
+std::string* ArenaStringPtr::ReleaseNonDefault(const std::string* default_value,
+ ::google::protobuf::Arena* arena) {
+ GOOGLE_DCHECK(!IsDefault(default_value));
+
+ if (!IsDonatedString()) {
+ std::string* released;
+ if (arena != nullptr) {
+ released = new std::string;
+ released->swap(*UnsafeMutablePointer());
+ } else {
+ released = UnsafeMutablePointer();
+ }
+ tagged_ptr_.Set(const_cast<std::string*>(default_value));
+ return released;
+ } else /* IsDonatedString() */ {
+ GOOGLE_DCHECK(arena != nullptr);
+ std::string* released = new std::string(Get());
+ tagged_ptr_.Set(const_cast<std::string*>(default_value));
+ return released;
+ }
+}
+
+void ArenaStringPtr::SetAllocated(const std::string* default_value,
+ std::string* value, ::google::protobuf::Arena* arena) {
+ // Release what we have first.
+ if (arena == nullptr && !IsDefault(default_value)) {
+ delete UnsafeMutablePointer();
+ }
+ if (value == nullptr) {
+ tagged_ptr_.Set(const_cast<std::string*>(default_value));
+ } else {
+#ifdef NDEBUG
+ tagged_ptr_.Set(value);
+ if (arena != nullptr) {
+ arena->Own(value);
+ }
+#else
+ // On debug builds, copy the string so the address differs. delete will
+ // fail if value was a stack-allocated temporary/etc., which would have
+ // failed when arena ran its cleanup list.
+ std::string* new_value = Arena::Create<std::string>(arena, *value);
+ delete value;
+ tagged_ptr_.Set(new_value);
+#endif
+ }
+}
+
+void ArenaStringPtr::Destroy(const std::string* default_value,
+ ::google::protobuf::Arena* arena) {
+ if (arena == nullptr) {
+ GOOGLE_DCHECK(!IsDonatedString());
+ if (!IsDefault(default_value)) {
+ delete UnsafeMutablePointer();
+ }
+ }
+}
+
+void ArenaStringPtr::Destroy(EmptyDefault, ::google::protobuf::Arena* arena) {
+ Destroy(&GetEmptyStringAlreadyInited(), arena);
+}
+
+void ArenaStringPtr::Destroy(NonEmptyDefault, ::google::protobuf::Arena* arena) {
+ Destroy(nullptr, arena);
+}
+
+void ArenaStringPtr::ClearToEmpty() {
+ if (IsDefault(&GetEmptyStringAlreadyInited())) {
+ // Already set to default -- do nothing.
+ } else {
+ // Unconditionally mask away the tag.
+ //
+ // UpdateDonatedString uses assign when capacity is larger than the new
+ // value, which is trivially true in the donated string case.
+ // const_cast<std::string*>(PtrValue<std::string>())->clear();
+ tagged_ptr_.Get()->clear();
+ }
+}
+
+void ArenaStringPtr::ClearToDefault(const LazyString& default_value,
+ ::google::protobuf::Arena* arena) {
+ (void)arena;
+ if (IsDefault(nullptr)) {
+ // Already set to default -- do nothing.
+ } else if (!IsDonatedString()) {
+ UnsafeMutablePointer()->assign(default_value.get());
+ }
+}
+
+inline void SetStrWithHeapBuffer(std::string* str, ArenaStringPtr* s) {
+ TaggedPtr<std::string> res;
+ res.Set(str);
+ s->UnsafeSetTaggedPointer(res);
+}
+
+const char* EpsCopyInputStream::ReadArenaString(const char* ptr,
+ ArenaStringPtr* s,
+ Arena* arena) {
+ GOOGLE_DCHECK(arena != nullptr);
+
+ int size = ReadSize(&ptr);
+ if (!ptr) return nullptr;
+
+ auto* str = Arena::Create<std::string>(arena);
+ ptr = ReadString(ptr, size, str);
+ GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+
+ SetStrWithHeapBuffer(str, s);
+
+ return ptr;
+}
+
+} // namespace internal
+} // namespace protobuf
+} // namespace google
+
+#include <port_undef.inc>
diff --git a/NorthstarDedicatedTest/include/protobuf/arenastring.h b/NorthstarDedicatedTest/include/protobuf/arenastring.h
new file mode 100644
index 00000000..573cd4a4
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/arenastring.h
@@ -0,0 +1,420 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef GOOGLE_PROTOBUF_ARENASTRING_H__
+#define GOOGLE_PROTOBUF_ARENASTRING_H__
+
+#include <string>
+#include <type_traits>
+#include <utility>
+
+#include <stubs/logging.h>
+#include <stubs/common.h>
+#include <arena.h>
+#include <port.h>
+
+#include <port_def.inc>
+
+#ifdef SWIG
+#error "You cannot SWIG proto headers"
+#endif
+
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+template <typename T>
+class ExplicitlyConstructed;
+
+class SwapFieldHelper;
+
+// Lazy string instance to support string fields with non-empty default.
+// These are initialized on the first call to .get().
+class PROTOBUF_EXPORT LazyString {
+ public:
+ // We explicitly make LazyString an aggregate so that MSVC can do constant
+ // initialization on it without marking it `constexpr`.
+ // We do not want to use `constexpr` because it makes it harder to have extern
+ // storage for it and causes library bloat.
+ struct InitValue {
+ const char* ptr;
+ size_t size;
+ };
+ // We keep a union of the initialization value and the 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;
+};
+
+template <typename T>
+class TaggedPtr {
+ public:
+ TaggedPtr() = default;
+ explicit constexpr TaggedPtr(const ExplicitlyConstructed<std::string>* ptr)
+ : ptr_(const_cast<ExplicitlyConstructed<std::string>*>(ptr)) {}
+
+ void SetTagged(T* p) {
+ Set(p);
+ ptr_ = reinterpret_cast<void*>(as_int() | 1);
+ }
+ void Set(T* p) { ptr_ = p; }
+ T* Get() const { return reinterpret_cast<T*>(as_int() & -2); }
+ bool IsTagged() const { return as_int() & 1; }
+
+ // Returned value is only safe to dereference if IsTagged() == false.
+ // It is safe to compare.
+ T* UnsafeGet() const { return static_cast<T*>(ptr_); }
+
+ bool IsNull() { return ptr_ == nullptr; }
+
+ private:
+ uintptr_t as_int() const { return reinterpret_cast<uintptr_t>(ptr_); }
+ void* ptr_;
+};
+
+static_assert(std::is_trivial<TaggedPtr<std::string>>::value,
+ "TaggedPtr must be trivial");
+
+// This class encapsulates a pointer to a std::string with or without a donated
+// buffer, tagged by bottom bit. It is a high-level wrapper that almost directly
+// corresponds to the interface required by string fields in generated
+// code. It replaces the old std::string* pointer in such cases.
+//
+// The object has different but similar code paths for when the default value is
+// the empty string and when it is a non-empty string.
+// The empty string is handled different throughout the library and there is a
+// single global instance of it we can share.
+//
+// For fields with an empty string default value, there are three distinct
+// states:
+//
+// - Pointer set to 'String' tag (LSB is 0), equal to
+// &GetEmptyStringAlreadyInited(): field is set to its default value. Points
+// to a true std::string*, but we do not own that std::string* (it's a
+// globally shared instance).
+//
+// - Pointer set to 'String' tag (LSB is 0), but not equal to the global empty
+// string: field points to a true std::string* instance that we own. This
+// instance is either on the heap or on the arena (i.e. registered on
+// free()/destructor-call list) as appropriate.
+//
+// - Pointer set to 'DonatedString' tag (LSB is 1): points to a std::string
+// instance with a buffer on the arena (arena is never nullptr in this case).
+//
+// For fields with a non-empty string default value, there are three distinct
+// states:
+//
+// - Pointer set to 'String' tag (LSB is 0), equal to `nullptr`:
+// Field is in "default" mode and does not point to any actual instance.
+// Methods that might need to create an instance of the object will pass a
+// `const LazyString&` for it.
+//
+// - Pointer set to 'String' tag (LSB is 0), but not equal to `nullptr`:
+// field points to a true std::string* instance that we own. This instance is
+// either on the heap or on the arena (i.e. registered on
+// free()/destructor-call list) as appropriate.
+//
+// - Pointer set to 'DonatedString' tag (LSB is 1): points to a std::string
+// instance with a buffer on the arena (arena is never nullptr in this case).
+//
+// Generated code and reflection code both ensure that ptr_ is never null for
+// fields with an empty default.
+// Because ArenaStringPtr is used in oneof unions, its constructor is a NOP and
+// so the field is always manually initialized via method calls.
+//
+// Side-note: why pass information about the default on every API call? Because
+// we don't want to hold it in a member variable, or else this would go into
+// every proto message instance. This would be a huge waste of space, since the
+// default instance pointer is typically a global (static class field). We want
+// the generated code to be as efficient as possible, and if we take
+// the default value information as a parameter that's in practice taken from a
+// static class field, and compare ptr_ to the default value, we end up with a
+// single "cmp %reg, GLOBAL" in the resulting machine code. (Note that this also
+// requires the String tag to be 0 so we can avoid the mask before comparing.)
+struct PROTOBUF_EXPORT ArenaStringPtr {
+ ArenaStringPtr() = default;
+ explicit constexpr ArenaStringPtr(
+ const ExplicitlyConstructed<std::string>* default_value)
+ : tagged_ptr_(default_value) {}
+
+ // Some methods below are overloaded on a `default_value` and on tags.
+ // The tagged overloads help reduce code size in the callers in generated
+ // code, while the `default_value` overloads are useful from reflection.
+ // By-value empty struct arguments are elided in the ABI.
+ struct EmptyDefault {};
+ struct NonEmptyDefault {};
+
+ void Set(const std::string* default_value, ConstStringParam value,
+ ::google::protobuf::Arena* arena);
+ void Set(const std::string* default_value, std::string&& value,
+ ::google::protobuf::Arena* arena);
+ void Set(EmptyDefault, ConstStringParam value, ::google::protobuf::Arena* arena);
+ void Set(EmptyDefault, std::string&& value, ::google::protobuf::Arena* arena);
+ void Set(NonEmptyDefault, ConstStringParam value, ::google::protobuf::Arena* arena);
+ void Set(NonEmptyDefault, std::string&& value, ::google::protobuf::Arena* arena);
+ template <typename FirstParam>
+ void Set(FirstParam p1, const char* str, ::google::protobuf::Arena* arena) {
+ Set(p1, ConstStringParam(str), arena);
+ }
+ template <typename FirstParam>
+ void Set(FirstParam p1, const char* str, size_t size,
+ ::google::protobuf::Arena* arena) {
+ ConstStringParam sp{str, size}; // for string_view and `const string &`
+ Set(p1, sp, arena);
+ }
+ template <typename FirstParam, typename RefWrappedType>
+ void Set(FirstParam p1,
+ std::reference_wrapper<RefWrappedType> const_string_ref,
+ ::google::protobuf::Arena* arena) {
+ Set(p1, const_string_ref.get(), arena);
+ }
+
+ template <typename FirstParam, typename SecondParam>
+ void SetBytes(FirstParam p1, SecondParam&& p2, ::google::protobuf::Arena* arena) {
+ Set(p1, static_cast<SecondParam&&>(p2), arena);
+ }
+ template <typename FirstParam>
+ void SetBytes(FirstParam p1, const void* str, size_t size,
+ ::google::protobuf::Arena* arena) {
+ // must work whether ConstStringParam is string_view or `const string &`
+ ConstStringParam sp{static_cast<const char*>(str), size};
+ Set(p1, sp, arena);
+ }
+
+ // Basic accessors.
+ PROTOBUF_NDEBUG_INLINE const std::string& Get() const {
+ // Unconditionally mask away the tag.
+ return *tagged_ptr_.Get();
+ }
+ PROTOBUF_NDEBUG_INLINE const std::string* GetPointer() const {
+ // Unconditionally mask away the tag.
+ return tagged_ptr_.Get();
+ }
+
+ // For fields with an empty default value.
+ std::string* Mutable(EmptyDefault, ::google::protobuf::Arena* arena);
+ // For fields with a non-empty default value.
+ std::string* Mutable(const LazyString& default_value, ::google::protobuf::Arena* arena);
+
+ // 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(const std::string* default_value,
+ ::google::protobuf::Arena* arena);
+ PROTOBUF_NODISCARD std::string* ReleaseNonDefault(
+ const std::string* default_value, ::google::protobuf::Arena* arena);
+
+ // 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(const std::string* default_value, std::string* value,
+ ::google::protobuf::Arena* arena);
+
+ // Swaps internal pointers. Arena-safety semantics: this is guarded by the
+ // logic in Swap()/UnsafeArenaSwap() at the message level, so this method is
+ // 'unsafe' if called directly.
+ inline PROTOBUF_NDEBUG_INLINE static void InternalSwap(
+ const std::string* default_value, ArenaStringPtr* rhs, Arena* rhs_arena,
+ ArenaStringPtr* lhs, Arena* lhs_arena);
+
+ // Frees storage (if not on an arena).
+ void Destroy(const std::string* default_value, ::google::protobuf::Arena* arena);
+ void Destroy(EmptyDefault, ::google::protobuf::Arena* arena);
+ void Destroy(NonEmptyDefault, ::google::protobuf::Arena* arena);
+
+ // Clears content, but keeps allocated 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);
+
+ // Called from generated code / reflection runtime only. Resets value to point
+ // to a default string pointer, with the semantics that this
+ // ArenaStringPtr does not own the pointed-to memory. Disregards initial value
+ // of ptr_ (so this is the *ONLY* safe method to call after construction or
+ // when reinitializing after becoming the active field in a oneof union).
+ inline void UnsafeSetDefault(const std::string* default_value);
+
+ // Returns a mutable pointer, but doesn't initialize the string to the
+ // default value.
+ std::string* MutableNoArenaNoDefault(const std::string* default_value);
+
+ // Get a mutable pointer with unspecified contents.
+ // Similar to `MutableNoArenaNoDefault`, but also handles the arena case.
+ // If the value was donated, the contents are discarded.
+ std::string* MutableNoCopy(const std::string* default_value,
+ ::google::protobuf::Arena* arena);
+
+ // Destroy the string. Assumes `arena == nullptr`.
+ void DestroyNoArena(const std::string* default_value);
+
+ // Internal setter used only at parse time to directly set a donated string
+ // value.
+ void UnsafeSetTaggedPointer(TaggedPtr<std::string> 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;
+
+ inline bool IsDefault(const std::string* default_value) const {
+ // Relies on the fact that kPtrTagString == 0, so if IsString(), ptr_ is the
+ // actual std::string pointer (and if !IsString(), ptr_ will never be equal
+ // to any aligned |default_value| pointer). The key is that we want to avoid
+ // masking in the fastpath const-pointer Get() case for non-arena code.
+ return tagged_ptr_.UnsafeGet() == default_value;
+ }
+
+ private:
+ TaggedPtr<std::string> tagged_ptr_;
+
+ bool IsDonatedString() const { return false; }
+
+ // Swaps tagged pointer without debug hardening. This is to allow python
+ // protobuf to maintain pointer stability even in DEBUG builds.
+ inline PROTOBUF_NDEBUG_INLINE static void UnsafeShallowSwap(
+ ArenaStringPtr* rhs, ArenaStringPtr* lhs) {
+ std::swap(lhs->tagged_ptr_, rhs->tagged_ptr_);
+ }
+
+ friend class ::google::protobuf::internal::SwapFieldHelper;
+
+ // Slow paths.
+
+ // MutableSlow requires that !IsString() || IsDefault
+ // Variadic to support 0 args for EmptyDefault and 1 arg for LazyString.
+ template <typename... Lazy>
+ std::string* MutableSlow(::google::protobuf::Arena* arena, const Lazy&... lazy_default);
+
+ // Sets value to a newly allocated string and returns it
+ std::string* SetAndReturnNewString();
+
+ // Destroys the non-default string value out-of-line
+ void DestroyNoArenaSlowPath();
+
+};
+
+inline void ArenaStringPtr::UnsafeSetDefault(const std::string* value) {
+ tagged_ptr_.Set(const_cast<std::string*>(value));
+}
+
+// Make sure rhs_arena allocated rhs, and lhs_arena allocated lhs.
+inline PROTOBUF_NDEBUG_INLINE void ArenaStringPtr::InternalSwap( //
+ const std::string* default_value, //
+ ArenaStringPtr* rhs, Arena* rhs_arena, //
+ ArenaStringPtr* lhs, Arena* lhs_arena) {
+ // Silence unused variable warnings in release buildls.
+ (void)default_value;
+ (void)rhs_arena;
+ (void)lhs_arena;
+ std::swap(lhs->tagged_ptr_, rhs->tagged_ptr_);
+#ifdef PROTOBUF_FORCE_COPY_IN_SWAP
+ auto force_realloc = [default_value](ArenaStringPtr* p, Arena* arena) {
+ if (p->IsDefault(default_value)) return;
+ std::string* old_value = p->tagged_ptr_.Get();
+ std::string* new_value =
+ p->IsDonatedString()
+ ? 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_.Set(new_value);
+ };
+ // Because, at this point, tagged_ptr_ has been swapped, arena should also be
+ // swapped.
+ force_realloc(lhs, rhs_arena);
+ force_realloc(rhs, lhs_arena);
+#endif // PROTOBUF_FORCE_COPY_IN_SWAP
+}
+
+inline void ArenaStringPtr::ClearNonDefaultToEmpty() {
+ // Unconditionally mask away the tag.
+ tagged_ptr_.Get()->clear();
+}
+
+inline std::string* ArenaStringPtr::MutableNoArenaNoDefault(
+ const std::string* default_value) {
+ // VERY IMPORTANT for performance and code size: this will reduce to a member
+ // variable load, a pointer check (against |default_value|, in practice a
+ // static global) and a branch to the slowpath (which calls operator new and
+ // the ctor). DO NOT add any tagged-pointer operations here.
+ if (IsDefault(default_value)) {
+ return SetAndReturnNewString();
+ } else {
+ return UnsafeMutablePointer();
+ }
+}
+
+inline void ArenaStringPtr::DestroyNoArena(const std::string* default_value) {
+ if (!IsDefault(default_value)) {
+ DestroyNoArenaSlowPath();
+ }
+}
+
+inline std::string* ArenaStringPtr::UnsafeMutablePointer() {
+ GOOGLE_DCHECK(!tagged_ptr_.IsTagged());
+ GOOGLE_DCHECK(tagged_ptr_.UnsafeGet() != nullptr);
+ return tagged_ptr_.UnsafeGet();
+}
+
+
+} // namespace internal
+} // namespace protobuf
+} // namespace google
+
+#include <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_ARENASTRING_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/arenastring_unittest.cc b/NorthstarDedicatedTest/include/protobuf/arenastring_unittest.cc
new file mode 100644
index 00000000..494f01ad
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/arenastring_unittest.cc
@@ -0,0 +1,157 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <arenastring.h>
+
+#include <algorithm>
+#include <cstdlib>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include <stubs/logging.h>
+#include <stubs/common.h>
+#include <io/coded_stream.h>
+#include <io/zero_copy_stream_impl.h>
+#include <generated_message_util.h>
+#include <message_lite.h>
+#include <gtest/gtest.h>
+#include <stubs/strutil.h>
+
+
+// Must be included last.
+#include <port_def.inc>
+
+namespace google {
+namespace protobuf {
+
+using internal::ArenaStringPtr;
+
+using EmptyDefault = ArenaStringPtr::EmptyDefault;
+
+const internal::LazyString nonempty_default{{{"default", 7}}, {nullptr}};
+const std::string* empty_default = &internal::GetEmptyString();
+
+class SingleArena : public testing::TestWithParam<bool> {
+ public:
+ std::unique_ptr<Arena> GetArena() {
+ if (this->GetParam()) return nullptr;
+ return std::unique_ptr<Arena>(new Arena());
+ }
+};
+
+INSTANTIATE_TEST_SUITE_P(ArenaString, SingleArena, testing::Bool());
+
+TEST_P(SingleArena, GetSet) {
+ auto arena = GetArena();
+ ArenaStringPtr field;
+ field.UnsafeSetDefault(empty_default);
+ EXPECT_EQ("", field.Get());
+ field.Set(empty_default, "Test short", arena.get());
+ EXPECT_EQ("Test short", field.Get());
+ field.Set(empty_default, "Test long long long long value", arena.get());
+ EXPECT_EQ("Test long long long long value", field.Get());
+ field.Set(empty_default, "", arena.get());
+ field.Destroy(empty_default, arena.get());
+}
+
+TEST_P(SingleArena, MutableAccessor) {
+ auto arena = GetArena();
+ ArenaStringPtr field;
+ const std::string* empty_default = &internal::GetEmptyString();
+ field.UnsafeSetDefault(empty_default);
+
+ std::string* mut = field.Mutable(EmptyDefault{}, arena.get());
+ EXPECT_EQ(mut, field.Mutable(EmptyDefault{}, arena.get()));
+ EXPECT_EQ(mut, &field.Get());
+ EXPECT_NE(empty_default, mut);
+ EXPECT_EQ("", *mut);
+ *mut = "Test long long long long value"; // ensure string allocates storage
+ EXPECT_EQ("Test long long long long value", field.Get());
+ field.Destroy(empty_default, arena.get());
+}
+
+TEST_P(SingleArena, NullDefault) {
+ auto arena = GetArena();
+
+ ArenaStringPtr field;
+ field.UnsafeSetDefault(nullptr);
+ std::string* mut = field.Mutable(nonempty_default, arena.get());
+ EXPECT_EQ(mut, field.Mutable(nonempty_default, arena.get()));
+ EXPECT_EQ(mut, &field.Get());
+ EXPECT_NE(nullptr, mut);
+ EXPECT_EQ("default", *mut);
+ *mut = "Test long long long long value"; // ensure string allocates storage
+ EXPECT_EQ("Test long long long long value", field.Get());
+ field.Destroy(nullptr, arena.get());
+}
+
+class DualArena : public testing::TestWithParam<std::tuple<bool, bool>> {
+ public:
+ std::unique_ptr<Arena> GetLhsArena() {
+ if (std::get<0>(this->GetParam())) return nullptr;
+ return std::unique_ptr<Arena>(new Arena());
+ }
+ std::unique_ptr<Arena> GetRhsArena() {
+ if (std::get<1>(this->GetParam())) return nullptr;
+ return std::unique_ptr<Arena>(new Arena());
+ }
+};
+
+INSTANTIATE_TEST_SUITE_P(ArenaString, DualArena,
+ testing::Combine(testing::Bool(), testing::Bool()));
+
+TEST_P(DualArena, Swap) {
+ auto lhs_arena = GetLhsArena();
+ ArenaStringPtr lhs;
+ lhs.UnsafeSetDefault(empty_default);
+ ArenaStringPtr rhs;
+ rhs.UnsafeSetDefault(empty_default);
+
+ {
+ auto rhs_arena = GetRhsArena();
+ lhs.Set(empty_default, "lhs value that has some heft", lhs_arena.get());
+ rhs.Set(empty_default, "rhs value that has some heft", rhs_arena.get());
+ ArenaStringPtr::InternalSwap(empty_default, //
+ &lhs, lhs_arena.get(), //
+ &rhs, rhs_arena.get());
+ EXPECT_EQ("rhs value that has some heft", lhs.Get());
+ EXPECT_EQ("lhs value that has some heft", rhs.Get());
+ lhs.Destroy(empty_default, rhs_arena.get());
+ }
+ EXPECT_EQ("lhs value that has some heft", rhs.Get());
+ rhs.Destroy(empty_default, lhs_arena.get());
+}
+
+
+} // namespace protobuf
+} // namespace google
+
+#include <port_undef.inc>
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/annotation_test_util.cc b/NorthstarDedicatedTest/include/protobuf/compiler/annotation_test_util.cc
new file mode 100644
index 00000000..0ffa4c08
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/annotation_test_util.cc
@@ -0,0 +1,168 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 <compiler/annotation_test_util.h>
+
+#include <cstdint>
+#include <memory>
+
+#include <testing/file.h>
+#include <testing/file.h>
+#include <compiler/code_generator.h>
+#include <compiler/command_line_interface.h>
+#include <io/printer.h>
+#include <io/zero_copy_stream.h>
+#include <io/zero_copy_stream_impl_lite.h>
+#include <descriptor.pb.h>
+#include <testing/googletest.h>
+#include <gtest/gtest.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace annotation_test_util {
+namespace {
+
+// A CodeGenerator that captures the FileDescriptor it's passed as a
+// FileDescriptorProto.
+class DescriptorCapturingGenerator : public CodeGenerator {
+ public:
+ // Does not own file; file must outlive the Generator.
+ explicit DescriptorCapturingGenerator(FileDescriptorProto* file)
+ : file_(file) {}
+
+ virtual bool Generate(const FileDescriptor* file,
+ const std::string& parameter, GeneratorContext* context,
+ std::string* error) const {
+ file->CopyTo(file_);
+ return true;
+ }
+
+ private:
+ FileDescriptorProto* file_;
+};
+} // namespace
+
+void AddFile(const std::string& filename, const std::string& data) {
+ GOOGLE_CHECK_OK(File::SetContents(TestTempDir() + "/" + filename, data,
+ true));
+}
+
+bool RunProtoCompiler(const std::string& filename,
+ const std::string& plugin_specific_args,
+ CommandLineInterface* cli, FileDescriptorProto* file) {
+ cli->SetInputsAreProtoPathRelative(true);
+
+ DescriptorCapturingGenerator capturing_generator(file);
+ cli->RegisterGenerator("--capture_out", &capturing_generator, "");
+
+ std::string proto_path = "-I" + TestTempDir();
+ std::string capture_out = "--capture_out=" + TestTempDir();
+
+ const char* argv[] = {"protoc", proto_path.c_str(),
+ plugin_specific_args.c_str(), capture_out.c_str(),
+ filename.c_str()};
+
+ return cli->Run(5, argv) == 0;
+}
+
+bool DecodeMetadata(const std::string& path, GeneratedCodeInfo* info) {
+ std::string data;
+ GOOGLE_CHECK_OK(File::GetContents(path, &data, true));
+ io::ArrayInputStream input(data.data(), data.size());
+ return info->ParseFromZeroCopyStream(&input);
+}
+
+void FindAnnotationsOnPath(
+ const GeneratedCodeInfo& info, const std::string& source_file,
+ const std::vector<int>& path,
+ std::vector<const GeneratedCodeInfo::Annotation*>* annotations) {
+ for (int i = 0; i < info.annotation_size(); ++i) {
+ const GeneratedCodeInfo::Annotation* annotation = &info.annotation(i);
+ if (annotation->source_file() != source_file ||
+ annotation->path_size() != path.size()) {
+ continue;
+ }
+ int node = 0;
+ for (; node < path.size(); ++node) {
+ if (annotation->path(node) != path[node]) {
+ break;
+ }
+ }
+ if (node == path.size()) {
+ annotations->push_back(annotation);
+ }
+ }
+}
+
+const GeneratedCodeInfo::Annotation* FindAnnotationOnPath(
+ const GeneratedCodeInfo& info, const std::string& source_file,
+ const std::vector<int>& path) {
+ std::vector<const GeneratedCodeInfo::Annotation*> annotations;
+ FindAnnotationsOnPath(info, source_file, path, &annotations);
+ if (annotations.empty()) {
+ return NULL;
+ }
+ return annotations[0];
+}
+
+bool AtLeastOneAnnotationMatchesSubstring(
+ const std::string& file_content,
+ const std::vector<const GeneratedCodeInfo::Annotation*>& annotations,
+ const std::string& expected_text) {
+ for (std::vector<const GeneratedCodeInfo::Annotation*>::const_iterator
+ i = annotations.begin(),
+ e = annotations.end();
+ i != e; ++i) {
+ const GeneratedCodeInfo::Annotation* annotation = *i;
+ uint32_t begin = annotation->begin();
+ uint32_t end = annotation->end();
+ if (end < begin || end > file_content.size()) {
+ return false;
+ }
+ if (file_content.substr(begin, end - begin) == expected_text) {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool AnnotationMatchesSubstring(const std::string& file_content,
+ const GeneratedCodeInfo::Annotation* annotation,
+ const std::string& expected_text) {
+ std::vector<const GeneratedCodeInfo::Annotation*> annotations;
+ annotations.push_back(annotation);
+ return AtLeastOneAnnotationMatchesSubstring(file_content, annotations,
+ expected_text);
+}
+} // namespace annotation_test_util
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/annotation_test_util.h b/NorthstarDedicatedTest/include/protobuf/compiler/annotation_test_util.h
new file mode 100644
index 00000000..2fd179cd
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/annotation_test_util.h
@@ -0,0 +1,115 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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_COMPILER_ANNOTATION_TEST_UTIL_H__
+#define GOOGLE_PROTOBUF_COMPILER_ANNOTATION_TEST_UTIL_H__
+
+#include <descriptor.pb.h>
+#include <testing/googletest.h>
+#include <gtest/gtest.h>
+
+// Utilities that assist in writing tests for generator annotations.
+// See java/internal/annotation_unittest.cc for an example.
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace annotation_test_util {
+
+// Struct that contains the file generated from a .proto file and its
+// GeneratedCodeInfo. For example, the Java generator will fill this struct
+// (for some 'foo.proto') with:
+// file_path = "Foo.java"
+// file_content = content of Foo.java
+// file_info = parsed content of Foo.java.pb.meta
+struct ExpectedOutput {
+ std::string file_path;
+ std::string file_content;
+ GeneratedCodeInfo file_info;
+ explicit ExpectedOutput(const std::string& file_path)
+ : file_path(file_path) {}
+};
+
+// Creates a file with name `filename` and content `data` in temp test
+// directory.
+void AddFile(const std::string& filename, const std::string& data);
+
+// Runs proto compiler. Captures proto file structure in FileDescriptorProto.
+// Files will be generated in TestTempDir() folder. Callers of this
+// function must read generated files themselves.
+//
+// filename: source .proto file used to generate code.
+// plugin_specific_args: command line arguments specific to current generator.
+// For Java, this value might be "--java_out=annotate_code:test_temp_dir"
+// cli: instance of command line interface to run generator. See Java's
+// annotation_unittest.cc for an example of how to initialize it.
+// file: output parameter, will be set to the descriptor of the proto file
+// specified in filename.
+bool RunProtoCompiler(const std::string& filename,
+ const std::string& plugin_specific_args,
+ CommandLineInterface* cli, FileDescriptorProto* file);
+
+bool DecodeMetadata(const std::string& path, GeneratedCodeInfo* info);
+
+// Finds all of the Annotations for a given source file and path.
+// See Location.path in https://github.com/protocolbuffers/protobuf/blob/master/src/google/protobuf/descriptor.proto for
+// explanation of what path vector is.
+void FindAnnotationsOnPath(
+ const GeneratedCodeInfo& info, const std::string& source_file,
+ const std::vector<int>& path,
+ std::vector<const GeneratedCodeInfo::Annotation*>* annotations);
+
+// Finds the Annotation for a given source file and path (or returns null if it
+// couldn't). If there are several annotations for given path, returns the first
+// one. See Location.path in
+// https://github.com/protocolbuffers/protobuf/blob/master/src/google/protobuf/descriptor.proto for explanation of what path
+// vector is.
+const GeneratedCodeInfo::Annotation* FindAnnotationOnPath(
+ const GeneratedCodeInfo& info, const std::string& source_file,
+ const std::vector<int>& path);
+
+// Returns true if at least one of the provided annotations covers a given
+// substring in file_content.
+bool AtLeastOneAnnotationMatchesSubstring(
+ const std::string& file_content,
+ const std::vector<const GeneratedCodeInfo::Annotation*>& annotations,
+ const std::string& expected_text);
+
+// Returns true if the provided annotation covers a given substring in
+// file_content.
+bool AnnotationMatchesSubstring(const std::string& file_content,
+ const GeneratedCodeInfo::Annotation* annotation,
+ const std::string& expected_text);
+
+} // namespace annotation_test_util
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_COMPILER_ANNOTATION_TEST_UTIL_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/code_generator.cc b/NorthstarDedicatedTest/include/protobuf/compiler/code_generator.cc
new file mode 100644
index 00000000..fd33d895
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/code_generator.cc
@@ -0,0 +1,137 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 <compiler/code_generator.h>
+
+#include <stubs/logging.h>
+#include <stubs/common.h>
+#include <compiler/plugin.pb.h>
+#include <descriptor.h>
+#include <stubs/strutil.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+
+CodeGenerator::~CodeGenerator() {}
+
+bool CodeGenerator::GenerateAll(const std::vector<const FileDescriptor*>& files,
+ const std::string& parameter,
+ GeneratorContext* generator_context,
+ std::string* error) const {
+ // Default implementation is just to call the per file method, and prefix any
+ // error string with the file to provide context.
+ bool succeeded = true;
+ for (int i = 0; i < files.size(); i++) {
+ const FileDescriptor* file = files[i];
+ succeeded = Generate(file, parameter, generator_context, error);
+ if (!succeeded && error && error->empty()) {
+ *error =
+ "Code generator returned false but provided no error "
+ "description.";
+ }
+ if (error && !error->empty()) {
+ *error = file->name() + ": " + *error;
+ break;
+ }
+ if (!succeeded) {
+ break;
+ }
+ }
+ return succeeded;
+}
+
+GeneratorContext::~GeneratorContext() {}
+
+io::ZeroCopyOutputStream* GeneratorContext::OpenForAppend(
+ const std::string& filename) {
+ return NULL;
+}
+
+io::ZeroCopyOutputStream* GeneratorContext::OpenForInsert(
+ const std::string& filename, const std::string& insertion_point) {
+ GOOGLE_LOG(FATAL) << "This GeneratorContext does not support insertion.";
+ return NULL; // make compiler happy
+}
+
+io::ZeroCopyOutputStream* GeneratorContext::OpenForInsertWithGeneratedCodeInfo(
+ const std::string& filename, const std::string& insertion_point,
+ const google::protobuf::GeneratedCodeInfo& /*info*/) {
+ return OpenForInsert(filename, insertion_point);
+}
+
+void GeneratorContext::ListParsedFiles(
+ std::vector<const FileDescriptor*>* output) {
+ GOOGLE_LOG(FATAL) << "This GeneratorContext does not support ListParsedFiles";
+}
+
+void GeneratorContext::GetCompilerVersion(Version* version) const {
+ version->set_major(GOOGLE_PROTOBUF_VERSION / 1000000);
+ version->set_minor(GOOGLE_PROTOBUF_VERSION / 1000 % 1000);
+ version->set_patch(GOOGLE_PROTOBUF_VERSION % 1000);
+ version->set_suffix(GOOGLE_PROTOBUF_VERSION_SUFFIX);
+}
+
+// Parses a set of comma-delimited name/value pairs.
+void ParseGeneratorParameter(
+ const std::string& text,
+ std::vector<std::pair<std::string, std::string> >* output) {
+ std::vector<std::string> parts = Split(text, ",", true);
+
+ for (int i = 0; i < parts.size(); i++) {
+ std::string::size_type equals_pos = parts[i].find_first_of('=');
+ std::pair<std::string, std::string> value;
+ if (equals_pos == std::string::npos) {
+ value.first = parts[i];
+ value.second = "";
+ } else {
+ value.first = parts[i].substr(0, equals_pos);
+ value.second = parts[i].substr(equals_pos + 1);
+ }
+ output->push_back(value);
+ }
+}
+
+// Strips ".proto" or ".protodevel" from the end of a filename.
+std::string StripProto(const std::string& filename) {
+ if (HasSuffixString(filename, ".protodevel")) {
+ return StripSuffixString(filename, ".protodevel");
+ } else {
+ return StripSuffixString(filename, ".proto");
+ }
+}
+
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/code_generator.h b/NorthstarDedicatedTest/include/protobuf/compiler/code_generator.h
new file mode 100644
index 00000000..ac2cf004
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/code_generator.h
@@ -0,0 +1,206 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 the abstract interface implemented by each of the language-specific
+// code generators.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_CODE_GENERATOR_H__
+#define GOOGLE_PROTOBUF_COMPILER_CODE_GENERATOR_H__
+
+#include <string>
+#include <utility>
+#include <vector>
+#include <stubs/common.h>
+
+#include <port_def.inc>
+
+namespace google {
+namespace protobuf {
+
+namespace io {
+class ZeroCopyOutputStream;
+}
+class FileDescriptor;
+class GeneratedCodeInfo;
+
+namespace compiler {
+class AccessInfoMap;
+
+class Version;
+
+// Defined in this file.
+class CodeGenerator;
+class GeneratorContext;
+
+// The abstract interface to a class which generates code implementing a
+// particular proto file in a particular language. A number of these may
+// be registered with CommandLineInterface to support various languages.
+class PROTOC_EXPORT CodeGenerator {
+ public:
+ inline CodeGenerator() {}
+ virtual ~CodeGenerator();
+
+ // Generates code for the given proto file, generating one or more files in
+ // the given output directory.
+ //
+ // A parameter to be passed to the generator can be specified on the command
+ // line. This is intended to be used to pass generator specific parameters.
+ // It is empty if no parameter was given. ParseGeneratorParameter (below),
+ // can be used to accept multiple parameters within the single parameter
+ // command line flag.
+ //
+ // Returns true if successful. Otherwise, sets *error to a description of
+ // the problem (e.g. "invalid parameter") and returns false.
+ virtual bool Generate(const FileDescriptor* file,
+ const std::string& parameter,
+ GeneratorContext* generator_context,
+ std::string* error) const = 0;
+
+ // Generates code for all given proto files.
+ //
+ // WARNING: The canonical code generator design produces one or two output
+ // files per input .proto file, and we do not wish to encourage alternate
+ // designs.
+ //
+ // A parameter is given as passed on the command line, as in |Generate()|
+ // above.
+ //
+ // Returns true if successful. Otherwise, sets *error to a description of
+ // the problem (e.g. "invalid parameter") and returns false.
+ virtual bool GenerateAll(const std::vector<const FileDescriptor*>& files,
+ const std::string& parameter,
+ GeneratorContext* generator_context,
+ std::string* error) const;
+
+ // This must be kept in sync with plugin.proto. See that file for
+ // documentation on each value.
+ enum Feature {
+ FEATURE_PROTO3_OPTIONAL = 1,
+ };
+
+ // Implement this to indicate what features this code generator supports.
+ //
+ // This must be a bitwise OR of values from the Feature enum above (or zero).
+ virtual uint64_t GetSupportedFeatures() const { return 0; }
+
+ // This is no longer used, but this class is part of the opensource protobuf
+ // library, so it has to remain to keep vtables the same for the current
+ // version of the library. When protobufs does a api breaking change, the
+ // method can be removed.
+ virtual bool HasGenerateAll() const { return true; }
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CodeGenerator);
+};
+
+// CodeGenerators generate one or more files in a given directory. This
+// abstract interface represents the directory to which the CodeGenerator is
+// to write and other information about the context in which the Generator
+// runs.
+class PROTOC_EXPORT GeneratorContext {
+ public:
+ inline GeneratorContext() {
+ }
+ virtual ~GeneratorContext();
+
+ // Opens the given file, truncating it if it exists, and returns a
+ // ZeroCopyOutputStream that writes to the file. The caller takes ownership
+ // of the returned object. This method never fails (a dummy stream will be
+ // returned instead).
+ //
+ // The filename given should be relative to the root of the source tree.
+ // E.g. the C++ generator, when generating code for "foo/bar.proto", will
+ // generate the files "foo/bar.pb.h" and "foo/bar.pb.cc"; note that
+ // "foo/" is included in these filenames. The filename is not allowed to
+ // contain "." or ".." components.
+ virtual io::ZeroCopyOutputStream* Open(const std::string& filename) = 0;
+
+ // Similar to Open() but the output will be appended to the file if exists
+ virtual io::ZeroCopyOutputStream* OpenForAppend(const std::string& filename);
+
+ // Creates a ZeroCopyOutputStream which will insert code into the given file
+ // at the given insertion point. See plugin.proto (plugin.pb.h) for more
+ // information on insertion points. The default implementation
+ // assert-fails -- it exists only for backwards-compatibility.
+ //
+ // WARNING: This feature is currently EXPERIMENTAL and is subject to change.
+ virtual io::ZeroCopyOutputStream* OpenForInsert(
+ const std::string& filename, const std::string& insertion_point);
+
+ // Similar to OpenForInsert, but if `info` is non-empty, will open (or create)
+ // filename.pb.meta and insert info at the appropriate place with the
+ // necessary shifts. The default implementation ignores `info`.
+ //
+ // WARNING: This feature will be REMOVED in the near future.
+ virtual io::ZeroCopyOutputStream* OpenForInsertWithGeneratedCodeInfo(
+ const std::string& filename, const std::string& insertion_point,
+ const google::protobuf::GeneratedCodeInfo& info);
+
+ // Returns a vector of FileDescriptors for all the files being compiled
+ // in this run. Useful for languages, such as Go, that treat files
+ // differently when compiled as a set rather than individually.
+ virtual void ListParsedFiles(std::vector<const FileDescriptor*>* output);
+
+ // Retrieves the version number of the protocol compiler associated with
+ // this GeneratorContext.
+ virtual void GetCompilerVersion(Version* version) const;
+
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(GeneratorContext);
+};
+
+// The type GeneratorContext was once called OutputDirectory. This typedef
+// provides backward compatibility.
+typedef GeneratorContext OutputDirectory;
+
+// Several code generators treat the parameter argument as holding a
+// list of options separated by commas. This helper function parses
+// a set of comma-delimited name/value pairs: e.g.,
+// "foo=bar,baz,qux=corge"
+// parses to the pairs:
+// ("foo", "bar"), ("baz", ""), ("qux", "corge")
+PROTOC_EXPORT void ParseGeneratorParameter(
+ const std::string&, std::vector<std::pair<std::string, std::string> >*);
+
+// Strips ".proto" or ".protodevel" from the end of a filename.
+PROTOC_EXPORT std::string StripProto(const std::string& filename);
+
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#include <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_COMPILER_CODE_GENERATOR_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/command_line_interface.cc b/NorthstarDedicatedTest/include/protobuf/compiler/command_line_interface.cc
new file mode 100644
index 00000000..f2209964
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/command_line_interface.cc
@@ -0,0 +1,2616 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 <compiler/command_line_interface.h>
+
+#include <cstdint>
+
+#include <stubs/platform_macros.h>
+
+#include <stdio.h>
+#include <sys/types.h>
+#ifdef major
+#undef major
+#endif
+#ifdef minor
+#undef minor
+#endif
+#include <fcntl.h>
+#include <sys/stat.h>
+#ifndef _MSC_VER
+#include <unistd.h>
+#endif
+#include <ctype.h>
+#include <errno.h>
+#include <fstream>
+#include <iostream>
+
+#include <limits.h> //For PATH_MAX
+
+#include <memory>
+
+#if defined(__APPLE__)
+#include <mach-o/dyld.h>
+#elif defined(__FreeBSD__)
+#include <sys/sysctl.h>
+#endif
+
+#include <stubs/common.h>
+#include <stubs/logging.h>
+#include <stubs/stringprintf.h>
+#include <compiler/subprocess.h>
+#include <compiler/zip_writer.h>
+#include <compiler/plugin.pb.h>
+#include <compiler/code_generator.h>
+#include <compiler/importer.h>
+#include <io/coded_stream.h>
+#include <io/printer.h>
+#include <io/zero_copy_stream_impl.h>
+#include <descriptor.h>
+#include <dynamic_message.h>
+#include <text_format.h>
+#include <stubs/strutil.h>
+#include <stubs/substitute.h>
+#include <io/io_win32.h>
+#include <stubs/map_util.h>
+#include <stubs/stl_util.h>
+
+
+#include <port_def.inc>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+
+#ifndef O_BINARY
+#ifdef _O_BINARY
+#define O_BINARY _O_BINARY
+#else
+#define O_BINARY 0 // If this isn't defined, the platform doesn't need it.
+#endif
+#endif
+
+namespace {
+#if defined(_WIN32)
+// 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::mkdir;
+using google::protobuf::io::win32::open;
+using google::protobuf::io::win32::setmode;
+using google::protobuf::io::win32::write;
+#endif
+
+static const char* kDefaultDirectDependenciesViolationMsg =
+ "File is imported but not declared in --direct_dependencies: %s";
+
+// Returns true if the text looks like a Windows-style absolute path, starting
+// with a drive letter. Example: "C:\foo". TODO(kenton): Share this with
+// copy in importer.cc?
+static bool IsWindowsAbsolutePath(const std::string& text) {
+#if defined(_WIN32) || defined(__CYGWIN__)
+ return text.size() >= 3 && text[1] == ':' && isalpha(text[0]) &&
+ (text[2] == '/' || text[2] == '\\') && text.find_last_of(':') == 1;
+#else
+ return false;
+#endif
+}
+
+void SetFdToTextMode(int fd) {
+#ifdef _WIN32
+ if (setmode(fd, _O_TEXT) == -1) {
+ // This should never happen, I think.
+ GOOGLE_LOG(WARNING) << "setmode(" << fd << ", _O_TEXT): " << strerror(errno);
+ }
+#endif
+ // (Text and binary are the same on non-Windows platforms.)
+}
+
+void SetFdToBinaryMode(int fd) {
+#ifdef _WIN32
+ if (setmode(fd, _O_BINARY) == -1) {
+ // This should never happen, I think.
+ GOOGLE_LOG(WARNING) << "setmode(" << fd << ", _O_BINARY): " << strerror(errno);
+ }
+#endif
+ // (Text and binary are the same on non-Windows platforms.)
+}
+
+void AddTrailingSlash(std::string* path) {
+ if (!path->empty() && path->at(path->size() - 1) != '/') {
+ path->push_back('/');
+ }
+}
+
+bool VerifyDirectoryExists(const std::string& path) {
+ if (path.empty()) return true;
+
+ if (access(path.c_str(), F_OK) == -1) {
+ std::cerr << path << ": " << strerror(errno) << std::endl;
+ return false;
+ } else {
+ return true;
+ }
+}
+
+// Try to create the parent directory of the given file, creating the parent's
+// parent if necessary, and so on. The full file name is actually
+// (prefix + filename), but we assume |prefix| already exists and only create
+// directories listed in |filename|.
+bool TryCreateParentDirectory(const std::string& prefix,
+ const std::string& filename) {
+ // Recursively create parent directories to the output file.
+ // On Windows, both '/' and '\' are valid path separators.
+ std::vector<std::string> parts =
+ Split(filename, "/\\", true);
+ std::string path_so_far = prefix;
+ for (int i = 0; i < parts.size() - 1; i++) {
+ path_so_far += parts[i];
+ if (mkdir(path_so_far.c_str(), 0777) != 0) {
+ if (errno != EEXIST) {
+ std::cerr << filename << ": while trying to create directory "
+ << path_so_far << ": " << strerror(errno) << std::endl;
+ return false;
+ }
+ }
+ path_so_far += '/';
+ }
+
+ return true;
+}
+
+// Get the absolute path of this protoc binary.
+bool GetProtocAbsolutePath(std::string* path) {
+#ifdef _WIN32
+ char buffer[MAX_PATH];
+ int len = GetModuleFileNameA(NULL, buffer, MAX_PATH);
+#elif defined(__APPLE__)
+ char buffer[PATH_MAX];
+ int len = 0;
+
+ char dirtybuffer[PATH_MAX];
+ uint32_t size = sizeof(dirtybuffer);
+ if (_NSGetExecutablePath(dirtybuffer, &size) == 0) {
+ realpath(dirtybuffer, buffer);
+ len = strlen(buffer);
+ }
+#elif defined(__FreeBSD__)
+ char buffer[PATH_MAX];
+ size_t len = PATH_MAX;
+ int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1};
+ if (sysctl(mib, 4, &buffer, &len, NULL, 0) != 0) {
+ len = 0;
+ }
+#else
+ char buffer[PATH_MAX];
+ int len = readlink("/proc/self/exe", buffer, PATH_MAX);
+#endif
+ if (len > 0) {
+ path->assign(buffer, len);
+ return true;
+ } else {
+ return false;
+ }
+}
+
+// Whether a path is where google/protobuf/descriptor.proto and other well-known
+// type protos are installed.
+bool IsInstalledProtoPath(const std::string& path) {
+ // Checking the descriptor.proto file should be good enough.
+ std::string file_path = path + "/google/protobuf/descriptor.proto";
+ return access(file_path.c_str(), F_OK) != -1;
+}
+
+// Add the paths where google/protobuf/descriptor.proto and other well-known
+// type protos are installed.
+void AddDefaultProtoPaths(
+ std::vector<std::pair<std::string, std::string>>* paths) {
+ // TODO(xiaofeng): The code currently only checks relative paths of where
+ // the protoc binary is installed. We probably should make it handle more
+ // cases than that.
+ std::string path;
+ if (!GetProtocAbsolutePath(&path)) {
+ return;
+ }
+ // Strip the binary name.
+ size_t pos = path.find_last_of("/\\");
+ if (pos == std::string::npos || pos == 0) {
+ return;
+ }
+ path = path.substr(0, pos);
+ // Check the binary's directory.
+ if (IsInstalledProtoPath(path)) {
+ paths->push_back(std::pair<std::string, std::string>("", path));
+ return;
+ }
+ // Check if there is an include subdirectory.
+ if (IsInstalledProtoPath(path + "/include")) {
+ paths->push_back(
+ std::pair<std::string, std::string>("", path + "/include"));
+ return;
+ }
+ // Check if the upper level directory has an "include" subdirectory.
+ pos = path.find_last_of("/\\");
+ if (pos == std::string::npos || pos == 0) {
+ return;
+ }
+ path = path.substr(0, pos);
+ if (IsInstalledProtoPath(path + "/include")) {
+ paths->push_back(
+ std::pair<std::string, std::string>("", path + "/include"));
+ return;
+ }
+}
+
+std::string PluginName(const std::string& plugin_prefix,
+ const std::string& directive) {
+ // Assuming the directive starts with "--" and ends with "_out" or "_opt",
+ // strip the "--" and "_out/_opt" and add the plugin prefix.
+ return plugin_prefix + "gen-" + directive.substr(2, directive.size() - 6);
+}
+
+} // namespace
+
+// A MultiFileErrorCollector that prints errors to stderr.
+class CommandLineInterface::ErrorPrinter
+ : public MultiFileErrorCollector,
+ public io::ErrorCollector,
+ public DescriptorPool::ErrorCollector {
+ public:
+ ErrorPrinter(ErrorFormat format, DiskSourceTree* tree = NULL)
+ : format_(format),
+ tree_(tree),
+ found_errors_(false),
+ found_warnings_(false) {}
+ ~ErrorPrinter() {}
+
+ // implements MultiFileErrorCollector ------------------------------
+ void AddError(const std::string& filename, int line, int column,
+ const std::string& message) override {
+ found_errors_ = true;
+ AddErrorOrWarning(filename, line, column, message, "error", std::cerr);
+ }
+
+ void AddWarning(const std::string& filename, int line, int column,
+ const std::string& message) override {
+ found_warnings_ = true;
+ AddErrorOrWarning(filename, line, column, message, "warning", std::clog);
+ }
+
+ // implements io::ErrorCollector -----------------------------------
+ void AddError(int line, int column, const std::string& message) override {
+ AddError("input", line, column, message);
+ }
+
+ void AddWarning(int line, int column, const std::string& message) override {
+ AddErrorOrWarning("input", line, column, message, "warning", std::clog);
+ }
+
+ // implements DescriptorPool::ErrorCollector-------------------------
+ void AddError(const std::string& filename, const std::string& element_name,
+ const Message* descriptor, ErrorLocation location,
+ const std::string& message) override {
+ AddErrorOrWarning(filename, -1, -1, message, "error", std::cerr);
+ }
+
+ void AddWarning(const std::string& filename, const std::string& element_name,
+ const Message* descriptor, ErrorLocation location,
+ const std::string& message) override {
+ AddErrorOrWarning(filename, -1, -1, message, "warning", std::clog);
+ }
+
+ bool FoundErrors() const { return found_errors_; }
+
+ bool FoundWarnings() const { return found_warnings_; }
+
+ private:
+ void AddErrorOrWarning(const std::string& filename, int line, int column,
+ const std::string& message, const std::string& type,
+ std::ostream& out) {
+ // Print full path when running under MSVS
+ std::string dfile;
+ if (format_ == CommandLineInterface::ERROR_FORMAT_MSVS && tree_ != NULL &&
+ tree_->VirtualFileToDiskFile(filename, &dfile)) {
+ out << dfile;
+ } else {
+ out << filename;
+ }
+
+ // Users typically expect 1-based line/column numbers, so we add 1
+ // to each here.
+ if (line != -1) {
+ // Allow for both GCC- and Visual-Studio-compatible output.
+ switch (format_) {
+ case CommandLineInterface::ERROR_FORMAT_GCC:
+ out << ":" << (line + 1) << ":" << (column + 1);
+ break;
+ case CommandLineInterface::ERROR_FORMAT_MSVS:
+ out << "(" << (line + 1) << ") : " << type
+ << " in column=" << (column + 1);
+ break;
+ }
+ }
+
+ if (type == "warning") {
+ out << ": warning: " << message << std::endl;
+ } else {
+ out << ": " << message << std::endl;
+ }
+ }
+
+ const ErrorFormat format_;
+ DiskSourceTree* tree_;
+ bool found_errors_;
+ bool found_warnings_;
+};
+
+// -------------------------------------------------------------------
+
+// A GeneratorContext implementation that buffers files in memory, then dumps
+// them all to disk on demand.
+class CommandLineInterface::GeneratorContextImpl : public GeneratorContext {
+ public:
+ GeneratorContextImpl(const std::vector<const FileDescriptor*>& parsed_files);
+
+ // Write all files in the directory to disk at the given output location,
+ // which must end in a '/'.
+ bool WriteAllToDisk(const std::string& prefix);
+
+ // Write the contents of this directory to a ZIP-format archive with the
+ // given name.
+ bool WriteAllToZip(const std::string& filename);
+
+ // Add a boilerplate META-INF/MANIFEST.MF file as required by the Java JAR
+ // format, unless one has already been written.
+ void AddJarManifest();
+
+ // Get name of all output files.
+ void GetOutputFilenames(std::vector<std::string>* output_filenames);
+
+ // implements GeneratorContext --------------------------------------
+ io::ZeroCopyOutputStream* Open(const std::string& filename) override;
+ io::ZeroCopyOutputStream* OpenForAppend(const std::string& filename) override;
+ io::ZeroCopyOutputStream* OpenForInsert(
+ const std::string& filename, const std::string& insertion_point) override;
+ io::ZeroCopyOutputStream* OpenForInsertWithGeneratedCodeInfo(
+ const std::string& filename, const std::string& insertion_point,
+ const google::protobuf::GeneratedCodeInfo& info) override;
+ void ListParsedFiles(std::vector<const FileDescriptor*>* output) override {
+ *output = parsed_files_;
+ }
+
+ private:
+ friend class MemoryOutputStream;
+
+ // The files_ field maps from path keys to file content values. It's a map
+ // instead of an unordered_map so that files are written in order (good when
+ // writing zips).
+ std::map<std::string, std::string> files_;
+ const std::vector<const FileDescriptor*>& parsed_files_;
+ bool had_error_;
+};
+
+class CommandLineInterface::MemoryOutputStream
+ : public io::ZeroCopyOutputStream {
+ public:
+ MemoryOutputStream(GeneratorContextImpl* directory,
+ const std::string& filename, bool append_mode);
+ MemoryOutputStream(GeneratorContextImpl* directory,
+ const std::string& filename,
+ const std::string& insertion_point);
+ MemoryOutputStream(GeneratorContextImpl* directory,
+ const std::string& filename,
+ const std::string& insertion_point,
+ const google::protobuf::GeneratedCodeInfo& info);
+ virtual ~MemoryOutputStream();
+
+ // implements ZeroCopyOutputStream ---------------------------------
+ bool Next(void** data, int* size) override {
+ return inner_->Next(data, size);
+ }
+ void BackUp(int count) override { inner_->BackUp(count); }
+ int64_t ByteCount() const override { return inner_->ByteCount(); }
+
+ private:
+ // Checks to see if "filename_.pb.meta" exists in directory_; if so, fixes the
+ // offsets in that GeneratedCodeInfo record to reflect bytes inserted in
+ // filename_ at original offset insertion_offset with length insertion_length.
+ // Also adds in the data from info_to_insert_ with updated offsets governed by
+ // insertion_offset and indent_length. We assume that insertions will not
+ // occur within any given annotated span of text. insertion_content must end
+ // with an endline.
+ void UpdateMetadata(const std::string& insertion_content,
+ size_t insertion_offset, size_t insertion_length,
+ size_t indent_length);
+
+ // Inserts info_to_insert_ into target_info, assuming that the relevant
+ // insertion was made at insertion_offset in file_content with the given
+ // indent_length. insertion_content must end with an endline.
+ void InsertShiftedInfo(const std::string& insertion_content,
+ size_t insertion_offset, size_t indent_length,
+ google::protobuf::GeneratedCodeInfo& target_info);
+
+ // Where to insert the string when it's done.
+ GeneratorContextImpl* directory_;
+ std::string filename_;
+ std::string insertion_point_;
+
+ // The string we're building.
+ std::string data_;
+
+ // Whether we should append the output stream to the existing file.
+ bool append_mode_;
+
+ // StringOutputStream writing to data_.
+ std::unique_ptr<io::StringOutputStream> inner_;
+
+ // The GeneratedCodeInfo to insert at the insertion point.
+ google::protobuf::GeneratedCodeInfo info_to_insert_;
+};
+
+// -------------------------------------------------------------------
+
+CommandLineInterface::GeneratorContextImpl::GeneratorContextImpl(
+ const std::vector<const FileDescriptor*>& parsed_files)
+ : parsed_files_(parsed_files), had_error_(false) {}
+
+bool CommandLineInterface::GeneratorContextImpl::WriteAllToDisk(
+ const std::string& prefix) {
+ if (had_error_) {
+ return false;
+ }
+
+ if (!VerifyDirectoryExists(prefix)) {
+ return false;
+ }
+
+ for (const auto& pair : files_) {
+ const std::string& relative_filename = pair.first;
+ const char* data = pair.second.data();
+ int size = pair.second.size();
+
+ if (!TryCreateParentDirectory(prefix, relative_filename)) {
+ return false;
+ }
+ std::string filename = prefix + relative_filename;
+
+ // Create the output file.
+ int file_descriptor;
+ do {
+ file_descriptor =
+ open(filename.c_str(), O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666);
+ } while (file_descriptor < 0 && errno == EINTR);
+
+ if (file_descriptor < 0) {
+ int error = errno;
+ std::cerr << filename << ": " << strerror(error);
+ return false;
+ }
+
+ // Write the file.
+ while (size > 0) {
+ int write_result;
+ do {
+ write_result = write(file_descriptor, data, size);
+ } while (write_result < 0 && errno == EINTR);
+
+ if (write_result <= 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 (write_result < 0) {
+ int error = errno;
+ std::cerr << filename << ": write: " << strerror(error);
+ } else {
+ std::cerr << filename << ": write() returned zero?" << std::endl;
+ }
+ return false;
+ }
+
+ data += write_result;
+ size -= write_result;
+ }
+
+ if (close(file_descriptor) != 0) {
+ int error = errno;
+ std::cerr << filename << ": close: " << strerror(error);
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool CommandLineInterface::GeneratorContextImpl::WriteAllToZip(
+ const std::string& filename) {
+ if (had_error_) {
+ return false;
+ }
+
+ // Create the output file.
+ int file_descriptor;
+ do {
+ file_descriptor =
+ open(filename.c_str(), O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666);
+ } while (file_descriptor < 0 && errno == EINTR);
+
+ if (file_descriptor < 0) {
+ int error = errno;
+ std::cerr << filename << ": " << strerror(error);
+ return false;
+ }
+
+ // Create the ZipWriter
+ io::FileOutputStream stream(file_descriptor);
+ ZipWriter zip_writer(&stream);
+
+ for (const auto& pair : files_) {
+ zip_writer.Write(pair.first, pair.second);
+ }
+
+ zip_writer.WriteDirectory();
+
+ if (stream.GetErrno() != 0) {
+ std::cerr << filename << ": " << strerror(stream.GetErrno()) << std::endl;
+ return false;
+ }
+
+ if (!stream.Close()) {
+ std::cerr << filename << ": " << strerror(stream.GetErrno()) << std::endl;
+ return false;
+ }
+
+ return true;
+}
+
+void CommandLineInterface::GeneratorContextImpl::AddJarManifest() {
+ auto pair = files_.insert({"META-INF/MANIFEST.MF", ""});
+ if (pair.second) {
+ pair.first->second =
+ "Manifest-Version: 1.0\n"
+ "Created-By: 1.6.0 (protoc)\n"
+ "\n";
+ }
+}
+
+void CommandLineInterface::GeneratorContextImpl::GetOutputFilenames(
+ std::vector<std::string>* output_filenames) {
+ for (const auto& pair : files_) {
+ output_filenames->push_back(pair.first);
+ }
+}
+
+io::ZeroCopyOutputStream* CommandLineInterface::GeneratorContextImpl::Open(
+ const std::string& filename) {
+ return new MemoryOutputStream(this, filename, false);
+}
+
+io::ZeroCopyOutputStream*
+CommandLineInterface::GeneratorContextImpl::OpenForAppend(
+ const std::string& filename) {
+ return new MemoryOutputStream(this, filename, true);
+}
+
+io::ZeroCopyOutputStream*
+CommandLineInterface::GeneratorContextImpl::OpenForInsert(
+ const std::string& filename, const std::string& insertion_point) {
+ return new MemoryOutputStream(this, filename, insertion_point);
+}
+
+io::ZeroCopyOutputStream*
+CommandLineInterface::GeneratorContextImpl::OpenForInsertWithGeneratedCodeInfo(
+ const std::string& filename, const std::string& insertion_point,
+ const google::protobuf::GeneratedCodeInfo& info) {
+ return new MemoryOutputStream(this, filename, insertion_point, info);
+}
+
+// -------------------------------------------------------------------
+
+CommandLineInterface::MemoryOutputStream::MemoryOutputStream(
+ GeneratorContextImpl* directory, const std::string& filename,
+ bool append_mode)
+ : directory_(directory),
+ filename_(filename),
+ append_mode_(append_mode),
+ inner_(new io::StringOutputStream(&data_)) {}
+
+CommandLineInterface::MemoryOutputStream::MemoryOutputStream(
+ GeneratorContextImpl* directory, const std::string& filename,
+ const std::string& insertion_point)
+ : directory_(directory),
+ filename_(filename),
+ insertion_point_(insertion_point),
+ inner_(new io::StringOutputStream(&data_)) {}
+
+CommandLineInterface::MemoryOutputStream::MemoryOutputStream(
+ GeneratorContextImpl* directory, const std::string& filename,
+ const std::string& insertion_point, const google::protobuf::GeneratedCodeInfo& info)
+ : directory_(directory),
+ filename_(filename),
+ insertion_point_(insertion_point),
+ inner_(new io::StringOutputStream(&data_)),
+ info_to_insert_(info) {}
+
+void CommandLineInterface::MemoryOutputStream::InsertShiftedInfo(
+ const std::string& insertion_content, size_t insertion_offset,
+ size_t indent_length, google::protobuf::GeneratedCodeInfo& target_info) {
+ // Keep track of how much extra data was added for indents before the
+ // current annotation being inserted. `pos` and `source_annotation.begin()`
+ // are offsets in `insertion_content`. `insertion_offset` is updated so that
+ // it can be added to an annotation's `begin` field to reflect that
+ // annotation's updated location after `insertion_content` was inserted into
+ // the target file.
+ size_t pos = 0;
+ insertion_offset += indent_length;
+ for (const auto& source_annotation : info_to_insert_.annotation()) {
+ GeneratedCodeInfo::Annotation* annotation = target_info.add_annotation();
+ int inner_indent = 0;
+ // insertion_content is guaranteed to end in an endline. This last endline
+ // has no effect on indentation.
+ for (; pos < source_annotation.end() && pos < insertion_content.size() - 1;
+ ++pos) {
+ if (insertion_content[pos] == '\n') {
+ if (pos >= source_annotation.begin()) {
+ // The beginning of the annotation is at insertion_offset, but the end
+ // can still move further in the target file.
+ inner_indent += indent_length;
+ } else {
+ insertion_offset += indent_length;
+ }
+ }
+ }
+ *annotation = source_annotation;
+ annotation->set_begin(annotation->begin() + insertion_offset);
+ insertion_offset += inner_indent;
+ annotation->set_end(annotation->end() + insertion_offset);
+ }
+}
+
+void CommandLineInterface::MemoryOutputStream::UpdateMetadata(
+ const std::string& insertion_content, size_t insertion_offset,
+ size_t insertion_length, size_t indent_length) {
+ auto it = directory_->files_.find(filename_ + ".pb.meta");
+ if (it == directory_->files_.end() && info_to_insert_.annotation().empty()) {
+ // No metadata was recorded for this file.
+ return;
+ }
+ GeneratedCodeInfo metadata;
+ bool is_text_format = false;
+ std::string* encoded_data = nullptr;
+ if (it != directory_->files_.end()) {
+ encoded_data = &it->second;
+ // Try to decode a GeneratedCodeInfo proto from the .pb.meta file. It may be
+ // in wire or text format. Keep the same format when the data is written out
+ // later.
+ if (!metadata.ParseFromString(*encoded_data)) {
+ if (!TextFormat::ParseFromString(*encoded_data, &metadata)) {
+ // The metadata is invalid.
+ std::cerr
+ << filename_
+ << ".pb.meta: Could not parse metadata as wire or text format."
+ << std::endl;
+ return;
+ }
+ // Generators that use the public plugin interface emit text-format
+ // metadata (because in the public plugin protocol, file content must be
+ // UTF8-encoded strings).
+ is_text_format = true;
+ }
+ } else {
+ // Create a new file to store the new metadata in info_to_insert_.
+ encoded_data =
+ &directory_->files_.insert({filename_ + ".pb.meta", ""}).first->second;
+ }
+ GeneratedCodeInfo new_metadata;
+ bool crossed_offset = false;
+ size_t to_add = 0;
+ for (const auto& source_annotation : metadata.annotation()) {
+ // The first time an annotation at or after the insertion point is found,
+ // insert the new metadata from info_to_insert_. Shift all annotations
+ // after the new metadata by the length of the text that was inserted
+ // (including any additional indent length).
+ if (source_annotation.begin() >= insertion_offset && !crossed_offset) {
+ crossed_offset = true;
+ InsertShiftedInfo(insertion_content, insertion_offset, indent_length,
+ new_metadata);
+ to_add += insertion_length;
+ }
+ GeneratedCodeInfo::Annotation* annotation = new_metadata.add_annotation();
+ *annotation = source_annotation;
+ annotation->set_begin(annotation->begin() + to_add);
+ annotation->set_end(annotation->end() + to_add);
+ }
+ // If there were never any annotations at or after the insertion point,
+ // make sure to still insert the new metadata from info_to_insert_.
+ if (!crossed_offset) {
+ InsertShiftedInfo(insertion_content, insertion_offset, indent_length,
+ new_metadata);
+ }
+ if (is_text_format) {
+ TextFormat::PrintToString(new_metadata, encoded_data);
+ } else {
+ new_metadata.SerializeToString(encoded_data);
+ }
+}
+
+CommandLineInterface::MemoryOutputStream::~MemoryOutputStream() {
+ // Make sure all data has been written.
+ inner_.reset();
+
+ // Insert into the directory.
+ auto pair = directory_->files_.insert({filename_, ""});
+ auto it = pair.first;
+ bool already_present = !pair.second;
+
+ if (insertion_point_.empty()) {
+ // This was just a regular Open().
+ if (already_present) {
+ if (append_mode_) {
+ it->second.append(data_);
+ } else {
+ std::cerr << filename_ << ": Tried to write the same file twice."
+ << std::endl;
+ directory_->had_error_ = true;
+ }
+ return;
+ }
+
+ it->second.swap(data_);
+ } else {
+ // This was an OpenForInsert().
+
+ // If the data doesn't end with a clean line break, add one.
+ if (!data_.empty() && data_[data_.size() - 1] != '\n') {
+ data_.push_back('\n');
+ }
+
+ // Find the file we are going to insert into.
+ if (!already_present) {
+ std::cerr << filename_
+ << ": Tried to insert into file that doesn't exist."
+ << std::endl;
+ directory_->had_error_ = true;
+ return;
+ }
+ std::string* target = &it->second;
+
+ // Find the insertion point.
+ std::string magic_string =
+ strings::Substitute("@@protoc_insertion_point($0)", insertion_point_);
+ std::string::size_type pos = target->find(magic_string);
+
+ if (pos == std::string::npos) {
+ std::cerr << filename_ << ": insertion point \"" << insertion_point_
+ << "\" not found." << std::endl;
+ directory_->had_error_ = true;
+ return;
+ }
+
+ if ((pos > 3) && (target->substr(pos - 3, 2) == "/*")) {
+ // Support for inline "/* @@protoc_insertion_point() */"
+ pos = pos - 3;
+ } else {
+ // Seek backwards to the beginning of the line, which is where we will
+ // insert the data. Note that this has the effect of pushing the
+ // insertion point down, so the data is inserted before it. This is
+ // intentional because it means that multiple insertions at the same point
+ // will end up in the expected order in the final output.
+ pos = target->find_last_of('\n', pos);
+ if (pos == std::string::npos) {
+ // Insertion point is on the first line.
+ pos = 0;
+ } else {
+ // Advance to character after '\n'.
+ ++pos;
+ }
+ }
+
+ // Extract indent.
+ std::string indent_(*target, pos,
+ target->find_first_not_of(" \t", pos) - pos);
+
+ if (indent_.empty()) {
+ // No indent. This makes things easier.
+ target->insert(pos, data_);
+ UpdateMetadata(data_, pos, data_.size(), 0);
+ } else {
+ // Calculate how much space we need.
+ int indent_size = 0;
+ for (int i = 0; i < data_.size(); i++) {
+ if (data_[i] == '\n') indent_size += indent_.size();
+ }
+
+ // Make a hole for it.
+ target->insert(pos, data_.size() + indent_size, '\0');
+
+ // Now copy in the data.
+ std::string::size_type data_pos = 0;
+ char* target_ptr = ::google::protobuf::string_as_array(target) + pos;
+ while (data_pos < data_.size()) {
+ // Copy indent.
+ memcpy(target_ptr, indent_.data(), indent_.size());
+ target_ptr += indent_.size();
+
+ // Copy line from data_.
+ // We already guaranteed that data_ ends with a newline (above), so this
+ // search can't fail.
+ std::string::size_type line_length =
+ data_.find_first_of('\n', data_pos) + 1 - data_pos;
+ memcpy(target_ptr, data_.data() + data_pos, line_length);
+ target_ptr += line_length;
+ data_pos += line_length;
+ }
+ UpdateMetadata(data_, pos, data_.size() + indent_size, indent_.size());
+
+ GOOGLE_CHECK_EQ(target_ptr,
+ ::google::protobuf::string_as_array(target) + pos + data_.size() + indent_size);
+ }
+ }
+}
+
+// ===================================================================
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+const char* const CommandLineInterface::kPathSeparator = ";";
+#else
+const char* const CommandLineInterface::kPathSeparator = ":";
+#endif
+
+CommandLineInterface::CommandLineInterface()
+ : direct_dependencies_violation_msg_(
+ kDefaultDirectDependenciesViolationMsg) {}
+
+CommandLineInterface::~CommandLineInterface() {}
+
+void CommandLineInterface::RegisterGenerator(const std::string& flag_name,
+ CodeGenerator* generator,
+ const std::string& help_text) {
+ GeneratorInfo info;
+ info.flag_name = flag_name;
+ info.generator = generator;
+ info.help_text = help_text;
+ generators_by_flag_name_[flag_name] = info;
+}
+
+void CommandLineInterface::RegisterGenerator(
+ const std::string& flag_name, const std::string& option_flag_name,
+ CodeGenerator* generator, const std::string& help_text) {
+ GeneratorInfo info;
+ info.flag_name = flag_name;
+ info.option_flag_name = option_flag_name;
+ info.generator = generator;
+ info.help_text = help_text;
+ generators_by_flag_name_[flag_name] = info;
+ generators_by_option_name_[option_flag_name] = info;
+}
+
+void CommandLineInterface::AllowPlugins(const std::string& exe_name_prefix) {
+ plugin_prefix_ = exe_name_prefix;
+}
+
+namespace {
+
+bool ContainsProto3Optional(const Descriptor* desc) {
+ for (int i = 0; i < desc->field_count(); i++) {
+ if (desc->field(i)->has_optional_keyword()) {
+ return true;
+ }
+ }
+ for (int i = 0; i < desc->nested_type_count(); i++) {
+ if (ContainsProto3Optional(desc->nested_type(i))) {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool ContainsProto3Optional(const FileDescriptor* file) {
+ if (file->syntax() == FileDescriptor::SYNTAX_PROTO3) {
+ for (int i = 0; i < file->message_type_count(); i++) {
+ if (ContainsProto3Optional(file->message_type(i))) {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+} // namespace
+
+namespace {
+std::unique_ptr<SimpleDescriptorDatabase>
+PopulateSingleSimpleDescriptorDatabase(const std::string& descriptor_set_name);
+}
+
+int CommandLineInterface::Run(int argc, const char* const argv[]) {
+ Clear();
+ switch (ParseArguments(argc, argv)) {
+ case PARSE_ARGUMENT_DONE_AND_EXIT:
+ return 0;
+ case PARSE_ARGUMENT_FAIL:
+ return 1;
+ case PARSE_ARGUMENT_DONE_AND_CONTINUE:
+ break;
+ }
+
+ std::vector<const FileDescriptor*> parsed_files;
+ std::unique_ptr<DiskSourceTree> disk_source_tree;
+ std::unique_ptr<ErrorPrinter> error_collector;
+ std::unique_ptr<DescriptorPool> descriptor_pool;
+
+ // The SimpleDescriptorDatabases here are the constituents of the
+ // MergedDescriptorDatabase descriptor_set_in_database, so this vector is for
+ // managing their lifetimes. Its scope should match descriptor_set_in_database
+ std::vector<std::unique_ptr<SimpleDescriptorDatabase>>
+ databases_per_descriptor_set;
+ std::unique_ptr<MergedDescriptorDatabase> descriptor_set_in_database;
+
+ std::unique_ptr<SourceTreeDescriptorDatabase> source_tree_database;
+
+ // Any --descriptor_set_in FileDescriptorSet objects will be used as a
+ // fallback to input_files on command line, so create that db first.
+ if (!descriptor_set_in_names_.empty()) {
+ for (const std::string& name : descriptor_set_in_names_) {
+ std::unique_ptr<SimpleDescriptorDatabase> database_for_descriptor_set =
+ PopulateSingleSimpleDescriptorDatabase(name);
+ if (!database_for_descriptor_set) {
+ return EXIT_FAILURE;
+ }
+ databases_per_descriptor_set.push_back(
+ std::move(database_for_descriptor_set));
+ }
+
+ std::vector<DescriptorDatabase*> raw_databases_per_descriptor_set;
+ raw_databases_per_descriptor_set.reserve(
+ databases_per_descriptor_set.size());
+ for (const std::unique_ptr<SimpleDescriptorDatabase>& db :
+ databases_per_descriptor_set) {
+ raw_databases_per_descriptor_set.push_back(db.get());
+ }
+ descriptor_set_in_database.reset(
+ new MergedDescriptorDatabase(raw_databases_per_descriptor_set));
+ }
+
+ if (proto_path_.empty()) {
+ // If there are no --proto_path flags, then just look in the specified
+ // --descriptor_set_in files. But first, verify that the input files are
+ // there.
+ if (!VerifyInputFilesInDescriptors(descriptor_set_in_database.get())) {
+ return 1;
+ }
+
+ error_collector.reset(new ErrorPrinter(error_format_));
+ descriptor_pool.reset(new DescriptorPool(descriptor_set_in_database.get(),
+ error_collector.get()));
+ } else {
+ disk_source_tree.reset(new DiskSourceTree());
+ if (!InitializeDiskSourceTree(disk_source_tree.get(),
+ descriptor_set_in_database.get())) {
+ return 1;
+ }
+
+ error_collector.reset(
+ new ErrorPrinter(error_format_, disk_source_tree.get()));
+
+ source_tree_database.reset(new SourceTreeDescriptorDatabase(
+ disk_source_tree.get(), descriptor_set_in_database.get()));
+ source_tree_database->RecordErrorsTo(error_collector.get());
+
+ descriptor_pool.reset(new DescriptorPool(
+ source_tree_database.get(),
+ source_tree_database->GetValidationErrorCollector()));
+ }
+
+ descriptor_pool->EnforceWeakDependencies(true);
+ if (!ParseInputFiles(descriptor_pool.get(), disk_source_tree.get(),
+ &parsed_files)) {
+ return 1;
+ }
+
+
+ // We construct a separate GeneratorContext for each output location. Note
+ // that two code generators may output to the same location, in which case
+ // they should share a single GeneratorContext so that OpenForInsert() works.
+ GeneratorContextMap output_directories;
+
+ // Generate output.
+ if (mode_ == MODE_COMPILE) {
+ for (int i = 0; i < output_directives_.size(); i++) {
+ std::string output_location = output_directives_[i].output_location;
+ if (!HasSuffixString(output_location, ".zip") &&
+ !HasSuffixString(output_location, ".jar") &&
+ !HasSuffixString(output_location, ".srcjar")) {
+ AddTrailingSlash(&output_location);
+ }
+
+ auto& generator = output_directories[output_location];
+
+ if (!generator) {
+ // First time we've seen this output location.
+ generator.reset(new GeneratorContextImpl(parsed_files));
+ }
+
+ if (!GenerateOutput(parsed_files, output_directives_[i],
+ generator.get())) {
+ return 1;
+ }
+ }
+ }
+
+ // Write all output to disk.
+ for (const auto& pair : output_directories) {
+ const std::string& location = pair.first;
+ GeneratorContextImpl* directory = pair.second.get();
+ if (HasSuffixString(location, "/")) {
+ if (!directory->WriteAllToDisk(location)) {
+ return 1;
+ }
+ } else {
+ if (HasSuffixString(location, ".jar")) {
+ directory->AddJarManifest();
+ }
+
+ if (!directory->WriteAllToZip(location)) {
+ return 1;
+ }
+ }
+ }
+
+ if (!dependency_out_name_.empty()) {
+ GOOGLE_DCHECK(disk_source_tree.get());
+ if (!GenerateDependencyManifestFile(parsed_files, output_directories,
+ disk_source_tree.get())) {
+ return 1;
+ }
+ }
+
+ if (!descriptor_set_out_name_.empty()) {
+ if (!WriteDescriptorSet(parsed_files)) {
+ return 1;
+ }
+ }
+
+ if (mode_ == MODE_ENCODE || mode_ == MODE_DECODE) {
+ if (codec_type_.empty()) {
+ // HACK: Define an EmptyMessage type to use for decoding.
+ DescriptorPool pool;
+ FileDescriptorProto file;
+ file.set_name("empty_message.proto");
+ file.add_message_type()->set_name("EmptyMessage");
+ GOOGLE_CHECK(pool.BuildFile(file) != NULL);
+ codec_type_ = "EmptyMessage";
+ if (!EncodeOrDecode(&pool)) {
+ return 1;
+ }
+ } else {
+ if (!EncodeOrDecode(descriptor_pool.get())) {
+ return 1;
+ }
+ }
+ }
+
+ if (error_collector->FoundErrors() ||
+ (fatal_warnings_ && error_collector->FoundWarnings())) {
+ return 1;
+ }
+
+ if (mode_ == MODE_PRINT) {
+ switch (print_mode_) {
+ case PRINT_FREE_FIELDS:
+ for (int i = 0; i < parsed_files.size(); ++i) {
+ const FileDescriptor* fd = parsed_files[i];
+ for (int j = 0; j < fd->message_type_count(); ++j) {
+ PrintFreeFieldNumbers(fd->message_type(j));
+ }
+ }
+ break;
+ case PRINT_NONE:
+ GOOGLE_LOG(ERROR) << "If the code reaches here, it usually means a bug of "
+ "flag parsing in the CommandLineInterface.";
+ return 1;
+
+ // Do not add a default case.
+ }
+ }
+
+ return 0;
+}
+
+bool CommandLineInterface::InitializeDiskSourceTree(
+ DiskSourceTree* source_tree, DescriptorDatabase* fallback_database) {
+ AddDefaultProtoPaths(&proto_path_);
+
+ // Set up the source tree.
+ for (int i = 0; i < proto_path_.size(); i++) {
+ source_tree->MapPath(proto_path_[i].first, proto_path_[i].second);
+ }
+
+ // Map input files to virtual paths if possible.
+ if (!MakeInputsBeProtoPathRelative(source_tree, fallback_database)) {
+ return false;
+ }
+
+ return true;
+}
+
+namespace {
+std::unique_ptr<SimpleDescriptorDatabase>
+PopulateSingleSimpleDescriptorDatabase(const std::string& descriptor_set_name) {
+ int fd;
+ do {
+ fd = open(descriptor_set_name.c_str(), O_RDONLY | O_BINARY);
+ } while (fd < 0 && errno == EINTR);
+ if (fd < 0) {
+ std::cerr << descriptor_set_name << ": " << strerror(ENOENT) << std::endl;
+ return nullptr;
+ }
+
+ FileDescriptorSet file_descriptor_set;
+ bool parsed = file_descriptor_set.ParseFromFileDescriptor(fd);
+ if (close(fd) != 0) {
+ std::cerr << descriptor_set_name << ": close: " << strerror(errno)
+ << std::endl;
+ return nullptr;
+ }
+
+ if (!parsed) {
+ std::cerr << descriptor_set_name << ": Unable to parse." << std::endl;
+ return nullptr;
+ }
+
+ std::unique_ptr<SimpleDescriptorDatabase> database{
+ new SimpleDescriptorDatabase()};
+
+ for (int j = 0; j < file_descriptor_set.file_size(); j++) {
+ FileDescriptorProto previously_added_file_descriptor_proto;
+ if (database->FindFileByName(file_descriptor_set.file(j).name(),
+ &previously_added_file_descriptor_proto)) {
+ // already present - skip
+ continue;
+ }
+ if (!database->Add(file_descriptor_set.file(j))) {
+ return nullptr;
+ }
+ }
+ return database;
+}
+
+} // namespace
+
+
+bool CommandLineInterface::VerifyInputFilesInDescriptors(
+ DescriptorDatabase* database) {
+ for (const auto& input_file : input_files_) {
+ FileDescriptorProto file_descriptor;
+ if (!database->FindFileByName(input_file, &file_descriptor)) {
+ std::cerr << "Could not find file in descriptor database: " << input_file
+ << ": " << strerror(ENOENT) << std::endl;
+ return false;
+ }
+
+ // Enforce --disallow_services.
+ if (disallow_services_ && file_descriptor.service_size() > 0) {
+ std::cerr << file_descriptor.name()
+ << ": This file contains services, but "
+ "--disallow_services was used."
+ << std::endl;
+ return false;
+ }
+
+ }
+ return true;
+}
+
+bool CommandLineInterface::ParseInputFiles(
+ DescriptorPool* descriptor_pool, DiskSourceTree* source_tree,
+ std::vector<const FileDescriptor*>* parsed_files) {
+
+ if (!proto_path_.empty()) {
+ // Track unused imports in all source files that were loaded from the
+ // filesystem. We do not track unused imports for files loaded from
+ // descriptor sets as they may be programmatically generated in which case
+ // exerting this level of rigor is less desirable. We're also making the
+ // assumption that the initial parse of the proto from the filesystem
+ // was rigorous in checking unused imports and that the descriptor set
+ // being parsed was produced then and that it was subsequent mutations
+ // of that descriptor set that left unused imports.
+ //
+ // Note that relying on proto_path exclusively is limited in that we may
+ // be loading descriptors from both the filesystem and descriptor sets
+ // depending on the invocation. At least for invocations that are
+ // exclusively reading from descriptor sets, we can eliminate this failure
+ // condition.
+ for (const auto& input_file : input_files_) {
+ descriptor_pool->AddUnusedImportTrackFile(input_file);
+ }
+ }
+
+ bool result = true;
+ // Parse each file.
+ for (const auto& input_file : input_files_) {
+ // Import the file.
+ const FileDescriptor* parsed_file =
+ descriptor_pool->FindFileByName(input_file);
+ if (parsed_file == NULL) {
+ result = false;
+ break;
+ }
+ parsed_files->push_back(parsed_file);
+
+ // Enforce --disallow_services.
+ if (disallow_services_ && parsed_file->service_count() > 0) {
+ std::cerr << parsed_file->name()
+ << ": This file contains services, but "
+ "--disallow_services was used."
+ << std::endl;
+ result = false;
+ break;
+ }
+
+
+ // Enforce --direct_dependencies
+ if (direct_dependencies_explicitly_set_) {
+ bool indirect_imports = false;
+ for (int i = 0; i < parsed_file->dependency_count(); i++) {
+ if (direct_dependencies_.find(parsed_file->dependency(i)->name()) ==
+ direct_dependencies_.end()) {
+ indirect_imports = true;
+ std::cerr << parsed_file->name() << ": "
+ << StringReplace(direct_dependencies_violation_msg_, "%s",
+ parsed_file->dependency(i)->name(),
+ true /* replace_all */)
+ << std::endl;
+ }
+ }
+ if (indirect_imports) {
+ result = false;
+ break;
+ }
+ }
+ }
+ descriptor_pool->ClearUnusedImportTrackFiles();
+ return result;
+}
+
+void CommandLineInterface::Clear() {
+ // Clear all members that are set by Run(). Note that we must not clear
+ // members which are set by other methods before Run() is called.
+ executable_name_.clear();
+ proto_path_.clear();
+ input_files_.clear();
+ direct_dependencies_.clear();
+ direct_dependencies_violation_msg_ = kDefaultDirectDependenciesViolationMsg;
+ output_directives_.clear();
+ codec_type_.clear();
+ descriptor_set_in_names_.clear();
+ descriptor_set_out_name_.clear();
+ dependency_out_name_.clear();
+
+
+ mode_ = MODE_COMPILE;
+ print_mode_ = PRINT_NONE;
+ imports_in_descriptor_set_ = false;
+ source_info_in_descriptor_set_ = false;
+ disallow_services_ = false;
+ direct_dependencies_explicitly_set_ = false;
+ deterministic_output_ = false;
+}
+
+bool CommandLineInterface::MakeProtoProtoPathRelative(
+ DiskSourceTree* source_tree, std::string* proto,
+ DescriptorDatabase* fallback_database) {
+ // If it's in the fallback db, don't report non-existent file errors.
+ FileDescriptorProto fallback_file;
+ bool in_fallback_database =
+ fallback_database != nullptr &&
+ fallback_database->FindFileByName(*proto, &fallback_file);
+
+ // If the input file path is not a physical file path, it must be a virtual
+ // path.
+ if (access(proto->c_str(), F_OK) < 0) {
+ std::string disk_file;
+ if (source_tree->VirtualFileToDiskFile(*proto, &disk_file) ||
+ in_fallback_database) {
+ return true;
+ } else {
+ std::cerr << "Could not make proto path relative: " << *proto << ": "
+ << strerror(ENOENT) << std::endl;
+ return false;
+ }
+ }
+
+ std::string virtual_file, shadowing_disk_file;
+ switch (source_tree->DiskFileToVirtualFile(*proto, &virtual_file,
+ &shadowing_disk_file)) {
+ case DiskSourceTree::SUCCESS:
+ *proto = virtual_file;
+ break;
+ case DiskSourceTree::SHADOWED:
+ std::cerr << *proto << ": Input is shadowed in the --proto_path by \""
+ << shadowing_disk_file
+ << "\". Either use the latter file as your input or reorder "
+ "the --proto_path so that the former file's location "
+ "comes first."
+ << std::endl;
+ return false;
+ case DiskSourceTree::CANNOT_OPEN: {
+ if (in_fallback_database) {
+ return true;
+ }
+ std::string error_str = source_tree->GetLastErrorMessage().empty()
+ ? strerror(errno)
+ : source_tree->GetLastErrorMessage();
+ std::cerr << "Could not map to virtual file: " << *proto << ": "
+ << error_str << std::endl;
+ return false;
+ }
+ case DiskSourceTree::NO_MAPPING: {
+ // Try to interpret the path as a virtual path.
+ std::string disk_file;
+ if (source_tree->VirtualFileToDiskFile(*proto, &disk_file) ||
+ in_fallback_database) {
+ return true;
+ } else {
+ // The input file path can't be mapped to any --proto_path and it also
+ // can't be interpreted as a virtual path.
+ std::cerr
+ << *proto
+ << ": File does not reside within any path "
+ "specified using --proto_path (or -I). You must specify a "
+ "--proto_path which encompasses this file. Note that the "
+ "proto_path must be an exact prefix of the .proto file "
+ "names -- protoc is too dumb to figure out when two paths "
+ "(e.g. absolute and relative) are equivalent (it's harder "
+ "than you think)."
+ << std::endl;
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
+bool CommandLineInterface::MakeInputsBeProtoPathRelative(
+ DiskSourceTree* source_tree, DescriptorDatabase* fallback_database) {
+ for (auto& input_file : input_files_) {
+ if (!MakeProtoProtoPathRelative(source_tree, &input_file,
+ fallback_database)) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+
+bool CommandLineInterface::ExpandArgumentFile(
+ const std::string& file, std::vector<std::string>* arguments) {
+ // The argument file is searched in the working directory only. We don't
+ // use the proto import path here.
+ std::ifstream file_stream(file.c_str());
+ if (!file_stream.is_open()) {
+ return false;
+ }
+ std::string argument;
+ // We don't support any kind of shell expansion right now.
+ while (std::getline(file_stream, argument)) {
+ arguments->push_back(argument);
+ }
+ return true;
+}
+
+CommandLineInterface::ParseArgumentStatus CommandLineInterface::ParseArguments(
+ int argc, const char* const argv[]) {
+ executable_name_ = argv[0];
+
+ std::vector<std::string> arguments;
+ for (int i = 1; i < argc; ++i) {
+ if (argv[i][0] == '@') {
+ if (!ExpandArgumentFile(argv[i] + 1, &arguments)) {
+ std::cerr << "Failed to open argument file: " << (argv[i] + 1)
+ << std::endl;
+ return PARSE_ARGUMENT_FAIL;
+ }
+ continue;
+ }
+ arguments.push_back(argv[i]);
+ }
+
+ // if no arguments are given, show help
+ if (arguments.empty()) {
+ PrintHelpText();
+ return PARSE_ARGUMENT_DONE_AND_EXIT; // Exit without running compiler.
+ }
+
+ // Iterate through all arguments and parse them.
+ for (int i = 0; i < arguments.size(); ++i) {
+ std::string name, value;
+
+ if (ParseArgument(arguments[i].c_str(), &name, &value)) {
+ // Returned true => Use the next argument as the flag value.
+ if (i + 1 == arguments.size() || arguments[i + 1][0] == '-') {
+ std::cerr << "Missing value for flag: " << name << std::endl;
+ if (name == "--decode") {
+ std::cerr << "To decode an unknown message, use --decode_raw."
+ << std::endl;
+ }
+ return PARSE_ARGUMENT_FAIL;
+ } else {
+ ++i;
+ value = arguments[i];
+ }
+ }
+
+ ParseArgumentStatus status = InterpretArgument(name, value);
+ if (status != PARSE_ARGUMENT_DONE_AND_CONTINUE) return status;
+ }
+
+ // Make sure each plugin option has a matching plugin output.
+ bool foundUnknownPluginOption = false;
+ for (std::map<std::string, std::string>::const_iterator i =
+ plugin_parameters_.begin();
+ i != plugin_parameters_.end(); ++i) {
+ if (plugins_.find(i->first) != plugins_.end()) {
+ continue;
+ }
+ bool foundImplicitPlugin = false;
+ for (std::vector<OutputDirective>::const_iterator j =
+ output_directives_.begin();
+ j != output_directives_.end(); ++j) {
+ if (j->generator == NULL) {
+ std::string plugin_name = PluginName(plugin_prefix_, j->name);
+ if (plugin_name == i->first) {
+ foundImplicitPlugin = true;
+ break;
+ }
+ }
+ }
+ if (!foundImplicitPlugin) {
+ std::cerr << "Unknown flag: "
+ // strip prefix + "gen-" and add back "_opt"
+ << "--" + i->first.substr(plugin_prefix_.size() + 4) + "_opt"
+ << std::endl;
+ foundUnknownPluginOption = true;
+ }
+ }
+ if (foundUnknownPluginOption) {
+ return PARSE_ARGUMENT_FAIL;
+ }
+
+ // The --proto_path & --descriptor_set_in flags both specify places to look
+ // for proto files. If neither were given, use the current working directory.
+ if (proto_path_.empty() && descriptor_set_in_names_.empty()) {
+ // Don't use make_pair as the old/default standard library on Solaris
+ // doesn't support it without explicit template parameters, which are
+ // incompatible with C++0x's make_pair.
+ proto_path_.push_back(std::pair<std::string, std::string>("", "."));
+ }
+
+ // Check error cases that span multiple flag values.
+ bool missing_proto_definitions = false;
+ switch (mode_) {
+ case MODE_COMPILE:
+ missing_proto_definitions = input_files_.empty();
+ break;
+ case MODE_DECODE:
+ // Handle --decode_raw separately, since it requires that no proto
+ // definitions are specified.
+ if (codec_type_.empty()) {
+ if (!input_files_.empty() || !descriptor_set_in_names_.empty()) {
+ std::cerr
+ << "When using --decode_raw, no input files should be given."
+ << std::endl;
+ return PARSE_ARGUMENT_FAIL;
+ }
+ missing_proto_definitions = false;
+ break; // only for --decode_raw
+ }
+ // --decode (not raw) is handled the same way as the rest of the modes.
+ PROTOBUF_FALLTHROUGH_INTENDED;
+ case MODE_ENCODE:
+ case MODE_PRINT:
+ missing_proto_definitions =
+ input_files_.empty() && descriptor_set_in_names_.empty();
+ break;
+ default:
+ GOOGLE_LOG(FATAL) << "Unexpected mode: " << mode_;
+ }
+ if (missing_proto_definitions) {
+ std::cerr << "Missing input file." << std::endl;
+ return PARSE_ARGUMENT_FAIL;
+ }
+ if (mode_ == MODE_COMPILE && output_directives_.empty() &&
+ descriptor_set_out_name_.empty()) {
+ std::cerr << "Missing output directives." << std::endl;
+ return PARSE_ARGUMENT_FAIL;
+ }
+ if (mode_ != MODE_COMPILE && !dependency_out_name_.empty()) {
+ std::cerr << "Can only use --dependency_out=FILE when generating code."
+ << std::endl;
+ return PARSE_ARGUMENT_FAIL;
+ }
+ if (mode_ != MODE_ENCODE && deterministic_output_) {
+ std::cerr << "Can only use --deterministic_output with --encode."
+ << std::endl;
+ return PARSE_ARGUMENT_FAIL;
+ }
+ if (!dependency_out_name_.empty() && input_files_.size() > 1) {
+ std::cerr
+ << "Can only process one input file when using --dependency_out=FILE."
+ << std::endl;
+ return PARSE_ARGUMENT_FAIL;
+ }
+ if (imports_in_descriptor_set_ && descriptor_set_out_name_.empty()) {
+ std::cerr << "--include_imports only makes sense when combined with "
+ "--descriptor_set_out."
+ << std::endl;
+ }
+ if (source_info_in_descriptor_set_ && descriptor_set_out_name_.empty()) {
+ std::cerr << "--include_source_info only makes sense when combined with "
+ "--descriptor_set_out."
+ << std::endl;
+ }
+
+ return PARSE_ARGUMENT_DONE_AND_CONTINUE;
+}
+
+bool CommandLineInterface::ParseArgument(const char* arg, std::string* name,
+ std::string* value) {
+ bool parsed_value = false;
+
+ if (arg[0] != '-') {
+ // Not a flag.
+ name->clear();
+ parsed_value = true;
+ *value = arg;
+ } else if (arg[1] == '-') {
+ // Two dashes: Multi-character name, with '=' separating name and
+ // value.
+ const char* equals_pos = strchr(arg, '=');
+ if (equals_pos != NULL) {
+ *name = std::string(arg, equals_pos - arg);
+ *value = equals_pos + 1;
+ parsed_value = true;
+ } else {
+ *name = arg;
+ }
+ } else {
+ // One dash: One-character name, all subsequent characters are the
+ // value.
+ if (arg[1] == '\0') {
+ // arg is just "-". We treat this as an input file, except that at
+ // present this will just lead to a "file not found" error.
+ name->clear();
+ *value = arg;
+ parsed_value = true;
+ } else {
+ *name = std::string(arg, 2);
+ *value = arg + 2;
+ parsed_value = !value->empty();
+ }
+ }
+
+ // Need to return true iff the next arg should be used as the value for this
+ // one, false otherwise.
+
+ if (parsed_value) {
+ // We already parsed a value for this flag.
+ return false;
+ }
+
+ if (*name == "-h" || *name == "--help" || *name == "--disallow_services" ||
+ *name == "--include_imports" || *name == "--include_source_info" ||
+ *name == "--version" || *name == "--decode_raw" ||
+ *name == "--print_free_field_numbers" ||
+ *name == "--experimental_allow_proto3_optional" ||
+ *name == "--deterministic_output" || *name == "--fatal_warnings") {
+ // HACK: These are the only flags that don't take a value.
+ // They probably should not be hard-coded like this but for now it's
+ // not worth doing better.
+ return false;
+ }
+
+ // Next argument is the flag value.
+ return true;
+}
+
+CommandLineInterface::ParseArgumentStatus
+CommandLineInterface::InterpretArgument(const std::string& name,
+ const std::string& value) {
+ if (name.empty()) {
+ // Not a flag. Just a filename.
+ if (value.empty()) {
+ std::cerr
+ << "You seem to have passed an empty string as one of the "
+ "arguments to "
+ << executable_name_
+ << ". This is actually "
+ "sort of hard to do. Congrats. Unfortunately it is not valid "
+ "input so the program is going to die now."
+ << std::endl;
+ return PARSE_ARGUMENT_FAIL;
+ }
+
+#if defined(_WIN32)
+ // On Windows, the shell (typically cmd.exe) does not expand wildcards in
+ // file names (e.g. foo\*.proto), so we do it ourselves.
+ switch (google::protobuf::io::win32::ExpandWildcards(
+ value,
+ [this](const string& path) { this->input_files_.push_back(path); })) {
+ case google::protobuf::io::win32::ExpandWildcardsResult::kSuccess:
+ break;
+ case google::protobuf::io::win32::ExpandWildcardsResult::
+ kErrorNoMatchingFile:
+ // Path does not exist, is not a file, or it's longer than MAX_PATH and
+ // long path handling is disabled.
+ std::cerr << "Invalid file name pattern or missing input file \""
+ << value << "\"" << std::endl;
+ return PARSE_ARGUMENT_FAIL;
+ default:
+ std::cerr << "Cannot convert path \"" << value
+ << "\" to or from Windows style" << std::endl;
+ return PARSE_ARGUMENT_FAIL;
+ }
+#else // not _WIN32
+ // On other platforms than Windows (e.g. Linux, Mac OS) the shell (typically
+ // Bash) expands wildcards.
+ input_files_.push_back(value);
+#endif // _WIN32
+
+ } else if (name == "-I" || name == "--proto_path") {
+ // Java's -classpath (and some other languages) delimits path components
+ // with colons. Let's accept that syntax too just to make things more
+ // intuitive.
+ std::vector<std::string> parts = Split(
+ value, CommandLineInterface::kPathSeparator,
+ true);
+
+ for (int i = 0; i < parts.size(); i++) {
+ std::string virtual_path;
+ std::string disk_path;
+
+ std::string::size_type equals_pos = parts[i].find_first_of('=');
+ if (equals_pos == std::string::npos) {
+ virtual_path = "";
+ disk_path = parts[i];
+ } else {
+ virtual_path = parts[i].substr(0, equals_pos);
+ disk_path = parts[i].substr(equals_pos + 1);
+ }
+
+ if (disk_path.empty()) {
+ std::cerr
+ << "--proto_path passed empty directory name. (Use \".\" for "
+ "current directory.)"
+ << std::endl;
+ return PARSE_ARGUMENT_FAIL;
+ }
+
+ // Make sure disk path exists, warn otherwise.
+ if (access(disk_path.c_str(), F_OK) < 0) {
+ // Try the original path; it may have just happened to have a '=' in it.
+ if (access(parts[i].c_str(), F_OK) < 0) {
+ std::cerr << disk_path << ": warning: directory does not exist."
+ << std::endl;
+ } else {
+ virtual_path = "";
+ disk_path = parts[i];
+ }
+ }
+
+ // Don't use make_pair as the old/default standard library on Solaris
+ // doesn't support it without explicit template parameters, which are
+ // incompatible with C++0x's make_pair.
+ proto_path_.push_back(
+ std::pair<std::string, std::string>(virtual_path, disk_path));
+ }
+
+ } else if (name == "--direct_dependencies") {
+ if (direct_dependencies_explicitly_set_) {
+ std::cerr << name
+ << " may only be passed once. To specify multiple "
+ "direct dependencies, pass them all as a single "
+ "parameter separated by ':'."
+ << std::endl;
+ return PARSE_ARGUMENT_FAIL;
+ }
+
+ direct_dependencies_explicitly_set_ = true;
+ std::vector<std::string> direct =
+ Split(value, ":", true);
+ GOOGLE_DCHECK(direct_dependencies_.empty());
+ direct_dependencies_.insert(direct.begin(), direct.end());
+
+ } else if (name == "--direct_dependencies_violation_msg") {
+ direct_dependencies_violation_msg_ = value;
+
+ } else if (name == "--descriptor_set_in") {
+ if (!descriptor_set_in_names_.empty()) {
+ std::cerr << name
+ << " may only be passed once. To specify multiple "
+ "descriptor sets, pass them all as a single "
+ "parameter separated by '"
+ << CommandLineInterface::kPathSeparator << "'." << std::endl;
+ return PARSE_ARGUMENT_FAIL;
+ }
+ if (value.empty()) {
+ std::cerr << name << " requires a non-empty value." << std::endl;
+ return PARSE_ARGUMENT_FAIL;
+ }
+ if (!dependency_out_name_.empty()) {
+ std::cerr << name << " cannot be used with --dependency_out."
+ << std::endl;
+ return PARSE_ARGUMENT_FAIL;
+ }
+
+ descriptor_set_in_names_ = Split(
+ value, CommandLineInterface::kPathSeparator,
+ true);
+
+ } else if (name == "-o" || name == "--descriptor_set_out") {
+ if (!descriptor_set_out_name_.empty()) {
+ std::cerr << name << " may only be passed once." << std::endl;
+ return PARSE_ARGUMENT_FAIL;
+ }
+ if (value.empty()) {
+ std::cerr << name << " requires a non-empty value." << std::endl;
+ return PARSE_ARGUMENT_FAIL;
+ }
+ if (mode_ != MODE_COMPILE) {
+ std::cerr
+ << "Cannot use --encode or --decode and generate descriptors at the "
+ "same time."
+ << std::endl;
+ return PARSE_ARGUMENT_FAIL;
+ }
+ descriptor_set_out_name_ = value;
+
+ } else if (name == "--dependency_out") {
+ if (!dependency_out_name_.empty()) {
+ std::cerr << name << " may only be passed once." << std::endl;
+ return PARSE_ARGUMENT_FAIL;
+ }
+ if (value.empty()) {
+ std::cerr << name << " requires a non-empty value." << std::endl;
+ return PARSE_ARGUMENT_FAIL;
+ }
+ if (!descriptor_set_in_names_.empty()) {
+ std::cerr << name << " cannot be used with --descriptor_set_in."
+ << std::endl;
+ return PARSE_ARGUMENT_FAIL;
+ }
+ dependency_out_name_ = value;
+
+ } else if (name == "--include_imports") {
+ if (imports_in_descriptor_set_) {
+ std::cerr << name << " may only be passed once." << std::endl;
+ return PARSE_ARGUMENT_FAIL;
+ }
+ imports_in_descriptor_set_ = true;
+
+ } else if (name == "--include_source_info") {
+ if (source_info_in_descriptor_set_) {
+ std::cerr << name << " may only be passed once." << std::endl;
+ return PARSE_ARGUMENT_FAIL;
+ }
+ source_info_in_descriptor_set_ = true;
+
+ } else if (name == "-h" || name == "--help") {
+ PrintHelpText();
+ return PARSE_ARGUMENT_DONE_AND_EXIT; // Exit without running compiler.
+
+ } else if (name == "--version") {
+ if (!version_info_.empty()) {
+ std::cout << version_info_ << std::endl;
+ }
+ std::cout << "libprotoc " << internal::VersionString(PROTOBUF_VERSION)
+ << PROTOBUF_VERSION_SUFFIX << std::endl;
+ return PARSE_ARGUMENT_DONE_AND_EXIT; // Exit without running compiler.
+
+ } else if (name == "--disallow_services") {
+ disallow_services_ = true;
+
+
+ } else if (name == "--experimental_allow_proto3_optional") {
+ // Flag is no longer observed, but we allow it for backward compat.
+ } else if (name == "--encode" || name == "--decode" ||
+ name == "--decode_raw") {
+ if (mode_ != MODE_COMPILE) {
+ std::cerr << "Only one of --encode and --decode can be specified."
+ << std::endl;
+ return PARSE_ARGUMENT_FAIL;
+ }
+ if (!output_directives_.empty() || !descriptor_set_out_name_.empty()) {
+ std::cerr << "Cannot use " << name
+ << " and generate code or descriptors at the same time."
+ << std::endl;
+ return PARSE_ARGUMENT_FAIL;
+ }
+
+ mode_ = (name == "--encode") ? MODE_ENCODE : MODE_DECODE;
+
+ if (value.empty() && name != "--decode_raw") {
+ std::cerr << "Type name for " << name << " cannot be blank." << std::endl;
+ if (name == "--decode") {
+ std::cerr << "To decode an unknown message, use --decode_raw."
+ << std::endl;
+ }
+ return PARSE_ARGUMENT_FAIL;
+ } else if (!value.empty() && name == "--decode_raw") {
+ std::cerr << "--decode_raw does not take a parameter." << std::endl;
+ return PARSE_ARGUMENT_FAIL;
+ }
+
+ codec_type_ = value;
+
+ } else if (name == "--deterministic_output") {
+ deterministic_output_ = true;
+
+ } else if (name == "--error_format") {
+ if (value == "gcc") {
+ error_format_ = ERROR_FORMAT_GCC;
+ } else if (value == "msvs") {
+ error_format_ = ERROR_FORMAT_MSVS;
+ } else {
+ std::cerr << "Unknown error format: " << value << std::endl;
+ return PARSE_ARGUMENT_FAIL;
+ }
+
+ } else if (name == "--fatal_warnings") {
+ if (fatal_warnings_) {
+ std::cerr << name << " may only be passed once." << std::endl;
+ return PARSE_ARGUMENT_FAIL;
+ }
+ fatal_warnings_ = true;
+ } else if (name == "--plugin") {
+ if (plugin_prefix_.empty()) {
+ std::cerr << "This compiler does not support plugins." << std::endl;
+ return PARSE_ARGUMENT_FAIL;
+ }
+
+ std::string plugin_name;
+ std::string path;
+
+ std::string::size_type equals_pos = value.find_first_of('=');
+ if (equals_pos == std::string::npos) {
+ // Use the basename of the file.
+ std::string::size_type slash_pos = value.find_last_of('/');
+ if (slash_pos == std::string::npos) {
+ plugin_name = value;
+ } else {
+ plugin_name = value.substr(slash_pos + 1);
+ }
+ path = value;
+ } else {
+ plugin_name = value.substr(0, equals_pos);
+ path = value.substr(equals_pos + 1);
+ }
+
+ plugins_[plugin_name] = path;
+
+ } else if (name == "--print_free_field_numbers") {
+ if (mode_ != MODE_COMPILE) {
+ std::cerr << "Cannot use " << name
+ << " and use --encode, --decode or print "
+ << "other info at the same time." << std::endl;
+ return PARSE_ARGUMENT_FAIL;
+ }
+ if (!output_directives_.empty() || !descriptor_set_out_name_.empty()) {
+ std::cerr << "Cannot use " << name
+ << " and generate code or descriptors at the same time."
+ << std::endl;
+ return PARSE_ARGUMENT_FAIL;
+ }
+ mode_ = MODE_PRINT;
+ print_mode_ = PRINT_FREE_FIELDS;
+ } else {
+ // Some other flag. Look it up in the generators list.
+ const GeneratorInfo* generator_info =
+ FindOrNull(generators_by_flag_name_, name);
+ if (generator_info == NULL &&
+ (plugin_prefix_.empty() || !HasSuffixString(name, "_out"))) {
+ // Check if it's a generator option flag.
+ generator_info = FindOrNull(generators_by_option_name_, name);
+ if (generator_info != NULL) {
+ std::string* parameters =
+ &generator_parameters_[generator_info->flag_name];
+ if (!parameters->empty()) {
+ parameters->append(",");
+ }
+ parameters->append(value);
+ } else if (HasPrefixString(name, "--") && HasSuffixString(name, "_opt")) {
+ std::string* parameters =
+ &plugin_parameters_[PluginName(plugin_prefix_, name)];
+ if (!parameters->empty()) {
+ parameters->append(",");
+ }
+ parameters->append(value);
+ } else {
+ std::cerr << "Unknown flag: " << name << std::endl;
+ return PARSE_ARGUMENT_FAIL;
+ }
+ } else {
+ // It's an output flag. Add it to the output directives.
+ if (mode_ != MODE_COMPILE) {
+ std::cerr << "Cannot use --encode, --decode or print .proto info and "
+ "generate code at the same time."
+ << std::endl;
+ return PARSE_ARGUMENT_FAIL;
+ }
+
+ OutputDirective directive;
+ directive.name = name;
+ if (generator_info == NULL) {
+ directive.generator = NULL;
+ } else {
+ directive.generator = generator_info->generator;
+ }
+
+ // Split value at ':' to separate the generator parameter from the
+ // filename. However, avoid doing this if the colon is part of a valid
+ // Windows-style absolute path.
+ std::string::size_type colon_pos = value.find_first_of(':');
+ if (colon_pos == std::string::npos || IsWindowsAbsolutePath(value)) {
+ directive.output_location = value;
+ } else {
+ directive.parameter = value.substr(0, colon_pos);
+ directive.output_location = value.substr(colon_pos + 1);
+ }
+
+ output_directives_.push_back(directive);
+ }
+ }
+
+ return PARSE_ARGUMENT_DONE_AND_CONTINUE;
+}
+
+void CommandLineInterface::PrintHelpText() {
+ // Sorry for indentation here; line wrapping would be uglier.
+ std::cout << "Usage: " << executable_name_ << " [OPTION] PROTO_FILES";
+ std::cout << R"(
+Parse PROTO_FILES and generate output based on the options given:
+ -IPATH, --proto_path=PATH Specify the directory in which to search for
+ imports. May be specified multiple times;
+ directories will be searched in order. If not
+ given, the current working directory is used.
+ If not found in any of the these directories,
+ the --descriptor_set_in descriptors will be
+ checked for required proto file.
+ --version Show version info and exit.
+ -h, --help Show this text and exit.
+ --encode=MESSAGE_TYPE Read a text-format message of the given type
+ from standard input and write it in binary
+ to standard output. The message type must
+ be defined in PROTO_FILES or their imports.
+ --deterministic_output When using --encode, ensure map fields are
+ deterministically ordered. Note that this order
+ is not canonical, and changes across builds or
+ releases of protoc.
+ --decode=MESSAGE_TYPE Read a binary message of the given type from
+ standard input and write it in text format
+ to standard output. The message type must
+ be defined in PROTO_FILES or their imports.
+ --decode_raw Read an arbitrary protocol message from
+ standard input and write the raw tag/value
+ pairs in text format to standard output. No
+ PROTO_FILES should be given when using this
+ flag.
+ --descriptor_set_in=FILES Specifies a delimited list of FILES
+ each containing a FileDescriptorSet (a
+ protocol buffer defined in descriptor.proto).
+ The FileDescriptor for each of the PROTO_FILES
+ provided will be loaded from these
+ FileDescriptorSets. If a FileDescriptor
+ appears multiple times, the first occurrence
+ will be used.
+ -oFILE, Writes a FileDescriptorSet (a protocol buffer,
+ --descriptor_set_out=FILE defined in descriptor.proto) containing all of
+ the input files to FILE.
+ --include_imports When using --descriptor_set_out, also include
+ all dependencies of the input files in the
+ set, so that the set is self-contained.
+ --include_source_info When using --descriptor_set_out, do not strip
+ SourceCodeInfo from the FileDescriptorProto.
+ This results in vastly larger descriptors that
+ include information about the original
+ location of each decl in the source file as
+ well as surrounding comments.
+ --dependency_out=FILE Write a dependency output file in the format
+ expected by make. This writes the transitive
+ set of input file paths to FILE
+ --error_format=FORMAT Set the format in which to print errors.
+ FORMAT may be 'gcc' (the default) or 'msvs'
+ (Microsoft Visual Studio format).
+ --fatal_warnings Make warnings be fatal (similar to -Werr in
+ gcc). This flag will make protoc return
+ with a non-zero exit code if any warnings
+ are generated.
+ --print_free_field_numbers Print the free field numbers of the messages
+ defined in the given proto files. Groups share
+ the same field number space with the parent
+ message. Extension ranges are counted as
+ occupied fields numbers.)";
+ if (!plugin_prefix_.empty()) {
+ std::cout << R"(
+ --plugin=EXECUTABLE Specifies a plugin executable to use.
+ Normally, protoc searches the PATH for
+ plugins, but you may specify additional
+ executables not in the path using this flag.
+ Additionally, EXECUTABLE may be of the form
+ NAME=PATH, in which case the given plugin name
+ is mapped to the given executable even if
+ the executable's own name differs.)";
+ }
+
+ for (GeneratorMap::iterator iter = generators_by_flag_name_.begin();
+ iter != generators_by_flag_name_.end(); ++iter) {
+ // FIXME(kenton): If the text is long enough it will wrap, which is ugly,
+ // but fixing this nicely (e.g. splitting on spaces) is probably more
+ // trouble than it's worth.
+ std::cout << std::endl
+ << " " << iter->first << "=OUT_DIR "
+ << std::string(19 - iter->first.size(),
+ ' ') // Spaces for alignment.
+ << iter->second.help_text;
+ }
+ std::cout << R"(
+ @<filename> Read options and filenames from file. If a
+ relative file path is specified, the file
+ will be searched in the working directory.
+ The --proto_path option will not affect how
+ this argument file is searched. Content of
+ the file will be expanded in the position of
+ @<filename> as in the argument list. Note
+ that shell expansion is not applied to the
+ content of the file (i.e., you cannot use
+ quotes, wildcards, escapes, commands, etc.).
+ Each line corresponds to a single argument,
+ even if it contains spaces.)";
+ std::cout << std::endl;
+}
+
+bool CommandLineInterface::EnforceProto3OptionalSupport(
+ const std::string& codegen_name, uint64_t supported_features,
+ const std::vector<const FileDescriptor*>& parsed_files) const {
+ bool supports_proto3_optional =
+ supported_features & CodeGenerator::FEATURE_PROTO3_OPTIONAL;
+ if (!supports_proto3_optional) {
+ for (const auto fd : parsed_files) {
+ if (ContainsProto3Optional(fd)) {
+ std::cerr << fd->name()
+ << ": is a proto3 file that contains optional fields, but "
+ "code generator "
+ << codegen_name
+ << " hasn't been updated to support optional fields in "
+ "proto3. Please ask the owner of this code generator to "
+ "support proto3 optional.";
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
+bool CommandLineInterface::GenerateOutput(
+ const std::vector<const FileDescriptor*>& parsed_files,
+ const OutputDirective& output_directive,
+ GeneratorContext* generator_context) {
+ // Call the generator.
+ std::string error;
+ if (output_directive.generator == NULL) {
+ // This is a plugin.
+ GOOGLE_CHECK(HasPrefixString(output_directive.name, "--") &&
+ HasSuffixString(output_directive.name, "_out"))
+ << "Bad name for plugin generator: " << output_directive.name;
+
+ std::string plugin_name = PluginName(plugin_prefix_, output_directive.name);
+ std::string parameters = output_directive.parameter;
+ if (!plugin_parameters_[plugin_name].empty()) {
+ if (!parameters.empty()) {
+ parameters.append(",");
+ }
+ parameters.append(plugin_parameters_[plugin_name]);
+ }
+ if (!GeneratePluginOutput(parsed_files, plugin_name, parameters,
+ generator_context, &error)) {
+ std::cerr << output_directive.name << ": " << error << std::endl;
+ return false;
+ }
+ } else {
+ // Regular generator.
+ std::string parameters = output_directive.parameter;
+ if (!generator_parameters_[output_directive.name].empty()) {
+ if (!parameters.empty()) {
+ parameters.append(",");
+ }
+ parameters.append(generator_parameters_[output_directive.name]);
+ }
+ if (!EnforceProto3OptionalSupport(
+ output_directive.name,
+ output_directive.generator->GetSupportedFeatures(), parsed_files)) {
+ return false;
+ }
+
+ if (!output_directive.generator->GenerateAll(parsed_files, parameters,
+ generator_context, &error)) {
+ // Generator returned an error.
+ std::cerr << output_directive.name << ": " << error << std::endl;
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool CommandLineInterface::GenerateDependencyManifestFile(
+ const std::vector<const FileDescriptor*>& parsed_files,
+ const GeneratorContextMap& output_directories,
+ DiskSourceTree* source_tree) {
+ FileDescriptorSet file_set;
+
+ std::set<const FileDescriptor*> already_seen;
+ for (int i = 0; i < parsed_files.size(); i++) {
+ GetTransitiveDependencies(parsed_files[i], false, false, &already_seen,
+ file_set.mutable_file());
+ }
+
+ std::vector<std::string> output_filenames;
+ for (const auto& pair : output_directories) {
+ const std::string& location = pair.first;
+ GeneratorContextImpl* directory = pair.second.get();
+ std::vector<std::string> relative_output_filenames;
+ directory->GetOutputFilenames(&relative_output_filenames);
+ for (int i = 0; i < relative_output_filenames.size(); i++) {
+ std::string output_filename = location + relative_output_filenames[i];
+ if (output_filename.compare(0, 2, "./") == 0) {
+ output_filename = output_filename.substr(2);
+ }
+ output_filenames.push_back(output_filename);
+ }
+ }
+
+ int fd;
+ do {
+ fd = open(dependency_out_name_.c_str(),
+ O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666);
+ } while (fd < 0 && errno == EINTR);
+
+ if (fd < 0) {
+ perror(dependency_out_name_.c_str());
+ return false;
+ }
+
+ io::FileOutputStream out(fd);
+ io::Printer printer(&out, '$');
+
+ for (int i = 0; i < output_filenames.size(); i++) {
+ printer.Print(output_filenames[i].c_str());
+ if (i == output_filenames.size() - 1) {
+ printer.Print(":");
+ } else {
+ printer.Print(" \\\n");
+ }
+ }
+
+ for (int i = 0; i < file_set.file_size(); i++) {
+ const FileDescriptorProto& file = file_set.file(i);
+ const std::string& virtual_file = file.name();
+ std::string disk_file;
+ if (source_tree &&
+ source_tree->VirtualFileToDiskFile(virtual_file, &disk_file)) {
+ printer.Print(" $disk_file$", "disk_file", disk_file);
+ if (i < file_set.file_size() - 1) printer.Print("\\\n");
+ } else {
+ std::cerr << "Unable to identify path for file " << virtual_file
+ << std::endl;
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool CommandLineInterface::GeneratePluginOutput(
+ const std::vector<const FileDescriptor*>& parsed_files,
+ const std::string& plugin_name, const std::string& parameter,
+ GeneratorContext* generator_context, std::string* error) {
+ CodeGeneratorRequest request;
+ CodeGeneratorResponse response;
+ std::string processed_parameter = parameter;
+
+
+ // Build the request.
+ if (!processed_parameter.empty()) {
+ request.set_parameter(processed_parameter);
+ }
+
+
+ std::set<const FileDescriptor*> already_seen;
+ for (int i = 0; i < parsed_files.size(); i++) {
+ request.add_file_to_generate(parsed_files[i]->name());
+ GetTransitiveDependencies(parsed_files[i],
+ true, // Include json_name for plugins.
+ true, // Include source code info.
+ &already_seen, request.mutable_proto_file());
+ }
+
+ google::protobuf::compiler::Version* version =
+ request.mutable_compiler_version();
+ version->set_major(PROTOBUF_VERSION / 1000000);
+ version->set_minor(PROTOBUF_VERSION / 1000 % 1000);
+ version->set_patch(PROTOBUF_VERSION % 1000);
+ version->set_suffix(PROTOBUF_VERSION_SUFFIX);
+
+ // Invoke the plugin.
+ Subprocess subprocess;
+
+ if (plugins_.count(plugin_name) > 0) {
+ subprocess.Start(plugins_[plugin_name], Subprocess::EXACT_NAME);
+ } else {
+ subprocess.Start(plugin_name, Subprocess::SEARCH_PATH);
+ }
+
+ std::string communicate_error;
+ if (!subprocess.Communicate(request, &response, &communicate_error)) {
+ *error = strings::Substitute("$0: $1", plugin_name, communicate_error);
+ return false;
+ }
+
+ // Write the files. We do this even if there was a generator error in order
+ // to match the behavior of a compiled-in generator.
+ std::unique_ptr<io::ZeroCopyOutputStream> current_output;
+ for (int i = 0; i < response.file_size(); i++) {
+ const CodeGeneratorResponse::File& output_file = response.file(i);
+
+ if (!output_file.insertion_point().empty()) {
+ std::string filename = output_file.name();
+ // Open a file for insert.
+ // We reset current_output to NULL first so that the old file is closed
+ // before the new one is opened.
+ current_output.reset();
+ current_output.reset(
+ generator_context->OpenForInsertWithGeneratedCodeInfo(
+ filename, output_file.insertion_point(),
+ output_file.generated_code_info()));
+ } else if (!output_file.name().empty()) {
+ // Starting a new file. Open it.
+ // We reset current_output to NULL first so that the old file is closed
+ // before the new one is opened.
+ current_output.reset();
+ current_output.reset(generator_context->Open(output_file.name()));
+ } else if (current_output == NULL) {
+ *error = strings::Substitute(
+ "$0: First file chunk returned by plugin did not specify a file "
+ "name.",
+ plugin_name);
+ return false;
+ }
+
+ // Use CodedOutputStream for convenience; otherwise we'd need to provide
+ // our own buffer-copying loop.
+ io::CodedOutputStream writer(current_output.get());
+ writer.WriteString(output_file.content());
+ }
+
+ // Check for errors.
+ if (!response.error().empty()) {
+ // Generator returned an error.
+ *error = response.error();
+ return false;
+ } else if (!EnforceProto3OptionalSupport(
+ plugin_name, response.supported_features(), parsed_files)) {
+ return false;
+ }
+
+ return true;
+}
+
+bool CommandLineInterface::EncodeOrDecode(const DescriptorPool* pool) {
+ // Look up the type.
+ const Descriptor* type = pool->FindMessageTypeByName(codec_type_);
+ if (type == NULL) {
+ std::cerr << "Type not defined: " << codec_type_ << std::endl;
+ return false;
+ }
+
+ DynamicMessageFactory dynamic_factory(pool);
+ std::unique_ptr<Message> message(dynamic_factory.GetPrototype(type)->New());
+
+ if (mode_ == MODE_ENCODE) {
+ SetFdToTextMode(STDIN_FILENO);
+ SetFdToBinaryMode(STDOUT_FILENO);
+ } else {
+ SetFdToBinaryMode(STDIN_FILENO);
+ SetFdToTextMode(STDOUT_FILENO);
+ }
+
+ io::FileInputStream in(STDIN_FILENO);
+ io::FileOutputStream out(STDOUT_FILENO);
+
+ if (mode_ == MODE_ENCODE) {
+ // Input is text.
+ ErrorPrinter error_collector(error_format_);
+ TextFormat::Parser parser;
+ parser.RecordErrorsTo(&error_collector);
+ parser.AllowPartialMessage(true);
+
+ if (!parser.Parse(&in, message.get())) {
+ std::cerr << "Failed to parse input." << std::endl;
+ return false;
+ }
+ } else {
+ // Input is binary.
+ if (!message->ParsePartialFromZeroCopyStream(&in)) {
+ std::cerr << "Failed to parse input." << std::endl;
+ return false;
+ }
+ }
+
+ if (!message->IsInitialized()) {
+ std::cerr << "warning: Input message is missing required fields: "
+ << message->InitializationErrorString() << std::endl;
+ }
+
+ if (mode_ == MODE_ENCODE) {
+ // Output is binary.
+ io::CodedOutputStream coded_out(&out);
+ coded_out.SetSerializationDeterministic(deterministic_output_);
+ if (!message->SerializePartialToCodedStream(&coded_out)) {
+ std::cerr << "output: I/O error." << std::endl;
+ return false;
+ }
+ } else {
+ // Output is text.
+ if (!TextFormat::Print(*message, &out)) {
+ std::cerr << "output: I/O error." << std::endl;
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool CommandLineInterface::WriteDescriptorSet(
+ const std::vector<const FileDescriptor*>& parsed_files) {
+ FileDescriptorSet file_set;
+
+ std::set<const FileDescriptor*> already_seen;
+ if (!imports_in_descriptor_set_) {
+ // Since we don't want to output transitive dependencies, but we do want
+ // things to be in dependency order, add all dependencies that aren't in
+ // parsed_files to already_seen. This will short circuit the recursion
+ // in GetTransitiveDependencies.
+ std::set<const FileDescriptor*> to_output;
+ to_output.insert(parsed_files.begin(), parsed_files.end());
+ for (int i = 0; i < parsed_files.size(); i++) {
+ const FileDescriptor* file = parsed_files[i];
+ for (int j = 0; j < file->dependency_count(); j++) {
+ const FileDescriptor* dependency = file->dependency(j);
+ // if the dependency isn't in parsed files, mark it as already seen
+ if (to_output.find(dependency) == to_output.end()) {
+ already_seen.insert(dependency);
+ }
+ }
+ }
+ }
+ for (int i = 0; i < parsed_files.size(); i++) {
+ GetTransitiveDependencies(parsed_files[i],
+ true, // Include json_name
+ source_info_in_descriptor_set_, &already_seen,
+ file_set.mutable_file());
+ }
+
+ int fd;
+ do {
+ fd = open(descriptor_set_out_name_.c_str(),
+ O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666);
+ } while (fd < 0 && errno == EINTR);
+
+ if (fd < 0) {
+ perror(descriptor_set_out_name_.c_str());
+ return false;
+ }
+
+ io::FileOutputStream out(fd);
+
+ {
+ io::CodedOutputStream coded_out(&out);
+ // Determinism is useful here because build outputs are sometimes checked
+ // into version control.
+ coded_out.SetSerializationDeterministic(true);
+ if (!file_set.SerializeToCodedStream(&coded_out)) {
+ std::cerr << descriptor_set_out_name_ << ": " << strerror(out.GetErrno())
+ << std::endl;
+ out.Close();
+ return false;
+ }
+ }
+
+ if (!out.Close()) {
+ std::cerr << descriptor_set_out_name_ << ": " << strerror(out.GetErrno())
+ << std::endl;
+ return false;
+ }
+
+ return true;
+}
+
+void CommandLineInterface::GetTransitiveDependencies(
+ const FileDescriptor* file, bool include_json_name,
+ bool include_source_code_info,
+ std::set<const FileDescriptor*>* already_seen,
+ RepeatedPtrField<FileDescriptorProto>* output) {
+ if (!already_seen->insert(file).second) {
+ // Already saw this file. Skip.
+ return;
+ }
+
+ // Add all dependencies.
+ for (int i = 0; i < file->dependency_count(); i++) {
+ GetTransitiveDependencies(file->dependency(i), include_json_name,
+ include_source_code_info, already_seen, output);
+ }
+
+ // Add this file.
+ FileDescriptorProto* new_descriptor = output->Add();
+ file->CopyTo(new_descriptor);
+ if (include_json_name) {
+ file->CopyJsonNameTo(new_descriptor);
+ }
+ if (include_source_code_info) {
+ file->CopySourceCodeInfoTo(new_descriptor);
+ }
+}
+
+namespace {
+
+// Utility function for PrintFreeFieldNumbers.
+// Stores occupied ranges into the ranges parameter, and next level of sub
+// message types into the nested_messages parameter. The FieldRange is left
+// inclusive, right exclusive. i.e. [a, b).
+//
+// Nested Messages:
+// Note that it only stores the nested message type, iff the nested type is
+// either a direct child of the given descriptor, or the nested type is a
+// descendant of the given descriptor and all the nodes between the
+// nested type and the given descriptor are group types. e.g.
+//
+// message Foo {
+// message Bar {
+// message NestedBar {}
+// }
+// group Baz = 1 {
+// group NestedBazGroup = 2 {
+// message Quz {
+// message NestedQuz {}
+// }
+// }
+// message NestedBaz {}
+// }
+// }
+//
+// In this case, Bar, Quz and NestedBaz will be added into the nested types.
+// Since free field numbers of group types will not be printed, this makes sure
+// the nested message types in groups will not be dropped. The nested_messages
+// parameter will contain the direct children (when groups are ignored in the
+// tree) of the given descriptor for the caller to traverse. The declaration
+// order of the nested messages is also preserved.
+typedef std::pair<int, int> FieldRange;
+void GatherOccupiedFieldRanges(
+ const Descriptor* descriptor, std::set<FieldRange>* ranges,
+ std::vector<const Descriptor*>* nested_messages) {
+ std::set<const Descriptor*> groups;
+ for (int i = 0; i < descriptor->field_count(); ++i) {
+ const FieldDescriptor* fd = descriptor->field(i);
+ ranges->insert(FieldRange(fd->number(), fd->number() + 1));
+ if (fd->type() == FieldDescriptor::TYPE_GROUP) {
+ groups.insert(fd->message_type());
+ }
+ }
+ for (int i = 0; i < descriptor->extension_range_count(); ++i) {
+ ranges->insert(FieldRange(descriptor->extension_range(i)->start,
+ descriptor->extension_range(i)->end));
+ }
+ for (int i = 0; i < descriptor->reserved_range_count(); ++i) {
+ ranges->insert(FieldRange(descriptor->reserved_range(i)->start,
+ descriptor->reserved_range(i)->end));
+ }
+ // Handle the nested messages/groups in declaration order to make it
+ // post-order strict.
+ for (int i = 0; i < descriptor->nested_type_count(); ++i) {
+ const Descriptor* nested_desc = descriptor->nested_type(i);
+ if (groups.find(nested_desc) != groups.end()) {
+ GatherOccupiedFieldRanges(nested_desc, ranges, nested_messages);
+ } else {
+ nested_messages->push_back(nested_desc);
+ }
+ }
+}
+
+// Utility function for PrintFreeFieldNumbers.
+// Actually prints the formatted free field numbers for given message name and
+// occupied ranges.
+void FormatFreeFieldNumbers(const std::string& name,
+ const std::set<FieldRange>& ranges) {
+ std::string output;
+ StringAppendF(&output, "%-35s free:", name.c_str());
+ int next_free_number = 1;
+ for (std::set<FieldRange>::const_iterator i = ranges.begin();
+ i != ranges.end(); ++i) {
+ // This happens when groups re-use parent field numbers, in which
+ // case we skip the FieldRange entirely.
+ if (next_free_number >= i->second) continue;
+
+ if (next_free_number < i->first) {
+ if (next_free_number + 1 == i->first) {
+ // Singleton
+ StringAppendF(&output, " %d", next_free_number);
+ } else {
+ // Range
+ StringAppendF(&output, " %d-%d", next_free_number, i->first - 1);
+ }
+ }
+ next_free_number = i->second;
+ }
+ if (next_free_number <= FieldDescriptor::kMaxNumber) {
+ StringAppendF(&output, " %d-INF", next_free_number);
+ }
+ std::cout << output << std::endl;
+}
+
+} // namespace
+
+void CommandLineInterface::PrintFreeFieldNumbers(const Descriptor* descriptor) {
+ std::set<FieldRange> ranges;
+ std::vector<const Descriptor*> nested_messages;
+ GatherOccupiedFieldRanges(descriptor, &ranges, &nested_messages);
+
+ for (int i = 0; i < nested_messages.size(); ++i) {
+ PrintFreeFieldNumbers(nested_messages[i]);
+ }
+ FormatFreeFieldNumbers(descriptor->full_name(), ranges);
+}
+
+
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/command_line_interface.h b/NorthstarDedicatedTest/include/protobuf/compiler/command_line_interface.h
new file mode 100644
index 00000000..4d37bd6d
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/command_line_interface.h
@@ -0,0 +1,462 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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.
+//
+// Implements the Protocol Compiler front-end such that it may be reused by
+// custom compilers written to support other languages.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_COMMAND_LINE_INTERFACE_H__
+#define GOOGLE_PROTOBUF_COMPILER_COMMAND_LINE_INTERFACE_H__
+
+#include <cstdint>
+#include <map>
+#include <memory>
+#include <set>
+#include <string>
+#include <unordered_map>
+#include <unordered_set>
+#include <utility>
+#include <vector>
+
+#include <stubs/common.h>
+#include <port_def.inc>
+
+namespace google {
+namespace protobuf {
+
+class Descriptor; // descriptor.h
+class DescriptorDatabase; // descriptor_database.h
+class DescriptorPool; // descriptor.h
+class FileDescriptor; // descriptor.h
+class FileDescriptorSet; // descriptor.h
+class FileDescriptorProto; // descriptor.pb.h
+template <typename T>
+class RepeatedPtrField; // repeated_field.h
+class SimpleDescriptorDatabase; // descriptor_database.h
+
+namespace compiler {
+
+class CodeGenerator; // code_generator.h
+class GeneratorContext; // code_generator.h
+class DiskSourceTree; // importer.h
+
+// This class implements the command-line interface to the protocol compiler.
+// It is designed to make it very easy to create a custom protocol compiler
+// supporting the languages of your choice. For example, if you wanted to
+// create a custom protocol compiler binary which includes both the regular
+// C++ support plus support for your own custom output "Foo", you would
+// write a class "FooGenerator" which implements the CodeGenerator interface,
+// then write a main() procedure like this:
+//
+// int main(int argc, char* argv[]) {
+// google::protobuf::compiler::CommandLineInterface cli;
+//
+// // Support generation of C++ source and headers.
+// google::protobuf::compiler::cpp::CppGenerator cpp_generator;
+// cli.RegisterGenerator("--cpp_out", &cpp_generator,
+// "Generate C++ source and header.");
+//
+// // Support generation of Foo code.
+// FooGenerator foo_generator;
+// cli.RegisterGenerator("--foo_out", &foo_generator,
+// "Generate Foo file.");
+//
+// return cli.Run(argc, argv);
+// }
+//
+// The compiler is invoked with syntax like:
+// protoc --cpp_out=outdir --foo_out=outdir --proto_path=src src/foo.proto
+//
+// The .proto file to compile can be specified on the command line using either
+// its physical file path, or a virtual path relative to a directory specified
+// in --proto_path. For example, for src/foo.proto, the following two protoc
+// invocations work the same way:
+// 1. protoc --proto_path=src src/foo.proto (physical file path)
+// 2. protoc --proto_path=src foo.proto (virtual path relative to src)
+//
+// If a file path can be interpreted both as a physical file path and as a
+// relative virtual path, the physical file path takes precedence.
+//
+// For a full description of the command-line syntax, invoke it with --help.
+class PROTOC_EXPORT CommandLineInterface {
+ public:
+ static const char* const kPathSeparator;
+
+ CommandLineInterface();
+ ~CommandLineInterface();
+
+ // Register a code generator for a language.
+ //
+ // Parameters:
+ // * flag_name: The command-line flag used to specify an output file of
+ // this type. The name must start with a '-'. If the name is longer
+ // than one letter, it must start with two '-'s.
+ // * generator: The CodeGenerator which will be called to generate files
+ // of this type.
+ // * help_text: Text describing this flag in the --help output.
+ //
+ // Some generators accept extra parameters. You can specify this parameter
+ // on the command-line by placing it before the output directory, separated
+ // by a colon:
+ // protoc --foo_out=enable_bar:outdir
+ // The text before the colon is passed to CodeGenerator::Generate() as the
+ // "parameter".
+ void RegisterGenerator(const std::string& flag_name, CodeGenerator* generator,
+ const std::string& help_text);
+
+ // Register a code generator for a language.
+ // Besides flag_name you can specify another option_flag_name that could be
+ // used to pass extra parameters to the registered code generator.
+ // Suppose you have registered a generator by calling:
+ // command_line_interface.RegisterGenerator("--foo_out", "--foo_opt", ...)
+ // Then you could invoke the compiler with a command like:
+ // protoc --foo_out=enable_bar:outdir --foo_opt=enable_baz
+ // This will pass "enable_bar,enable_baz" as the parameter to the generator.
+ void RegisterGenerator(const std::string& flag_name,
+ const std::string& option_flag_name,
+ CodeGenerator* generator,
+ const std::string& help_text);
+
+ // Enables "plugins". In this mode, if a command-line flag ends with "_out"
+ // but does not match any registered generator, the compiler will attempt to
+ // find a "plugin" to implement the generator. Plugins are just executables.
+ // They should live somewhere in the PATH.
+ //
+ // The compiler determines the executable name to search for by concatenating
+ // exe_name_prefix with the unrecognized flag name, removing "_out". So, for
+ // example, if exe_name_prefix is "protoc-" and you pass the flag --foo_out,
+ // the compiler will try to run the program "protoc-gen-foo".
+ //
+ // The plugin program should implement the following usage:
+ // plugin [--out=OUTDIR] [--parameter=PARAMETER] PROTO_FILES < DESCRIPTORS
+ // --out indicates the output directory (as passed to the --foo_out
+ // parameter); if omitted, the current directory should be used. --parameter
+ // gives the generator parameter, if any was provided (see below). The
+ // PROTO_FILES list the .proto files which were given on the compiler
+ // command-line; these are the files for which the plugin is expected to
+ // generate output code. Finally, DESCRIPTORS is an encoded FileDescriptorSet
+ // (as defined in descriptor.proto). This is piped to the plugin's stdin.
+ // The set will include descriptors for all the files listed in PROTO_FILES as
+ // well as all files that they import. The plugin MUST NOT attempt to read
+ // the PROTO_FILES directly -- it must use the FileDescriptorSet.
+ //
+ // The plugin should generate whatever files are necessary, as code generators
+ // normally do. It should write the names of all files it generates to
+ // stdout. The names should be relative to the output directory, NOT absolute
+ // names or relative to the current directory. If any errors occur, error
+ // messages should be written to stderr. If an error is fatal, the plugin
+ // should exit with a non-zero exit code.
+ //
+ // Plugins can have generator parameters similar to normal built-in
+ // generators. Extra generator parameters can be passed in via a matching
+ // "_opt" parameter. For example:
+ // protoc --plug_out=enable_bar:outdir --plug_opt=enable_baz
+ // This will pass "enable_bar,enable_baz" as the parameter to the plugin.
+ //
+ void AllowPlugins(const std::string& exe_name_prefix);
+
+ // Run the Protocol Compiler with the given command-line parameters.
+ // Returns the error code which should be returned by main().
+ //
+ // It may not be safe to call Run() in a multi-threaded environment because
+ // it calls strerror(). I'm not sure why you'd want to do this anyway.
+ int Run(int argc, const char* const argv[]);
+
+ // DEPRECATED. Calling this method has no effect. Protocol compiler now
+ // always try to find the .proto file relative to the current directory
+ // first and if the file is not found, it will then treat the input path
+ // as a virtual path.
+ void SetInputsAreProtoPathRelative(bool /* enable */) {}
+
+ // Provides some text which will be printed when the --version flag is
+ // used. The version of libprotoc will also be printed on the next line
+ // after this text.
+ void SetVersionInfo(const std::string& text) { version_info_ = text; }
+
+
+ private:
+ // -----------------------------------------------------------------
+
+ class ErrorPrinter;
+ class GeneratorContextImpl;
+ class MemoryOutputStream;
+ typedef std::unordered_map<std::string, std::unique_ptr<GeneratorContextImpl>>
+ GeneratorContextMap;
+
+ // Clear state from previous Run().
+ void Clear();
+
+ // Remaps the proto file so that it is relative to one of the directories
+ // in proto_path_. Returns false if an error occurred.
+ bool MakeProtoProtoPathRelative(DiskSourceTree* source_tree,
+ std::string* proto,
+ DescriptorDatabase* fallback_database);
+
+ // Remaps each file in input_files_ so that it is relative to one of the
+ // directories in proto_path_. Returns false if an error occurred.
+ bool MakeInputsBeProtoPathRelative(DiskSourceTree* source_tree,
+ DescriptorDatabase* fallback_database);
+
+ // Fails if these files use proto3 optional and the code generator doesn't
+ // support it. This is a permanent check.
+ bool EnforceProto3OptionalSupport(
+ const std::string& codegen_name, uint64_t supported_features,
+ const std::vector<const FileDescriptor*>& parsed_files) const;
+
+
+ // Return status for ParseArguments() and InterpretArgument().
+ enum ParseArgumentStatus {
+ PARSE_ARGUMENT_DONE_AND_CONTINUE,
+ PARSE_ARGUMENT_DONE_AND_EXIT,
+ PARSE_ARGUMENT_FAIL
+ };
+
+ // Parse all command-line arguments.
+ ParseArgumentStatus ParseArguments(int argc, const char* const argv[]);
+
+ // Read an argument file and append the file's content to the list of
+ // arguments. Return false if the file cannot be read.
+ bool ExpandArgumentFile(const std::string& file,
+ std::vector<std::string>* arguments);
+
+ // Parses a command-line argument into a name/value pair. Returns
+ // true if the next argument in the argv should be used as the value,
+ // false otherwise.
+ //
+ // Examples:
+ // "-Isrc/protos" ->
+ // name = "-I", value = "src/protos"
+ // "--cpp_out=src/foo.pb2.cc" ->
+ // name = "--cpp_out", value = "src/foo.pb2.cc"
+ // "foo.proto" ->
+ // name = "", value = "foo.proto"
+ bool ParseArgument(const char* arg, std::string* name, std::string* value);
+
+ // Interprets arguments parsed with ParseArgument.
+ ParseArgumentStatus InterpretArgument(const std::string& name,
+ const std::string& value);
+
+ // Print the --help text to stderr.
+ void PrintHelpText();
+
+ // Loads proto_path_ into the provided source_tree.
+ bool InitializeDiskSourceTree(DiskSourceTree* source_tree,
+ DescriptorDatabase* fallback_database);
+
+ // Verify that all the input files exist in the given database.
+ bool VerifyInputFilesInDescriptors(DescriptorDatabase* fallback_database);
+
+ // Parses input_files_ into parsed_files
+ bool ParseInputFiles(DescriptorPool* descriptor_pool,
+ DiskSourceTree* source_tree,
+ std::vector<const FileDescriptor*>* parsed_files);
+
+ // Generate the given output file from the given input.
+ struct OutputDirective; // see below
+ bool GenerateOutput(const std::vector<const FileDescriptor*>& parsed_files,
+ const OutputDirective& output_directive,
+ GeneratorContext* generator_context);
+ bool GeneratePluginOutput(
+ const std::vector<const FileDescriptor*>& parsed_files,
+ const std::string& plugin_name, const std::string& parameter,
+ GeneratorContext* generator_context, std::string* error);
+
+ // Implements --encode and --decode.
+ bool EncodeOrDecode(const DescriptorPool* pool);
+
+ // Implements the --descriptor_set_out option.
+ bool WriteDescriptorSet(
+ const std::vector<const FileDescriptor*>& parsed_files);
+
+ // Implements the --dependency_out option
+ bool GenerateDependencyManifestFile(
+ const std::vector<const FileDescriptor*>& parsed_files,
+ const GeneratorContextMap& output_directories,
+ DiskSourceTree* source_tree);
+
+ // Get all transitive dependencies of the given file (including the file
+ // itself), adding them to the given list of FileDescriptorProtos. The
+ // protos will be ordered such that every file is listed before any file that
+ // depends on it, so that you can call DescriptorPool::BuildFile() on them
+ // in order. Any files in *already_seen will not be added, and each file
+ // added will be inserted into *already_seen. If include_source_code_info is
+ // true then include the source code information in the FileDescriptorProtos.
+ // If include_json_name is true, populate the json_name field of
+ // FieldDescriptorProto for all fields.
+ static void GetTransitiveDependencies(
+ const FileDescriptor* file, bool include_json_name,
+ bool include_source_code_info,
+ std::set<const FileDescriptor*>* already_seen,
+ RepeatedPtrField<FileDescriptorProto>* output);
+
+ // Implements the --print_free_field_numbers. This function prints free field
+ // numbers into stdout for the message and it's nested message types in
+ // post-order, i.e. nested types first. Printed range are left-right
+ // inclusive, i.e. [a, b].
+ //
+ // Groups:
+ // For historical reasons, groups are considered to share the same
+ // field number space with the parent message, thus it will not print free
+ // field numbers for groups. The field numbers used in the groups are
+ // excluded in the free field numbers of the parent message.
+ //
+ // Extension Ranges:
+ // Extension ranges are considered ocuppied field numbers and they will not be
+ // listed as free numbers in the output.
+ void PrintFreeFieldNumbers(const Descriptor* descriptor);
+
+ // -----------------------------------------------------------------
+
+ // The name of the executable as invoked (i.e. argv[0]).
+ std::string executable_name_;
+
+ // Version info set with SetVersionInfo().
+ std::string version_info_;
+
+ // Registered generators.
+ struct GeneratorInfo {
+ std::string flag_name;
+ std::string option_flag_name;
+ CodeGenerator* generator;
+ std::string help_text;
+ };
+ typedef std::map<std::string, GeneratorInfo> GeneratorMap;
+ GeneratorMap generators_by_flag_name_;
+ GeneratorMap generators_by_option_name_;
+ // A map from generator names to the parameters specified using the option
+ // flag. For example, if the user invokes the compiler with:
+ // protoc --foo_out=outputdir --foo_opt=enable_bar ...
+ // Then there will be an entry ("--foo_out", "enable_bar") in this map.
+ std::map<std::string, std::string> generator_parameters_;
+ // Similar to generator_parameters_, but stores the parameters for plugins.
+ std::map<std::string, std::string> plugin_parameters_;
+
+ // See AllowPlugins(). If this is empty, plugins aren't allowed.
+ std::string plugin_prefix_;
+
+ // Maps specific plugin names to files. When executing a plugin, this map
+ // is searched first to find the plugin executable. If not found here, the
+ // PATH (or other OS-specific search strategy) is searched.
+ std::map<std::string, std::string> plugins_;
+
+ // Stuff parsed from command line.
+ enum Mode {
+ MODE_COMPILE, // Normal mode: parse .proto files and compile them.
+ MODE_ENCODE, // --encode: read text from stdin, write binary to stdout.
+ MODE_DECODE, // --decode: read binary from stdin, write text to stdout.
+ MODE_PRINT, // Print mode: print info of the given .proto files and exit.
+ };
+
+ Mode mode_ = MODE_COMPILE;
+
+ enum PrintMode {
+ PRINT_NONE, // Not in MODE_PRINT
+ PRINT_FREE_FIELDS, // --print_free_fields
+ };
+
+ PrintMode print_mode_ = PRINT_NONE;
+
+ enum ErrorFormat {
+ ERROR_FORMAT_GCC, // GCC error output format (default).
+ ERROR_FORMAT_MSVS // Visual Studio output (--error_format=msvs).
+ };
+
+ ErrorFormat error_format_ = ERROR_FORMAT_GCC;
+
+ // True if we should treat warnings as errors that fail the compilation.
+ bool fatal_warnings_ = false;
+
+ std::vector<std::pair<std::string, std::string> >
+ proto_path_; // Search path for proto files.
+ std::vector<std::string> input_files_; // Names of the input proto files.
+
+ // Names of proto files which are allowed to be imported. Used by build
+ // systems to enforce depend-on-what-you-import.
+ std::set<std::string> direct_dependencies_;
+ bool direct_dependencies_explicitly_set_ = false;
+
+ // If there's a violation of depend-on-what-you-import, this string will be
+ // presented to the user. "%s" will be replaced with the violating import.
+ std::string direct_dependencies_violation_msg_;
+
+ // output_directives_ lists all the files we are supposed to output and what
+ // generator to use for each.
+ struct OutputDirective {
+ std::string name; // E.g. "--foo_out"
+ CodeGenerator* generator; // NULL for plugins
+ std::string parameter;
+ std::string output_location;
+ };
+ std::vector<OutputDirective> output_directives_;
+
+ // When using --encode or --decode, this names the type we are encoding or
+ // decoding. (Empty string indicates --decode_raw.)
+ std::string codec_type_;
+
+ // If --descriptor_set_in was given, these are filenames containing
+ // parsed FileDescriptorSets to be used for loading protos. Otherwise, empty.
+ std::vector<std::string> descriptor_set_in_names_;
+
+ // If --descriptor_set_out was given, this is the filename to which the
+ // FileDescriptorSet should be written. Otherwise, empty.
+ std::string descriptor_set_out_name_;
+
+ // If --dependency_out was given, this is the path to the file where the
+ // dependency file will be written. Otherwise, empty.
+ std::string dependency_out_name_;
+
+ // True if --include_imports was given, meaning that we should
+ // write all transitive dependencies to the DescriptorSet. Otherwise, only
+ // the .proto files listed on the command-line are added.
+ bool imports_in_descriptor_set_;
+
+ // True if --include_source_info was given, meaning that we should not strip
+ // SourceCodeInfo from the DescriptorSet.
+ bool source_info_in_descriptor_set_ = false;
+
+ // Was the --disallow_services flag used?
+ bool disallow_services_ = false;
+
+ // When using --encode, this will be passed to SetSerializationDeterministic.
+ bool deterministic_output_ = false;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CommandLineInterface);
+};
+
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#include <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_COMPILER_COMMAND_LINE_INTERFACE_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/command_line_interface_unittest.cc b/NorthstarDedicatedTest/include/protobuf/compiler/command_line_interface_unittest.cc
new file mode 100644
index 00000000..78c13f61
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/command_line_interface_unittest.cc
@@ -0,0 +1,2760 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 <fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include <cstdint>
+
+#ifndef _MSC_VER
+#include <unistd.h>
+#endif
+#include <memory>
+#include <string>
+#include <vector>
+
+#include <stubs/stringprintf.h>
+#include <testing/file.h>
+#include <testing/file.h>
+#include <testing/file.h>
+#include <any.pb.h>
+#include <compiler/mock_code_generator.h>
+#include <compiler/subprocess.h>
+#include <compiler/code_generator.h>
+#include <compiler/command_line_interface.h>
+#include <test_util2.h>
+#include <unittest.pb.h>
+#include <unittest_custom_options.pb.h>
+#include <io/printer.h>
+#include <io/zero_copy_stream.h>
+#include <descriptor.pb.h>
+#include <descriptor.h>
+#include <testing/googletest.h>
+#include <gtest/gtest.h>
+#include <stubs/strutil.h>
+#include <stubs/substitute.h>
+#include <io/io_win32.h>
+
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+
+#if defined(_WIN32)
+// 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::dup;
+using google::protobuf::io::win32::dup2;
+using google::protobuf::io::win32::open;
+using google::protobuf::io::win32::write;
+#endif
+
+// Disable the whole test when we use tcmalloc for "draconian" heap checks, in
+// which case tcmalloc will print warnings that fail the plugin tests.
+#if !GOOGLE_PROTOBUF_HEAP_CHECK_DRACONIAN
+
+
+namespace {
+
+bool FileExists(const std::string& path) {
+ return File::Exists(path);
+}
+
+class CommandLineInterfaceTest : public testing::Test {
+ protected:
+ virtual void SetUp();
+ virtual void TearDown();
+
+ // Runs the CommandLineInterface with the given command line. The
+ // command is automatically split on spaces, and the string "$tmpdir"
+ // is replaced with TestTempDir().
+ void Run(const std::string& command);
+ void RunWithArgs(std::vector<std::string> args);
+
+ // -----------------------------------------------------------------
+ // Methods to set up the test (called before Run()).
+
+ class NullCodeGenerator;
+
+ // Normally plugins are allowed for all tests. Call this to explicitly
+ // disable them.
+ void DisallowPlugins() { disallow_plugins_ = true; }
+
+ // Create a temp file within temp_directory_ with the given name.
+ // The containing directory is also created if necessary.
+ void CreateTempFile(const std::string& name, const std::string& contents);
+
+ // Create a subdirectory within temp_directory_.
+ void CreateTempDir(const std::string& name);
+
+#ifdef PROTOBUF_OPENSOURCE
+ // Change working directory to temp directory.
+ void SwitchToTempDirectory() {
+ File::ChangeWorkingDirectory(temp_directory_);
+ }
+#else // !PROTOBUF_OPENSOURCE
+ // TODO(teboring): Figure out how to change and get working directory in
+ // google3.
+#endif // !PROTOBUF_OPENSOURCE
+
+ // -----------------------------------------------------------------
+ // Methods to check the test results (called after Run()).
+
+ // Checks that no text was written to stderr during Run(), and Run()
+ // returned 0.
+ void ExpectNoErrors();
+
+ // Checks that Run() returned non-zero and the stderr output is exactly
+ // the text given. expected_test may contain references to "$tmpdir",
+ // which will be replaced by the temporary directory path.
+ void ExpectErrorText(const std::string& expected_text);
+
+ // Checks that Run() returned non-zero and the stderr contains the given
+ // substring.
+ void ExpectErrorSubstring(const std::string& expected_substring);
+
+ // Checks that Run() returned zero and the stderr contains the given
+ // substring.
+ void ExpectWarningSubstring(const std::string& expected_substring);
+
+ // Checks that the captured stdout is the same as the expected_text.
+ void ExpectCapturedStdout(const std::string& expected_text);
+
+ // Checks that Run() returned zero and the stdout contains the given
+ // substring.
+ void ExpectCapturedStdoutSubstringWithZeroReturnCode(
+ const std::string& expected_substring);
+
+ // Checks that Run() returned zero and the stderr contains the given
+ // substring.
+ void ExpectCapturedStderrSubstringWithZeroReturnCode(
+ const std::string& expected_substring);
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ // Returns true if ExpectErrorSubstring(expected_substring) would pass, but
+ // does not fail otherwise.
+ bool HasAlternateErrorSubstring(const std::string& expected_substring);
+#endif // _WIN32 && !__CYGWIN__
+
+ // Checks that MockCodeGenerator::Generate() was called in the given
+ // context (or the generator in test_plugin.cc, which produces the same
+ // output). That is, this tests if the generator with the given name
+ // was called with the given parameter and proto file and produced the
+ // given output file. This is checked by reading the output file and
+ // checking that it contains the content that MockCodeGenerator would
+ // generate given these inputs. message_name is the name of the first
+ // message that appeared in the proto file; this is just to make extra
+ // sure that the correct file was parsed.
+ void ExpectGenerated(const std::string& generator_name,
+ const std::string& parameter,
+ const std::string& proto_name,
+ const std::string& message_name);
+ void ExpectGenerated(const std::string& generator_name,
+ const std::string& parameter,
+ const std::string& proto_name,
+ const std::string& message_name,
+ const std::string& output_directory);
+ void ExpectGeneratedWithMultipleInputs(const std::string& generator_name,
+ const std::string& all_proto_names,
+ const std::string& proto_name,
+ const std::string& message_name);
+ void ExpectGeneratedWithInsertions(const std::string& generator_name,
+ const std::string& parameter,
+ const std::string& insertions,
+ const std::string& proto_name,
+ const std::string& message_name);
+ void CheckGeneratedAnnotations(const std::string& name,
+ const std::string& file);
+
+#if defined(_WIN32)
+ void ExpectNullCodeGeneratorCalled(const std::string& parameter);
+#endif // _WIN32
+
+
+ void ReadDescriptorSet(const std::string& filename,
+ FileDescriptorSet* descriptor_set);
+
+ void WriteDescriptorSet(const std::string& filename,
+ const FileDescriptorSet* descriptor_set);
+
+ void ExpectFileContent(const std::string& filename,
+ const std::string& content);
+
+ // The default code generators support all features. Use this to create a
+ // code generator that omits the given feature(s).
+ void CreateGeneratorWithMissingFeatures(const std::string& name,
+ const std::string& description,
+ uint64_t features) {
+ MockCodeGenerator* generator = new MockCodeGenerator(name);
+ generator->SuppressFeatures(features);
+ mock_generators_to_delete_.push_back(generator);
+ cli_.RegisterGenerator(name, generator, description);
+ }
+
+ private:
+ // The object we are testing.
+ CommandLineInterface cli_;
+
+ // Was DisallowPlugins() called?
+ bool disallow_plugins_;
+
+ // We create a directory within TestTempDir() in order to add extra
+ // protection against accidentally deleting user files (since we recursively
+ // delete this directory during the test). This is the full path of that
+ // directory.
+ std::string temp_directory_;
+
+ // The result of Run().
+ int return_code_;
+
+ // The captured stderr output.
+ std::string error_text_;
+
+ // The captured stdout.
+ std::string captured_stdout_;
+
+ // Pointers which need to be deleted later.
+ std::vector<CodeGenerator*> mock_generators_to_delete_;
+
+ NullCodeGenerator* null_generator_;
+};
+
+class CommandLineInterfaceTest::NullCodeGenerator : public CodeGenerator {
+ public:
+ NullCodeGenerator() : called_(false) {}
+ ~NullCodeGenerator() {}
+
+ mutable bool called_;
+ mutable std::string parameter_;
+
+ // implements CodeGenerator ----------------------------------------
+ bool Generate(const FileDescriptor* file, const std::string& parameter,
+ GeneratorContext* context, std::string* error) const {
+ called_ = true;
+ parameter_ = parameter;
+ return true;
+ }
+};
+
+// ===================================================================
+
+void CommandLineInterfaceTest::SetUp() {
+ temp_directory_ = TestTempDir() + "/proto2_cli_test_temp";
+
+ // If the temp directory already exists, it must be left over from a
+ // previous run. Delete it.
+ if (FileExists(temp_directory_)) {
+ File::DeleteRecursively(temp_directory_, NULL, NULL);
+ }
+
+ // Create the temp directory.
+ GOOGLE_CHECK_OK(File::CreateDir(temp_directory_, 0777));
+
+ // Register generators.
+ CodeGenerator* generator = new MockCodeGenerator("test_generator");
+ mock_generators_to_delete_.push_back(generator);
+ cli_.RegisterGenerator("--test_out", "--test_opt", generator, "Test output.");
+ cli_.RegisterGenerator("-t", generator, "Test output.");
+
+ generator = new MockCodeGenerator("alt_generator");
+ mock_generators_to_delete_.push_back(generator);
+ cli_.RegisterGenerator("--alt_out", generator, "Alt output.");
+
+ generator = null_generator_ = new NullCodeGenerator();
+ mock_generators_to_delete_.push_back(generator);
+ cli_.RegisterGenerator("--null_out", generator, "Null output.");
+
+
+ disallow_plugins_ = false;
+}
+
+void CommandLineInterfaceTest::TearDown() {
+ // Delete the temp directory.
+ if (FileExists(temp_directory_)) {
+ File::DeleteRecursively(temp_directory_, NULL, NULL);
+ }
+
+ // Delete all the MockCodeGenerators.
+ for (int i = 0; i < mock_generators_to_delete_.size(); i++) {
+ delete mock_generators_to_delete_[i];
+ }
+ mock_generators_to_delete_.clear();
+}
+
+void CommandLineInterfaceTest::Run(const std::string& command) {
+ RunWithArgs(Split(command, " ", true));
+}
+
+void CommandLineInterfaceTest::RunWithArgs(std::vector<std::string> args) {
+ if (!disallow_plugins_) {
+ cli_.AllowPlugins("prefix-");
+ std::string plugin_path;
+#ifdef GOOGLE_PROTOBUF_TEST_PLUGIN_PATH
+ plugin_path = GOOGLE_PROTOBUF_TEST_PLUGIN_PATH;
+#else
+ const char* possible_paths[] = {
+ // When building with shared libraries, libtool hides the real
+ // executable
+ // in .libs and puts a fake wrapper in the current directory.
+ // Unfortunately, due to an apparent bug on Cygwin/MinGW, if one program
+ // wrapped in this way (e.g. protobuf-tests.exe) tries to execute
+ // another
+ // program wrapped in this way (e.g. test_plugin.exe), the latter fails
+ // with error code 127 and no explanation message. Presumably the
+ // problem
+ // is that the wrapper for protobuf-tests.exe set some environment
+ // variables that confuse the wrapper for test_plugin.exe. Luckily, it
+ // turns out that if we simply invoke the wrapped test_plugin.exe
+ // directly, it works -- I guess the environment variables set by the
+ // protobuf-tests.exe wrapper happen to be correct for it too. So we do
+ // that.
+ ".libs/test_plugin.exe", // Win32 w/autotool (Cygwin / MinGW)
+ "test_plugin.exe", // Other Win32 (MSVC)
+ "test_plugin", // Unix
+ };
+ for (int i = 0; i < GOOGLE_ARRAYSIZE(possible_paths); i++) {
+ if (access(possible_paths[i], F_OK) == 0) {
+ plugin_path = possible_paths[i];
+ break;
+ }
+ }
+#endif
+
+ if (plugin_path.empty()) {
+ GOOGLE_LOG(ERROR)
+ << "Plugin executable not found. Plugin tests are likely to fail.";
+ } else {
+ args.push_back("--plugin=prefix-gen-plug=" + plugin_path);
+ }
+ }
+
+ std::unique_ptr<const char*[]> argv(new const char*[args.size()]);
+
+ for (int i = 0; i < args.size(); i++) {
+ args[i] = StringReplace(args[i], "$tmpdir", temp_directory_, true);
+ argv[i] = args[i].c_str();
+ }
+
+ // TODO(jieluo): Cygwin doesn't work well if we try to capture stderr and
+ // stdout at the same time. Need to figure out why and add this capture back
+ // for Cygwin.
+#if !defined(__CYGWIN__)
+ CaptureTestStdout();
+#endif
+ CaptureTestStderr();
+
+ return_code_ = cli_.Run(args.size(), argv.get());
+
+ error_text_ = GetCapturedTestStderr();
+#if !defined(__CYGWIN__)
+ captured_stdout_ = GetCapturedTestStdout();
+#endif
+}
+
+// -------------------------------------------------------------------
+
+void CommandLineInterfaceTest::CreateTempFile(const std::string& name,
+ const std::string& contents) {
+ // Create parent directory, if necessary.
+ std::string::size_type slash_pos = name.find_last_of('/');
+ if (slash_pos != std::string::npos) {
+ std::string dir = name.substr(0, slash_pos);
+ if (!FileExists(temp_directory_ + "/" + dir)) {
+ GOOGLE_CHECK_OK(File::RecursivelyCreateDir(temp_directory_ + "/" + dir,
+ 0777));
+ }
+ }
+
+ // Write file.
+ std::string full_name = temp_directory_ + "/" + name;
+ GOOGLE_CHECK_OK(File::SetContents(
+ full_name, StringReplace(contents, "$tmpdir", temp_directory_, true),
+ true));
+}
+
+void CommandLineInterfaceTest::CreateTempDir(const std::string& name) {
+ GOOGLE_CHECK_OK(File::RecursivelyCreateDir(temp_directory_ + "/" + name,
+ 0777));
+}
+
+// -------------------------------------------------------------------
+
+void CommandLineInterfaceTest::ExpectNoErrors() {
+ EXPECT_EQ(0, return_code_);
+ EXPECT_EQ("", error_text_);
+}
+
+void CommandLineInterfaceTest::ExpectErrorText(
+ const std::string& expected_text) {
+ EXPECT_NE(0, return_code_);
+ EXPECT_EQ(StringReplace(expected_text, "$tmpdir", temp_directory_, true),
+ error_text_);
+}
+
+void CommandLineInterfaceTest::ExpectErrorSubstring(
+ const std::string& expected_substring) {
+ EXPECT_NE(0, return_code_);
+ EXPECT_PRED_FORMAT2(testing::IsSubstring, expected_substring, error_text_);
+}
+
+void CommandLineInterfaceTest::ExpectWarningSubstring(
+ const std::string& expected_substring) {
+ EXPECT_PRED_FORMAT2(testing::IsSubstring, expected_substring, error_text_);
+ EXPECT_EQ(0, return_code_);
+}
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+bool CommandLineInterfaceTest::HasAlternateErrorSubstring(
+ const std::string& expected_substring) {
+ EXPECT_NE(0, return_code_);
+ return error_text_.find(expected_substring) != std::string::npos;
+}
+#endif // _WIN32 && !__CYGWIN__
+
+void CommandLineInterfaceTest::ExpectGenerated(
+ const std::string& generator_name, const std::string& parameter,
+ const std::string& proto_name, const std::string& message_name) {
+ MockCodeGenerator::ExpectGenerated(generator_name, parameter, "", proto_name,
+ message_name, proto_name, temp_directory_);
+}
+
+void CommandLineInterfaceTest::ExpectGenerated(
+ const std::string& generator_name, const std::string& parameter,
+ const std::string& proto_name, const std::string& message_name,
+ const std::string& output_directory) {
+ MockCodeGenerator::ExpectGenerated(generator_name, parameter, "", proto_name,
+ message_name, proto_name,
+ temp_directory_ + "/" + output_directory);
+}
+
+void CommandLineInterfaceTest::ExpectGeneratedWithMultipleInputs(
+ const std::string& generator_name, const std::string& all_proto_names,
+ const std::string& proto_name, const std::string& message_name) {
+ MockCodeGenerator::ExpectGenerated(generator_name, "", "", proto_name,
+ message_name, all_proto_names,
+ temp_directory_);
+}
+
+void CommandLineInterfaceTest::ExpectGeneratedWithInsertions(
+ const std::string& generator_name, const std::string& parameter,
+ const std::string& insertions, const std::string& proto_name,
+ const std::string& message_name) {
+ MockCodeGenerator::ExpectGenerated(generator_name, parameter, insertions,
+ proto_name, message_name, proto_name,
+ temp_directory_);
+}
+
+void CommandLineInterfaceTest::CheckGeneratedAnnotations(
+ const std::string& name, const std::string& file) {
+ MockCodeGenerator::CheckGeneratedAnnotations(name, file, temp_directory_);
+}
+
+#if defined(_WIN32)
+void CommandLineInterfaceTest::ExpectNullCodeGeneratorCalled(
+ const std::string& parameter) {
+ EXPECT_TRUE(null_generator_->called_);
+ EXPECT_EQ(parameter, null_generator_->parameter_);
+}
+#endif // _WIN32
+
+
+void CommandLineInterfaceTest::ReadDescriptorSet(
+ const std::string& filename, FileDescriptorSet* descriptor_set) {
+ std::string path = temp_directory_ + "/" + filename;
+ std::string file_contents;
+ GOOGLE_CHECK_OK(File::GetContents(path, &file_contents, true));
+
+ if (!descriptor_set->ParseFromString(file_contents)) {
+ FAIL() << "Could not parse file contents: " << path;
+ }
+}
+
+void CommandLineInterfaceTest::WriteDescriptorSet(
+ const std::string& filename, const FileDescriptorSet* descriptor_set) {
+ std::string binary_proto;
+ GOOGLE_CHECK(descriptor_set->SerializeToString(&binary_proto));
+ CreateTempFile(filename, binary_proto);
+}
+
+void CommandLineInterfaceTest::ExpectCapturedStdout(
+ const std::string& expected_text) {
+ EXPECT_EQ(expected_text, captured_stdout_);
+}
+
+void CommandLineInterfaceTest::ExpectCapturedStdoutSubstringWithZeroReturnCode(
+ const std::string& expected_substring) {
+ EXPECT_EQ(0, return_code_);
+ EXPECT_PRED_FORMAT2(testing::IsSubstring, expected_substring,
+ captured_stdout_);
+}
+
+void CommandLineInterfaceTest::ExpectCapturedStderrSubstringWithZeroReturnCode(
+ const std::string& expected_substring) {
+ EXPECT_EQ(0, return_code_);
+ EXPECT_PRED_FORMAT2(testing::IsSubstring, expected_substring, error_text_);
+}
+
+void CommandLineInterfaceTest::ExpectFileContent(const std::string& filename,
+ const std::string& content) {
+ std::string path = temp_directory_ + "/" + filename;
+ std::string file_contents;
+ GOOGLE_CHECK_OK(File::GetContents(path, &file_contents, true));
+
+ EXPECT_EQ(StringReplace(content, "$tmpdir", temp_directory_, true),
+ file_contents);
+}
+
+// ===================================================================
+
+TEST_F(CommandLineInterfaceTest, BasicOutput) {
+ // Test that the common case works.
+
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "message Foo {}\n");
+
+ Run("protocol_compiler --test_out=$tmpdir "
+ "--proto_path=$tmpdir foo.proto");
+
+ ExpectNoErrors();
+ ExpectGenerated("test_generator", "", "foo.proto", "Foo");
+}
+
+TEST_F(CommandLineInterfaceTest, BasicOutput_DescriptorSetIn) {
+ // Test that the common case works.
+ FileDescriptorSet file_descriptor_set;
+ FileDescriptorProto* file_descriptor_proto = file_descriptor_set.add_file();
+ file_descriptor_proto->set_name("foo.proto");
+ file_descriptor_proto->add_message_type()->set_name("Foo");
+
+ WriteDescriptorSet("foo.bin", &file_descriptor_set);
+
+ Run("protocol_compiler --test_out=$tmpdir "
+ "--descriptor_set_in=$tmpdir/foo.bin foo.proto");
+
+ ExpectNoErrors();
+ ExpectGenerated("test_generator", "", "foo.proto", "Foo");
+}
+
+TEST_F(CommandLineInterfaceTest, BasicPlugin) {
+ // Test that basic plugins work.
+
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "message Foo {}\n");
+
+ Run("protocol_compiler --plug_out=$tmpdir "
+ "--proto_path=$tmpdir foo.proto");
+
+ ExpectNoErrors();
+ ExpectGenerated("test_plugin", "", "foo.proto", "Foo");
+}
+
+TEST_F(CommandLineInterfaceTest, BasicPlugin_DescriptorSetIn) {
+ // Test that basic plugins work.
+
+ FileDescriptorSet file_descriptor_set;
+ FileDescriptorProto* file_descriptor_proto = file_descriptor_set.add_file();
+ file_descriptor_proto->set_name("foo.proto");
+ file_descriptor_proto->add_message_type()->set_name("Foo");
+
+ WriteDescriptorSet("foo.bin", &file_descriptor_set);
+
+ Run("protocol_compiler --plug_out=$tmpdir "
+ "--descriptor_set_in=$tmpdir/foo.bin foo.proto");
+
+ ExpectNoErrors();
+ ExpectGenerated("test_plugin", "", "foo.proto", "Foo");
+}
+
+TEST_F(CommandLineInterfaceTest, GeneratorAndPlugin) {
+ // Invoke a generator and a plugin at the same time.
+
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "message Foo {}\n");
+
+ Run("protocol_compiler --test_out=$tmpdir --plug_out=$tmpdir "
+ "--proto_path=$tmpdir foo.proto");
+
+ ExpectNoErrors();
+ ExpectGenerated("test_generator", "", "foo.proto", "Foo");
+ ExpectGenerated("test_plugin", "", "foo.proto", "Foo");
+}
+
+TEST_F(CommandLineInterfaceTest, GeneratorAndPlugin_DescriptorSetIn) {
+ // Invoke a generator and a plugin at the same time.
+
+ FileDescriptorSet file_descriptor_set;
+ FileDescriptorProto* file_descriptor_proto = file_descriptor_set.add_file();
+ file_descriptor_proto->set_name("foo.proto");
+ file_descriptor_proto->add_message_type()->set_name("Foo");
+
+ WriteDescriptorSet("foo.bin", &file_descriptor_set);
+
+ Run("protocol_compiler --test_out=$tmpdir --plug_out=$tmpdir "
+ "--descriptor_set_in=$tmpdir/foo.bin foo.proto");
+
+ ExpectNoErrors();
+ ExpectGenerated("test_generator", "", "foo.proto", "Foo");
+ ExpectGenerated("test_plugin", "", "foo.proto", "Foo");
+}
+
+TEST_F(CommandLineInterfaceTest, MultipleInputs) {
+ // Test parsing multiple input files.
+
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "message Foo {}\n");
+ CreateTempFile("bar.proto",
+ "syntax = \"proto2\";\n"
+ "message Bar {}\n");
+
+ Run("protocol_compiler --test_out=$tmpdir --plug_out=$tmpdir "
+ "--proto_path=$tmpdir foo.proto bar.proto");
+
+ ExpectNoErrors();
+ ExpectGeneratedWithMultipleInputs("test_generator", "foo.proto,bar.proto",
+ "foo.proto", "Foo");
+ ExpectGeneratedWithMultipleInputs("test_generator", "foo.proto,bar.proto",
+ "bar.proto", "Bar");
+ ExpectGeneratedWithMultipleInputs("test_plugin", "foo.proto,bar.proto",
+ "foo.proto", "Foo");
+ ExpectGeneratedWithMultipleInputs("test_plugin", "foo.proto,bar.proto",
+ "bar.proto", "Bar");
+}
+
+TEST_F(CommandLineInterfaceTest, MultipleInputs_DescriptorSetIn) {
+ // Test parsing multiple input files.
+ FileDescriptorSet file_descriptor_set;
+
+ FileDescriptorProto* file_descriptor_proto = file_descriptor_set.add_file();
+ file_descriptor_proto->set_name("foo.proto");
+ file_descriptor_proto->add_message_type()->set_name("Foo");
+
+ file_descriptor_proto = file_descriptor_set.add_file();
+ file_descriptor_proto->set_name("bar.proto");
+ file_descriptor_proto->add_message_type()->set_name("Bar");
+
+ WriteDescriptorSet("foo.bin", &file_descriptor_set);
+
+ Run("protocol_compiler --test_out=$tmpdir --plug_out=$tmpdir "
+ "--descriptor_set_in=$tmpdir/foo.bin foo.proto bar.proto");
+
+ ExpectNoErrors();
+ ExpectGeneratedWithMultipleInputs("test_generator", "foo.proto,bar.proto",
+ "foo.proto", "Foo");
+ ExpectGeneratedWithMultipleInputs("test_generator", "foo.proto,bar.proto",
+ "bar.proto", "Bar");
+ ExpectGeneratedWithMultipleInputs("test_plugin", "foo.proto,bar.proto",
+ "foo.proto", "Foo");
+ ExpectGeneratedWithMultipleInputs("test_plugin", "foo.proto,bar.proto",
+ "bar.proto", "Bar");
+}
+
+TEST_F(CommandLineInterfaceTest, MultipleInputs_UnusedImport_DescriptorSetIn) {
+ // Test unused import warning is not raised when descriptor_set_in is called
+ // and custom options are in unknown field instead of uninterpreted_options.
+ FileDescriptorSet file_descriptor_set;
+
+ const FileDescriptor* descriptor_file =
+ FileDescriptorProto::descriptor()->file();
+ descriptor_file->CopyTo(file_descriptor_set.add_file());
+
+ FileDescriptorProto& any_proto = *file_descriptor_set.add_file();
+ google::protobuf::Any::descriptor()->file()->CopyTo(&any_proto);
+
+ const FileDescriptor* custom_file =
+ protobuf_unittest::AggregateMessage::descriptor()->file();
+ FileDescriptorProto* file_descriptor_proto = file_descriptor_set.add_file();
+ custom_file->CopyTo(file_descriptor_proto);
+ file_descriptor_proto->set_name("custom_options.proto");
+ // Add a custom message option.
+ FieldDescriptorProto* extension_option =
+ file_descriptor_proto->add_extension();
+ extension_option->set_name("unknown_option");
+ extension_option->set_extendee(".google.protobuf.MessageOptions");
+ extension_option->set_number(1111);
+ extension_option->set_label(FieldDescriptorProto::LABEL_OPTIONAL);
+ extension_option->set_type(FieldDescriptorProto::TYPE_INT64);
+
+ file_descriptor_proto = file_descriptor_set.add_file();
+ file_descriptor_proto->set_name("import_custom_unknown_options.proto");
+ file_descriptor_proto->add_dependency("custom_options.proto");
+ // Add custom message option to unknown field. This custom option is
+ // not known in generated pool, thus option will be in unknown fields.
+ file_descriptor_proto->add_message_type()->set_name("Bar");
+ file_descriptor_proto->mutable_message_type(0)
+ ->mutable_options()
+ ->mutable_unknown_fields()
+ ->AddVarint(1111, 2222);
+
+ WriteDescriptorSet("foo.bin", &file_descriptor_set);
+
+ Run("protocol_compiler --test_out=$tmpdir --plug_out=$tmpdir "
+ "--descriptor_set_in=$tmpdir/foo.bin "
+ "import_custom_unknown_options.proto");
+
+ // TODO(jieluo): Fix this test. This test case only happens when
+ // CommandLineInterface::Run() is used instead of invoke protoc combined
+ // with descriptor_set_in, and same custom options are defined in both
+ // generated pool and descriptor_set_in. There's no such uages for now but
+ // still need to be fixed.
+ /*
+ file_descriptor_proto = file_descriptor_set.add_file();
+ file_descriptor_proto->set_name("import_custom_extension_options.proto");
+ file_descriptor_proto->add_dependency("custom_options.proto");
+ // Add custom message option to unknown field. This custom option is
+ // also defined in generated pool, thus option will be in extensions.
+ file_descriptor_proto->add_message_type()->set_name("Foo");
+ file_descriptor_proto->mutable_message_type(0)
+ ->mutable_options()
+ ->mutable_unknown_fields()
+ ->AddVarint(protobuf_unittest::message_opt1.number(), 2222);
+
+ WriteDescriptorSet("foo.bin", &file_descriptor_set);
+
+ Run("protocol_compiler --test_out=$tmpdir --plug_out=$tmpdir "
+ "--descriptor_set_in=$tmpdir/foo.bin import_custom_unknown_options.proto "
+ "import_custom_extension_options.proto");
+ */
+
+ ExpectNoErrors();
+}
+
+TEST_F(CommandLineInterfaceTest, MultipleInputsWithImport) {
+ // Test parsing multiple input files with an import of a separate file.
+
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "message Foo {}\n");
+ CreateTempFile("bar.proto",
+ "syntax = \"proto2\";\n"
+ "import \"baz.proto\";\n"
+ "message Bar {\n"
+ " optional Baz a = 1;\n"
+ "}\n");
+ CreateTempFile("baz.proto",
+ "syntax = \"proto2\";\n"
+ "message Baz {}\n");
+
+ Run("protocol_compiler --test_out=$tmpdir --plug_out=$tmpdir "
+ "--proto_path=$tmpdir foo.proto bar.proto");
+
+ ExpectNoErrors();
+ ExpectGeneratedWithMultipleInputs("test_generator", "foo.proto,bar.proto",
+ "foo.proto", "Foo");
+ ExpectGeneratedWithMultipleInputs("test_generator", "foo.proto,bar.proto",
+ "bar.proto", "Bar");
+ ExpectGeneratedWithMultipleInputs("test_plugin", "foo.proto,bar.proto",
+ "foo.proto", "Foo");
+ ExpectGeneratedWithMultipleInputs("test_plugin", "foo.proto,bar.proto",
+ "bar.proto", "Bar");
+}
+
+TEST_F(CommandLineInterfaceTest, MultipleInputsWithImport_DescriptorSetIn) {
+ // Test parsing multiple input files with an import of a separate file.
+ FileDescriptorSet file_descriptor_set;
+
+ FileDescriptorProto* file_descriptor_proto = file_descriptor_set.add_file();
+ file_descriptor_proto->set_name("foo.proto");
+ file_descriptor_proto->add_message_type()->set_name("Foo");
+
+ file_descriptor_proto = file_descriptor_set.add_file();
+ file_descriptor_proto->set_name("bar.proto");
+ file_descriptor_proto->add_dependency("baz.proto");
+ DescriptorProto* message = file_descriptor_proto->add_message_type();
+ message->set_name("Bar");
+ FieldDescriptorProto* field = message->add_field();
+ field->set_type_name("Baz");
+ field->set_name("a");
+ field->set_number(1);
+
+ WriteDescriptorSet("foo_and_bar.bin", &file_descriptor_set);
+
+ file_descriptor_set.clear_file();
+ file_descriptor_proto = file_descriptor_set.add_file();
+ file_descriptor_proto->set_name("baz.proto");
+ file_descriptor_proto->add_message_type()->set_name("Baz");
+
+ file_descriptor_proto = file_descriptor_set.add_file();
+ file_descriptor_proto->set_name("bat.proto");
+ file_descriptor_proto->add_dependency("baz.proto");
+ message = file_descriptor_proto->add_message_type();
+ message->set_name("Bat");
+ field = message->add_field();
+ field->set_type_name("Baz");
+ field->set_name("a");
+ field->set_number(1);
+
+ WriteDescriptorSet("baz_and_bat.bin", &file_descriptor_set);
+ Run(strings::Substitute(
+ "protocol_compiler --test_out=$$tmpdir --plug_out=$$tmpdir "
+ "--descriptor_set_in=$0 foo.proto bar.proto",
+ std::string("$tmpdir/foo_and_bar.bin") +
+ CommandLineInterface::kPathSeparator + "$tmpdir/baz_and_bat.bin"));
+
+ ExpectNoErrors();
+ ExpectGeneratedWithMultipleInputs("test_generator", "foo.proto,bar.proto",
+ "foo.proto", "Foo");
+ ExpectGeneratedWithMultipleInputs("test_generator", "foo.proto,bar.proto",
+ "bar.proto", "Bar");
+ ExpectGeneratedWithMultipleInputs("test_plugin", "foo.proto,bar.proto",
+ "foo.proto", "Foo");
+ ExpectGeneratedWithMultipleInputs("test_plugin", "foo.proto,bar.proto",
+ "bar.proto", "Bar");
+
+ Run(strings::Substitute(
+ "protocol_compiler --test_out=$$tmpdir --plug_out=$$tmpdir "
+ "--descriptor_set_in=$0 baz.proto bat.proto",
+ std::string("$tmpdir/foo_and_bar.bin") +
+ CommandLineInterface::kPathSeparator + "$tmpdir/baz_and_bat.bin"));
+
+ ExpectNoErrors();
+ ExpectGeneratedWithMultipleInputs("test_generator", "baz.proto,bat.proto",
+ "baz.proto", "Baz");
+ ExpectGeneratedWithMultipleInputs("test_generator", "baz.proto,bat.proto",
+ "bat.proto", "Bat");
+ ExpectGeneratedWithMultipleInputs("test_plugin", "baz.proto,bat.proto",
+ "baz.proto", "Baz");
+ ExpectGeneratedWithMultipleInputs("test_plugin", "baz.proto,bat.proto",
+ "bat.proto", "Bat");
+}
+
+TEST_F(CommandLineInterfaceTest,
+ MultipleInputsWithImport_DescriptorSetIn_DuplicateFileDescriptor) {
+ // Test parsing multiple input files with an import of a separate file.
+ FileDescriptorSet file_descriptor_set;
+
+ FileDescriptorProto foo_file_descriptor_proto;
+ foo_file_descriptor_proto.set_name("foo.proto");
+ foo_file_descriptor_proto.add_message_type()->set_name("Foo");
+
+ file_descriptor_set.add_file()->CopyFrom(foo_file_descriptor_proto);
+
+ FileDescriptorProto* file_descriptor_proto = file_descriptor_set.add_file();
+ file_descriptor_proto->set_name("bar.proto");
+ file_descriptor_proto->add_dependency("baz.proto");
+ file_descriptor_proto->add_dependency("foo.proto");
+ DescriptorProto* message = file_descriptor_proto->add_message_type();
+ message->set_name("Bar");
+ FieldDescriptorProto* field = message->add_field();
+ field->set_type_name("Baz");
+ field->set_name("a");
+ field->set_number(1);
+ field = message->add_field();
+ field->set_type_name("Foo");
+ field->set_name("f");
+ field->set_number(2);
+ WriteDescriptorSet("foo_and_bar.bin", &file_descriptor_set);
+
+ file_descriptor_set.clear_file();
+ file_descriptor_set.add_file()->CopyFrom(foo_file_descriptor_proto);
+
+ file_descriptor_proto = file_descriptor_set.add_file();
+ file_descriptor_proto->set_name("baz.proto");
+ file_descriptor_proto->add_dependency("foo.proto");
+ message = file_descriptor_proto->add_message_type();
+ message->set_name("Baz");
+ field = message->add_field();
+ field->set_type_name("Foo");
+ field->set_name("f");
+ field->set_number(1);
+ WriteDescriptorSet("foo_and_baz.bin", &file_descriptor_set);
+
+ Run(strings::Substitute(
+ "protocol_compiler --test_out=$$tmpdir --plug_out=$$tmpdir "
+ "--descriptor_set_in=$0 bar.proto",
+ std::string("$tmpdir/foo_and_bar.bin") +
+ CommandLineInterface::kPathSeparator + "$tmpdir/foo_and_baz.bin"));
+
+ ExpectNoErrors();
+ ExpectGenerated("test_generator", "", "bar.proto", "Bar");
+ ExpectGenerated("test_plugin", "", "bar.proto", "Bar");
+}
+
+TEST_F(CommandLineInterfaceTest,
+ MultipleInputsWithImport_DescriptorSetIn_MissingImport) {
+ // Test parsing multiple input files with an import of a separate file.
+ FileDescriptorSet file_descriptor_set;
+
+ FileDescriptorProto* file_descriptor_proto = file_descriptor_set.add_file();
+ file_descriptor_proto->set_name("foo.proto");
+ file_descriptor_proto->add_message_type()->set_name("Foo");
+
+ file_descriptor_proto = file_descriptor_set.add_file();
+ file_descriptor_proto->set_name("bar.proto");
+ file_descriptor_proto->add_dependency("baz.proto");
+ DescriptorProto* message = file_descriptor_proto->add_message_type();
+ message->set_name("Bar");
+ FieldDescriptorProto* field = message->add_field();
+ field->set_type_name("Baz");
+ field->set_name("a");
+ field->set_number(1);
+
+ WriteDescriptorSet("foo_and_bar.bin", &file_descriptor_set);
+
+ file_descriptor_set.clear_file();
+ file_descriptor_proto = file_descriptor_set.add_file();
+ file_descriptor_proto->set_name("baz.proto");
+ file_descriptor_proto->add_message_type()->set_name("Baz");
+
+ WriteDescriptorSet("baz.bin", &file_descriptor_set);
+ Run("protocol_compiler --test_out=$tmpdir --plug_out=$tmpdir "
+ "--descriptor_set_in=$tmpdir/foo_and_bar.bin "
+ "foo.proto bar.proto");
+ ExpectErrorSubstring(
+ "bar.proto: Import \"baz.proto\" was not found or had errors.");
+ ExpectErrorSubstring("bar.proto: \"Baz\" is not defined.");
+}
+
+TEST_F(CommandLineInterfaceTest,
+ InputsOnlyFromDescriptorSetIn_UnusedImportIsNotReported) {
+ FileDescriptorSet file_descriptor_set;
+
+ FileDescriptorProto* file_descriptor_proto = file_descriptor_set.add_file();
+ file_descriptor_proto->set_name("unused.proto");
+ file_descriptor_proto->add_message_type()->set_name("Unused");
+
+ file_descriptor_proto = file_descriptor_set.add_file();
+ file_descriptor_proto->set_name("bar.proto");
+ file_descriptor_proto->add_dependency("unused.proto");
+ file_descriptor_proto->add_message_type()->set_name("Bar");
+
+ WriteDescriptorSet("unused_and_bar.bin", &file_descriptor_set);
+
+ Run("protocol_compiler --test_out=$tmpdir --plug_out=$tmpdir "
+ "--descriptor_set_in=$tmpdir/unused_and_bar.bin unused.proto bar.proto");
+ ExpectNoErrors();
+}
+
+TEST_F(CommandLineInterfaceTest,
+ InputsFromDescriptorSetInAndFileSystem_UnusedImportIsReported) {
+ FileDescriptorSet file_descriptor_set;
+
+ FileDescriptorProto* file_descriptor_proto = file_descriptor_set.add_file();
+ file_descriptor_proto->set_name("unused.proto");
+ file_descriptor_proto->add_message_type()->set_name("Unused");
+
+ file_descriptor_proto = file_descriptor_set.add_file();
+ file_descriptor_proto->set_name("bar.proto");
+ file_descriptor_proto->add_dependency("unused.proto");
+ file_descriptor_proto->add_message_type()->set_name("Bar");
+
+ WriteDescriptorSet("unused_and_bar.bin", &file_descriptor_set);
+
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "import \"bar.proto\";\n"
+ "message Foo {\n"
+ " optional Bar bar = 1;\n"
+ "}\n");
+
+ Run("protocol_compiler --test_out=$tmpdir --plug_out=$tmpdir "
+ "--descriptor_set_in=$tmpdir/unused_and_bar.bin "
+ "--proto_path=$tmpdir unused.proto bar.proto foo.proto");
+ // Reporting unused imports here is unfair, since it's unactionable. Notice
+ // the lack of a line number.
+ // TODO(b/144853061): If the file with unused import is from the descriptor
+ // set and not from the file system, suppress the warning.
+ ExpectWarningSubstring("bar.proto: warning: Import unused.proto is unused.");
+}
+
+TEST_F(CommandLineInterfaceTest,
+ OnlyReportsUnusedImportsForFilesBeingGenerated) {
+ CreateTempFile("unused.proto",
+ "syntax = \"proto2\";\n"
+ "message Unused {}\n");
+ CreateTempFile("bar.proto",
+ "syntax = \"proto2\";\n"
+ "import \"unused.proto\";\n"
+ "message Bar {}\n");
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "import \"bar.proto\";\n"
+ "message Foo {\n"
+ " optional Bar bar = 1;\n"
+ "}\n");
+
+ Run("protocol_compiler --test_out=$tmpdir "
+ "--proto_path=$tmpdir foo.proto");
+ ExpectNoErrors();
+}
+
+TEST_F(CommandLineInterfaceTest, ReportsTransitiveMisingImports_LeafFirst) {
+ CreateTempFile("unused.proto",
+ "syntax = \"proto2\";\n"
+ "message Unused {}\n");
+ CreateTempFile("bar.proto",
+ "syntax = \"proto2\";\n"
+ "import \"unused.proto\";\n"
+ "message Bar {}\n");
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "import \"bar.proto\";\n"
+ "message Foo {\n"
+ " optional Bar bar = 1;\n"
+ "}\n");
+
+ Run("protocol_compiler --test_out=$tmpdir "
+ "--proto_path=$tmpdir bar.proto foo.proto");
+ ExpectWarningSubstring(
+ "bar.proto:2:1: warning: Import unused.proto is unused.");
+}
+
+TEST_F(CommandLineInterfaceTest, ReportsTransitiveMisingImports_LeafLast) {
+ CreateTempFile("unused.proto",
+ "syntax = \"proto2\";\n"
+ "message Unused {}\n");
+ CreateTempFile("bar.proto",
+ "syntax = \"proto2\";\n"
+ "import \"unused.proto\";\n"
+ "message Bar {}\n");
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "import \"bar.proto\";\n"
+ "message Foo {\n"
+ " optional Bar bar = 1;\n"
+ "}\n");
+
+ Run("protocol_compiler --test_out=$tmpdir "
+ "--proto_path=$tmpdir foo.proto bar.proto");
+ ExpectWarningSubstring(
+ "bar.proto:2:1: warning: Import unused.proto is unused.");
+}
+TEST_F(CommandLineInterfaceTest, CreateDirectory) {
+ // Test that when we output to a sub-directory, it is created.
+
+ CreateTempFile("bar/baz/foo.proto",
+ "syntax = \"proto2\";\n"
+ "message Foo {}\n");
+ CreateTempDir("out");
+ CreateTempDir("plugout");
+
+ Run("protocol_compiler --test_out=$tmpdir/out --plug_out=$tmpdir/plugout "
+ "--proto_path=$tmpdir bar/baz/foo.proto");
+
+ ExpectNoErrors();
+ ExpectGenerated("test_generator", "", "bar/baz/foo.proto", "Foo", "out");
+ ExpectGenerated("test_plugin", "", "bar/baz/foo.proto", "Foo", "plugout");
+}
+
+TEST_F(CommandLineInterfaceTest, GeneratorParameters) {
+ // Test that generator parameters are correctly parsed from the command line.
+
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "message Foo {}\n");
+
+ Run("protocol_compiler --test_out=TestParameter:$tmpdir "
+ "--plug_out=TestPluginParameter:$tmpdir "
+ "--proto_path=$tmpdir foo.proto");
+
+ ExpectNoErrors();
+ ExpectGenerated("test_generator", "TestParameter", "foo.proto", "Foo");
+ ExpectGenerated("test_plugin", "TestPluginParameter", "foo.proto", "Foo");
+}
+
+TEST_F(CommandLineInterfaceTest, ExtraGeneratorParameters) {
+ // Test that generator parameters specified with the option flag are
+ // correctly passed to the code generator.
+
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "message Foo {}\n");
+ // Create the "a" and "b" sub-directories.
+ CreateTempDir("a");
+ CreateTempDir("b");
+
+ Run("protocol_compiler "
+ "--test_opt=foo1 "
+ "--test_out=bar:$tmpdir/a "
+ "--test_opt=foo2 "
+ "--test_out=baz:$tmpdir/b "
+ "--test_opt=foo3 "
+ "--proto_path=$tmpdir foo.proto");
+
+ ExpectNoErrors();
+ ExpectGenerated("test_generator", "bar,foo1,foo2,foo3", "foo.proto", "Foo",
+ "a");
+ ExpectGenerated("test_generator", "baz,foo1,foo2,foo3", "foo.proto", "Foo",
+ "b");
+}
+
+TEST_F(CommandLineInterfaceTest, ExtraPluginParameters) {
+ // Test that generator parameters specified with the option flag are
+ // correctly passed to the code generator.
+
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "message Foo {}\n");
+ // Create the "a" and "b" sub-directories.
+ CreateTempDir("a");
+ CreateTempDir("b");
+
+ Run("protocol_compiler "
+ "--plug_opt=foo1 "
+ "--plug_out=bar:$tmpdir/a "
+ "--plug_opt=foo2 "
+ "--plug_out=baz:$tmpdir/b "
+ "--plug_opt=foo3 "
+ "--proto_path=$tmpdir foo.proto");
+
+ ExpectNoErrors();
+ ExpectGenerated("test_plugin", "bar,foo1,foo2,foo3", "foo.proto", "Foo", "a");
+ ExpectGenerated("test_plugin", "baz,foo1,foo2,foo3", "foo.proto", "Foo", "b");
+}
+
+TEST_F(CommandLineInterfaceTest, UnrecognizedExtraParameters) {
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "message Foo {}\n");
+
+ Run("protocol_compiler --plug_out=TestParameter:$tmpdir "
+ "--unknown_plug_a_opt=Foo "
+ "--unknown_plug_b_opt=Bar "
+ "--proto_path=$tmpdir foo.proto");
+
+ ExpectErrorSubstring("Unknown flag: --unknown_plug_a_opt");
+ ExpectErrorSubstring("Unknown flag: --unknown_plug_b_opt");
+}
+
+TEST_F(CommandLineInterfaceTest, ExtraPluginParametersForOutParameters) {
+ // This doesn't rely on the plugin having been registered and instead that
+ // the existence of --[name]_out is enough to make the --[name]_opt valid.
+ // However, running out of process plugins found via the search path (i.e. -
+ // not pre registered with --plugin) isn't support in this test suite, so we
+ // list the options pre/post the _out directive, and then include _opt that
+ // will be unknown, and confirm the failure output is about the expected
+ // unknown directive, which means the other were accepted.
+ // NOTE: UnrecognizedExtraParameters confirms that if two unknown _opt
+ // directives appear, they both are reported.
+
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "message Foo {}\n");
+
+ Run("protocol_compiler --plug_out=TestParameter:$tmpdir "
+ "--xyz_opt=foo=bar --xyz_out=$tmpdir "
+ "--abc_out=$tmpdir --abc_opt=foo=bar "
+ "--unknown_plug_opt=Foo "
+ "--proto_path=$tmpdir foo.proto");
+
+ ExpectErrorText("Unknown flag: --unknown_plug_opt\n");
+}
+
+TEST_F(CommandLineInterfaceTest, Insert) {
+ // Test running a generator that inserts code into another's output.
+
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "message Foo {}\n");
+
+ Run("protocol_compiler "
+ "--test_out=TestParameter:$tmpdir "
+ "--plug_out=TestPluginParameter:$tmpdir "
+ "--test_out=insert=test_generator,test_plugin:$tmpdir "
+ "--plug_out=insert=test_generator,test_plugin:$tmpdir "
+ "--proto_path=$tmpdir foo.proto");
+
+ ExpectNoErrors();
+ ExpectGeneratedWithInsertions("test_generator", "TestParameter",
+ "test_generator,test_plugin", "foo.proto",
+ "Foo");
+ ExpectGeneratedWithInsertions("test_plugin", "TestPluginParameter",
+ "test_generator,test_plugin", "foo.proto",
+ "Foo");
+}
+
+TEST_F(CommandLineInterfaceTest, InsertWithAnnotationFixup) {
+ // Check that annotation spans are updated after insertions.
+
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "message MockCodeGenerator_Annotate {}\n");
+
+ Run("protocol_compiler "
+ "--test_out=TestParameter:$tmpdir "
+ "--plug_out=TestPluginParameter:$tmpdir "
+ "--test_out=insert_endlines=test_generator,test_plugin:$tmpdir "
+ "--plug_out=insert_endlines=test_generator,test_plugin:$tmpdir "
+ "--proto_path=$tmpdir foo.proto");
+
+ ExpectNoErrors();
+ CheckGeneratedAnnotations("test_generator", "foo.proto");
+ CheckGeneratedAnnotations("test_plugin", "foo.proto");
+}
+
+#if defined(_WIN32)
+
+TEST_F(CommandLineInterfaceTest, WindowsOutputPath) {
+ // Test that the output path can be a Windows-style path.
+
+ CreateTempFile("foo.proto", "syntax = \"proto2\";\n");
+
+ Run("protocol_compiler --null_out=C:\\ "
+ "--proto_path=$tmpdir foo.proto");
+
+ ExpectNoErrors();
+ ExpectNullCodeGeneratorCalled("");
+}
+
+TEST_F(CommandLineInterfaceTest, WindowsOutputPathAndParameter) {
+ // Test that we can have a windows-style output path and a parameter.
+
+ CreateTempFile("foo.proto", "syntax = \"proto2\";\n");
+
+ Run("protocol_compiler --null_out=bar:C:\\ "
+ "--proto_path=$tmpdir foo.proto");
+
+ ExpectNoErrors();
+ ExpectNullCodeGeneratorCalled("bar");
+}
+
+TEST_F(CommandLineInterfaceTest, TrailingBackslash) {
+ // Test that the directories can end in backslashes. Some users claim this
+ // doesn't work on their system.
+
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "message Foo {}\n");
+
+ Run("protocol_compiler --test_out=$tmpdir\\ "
+ "--proto_path=$tmpdir\\ foo.proto");
+
+ ExpectNoErrors();
+ ExpectGenerated("test_generator", "", "foo.proto", "Foo");
+}
+
+TEST_F(CommandLineInterfaceTest, Win32ErrorMessage) {
+ EXPECT_EQ("The system cannot find the file specified.\r\n",
+ Subprocess::Win32ErrorMessage(ERROR_FILE_NOT_FOUND));
+}
+
+#endif // defined(_WIN32) || defined(__CYGWIN__)
+
+TEST_F(CommandLineInterfaceTest, PathLookup) {
+ // Test that specifying multiple directories in the proto search path works.
+
+ CreateTempFile("b/bar.proto",
+ "syntax = \"proto2\";\n"
+ "message Bar {}\n");
+ CreateTempFile("a/foo.proto",
+ "syntax = \"proto2\";\n"
+ "import \"bar.proto\";\n"
+ "message Foo {\n"
+ " optional Bar a = 1;\n"
+ "}\n");
+ CreateTempFile("b/foo.proto", "this should not be parsed\n");
+
+ Run("protocol_compiler --test_out=$tmpdir "
+ "--proto_path=$tmpdir/a --proto_path=$tmpdir/b foo.proto");
+
+ ExpectNoErrors();
+ ExpectGenerated("test_generator", "", "foo.proto", "Foo");
+}
+
+TEST_F(CommandLineInterfaceTest, ColonDelimitedPath) {
+ // Same as PathLookup, but we provide the proto_path in a single flag.
+
+ CreateTempFile("b/bar.proto",
+ "syntax = \"proto2\";\n"
+ "message Bar {}\n");
+ CreateTempFile("a/foo.proto",
+ "syntax = \"proto2\";\n"
+ "import \"bar.proto\";\n"
+ "message Foo {\n"
+ " optional Bar a = 1;\n"
+ "}\n");
+ CreateTempFile("b/foo.proto", "this should not be parsed\n");
+
+ Run(strings::Substitute(
+ "protocol_compiler --test_out=$$tmpdir --proto_path=$0 foo.proto",
+ std::string("$tmpdir/a") + CommandLineInterface::kPathSeparator +
+ "$tmpdir/b"));
+
+ ExpectNoErrors();
+ ExpectGenerated("test_generator", "", "foo.proto", "Foo");
+}
+
+TEST_F(CommandLineInterfaceTest, NonRootMapping) {
+ // Test setting up a search path mapping a directory to a non-root location.
+
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "message Foo {}\n");
+
+ Run("protocol_compiler --test_out=$tmpdir "
+ "--proto_path=bar=$tmpdir bar/foo.proto");
+
+ ExpectNoErrors();
+ ExpectGenerated("test_generator", "", "bar/foo.proto", "Foo");
+}
+
+TEST_F(CommandLineInterfaceTest, PathWithEqualsSign) {
+ // Test setting up a search path which happens to have '=' in it.
+
+ CreateTempDir("with=sign");
+ CreateTempFile("with=sign/foo.proto",
+ "syntax = \"proto2\";\n"
+ "message Foo {}\n");
+
+ Run("protocol_compiler --test_out=$tmpdir "
+ "--proto_path=$tmpdir/with=sign foo.proto");
+
+ ExpectNoErrors();
+ ExpectGenerated("test_generator", "", "foo.proto", "Foo");
+}
+
+TEST_F(CommandLineInterfaceTest, MultipleGenerators) {
+ // Test that we can have multiple generators and use both in one invocation,
+ // each with a different output directory.
+
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "message Foo {}\n");
+ // Create the "a" and "b" sub-directories.
+ CreateTempDir("a");
+ CreateTempDir("b");
+
+ Run("protocol_compiler "
+ "--test_out=$tmpdir/a "
+ "--alt_out=$tmpdir/b "
+ "--proto_path=$tmpdir foo.proto");
+
+ ExpectNoErrors();
+ ExpectGenerated("test_generator", "", "foo.proto", "Foo", "a");
+ ExpectGenerated("alt_generator", "", "foo.proto", "Foo", "b");
+}
+
+TEST_F(CommandLineInterfaceTest, DisallowServicesNoServices) {
+ // Test that --disallow_services doesn't cause a problem when there are no
+ // services.
+
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "message Foo {}\n");
+
+ Run("protocol_compiler --disallow_services --test_out=$tmpdir "
+ "--proto_path=$tmpdir foo.proto");
+
+ ExpectNoErrors();
+ ExpectGenerated("test_generator", "", "foo.proto", "Foo");
+}
+
+TEST_F(CommandLineInterfaceTest, DisallowServicesHasService) {
+ // Test that --disallow_services produces an error when there are services.
+
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "message Foo {}\n"
+ "service Bar {}\n");
+
+ Run("protocol_compiler --disallow_services --test_out=$tmpdir "
+ "--proto_path=$tmpdir foo.proto");
+
+ ExpectErrorSubstring("foo.proto: This file contains services");
+}
+
+TEST_F(CommandLineInterfaceTest, AllowServicesHasService) {
+ // Test that services work fine as long as --disallow_services is not used.
+
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "message Foo {}\n"
+ "service Bar {}\n");
+
+ Run("protocol_compiler --test_out=$tmpdir "
+ "--proto_path=$tmpdir foo.proto");
+
+ ExpectNoErrors();
+ ExpectGenerated("test_generator", "", "foo.proto", "Foo");
+}
+
+
+TEST_F(CommandLineInterfaceTest, DirectDependencies_Missing_EmptyList) {
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "import \"bar.proto\";\n"
+ "message Foo { optional Bar bar = 1; }");
+ CreateTempFile("bar.proto",
+ "syntax = \"proto2\";\n"
+ "message Bar { optional string text = 1; }");
+
+ Run("protocol_compiler --test_out=$tmpdir --proto_path=$tmpdir "
+ "--direct_dependencies= foo.proto");
+
+ ExpectErrorText(
+ "foo.proto: File is imported but not declared in --direct_dependencies: "
+ "bar.proto\n");
+}
+
+TEST_F(CommandLineInterfaceTest, DirectDependencies_Missing) {
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "import \"bar.proto\";\n"
+ "import \"bla.proto\";\n"
+ "message Foo { optional Bar bar = 1; optional Bla bla = 2; }");
+ CreateTempFile("bar.proto",
+ "syntax = \"proto2\";\n"
+ "message Bar { optional string text = 1; }");
+ CreateTempFile("bla.proto",
+ "syntax = \"proto2\";\n"
+ "message Bla { optional int64 number = 1; }");
+
+ Run("protocol_compiler --test_out=$tmpdir --proto_path=$tmpdir "
+ "--direct_dependencies=bla.proto foo.proto");
+
+ ExpectErrorText(
+ "foo.proto: File is imported but not declared in --direct_dependencies: "
+ "bar.proto\n");
+}
+
+TEST_F(CommandLineInterfaceTest, DirectDependencies_NoViolation) {
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "import \"bar.proto\";\n"
+ "message Foo { optional Bar bar = 1; }");
+ CreateTempFile("bar.proto",
+ "syntax = \"proto2\";\n"
+ "message Bar { optional string text = 1; }");
+
+ Run("protocol_compiler --test_out=$tmpdir --proto_path=$tmpdir "
+ "--direct_dependencies=bar.proto foo.proto");
+
+ ExpectNoErrors();
+}
+
+TEST_F(CommandLineInterfaceTest, DirectDependencies_NoViolation_MultiImports) {
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "import \"bar.proto\";\n"
+ "import \"bla.proto\";\n"
+ "message Foo { optional Bar bar = 1; optional Bla bla = 2; }");
+ CreateTempFile("bar.proto",
+ "syntax = \"proto2\";\n"
+ "message Bar { optional string text = 1; }");
+ CreateTempFile("bla.proto",
+ "syntax = \"proto2\";\n"
+ "message Bla { optional int64 number = 1; }");
+
+ Run("protocol_compiler --test_out=$tmpdir --proto_path=$tmpdir "
+ "--direct_dependencies=bar.proto:bla.proto foo.proto");
+
+ ExpectNoErrors();
+}
+
+TEST_F(CommandLineInterfaceTest, DirectDependencies_ProvidedMultipleTimes) {
+ CreateTempFile("foo.proto", "syntax = \"proto2\";\n");
+
+ Run("protocol_compiler --test_out=$tmpdir --proto_path=$tmpdir "
+ "--direct_dependencies=bar.proto --direct_dependencies=bla.proto "
+ "foo.proto");
+
+ ExpectErrorText(
+ "--direct_dependencies may only be passed once. To specify multiple "
+ "direct dependencies, pass them all as a single parameter separated by "
+ "':'.\n");
+}
+
+TEST_F(CommandLineInterfaceTest, DirectDependencies_CustomErrorMessage) {
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "import \"bar.proto\";\n"
+ "message Foo { optional Bar bar = 1; }");
+ CreateTempFile("bar.proto",
+ "syntax = \"proto2\";\n"
+ "message Bar { optional string text = 1; }");
+
+ std::vector<std::string> commands;
+ commands.push_back("protocol_compiler");
+ commands.push_back("--test_out=$tmpdir");
+ commands.push_back("--proto_path=$tmpdir");
+ commands.push_back("--direct_dependencies=");
+ commands.push_back("--direct_dependencies_violation_msg=Bla \"%s\" Bla");
+ commands.push_back("foo.proto");
+ RunWithArgs(commands);
+
+ ExpectErrorText("foo.proto: Bla \"bar.proto\" Bla\n");
+}
+
+TEST_F(CommandLineInterfaceTest, CwdRelativeInputs) {
+ // Test that we can accept working-directory-relative input files.
+
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "message Foo {}\n");
+
+ Run("protocol_compiler --test_out=$tmpdir "
+ "--proto_path=$tmpdir $tmpdir/foo.proto");
+
+ ExpectNoErrors();
+ ExpectGenerated("test_generator", "", "foo.proto", "Foo");
+}
+
+TEST_F(CommandLineInterfaceTest, WriteDescriptorSet) {
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "message Foo {}\n");
+ CreateTempFile("bar.proto",
+ "syntax = \"proto2\";\n"
+ "import \"foo.proto\";\n"
+ "message Bar {\n"
+ " optional Foo foo = 1;\n"
+ "}\n");
+
+ Run("protocol_compiler --descriptor_set_out=$tmpdir/descriptor_set "
+ "--proto_path=$tmpdir bar.proto");
+
+ ExpectNoErrors();
+
+ FileDescriptorSet descriptor_set;
+ ReadDescriptorSet("descriptor_set", &descriptor_set);
+ if (HasFatalFailure()) return;
+ EXPECT_EQ(1, descriptor_set.file_size());
+ EXPECT_EQ("bar.proto", descriptor_set.file(0).name());
+ // Descriptor set should not have source code info.
+ EXPECT_FALSE(descriptor_set.file(0).has_source_code_info());
+ // Descriptor set should have json_name.
+ EXPECT_EQ("Bar", descriptor_set.file(0).message_type(0).name());
+ EXPECT_EQ("foo", descriptor_set.file(0).message_type(0).field(0).name());
+ EXPECT_TRUE(descriptor_set.file(0).message_type(0).field(0).has_json_name());
+}
+
+TEST_F(CommandLineInterfaceTest, WriteDescriptorSetWithDuplicates) {
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "message Foo {}\n");
+ CreateTempFile("bar.proto",
+ "syntax = \"proto2\";\n"
+ "import \"foo.proto\";\n"
+ "message Bar {\n"
+ " optional Foo foo = 1;\n"
+ "}\n");
+ CreateTempFile("baz.proto",
+ "syntax = \"proto2\";\n"
+ "import \"foo.proto\";\n"
+ "message Baz {\n"
+ " optional Foo foo = 1;\n"
+ "}\n");
+
+ Run("protocol_compiler --descriptor_set_out=$tmpdir/descriptor_set "
+ "--proto_path=$tmpdir bar.proto foo.proto bar.proto baz.proto");
+
+ ExpectNoErrors();
+
+ FileDescriptorSet descriptor_set;
+ ReadDescriptorSet("descriptor_set", &descriptor_set);
+ if (HasFatalFailure()) return;
+ EXPECT_EQ(3, descriptor_set.file_size());
+ // foo should come first since the output is in dependency order.
+ // since bar and baz are unordered, they should be in command line order.
+ EXPECT_EQ("foo.proto", descriptor_set.file(0).name());
+ EXPECT_EQ("bar.proto", descriptor_set.file(1).name());
+ EXPECT_EQ("baz.proto", descriptor_set.file(2).name());
+ // Descriptor set should not have source code info.
+ EXPECT_FALSE(descriptor_set.file(0).has_source_code_info());
+ // Descriptor set should have json_name.
+ EXPECT_EQ("Bar", descriptor_set.file(1).message_type(0).name());
+ EXPECT_EQ("foo", descriptor_set.file(1).message_type(0).field(0).name());
+ EXPECT_TRUE(descriptor_set.file(1).message_type(0).field(0).has_json_name());
+}
+
+TEST_F(CommandLineInterfaceTest, WriteDescriptorSetWithSourceInfo) {
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "message Foo {}\n");
+ CreateTempFile("bar.proto",
+ "syntax = \"proto2\";\n"
+ "import \"foo.proto\";\n"
+ "message Bar {\n"
+ " optional Foo foo = 1;\n"
+ "}\n");
+
+ Run("protocol_compiler --descriptor_set_out=$tmpdir/descriptor_set "
+ "--include_source_info --proto_path=$tmpdir bar.proto");
+
+ ExpectNoErrors();
+
+ FileDescriptorSet descriptor_set;
+ ReadDescriptorSet("descriptor_set", &descriptor_set);
+ if (HasFatalFailure()) return;
+ EXPECT_EQ(1, descriptor_set.file_size());
+ EXPECT_EQ("bar.proto", descriptor_set.file(0).name());
+ // Source code info included.
+ EXPECT_TRUE(descriptor_set.file(0).has_source_code_info());
+}
+
+TEST_F(CommandLineInterfaceTest, WriteTransitiveDescriptorSet) {
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "message Foo {}\n");
+ CreateTempFile("bar.proto",
+ "syntax = \"proto2\";\n"
+ "import \"foo.proto\";\n"
+ "message Bar {\n"
+ " optional Foo foo = 1;\n"
+ "}\n");
+
+ Run("protocol_compiler --descriptor_set_out=$tmpdir/descriptor_set "
+ "--include_imports --proto_path=$tmpdir bar.proto");
+
+ ExpectNoErrors();
+
+ FileDescriptorSet descriptor_set;
+ ReadDescriptorSet("descriptor_set", &descriptor_set);
+ if (HasFatalFailure()) return;
+ EXPECT_EQ(2, descriptor_set.file_size());
+ if (descriptor_set.file(0).name() == "bar.proto") {
+ std::swap(descriptor_set.mutable_file()->mutable_data()[0],
+ descriptor_set.mutable_file()->mutable_data()[1]);
+ }
+ EXPECT_EQ("foo.proto", descriptor_set.file(0).name());
+ EXPECT_EQ("bar.proto", descriptor_set.file(1).name());
+ // Descriptor set should not have source code info.
+ EXPECT_FALSE(descriptor_set.file(0).has_source_code_info());
+ EXPECT_FALSE(descriptor_set.file(1).has_source_code_info());
+}
+
+TEST_F(CommandLineInterfaceTest, WriteTransitiveDescriptorSetWithSourceInfo) {
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "message Foo {}\n");
+ CreateTempFile("bar.proto",
+ "syntax = \"proto2\";\n"
+ "import \"foo.proto\";\n"
+ "message Bar {\n"
+ " optional Foo foo = 1;\n"
+ "}\n");
+
+ Run("protocol_compiler --descriptor_set_out=$tmpdir/descriptor_set "
+ "--include_imports --include_source_info --proto_path=$tmpdir bar.proto");
+
+ ExpectNoErrors();
+
+ FileDescriptorSet descriptor_set;
+ ReadDescriptorSet("descriptor_set", &descriptor_set);
+ if (HasFatalFailure()) return;
+ EXPECT_EQ(2, descriptor_set.file_size());
+ if (descriptor_set.file(0).name() == "bar.proto") {
+ std::swap(descriptor_set.mutable_file()->mutable_data()[0],
+ descriptor_set.mutable_file()->mutable_data()[1]);
+ }
+ EXPECT_EQ("foo.proto", descriptor_set.file(0).name());
+ EXPECT_EQ("bar.proto", descriptor_set.file(1).name());
+ // Source code info included.
+ EXPECT_TRUE(descriptor_set.file(0).has_source_code_info());
+ EXPECT_TRUE(descriptor_set.file(1).has_source_code_info());
+}
+
+#ifdef _WIN32
+// TODO(teboring): Figure out how to write test on windows.
+#else
+TEST_F(CommandLineInterfaceTest, WriteDependencyManifestFileGivenTwoInputs) {
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "message Foo {}\n");
+ CreateTempFile("bar.proto",
+ "syntax = \"proto2\";\n"
+ "import \"foo.proto\";\n"
+ "message Bar {\n"
+ " optional Foo foo = 1;\n"
+ "}\n");
+
+ Run("protocol_compiler --dependency_out=$tmpdir/manifest "
+ "--test_out=$tmpdir --proto_path=$tmpdir bar.proto foo.proto");
+
+ ExpectErrorText(
+ "Can only process one input file when using --dependency_out=FILE.\n");
+}
+
+#ifdef PROTOBUF_OPENSOURCE
+TEST_F(CommandLineInterfaceTest, WriteDependencyManifestFile) {
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "message Foo {}\n");
+ CreateTempFile("bar.proto",
+ "syntax = \"proto2\";\n"
+ "import \"foo.proto\";\n"
+ "message Bar {\n"
+ " optional Foo foo = 1;\n"
+ "}\n");
+
+ std::string current_working_directory = getcwd(NULL, 0);
+ SwitchToTempDirectory();
+
+ Run("protocol_compiler --dependency_out=manifest --test_out=. "
+ "bar.proto");
+
+ ExpectNoErrors();
+
+ ExpectFileContent("manifest",
+ "bar.proto.MockCodeGenerator.test_generator: "
+ "foo.proto\\\n bar.proto");
+
+ File::ChangeWorkingDirectory(current_working_directory);
+}
+#else // !PROTOBUF_OPENSOURCE
+// TODO(teboring): Figure out how to change and get working directory in
+// google3.
+#endif // !PROTOBUF_OPENSOURCE
+
+TEST_F(CommandLineInterfaceTest, WriteDependencyManifestFileForAbsolutePath) {
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "message Foo {}\n");
+ CreateTempFile("bar.proto",
+ "syntax = \"proto2\";\n"
+ "import \"foo.proto\";\n"
+ "message Bar {\n"
+ " optional Foo foo = 1;\n"
+ "}\n");
+
+ Run("protocol_compiler --dependency_out=$tmpdir/manifest "
+ "--test_out=$tmpdir --proto_path=$tmpdir bar.proto");
+
+ ExpectNoErrors();
+
+ ExpectFileContent("manifest",
+ "$tmpdir/bar.proto.MockCodeGenerator.test_generator: "
+ "$tmpdir/foo.proto\\\n $tmpdir/bar.proto");
+}
+#endif // !_WIN32
+
+TEST_F(CommandLineInterfaceTest, TestArgumentFile) {
+ // Test parsing multiple input files using an argument file.
+
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "message Foo {}\n");
+ CreateTempFile("bar.proto",
+ "syntax = \"proto2\";\n"
+ "message Bar {}\n");
+ CreateTempFile("arguments.txt",
+ "--test_out=$tmpdir\n"
+ "--plug_out=$tmpdir\n"
+ "--proto_path=$tmpdir\n"
+ "--direct_dependencies_violation_msg=%s is not imported\n"
+ "foo.proto\n"
+ "bar.proto");
+
+ Run("protocol_compiler @$tmpdir/arguments.txt");
+
+ ExpectNoErrors();
+ ExpectGeneratedWithMultipleInputs("test_generator", "foo.proto,bar.proto",
+ "foo.proto", "Foo");
+ ExpectGeneratedWithMultipleInputs("test_generator", "foo.proto,bar.proto",
+ "bar.proto", "Bar");
+ ExpectGeneratedWithMultipleInputs("test_plugin", "foo.proto,bar.proto",
+ "foo.proto", "Foo");
+ ExpectGeneratedWithMultipleInputs("test_plugin", "foo.proto,bar.proto",
+ "bar.proto", "Bar");
+}
+
+
+// -------------------------------------------------------------------
+
+TEST_F(CommandLineInterfaceTest, ParseErrors) {
+ // Test that parse errors are reported.
+
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "badsyntax\n");
+
+ Run("protocol_compiler --test_out=$tmpdir "
+ "--proto_path=$tmpdir foo.proto");
+
+ ExpectErrorText(
+ "foo.proto:2:1: Expected top-level statement (e.g. \"message\").\n");
+}
+
+TEST_F(CommandLineInterfaceTest, ParseErrors_DescriptorSetIn) {
+ // Test that parse errors are reported.
+ CreateTempFile("foo.bin", "not a FileDescriptorSet");
+
+ Run("protocol_compiler --test_out=$tmpdir "
+ "--descriptor_set_in=$tmpdir/foo.bin foo.proto");
+
+ ExpectErrorText("$tmpdir/foo.bin: Unable to parse.\n");
+}
+
+TEST_F(CommandLineInterfaceTest, ParseErrorsMultipleFiles) {
+ // Test that parse errors are reported from multiple files.
+
+ // We set up files such that foo.proto actually depends on bar.proto in
+ // two ways: Directly and through baz.proto. bar.proto's errors should
+ // only be reported once.
+ CreateTempFile("bar.proto",
+ "syntax = \"proto2\";\n"
+ "badsyntax\n");
+ CreateTempFile("baz.proto",
+ "syntax = \"proto2\";\n"
+ "import \"bar.proto\";\n");
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "import \"bar.proto\";\n"
+ "import \"baz.proto\";\n");
+
+ Run("protocol_compiler --test_out=$tmpdir "
+ "--proto_path=$tmpdir foo.proto");
+
+ ExpectErrorText(
+ "bar.proto:2:1: Expected top-level statement (e.g. \"message\").\n"
+ "baz.proto:2:1: Import \"bar.proto\" was not found or had errors.\n"
+ "foo.proto:2:1: Import \"bar.proto\" was not found or had errors.\n"
+ "foo.proto:3:1: Import \"baz.proto\" was not found or had errors.\n");
+}
+
+TEST_F(CommandLineInterfaceTest, RecursiveImportFails) {
+ // Create a proto file that imports itself.
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "import \"foo.proto\";\n");
+
+ Run("protocol_compiler --test_out=$tmpdir "
+ "--proto_path=$tmpdir foo.proto");
+
+ ExpectErrorSubstring(
+ "foo.proto:2:1: File recursively imports itself: "
+ "foo.proto -> foo.proto\n");
+}
+
+TEST_F(CommandLineInterfaceTest, InputNotFoundError) {
+ // Test what happens if the input file is not found.
+
+ Run("protocol_compiler --test_out=$tmpdir "
+ "--proto_path=$tmpdir foo.proto");
+
+ ExpectErrorText(
+ "Could not make proto path relative: foo.proto: No such file or "
+ "directory\n");
+}
+
+TEST_F(CommandLineInterfaceTest, InputNotFoundError_DescriptorSetIn) {
+ // Test what happens if the input file is not found.
+
+ Run("protocol_compiler --test_out=$tmpdir "
+ "--descriptor_set_in=$tmpdir/foo.bin foo.proto");
+
+ ExpectErrorText("$tmpdir/foo.bin: No such file or directory\n");
+}
+
+TEST_F(CommandLineInterfaceTest, CwdRelativeInputNotFoundError) {
+ // Test what happens when a working-directory-relative input file is not
+ // found.
+
+ Run("protocol_compiler --test_out=$tmpdir "
+ "--proto_path=$tmpdir $tmpdir/foo.proto");
+
+ ExpectErrorText(
+ "Could not make proto path relative: $tmpdir/foo.proto: No such file or "
+ "directory\n");
+}
+
+TEST_F(CommandLineInterfaceTest, CwdRelativeInputNotMappedError) {
+ // Test what happens when a working-directory-relative input file is not
+ // mapped to a virtual path.
+
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "message Foo {}\n");
+
+ // Create a directory called "bar" so that we can point --proto_path at it.
+ CreateTempFile("bar/dummy", "");
+
+ Run("protocol_compiler --test_out=$tmpdir "
+ "--proto_path=$tmpdir/bar $tmpdir/foo.proto");
+
+ ExpectErrorText(
+ "$tmpdir/foo.proto: File does not reside within any path "
+ "specified using --proto_path (or -I). You must specify a "
+ "--proto_path which encompasses this file. Note that the "
+ "proto_path must be an exact prefix of the .proto file "
+ "names -- protoc is too dumb to figure out when two paths "
+ "(e.g. absolute and relative) are equivalent (it's harder "
+ "than you think).\n");
+}
+
+TEST_F(CommandLineInterfaceTest, CwdRelativeInputNotFoundAndNotMappedError) {
+ // Check what happens if the input file is not found *and* is not mapped
+ // in the proto_path.
+
+ // Create a directory called "bar" so that we can point --proto_path at it.
+ CreateTempFile("bar/dummy", "");
+
+ Run("protocol_compiler --test_out=$tmpdir "
+ "--proto_path=$tmpdir/bar $tmpdir/foo.proto");
+
+ ExpectErrorText(
+ "Could not make proto path relative: $tmpdir/foo.proto: No such file or "
+ "directory\n");
+}
+
+TEST_F(CommandLineInterfaceTest, CwdRelativeInputShadowedError) {
+ // Test what happens when a working-directory-relative input file is shadowed
+ // by another file in the virtual path.
+
+ CreateTempFile("foo/foo.proto",
+ "syntax = \"proto2\";\n"
+ "message Foo {}\n");
+ CreateTempFile("bar/foo.proto",
+ "syntax = \"proto2\";\n"
+ "message Bar {}\n");
+
+ Run("protocol_compiler --test_out=$tmpdir "
+ "--proto_path=$tmpdir/foo --proto_path=$tmpdir/bar "
+ "$tmpdir/bar/foo.proto");
+
+ ExpectErrorText(
+ "$tmpdir/bar/foo.proto: Input is shadowed in the --proto_path "
+ "by \"$tmpdir/foo/foo.proto\". Either use the latter "
+ "file as your input or reorder the --proto_path so that the "
+ "former file's location comes first.\n");
+}
+
+TEST_F(CommandLineInterfaceTest, ProtoPathNotFoundError) {
+ // Test what happens if the input file is not found.
+
+ Run("protocol_compiler --test_out=$tmpdir "
+ "--proto_path=$tmpdir/foo foo.proto");
+
+ ExpectErrorText(
+ "$tmpdir/foo: warning: directory does not exist.\n"
+ "Could not make proto path relative: foo.proto: No such file or "
+ "directory\n");
+}
+
+TEST_F(CommandLineInterfaceTest, ProtoPathAndDescriptorSetIn) {
+ Run("protocol_compiler --test_out=$tmpdir "
+ "--proto_path=$tmpdir --descriptor_set_in=$tmpdir/foo.bin foo.proto");
+ ExpectErrorText("$tmpdir/foo.bin: No such file or directory\n");
+
+ Run("protocol_compiler --test_out=$tmpdir "
+ "--descriptor_set_in=$tmpdir/foo.bin --proto_path=$tmpdir foo.proto");
+ ExpectErrorText("$tmpdir/foo.bin: No such file or directory\n");
+}
+
+TEST_F(CommandLineInterfaceTest, ProtoPathAndDescriptorSetIn_CompileFiles) {
+ // Test what happens if a proto is in a --descriptor_set_in and also exists
+ // on disk.
+ FileDescriptorSet file_descriptor_set;
+
+ // NOTE: This file desc SHOULD be different from the one created as a temp
+ // to make it easier to test that the file was output instead of the
+ // contents of the --descriptor_set_in file.
+ FileDescriptorProto* file_descriptor_proto = file_descriptor_set.add_file();
+ file_descriptor_proto->set_name("foo.proto");
+ file_descriptor_proto->add_message_type()->set_name("Foo");
+
+ WriteDescriptorSet("foo.bin", &file_descriptor_set);
+
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "message FooBar { required string foo_message = 1; }\n");
+
+ Run("protocol_compiler --descriptor_set_out=$tmpdir/descriptor_set "
+ "--descriptor_set_in=$tmpdir/foo.bin "
+ "--include_source_info "
+ "--proto_path=$tmpdir foo.proto");
+
+ ExpectNoErrors();
+
+ FileDescriptorSet descriptor_set;
+ ReadDescriptorSet("descriptor_set", &descriptor_set);
+
+ EXPECT_EQ(1, descriptor_set.file_size());
+ EXPECT_EQ("foo.proto", descriptor_set.file(0).name());
+ // Descriptor set SHOULD have source code info.
+ EXPECT_TRUE(descriptor_set.file(0).has_source_code_info());
+
+ EXPECT_EQ("FooBar", descriptor_set.file(0).message_type(0).name());
+ EXPECT_EQ("foo_message",
+ descriptor_set.file(0).message_type(0).field(0).name());
+}
+
+TEST_F(CommandLineInterfaceTest, ProtoPathAndDependencyOut) {
+ Run("protocol_compiler --test_out=$tmpdir "
+ "--dependency_out=$tmpdir/manifest "
+ "--descriptor_set_in=$tmpdir/foo.bin foo.proto");
+ ExpectErrorText(
+ "--descriptor_set_in cannot be used with --dependency_out.\n");
+
+ Run("protocol_compiler --test_out=$tmpdir "
+ "--descriptor_set_in=$tmpdir/foo.bin "
+ "--dependency_out=$tmpdir/manifest foo.proto");
+ ExpectErrorText(
+ "--dependency_out cannot be used with --descriptor_set_in.\n");
+}
+
+TEST_F(CommandLineInterfaceTest, MissingInputError) {
+ // Test that we get an error if no inputs are given.
+
+ Run("protocol_compiler --test_out=$tmpdir "
+ "--proto_path=$tmpdir");
+
+ ExpectErrorText("Missing input file.\n");
+}
+
+TEST_F(CommandLineInterfaceTest, MissingOutputError) {
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "message Foo {}\n");
+
+ Run("protocol_compiler --proto_path=$tmpdir foo.proto");
+
+ ExpectErrorText("Missing output directives.\n");
+}
+
+TEST_F(CommandLineInterfaceTest, OutputWriteError) {
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "message Foo {}\n");
+
+ std::string output_file =
+ MockCodeGenerator::GetOutputFileName("test_generator", "foo.proto");
+
+ // Create a directory blocking our output location.
+ CreateTempDir(output_file);
+
+ Run("protocol_compiler --test_out=$tmpdir "
+ "--proto_path=$tmpdir foo.proto");
+
+ // MockCodeGenerator no longer detects an error because we actually write to
+ // an in-memory location first, then dump to disk at the end. This is no
+ // big deal.
+ // ExpectErrorSubstring("MockCodeGenerator detected write error.");
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ // Windows with MSVCRT.dll produces EPERM instead of EISDIR.
+ if (HasAlternateErrorSubstring(output_file + ": Permission denied")) {
+ return;
+ }
+#endif
+
+ ExpectErrorSubstring(output_file + ": Is a directory");
+}
+
+TEST_F(CommandLineInterfaceTest, PluginOutputWriteError) {
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "message Foo {}\n");
+
+ std::string output_file =
+ MockCodeGenerator::GetOutputFileName("test_plugin", "foo.proto");
+
+ // Create a directory blocking our output location.
+ CreateTempDir(output_file);
+
+ Run("protocol_compiler --plug_out=$tmpdir "
+ "--proto_path=$tmpdir foo.proto");
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ // Windows with MSVCRT.dll produces EPERM instead of EISDIR.
+ if (HasAlternateErrorSubstring(output_file + ": Permission denied")) {
+ return;
+ }
+#endif
+
+ ExpectErrorSubstring(output_file + ": Is a directory");
+}
+
+TEST_F(CommandLineInterfaceTest, OutputDirectoryNotFoundError) {
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "message Foo {}\n");
+
+ Run("protocol_compiler --test_out=$tmpdir/nosuchdir "
+ "--proto_path=$tmpdir foo.proto");
+
+ ExpectErrorSubstring("nosuchdir/: No such file or directory");
+}
+
+TEST_F(CommandLineInterfaceTest, PluginOutputDirectoryNotFoundError) {
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "message Foo {}\n");
+
+ Run("protocol_compiler --plug_out=$tmpdir/nosuchdir "
+ "--proto_path=$tmpdir foo.proto");
+
+ ExpectErrorSubstring("nosuchdir/: No such file or directory");
+}
+
+TEST_F(CommandLineInterfaceTest, OutputDirectoryIsFileError) {
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "message Foo {}\n");
+
+ Run("protocol_compiler --test_out=$tmpdir/foo.proto "
+ "--proto_path=$tmpdir foo.proto");
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ // Windows with MSVCRT.dll produces EINVAL instead of ENOTDIR.
+ if (HasAlternateErrorSubstring("foo.proto/: Invalid argument")) {
+ return;
+ }
+#endif
+
+ ExpectErrorSubstring("foo.proto/: Not a directory");
+}
+
+TEST_F(CommandLineInterfaceTest, GeneratorError) {
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "message MockCodeGenerator_Error {}\n");
+
+ Run("protocol_compiler --test_out=$tmpdir "
+ "--proto_path=$tmpdir foo.proto");
+
+ ExpectErrorSubstring(
+ "--test_out: foo.proto: Saw message type MockCodeGenerator_Error.");
+}
+
+TEST_F(CommandLineInterfaceTest, GeneratorPluginError) {
+ // Test a generator plugin that returns an error.
+
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "message MockCodeGenerator_Error {}\n");
+
+ Run("protocol_compiler --plug_out=TestParameter:$tmpdir "
+ "--proto_path=$tmpdir foo.proto");
+
+ ExpectErrorSubstring(
+ "--plug_out: foo.proto: Saw message type MockCodeGenerator_Error.");
+}
+
+TEST_F(CommandLineInterfaceTest, GeneratorPluginFail) {
+ // Test a generator plugin that exits with an error code.
+
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "message MockCodeGenerator_Exit {}\n");
+
+ Run("protocol_compiler --plug_out=TestParameter:$tmpdir "
+ "--proto_path=$tmpdir foo.proto");
+
+ ExpectErrorSubstring("Saw message type MockCodeGenerator_Exit.");
+ ExpectErrorSubstring(
+ "--plug_out: prefix-gen-plug: Plugin failed with status code 123.");
+}
+
+TEST_F(CommandLineInterfaceTest, GeneratorPluginCrash) {
+ // Test a generator plugin that crashes.
+
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "message MockCodeGenerator_Abort {}\n");
+
+ Run("protocol_compiler --plug_out=TestParameter:$tmpdir "
+ "--proto_path=$tmpdir foo.proto");
+
+ ExpectErrorSubstring("Saw message type MockCodeGenerator_Abort.");
+
+#ifdef _WIN32
+ // Windows doesn't have signals. It looks like abort()ing causes the process
+ // to exit with status code 3, but let's not depend on the exact number here.
+ ExpectErrorSubstring(
+ "--plug_out: prefix-gen-plug: Plugin failed with status code");
+#else
+ // Don't depend on the exact signal number.
+ ExpectErrorSubstring("--plug_out: prefix-gen-plug: Plugin killed by signal");
+#endif
+}
+
+TEST_F(CommandLineInterfaceTest, PluginReceivesSourceCodeInfo) {
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "message MockCodeGenerator_HasSourceCodeInfo {}\n");
+
+ Run("protocol_compiler --plug_out=$tmpdir --proto_path=$tmpdir foo.proto");
+
+ ExpectErrorSubstring(
+ "Saw message type MockCodeGenerator_HasSourceCodeInfo: 1.");
+}
+
+TEST_F(CommandLineInterfaceTest, PluginReceivesJsonName) {
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "message MockCodeGenerator_HasJsonName {\n"
+ " optional int32 value = 1;\n"
+ "}\n");
+
+ Run("protocol_compiler --plug_out=$tmpdir --proto_path=$tmpdir foo.proto");
+
+ ExpectErrorSubstring("Saw json_name: 1");
+}
+
+TEST_F(CommandLineInterfaceTest, PluginReceivesCompilerVersion) {
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "message MockCodeGenerator_ShowVersionNumber {\n"
+ " optional int32 value = 1;\n"
+ "}\n");
+
+ Run("protocol_compiler --plug_out=$tmpdir --proto_path=$tmpdir foo.proto");
+
+ ExpectErrorSubstring(StringPrintf("Saw compiler_version: %d %s",
+ GOOGLE_PROTOBUF_VERSION,
+ GOOGLE_PROTOBUF_VERSION_SUFFIX));
+}
+
+TEST_F(CommandLineInterfaceTest, GeneratorPluginNotFound) {
+ // Test what happens if the plugin isn't found.
+
+ CreateTempFile("error.proto",
+ "syntax = \"proto2\";\n"
+ "message Foo {}\n");
+
+ Run("protocol_compiler --badplug_out=TestParameter:$tmpdir "
+ "--plugin=prefix-gen-badplug=no_such_file "
+ "--proto_path=$tmpdir error.proto");
+
+#ifdef _WIN32
+ ExpectErrorSubstring("--badplug_out: prefix-gen-badplug: " +
+ Subprocess::Win32ErrorMessage(ERROR_FILE_NOT_FOUND));
+#else
+ // Error written to stdout by child process after exec() fails.
+ ExpectErrorSubstring("no_such_file: program not found or is not executable");
+
+ ExpectErrorSubstring(
+ "Please specify a program using absolute path or make sure "
+ "the program is available in your PATH system variable");
+
+ // Error written by parent process when child fails.
+ ExpectErrorSubstring(
+ "--badplug_out: prefix-gen-badplug: Plugin failed with status code 1.");
+#endif
+}
+
+TEST_F(CommandLineInterfaceTest, GeneratorPluginNotAllowed) {
+ // Test what happens if plugins aren't allowed.
+
+ CreateTempFile("error.proto",
+ "syntax = \"proto2\";\n"
+ "message Foo {}\n");
+
+ DisallowPlugins();
+ Run("protocol_compiler --plug_out=TestParameter:$tmpdir "
+ "--proto_path=$tmpdir error.proto");
+
+ ExpectErrorSubstring("Unknown flag: --plug_out");
+}
+
+TEST_F(CommandLineInterfaceTest, HelpText) {
+ Run("test_exec_name --help");
+
+ ExpectCapturedStdoutSubstringWithZeroReturnCode("Usage: test_exec_name ");
+ ExpectCapturedStdoutSubstringWithZeroReturnCode("--test_out=OUT_DIR");
+ ExpectCapturedStdoutSubstringWithZeroReturnCode("Test output.");
+ ExpectCapturedStdoutSubstringWithZeroReturnCode("--alt_out=OUT_DIR");
+ ExpectCapturedStdoutSubstringWithZeroReturnCode("Alt output.");
+}
+
+TEST_F(CommandLineInterfaceTest, GccFormatErrors) {
+ // Test --error_format=gcc (which is the default, but we want to verify
+ // that it can be set explicitly).
+
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "badsyntax\n");
+
+ Run("protocol_compiler --test_out=$tmpdir "
+ "--proto_path=$tmpdir --error_format=gcc foo.proto");
+
+ ExpectErrorText(
+ "foo.proto:2:1: Expected top-level statement (e.g. \"message\").\n");
+}
+
+TEST_F(CommandLineInterfaceTest, MsvsFormatErrors) {
+ // Test --error_format=msvs
+
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "badsyntax\n");
+
+ Run("protocol_compiler --test_out=$tmpdir "
+ "--proto_path=$tmpdir --error_format=msvs foo.proto");
+
+ ExpectErrorText(
+ "$tmpdir/foo.proto(2) : error in column=1: Expected top-level statement "
+ "(e.g. \"message\").\n");
+}
+
+TEST_F(CommandLineInterfaceTest, InvalidErrorFormat) {
+ // Test invalid --error_format
+
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "badsyntax\n");
+
+ Run("protocol_compiler --test_out=$tmpdir "
+ "--proto_path=$tmpdir --error_format=invalid foo.proto");
+
+ ExpectErrorText("Unknown error format: invalid\n");
+}
+
+TEST_F(CommandLineInterfaceTest, Warnings) {
+ // Test --fatal_warnings.
+
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "import \"bar.proto\";\n");
+ CreateTempFile("bar.proto", "syntax = \"proto2\";\n");
+
+ Run("protocol_compiler --test_out=$tmpdir "
+ "--proto_path=$tmpdir foo.proto");
+ ExpectCapturedStderrSubstringWithZeroReturnCode(
+ "foo.proto:2:1: warning: Import bar.proto is unused.");
+
+ Run("protocol_compiler --test_out=$tmpdir --fatal_warnings "
+ "--proto_path=$tmpdir foo.proto");
+ ExpectErrorSubstring("foo.proto:2:1: warning: Import bar.proto is unused.");
+}
+
+// -------------------------------------------------------------------
+// Flag parsing tests
+
+TEST_F(CommandLineInterfaceTest, ParseSingleCharacterFlag) {
+ // Test that a single-character flag works.
+
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "message Foo {}\n");
+
+ Run("protocol_compiler -t$tmpdir "
+ "--proto_path=$tmpdir foo.proto");
+
+ ExpectNoErrors();
+ ExpectGenerated("test_generator", "", "foo.proto", "Foo");
+}
+
+TEST_F(CommandLineInterfaceTest, ParseSpaceDelimitedValue) {
+ // Test that separating the flag value with a space works.
+
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "message Foo {}\n");
+
+ Run("protocol_compiler --test_out $tmpdir "
+ "--proto_path=$tmpdir foo.proto");
+
+ ExpectNoErrors();
+ ExpectGenerated("test_generator", "", "foo.proto", "Foo");
+}
+
+TEST_F(CommandLineInterfaceTest, ParseSingleCharacterSpaceDelimitedValue) {
+ // Test that separating the flag value with a space works for
+ // single-character flags.
+
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "message Foo {}\n");
+
+ Run("protocol_compiler -t $tmpdir "
+ "--proto_path=$tmpdir foo.proto");
+
+ ExpectNoErrors();
+ ExpectGenerated("test_generator", "", "foo.proto", "Foo");
+}
+
+TEST_F(CommandLineInterfaceTest, MissingValueError) {
+ // Test that we get an error if a flag is missing its value.
+
+ Run("protocol_compiler --test_out --proto_path=$tmpdir foo.proto");
+
+ ExpectErrorText("Missing value for flag: --test_out\n");
+}
+
+TEST_F(CommandLineInterfaceTest, MissingValueAtEndError) {
+ // Test that we get an error if the last argument is a flag requiring a
+ // value.
+
+ Run("protocol_compiler --test_out");
+
+ ExpectErrorText("Missing value for flag: --test_out\n");
+}
+
+TEST_F(CommandLineInterfaceTest, Proto3OptionalDisallowedNoCodegenSupport) {
+ CreateTempFile("google/foo.proto",
+ "syntax = \"proto3\";\n"
+ "message Foo {\n"
+ " optional int32 i = 1;\n"
+ "}\n");
+
+ CreateGeneratorWithMissingFeatures("--no_proto3_optional_out",
+ "Doesn't support proto3 optional",
+ CodeGenerator::FEATURE_PROTO3_OPTIONAL);
+
+ Run("protocol_compiler --experimental_allow_proto3_optional "
+ "--proto_path=$tmpdir google/foo.proto --no_proto3_optional_out=$tmpdir");
+
+ ExpectErrorSubstring(
+ "code generator --no_proto3_optional_out hasn't been updated to support "
+ "optional fields in proto3");
+}
+
+TEST_F(CommandLineInterfaceTest, Proto3OptionalAllowWithFlag) {
+ CreateTempFile("google/foo.proto",
+ "syntax = \"proto3\";\n"
+ "message Foo {\n"
+ " optional int32 i = 1;\n"
+ "}\n");
+
+ Run("protocol_compiler --experimental_allow_proto3_optional "
+ "--proto_path=$tmpdir google/foo.proto --test_out=$tmpdir");
+ ExpectNoErrors();
+}
+
+TEST_F(CommandLineInterfaceTest, PrintFreeFieldNumbers) {
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "package foo;\n"
+ "message Foo {\n"
+ " optional int32 a = 2;\n"
+ " optional string b = 4;\n"
+ " optional string c = 5;\n"
+ " optional int64 d = 8;\n"
+ " optional double e = 10;\n"
+ "}\n");
+ CreateTempFile("bar.proto",
+ "syntax = \"proto2\";\n"
+ "message Bar {\n"
+ " optional int32 a = 2;\n"
+ " extensions 4 to 5;\n"
+ " optional int64 d = 8;\n"
+ " extensions 10;\n"
+ "}\n");
+ CreateTempFile("baz.proto",
+ "syntax = \"proto2\";\n"
+ "message Baz {\n"
+ " optional int32 a = 2;\n"
+ " optional int64 d = 8;\n"
+ " extensions 15 to max;\n" // unordered.
+ " extensions 13;\n"
+ " extensions 10 to 12;\n"
+ " extensions 5;\n"
+ " extensions 4;\n"
+ "}\n");
+ CreateTempFile(
+ "quz.proto",
+ "syntax = \"proto2\";\n"
+ "message Quz {\n"
+ " message Foo {}\n" // nested message
+ " optional int32 a = 2;\n"
+ " optional group C = 4 {\n"
+ " optional int32 d = 5;\n"
+ " }\n"
+ " extensions 8 to 10;\n"
+ " optional group E = 11 {\n"
+ " optional int32 f = 9;\n" // explicitly reuse extension range 8-10
+ " optional group G = 15 {\n" // nested group
+ " message Foo {}\n" // nested message inside nested group
+ " }\n"
+ " }\n"
+ "}\n");
+
+ Run("protocol_compiler --print_free_field_numbers --proto_path=$tmpdir "
+ "foo.proto bar.proto baz.proto quz.proto");
+
+ ExpectNoErrors();
+
+ // TODO(jieluo): Cygwin doesn't work well if we try to capture stderr and
+ // stdout at the same time. Need to figure out why and add this test back
+ // for Cygwin.
+#if !defined(__CYGWIN__)
+ ExpectCapturedStdout(
+ "foo.Foo free: 1 3 6-7 9 11-INF\n"
+ "Bar free: 1 3 6-7 9 11-INF\n"
+ "Baz free: 1 3 6-7 9 14\n"
+ "Quz.Foo free: 1-INF\n"
+ "Quz.E.G.Foo free: 1-INF\n"
+ "Quz free: 1 3 6-7 12-14 16-INF\n");
+#endif
+}
+
+// ===================================================================
+
+// Test for --encode and --decode. Note that it would be easier to do this
+// test as a shell script, but we'd like to be able to run the test on
+// platforms that don't have a Bourne-compatible shell available (especially
+// Windows/MSVC).
+
+enum EncodeDecodeTestMode { PROTO_PATH, DESCRIPTOR_SET_IN };
+
+class EncodeDecodeTest : public testing::TestWithParam<EncodeDecodeTestMode> {
+ protected:
+ virtual void SetUp() {
+ WriteUnittestProtoDescriptorSet();
+ duped_stdin_ = dup(STDIN_FILENO);
+ }
+
+ virtual void TearDown() {
+ dup2(duped_stdin_, STDIN_FILENO);
+ close(duped_stdin_);
+ }
+
+ void RedirectStdinFromText(const std::string& input) {
+ std::string filename = TestTempDir() + "/test_stdin";
+ GOOGLE_CHECK_OK(File::SetContents(filename, input, true));
+ GOOGLE_CHECK(RedirectStdinFromFile(filename));
+ }
+
+ bool RedirectStdinFromFile(const std::string& filename) {
+ int fd = open(filename.c_str(), O_RDONLY);
+ if (fd < 0) return false;
+ dup2(fd, STDIN_FILENO);
+ close(fd);
+ return true;
+ }
+
+ // Remove '\r' characters from text.
+ std::string StripCR(const std::string& text) {
+ std::string result;
+
+ for (int i = 0; i < text.size(); i++) {
+ if (text[i] != '\r') {
+ result.push_back(text[i]);
+ }
+ }
+
+ return result;
+ }
+
+ enum Type { TEXT, BINARY };
+ enum ReturnCode { SUCCESS, ERROR };
+
+ bool Run(const std::string& command, bool specify_proto_files = true) {
+ std::vector<std::string> args;
+ args.push_back("protoc");
+ for (StringPiece split_piece :
+ Split(command, " ", true)) {
+ args.push_back(std::string(split_piece));
+ }
+ if (specify_proto_files) {
+ switch (GetParam()) {
+ case PROTO_PATH:
+ args.push_back("--proto_path=" + TestUtil::TestSourceDir());
+ break;
+ case DESCRIPTOR_SET_IN:
+ args.push_back(StrCat("--descriptor_set_in=",
+ unittest_proto_descriptor_set_filename_));
+ break;
+ default:
+ ADD_FAILURE() << "unexpected EncodeDecodeTestMode: " << GetParam();
+ }
+ }
+
+ std::unique_ptr<const char*[]> argv(new const char*[args.size()]);
+ for (int i = 0; i < args.size(); i++) {
+ argv[i] = args[i].c_str();
+ }
+
+ CommandLineInterface cli;
+
+ CaptureTestStdout();
+ CaptureTestStderr();
+
+ int result = cli.Run(args.size(), argv.get());
+
+ captured_stdout_ = GetCapturedTestStdout();
+ captured_stderr_ = GetCapturedTestStderr();
+
+ return result == 0;
+ }
+
+ void ExpectStdoutMatchesBinaryFile(const std::string& filename) {
+ std::string expected_output;
+ GOOGLE_CHECK_OK(File::GetContents(filename, &expected_output, true));
+
+ // Don't use EXPECT_EQ because we don't want to print raw binary data to
+ // stdout on failure.
+ EXPECT_TRUE(captured_stdout_ == expected_output);
+ }
+
+ void ExpectStdoutMatchesTextFile(const std::string& filename) {
+ std::string expected_output;
+ GOOGLE_CHECK_OK(File::GetContents(filename, &expected_output, true));
+
+ ExpectStdoutMatchesText(expected_output);
+ }
+
+ void ExpectStdoutMatchesText(const std::string& expected_text) {
+ EXPECT_EQ(StripCR(expected_text), StripCR(captured_stdout_));
+ }
+
+ void ExpectStderrMatchesText(const std::string& expected_text) {
+ EXPECT_EQ(StripCR(expected_text), StripCR(captured_stderr_));
+ }
+
+ void ExpectStderrContainsText(const std::string& expected_text) {
+ EXPECT_NE(StripCR(captured_stderr_).find(StripCR(expected_text)),
+ std::string::npos);
+ }
+
+ private:
+ void WriteUnittestProtoDescriptorSet() {
+ unittest_proto_descriptor_set_filename_ =
+ TestTempDir() + "/unittest_proto_descriptor_set.bin";
+ FileDescriptorSet file_descriptor_set;
+ protobuf_unittest::TestAllTypes test_all_types;
+ test_all_types.descriptor()->file()->CopyTo(file_descriptor_set.add_file());
+
+ protobuf_unittest_import::ImportMessage import_message;
+ import_message.descriptor()->file()->CopyTo(file_descriptor_set.add_file());
+
+ protobuf_unittest_import::PublicImportMessage public_import_message;
+ public_import_message.descriptor()->file()->CopyTo(
+ file_descriptor_set.add_file());
+ GOOGLE_DCHECK(file_descriptor_set.IsInitialized());
+
+ std::string binary_proto;
+ GOOGLE_CHECK(file_descriptor_set.SerializeToString(&binary_proto));
+ GOOGLE_CHECK_OK(File::SetContents(unittest_proto_descriptor_set_filename_,
+ binary_proto, true));
+ }
+
+ int duped_stdin_;
+ std::string captured_stdout_;
+ std::string captured_stderr_;
+ std::string unittest_proto_descriptor_set_filename_;
+};
+
+TEST_P(EncodeDecodeTest, Encode) {
+ RedirectStdinFromFile(TestUtil::GetTestDataPath(
+ "net/proto2/internal/"
+ "testdata/text_format_unittest_data_oneof_implemented.txt"));
+ std::string args;
+ if (GetParam() != DESCRIPTOR_SET_IN) {
+ args.append(
+ TestUtil::MaybeTranslatePath("net/proto2/internal/unittest.proto"));
+ }
+ EXPECT_TRUE(Run(args + " --encode=protobuf_unittest.TestAllTypes"));
+ ExpectStdoutMatchesBinaryFile(TestUtil::GetTestDataPath(
+ "net/proto2/internal/testdata/golden_message_oneof_implemented"));
+ ExpectStderrMatchesText("");
+}
+
+TEST_P(EncodeDecodeTest, Decode) {
+ RedirectStdinFromFile(TestUtil::GetTestDataPath(
+ "net/proto2/internal/testdata/golden_message_oneof_implemented"));
+ EXPECT_TRUE(
+ Run(TestUtil::MaybeTranslatePath("net/proto2/internal/unittest.proto") +
+ " --decode=protobuf_unittest.TestAllTypes"));
+ ExpectStdoutMatchesTextFile(TestUtil::GetTestDataPath(
+ "net/proto2/internal/"
+ "testdata/text_format_unittest_data_oneof_implemented.txt"));
+ ExpectStderrMatchesText("");
+}
+
+TEST_P(EncodeDecodeTest, Partial) {
+ RedirectStdinFromText("");
+ EXPECT_TRUE(
+ Run(TestUtil::MaybeTranslatePath("net/proto2/internal/unittest.proto") +
+ " --encode=protobuf_unittest.TestRequired"));
+ ExpectStdoutMatchesText("");
+ ExpectStderrMatchesText(
+ "warning: Input message is missing required fields: a, b, c\n");
+}
+
+TEST_P(EncodeDecodeTest, DecodeRaw) {
+ protobuf_unittest::TestAllTypes message;
+ message.set_optional_int32(123);
+ message.set_optional_string("foo");
+ std::string data;
+ message.SerializeToString(&data);
+
+ RedirectStdinFromText(data);
+ EXPECT_TRUE(Run("--decode_raw", /*specify_proto_files=*/false));
+ ExpectStdoutMatchesText(
+ "1: 123\n"
+ "14: \"foo\"\n");
+ ExpectStderrMatchesText("");
+}
+
+TEST_P(EncodeDecodeTest, UnknownType) {
+ EXPECT_FALSE(
+ Run(TestUtil::MaybeTranslatePath("net/proto2/internal/unittest.proto") +
+ " --encode=NoSuchType"));
+ ExpectStdoutMatchesText("");
+ ExpectStderrMatchesText("Type not defined: NoSuchType\n");
+}
+
+TEST_P(EncodeDecodeTest, ProtoParseError) {
+ EXPECT_FALSE(
+ Run("net/proto2/internal/no_such_file.proto "
+ "--encode=NoSuchType"));
+ ExpectStdoutMatchesText("");
+ ExpectStderrContainsText(
+ "net/proto2/internal/no_such_file.proto: No such file or directory\n");
+}
+
+TEST_P(EncodeDecodeTest, EncodeDeterministicOutput) {
+ RedirectStdinFromFile(TestUtil::GetTestDataPath(
+ "net/proto2/internal/"
+ "testdata/text_format_unittest_data_oneof_implemented.txt"));
+ std::string args;
+ if (GetParam() != DESCRIPTOR_SET_IN) {
+ args.append(
+ TestUtil::MaybeTranslatePath("net/proto2/internal/unittest.proto"));
+ }
+ EXPECT_TRUE(Run(
+ args + " --encode=protobuf_unittest.TestAllTypes --deterministic_output"));
+ ExpectStdoutMatchesBinaryFile(TestUtil::GetTestDataPath(
+ "net/proto2/internal/testdata/golden_message_oneof_implemented"));
+ ExpectStderrMatchesText("");
+}
+
+TEST_P(EncodeDecodeTest, DecodeDeterministicOutput) {
+ RedirectStdinFromFile(TestUtil::GetTestDataPath(
+ "net/proto2/internal/testdata/golden_message_oneof_implemented"));
+ EXPECT_FALSE(
+ Run(TestUtil::MaybeTranslatePath("net/proto2/internal/unittest.proto") +
+ " --decode=protobuf_unittest.TestAllTypes --deterministic_output"));
+ ExpectStderrMatchesText(
+ "Can only use --deterministic_output with --encode.\n");
+}
+
+INSTANTIATE_TEST_SUITE_P(FileDescriptorSetSource, EncodeDecodeTest,
+ testing::Values(PROTO_PATH, DESCRIPTOR_SET_IN));
+} // anonymous namespace
+
+#endif // !GOOGLE_PROTOBUF_HEAP_CHECK_DRACONIAN
+
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc b/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc
new file mode 100644
index 00000000..e13b29f9
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc
@@ -0,0 +1,195 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 test insures that net/proto2/proto/descriptor.pb.{h,cc} match exactly
+// what would be generated by the protocol compiler. These files are not
+// generated automatically at build time because they are compiled into the
+// protocol compiler itself. So, if they were auto-generated, you'd have a
+// chicken-and-egg problem.
+//
+// If this test fails, run the script
+// "generate_descriptor_proto.sh" and add
+// descriptor.pb.{h,cc} to your changelist.
+
+#include <map>
+
+#include <testing/file.h>
+#include <testing/file.h>
+#include <compiler/cpp/cpp_helpers.h>
+#include <compiler/cpp/cpp_generator.h>
+#include <compiler/importer.h>
+#include <test_util2.h>
+#include <io/zero_copy_stream_impl.h>
+#include <descriptor.h>
+#include <stubs/strutil.h>
+#include <testing/googletest.h>
+#include <gtest/gtest.h>
+#include <stubs/substitute.h>
+#include <stubs/map_util.h>
+#include <stubs/stl_util.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+namespace {
+
+class MockErrorCollector : public MultiFileErrorCollector {
+ public:
+ MockErrorCollector() {}
+ ~MockErrorCollector() {}
+
+ std::string text_;
+
+ // implements ErrorCollector ---------------------------------------
+ void AddError(const std::string& filename, int line, int column,
+ const std::string& message) {
+ strings::SubstituteAndAppend(&text_, "$0:$1:$2: $3\n", filename, line, column,
+ message);
+ }
+};
+
+class MockGeneratorContext : public GeneratorContext {
+ public:
+ void ExpectFileMatches(const std::string& virtual_filename,
+ const std::string& physical_filename) {
+ auto it = files_.find(virtual_filename);
+ ASSERT_TRUE(it != files_.end())
+ << "Generator failed to generate file: " << virtual_filename;
+
+ std::string expected_contents = *it->second;
+ std::string actual_contents;
+ GOOGLE_CHECK_OK(
+ File::GetContents(TestUtil::TestSourceDir() + "/" + physical_filename,
+ &actual_contents, true))
+ << physical_filename;
+ CleanStringLineEndings(&actual_contents, false);
+
+#ifdef WRITE_FILES // Define to debug mismatched files.
+ GOOGLE_CHECK_OK(File::SetContents("/tmp/expected.cc", expected_contents,
+ true));
+ GOOGLE_CHECK_OK(
+ File::SetContents("/tmp/actual.cc", actual_contents, true));
+#endif
+
+ ASSERT_EQ(expected_contents, actual_contents)
+ << physical_filename
+ << " needs to be regenerated. Please run "
+ "generate_descriptor_proto.sh. "
+ "Then add this file to your CL.";
+ }
+
+ // implements GeneratorContext --------------------------------------
+
+ virtual io::ZeroCopyOutputStream* Open(const std::string& filename) {
+ auto& map_slot = files_[filename];
+ map_slot.reset(new std::string);
+ return new io::StringOutputStream(map_slot.get());
+ }
+
+ private:
+ std::map<std::string, std::unique_ptr<std::string>> files_;
+};
+
+const char kDescriptorParameter[] = "dllexport_decl=PROTOBUF_EXPORT";
+const char kPluginParameter[] = "dllexport_decl=PROTOC_EXPORT";
+
+
+const char* test_protos[][2] = {
+ {"google/protobuf/descriptor", kDescriptorParameter},
+ {"google/protobuf/compiler/plugin", kPluginParameter},
+};
+
+TEST(BootstrapTest, GeneratedFilesMatch) {
+ // We need a mapping from the actual file to virtual and actual path
+ // of the data to compare to.
+ std::map<std::string, std::string> vpath_map;
+ std::map<std::string, std::string> rpath_map;
+ rpath_map["third_party/protobuf/src/google/protobuf/test_messages_proto2"] =
+ "net/proto2/z_generated_example/test_messages_proto2";
+ rpath_map["third_party/protobuf/src/google/protobuf/test_messages_proto3"] =
+ "net/proto2/z_generated_example/test_messages_proto3";
+ rpath_map["net/proto2/internal/proto2_weak"] =
+ "net/proto2/z_generated_example/proto2_weak";
+
+ DiskSourceTree source_tree;
+ source_tree.MapPath("", TestUtil::TestSourceDir());
+
+ for (auto file_parameter : test_protos) {
+ MockErrorCollector error_collector;
+ Importer importer(&source_tree, &error_collector);
+ const FileDescriptor* file =
+ importer.Import(file_parameter[0] + std::string(".proto"));
+ ASSERT_TRUE(file != nullptr)
+ << "Can't import file " << file_parameter[0] + std::string(".proto")
+ << "\n";
+ EXPECT_EQ("", error_collector.text_);
+ CppGenerator generator;
+ MockGeneratorContext context;
+#ifdef GOOGLE_PROTOBUF_RUNTIME_INCLUDE_BASE
+ generator.set_opensource_runtime(true);
+ generator.set_runtime_include_base(GOOGLE_PROTOBUF_RUNTIME_INCLUDE_BASE);
+#endif
+ std::string error;
+ ASSERT_TRUE(generator.Generate(file, file_parameter[1], &context, &error));
+
+ std::string vpath =
+ FindWithDefault(vpath_map, file_parameter[0], file_parameter[0]);
+ std::string rpath =
+ FindWithDefault(rpath_map, file_parameter[0], file_parameter[0]);
+ context.ExpectFileMatches(vpath + ".pb.cc", rpath + ".pb.cc");
+ context.ExpectFileMatches(vpath + ".pb.h", rpath + ".pb.h");
+ }
+}
+
+// test Generate in cpp_generator.cc
+TEST(BootstrapTest, OptionNotExist) {
+ cpp::CppGenerator generator;
+ DescriptorPool pool;
+ GeneratorContext* generator_context = nullptr;
+ std::string parameter = "aaa";
+ std::string error;
+ ASSERT_FALSE(generator.Generate(
+ pool.FindFileByName("google/protobuf/descriptor.proto"), parameter,
+ generator_context, &error));
+ EXPECT_EQ(error, "Unknown generator option: " + parameter);
+}
+
+} // namespace
+
+} // namespace cpp
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_enum.cc b/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_enum.cc
new file mode 100644
index 00000000..e2bf2e6f
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_enum.cc
@@ -0,0 +1,438 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 <compiler/cpp/cpp_enum.h>
+
+#include <cstdint>
+#include <limits>
+#include <map>
+
+#include <compiler/cpp/cpp_helpers.h>
+#include <compiler/cpp/cpp_names.h>
+#include <io/printer.h>
+#include <stubs/strutil.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+namespace {
+// The GOOGLE_ARRAYSIZE constant is the max enum value plus 1. If the max enum value
+// is kint32max, GOOGLE_ARRAYSIZE will overflow. In such cases we should omit the
+// generation of the GOOGLE_ARRAYSIZE constant.
+bool ShouldGenerateArraySize(const EnumDescriptor* descriptor) {
+ int32_t max_value = descriptor->value(0)->number();
+ for (int i = 0; i < descriptor->value_count(); i++) {
+ if (descriptor->value(i)->number() > max_value) {
+ max_value = descriptor->value(i)->number();
+ }
+ }
+ return max_value != std::numeric_limits<int32_t>::max();
+}
+
+// Returns the number of unique numeric enum values. This is less than
+// descriptor->value_count() when there are aliased values.
+int CountUniqueValues(const EnumDescriptor* descriptor) {
+ std::set<int> values;
+ for (int i = 0; i < descriptor->value_count(); ++i) {
+ values.insert(descriptor->value(i)->number());
+ }
+ return values.size();
+}
+
+} // namespace
+
+EnumGenerator::EnumGenerator(const EnumDescriptor* descriptor,
+ const std::map<std::string, std::string>& vars,
+ const Options& options)
+ : descriptor_(descriptor),
+ classname_(ClassName(descriptor, false)),
+ options_(options),
+ generate_array_size_(ShouldGenerateArraySize(descriptor)),
+ variables_(vars) {
+ variables_["classname"] = classname_;
+ variables_["classtype"] = QualifiedClassName(descriptor_, options);
+ variables_["short_name"] = descriptor_->name();
+ variables_["nested_name"] = descriptor_->name();
+ variables_["resolved_name"] = ResolveKeyword(descriptor_->name());
+ variables_["prefix"] =
+ (descriptor_->containing_type() == NULL) ? "" : classname_ + "_";
+}
+
+EnumGenerator::~EnumGenerator() {}
+
+void EnumGenerator::GenerateDefinition(io::Printer* printer) {
+ Formatter format(printer, variables_);
+ format("enum ${1$$classname$$}$ : int {\n", descriptor_);
+ format.Indent();
+
+ const EnumValueDescriptor* min_value = descriptor_->value(0);
+ const EnumValueDescriptor* max_value = descriptor_->value(0);
+
+ for (int i = 0; i < descriptor_->value_count(); i++) {
+ auto format_value = format;
+ format_value.Set("name", EnumValueName(descriptor_->value(i)));
+ // In C++, an value of -2147483648 gets interpreted as the negative of
+ // 2147483648, and since 2147483648 can't fit in an integer, this produces a
+ // compiler warning. This works around that issue.
+ format_value.Set("number", Int32ToString(descriptor_->value(i)->number()));
+ format_value.Set("deprecation",
+ DeprecatedAttribute(options_, descriptor_->value(i)));
+
+ if (i > 0) format_value(",\n");
+ format_value("${1$$prefix$$name$$}$ $deprecation$= $number$",
+ descriptor_->value(i));
+
+ if (descriptor_->value(i)->number() < min_value->number()) {
+ min_value = descriptor_->value(i);
+ }
+ if (descriptor_->value(i)->number() > max_value->number()) {
+ max_value = descriptor_->value(i);
+ }
+ }
+
+ if (descriptor_->file()->syntax() == FileDescriptor::SYNTAX_PROTO3) {
+ // For new enum semantics: generate min and max sentinel values equal to
+ // INT32_MIN and INT32_MAX
+ if (descriptor_->value_count() > 0) format(",\n");
+ format(
+ "$classname$_$prefix$INT_MIN_SENTINEL_DO_NOT_USE_ = "
+ "std::numeric_limits<$int32$>::min(),\n"
+ "$classname$_$prefix$INT_MAX_SENTINEL_DO_NOT_USE_ = "
+ "std::numeric_limits<$int32$>::max()");
+ }
+
+ format.Outdent();
+ format("\n};\n");
+
+ format(
+ "$dllexport_decl $bool $classname$_IsValid(int value);\n"
+ "constexpr $classname$ ${1$$prefix$$short_name$_MIN$}$ = "
+ "$prefix$$2$;\n"
+ "constexpr $classname$ ${1$$prefix$$short_name$_MAX$}$ = "
+ "$prefix$$3$;\n",
+ descriptor_, EnumValueName(min_value), EnumValueName(max_value));
+
+ if (generate_array_size_) {
+ format(
+ "constexpr int ${1$$prefix$$short_name$_ARRAYSIZE$}$ = "
+ "$prefix$$short_name$_MAX + 1;\n\n",
+ descriptor_);
+ }
+
+ if (HasDescriptorMethods(descriptor_->file(), options_)) {
+ format(
+ "$dllexport_decl $const ::$proto_ns$::EnumDescriptor* "
+ "$classname$_descriptor();\n");
+ }
+
+ // The _Name and _Parse functions. The lite implementation is table-based, so
+ // we make sure to keep the tables hidden in the .cc file.
+ if (!HasDescriptorMethods(descriptor_->file(), options_)) {
+ format("const std::string& $classname$_Name($classname$ value);\n");
+ }
+ // The _Name() function accepts the enum type itself but also any integral
+ // type.
+ format(
+ "template<typename T>\n"
+ "inline const std::string& $classname$_Name(T enum_t_value) {\n"
+ " static_assert(::std::is_same<T, $classname$>::value ||\n"
+ " ::std::is_integral<T>::value,\n"
+ " \"Incorrect type passed to function $classname$_Name.\");\n");
+ if (HasDescriptorMethods(descriptor_->file(), options_)) {
+ format(
+ " return ::$proto_ns$::internal::NameOfEnum(\n"
+ " $classname$_descriptor(), enum_t_value);\n");
+ } else {
+ format(
+ " return $classname$_Name(static_cast<$classname$>(enum_t_value));\n");
+ }
+ format("}\n");
+
+ if (HasDescriptorMethods(descriptor_->file(), options_)) {
+ format(
+ "inline bool $classname$_Parse(\n"
+ " ::PROTOBUF_NAMESPACE_ID::ConstStringParam name, $classname$* "
+ "value) "
+ "{\n"
+ " return ::$proto_ns$::internal::ParseNamedEnum<$classname$>(\n"
+ " $classname$_descriptor(), name, value);\n"
+ "}\n");
+ } else {
+ format(
+ "bool $classname$_Parse(\n"
+ " ::PROTOBUF_NAMESPACE_ID::ConstStringParam name, $classname$* "
+ "value);\n");
+ }
+}
+
+void EnumGenerator::GenerateGetEnumDescriptorSpecializations(
+ io::Printer* printer) {
+ Formatter format(printer, variables_);
+ format(
+ "template <> struct is_proto_enum< $classtype$> : ::std::true_type "
+ "{};\n");
+ if (HasDescriptorMethods(descriptor_->file(), options_)) {
+ format(
+ "template <>\n"
+ "inline const EnumDescriptor* GetEnumDescriptor< $classtype$>() {\n"
+ " return $classtype$_descriptor();\n"
+ "}\n");
+ }
+}
+
+void EnumGenerator::GenerateSymbolImports(io::Printer* printer) const {
+ Formatter format(printer, variables_);
+ format("typedef $classname$ $resolved_name$;\n");
+
+ for (int j = 0; j < descriptor_->value_count(); j++) {
+ std::string deprecated_attr =
+ DeprecatedAttribute(options_, descriptor_->value(j));
+ format(
+ "$1$static constexpr $resolved_name$ ${2$$3$$}$ =\n"
+ " $classname$_$3$;\n",
+ deprecated_attr, descriptor_->value(j),
+ EnumValueName(descriptor_->value(j)));
+ }
+
+ format(
+ "static inline bool $nested_name$_IsValid(int value) {\n"
+ " return $classname$_IsValid(value);\n"
+ "}\n"
+ "static constexpr $resolved_name$ ${1$$nested_name$_MIN$}$ =\n"
+ " $classname$_$nested_name$_MIN;\n"
+ "static constexpr $resolved_name$ ${1$$nested_name$_MAX$}$ =\n"
+ " $classname$_$nested_name$_MAX;\n",
+ descriptor_);
+ if (generate_array_size_) {
+ format(
+ "static constexpr int ${1$$nested_name$_ARRAYSIZE$}$ =\n"
+ " $classname$_$nested_name$_ARRAYSIZE;\n",
+ descriptor_);
+ }
+
+ if (HasDescriptorMethods(descriptor_->file(), options_)) {
+ format(
+ "static inline const ::$proto_ns$::EnumDescriptor*\n"
+ "$nested_name$_descriptor() {\n"
+ " return $classname$_descriptor();\n"
+ "}\n");
+ }
+
+ format(
+ "template<typename T>\n"
+ "static inline const std::string& $nested_name$_Name(T enum_t_value) {\n"
+ " static_assert(::std::is_same<T, $resolved_name$>::value ||\n"
+ " ::std::is_integral<T>::value,\n"
+ " \"Incorrect type passed to function $nested_name$_Name.\");\n"
+ " return $classname$_Name(enum_t_value);\n"
+ "}\n");
+ format(
+ "static inline bool "
+ "$nested_name$_Parse(::PROTOBUF_NAMESPACE_ID::ConstStringParam name,\n"
+ " $resolved_name$* value) {\n"
+ " return $classname$_Parse(name, value);\n"
+ "}\n");
+}
+
+void EnumGenerator::GenerateMethods(int idx, io::Printer* printer) {
+ Formatter format(printer, variables_);
+ if (HasDescriptorMethods(descriptor_->file(), options_)) {
+ format(
+ "const ::$proto_ns$::EnumDescriptor* $classname$_descriptor() {\n"
+ " ::$proto_ns$::internal::AssignDescriptors(&$desc_table$);\n"
+ " return $file_level_enum_descriptors$[$1$];\n"
+ "}\n",
+ idx);
+ }
+
+ format(
+ "bool $classname$_IsValid(int value) {\n"
+ " switch (value) {\n");
+
+ // Multiple values may have the same number. Make sure we only cover
+ // each number once by first constructing a set containing all valid
+ // numbers, then printing a case statement for each element.
+
+ std::set<int> numbers;
+ for (int j = 0; j < descriptor_->value_count(); j++) {
+ const EnumValueDescriptor* value = descriptor_->value(j);
+ numbers.insert(value->number());
+ }
+
+ for (std::set<int>::iterator iter = numbers.begin(); iter != numbers.end();
+ ++iter) {
+ format(" case $1$:\n", Int32ToString(*iter));
+ }
+
+ format(
+ " return true;\n"
+ " default:\n"
+ " return false;\n"
+ " }\n"
+ "}\n"
+ "\n");
+
+ if (!HasDescriptorMethods(descriptor_->file(), options_)) {
+ // In lite mode (where descriptors are unavailable), we generate separate
+ // tables for mapping between enum names and numbers. The _entries table
+ // contains the bulk of the data and is sorted by name, while
+ // _entries_by_number is sorted by number and just contains pointers into
+ // _entries. The two tables allow mapping from name to number and number to
+ // name, both in time logarithmic in the number of enum entries. This could
+ // probably be made faster, but for now the tables are intended to be simple
+ // and compact.
+ //
+ // Enums with allow_alias = true support multiple entries with the same
+ // numerical value. In cases where there are multiple names for the same
+ // number, we treat the first name appearing in the .proto file as the
+ // canonical one.
+ std::map<std::string, int> name_to_number;
+ std::map<int, std::string> number_to_canonical_name;
+ for (int i = 0; i < descriptor_->value_count(); i++) {
+ const EnumValueDescriptor* value = descriptor_->value(i);
+ name_to_number.emplace(value->name(), value->number());
+ // The same number may appear with multiple names, so we use emplace() to
+ // let the first name win.
+ number_to_canonical_name.emplace(value->number(), value->name());
+ }
+
+ format(
+ "static ::$proto_ns$::internal::ExplicitlyConstructed<std::string> "
+ "$classname$_strings[$1$] = {};\n\n",
+ CountUniqueValues(descriptor_));
+
+ // We concatenate all the names for a given enum into one big string
+ // literal. If instead we store an array of string literals, the linker
+ // seems to put all enum strings for a given .proto file in the same
+ // section, which hinders its ability to strip out unused strings.
+ format("static const char $classname$_names[] =");
+ for (const auto& p : name_to_number) {
+ format("\n \"$1$\"", p.first);
+ }
+ format(";\n\n");
+
+ format(
+ "static const ::$proto_ns$::internal::EnumEntry $classname$_entries[] "
+ "= {\n");
+ int i = 0;
+ std::map<int, int> number_to_index;
+ int data_index = 0;
+ for (const auto& p : name_to_number) {
+ format(" { {$classname$_names + $1$, $2$}, $3$ },\n", data_index,
+ p.first.size(), p.second);
+ if (number_to_canonical_name[p.second] == p.first) {
+ number_to_index.emplace(p.second, i);
+ }
+ ++i;
+ data_index += p.first.size();
+ }
+
+ format(
+ "};\n"
+ "\n"
+ "static const int $classname$_entries_by_number[] = {\n");
+ for (const auto& p : number_to_index) {
+ format(" $1$, // $2$ -> $3$\n", p.second, p.first,
+ number_to_canonical_name[p.first]);
+ }
+ format(
+ "};\n"
+ "\n");
+
+ format(
+ "const std::string& $classname$_Name(\n"
+ " $classname$ value) {\n"
+ " static const bool dummy =\n"
+ " ::$proto_ns$::internal::InitializeEnumStrings(\n"
+ " $classname$_entries,\n"
+ " $classname$_entries_by_number,\n"
+ " $1$, $classname$_strings);\n"
+ " (void) dummy;\n"
+ " int idx = ::$proto_ns$::internal::LookUpEnumName(\n"
+ " $classname$_entries,\n"
+ " $classname$_entries_by_number,\n"
+ " $1$, value);\n"
+ " return idx == -1 ? ::$proto_ns$::internal::GetEmptyString() :\n"
+ " $classname$_strings[idx].get();\n"
+ "}\n",
+ CountUniqueValues(descriptor_));
+ format(
+ "bool $classname$_Parse(\n"
+ " ::PROTOBUF_NAMESPACE_ID::ConstStringParam name, $classname$* "
+ "value) "
+ "{\n"
+ " int int_value;\n"
+ " bool success = ::$proto_ns$::internal::LookUpEnumValue(\n"
+ " $classname$_entries, $1$, name, &int_value);\n"
+ " if (success) {\n"
+ " *value = static_cast<$classname$>(int_value);\n"
+ " }\n"
+ " return success;\n"
+ "}\n",
+ descriptor_->value_count());
+ }
+
+ if (descriptor_->containing_type() != NULL) {
+ std::string parent = ClassName(descriptor_->containing_type(), false);
+ // Before C++17, we must define the static constants which were
+ // declared in the header, to give the linker a place to put them.
+ // But MSVC++ pre-2015 and post-2017 (version 15.5+) insists that we not.
+ format(
+ "#if (__cplusplus < 201703) && "
+ "(!defined(_MSC_VER) || (_MSC_VER >= 1900 && _MSC_VER < 1912))\n");
+
+ for (int i = 0; i < descriptor_->value_count(); i++) {
+ format("constexpr $classname$ $1$::$2$;\n", parent,
+ EnumValueName(descriptor_->value(i)));
+ }
+ format(
+ "constexpr $classname$ $1$::$nested_name$_MIN;\n"
+ "constexpr $classname$ $1$::$nested_name$_MAX;\n",
+ parent);
+ if (generate_array_size_) {
+ format("constexpr int $1$::$nested_name$_ARRAYSIZE;\n", parent);
+ }
+
+ format(
+ "#endif // (__cplusplus < 201703) && "
+ "(!defined(_MSC_VER) || (_MSC_VER >= 1900 && _MSC_VER < 1912))\n");
+ }
+}
+
+} // namespace cpp
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_enum.h b/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_enum.h
new file mode 100644
index 00000000..19a2cbe5
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_enum.h
@@ -0,0 +1,105 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 GOOGLE_PROTOBUF_COMPILER_CPP_ENUM_H__
+#define GOOGLE_PROTOBUF_COMPILER_CPP_ENUM_H__
+
+#include <map>
+#include <set>
+#include <string>
+#include <compiler/cpp/cpp_options.h>
+#include <descriptor.h>
+
+namespace google {
+namespace protobuf {
+namespace io {
+class Printer; // printer.h
+}
+} // namespace protobuf
+} // namespace google
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+class EnumGenerator {
+ public:
+ // See generator.cc for the meaning of dllexport_decl.
+ EnumGenerator(const EnumDescriptor* descriptor,
+ const std::map<std::string, std::string>& vars,
+ const Options& options);
+ ~EnumGenerator();
+
+ // Generate header code defining the enum. This code should be placed
+ // within the enum's package namespace, but NOT within any class, even for
+ // nested enums.
+ void GenerateDefinition(io::Printer* printer);
+
+ // Generate specialization of GetEnumDescriptor<MyEnum>().
+ // Precondition: in ::google::protobuf namespace.
+ void GenerateGetEnumDescriptorSpecializations(io::Printer* printer);
+
+ // For enums nested within a message, generate code to import all the enum's
+ // symbols (e.g. the enum type name, all its values, etc.) into the class's
+ // namespace. This should be placed inside the class definition in the
+ // header.
+ void GenerateSymbolImports(io::Printer* printer) const;
+
+ // Source file stuff.
+
+ // Generate non-inline methods related to the enum, such as IsValidValue().
+ // Goes in the .cc file. EnumDescriptors are stored in an array, idx is
+ // the index in this array that corresponds with this enum.
+ void GenerateMethods(int idx, io::Printer* printer);
+
+ private:
+ const EnumDescriptor* descriptor_;
+ const std::string classname_;
+ const Options& options_;
+ // whether to generate the *_ARRAYSIZE constant.
+ const bool generate_array_size_;
+
+ std::map<std::string, std::string> variables_;
+
+ friend class FileGenerator;
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumGenerator);
+};
+
+} // namespace cpp
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_COMPILER_CPP_ENUM_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_enum_field.cc b/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_enum_field.cc
new file mode 100644
index 00000000..e0b3f9e5
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_enum_field.cc
@@ -0,0 +1,406 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 <compiler/cpp/cpp_enum_field.h>
+#include <compiler/cpp/cpp_helpers.h>
+#include <io/printer.h>
+#include <wire_format.h>
+#include <stubs/strutil.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+namespace {
+
+void SetEnumVariables(const FieldDescriptor* descriptor,
+ std::map<std::string, std::string>* variables,
+ const Options& options) {
+ SetCommonFieldVariables(descriptor, variables, options);
+ const EnumValueDescriptor* default_value = descriptor->default_value_enum();
+ (*variables)["type"] = QualifiedClassName(descriptor->enum_type(), options);
+ (*variables)["default"] = Int32ToString(default_value->number());
+ (*variables)["full_name"] = descriptor->full_name();
+}
+
+} // namespace
+
+// ===================================================================
+
+EnumFieldGenerator::EnumFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options)
+ : FieldGenerator(descriptor, options) {
+ SetEnumVariables(descriptor, &variables_, options);
+}
+
+EnumFieldGenerator::~EnumFieldGenerator() {}
+
+void EnumFieldGenerator::GeneratePrivateMembers(io::Printer* printer) const {
+ Formatter format(printer, variables_);
+ format("int $name$_;\n");
+}
+
+void EnumFieldGenerator::GenerateAccessorDeclarations(
+ io::Printer* printer) const {
+ Formatter format(printer, variables_);
+ format(
+ "$deprecated_attr$$type$ ${1$$name$$}$() const;\n"
+ "$deprecated_attr$void ${1$set_$name$$}$($type$ value);\n"
+ "private:\n"
+ "$type$ ${1$_internal_$name$$}$() const;\n"
+ "void ${1$_internal_set_$name$$}$($type$ value);\n"
+ "public:\n",
+ descriptor_);
+}
+
+void EnumFieldGenerator::GenerateInlineAccessorDefinitions(
+ io::Printer* printer) const {
+ Formatter format(printer, variables_);
+ format(
+ "inline $type$ $classname$::_internal_$name$() const {\n"
+ " return static_cast< $type$ >($name$_);\n"
+ "}\n"
+ "inline $type$ $classname$::$name$() const {\n"
+ "$annotate_get$"
+ " // @@protoc_insertion_point(field_get:$full_name$)\n"
+ " return _internal_$name$();\n"
+ "}\n"
+ "inline void $classname$::_internal_set_$name$($type$ value) {\n");
+ if (!HasPreservingUnknownEnumSemantics(descriptor_)) {
+ format(" assert($type$_IsValid(value));\n");
+ }
+ format(
+ " $set_hasbit$\n"
+ " $name$_ = value;\n"
+ "}\n"
+ "inline void $classname$::set_$name$($type$ value) {\n"
+ " _internal_set_$name$(value);\n"
+ "$annotate_set$"
+ " // @@protoc_insertion_point(field_set:$full_name$)\n"
+ "}\n");
+}
+
+void EnumFieldGenerator::GenerateClearingCode(io::Printer* printer) const {
+ Formatter format(printer, variables_);
+ format("$name$_ = $default$;\n");
+}
+
+void EnumFieldGenerator::GenerateMergingCode(io::Printer* printer) const {
+ Formatter format(printer, variables_);
+ format("_internal_set_$name$(from._internal_$name$());\n");
+}
+
+void EnumFieldGenerator::GenerateSwappingCode(io::Printer* printer) const {
+ Formatter format(printer, variables_);
+ format("swap($name$_, other->$name$_);\n");
+}
+
+void EnumFieldGenerator::GenerateConstructorCode(io::Printer* printer) const {
+ Formatter format(printer, variables_);
+ format("$name$_ = $default$;\n");
+}
+
+void EnumFieldGenerator::GenerateCopyConstructorCode(
+ io::Printer* printer) const {
+ Formatter format(printer, variables_);
+ format("$name$_ = from.$name$_;\n");
+}
+
+void EnumFieldGenerator::GenerateSerializeWithCachedSizesToArray(
+ io::Printer* printer) const {
+ Formatter format(printer, variables_);
+ format(
+ "target = stream->EnsureSpace(target);\n"
+ "target = ::$proto_ns$::internal::WireFormatLite::WriteEnumToArray(\n"
+ " $number$, this->_internal_$name$(), target);\n");
+}
+
+void EnumFieldGenerator::GenerateByteSize(io::Printer* printer) const {
+ Formatter format(printer, variables_);
+ format(
+ "total_size += $tag_size$ +\n"
+ " "
+ "::$proto_ns$::internal::WireFormatLite::EnumSize(this->_internal_$name$("
+ "));\n");
+}
+
+void EnumFieldGenerator::GenerateConstinitInitializer(
+ io::Printer* printer) const {
+ Formatter format(printer, variables_);
+ format("$name$_($default$)\n");
+}
+
+// ===================================================================
+
+EnumOneofFieldGenerator::EnumOneofFieldGenerator(
+ const FieldDescriptor* descriptor, const Options& options)
+ : EnumFieldGenerator(descriptor, options) {
+ SetCommonOneofFieldVariables(descriptor, &variables_);
+}
+
+EnumOneofFieldGenerator::~EnumOneofFieldGenerator() {}
+
+void EnumOneofFieldGenerator::GenerateInlineAccessorDefinitions(
+ io::Printer* printer) const {
+ Formatter format(printer, variables_);
+ format(
+ "inline $type$ $classname$::_internal_$name$() const {\n"
+ " if (_internal_has_$name$()) {\n"
+ " return static_cast< $type$ >($field_member$);\n"
+ " }\n"
+ " return static_cast< $type$ >($default$);\n"
+ "}\n"
+ "inline $type$ $classname$::$name$() const {\n"
+ "$annotate_get$"
+ " // @@protoc_insertion_point(field_get:$full_name$)\n"
+ " return _internal_$name$();\n"
+ "}\n"
+ "inline void $classname$::_internal_set_$name$($type$ value) {\n");
+ if (!HasPreservingUnknownEnumSemantics(descriptor_)) {
+ format(" assert($type$_IsValid(value));\n");
+ }
+ format(
+ " if (!_internal_has_$name$()) {\n"
+ " clear_$oneof_name$();\n"
+ " set_has_$name$();\n"
+ " }\n"
+ " $field_member$ = value;\n"
+ "}\n"
+ "inline void $classname$::set_$name$($type$ value) {\n"
+ " _internal_set_$name$(value);\n"
+ "$annotate_set$"
+ " // @@protoc_insertion_point(field_set:$full_name$)\n"
+ "}\n");
+}
+
+void EnumOneofFieldGenerator::GenerateClearingCode(io::Printer* printer) const {
+ Formatter format(printer, variables_);
+ format("$field_member$ = $default$;\n");
+}
+
+void EnumOneofFieldGenerator::GenerateSwappingCode(io::Printer* printer) const {
+ // Don't print any swapping code. Swapping the union will swap this field.
+}
+
+void EnumOneofFieldGenerator::GenerateConstructorCode(
+ io::Printer* printer) const {
+ Formatter format(printer, variables_);
+ format("$ns$::_$classname$_default_instance_.$name$_ = $default$;\n");
+}
+
+// ===================================================================
+
+RepeatedEnumFieldGenerator::RepeatedEnumFieldGenerator(
+ const FieldDescriptor* descriptor, const Options& options)
+ : FieldGenerator(descriptor, options) {
+ SetEnumVariables(descriptor, &variables_, options);
+}
+
+RepeatedEnumFieldGenerator::~RepeatedEnumFieldGenerator() {}
+
+void RepeatedEnumFieldGenerator::GeneratePrivateMembers(
+ io::Printer* printer) const {
+ Formatter format(printer, variables_);
+ format("::$proto_ns$::RepeatedField<int> $name$_;\n");
+ if (descriptor_->is_packed() &&
+ HasGeneratedMethods(descriptor_->file(), options_)) {
+ format("mutable std::atomic<int> _$name$_cached_byte_size_;\n");
+ }
+}
+
+void RepeatedEnumFieldGenerator::GenerateAccessorDeclarations(
+ io::Printer* printer) const {
+ Formatter format(printer, variables_);
+ format(
+ "private:\n"
+ "$type$ ${1$_internal_$name$$}$(int index) const;\n"
+ "void ${1$_internal_add_$name$$}$($type$ value);\n"
+ "::$proto_ns$::RepeatedField<int>* "
+ "${1$_internal_mutable_$name$$}$();\n"
+ "public:\n"
+ "$deprecated_attr$$type$ ${1$$name$$}$(int index) const;\n"
+ "$deprecated_attr$void ${1$set_$name$$}$(int index, $type$ value);\n"
+ "$deprecated_attr$void ${1$add_$name$$}$($type$ value);\n"
+ "$deprecated_attr$const ::$proto_ns$::RepeatedField<int>& "
+ "${1$$name$$}$() const;\n"
+ "$deprecated_attr$::$proto_ns$::RepeatedField<int>* "
+ "${1$mutable_$name$$}$();\n",
+ descriptor_);
+}
+
+void RepeatedEnumFieldGenerator::GenerateInlineAccessorDefinitions(
+ io::Printer* printer) const {
+ Formatter format(printer, variables_);
+ format(
+ "inline $type$ $classname$::_internal_$name$(int index) const {\n"
+ " return static_cast< $type$ >($name$_.Get(index));\n"
+ "}\n"
+ "inline $type$ $classname$::$name$(int index) const {\n"
+ "$annotate_get$"
+ " // @@protoc_insertion_point(field_get:$full_name$)\n"
+ " return _internal_$name$(index);\n"
+ "}\n"
+ "inline void $classname$::set_$name$(int index, $type$ value) {\n");
+ if (!HasPreservingUnknownEnumSemantics(descriptor_)) {
+ format(" assert($type$_IsValid(value));\n");
+ }
+ format(
+ " $name$_.Set(index, value);\n"
+ "$annotate_set$"
+ " // @@protoc_insertion_point(field_set:$full_name$)\n"
+ "}\n"
+ "inline void $classname$::_internal_add_$name$($type$ value) {\n");
+ if (!HasPreservingUnknownEnumSemantics(descriptor_)) {
+ format(" assert($type$_IsValid(value));\n");
+ }
+ format(
+ " $name$_.Add(value);\n"
+ "}\n"
+ "inline void $classname$::add_$name$($type$ value) {\n"
+ " _internal_add_$name$(value);\n"
+ "$annotate_add$"
+ " // @@protoc_insertion_point(field_add:$full_name$)\n"
+ "}\n"
+ "inline const ::$proto_ns$::RepeatedField<int>&\n"
+ "$classname$::$name$() const {\n"
+ "$annotate_list$"
+ " // @@protoc_insertion_point(field_list:$full_name$)\n"
+ " return $name$_;\n"
+ "}\n"
+ "inline ::$proto_ns$::RepeatedField<int>*\n"
+ "$classname$::_internal_mutable_$name$() {\n"
+ " return &$name$_;\n"
+ "}\n"
+ "inline ::$proto_ns$::RepeatedField<int>*\n"
+ "$classname$::mutable_$name$() {\n"
+ "$annotate_mutable_list$"
+ " // @@protoc_insertion_point(field_mutable_list:$full_name$)\n"
+ " return _internal_mutable_$name$();\n"
+ "}\n");
+}
+
+void RepeatedEnumFieldGenerator::GenerateClearingCode(
+ io::Printer* printer) const {
+ Formatter format(printer, variables_);
+ format("$name$_.Clear();\n");
+}
+
+void RepeatedEnumFieldGenerator::GenerateMergingCode(
+ io::Printer* printer) const {
+ Formatter format(printer, variables_);
+ format("$name$_.MergeFrom(from.$name$_);\n");
+}
+
+void RepeatedEnumFieldGenerator::GenerateSwappingCode(
+ io::Printer* printer) const {
+ Formatter format(printer, variables_);
+ format("$name$_.InternalSwap(&other->$name$_);\n");
+}
+
+void RepeatedEnumFieldGenerator::GenerateConstructorCode(
+ io::Printer* printer) const {
+ // Not needed for repeated fields.
+}
+
+void RepeatedEnumFieldGenerator::GenerateSerializeWithCachedSizesToArray(
+ io::Printer* printer) const {
+ Formatter format(printer, variables_);
+ if (descriptor_->is_packed()) {
+ // Write the tag and the size.
+ format(
+ "{\n"
+ " int byte_size = "
+ "_$name$_cached_byte_size_.load(std::memory_order_relaxed);\n"
+ " if (byte_size > 0) {\n"
+ " target = stream->WriteEnumPacked(\n"
+ " $number$, $name$_, byte_size, target);\n"
+ " }\n"
+ "}\n");
+ } else {
+ format(
+ "for (int i = 0, n = this->_internal_$name$_size(); i < n; i++) {\n"
+ " target = stream->EnsureSpace(target);\n"
+ " target = ::$proto_ns$::internal::WireFormatLite::WriteEnumToArray(\n"
+ " $number$, this->_internal_$name$(i), target);\n"
+ "}\n");
+ }
+}
+
+void RepeatedEnumFieldGenerator::GenerateByteSize(io::Printer* printer) const {
+ Formatter format(printer, variables_);
+ format(
+ "{\n"
+ " size_t data_size = 0;\n"
+ " unsigned int count = static_cast<unsigned "
+ "int>(this->_internal_$name$_size());");
+ format.Indent();
+ format(
+ "for (unsigned int i = 0; i < count; i++) {\n"
+ " data_size += ::$proto_ns$::internal::WireFormatLite::EnumSize(\n"
+ " this->_internal_$name$(static_cast<int>(i)));\n"
+ "}\n");
+
+ if (descriptor_->is_packed()) {
+ format(
+ "if (data_size > 0) {\n"
+ " total_size += $tag_size$ +\n"
+ " ::$proto_ns$::internal::WireFormatLite::Int32Size(\n"
+ " static_cast<$int32$>(data_size));\n"
+ "}\n"
+ "int cached_size = ::$proto_ns$::internal::ToCachedSize(data_size);\n"
+ "_$name$_cached_byte_size_.store(cached_size,\n"
+ " std::memory_order_relaxed);\n"
+ "total_size += data_size;\n");
+ } else {
+ format("total_size += ($tag_size$UL * count) + data_size;\n");
+ }
+ format.Outdent();
+ format("}\n");
+}
+
+void RepeatedEnumFieldGenerator::GenerateConstinitInitializer(
+ io::Printer* printer) const {
+ Formatter format(printer, variables_);
+ format("$name$_()");
+ if (descriptor_->is_packed() &&
+ HasGeneratedMethods(descriptor_->file(), options_)) {
+ format("\n, _$name$_cached_byte_size_(0)");
+ }
+}
+
+} // namespace cpp
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_enum_field.h b/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_enum_field.h
new file mode 100644
index 00000000..3be207bf
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_enum_field.h
@@ -0,0 +1,115 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 GOOGLE_PROTOBUF_COMPILER_CPP_ENUM_FIELD_H__
+#define GOOGLE_PROTOBUF_COMPILER_CPP_ENUM_FIELD_H__
+
+#include <map>
+#include <string>
+#include <compiler/cpp/cpp_field.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+class EnumFieldGenerator : public FieldGenerator {
+ public:
+ EnumFieldGenerator(const FieldDescriptor* descriptor, const Options& options);
+ ~EnumFieldGenerator();
+
+ // implements FieldGenerator ---------------------------------------
+ void GeneratePrivateMembers(io::Printer* printer) const override;
+ void GenerateAccessorDeclarations(io::Printer* printer) const override;
+ void GenerateInlineAccessorDefinitions(io::Printer* printer) const override;
+ void GenerateClearingCode(io::Printer* printer) const override;
+ void GenerateMergingCode(io::Printer* printer) const override;
+ void GenerateSwappingCode(io::Printer* printer) const override;
+ void GenerateConstructorCode(io::Printer* printer) const override;
+ void GenerateCopyConstructorCode(io::Printer* printer) const override;
+ void GenerateSerializeWithCachedSizesToArray(
+ io::Printer* printer) const override;
+ void GenerateByteSize(io::Printer* printer) const override;
+ void GenerateConstinitInitializer(io::Printer* printer) const override;
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumFieldGenerator);
+};
+
+class EnumOneofFieldGenerator : public EnumFieldGenerator {
+ public:
+ EnumOneofFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options);
+ ~EnumOneofFieldGenerator();
+
+ // implements FieldGenerator ---------------------------------------
+ void GenerateInlineAccessorDefinitions(io::Printer* printer) const override;
+ void GenerateClearingCode(io::Printer* printer) const override;
+ void GenerateSwappingCode(io::Printer* printer) const override;
+ void GenerateConstructorCode(io::Printer* printer) const override;
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumOneofFieldGenerator);
+};
+
+class RepeatedEnumFieldGenerator : public FieldGenerator {
+ public:
+ RepeatedEnumFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options);
+ ~RepeatedEnumFieldGenerator();
+
+ // implements FieldGenerator ---------------------------------------
+ void GeneratePrivateMembers(io::Printer* printer) const override;
+ void GenerateAccessorDeclarations(io::Printer* printer) const override;
+ void GenerateInlineAccessorDefinitions(io::Printer* printer) const override;
+ void GenerateClearingCode(io::Printer* printer) const override;
+ void GenerateMergingCode(io::Printer* printer) const override;
+ void GenerateSwappingCode(io::Printer* printer) const override;
+ void GenerateConstructorCode(io::Printer* printer) const override;
+ void GenerateCopyConstructorCode(io::Printer* printer) const override {}
+ void GenerateSerializeWithCachedSizesToArray(
+ io::Printer* printer) const override;
+ void GenerateByteSize(io::Printer* printer) const override;
+ void GenerateConstinitInitializer(io::Printer* printer) const override;
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedEnumFieldGenerator);
+};
+
+} // namespace cpp
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_COMPILER_CPP_ENUM_FIELD_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_extension.cc b/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_extension.cc
new file mode 100644
index 00000000..f0dae72d
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_extension.cc
@@ -0,0 +1,189 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 <compiler/cpp/cpp_extension.h>
+#include <map>
+#include <compiler/cpp/cpp_helpers.h>
+#include <descriptor.pb.h>
+#include <io/printer.h>
+#include <stubs/strutil.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+ExtensionGenerator::ExtensionGenerator(const FieldDescriptor* descriptor,
+ const Options& options,
+ MessageSCCAnalyzer* scc_analyzer)
+ : descriptor_(descriptor), options_(options), scc_analyzer_(scc_analyzer) {
+ // Construct type_traits_.
+ if (descriptor_->is_repeated()) {
+ type_traits_ = "Repeated";
+ }
+
+ switch (descriptor_->cpp_type()) {
+ case FieldDescriptor::CPPTYPE_ENUM:
+ type_traits_.append("EnumTypeTraits< ");
+ type_traits_.append(ClassName(descriptor_->enum_type(), true));
+ type_traits_.append(", ");
+ type_traits_.append(ClassName(descriptor_->enum_type(), true));
+ type_traits_.append("_IsValid>");
+ break;
+ case FieldDescriptor::CPPTYPE_STRING:
+ type_traits_.append("StringTypeTraits");
+ break;
+ case FieldDescriptor::CPPTYPE_MESSAGE:
+ type_traits_.append("MessageTypeTraits< ");
+ type_traits_.append(ClassName(descriptor_->message_type(), true));
+ type_traits_.append(" >");
+ break;
+ default:
+ type_traits_.append("PrimitiveTypeTraits< ");
+ type_traits_.append(PrimitiveTypeName(options_, descriptor_->cpp_type()));
+ type_traits_.append(" >");
+ break;
+ }
+ SetCommonVars(options, &variables_);
+ variables_["extendee"] =
+ QualifiedClassName(descriptor_->containing_type(), options_);
+ variables_["type_traits"] = type_traits_;
+ std::string name = descriptor_->name();
+ variables_["name"] = ResolveKeyword(name);
+ variables_["constant_name"] = FieldConstantName(descriptor_);
+ variables_["field_type"] =
+ StrCat(static_cast<int>(descriptor_->type()));
+ variables_["packed"] = descriptor_->is_packed() ? "true" : "false";
+
+ std::string scope =
+ IsScoped() ? ClassName(descriptor_->extension_scope(), false) + "::" : "";
+ variables_["scope"] = scope;
+ variables_["scoped_name"] = ExtensionName(descriptor_);
+ variables_["number"] = StrCat(descriptor_->number());
+}
+
+ExtensionGenerator::~ExtensionGenerator() {}
+
+bool ExtensionGenerator::IsScoped() const {
+ return descriptor_->extension_scope() != nullptr;
+}
+
+void ExtensionGenerator::GenerateDeclaration(io::Printer* printer) const {
+ Formatter format(printer, variables_);
+
+ // If this is a class member, it needs to be declared "static". Otherwise,
+ // it needs to be "extern". In the latter case, it also needs the DLL
+ // export/import specifier.
+ std::string qualifier;
+ if (!IsScoped()) {
+ qualifier = "extern";
+ if (!options_.dllexport_decl.empty()) {
+ qualifier = options_.dllexport_decl + " " + qualifier;
+ }
+ } else {
+ qualifier = "static";
+ }
+
+ format(
+ "static const int $constant_name$ = $number$;\n"
+ "$1$ ::$proto_ns$::internal::ExtensionIdentifier< $extendee$,\n"
+ " ::$proto_ns$::internal::$type_traits$, $field_type$, $packed$ >\n"
+ " ${2$$name$$}$;\n",
+ qualifier, descriptor_);
+}
+
+void ExtensionGenerator::GenerateDefinition(io::Printer* printer) {
+ // If we are building for lite with implicit weak fields, we want to skip over
+ // any custom options (i.e. extensions of messages from descriptor.proto).
+ // This prevents the creation of any unnecessary linker references to the
+ // descriptor messages.
+ if (options_.lite_implicit_weak_fields &&
+ descriptor_->containing_type()->file()->name() ==
+ "net/proto2/proto/descriptor.proto") {
+ return;
+ }
+
+ Formatter format(printer, variables_);
+ std::string default_str;
+ // If this is a class member, it needs to be declared in its class scope.
+ if (descriptor_->cpp_type() == FieldDescriptor::CPPTYPE_STRING) {
+ // We need to declare a global string which will contain the default value.
+ // We cannot declare it at class scope because that would require exposing
+ // it in the header which would be annoying for other reasons. So we
+ // replace :: with _ in the name and declare it as a global.
+ default_str =
+ StringReplace(variables_["scoped_name"], "::", "_", true) + "_default";
+ format("const std::string $1$($2$);\n", default_str,
+ DefaultValue(options_, descriptor_));
+ } else if (descriptor_->message_type()) {
+ // We have to initialize the default instance for extensions at registration
+ // time.
+ default_str =
+ FieldMessageTypeName(descriptor_, options_) + "::default_instance()";
+ } else {
+ default_str = DefaultValue(options_, descriptor_);
+ }
+
+ // Likewise, class members need to declare the field constant variable.
+ if (IsScoped()) {
+ format(
+ "#if !defined(_MSC_VER) || (_MSC_VER >= 1900 && _MSC_VER < 1912)\n"
+ "const int $scope$$constant_name$;\n"
+ "#endif\n");
+ }
+
+ format(
+ "PROTOBUF_ATTRIBUTE_INIT_PRIORITY "
+ "::$proto_ns$::internal::ExtensionIdentifier< $extendee$,\n"
+ " ::$proto_ns$::internal::$type_traits$, $field_type$, $packed$ >\n"
+ " $scoped_name$($constant_name$, $1$);\n",
+ default_str);
+
+ // Register extension verify function if needed.
+ if (descriptor_->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
+ ShouldVerify(descriptor_->message_type(), options_, scc_analyzer_) &&
+ ShouldVerify(descriptor_->containing_type(), options_, scc_analyzer_)) {
+ format(
+ "PROTOBUF_ATTRIBUTE_INIT_PRIORITY "
+ "::$proto_ns$::internal::RegisterExtensionVerify< $extendee$,\n"
+ " $1$, $number$> $2$_$name$_register;\n",
+ ClassName(descriptor_->message_type(), true),
+ IsScoped() ? ClassName(descriptor_->extension_scope(), false) : "");
+ }
+}
+
+} // namespace cpp
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_extension.h b/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_extension.h
new file mode 100644
index 00000000..76c0e3db
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_extension.h
@@ -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.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_EXTENSION_H__
+#define GOOGLE_PROTOBUF_COMPILER_CPP_EXTENSION_H__
+
+#include <map>
+#include <string>
+
+#include <stubs/common.h>
+#include <compiler/cpp/cpp_options.h>
+
+namespace google {
+namespace protobuf {
+class FieldDescriptor; // descriptor.h
+namespace io {
+class Printer; // printer.h
+}
+} // namespace protobuf
+} // namespace google
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+class MessageSCCAnalyzer;
+
+// Generates code for an extension, which may be within the scope of some
+// message or may be at file scope. This is much simpler than FieldGenerator
+// since extensions are just simple identifiers with interesting types.
+class ExtensionGenerator {
+ public:
+ // See generator.cc for the meaning of dllexport_decl.
+ explicit ExtensionGenerator(const FieldDescriptor* descriptor,
+ const Options& options,
+ MessageSCCAnalyzer* scc_analyzer);
+ ~ExtensionGenerator();
+
+ // Header stuff.
+ void GenerateDeclaration(io::Printer* printer) const;
+
+ // Source file stuff.
+ void GenerateDefinition(io::Printer* printer);
+
+ bool IsScoped() const;
+
+ private:
+ const FieldDescriptor* descriptor_;
+ std::string type_traits_;
+ Options options_;
+ MessageSCCAnalyzer* scc_analyzer_;
+
+ std::map<std::string, std::string> variables_;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ExtensionGenerator);
+};
+
+} // namespace cpp
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_COMPILER_CPP_MESSAGE_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_field.cc b/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_field.cc
new file mode 100644
index 00000000..8edda0c7
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_field.cc
@@ -0,0 +1,391 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <compiler/cpp/cpp_field.h>
+
+#include <cstdint>
+#include <memory>
+#include <string>
+
+#include <compiler/cpp/cpp_helpers.h>
+#include <compiler/cpp/cpp_primitive_field.h>
+#include <compiler/cpp/cpp_string_field.h>
+#include <stubs/strutil.h>
+#include <stubs/substitute.h>
+#include <stubs/logging.h>
+#include <stubs/common.h>
+#include <compiler/cpp/cpp_enum_field.h>
+#include <compiler/cpp/cpp_map_field.h>
+#include <compiler/cpp/cpp_message_field.h>
+#include <descriptor.pb.h>
+#include <io/printer.h>
+#include <wire_format.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+using internal::WireFormat;
+
+namespace {
+
+void MaySetAnnotationVariable(const Options& options,
+ StringPiece annotation_name,
+ StringPiece substitute_template_prefix,
+ StringPiece prepared_template,
+ int field_index, StringPiece access_type,
+ std::map<std::string, std::string>* variables) {
+ if (options.field_listener_options.forbidden_field_listener_events.count(
+ std::string(annotation_name)))
+ return;
+ (*variables)[StrCat("annotate_", annotation_name)] = strings::Substitute(
+ StrCat(substitute_template_prefix, prepared_template, ");\n"),
+ field_index, access_type);
+}
+
+std::string GenerateTemplateForOneofString(const FieldDescriptor* descriptor,
+ StringPiece proto_ns,
+ StringPiece field_member) {
+ std::string field_name = google::protobuf::compiler::cpp::FieldName(descriptor);
+ std::string field_pointer =
+ descriptor->options().ctype() == google::protobuf::FieldOptions::STRING
+ ? "$0.GetPointer()"
+ : "$0";
+
+ if (descriptor->default_value_string().empty()) {
+ return strings::Substitute(StrCat("_internal_has_", field_name, "() ? ",
+ field_pointer, ": nullptr"),
+ field_member);
+ }
+
+ if (descriptor->options().ctype() == google::protobuf::FieldOptions::STRING_PIECE) {
+ return strings::Substitute(StrCat("_internal_has_", field_name, "() ? ",
+ field_pointer, ": nullptr"),
+ field_member);
+ }
+
+ std::string default_value_pointer =
+ descriptor->options().ctype() == google::protobuf::FieldOptions::STRING
+ ? "&$1.get()"
+ : "&$1";
+ return strings::Substitute(
+ StrCat("_internal_has_", field_name, "() ? ", field_pointer, " : ",
+ default_value_pointer),
+ field_member, MakeDefaultName(descriptor));
+}
+
+std::string GenerateTemplateForSingleString(const FieldDescriptor* descriptor,
+ StringPiece field_member) {
+ if (descriptor->default_value_string().empty()) {
+ return StrCat("&", field_member);
+ }
+
+ if (descriptor->options().ctype() == google::protobuf::FieldOptions::STRING) {
+ return strings::Substitute(
+ "$0.IsDefault(nullptr) ? &$1.get() : $0.GetPointer()", field_member,
+ MakeDefaultName(descriptor));
+ }
+
+ return StrCat("&", field_member);
+}
+
+} // namespace
+
+void AddAccessorAnnotations(const FieldDescriptor* descriptor,
+ const Options& options,
+ std::map<std::string, std::string>* variables) {
+ // Can be expanded to include more specific calls, for example, for arena or
+ // clear calls.
+ static constexpr const char* kAccessorsAnnotations[] = {
+ "annotate_add", "annotate_get", "annotate_has",
+ "annotate_list", "annotate_mutable", "annotate_mutable_list",
+ "annotate_release", "annotate_set", "annotate_size",
+ "annotate_clear", "annotate_add_mutable",
+ };
+ for (size_t i = 0; i < GOOGLE_ARRAYSIZE(kAccessorsAnnotations); ++i) {
+ (*variables)[kAccessorsAnnotations[i]] = "";
+ }
+ if (options.annotate_accessor) {
+ for (size_t i = 0; i < GOOGLE_ARRAYSIZE(kAccessorsAnnotations); ++i) {
+ (*variables)[kAccessorsAnnotations[i]] = StrCat(
+ " ", FieldName(descriptor), "_AccessedNoStrip = true;\n");
+ }
+ }
+ if (!options.field_listener_options.inject_field_listener_events) {
+ return;
+ }
+ if (descriptor->file()->options().optimize_for() ==
+ google::protobuf::FileOptions::LITE_RUNTIME) {
+ return;
+ }
+ std::string field_member = (*variables)["field_member"];
+ const google::protobuf::OneofDescriptor* oneof_member =
+ descriptor->real_containing_oneof();
+ if (oneof_member) {
+ field_member = StrCat(oneof_member->name(), "_.", field_member);
+ }
+ const std::string proto_ns = (*variables)["proto_ns"];
+ const std::string substitute_template_prefix = " _tracker_.$1<$0>(this, ";
+ std::string prepared_template;
+
+ // Flat template is needed if the prepared one is introspecting the values
+ // inside the returned values, for example, for repeated fields and maps.
+ std::string prepared_flat_template;
+ std::string prepared_add_template;
+ // TODO(b/190614678): Support fields with type Message or Map.
+ if (descriptor->is_repeated() && !descriptor->is_map()) {
+ if (descriptor->type() != FieldDescriptor::TYPE_MESSAGE &&
+ descriptor->type() != FieldDescriptor::TYPE_GROUP) {
+ prepared_template = strings::Substitute("&$0.Get(index)", field_member);
+ prepared_add_template =
+ strings::Substitute("&$0.Get($0.size() - 1)", field_member);
+ } else {
+ prepared_template = "nullptr";
+ prepared_add_template = "nullptr";
+ }
+ } else if (descriptor->is_map()) {
+ prepared_template = "nullptr";
+ } else if (descriptor->type() == FieldDescriptor::TYPE_MESSAGE &&
+ !descriptor->options().lazy()) {
+ prepared_template = "nullptr";
+ } else if (descriptor->cpp_type() == FieldDescriptor::CPPTYPE_STRING) {
+ if (oneof_member) {
+ prepared_template = GenerateTemplateForOneofString(
+ descriptor, (*variables)["proto_ns"], field_member);
+ } else {
+ prepared_template =
+ GenerateTemplateForSingleString(descriptor, field_member);
+ }
+ } else {
+ prepared_template = StrCat("&", field_member);
+ }
+ if (descriptor->is_repeated() && !descriptor->is_map() &&
+ descriptor->type() != FieldDescriptor::TYPE_MESSAGE &&
+ descriptor->type() != FieldDescriptor::TYPE_GROUP) {
+ prepared_flat_template = StrCat("&", field_member);
+ } else {
+ prepared_flat_template = prepared_template;
+ }
+
+ MaySetAnnotationVariable(options, "get", substitute_template_prefix,
+ prepared_template, descriptor->index(), "OnGet",
+ variables);
+ MaySetAnnotationVariable(options, "set", substitute_template_prefix,
+ prepared_template, descriptor->index(), "OnSet",
+ variables);
+ MaySetAnnotationVariable(options, "has", substitute_template_prefix,
+ prepared_template, descriptor->index(), "OnHas",
+ variables);
+ MaySetAnnotationVariable(options, "mutable", substitute_template_prefix,
+ prepared_template, descriptor->index(), "OnMutable",
+ variables);
+ MaySetAnnotationVariable(options, "release", substitute_template_prefix,
+ prepared_template, descriptor->index(), "OnRelease",
+ variables);
+ MaySetAnnotationVariable(options, "clear", substitute_template_prefix,
+ prepared_flat_template, descriptor->index(),
+ "OnClear", variables);
+ MaySetAnnotationVariable(options, "size", substitute_template_prefix,
+ prepared_flat_template, descriptor->index(),
+ "OnSize", variables);
+ MaySetAnnotationVariable(options, "list", substitute_template_prefix,
+ prepared_flat_template, descriptor->index(),
+ "OnList", variables);
+ MaySetAnnotationVariable(options, "mutable_list", substitute_template_prefix,
+ prepared_flat_template, descriptor->index(),
+ "OnMutableList", variables);
+ MaySetAnnotationVariable(options, "add", substitute_template_prefix,
+ prepared_add_template, descriptor->index(), "OnAdd",
+ variables);
+ MaySetAnnotationVariable(options, "add_mutable", substitute_template_prefix,
+ prepared_add_template, descriptor->index(),
+ "OnAddMutable", variables);
+}
+
+void SetCommonFieldVariables(const FieldDescriptor* descriptor,
+ std::map<std::string, std::string>* variables,
+ const Options& options) {
+ SetCommonVars(options, variables);
+ (*variables)["ns"] = Namespace(descriptor, options);
+ (*variables)["name"] = FieldName(descriptor);
+ (*variables)["index"] = StrCat(descriptor->index());
+ (*variables)["number"] = StrCat(descriptor->number());
+ (*variables)["classname"] = ClassName(FieldScope(descriptor), false);
+ (*variables)["declared_type"] = DeclaredTypeMethodName(descriptor->type());
+ (*variables)["field_member"] = FieldName(descriptor) + "_";
+
+ (*variables)["tag_size"] = StrCat(
+ WireFormat::TagSize(descriptor->number(), descriptor->type()));
+ (*variables)["deprecated_attr"] = DeprecatedAttribute(options, descriptor);
+
+ (*variables)["set_hasbit"] = "";
+ (*variables)["clear_hasbit"] = "";
+ if (HasHasbit(descriptor)) {
+ (*variables)["set_hasbit_io"] =
+ "_Internal::set_has_" + FieldName(descriptor) + "(&_has_bits_);";
+ } else {
+ (*variables)["set_hasbit_io"] = "";
+ }
+
+ AddAccessorAnnotations(descriptor, options, variables);
+
+ // These variables are placeholders to pick out the beginning and ends of
+ // identifiers for annotations (when doing so with existing variables would
+ // be ambiguous or impossible). They should never be set to anything but the
+ // empty string.
+ (*variables)["{"] = "";
+ (*variables)["}"] = "";
+}
+
+void FieldGenerator::SetHasBitIndex(int32_t has_bit_index) {
+ if (!HasHasbit(descriptor_)) {
+ GOOGLE_CHECK_EQ(has_bit_index, -1);
+ return;
+ }
+ variables_["set_hasbit"] = StrCat(
+ "_has_bits_[", has_bit_index / 32, "] |= 0x",
+ strings::Hex(1u << (has_bit_index % 32), strings::ZERO_PAD_8), "u;");
+ variables_["clear_hasbit"] = StrCat(
+ "_has_bits_[", has_bit_index / 32, "] &= ~0x",
+ strings::Hex(1u << (has_bit_index % 32), strings::ZERO_PAD_8), "u;");
+}
+
+void FieldGenerator::SetInlinedStringIndex(int32_t inlined_string_index) {
+ if (!IsStringInlined(descriptor_, options_)) {
+ GOOGLE_CHECK_EQ(inlined_string_index, -1);
+ return;
+ }
+ variables_["inlined_string_donated"] = StrCat(
+ "(_inlined_string_donated_[", inlined_string_index / 32, "] & 0x",
+ strings::Hex(1u << (inlined_string_index % 32), strings::ZERO_PAD_8),
+ "u) != 0;");
+ variables_["donating_states_word"] =
+ StrCat("_inlined_string_donated_[", inlined_string_index / 32, "]");
+ variables_["mask_for_undonate"] = StrCat(
+ "~0x", strings::Hex(1u << (inlined_string_index % 32), strings::ZERO_PAD_8),
+ "u");
+}
+
+void SetCommonOneofFieldVariables(
+ const FieldDescriptor* descriptor,
+ std::map<std::string, std::string>* variables) {
+ const std::string prefix = descriptor->containing_oneof()->name() + "_.";
+ (*variables)["oneof_name"] = descriptor->containing_oneof()->name();
+ (*variables)["field_member"] =
+ StrCat(prefix, (*variables)["name"], "_");
+}
+
+FieldGenerator::~FieldGenerator() {}
+
+FieldGeneratorMap::FieldGeneratorMap(const Descriptor* descriptor,
+ const Options& options,
+ MessageSCCAnalyzer* scc_analyzer)
+ : descriptor_(descriptor), field_generators_(descriptor->field_count()) {
+ // Construct all the FieldGenerators.
+ for (int i = 0; i < descriptor->field_count(); i++) {
+ field_generators_[i].reset(
+ MakeGenerator(descriptor->field(i), options, scc_analyzer));
+ }
+}
+
+FieldGenerator* FieldGeneratorMap::MakeGoogleInternalGenerator(
+ const FieldDescriptor* field, const Options& options,
+ MessageSCCAnalyzer* scc_analyzer) {
+
+ return nullptr;
+}
+
+FieldGenerator* FieldGeneratorMap::MakeGenerator(
+ const FieldDescriptor* field, const Options& options,
+ MessageSCCAnalyzer* scc_analyzer) {
+ FieldGenerator* generator =
+ MakeGoogleInternalGenerator(field, options, scc_analyzer);
+ if (generator) {
+ return generator;
+ }
+
+ if (field->is_repeated()) {
+ switch (field->cpp_type()) {
+ case FieldDescriptor::CPPTYPE_MESSAGE:
+ if (field->is_map()) {
+ return new MapFieldGenerator(field, options, scc_analyzer);
+ } else {
+ return new RepeatedMessageFieldGenerator(field, options,
+ scc_analyzer);
+ }
+ case FieldDescriptor::CPPTYPE_STRING:
+ return new RepeatedStringFieldGenerator(field, options);
+ case FieldDescriptor::CPPTYPE_ENUM:
+ return new RepeatedEnumFieldGenerator(field, options);
+ default:
+ return new RepeatedPrimitiveFieldGenerator(field, options);
+ }
+ } else if (field->real_containing_oneof()) {
+ switch (field->cpp_type()) {
+ case FieldDescriptor::CPPTYPE_MESSAGE:
+ return new MessageOneofFieldGenerator(field, options, scc_analyzer);
+ case FieldDescriptor::CPPTYPE_STRING:
+ return new StringOneofFieldGenerator(field, options);
+ case FieldDescriptor::CPPTYPE_ENUM:
+ return new EnumOneofFieldGenerator(field, options);
+ default:
+ return new PrimitiveOneofFieldGenerator(field, options);
+ }
+ } else {
+ switch (field->cpp_type()) {
+ case FieldDescriptor::CPPTYPE_MESSAGE:
+ return new MessageFieldGenerator(field, options, scc_analyzer);
+ case FieldDescriptor::CPPTYPE_STRING:
+ return new StringFieldGenerator(field, options);
+ case FieldDescriptor::CPPTYPE_ENUM:
+ return new EnumFieldGenerator(field, options);
+ default:
+ return new PrimitiveFieldGenerator(field, options);
+ }
+ }
+}
+
+FieldGeneratorMap::~FieldGeneratorMap() {}
+
+const FieldGenerator& FieldGeneratorMap::get(
+ const FieldDescriptor* field) const {
+ GOOGLE_CHECK_EQ(field->containing_type(), descriptor_);
+ return *field_generators_[field->index()];
+}
+
+} // namespace cpp
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_field.h b/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_field.h
new file mode 100644
index 00000000..d0ead8c6
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_field.h
@@ -0,0 +1,242 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 GOOGLE_PROTOBUF_COMPILER_CPP_FIELD_H__
+#define GOOGLE_PROTOBUF_COMPILER_CPP_FIELD_H__
+
+#include <cstdint>
+#include <map>
+#include <memory>
+#include <string>
+
+#include <compiler/cpp/cpp_helpers.h>
+#include <compiler/cpp/cpp_options.h>
+#include <descriptor.h>
+
+namespace google {
+namespace protobuf {
+namespace io {
+class Printer; // printer.h
+}
+} // namespace protobuf
+} // namespace google
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+// Helper function: set variables in the map that are the same for all
+// field code generators.
+// ['name', 'index', 'number', 'classname', 'declared_type', 'tag_size',
+// 'deprecation'].
+void SetCommonFieldVariables(const FieldDescriptor* descriptor,
+ std::map<std::string, std::string>* variables,
+ const Options& options);
+
+void SetCommonOneofFieldVariables(
+ const FieldDescriptor* descriptor,
+ std::map<std::string, std::string>* variables);
+
+class FieldGenerator {
+ public:
+ explicit FieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options)
+ : descriptor_(descriptor), options_(options) {}
+ virtual ~FieldGenerator();
+ virtual void GenerateSerializeWithCachedSizes(
+ io::Printer* printer) const final{};
+ // Generate lines of code declaring members fields of the message class
+ // needed to represent this field. These are placed inside the message
+ // class.
+ virtual void GeneratePrivateMembers(io::Printer* printer) const = 0;
+
+ // Generate static default variable for this field. These are placed inside
+ // the message class. Most field types don't need this, so the default
+ // implementation is empty.
+ virtual void GenerateStaticMembers(io::Printer* /*printer*/) const {}
+
+ // Generate prototypes for all of the accessor functions related to this
+ // field. These are placed inside the class definition.
+ virtual void GenerateAccessorDeclarations(io::Printer* printer) const = 0;
+
+ // Generate inline definitions of accessor functions for this field.
+ // These are placed inside the header after all class definitions.
+ virtual void GenerateInlineAccessorDefinitions(
+ io::Printer* printer) const = 0;
+
+ // Generate definitions of accessors that aren't inlined. These are
+ // placed somewhere in the .cc file.
+ // Most field types don't need this, so the default implementation is empty.
+ virtual void GenerateNonInlineAccessorDefinitions(
+ io::Printer* /*printer*/) const {}
+
+ // Generate declarations of accessors that are for internal purposes only.
+ // Most field types don't need this, so the default implementation is empty.
+ virtual void GenerateInternalAccessorDefinitions(
+ io::Printer* /*printer*/) const {}
+
+ // Generate definitions of accessors that are for internal purposes only.
+ // Most field types don't need this, so the default implementation is empty.
+ virtual void GenerateInternalAccessorDeclarations(
+ io::Printer* /*printer*/) const {}
+
+ // Generate lines of code (statements, not declarations) which clear the
+ // field. This is used to define the clear_$name$() method
+ virtual void GenerateClearingCode(io::Printer* printer) const = 0;
+
+ // Generate lines of code (statements, not declarations) which clear the
+ // field as part of the Clear() method for the whole message. For message
+ // types which have field presence bits, MessageGenerator::GenerateClear
+ // will have already checked the presence bits.
+ //
+ // Since most field types can re-use GenerateClearingCode, this method is
+ // not pure virtual.
+ virtual void GenerateMessageClearingCode(io::Printer* printer) const {
+ GenerateClearingCode(printer);
+ }
+
+ // Generate lines of code (statements, not declarations) which merges the
+ // contents of the field from the current message to the target message,
+ // which is stored in the generated code variable "from".
+ // This is used to fill in the MergeFrom method for the whole message.
+ // Details of this usage can be found in message.cc under the
+ // GenerateMergeFrom method.
+ virtual void GenerateMergingCode(io::Printer* printer) const = 0;
+
+ // Generates a copy constructor
+ virtual void GenerateCopyConstructorCode(io::Printer* printer) const = 0;
+
+ // Generate lines of code (statements, not declarations) which swaps
+ // this field and the corresponding field of another message, which
+ // is stored in the generated code variable "other". This is used to
+ // define the Swap method. Details of usage can be found in
+ // message.cc under the GenerateSwap method.
+ virtual void GenerateSwappingCode(io::Printer* printer) const = 0;
+
+ // Generate initialization code for private members declared by
+ // GeneratePrivateMembers(). These go into the message class's SharedCtor()
+ // method, invoked by each of the generated constructors.
+ virtual void GenerateConstructorCode(io::Printer* printer) const = 0;
+
+ // Generate any code that needs to go in the class's SharedDtor() method,
+ // invoked by the destructor.
+ // Most field types don't need this, so the default implementation is empty.
+ virtual void GenerateDestructorCode(io::Printer* /*printer*/) const {}
+
+ // Generate a manual destructor invocation for use when the message is on an
+ // arena. The code that this method generates will be executed inside a
+ // shared-for-the-whole-message-class method registered with
+ // OwnDestructor(). The method should return |true| if it generated any code
+ // that requires a call; this allows the message generator to eliminate the
+ // OwnDestructor() registration if no fields require it.
+ virtual bool GenerateArenaDestructorCode(io::Printer* printer) const {
+ return false;
+ }
+
+ // Generate initialization code for private members declared by
+ // GeneratePrivateMembers(), specifically for the constexpr constructor.
+ // These go into the constructor's initializer list and must follow that
+ // syntax (eg `field_(args)`). Does not include `:` or `,` separators.
+ virtual void GenerateConstinitInitializer(io::Printer* printer) const {}
+
+ // Generate lines to serialize this field directly to the array "target",
+ // which are placed within the message's SerializeWithCachedSizesToArray()
+ // method. This must also advance "target" past the written bytes.
+ virtual void GenerateSerializeWithCachedSizesToArray(
+ io::Printer* printer) const = 0;
+
+ // Generate lines to compute the serialized size of this field, which
+ // are placed in the message's ByteSize() method.
+ virtual void GenerateByteSize(io::Printer* printer) const = 0;
+
+ // Generates lines to call IsInitialized() for eligible message fields. Non
+ // message fields won't need to override this function.
+ virtual void GenerateIsInitialized(io::Printer* printer) const {}
+
+ virtual bool IsInlined() const { return false; }
+
+ void SetHasBitIndex(int32_t has_bit_index);
+ void SetInlinedStringIndex(int32_t inlined_string_index);
+
+ protected:
+ const FieldDescriptor* descriptor_;
+ const Options& options_;
+ std::map<std::string, std::string> variables_;
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldGenerator);
+};
+
+// Convenience class which constructs FieldGenerators for a Descriptor.
+class FieldGeneratorMap {
+ public:
+ FieldGeneratorMap(const Descriptor* descriptor, const Options& options,
+ MessageSCCAnalyzer* scc_analyzer);
+ ~FieldGeneratorMap();
+
+ const FieldGenerator& get(const FieldDescriptor* field) const;
+
+ void SetHasBitIndices(const std::vector<int>& has_bit_indices_) {
+ for (int i = 0; i < descriptor_->field_count(); ++i) {
+ field_generators_[i]->SetHasBitIndex(has_bit_indices_[i]);
+ }
+ }
+
+ void SetInlinedStringIndices(const std::vector<int>& inlined_string_indices) {
+ for (int i = 0; i < descriptor_->field_count(); ++i) {
+ field_generators_[i]->SetInlinedStringIndex(inlined_string_indices[i]);
+ }
+ }
+
+ private:
+ const Descriptor* descriptor_;
+ std::vector<std::unique_ptr<FieldGenerator>> field_generators_;
+
+ static FieldGenerator* MakeGoogleInternalGenerator(
+ const FieldDescriptor* field, const Options& options,
+ MessageSCCAnalyzer* scc_analyzer);
+ static FieldGenerator* MakeGenerator(const FieldDescriptor* field,
+ const Options& options,
+ MessageSCCAnalyzer* scc_analyzer);
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldGeneratorMap);
+};
+
+} // namespace cpp
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_COMPILER_CPP_FIELD_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_file.cc b/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_file.cc
new file mode 100644
index 00000000..51758b9e
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_file.cc
@@ -0,0 +1,1419 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 <compiler/cpp/cpp_file.h>
+
+#include <iostream>
+#include <map>
+#include <memory>
+#include <set>
+#include <unordered_map>
+#include <unordered_set>
+#include <vector>
+
+#include <compiler/cpp/cpp_enum.h>
+#include <compiler/cpp/cpp_extension.h>
+#include <compiler/cpp/cpp_field.h>
+#include <compiler/cpp/cpp_helpers.h>
+#include <compiler/cpp/cpp_message.h>
+#include <compiler/cpp/cpp_service.h>
+#include <compiler/scc.h>
+#include <descriptor.pb.h>
+#include <io/printer.h>
+#include <stubs/strutil.h>
+
+// Must be last.
+#include <port_def.inc>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+namespace {
+
+// When we forward-declare things, we want to create a sorted order so our
+// output is deterministic and minimizes namespace changes.
+template <class T>
+std::string GetSortKey(const T& val) {
+ return val.full_name();
+}
+
+template <>
+std::string GetSortKey<FileDescriptor>(const FileDescriptor& val) {
+ return val.name();
+}
+
+template <class T>
+bool CompareSortKeys(const T* a, const T* b) {
+ return GetSortKey(*a) < GetSortKey(*b);
+}
+
+template <class T>
+std::vector<const T*> Sorted(const std::unordered_set<const T*>& vals) {
+ std::vector<const T*> sorted(vals.begin(), vals.end());
+ std::sort(sorted.begin(), sorted.end(), CompareSortKeys<T>);
+ return sorted;
+}
+
+} // namespace
+
+FileGenerator::FileGenerator(const FileDescriptor* file, const Options& options)
+ : file_(file), options_(options), scc_analyzer_(options) {
+ // These variables are the same on a file level
+ SetCommonVars(options, &variables_);
+ variables_["dllexport_decl"] = options.dllexport_decl;
+ variables_["tablename"] = UniqueName("TableStruct", file_, options_);
+ variables_["file_level_metadata"] =
+ UniqueName("file_level_metadata", file_, options_);
+ variables_["desc_table"] = DescriptorTableName(file_, options_);
+ variables_["file_level_enum_descriptors"] =
+ UniqueName("file_level_enum_descriptors", file_, options_);
+ variables_["file_level_service_descriptors"] =
+ UniqueName("file_level_service_descriptors", file_, options_);
+ variables_["filename"] = file_->name();
+ variables_["package_ns"] = Namespace(file_, options);
+
+ std::vector<const Descriptor*> msgs = FlattenMessagesInFile(file);
+ for (int i = 0; i < msgs.size(); i++) {
+ // Deleted in destructor
+ MessageGenerator* msg_gen =
+ new MessageGenerator(msgs[i], variables_, i, options, &scc_analyzer_);
+ message_generators_.emplace_back(msg_gen);
+ msg_gen->AddGenerators(&enum_generators_, &extension_generators_);
+ }
+
+ for (int i = 0; i < file->enum_type_count(); i++) {
+ enum_generators_.emplace_back(
+ new EnumGenerator(file->enum_type(i), variables_, options));
+ }
+
+ for (int i = 0; i < file->service_count(); i++) {
+ service_generators_.emplace_back(
+ new ServiceGenerator(file->service(i), variables_, options));
+ }
+ if (HasGenericServices(file_, options_)) {
+ for (int i = 0; i < service_generators_.size(); i++) {
+ service_generators_[i]->index_in_metadata_ = i;
+ }
+ }
+ for (int i = 0; i < file->extension_count(); i++) {
+ extension_generators_.emplace_back(
+ new ExtensionGenerator(file->extension(i), options, &scc_analyzer_));
+ }
+ for (int i = 0; i < file->weak_dependency_count(); ++i) {
+ weak_deps_.insert(file->weak_dependency(i));
+ }
+}
+
+FileGenerator::~FileGenerator() = default;
+
+void FileGenerator::GenerateMacroUndefs(io::Printer* printer) {
+ Formatter format(printer, variables_);
+ // Only do this for protobuf's own types. There are some google3 protos using
+ // macros as field names and the generated code compiles after the macro
+ // expansion. Undefing these macros actually breaks such code.
+ if (file_->name() != "net/proto2/compiler/proto/plugin.proto" &&
+ file_->name() != "google/protobuf/compiler/plugin.proto") {
+ return;
+ }
+ std::vector<std::string> names_to_undef;
+ std::vector<const FieldDescriptor*> fields;
+ ListAllFields(file_, &fields);
+ for (int i = 0; i < fields.size(); i++) {
+ const std::string& name = fields[i]->name();
+ static const char* kMacroNames[] = {"major", "minor"};
+ for (int j = 0; j < GOOGLE_ARRAYSIZE(kMacroNames); ++j) {
+ if (name == kMacroNames[j]) {
+ names_to_undef.push_back(name);
+ break;
+ }
+ }
+ }
+ for (int i = 0; i < names_to_undef.size(); ++i) {
+ format(
+ "#ifdef $1$\n"
+ "#undef $1$\n"
+ "#endif\n",
+ names_to_undef[i]);
+ }
+}
+
+void FileGenerator::GenerateHeader(io::Printer* printer) {
+ Formatter format(printer, variables_);
+
+ // port_def.inc must be included after all other includes.
+ IncludeFile("net/proto2/public/port_def.inc", printer);
+ format("#define $1$$ dllexport_decl$\n", FileDllExport(file_, options_));
+ GenerateMacroUndefs(printer);
+
+ // For Any support with lite protos, we need to friend AnyMetadata, so we
+ // forward-declare it here.
+ format(
+ "PROTOBUF_NAMESPACE_OPEN\n"
+ "namespace internal {\n"
+ "class AnyMetadata;\n"
+ "} // namespace internal\n"
+ "PROTOBUF_NAMESPACE_CLOSE\n");
+
+ GenerateGlobalStateFunctionDeclarations(printer);
+
+ GenerateForwardDeclarations(printer);
+
+ {
+ NamespaceOpener ns(Namespace(file_, options_), format);
+
+ format("\n");
+
+ GenerateEnumDefinitions(printer);
+
+ format(kThickSeparator);
+ format("\n");
+
+ GenerateMessageDefinitions(printer);
+
+ format("\n");
+ format(kThickSeparator);
+ format("\n");
+
+ GenerateServiceDefinitions(printer);
+
+ GenerateExtensionIdentifiers(printer);
+
+ format("\n");
+ format(kThickSeparator);
+ format("\n");
+
+ GenerateInlineFunctionDefinitions(printer);
+
+ format(
+ "\n"
+ "// @@protoc_insertion_point(namespace_scope)\n"
+ "\n");
+ }
+
+ // We need to specialize some templates in the ::google::protobuf namespace:
+ GenerateProto2NamespaceEnumSpecializations(printer);
+
+ format(
+ "\n"
+ "// @@protoc_insertion_point(global_scope)\n"
+ "\n");
+ IncludeFile("net/proto2/public/port_undef.inc", printer);
+}
+
+void FileGenerator::GenerateProtoHeader(io::Printer* printer,
+ const std::string& info_path) {
+ Formatter format(printer, variables_);
+ if (!options_.proto_h) {
+ return;
+ }
+
+ GenerateTopHeaderGuard(printer, false);
+
+ if (!options_.opensource_runtime) {
+ format(
+ "#ifdef SWIG\n"
+ "#error \"Do not SWIG-wrap protobufs.\"\n"
+ "#endif // SWIG\n"
+ "\n");
+ }
+
+ if (IsBootstrapProto(options_, file_)) {
+ format("// IWYU pragma: private, include \"$1$.proto.h\"\n\n",
+ StripProto(file_->name()));
+ }
+
+ GenerateLibraryIncludes(printer);
+
+ for (int i = 0; i < file_->public_dependency_count(); i++) {
+ const FileDescriptor* dep = file_->public_dependency(i);
+ format("#include \"$1$.proto.h\"\n", StripProto(dep->name()));
+ }
+
+ format("// @@protoc_insertion_point(includes)\n");
+
+ GenerateMetadataPragma(printer, info_path);
+
+ GenerateHeader(printer);
+
+ GenerateBottomHeaderGuard(printer, false);
+}
+
+void FileGenerator::GeneratePBHeader(io::Printer* printer,
+ const std::string& info_path) {
+ Formatter format(printer, variables_);
+ GenerateTopHeaderGuard(printer, true);
+
+ if (options_.proto_h) {
+ std::string target_basename = StripProto(file_->name());
+ if (!options_.opensource_runtime) {
+ GetBootstrapBasename(options_, target_basename, &target_basename);
+ }
+ format("#include \"$1$.proto.h\" // IWYU pragma: export\n",
+ target_basename);
+ } else {
+ GenerateLibraryIncludes(printer);
+ }
+
+ if (options_.transitive_pb_h) {
+ GenerateDependencyIncludes(printer);
+ }
+
+ // This is unfortunately necessary for some plugins. I don't see why we
+ // need two of the same insertion points.
+ // TODO(gerbens) remove this.
+ format("// @@protoc_insertion_point(includes)\n");
+
+ GenerateMetadataPragma(printer, info_path);
+
+ if (!options_.proto_h) {
+ GenerateHeader(printer);
+ } else {
+ {
+ NamespaceOpener ns(Namespace(file_, options_), format);
+ format(
+ "\n"
+ "// @@protoc_insertion_point(namespace_scope)\n");
+ }
+ format(
+ "\n"
+ "// @@protoc_insertion_point(global_scope)\n"
+ "\n");
+ }
+
+ GenerateBottomHeaderGuard(printer, true);
+}
+
+void FileGenerator::DoIncludeFile(const std::string& google3_name,
+ bool do_export, io::Printer* printer) {
+ Formatter format(printer, variables_);
+ const std::string prefix = "net/proto2/";
+ GOOGLE_CHECK(google3_name.find(prefix) == 0) << google3_name;
+
+ if (options_.opensource_runtime) {
+ std::string path = google3_name.substr(prefix.size());
+
+ path = StringReplace(path, "internal/", "", false);
+ path = StringReplace(path, "proto/", "", false);
+ path = StringReplace(path, "public/", "", false);
+ if (options_.runtime_include_base.empty()) {
+ format("#include <$1$>", path);
+ } else {
+ format("#include \"$1$google/protobuf/$2$\"",
+ options_.runtime_include_base, path);
+ }
+ } else {
+ format("#include \"$1$\"", google3_name);
+ }
+
+ if (do_export) {
+ format(" // IWYU pragma: export");
+ }
+
+ format("\n");
+}
+
+std::string FileGenerator::CreateHeaderInclude(const std::string& basename,
+ const FileDescriptor* file) {
+ bool use_system_include = false;
+ std::string name = basename;
+
+ if (options_.opensource_runtime) {
+ if (IsWellKnownMessage(file)) {
+ if (options_.runtime_include_base.empty()) {
+ use_system_include = true;
+ } else {
+ name = options_.runtime_include_base + basename;
+ }
+ }
+ }
+
+ std::string left = "\"";
+ std::string right = "\"";
+ if (use_system_include) {
+ left = "<";
+ right = ">";
+ }
+ return left + name + right;
+}
+
+void FileGenerator::GenerateSourceIncludes(io::Printer* printer) {
+ Formatter format(printer, variables_);
+ std::string target_basename = StripProto(file_->name());
+ if (!options_.opensource_runtime) {
+ GetBootstrapBasename(options_, target_basename, &target_basename);
+ }
+ target_basename += options_.proto_h ? ".proto.h" : ".pb.h";
+ format(
+ "// Generated by the protocol buffer compiler. DO NOT EDIT!\n"
+ "// source: $filename$\n"
+ "\n"
+ "#include $1$\n"
+ "\n"
+ "#include <algorithm>\n" // for swap()
+ "\n",
+ CreateHeaderInclude(target_basename, file_));
+
+ IncludeFile("net/proto2/io/public/coded_stream.h", printer);
+ // TODO(gerbens) This is to include parse_context.h, we need a better way
+ IncludeFile("net/proto2/public/extension_set.h", printer);
+ IncludeFile("net/proto2/public/wire_format_lite.h", printer);
+
+ // Unknown fields implementation in lite mode uses StringOutputStream
+ if (!UseUnknownFieldSet(file_, options_) && !message_generators_.empty()) {
+ IncludeFile("net/proto2/io/public/zero_copy_stream_impl_lite.h", printer);
+ }
+
+ if (HasDescriptorMethods(file_, options_)) {
+ IncludeFile("net/proto2/public/descriptor.h", printer);
+ IncludeFile("net/proto2/public/generated_message_reflection.h", printer);
+ IncludeFile("net/proto2/public/reflection_ops.h", printer);
+ IncludeFile("net/proto2/public/wire_format.h", printer);
+ }
+
+ if (HasGeneratedMethods(file_, options_) &&
+ options_.tctable_mode != Options::kTCTableNever) {
+ IncludeFile("net/proto2/public/generated_message_tctable_impl.h", printer);
+ }
+
+ if (options_.proto_h) {
+ // Use the smaller .proto.h files.
+ for (int i = 0; i < file_->dependency_count(); i++) {
+ const FileDescriptor* dep = file_->dependency(i);
+ // Do not import weak deps.
+ if (!options_.opensource_runtime && IsDepWeak(dep)) continue;
+ std::string basename = StripProto(dep->name());
+ if (IsBootstrapProto(options_, file_)) {
+ GetBootstrapBasename(options_, basename, &basename);
+ }
+ format("#include \"$1$.proto.h\"\n", basename);
+ }
+ }
+ if (HasCordFields(file_, options_)) {
+ format(
+ "#include \"third_party/absl/strings/internal/string_constant.h\"\n");
+ }
+
+ format("// @@protoc_insertion_point(includes)\n");
+ IncludeFile("net/proto2/public/port_def.inc", printer);
+
+ // For MSVC builds, we use #pragma init_seg to move the initialization of our
+ // libraries to happen before the user code.
+ // This worksaround the fact that MSVC does not do constant initializers when
+ // required by the standard.
+ format("\nPROTOBUF_PRAGMA_INIT_SEG\n");
+}
+
+void FileGenerator::GenerateSourceDefaultInstance(int idx,
+ io::Printer* printer) {
+ Formatter format(printer, variables_);
+ MessageGenerator* generator = message_generators_[idx].get();
+ generator->GenerateConstexprConstructor(printer);
+ // Use a union to disable the destructor of the _instance member.
+ // We can constant initialize, but the object will still have a non-trivial
+ // destructor that we need to elide.
+ format(
+ "struct $1$ {\n"
+ " constexpr $1$()\n"
+ " : _instance(::$proto_ns$::internal::ConstantInitialized{}) {}\n"
+ " ~$1$() {}\n"
+ " union {\n"
+ " $2$ _instance;\n"
+ " };\n"
+ "};\n",
+ DefaultInstanceType(generator->descriptor_, options_),
+ generator->classname_);
+ // NO_DESTROY is not necessary for correctness. The empty destructor is
+ // enough. However, the empty destructor fails to be elided in some
+ // configurations (like non-opt or with certain sanitizers). NO_DESTROY is
+ // there just to improve performance and binary size in these builds.
+ format("PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT $1$ $2$;\n",
+ DefaultInstanceType(generator->descriptor_, options_),
+ DefaultInstanceName(generator->descriptor_, options_));
+
+ for (int i = 0; i < generator->descriptor_->field_count(); i++) {
+ const FieldDescriptor* field = generator->descriptor_->field(i);
+ if (IsStringInlined(field, options_)) {
+ // Force the initialization of the inlined string in the default instance.
+ format(
+ "PROTOBUF_ATTRIBUTE_INIT_PRIORITY std::true_type "
+ "$1$::_init_inline_$2$_ = "
+ "($3$._instance.$2$_.Init(), std::true_type{});\n",
+ ClassName(generator->descriptor_), FieldName(field),
+ DefaultInstanceName(generator->descriptor_, options_));
+ }
+ }
+
+ if (options_.lite_implicit_weak_fields) {
+ format("$1$* $2$ = &$3$;\n",
+ DefaultInstanceType(generator->descriptor_, options_),
+ DefaultInstancePtr(generator->descriptor_, options_),
+ DefaultInstanceName(generator->descriptor_, options_));
+ }
+}
+
+// A list of things defined in one .pb.cc file that we need to reference from
+// another .pb.cc file.
+struct FileGenerator::CrossFileReferences {
+ // Populated if we are referencing from messages or files.
+ std::unordered_set<const Descriptor*> weak_default_instances;
+
+ // Only if we are referencing from files.
+ std::unordered_set<const FileDescriptor*> strong_reflection_files;
+ std::unordered_set<const FileDescriptor*> weak_reflection_files;
+};
+
+void FileGenerator::GetCrossFileReferencesForField(const FieldDescriptor* field,
+ CrossFileReferences* refs) {
+ const Descriptor* msg = field->message_type();
+ if (msg == nullptr) return;
+
+ if (IsImplicitWeakField(field, options_, &scc_analyzer_) ||
+ IsWeak(field, options_)) {
+ refs->weak_default_instances.insert(msg);
+ }
+}
+
+void FileGenerator::GetCrossFileReferencesForFile(const FileDescriptor* file,
+ CrossFileReferences* refs) {
+ ForEachField(file, [this, refs](const FieldDescriptor* field) {
+ GetCrossFileReferencesForField(field, refs);
+ });
+
+ if (!HasDescriptorMethods(file, options_)) return;
+
+ for (int i = 0; i < file->dependency_count(); i++) {
+ const FileDescriptor* dep = file->dependency(i);
+ if (IsDepWeak(dep)) {
+ refs->weak_reflection_files.insert(dep);
+ } else {
+ refs->strong_reflection_files.insert(dep);
+ }
+ }
+}
+
+// Generates references to variables defined in other files.
+void FileGenerator::GenerateInternalForwardDeclarations(
+ const CrossFileReferences& refs, io::Printer* printer) {
+ Formatter format(printer, variables_);
+
+ {
+ NamespaceOpener ns(format);
+ for (auto instance : Sorted(refs.weak_default_instances)) {
+ ns.ChangeTo(Namespace(instance, options_));
+ if (options_.lite_implicit_weak_fields) {
+ format("extern $1$ $2$;\n", DefaultInstanceType(instance, options_),
+ DefaultInstanceName(instance, options_));
+ format("__attribute__((weak)) $1$* $2$ = nullptr;\n",
+ DefaultInstanceType(instance, options_),
+ DefaultInstancePtr(instance, options_));
+ } else {
+ format("extern __attribute__((weak)) $1$ $2$;\n",
+ DefaultInstanceType(instance, options_),
+ DefaultInstanceName(instance, options_));
+ }
+ }
+ }
+
+ for (auto file : Sorted(refs.weak_reflection_files)) {
+ format(
+ "extern __attribute__((weak)) const "
+ "::$proto_ns$::internal::DescriptorTable $1$;\n",
+ DescriptorTableName(file, options_));
+ }
+}
+
+void FileGenerator::GenerateSourceForMessage(int idx, io::Printer* printer) {
+ Formatter format(printer, variables_);
+ GenerateSourceIncludes(printer);
+
+ CrossFileReferences refs;
+ ForEachField(message_generators_[idx]->descriptor_,
+ [this, &refs](const FieldDescriptor* field) {
+ GetCrossFileReferencesForField(field, &refs);
+ });
+ GenerateInternalForwardDeclarations(refs, printer);
+
+ { // package namespace
+ NamespaceOpener ns(Namespace(file_, options_), format);
+
+ // Define default instances
+ GenerateSourceDefaultInstance(idx, printer);
+
+ // Generate classes.
+ format("\n");
+ message_generators_[idx]->GenerateClassMethods(printer);
+
+ format(
+ "\n"
+ "// @@protoc_insertion_point(namespace_scope)\n");
+ } // end package namespace
+
+ {
+ NamespaceOpener proto_ns(ProtobufNamespace(options_), format);
+ message_generators_[idx]->GenerateSourceInProto2Namespace(printer);
+ }
+
+ format(
+ "\n"
+ "// @@protoc_insertion_point(global_scope)\n");
+}
+
+void FileGenerator::GenerateSourceForExtension(int idx, io::Printer* printer) {
+ Formatter format(printer, variables_);
+ GenerateSourceIncludes(printer);
+ NamespaceOpener ns(Namespace(file_, options_), format);
+ extension_generators_[idx]->GenerateDefinition(printer);
+}
+
+void FileGenerator::GenerateGlobalSource(io::Printer* printer) {
+ Formatter format(printer, variables_);
+ GenerateSourceIncludes(printer);
+
+ {
+ GenerateTables(printer);
+
+ // Define the code to initialize reflection. This code uses a global
+ // constructor to register reflection data with the runtime pre-main.
+ if (HasDescriptorMethods(file_, options_)) {
+ GenerateReflectionInitializationCode(printer);
+ }
+ }
+
+ NamespaceOpener ns(Namespace(file_, options_), format);
+
+ // Generate enums.
+ for (int i = 0; i < enum_generators_.size(); i++) {
+ enum_generators_[i]->GenerateMethods(i, printer);
+ }
+}
+
+void FileGenerator::GenerateSource(io::Printer* printer) {
+ Formatter format(printer, variables_);
+ GenerateSourceIncludes(printer);
+ CrossFileReferences refs;
+ GetCrossFileReferencesForFile(file_, &refs);
+ GenerateInternalForwardDeclarations(refs, printer);
+
+ {
+ NamespaceOpener ns(Namespace(file_, options_), format);
+
+ // Define default instances
+ for (int i = 0; i < message_generators_.size(); i++) {
+ GenerateSourceDefaultInstance(i, printer);
+ }
+ }
+
+ {
+ GenerateTables(printer);
+
+ if (HasDescriptorMethods(file_, options_)) {
+ // Define the code to initialize reflection. This code uses a global
+ // constructor to register reflection data with the runtime pre-main.
+ GenerateReflectionInitializationCode(printer);
+ }
+ }
+
+ {
+ NamespaceOpener ns(Namespace(file_, options_), format);
+
+ // Actually implement the protos
+
+ // Generate enums.
+ for (int i = 0; i < enum_generators_.size(); i++) {
+ enum_generators_[i]->GenerateMethods(i, printer);
+ }
+
+ // Generate classes.
+ for (int i = 0; i < message_generators_.size(); i++) {
+ format("\n");
+ format(kThickSeparator);
+ format("\n");
+ message_generators_[i]->GenerateClassMethods(printer);
+ }
+
+ if (HasGenericServices(file_, options_)) {
+ // Generate services.
+ for (int i = 0; i < service_generators_.size(); i++) {
+ if (i == 0) format("\n");
+ format(kThickSeparator);
+ format("\n");
+ service_generators_[i]->GenerateImplementation(printer);
+ }
+ }
+
+ // Define extensions.
+ for (int i = 0; i < extension_generators_.size(); i++) {
+ extension_generators_[i]->GenerateDefinition(printer);
+ }
+
+ format(
+ "\n"
+ "// @@protoc_insertion_point(namespace_scope)\n");
+ }
+
+ {
+ NamespaceOpener proto_ns(ProtobufNamespace(options_), format);
+ for (int i = 0; i < message_generators_.size(); i++) {
+ message_generators_[i]->GenerateSourceInProto2Namespace(printer);
+ }
+ }
+
+ format(
+ "\n"
+ "// @@protoc_insertion_point(global_scope)\n");
+
+ IncludeFile("net/proto2/public/port_undef.inc", printer);
+}
+
+void FileGenerator::GenerateReflectionInitializationCode(io::Printer* printer) {
+ Formatter format(printer, variables_);
+
+ if (!message_generators_.empty()) {
+ format("static ::$proto_ns$::Metadata $file_level_metadata$[$1$];\n",
+ message_generators_.size());
+ }
+ if (!enum_generators_.empty()) {
+ format(
+ "static "
+ "const ::$proto_ns$::EnumDescriptor* "
+ "$file_level_enum_descriptors$[$1$];\n",
+ enum_generators_.size());
+ } else {
+ format(
+ "static "
+ "constexpr ::$proto_ns$::EnumDescriptor const** "
+ "$file_level_enum_descriptors$ = nullptr;\n");
+ }
+ if (HasGenericServices(file_, options_) && file_->service_count() > 0) {
+ format(
+ "static "
+ "const ::$proto_ns$::ServiceDescriptor* "
+ "$file_level_service_descriptors$[$1$];\n",
+ file_->service_count());
+ } else {
+ format(
+ "static "
+ "constexpr ::$proto_ns$::ServiceDescriptor const** "
+ "$file_level_service_descriptors$ = nullptr;\n");
+ }
+
+ if (!message_generators_.empty()) {
+ format(
+ "\n"
+ "const $uint32$ $tablename$::offsets[] "
+ "PROTOBUF_SECTION_VARIABLE(protodesc_cold) = {\n");
+ format.Indent();
+ std::vector<std::pair<size_t, size_t> > pairs;
+ pairs.reserve(message_generators_.size());
+ for (int i = 0; i < message_generators_.size(); i++) {
+ pairs.push_back(message_generators_[i]->GenerateOffsets(printer));
+ }
+ format.Outdent();
+ format(
+ "};\n"
+ "static const ::$proto_ns$::internal::MigrationSchema schemas[] "
+ "PROTOBUF_SECTION_VARIABLE(protodesc_cold) = {\n");
+ format.Indent();
+ {
+ int offset = 0;
+ for (int i = 0; i < message_generators_.size(); i++) {
+ message_generators_[i]->GenerateSchema(printer, offset,
+ pairs[i].second);
+ offset += pairs[i].first;
+ }
+ }
+ format.Outdent();
+ format(
+ "};\n"
+ "\nstatic "
+ "::$proto_ns$::Message const * const file_default_instances[] = {\n");
+ format.Indent();
+ for (int i = 0; i < message_generators_.size(); i++) {
+ const Descriptor* descriptor = message_generators_[i]->descriptor_;
+ format(
+ "reinterpret_cast<const "
+ "::$proto_ns$::Message*>(&$1$::_$2$_default_instance_),\n",
+ Namespace(descriptor, options_), // 1
+ ClassName(descriptor)); // 2
+ }
+ format.Outdent();
+ format(
+ "};\n"
+ "\n");
+ } else {
+ // we still need these symbols to exist
+ format(
+ // MSVC doesn't like empty arrays, so we add a dummy.
+ "const $uint32$ $tablename$::offsets[1] = {};\n"
+ "static constexpr ::$proto_ns$::internal::MigrationSchema* schemas = "
+ "nullptr;"
+ "\n"
+ "static constexpr ::$proto_ns$::Message* const* "
+ "file_default_instances = nullptr;\n"
+ "\n");
+ }
+
+ // ---------------------------------------------------------------
+
+ // Embed the descriptor. We simply serialize the entire
+ // FileDescriptorProto/ and embed it as a string literal, which is parsed and
+ // built into real descriptors at initialization time.
+ const std::string protodef_name =
+ UniqueName("descriptor_table_protodef", file_, options_);
+ format("const char $1$[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) =\n",
+ protodef_name);
+ format.Indent();
+ FileDescriptorProto file_proto;
+ file_->CopyTo(&file_proto);
+ std::string file_data;
+ file_proto.SerializeToString(&file_data);
+
+ {
+ if (file_data.size() > 65535) {
+ // Workaround for MSVC: "Error C1091: compiler limit: string exceeds
+ // 65535 bytes in length". Declare a static array of chars rather than
+ // use a string literal. Only write 25 bytes per line.
+ static const int kBytesPerLine = 25;
+ format("{ ");
+ for (int i = 0; i < file_data.size();) {
+ for (int j = 0; j < kBytesPerLine && i < file_data.size(); ++i, ++j) {
+ format("'$1$', ", CEscape(file_data.substr(i, 1)));
+ }
+ format("\n");
+ }
+ format("'\\0' }"); // null-terminate
+ } else {
+ // Only write 40 bytes per line.
+ static const int kBytesPerLine = 40;
+ for (int i = 0; i < file_data.size(); i += kBytesPerLine) {
+ format(
+ "\"$1$\"\n",
+ EscapeTrigraphs(CEscape(file_data.substr(i, kBytesPerLine))));
+ }
+ }
+ format(";\n");
+ }
+ format.Outdent();
+
+ CrossFileReferences refs;
+ GetCrossFileReferencesForFile(file_, &refs);
+ int num_deps =
+ refs.strong_reflection_files.size() + refs.weak_reflection_files.size();
+
+ // Build array of DescriptorTable deps.
+ if (num_deps > 0) {
+ format(
+ "static const ::$proto_ns$::internal::DescriptorTable*const "
+ "$desc_table$_deps[$1$] = {\n",
+ num_deps);
+
+ for (auto dep : Sorted(refs.strong_reflection_files)) {
+ format(" &::$1$,\n", DescriptorTableName(dep, options_));
+ }
+ for (auto dep : Sorted(refs.weak_reflection_files)) {
+ format(" &::$1$,\n", DescriptorTableName(dep, options_));
+ }
+
+ format("};\n");
+ }
+
+ // The DescriptorTable itself.
+ // Should be "bool eager = NeedsEagerDescriptorAssignment(file_, options_);"
+ // however this might cause a tsan failure in superroot b/148382879,
+ // so disable for now.
+ bool eager = false;
+ format(
+ "static ::$proto_ns$::internal::once_flag $desc_table$_once;\n"
+ "const ::$proto_ns$::internal::DescriptorTable $desc_table$ = {\n"
+ " false, $1$, $2$, $3$, \"$filename$\", \n"
+ " &$desc_table$_once, $4$, $5$, $6$,\n"
+ " schemas, file_default_instances, $tablename$::offsets,\n"
+ " $7$, $file_level_enum_descriptors$, "
+ "$file_level_service_descriptors$,\n"
+ "};\n"
+ // This function exists to be marked as weak.
+ // It can significantly speed up compilation by breaking up LLVM's SCC in
+ // the .pb.cc translation units. Large translation units see a reduction
+ // of more than 35% of walltime for optimized builds.
+ // Without the weak attribute all the messages in the file, including all
+ // the vtables and everything they use become part of the same SCC through
+ // a cycle like:
+ // GetMetadata -> descriptor table -> default instances ->
+ // vtables -> GetMetadata
+ // By adding a weak function here we break the connection from the
+ // individual vtables back into the descriptor table.
+ "PROTOBUF_ATTRIBUTE_WEAK const ::$proto_ns$::internal::DescriptorTable* "
+ "$desc_table$_getter() {\n"
+ " return &$desc_table$;\n"
+ "}\n"
+ "\n",
+ eager ? "true" : "false", file_data.size(), protodef_name,
+ num_deps == 0 ? "nullptr" : variables_["desc_table"] + "_deps", num_deps,
+ message_generators_.size(),
+ message_generators_.empty() ? "nullptr"
+ : variables_["file_level_metadata"]);
+
+ // For descriptor.proto we want to avoid doing any dynamic initialization,
+ // because in some situations that would otherwise pull in a lot of
+ // unnecessary code that can't be stripped by --gc-sections. Descriptor
+ // initialization will still be performed lazily when it's needed.
+ if (file_->name() != "net/proto2/proto/descriptor.proto") {
+ format(
+ "// Force running AddDescriptors() at dynamic initialization time.\n"
+ "PROTOBUF_ATTRIBUTE_INIT_PRIORITY "
+ "static ::$proto_ns$::internal::AddDescriptorsRunner "
+ "$1$(&$desc_table$);\n",
+ UniqueName("dynamic_init_dummy", file_, options_));
+ }
+}
+
+void FileGenerator::GenerateTables(io::Printer* printer) {
+ Formatter format(printer, variables_);
+ if (options_.table_driven_parsing) {
+ // TODO(ckennelly): Gate this with the same options flag to enable
+ // table-driven parsing.
+ format(
+ "PROTOBUF_CONSTEXPR_VAR ::$proto_ns$::internal::ParseTableField\n"
+ " const $tablename$::entries[] "
+ "PROTOBUF_SECTION_VARIABLE(protodesc_cold) = {\n");
+ format.Indent();
+
+ std::vector<size_t> entries;
+ size_t count = 0;
+ for (int i = 0; i < message_generators_.size(); i++) {
+ size_t value = message_generators_[i]->GenerateParseOffsets(printer);
+ entries.push_back(value);
+ count += value;
+ }
+
+ // We need these arrays to exist, and MSVC does not like empty arrays.
+ if (count == 0) {
+ format("{0, 0, 0, ::$proto_ns$::internal::kInvalidMask, 0, 0},\n");
+ }
+
+ format.Outdent();
+ format(
+ "};\n"
+ "\n"
+ "PROTOBUF_CONSTEXPR_VAR "
+ "::$proto_ns$::internal::AuxiliaryParseTableField\n"
+ " const $tablename$::aux[] "
+ "PROTOBUF_SECTION_VARIABLE(protodesc_cold) = {\n");
+ format.Indent();
+
+ std::vector<size_t> aux_entries;
+ count = 0;
+ for (int i = 0; i < message_generators_.size(); i++) {
+ size_t value = message_generators_[i]->GenerateParseAuxTable(printer);
+ aux_entries.push_back(value);
+ count += value;
+ }
+
+ if (count == 0) {
+ format("::$proto_ns$::internal::AuxiliaryParseTableField(),\n");
+ }
+
+ format.Outdent();
+ format(
+ "};\n"
+ "PROTOBUF_CONSTEXPR_VAR ::$proto_ns$::internal::ParseTable const\n"
+ " $tablename$::schema[] "
+ "PROTOBUF_SECTION_VARIABLE(protodesc_cold) = {\n");
+ format.Indent();
+
+ size_t offset = 0;
+ size_t aux_offset = 0;
+ for (int i = 0; i < message_generators_.size(); i++) {
+ message_generators_[i]->GenerateParseTable(printer, offset, aux_offset);
+ offset += entries[i];
+ aux_offset += aux_entries[i];
+ }
+
+ if (message_generators_.empty()) {
+ format("{ nullptr, nullptr, 0, -1, -1, false },\n");
+ }
+
+ format.Outdent();
+ format(
+ "};\n"
+ "\n");
+ }
+
+ if (!message_generators_.empty() && options_.table_driven_serialization) {
+ format(
+ "const ::$proto_ns$::internal::FieldMetadata "
+ "$tablename$::field_metadata[] "
+ "= {\n");
+ format.Indent();
+ std::vector<int> field_metadata_offsets;
+ int idx = 0;
+ for (int i = 0; i < message_generators_.size(); i++) {
+ field_metadata_offsets.push_back(idx);
+ idx += message_generators_[i]->GenerateFieldMetadata(printer);
+ }
+ field_metadata_offsets.push_back(idx);
+ format.Outdent();
+ format(
+ "};\n"
+ "const ::$proto_ns$::internal::SerializationTable "
+ "$tablename$::serialization_table[] = {\n");
+ format.Indent();
+ // We rely on the order we layout the tables to match the order we
+ // calculate them with FlattenMessagesInFile, so we check here that
+ // these match exactly.
+ std::vector<const Descriptor*> calculated_order =
+ FlattenMessagesInFile(file_);
+ GOOGLE_CHECK_EQ(calculated_order.size(), message_generators_.size());
+ for (int i = 0; i < message_generators_.size(); i++) {
+ GOOGLE_CHECK_EQ(calculated_order[i], message_generators_[i]->descriptor_);
+ format("{$1$, $tablename$::field_metadata + $2$},\n",
+ field_metadata_offsets[i + 1] - field_metadata_offsets[i], // 1
+ field_metadata_offsets[i]); // 2
+ }
+ format.Outdent();
+ format(
+ "};\n"
+ "\n");
+ }
+}
+
+class FileGenerator::ForwardDeclarations {
+ public:
+ void AddMessage(const Descriptor* d) { classes_[ClassName(d)] = d; }
+ void AddEnum(const EnumDescriptor* d) { enums_[ClassName(d)] = d; }
+
+ void Print(const Formatter& format, const Options& options) const {
+ for (const auto& p : enums_) {
+ const std::string& enumname = p.first;
+ const EnumDescriptor* enum_desc = p.second;
+ format(
+ "enum ${1$$2$$}$ : int;\n"
+ "bool $2$_IsValid(int value);\n",
+ enum_desc, enumname);
+ }
+ for (const auto& p : classes_) {
+ const std::string& classname = p.first;
+ const Descriptor* class_desc = p.second;
+ format(
+ "class ${1$$2$$}$;\n"
+ "struct $3$;\n"
+ "$dllexport_decl $extern $3$ $4$;\n",
+ class_desc, classname, DefaultInstanceType(class_desc, options),
+ DefaultInstanceName(class_desc, options));
+ }
+ }
+
+ void PrintTopLevelDecl(const Formatter& format,
+ const Options& options) const {
+ for (const auto& pair : classes_) {
+ format(
+ "template<> $dllexport_decl $"
+ "$1$* Arena::CreateMaybeMessage<$1$>(Arena*);\n",
+ QualifiedClassName(pair.second, options));
+ }
+ }
+
+ private:
+ std::map<std::string, const Descriptor*> classes_;
+ std::map<std::string, const EnumDescriptor*> enums_;
+};
+
+static void PublicImportDFS(const FileDescriptor* fd,
+ std::unordered_set<const FileDescriptor*>* fd_set) {
+ for (int i = 0; i < fd->public_dependency_count(); i++) {
+ const FileDescriptor* dep = fd->public_dependency(i);
+ if (fd_set->insert(dep).second) PublicImportDFS(dep, fd_set);
+ }
+}
+
+void FileGenerator::GenerateForwardDeclarations(io::Printer* printer) {
+ Formatter format(printer, variables_);
+ std::vector<const Descriptor*> classes;
+ std::vector<const EnumDescriptor*> enums;
+
+ FlattenMessagesInFile(file_, &classes); // All messages need forward decls.
+
+ if (options_.proto_h) { // proto.h needs extra forward declarations.
+ // All classes / enums referred to as field members
+ std::vector<const FieldDescriptor*> fields;
+ ListAllFields(file_, &fields);
+ for (int i = 0; i < fields.size(); i++) {
+ classes.push_back(fields[i]->containing_type());
+ classes.push_back(fields[i]->message_type());
+ enums.push_back(fields[i]->enum_type());
+ }
+ ListAllTypesForServices(file_, &classes);
+ }
+
+ // Calculate the set of files whose definitions we get through include.
+ // No need to forward declare types that are defined in these.
+ std::unordered_set<const FileDescriptor*> public_set;
+ PublicImportDFS(file_, &public_set);
+
+ std::map<std::string, ForwardDeclarations> decls;
+ for (int i = 0; i < classes.size(); i++) {
+ const Descriptor* d = classes[i];
+ if (d && !public_set.count(d->file()))
+ decls[Namespace(d, options_)].AddMessage(d);
+ }
+ for (int i = 0; i < enums.size(); i++) {
+ const EnumDescriptor* d = enums[i];
+ if (d && !public_set.count(d->file()))
+ decls[Namespace(d, options_)].AddEnum(d);
+ }
+
+ {
+ NamespaceOpener ns(format);
+ for (const auto& pair : decls) {
+ ns.ChangeTo(pair.first);
+ pair.second.Print(format, options_);
+ }
+ }
+ format("PROTOBUF_NAMESPACE_OPEN\n");
+ for (const auto& pair : decls) {
+ pair.second.PrintTopLevelDecl(format, options_);
+ }
+ format("PROTOBUF_NAMESPACE_CLOSE\n");
+}
+
+void FileGenerator::GenerateTopHeaderGuard(io::Printer* printer, bool pb_h) {
+ Formatter format(printer, variables_);
+ // Generate top of header.
+ format(
+ "// Generated by the protocol buffer compiler. DO NOT EDIT!\n"
+ "// source: $filename$\n"
+ "\n"
+ "#ifndef $1$\n"
+ "#define $1$\n"
+ "\n"
+ "#include <limits>\n"
+ "#include <string>\n",
+ IncludeGuard(file_, pb_h, options_));
+ if (!options_.opensource_runtime && !enum_generators_.empty()) {
+ // Add header to provide std::is_integral for safe Enum_Name() function.
+ format("#include <type_traits>\n");
+ }
+ format("\n");
+}
+
+void FileGenerator::GenerateBottomHeaderGuard(io::Printer* printer, bool pb_h) {
+ Formatter format(printer, variables_);
+ format("#endif // $GOOGLE_PROTOBUF$_INCLUDED_$1$\n",
+ IncludeGuard(file_, pb_h, options_));
+}
+
+void FileGenerator::GenerateLibraryIncludes(io::Printer* printer) {
+ Formatter format(printer, variables_);
+ if (UsingImplicitWeakFields(file_, options_)) {
+ IncludeFile("net/proto2/public/implicit_weak_message.h", printer);
+ }
+ if (HasWeakFields(file_, options_)) {
+ GOOGLE_CHECK(!options_.opensource_runtime);
+ IncludeFile("net/proto2/public/weak_field_map.h", printer);
+ }
+ if (HasLazyFields(file_, options_, &scc_analyzer_)) {
+ GOOGLE_CHECK(!options_.opensource_runtime);
+ IncludeFile("net/proto2/public/lazy_field.h", printer);
+ }
+ if (ShouldVerify(file_, options_, &scc_analyzer_)) {
+ IncludeFile("net/proto2/public/wire_format_verify.h", printer);
+ }
+
+ if (options_.opensource_runtime) {
+ // Verify the protobuf library header version is compatible with the protoc
+ // version before going any further.
+ IncludeFile("net/proto2/public/port_def.inc", printer);
+ format(
+ "#if PROTOBUF_VERSION < $1$\n"
+ "#error This file was generated by a newer version of protoc which is\n"
+ "#error incompatible with your Protocol Buffer headers. Please update\n"
+ "#error your headers.\n"
+ "#endif\n"
+ "#if $2$ < PROTOBUF_MIN_PROTOC_VERSION\n"
+ "#error This file was generated by an older version of protoc which "
+ "is\n"
+ "#error incompatible with your Protocol Buffer headers. Please\n"
+ "#error regenerate this file with a newer version of protoc.\n"
+ "#endif\n"
+ "\n",
+ PROTOBUF_MIN_HEADER_VERSION_FOR_PROTOC, // 1
+ PROTOBUF_VERSION); // 2
+ IncludeFile("net/proto2/public/port_undef.inc", printer);
+ }
+
+ // OK, it's now safe to #include other files.
+ IncludeFile("net/proto2/io/public/coded_stream.h", printer);
+ IncludeFile("net/proto2/public/arena.h", printer);
+ IncludeFile("net/proto2/public/arenastring.h", printer);
+ if ((options_.force_inline_string || options_.profile_driven_inline_string) &&
+ !options_.opensource_runtime) {
+ IncludeFile("net/proto2/public/inlined_string_field.h", printer);
+ }
+ if (HasSimpleBaseClasses(file_, options_)) {
+ IncludeFile("net/proto2/public/generated_message_bases.h", printer);
+ }
+ IncludeFile("net/proto2/public/generated_message_table_driven.h", printer);
+ if (HasGeneratedMethods(file_, options_) &&
+ options_.tctable_mode != Options::kTCTableNever) {
+ IncludeFile("net/proto2/public/generated_message_tctable_decl.h", printer);
+ }
+ IncludeFile("net/proto2/public/generated_message_util.h", printer);
+ IncludeFile("net/proto2/public/metadata_lite.h", printer);
+
+ if (HasDescriptorMethods(file_, options_)) {
+ IncludeFile("net/proto2/public/generated_message_reflection.h", printer);
+ }
+
+ if (!message_generators_.empty()) {
+ if (HasDescriptorMethods(file_, options_)) {
+ IncludeFile("net/proto2/public/message.h", printer);
+ } else {
+ IncludeFile("net/proto2/public/message_lite.h", printer);
+ }
+ }
+ if (options_.opensource_runtime) {
+ // Open-source relies on unconditional includes of these.
+ IncludeFileAndExport("net/proto2/public/repeated_field.h", printer);
+ IncludeFileAndExport("net/proto2/public/extension_set.h", printer);
+ } else {
+ // Google3 includes these files only when they are necessary.
+ if (HasExtensionsOrExtendableMessage(file_)) {
+ IncludeFileAndExport("net/proto2/public/extension_set.h", printer);
+ }
+ if (HasRepeatedFields(file_)) {
+ IncludeFileAndExport("net/proto2/public/repeated_field.h", printer);
+ }
+ if (HasStringPieceFields(file_, options_)) {
+ IncludeFile("net/proto2/public/string_piece_field_support.h", printer);
+ }
+ if (HasCordFields(file_, options_)) {
+ format("#include \"third_party/absl/strings/cord.h\"\n");
+ }
+ }
+ if (HasMapFields(file_)) {
+ IncludeFileAndExport("net/proto2/public/map.h", printer);
+ if (HasDescriptorMethods(file_, options_)) {
+ IncludeFile("net/proto2/public/map_entry.h", printer);
+ IncludeFile("net/proto2/public/map_field_inl.h", printer);
+ } else {
+ IncludeFile("net/proto2/public/map_entry_lite.h", printer);
+ IncludeFile("net/proto2/public/map_field_lite.h", printer);
+ }
+ }
+
+ if (HasEnumDefinitions(file_)) {
+ if (HasDescriptorMethods(file_, options_)) {
+ IncludeFile("net/proto2/public/generated_enum_reflection.h", printer);
+ } else {
+ IncludeFile("net/proto2/public/generated_enum_util.h", printer);
+ }
+ }
+
+ if (HasGenericServices(file_, options_)) {
+ IncludeFile("net/proto2/public/service.h", printer);
+ }
+
+ if (UseUnknownFieldSet(file_, options_) && !message_generators_.empty()) {
+ IncludeFile("net/proto2/public/unknown_field_set.h", printer);
+ }
+}
+
+void FileGenerator::GenerateMetadataPragma(io::Printer* printer,
+ const std::string& info_path) {
+ Formatter format(printer, variables_);
+ if (!info_path.empty() && !options_.annotation_pragma_name.empty() &&
+ !options_.annotation_guard_name.empty()) {
+ format.Set("guard", options_.annotation_guard_name);
+ format.Set("pragma", options_.annotation_pragma_name);
+ format.Set("info_path", info_path);
+ format(
+ "#ifdef $guard$\n"
+ "#pragma $pragma$ \"$info_path$\"\n"
+ "#endif // $guard$\n");
+ }
+}
+
+void FileGenerator::GenerateDependencyIncludes(io::Printer* printer) {
+ Formatter format(printer, variables_);
+ for (int i = 0; i < file_->dependency_count(); i++) {
+ std::string basename = StripProto(file_->dependency(i)->name());
+
+ // Do not import weak deps.
+ if (IsDepWeak(file_->dependency(i))) continue;
+
+ if (IsBootstrapProto(options_, file_)) {
+ GetBootstrapBasename(options_, basename, &basename);
+ }
+
+ format("#include $1$\n",
+ CreateHeaderInclude(basename + ".pb.h", file_->dependency(i)));
+ }
+}
+
+void FileGenerator::GenerateGlobalStateFunctionDeclarations(
+ io::Printer* printer) {
+ Formatter format(printer, variables_);
+ // Forward-declare the DescriptorTable because this is referenced by .pb.cc
+ // files depending on this file.
+ //
+ // The TableStruct is also outputted in weak_message_field.cc, because the
+ // weak fields must refer to table struct but cannot include the header.
+ // Also it annotates extra weak attributes.
+ // TODO(gerbens) make sure this situation is handled better.
+ format(
+ "\n"
+ "// Internal implementation detail -- do not use these members.\n"
+ "struct $dllexport_decl $$tablename$ {\n"
+ // These tables describe how to serialize and parse messages. Used
+ // for table driven code.
+ " static const ::$proto_ns$::internal::ParseTableField entries[]\n"
+ " PROTOBUF_SECTION_VARIABLE(protodesc_cold);\n"
+ " static const ::$proto_ns$::internal::AuxiliaryParseTableField aux[]\n"
+ " PROTOBUF_SECTION_VARIABLE(protodesc_cold);\n"
+ " static const ::$proto_ns$::internal::ParseTable schema[$1$]\n"
+ " PROTOBUF_SECTION_VARIABLE(protodesc_cold);\n"
+ " static const ::$proto_ns$::internal::FieldMetadata field_metadata[];\n"
+ " static const ::$proto_ns$::internal::SerializationTable "
+ "serialization_table[];\n"
+ " static const $uint32$ offsets[];\n"
+ "};\n",
+ std::max(size_t(1), message_generators_.size()));
+ if (HasDescriptorMethods(file_, options_)) {
+ format(
+ "$dllexport_decl $extern const ::$proto_ns$::internal::DescriptorTable "
+ "$desc_table$;\n");
+ }
+}
+
+void FileGenerator::GenerateMessageDefinitions(io::Printer* printer) {
+ Formatter format(printer, variables_);
+ // Generate class definitions.
+ for (int i = 0; i < message_generators_.size(); i++) {
+ if (i > 0) {
+ format("\n");
+ format(kThinSeparator);
+ format("\n");
+ }
+ message_generators_[i]->GenerateClassDefinition(printer);
+ }
+}
+
+void FileGenerator::GenerateEnumDefinitions(io::Printer* printer) {
+ // Generate enum definitions.
+ for (int i = 0; i < enum_generators_.size(); i++) {
+ enum_generators_[i]->GenerateDefinition(printer);
+ }
+}
+
+void FileGenerator::GenerateServiceDefinitions(io::Printer* printer) {
+ Formatter format(printer, variables_);
+ if (HasGenericServices(file_, options_)) {
+ // Generate service definitions.
+ for (int i = 0; i < service_generators_.size(); i++) {
+ if (i > 0) {
+ format("\n");
+ format(kThinSeparator);
+ format("\n");
+ }
+ service_generators_[i]->GenerateDeclarations(printer);
+ }
+
+ format("\n");
+ format(kThickSeparator);
+ format("\n");
+ }
+}
+
+void FileGenerator::GenerateExtensionIdentifiers(io::Printer* printer) {
+ // Declare extension identifiers. These are in global scope and so only
+ // the global scope extensions.
+ for (auto& extension_generator : extension_generators_) {
+ if (extension_generator->IsScoped()) continue;
+ extension_generator->GenerateDeclaration(printer);
+ }
+}
+
+void FileGenerator::GenerateInlineFunctionDefinitions(io::Printer* printer) {
+ Formatter format(printer, variables_);
+ // TODO(gerbens) remove pragmas when gcc is no longer used. Current version
+ // of gcc fires a bogus error when compiled with strict-aliasing.
+ format(
+ "#ifdef __GNUC__\n"
+ " #pragma GCC diagnostic push\n"
+ " #pragma GCC diagnostic ignored \"-Wstrict-aliasing\"\n"
+ "#endif // __GNUC__\n");
+ // Generate class inline methods.
+ for (int i = 0; i < message_generators_.size(); i++) {
+ if (i > 0) {
+ format(kThinSeparator);
+ format("\n");
+ }
+ message_generators_[i]->GenerateInlineMethods(printer);
+ }
+ format(
+ "#ifdef __GNUC__\n"
+ " #pragma GCC diagnostic pop\n"
+ "#endif // __GNUC__\n");
+
+ for (int i = 0; i < message_generators_.size(); i++) {
+ if (i > 0) {
+ format(kThinSeparator);
+ format("\n");
+ }
+ }
+}
+
+void FileGenerator::GenerateProto2NamespaceEnumSpecializations(
+ io::Printer* printer) {
+ Formatter format(printer, variables_);
+ // Emit GetEnumDescriptor specializations into google::protobuf namespace:
+ if (HasEnumDefinitions(file_)) {
+ format("\n");
+ {
+ NamespaceOpener proto_ns(ProtobufNamespace(options_), format);
+ format("\n");
+ for (int i = 0; i < enum_generators_.size(); i++) {
+ enum_generators_[i]->GenerateGetEnumDescriptorSpecializations(printer);
+ }
+ format("\n");
+ }
+ }
+}
+
+} // namespace cpp
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_file.h b/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_file.h
new file mode 100644
index 00000000..a5e751aa
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_file.h
@@ -0,0 +1,208 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_FILE_H__
+#define GOOGLE_PROTOBUF_COMPILER_CPP_FILE_H__
+
+#include <algorithm>
+#include <memory>
+#include <set>
+#include <string>
+#include <vector>
+#include <stubs/common.h>
+#include <compiler/cpp/cpp_field.h>
+#include <compiler/cpp/cpp_helpers.h>
+#include <compiler/cpp/cpp_options.h>
+#include <compiler/scc.h>
+
+namespace google {
+namespace protobuf {
+class FileDescriptor; // descriptor.h
+namespace io {
+class Printer; // printer.h
+}
+} // namespace protobuf
+} // namespace google
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+class EnumGenerator; // enum.h
+class MessageGenerator; // message.h
+class ServiceGenerator; // service.h
+class ExtensionGenerator; // extension.h
+
+class FileGenerator {
+ public:
+ // See generator.cc for the meaning of dllexport_decl.
+ FileGenerator(const FileDescriptor* file, const Options& options);
+ ~FileGenerator();
+
+ // Shared code between the two header generators below.
+ void GenerateHeader(io::Printer* printer);
+
+ // info_path, if non-empty, should be the path (relative to printer's
+ // output) to the metadata file describing this proto header.
+ void GenerateProtoHeader(io::Printer* printer, const std::string& info_path);
+ // info_path, if non-empty, should be the path (relative to printer's
+ // output) to the metadata file describing this PB header.
+ void GeneratePBHeader(io::Printer* printer, const std::string& info_path);
+ void GenerateSource(io::Printer* printer);
+
+ // The following member functions are used when the lite_implicit_weak_fields
+ // option is set. In this mode the code is organized a bit differently to
+ // promote better linker stripping of unused code. In particular, we generate
+ // one .cc file per message, one .cc file per extension, and a main pb.cc file
+ // containing everything else.
+
+ int NumMessages() const { return message_generators_.size(); }
+ int NumExtensions() const { return extension_generators_.size(); }
+ // Generates the source file for one message.
+ void GenerateSourceForMessage(int idx, io::Printer* printer);
+ // Generates the source file for one extension.
+ void GenerateSourceForExtension(int idx, io::Printer* printer);
+ // Generates a source file containing everything except messages and
+ // extensions.
+ void GenerateGlobalSource(io::Printer* printer);
+
+ private:
+ // Internal type used by GenerateForwardDeclarations (defined in file.cc).
+ class ForwardDeclarations;
+ struct CrossFileReferences;
+
+ void IncludeFile(const std::string& google3_name, io::Printer* printer) {
+ DoIncludeFile(google3_name, false, printer);
+ }
+ void IncludeFileAndExport(const std::string& google3_name,
+ io::Printer* printer) {
+ DoIncludeFile(google3_name, true, printer);
+ }
+ void DoIncludeFile(const std::string& google3_name, bool do_export,
+ io::Printer* printer);
+
+ std::string CreateHeaderInclude(const std::string& basename,
+ const FileDescriptor* file);
+ void GetCrossFileReferencesForField(const FieldDescriptor* field,
+ CrossFileReferences* refs);
+ void GetCrossFileReferencesForFile(const FileDescriptor* file,
+ CrossFileReferences* refs);
+ void GenerateInternalForwardDeclarations(const CrossFileReferences& refs,
+ io::Printer* printer);
+ void GenerateSourceIncludes(io::Printer* printer);
+ void GenerateSourceDefaultInstance(int idx, io::Printer* printer);
+
+ void GenerateInitForSCC(const SCC* scc, const CrossFileReferences& refs,
+ io::Printer* printer);
+ void GenerateTables(io::Printer* printer);
+ void GenerateReflectionInitializationCode(io::Printer* printer);
+
+ // For other imports, generates their forward-declarations.
+ void GenerateForwardDeclarations(io::Printer* printer);
+
+ // Generates top or bottom of a header file.
+ void GenerateTopHeaderGuard(io::Printer* printer, bool pb_h);
+ void GenerateBottomHeaderGuard(io::Printer* printer, bool pb_h);
+
+ // Generates #include directives.
+ void GenerateLibraryIncludes(io::Printer* printer);
+ void GenerateDependencyIncludes(io::Printer* printer);
+
+ // Generate a pragma to pull in metadata using the given info_path (if
+ // non-empty). info_path should be relative to printer's output.
+ void GenerateMetadataPragma(io::Printer* printer,
+ const std::string& info_path);
+
+ // Generates a couple of different pieces before definitions:
+ void GenerateGlobalStateFunctionDeclarations(io::Printer* printer);
+
+ // Generates types for classes.
+ void GenerateMessageDefinitions(io::Printer* printer);
+
+ void GenerateEnumDefinitions(io::Printer* printer);
+
+ // Generates generic service definitions.
+ void GenerateServiceDefinitions(io::Printer* printer);
+
+ // Generates extension identifiers.
+ void GenerateExtensionIdentifiers(io::Printer* printer);
+
+ // Generates inline function definitions.
+ void GenerateInlineFunctionDefinitions(io::Printer* printer);
+
+ void GenerateProto2NamespaceEnumSpecializations(io::Printer* printer);
+
+ // Sometimes the names we use in a .proto file happen to be defined as
+ // macros on some platforms (e.g., macro/minor used in plugin.proto are
+ // defined as macros in sys/types.h on FreeBSD and a few other platforms).
+ // To make the generated code compile on these platforms, we either have to
+ // undef the macro for these few platforms, or rename the field name for all
+ // platforms. Since these names are part of protobuf public API, renaming is
+ // generally a breaking change so we prefer the #undef approach.
+ void GenerateMacroUndefs(io::Printer* printer);
+
+ bool IsDepWeak(const FileDescriptor* dep) const {
+ if (weak_deps_.count(dep) != 0) {
+ GOOGLE_CHECK(!options_.opensource_runtime);
+ return true;
+ }
+ return false;
+ }
+
+ std::set<const FileDescriptor*> weak_deps_;
+
+ const FileDescriptor* file_;
+ const Options options_;
+
+ MessageSCCAnalyzer scc_analyzer_;
+
+ std::map<std::string, std::string> variables_;
+
+ // Contains the post-order walk of all the messages (and child messages) in
+ // this file. If you need a pre-order walk just reverse iterate.
+ std::vector<std::unique_ptr<MessageGenerator>> message_generators_;
+ std::vector<std::unique_ptr<EnumGenerator>> enum_generators_;
+ std::vector<std::unique_ptr<ServiceGenerator>> service_generators_;
+ std::vector<std::unique_ptr<ExtensionGenerator>> extension_generators_;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FileGenerator);
+};
+
+} // namespace cpp
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_COMPILER_CPP_FILE_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_generator.cc b/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_generator.cc
new file mode 100644
index 00000000..88caa897
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_generator.cc
@@ -0,0 +1,271 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 <compiler/cpp/cpp_generator.h>
+
+#include <memory>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include <stubs/strutil.h>
+#include <compiler/cpp/cpp_file.h>
+#include <compiler/cpp/cpp_helpers.h>
+#include <descriptor.pb.h>
+#include <io/printer.h>
+#include <io/zero_copy_stream.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+CppGenerator::CppGenerator() {}
+CppGenerator::~CppGenerator() {}
+
+namespace {
+std::string NumberedCcFileName(const std::string& basename, int number) {
+ return StrCat(basename, ".out/", number, ".cc");
+}
+} // namespace
+
+bool CppGenerator::Generate(const FileDescriptor* file,
+ const std::string& parameter,
+ GeneratorContext* generator_context,
+ std::string* error) const {
+ std::vector<std::pair<std::string, std::string> > options;
+ ParseGeneratorParameter(parameter, &options);
+
+ // -----------------------------------------------------------------
+ // parse generator options
+
+ // If the dllexport_decl option is passed to the compiler, we need to write
+ // it in front of every symbol that should be exported if this .proto is
+ // compiled into a Windows DLL. E.g., if the user invokes the protocol
+ // compiler as:
+ // protoc --cpp_out=dllexport_decl=FOO_EXPORT:outdir foo.proto
+ // then we'll define classes like this:
+ // class FOO_EXPORT Foo {
+ // ...
+ // }
+ // FOO_EXPORT is a macro which should expand to __declspec(dllexport) or
+ // __declspec(dllimport) depending on what is being compiled.
+ //
+ Options file_options;
+
+ file_options.opensource_runtime = opensource_runtime_;
+ file_options.runtime_include_base = runtime_include_base_;
+
+ for (int i = 0; i < options.size(); i++) {
+ if (options[i].first == "dllexport_decl") {
+ file_options.dllexport_decl = options[i].second;
+ } else if (options[i].first == "safe_boundary_check") {
+ file_options.safe_boundary_check = true;
+ } else if (options[i].first == "annotate_headers") {
+ file_options.annotate_headers = true;
+ } else if (options[i].first == "annotation_pragma_name") {
+ file_options.annotation_pragma_name = options[i].second;
+ } else if (options[i].first == "annotation_guard_name") {
+ file_options.annotation_guard_name = options[i].second;
+ } else if (options[i].first == "speed") {
+ file_options.enforce_mode = EnforceOptimizeMode::kSpeed;
+ } else if (options[i].first == "code_size") {
+ file_options.enforce_mode = EnforceOptimizeMode::kCodeSize;
+ } else if (options[i].first == "lite") {
+ file_options.enforce_mode = EnforceOptimizeMode::kLiteRuntime;
+ } else if (options[i].first == "lite_implicit_weak_fields") {
+ file_options.enforce_mode = EnforceOptimizeMode::kLiteRuntime;
+ file_options.lite_implicit_weak_fields = true;
+ if (!options[i].second.empty()) {
+ file_options.num_cc_files =
+ strto32(options[i].second.c_str(), NULL, 10);
+ }
+ } else if (options[i].first == "annotate_accessor") {
+ file_options.annotate_accessor = true;
+ } else if (options[i].first == "inject_field_listener_events") {
+ file_options.field_listener_options.inject_field_listener_events = true;
+ } else if (options[i].first == "forbidden_field_listener_events") {
+ std::size_t pos = 0;
+ do {
+ std::size_t next_pos = options[i].second.find_first_of("+", pos);
+ if (next_pos == std::string::npos) {
+ next_pos = options[i].second.size();
+ }
+ if (next_pos > pos)
+ file_options.field_listener_options.forbidden_field_listener_events
+ .insert(options[i].second.substr(pos, next_pos - pos));
+ pos = next_pos + 1;
+ } while (pos < options[i].second.size());
+ } else if (options[i].first == "eagerly_verified_lazy") {
+ file_options.eagerly_verified_lazy = true;
+ } else if (options[i].first == "force_eagerly_verified_lazy") {
+ file_options.force_eagerly_verified_lazy = true;
+ } else if (options[i].first == "table_driven_parsing") {
+ file_options.table_driven_parsing = true;
+ } else if (options[i].first == "table_driven_serialization") {
+ file_options.table_driven_serialization = true;
+ } else if (options[i].first == "experimental_tail_call_table_mode") {
+ if (options[i].second == "never") {
+ file_options.tctable_mode = Options::kTCTableNever;
+ } else if (options[i].second == "guarded") {
+ file_options.tctable_mode = Options::kTCTableGuarded;
+ } else if (options[i].second == "always") {
+ file_options.tctable_mode = Options::kTCTableAlways;
+ } else {
+ *error = "Unknown value for experimental_tail_call_table_mode: " +
+ options[i].second;
+ return false;
+ }
+ } else {
+ *error = "Unknown generator option: " + options[i].first;
+ return false;
+ }
+ }
+
+ // The safe_boundary_check option controls behavior for Google-internal
+ // protobuf APIs.
+ if (file_options.safe_boundary_check && file_options.opensource_runtime) {
+ *error =
+ "The safe_boundary_check option is not supported outside of Google.";
+ return false;
+ }
+
+ // -----------------------------------------------------------------
+
+
+ std::string basename = StripProto(file->name());
+
+ if (MaybeBootstrap(file_options, generator_context, file_options.bootstrap,
+ &basename)) {
+ return true;
+ }
+
+ FileGenerator file_generator(file, file_options);
+
+ // Generate header(s).
+ if (file_options.proto_h) {
+ std::unique_ptr<io::ZeroCopyOutputStream> output(
+ generator_context->Open(basename + ".proto.h"));
+ GeneratedCodeInfo annotations;
+ io::AnnotationProtoCollector<GeneratedCodeInfo> annotation_collector(
+ &annotations);
+ std::string info_path = basename + ".proto.h.meta";
+ io::Printer printer(
+ output.get(), '$',
+ file_options.annotate_headers ? &annotation_collector : NULL);
+ file_generator.GenerateProtoHeader(
+ &printer, file_options.annotate_headers ? info_path : "");
+ if (file_options.annotate_headers) {
+ std::unique_ptr<io::ZeroCopyOutputStream> info_output(
+ generator_context->Open(info_path));
+ annotations.SerializeToZeroCopyStream(info_output.get());
+ }
+ }
+
+ {
+ std::unique_ptr<io::ZeroCopyOutputStream> output(
+ generator_context->Open(basename + ".pb.h"));
+ GeneratedCodeInfo annotations;
+ io::AnnotationProtoCollector<GeneratedCodeInfo> annotation_collector(
+ &annotations);
+ std::string info_path = basename + ".pb.h.meta";
+ io::Printer printer(
+ output.get(), '$',
+ file_options.annotate_headers ? &annotation_collector : NULL);
+ file_generator.GeneratePBHeader(
+ &printer, file_options.annotate_headers ? info_path : "");
+ if (file_options.annotate_headers) {
+ std::unique_ptr<io::ZeroCopyOutputStream> info_output(
+ generator_context->Open(info_path));
+ annotations.SerializeToZeroCopyStream(info_output.get());
+ }
+ }
+
+ // Generate cc file(s).
+ if (UsingImplicitWeakFields(file, file_options)) {
+ {
+ // This is the global .cc file, containing
+ // enum/services/tables/reflection
+ std::unique_ptr<io::ZeroCopyOutputStream> output(
+ generator_context->Open(basename + ".pb.cc"));
+ io::Printer printer(output.get(), '$');
+ file_generator.GenerateGlobalSource(&printer);
+ }
+
+ int num_cc_files =
+ file_generator.NumMessages() + file_generator.NumExtensions();
+
+ // If we're using implicit weak fields then we allow the user to
+ // optionally specify how many files to generate, not counting the global
+ // pb.cc file. If we have more files than messages, then some files will
+ // be generated as empty placeholders.
+ if (file_options.num_cc_files > 0) {
+ GOOGLE_CHECK_LE(num_cc_files, file_options.num_cc_files)
+ << "There must be at least as many numbered .cc files as messages "
+ "and extensions.";
+ num_cc_files = file_options.num_cc_files;
+ }
+ int cc_file_number = 0;
+ for (int i = 0; i < file_generator.NumMessages(); i++) {
+ std::unique_ptr<io::ZeroCopyOutputStream> output(generator_context->Open(
+ NumberedCcFileName(basename, cc_file_number++)));
+ io::Printer printer(output.get(), '$');
+ file_generator.GenerateSourceForMessage(i, &printer);
+ }
+ for (int i = 0; i < file_generator.NumExtensions(); i++) {
+ std::unique_ptr<io::ZeroCopyOutputStream> output(generator_context->Open(
+ NumberedCcFileName(basename, cc_file_number++)));
+ io::Printer printer(output.get(), '$');
+ file_generator.GenerateSourceForExtension(i, &printer);
+ }
+ // Create empty placeholder files if necessary to match the expected number
+ // of files.
+ for (; cc_file_number < num_cc_files; ++cc_file_number) {
+ std::unique_ptr<io::ZeroCopyOutputStream> output(generator_context->Open(
+ NumberedCcFileName(basename, cc_file_number)));
+ }
+ } else {
+ std::unique_ptr<io::ZeroCopyOutputStream> output(
+ generator_context->Open(basename + ".pb.cc"));
+ io::Printer printer(output.get(), '$');
+ file_generator.GenerateSource(&printer);
+ }
+
+ return true;
+}
+
+} // namespace cpp
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_generator.h b/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_generator.h
new file mode 100644
index 00000000..14c7672a
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_generator.h
@@ -0,0 +1,106 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// Generates C++ code for a given .proto file.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_GENERATOR_H__
+#define GOOGLE_PROTOBUF_COMPILER_CPP_GENERATOR_H__
+
+#include <string>
+#include <compiler/code_generator.h>
+
+#include <port_def.inc>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+// CodeGenerator implementation which generates a C++ source file and
+// header. If you create your own protocol compiler binary and you want
+// it to support C++ output, you can do so by registering an instance of this
+// CodeGenerator with the CommandLineInterface in your main() function.
+class PROTOC_EXPORT CppGenerator : public CodeGenerator {
+ public:
+ CppGenerator();
+ ~CppGenerator();
+
+ enum class Runtime {
+ kGoogle3, // Use the internal google3 runtime.
+ kOpensource, // Use the open-source runtime.
+
+ // Use the open-source runtime with google3 #include paths. We make these
+ // absolute to avoid ambiguity, so the runtime will be #included like:
+ // #include "third_party/protobuf/.../google/protobuf/message.h"
+ kOpensourceGoogle3
+ };
+
+ void set_opensource_runtime(bool opensource) {
+ opensource_runtime_ = opensource;
+ }
+
+ // If set to a non-empty string, generated code will do:
+ // #include "<BASE>/google/protobuf/message.h"
+ // instead of:
+ // #include <message.h>
+ // This has no effect if opensource_runtime = false.
+ void set_runtime_include_base(const std::string& base) {
+ runtime_include_base_ = base;
+ }
+
+ // implements CodeGenerator ----------------------------------------
+ bool Generate(const FileDescriptor* file, const std::string& parameter,
+ GeneratorContext* generator_context,
+ std::string* error) const override;
+
+ uint64_t GetSupportedFeatures() const override {
+ // We don't fully support this yet, but this is needed to unblock the tests,
+ // and we will have full support before the experimental flag is removed.
+ return FEATURE_PROTO3_OPTIONAL;
+ }
+
+ private:
+ bool opensource_runtime_ = true;
+ std::string runtime_include_base_;
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CppGenerator);
+};
+
+} // namespace cpp
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#include <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_COMPILER_CPP_GENERATOR_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_helpers.cc b/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_helpers.cc
new file mode 100644
index 00000000..9f133247
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_helpers.cc
@@ -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.
+
+#include <compiler/cpp/cpp_helpers.h>
+
+#include <cstdint>
+#include <functional>
+#include <limits>
+#include <map>
+#include <queue>
+#include <unordered_set>
+#include <vector>
+
+#include <stubs/common.h>
+#include <stubs/logging.h>
+#include <compiler/cpp/cpp_options.h>
+#include <compiler/cpp/cpp_names.h>
+#include <descriptor.pb.h>
+#include <descriptor.h>
+#include <compiler/scc.h>
+#include <io/printer.h>
+#include <io/zero_copy_stream.h>
+#include <dynamic_message.h>
+#include <wire_format.h>
+#include <wire_format_lite.h>
+#include <stubs/strutil.h>
+#include <stubs/substitute.h>
+#include <stubs/hash.h>
+
+// Must be last.
+#include <port_def.inc>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+namespace {
+
+static const char kAnyMessageName[] = "Any";
+static const char kAnyProtoFile[] = "google/protobuf/any.proto";
+
+std::string DotsToColons(const std::string& name) {
+ return StringReplace(name, ".", "::", true);
+}
+
+static const char* const kKeywordList[] = { //
+ "NULL",
+ "alignas",
+ "alignof",
+ "and",
+ "and_eq",
+ "asm",
+ "auto",
+ "bitand",
+ "bitor",
+ "bool",
+ "break",
+ "case",
+ "catch",
+ "char",
+ "class",
+ "compl",
+ "const",
+ "constexpr",
+ "const_cast",
+ "continue",
+ "decltype",
+ "default",
+ "delete",
+ "do",
+ "double",
+ "dynamic_cast",
+ "else",
+ "enum",
+ "explicit",
+ "export",
+ "extern",
+ "false",
+ "float",
+ "for",
+ "friend",
+ "goto",
+ "if",
+ "inline",
+ "int",
+ "long",
+ "mutable",
+ "namespace",
+ "new",
+ "noexcept",
+ "not",
+ "not_eq",
+ "nullptr",
+ "operator",
+ "or",
+ "or_eq",
+ "private",
+ "protected",
+ "public",
+ "register",
+ "reinterpret_cast",
+ "return",
+ "short",
+ "signed",
+ "sizeof",
+ "static",
+ "static_assert",
+ "static_cast",
+ "struct",
+ "switch",
+ "template",
+ "this",
+ "thread_local",
+ "throw",
+ "true",
+ "try",
+ "typedef",
+ "typeid",
+ "typename",
+ "union",
+ "unsigned",
+ "using",
+ "virtual",
+ "void",
+ "volatile",
+ "wchar_t",
+ "while",
+ "xor",
+ "xor_eq"};
+
+static std::unordered_set<std::string>* MakeKeywordsMap() {
+ auto* result = new std::unordered_set<std::string>();
+ for (const auto keyword : kKeywordList) {
+ result->emplace(keyword);
+ }
+ return result;
+}
+
+static std::unordered_set<std::string>& kKeywords = *MakeKeywordsMap();
+
+std::string IntTypeName(const Options& options, const std::string& type) {
+ return type + "_t";
+}
+
+void SetIntVar(const Options& options, const std::string& type,
+ std::map<std::string, std::string>* variables) {
+ (*variables)[type] = IntTypeName(options, type);
+}
+bool IsEagerlyVerifiedLazyImpl(const FieldDescriptor* field,
+ const Options& options,
+ MessageSCCAnalyzer* scc_analyzer) {
+ return false;
+}
+
+} // namespace
+
+bool IsLazy(const FieldDescriptor* field, const Options& options,
+ MessageSCCAnalyzer* scc_analyzer) {
+ return IsLazilyVerifiedLazy(field, options) ||
+ IsEagerlyVerifiedLazyImpl(field, options, scc_analyzer);
+}
+
+void SetCommonVars(const Options& options,
+ std::map<std::string, std::string>* variables) {
+ (*variables)["proto_ns"] = ProtobufNamespace(options);
+
+ // Warning: there is some clever naming/splitting here to avoid extract script
+ // rewrites. The names of these variables must not be things that the extract
+ // script will rewrite. That's why we use "CHK" (for example) instead of
+ // "GOOGLE_CHECK".
+ if (options.opensource_runtime) {
+ (*variables)["GOOGLE_PROTOBUF"] = "GOOGLE_PROTOBUF";
+ (*variables)["CHK"] = "GOOGLE_CHECK";
+ (*variables)["DCHK"] = "GOOGLE_DCHECK";
+ } else {
+ // These values are things the extract script would rewrite if we did not
+ // split them. It might not strictly matter since we don't generate google3
+ // code in open-source. But it's good to prevent surprising things from
+ // happening.
+ (*variables)["GOOGLE_PROTOBUF"] =
+ "GOOGLE3"
+ "_PROTOBUF";
+ (*variables)["CHK"] =
+ "CH"
+ "ECK";
+ (*variables)["DCHK"] =
+ "DCH"
+ "ECK";
+ }
+
+ SetIntVar(options, "int8", variables);
+ SetIntVar(options, "uint8", variables);
+ SetIntVar(options, "uint32", variables);
+ SetIntVar(options, "uint64", variables);
+ SetIntVar(options, "int32", variables);
+ SetIntVar(options, "int64", variables);
+ (*variables)["string"] = "std::string";
+}
+
+void SetUnknownFieldsVariable(const Descriptor* descriptor,
+ const Options& options,
+ std::map<std::string, std::string>* variables) {
+ std::string proto_ns = ProtobufNamespace(options);
+ std::string unknown_fields_type;
+ if (UseUnknownFieldSet(descriptor->file(), options)) {
+ unknown_fields_type = "::" + proto_ns + "::UnknownFieldSet";
+ (*variables)["unknown_fields"] =
+ "_internal_metadata_.unknown_fields<" + unknown_fields_type + ">(" +
+ unknown_fields_type + "::default_instance)";
+ } else {
+ unknown_fields_type =
+ PrimitiveTypeName(options, FieldDescriptor::CPPTYPE_STRING);
+ (*variables)["unknown_fields"] = "_internal_metadata_.unknown_fields<" +
+ unknown_fields_type + ">(::" + proto_ns +
+ "::internal::GetEmptyString)";
+ }
+ (*variables)["unknown_fields_type"] = unknown_fields_type;
+ (*variables)["have_unknown_fields"] =
+ "_internal_metadata_.have_unknown_fields()";
+ (*variables)["mutable_unknown_fields"] =
+ "_internal_metadata_.mutable_unknown_fields<" + unknown_fields_type +
+ ">()";
+}
+
+std::string UnderscoresToCamelCase(const std::string& input,
+ bool cap_next_letter) {
+ std::string result;
+ // Note: I distrust ctype.h due to locales.
+ for (int i = 0; i < input.size(); i++) {
+ if ('a' <= input[i] && input[i] <= 'z') {
+ if (cap_next_letter) {
+ result += input[i] + ('A' - 'a');
+ } else {
+ result += input[i];
+ }
+ cap_next_letter = false;
+ } else if ('A' <= input[i] && input[i] <= 'Z') {
+ // Capital letters are left as-is.
+ result += input[i];
+ cap_next_letter = false;
+ } else if ('0' <= input[i] && input[i] <= '9') {
+ result += input[i];
+ cap_next_letter = true;
+ } else {
+ cap_next_letter = true;
+ }
+ }
+ return result;
+}
+
+const char kThickSeparator[] =
+ "// ===================================================================\n";
+const char kThinSeparator[] =
+ "// -------------------------------------------------------------------\n";
+
+bool CanInitializeByZeroing(const FieldDescriptor* field) {
+ if (field->is_repeated() || field->is_extension()) return false;
+ switch (field->cpp_type()) {
+ case FieldDescriptor::CPPTYPE_ENUM:
+ return field->default_value_enum()->number() == 0;
+ case FieldDescriptor::CPPTYPE_INT32:
+ return field->default_value_int32() == 0;
+ case FieldDescriptor::CPPTYPE_INT64:
+ return field->default_value_int64() == 0;
+ case FieldDescriptor::CPPTYPE_UINT32:
+ return field->default_value_uint32() == 0;
+ case FieldDescriptor::CPPTYPE_UINT64:
+ return field->default_value_uint64() == 0;
+ case FieldDescriptor::CPPTYPE_FLOAT:
+ return field->default_value_float() == 0;
+ case FieldDescriptor::CPPTYPE_DOUBLE:
+ return field->default_value_double() == 0;
+ case FieldDescriptor::CPPTYPE_BOOL:
+ return field->default_value_bool() == false;
+ default:
+ return false;
+ }
+}
+
+std::string ClassName(const Descriptor* descriptor) {
+ const Descriptor* parent = descriptor->containing_type();
+ std::string res;
+ if (parent) res += ClassName(parent) + "_";
+ res += descriptor->name();
+ if (IsMapEntryMessage(descriptor)) res += "_DoNotUse";
+ return ResolveKeyword(res);
+}
+
+std::string ClassName(const EnumDescriptor* enum_descriptor) {
+ if (enum_descriptor->containing_type() == nullptr) {
+ return ResolveKeyword(enum_descriptor->name());
+ } else {
+ return ClassName(enum_descriptor->containing_type()) + "_" +
+ enum_descriptor->name();
+ }
+}
+
+std::string QualifiedClassName(const Descriptor* d, const Options& options) {
+ return QualifiedFileLevelSymbol(d->file(), ClassName(d), options);
+}
+
+std::string QualifiedClassName(const EnumDescriptor* d,
+ const Options& options) {
+ return QualifiedFileLevelSymbol(d->file(), ClassName(d), options);
+}
+
+std::string QualifiedClassName(const Descriptor* d) {
+ return QualifiedClassName(d, Options());
+}
+
+std::string QualifiedClassName(const EnumDescriptor* d) {
+ return QualifiedClassName(d, Options());
+}
+
+std::string ExtensionName(const FieldDescriptor* d) {
+ if (const Descriptor* scope = d->extension_scope())
+ return StrCat(ClassName(scope), "::", ResolveKeyword(d->name()));
+ return ResolveKeyword(d->name());
+}
+
+std::string QualifiedExtensionName(const FieldDescriptor* d,
+ const Options& options) {
+ GOOGLE_DCHECK(d->is_extension());
+ return QualifiedFileLevelSymbol(d->file(), ExtensionName(d), options);
+}
+
+std::string QualifiedExtensionName(const FieldDescriptor* d) {
+ return QualifiedExtensionName(d, Options());
+}
+
+std::string Namespace(const std::string& package) {
+ if (package.empty()) return "";
+ return "::" + DotsToColons(package);
+}
+
+std::string Namespace(const FileDescriptor* d, const Options& options) {
+ std::string ret = Namespace(d->package());
+ if (IsWellKnownMessage(d) && options.opensource_runtime) {
+ // Written with string concatenation to prevent rewriting of
+ // ::google::protobuf.
+ ret = StringReplace(ret,
+ "::google::"
+ "protobuf",
+ "::PROTOBUF_NAMESPACE_ID", false);
+ }
+ return ret;
+}
+
+std::string Namespace(const Descriptor* d, const Options& options) {
+ return Namespace(d->file(), options);
+}
+
+std::string Namespace(const FieldDescriptor* d, const Options& options) {
+ return Namespace(d->file(), options);
+}
+
+std::string Namespace(const EnumDescriptor* d, const Options& options) {
+ return Namespace(d->file(), options);
+}
+
+std::string DefaultInstanceType(const Descriptor* descriptor,
+ const Options& options) {
+ return ClassName(descriptor) + "DefaultTypeInternal";
+}
+
+std::string DefaultInstanceName(const Descriptor* descriptor,
+ const Options& options) {
+ return "_" + ClassName(descriptor, false) + "_default_instance_";
+}
+
+std::string DefaultInstancePtr(const Descriptor* descriptor,
+ const Options& options) {
+ return DefaultInstanceName(descriptor, options) + "ptr_";
+}
+
+std::string QualifiedDefaultInstanceName(const Descriptor* descriptor,
+ const Options& options) {
+ return QualifiedFileLevelSymbol(
+ descriptor->file(), DefaultInstanceName(descriptor, options), options);
+}
+
+std::string QualifiedDefaultInstancePtr(const Descriptor* descriptor,
+ const Options& options) {
+ return QualifiedDefaultInstanceName(descriptor, options) + "ptr_";
+}
+
+std::string DescriptorTableName(const FileDescriptor* file,
+ const Options& options) {
+ return UniqueName("descriptor_table", file, options);
+}
+
+std::string FileDllExport(const FileDescriptor* file, const Options& options) {
+ return UniqueName("PROTOBUF_INTERNAL_EXPORT", file, options);
+}
+
+std::string SuperClassName(const Descriptor* descriptor,
+ const Options& options) {
+ if (!HasDescriptorMethods(descriptor->file(), options)) {
+ return "::" + ProtobufNamespace(options) + "::MessageLite";
+ }
+ auto simple_base = SimpleBaseClass(descriptor, options);
+ if (simple_base.empty()) {
+ return "::" + ProtobufNamespace(options) + "::Message";
+ }
+ return "::" + ProtobufNamespace(options) + "::internal::" + simple_base;
+}
+
+std::string ResolveKeyword(const std::string& name) {
+ if (kKeywords.count(name) > 0) {
+ return name + "_";
+ }
+ return name;
+}
+
+std::string FieldName(const FieldDescriptor* field) {
+ std::string result = field->name();
+ LowerString(&result);
+ if (kKeywords.count(result) > 0) {
+ result.append("_");
+ }
+ return result;
+}
+
+std::string OneofCaseConstantName(const FieldDescriptor* field) {
+ GOOGLE_DCHECK(field->containing_oneof());
+ std::string field_name = UnderscoresToCamelCase(field->name(), true);
+ return "k" + field_name;
+}
+
+std::string QualifiedOneofCaseConstantName(const FieldDescriptor* field) {
+ GOOGLE_DCHECK(field->containing_oneof());
+ const std::string qualification =
+ QualifiedClassName(field->containing_type());
+ return StrCat(qualification, "::", OneofCaseConstantName(field));
+}
+
+std::string EnumValueName(const EnumValueDescriptor* enum_value) {
+ std::string result = enum_value->name();
+ if (kKeywords.count(result) > 0) {
+ result.append("_");
+ }
+ return result;
+}
+
+int EstimateAlignmentSize(const FieldDescriptor* field) {
+ if (field == nullptr) return 0;
+ if (field->is_repeated()) return 8;
+ switch (field->cpp_type()) {
+ case FieldDescriptor::CPPTYPE_BOOL:
+ return 1;
+
+ case FieldDescriptor::CPPTYPE_INT32:
+ case FieldDescriptor::CPPTYPE_UINT32:
+ case FieldDescriptor::CPPTYPE_ENUM:
+ case FieldDescriptor::CPPTYPE_FLOAT:
+ return 4;
+
+ case FieldDescriptor::CPPTYPE_INT64:
+ case FieldDescriptor::CPPTYPE_UINT64:
+ case FieldDescriptor::CPPTYPE_DOUBLE:
+ case FieldDescriptor::CPPTYPE_STRING:
+ case FieldDescriptor::CPPTYPE_MESSAGE:
+ return 8;
+ }
+ GOOGLE_LOG(FATAL) << "Can't get here.";
+ return -1; // Make compiler happy.
+}
+
+std::string FieldConstantName(const FieldDescriptor* field) {
+ std::string field_name = UnderscoresToCamelCase(field->name(), true);
+ std::string result = "k" + field_name + "FieldNumber";
+
+ if (!field->is_extension() &&
+ field->containing_type()->FindFieldByCamelcaseName(
+ field->camelcase_name()) != field) {
+ // This field's camelcase name is not unique. As a hack, add the field
+ // number to the constant name. This makes the constant rather useless,
+ // but what can we do?
+ result += "_" + StrCat(field->number());
+ }
+
+ return result;
+}
+
+std::string FieldMessageTypeName(const FieldDescriptor* field,
+ const Options& options) {
+ // Note: The Google-internal version of Protocol Buffers uses this function
+ // as a hook point for hacks to support legacy code.
+ return QualifiedClassName(field->message_type(), options);
+}
+
+std::string StripProto(const std::string& filename) {
+ /*
+ * TODO(github/georgthegreat) remove this proxy method
+ * once Google's internal codebase will become ready
+ */
+ return compiler::StripProto(filename);
+}
+
+const char* PrimitiveTypeName(FieldDescriptor::CppType type) {
+ switch (type) {
+ case FieldDescriptor::CPPTYPE_INT32:
+ return "int32_t";
+ case FieldDescriptor::CPPTYPE_INT64:
+ return "int64_t";
+ case FieldDescriptor::CPPTYPE_UINT32:
+ return "uint32_t";
+ case FieldDescriptor::CPPTYPE_UINT64:
+ return "uint64_t";
+ case FieldDescriptor::CPPTYPE_DOUBLE:
+ return "double";
+ case FieldDescriptor::CPPTYPE_FLOAT:
+ return "float";
+ case FieldDescriptor::CPPTYPE_BOOL:
+ return "bool";
+ case FieldDescriptor::CPPTYPE_ENUM:
+ return "int";
+ case FieldDescriptor::CPPTYPE_STRING:
+ return "std::string";
+ case FieldDescriptor::CPPTYPE_MESSAGE:
+ return nullptr;
+
+ // No default because we want the compiler to complain if any new
+ // CppTypes are added.
+ }
+
+ GOOGLE_LOG(FATAL) << "Can't get here.";
+ return nullptr;
+}
+
+std::string PrimitiveTypeName(const Options& options,
+ FieldDescriptor::CppType type) {
+ switch (type) {
+ case FieldDescriptor::CPPTYPE_INT32:
+ return IntTypeName(options, "int32");
+ case FieldDescriptor::CPPTYPE_INT64:
+ return IntTypeName(options, "int64");
+ case FieldDescriptor::CPPTYPE_UINT32:
+ return IntTypeName(options, "uint32");
+ case FieldDescriptor::CPPTYPE_UINT64:
+ return IntTypeName(options, "uint64");
+ case FieldDescriptor::CPPTYPE_DOUBLE:
+ return "double";
+ case FieldDescriptor::CPPTYPE_FLOAT:
+ return "float";
+ case FieldDescriptor::CPPTYPE_BOOL:
+ return "bool";
+ case FieldDescriptor::CPPTYPE_ENUM:
+ return "int";
+ case FieldDescriptor::CPPTYPE_STRING:
+ return "std::string";
+ case FieldDescriptor::CPPTYPE_MESSAGE:
+ return "";
+
+ // No default because we want the compiler to complain if any new
+ // CppTypes are added.
+ }
+
+ GOOGLE_LOG(FATAL) << "Can't get here.";
+ return "";
+}
+
+const char* DeclaredTypeMethodName(FieldDescriptor::Type type) {
+ switch (type) {
+ case FieldDescriptor::TYPE_INT32:
+ return "Int32";
+ case FieldDescriptor::TYPE_INT64:
+ return "Int64";
+ case FieldDescriptor::TYPE_UINT32:
+ return "UInt32";
+ case FieldDescriptor::TYPE_UINT64:
+ return "UInt64";
+ case FieldDescriptor::TYPE_SINT32:
+ return "SInt32";
+ case FieldDescriptor::TYPE_SINT64:
+ return "SInt64";
+ case FieldDescriptor::TYPE_FIXED32:
+ return "Fixed32";
+ case FieldDescriptor::TYPE_FIXED64:
+ return "Fixed64";
+ case FieldDescriptor::TYPE_SFIXED32:
+ return "SFixed32";
+ case FieldDescriptor::TYPE_SFIXED64:
+ return "SFixed64";
+ case FieldDescriptor::TYPE_FLOAT:
+ return "Float";
+ case FieldDescriptor::TYPE_DOUBLE:
+ return "Double";
+
+ case FieldDescriptor::TYPE_BOOL:
+ return "Bool";
+ case FieldDescriptor::TYPE_ENUM:
+ return "Enum";
+
+ case FieldDescriptor::TYPE_STRING:
+ return "String";
+ case FieldDescriptor::TYPE_BYTES:
+ return "Bytes";
+ case FieldDescriptor::TYPE_GROUP:
+ return "Group";
+ case FieldDescriptor::TYPE_MESSAGE:
+ return "Message";
+
+ // No default because we want the compiler to complain if any new
+ // types are added.
+ }
+ GOOGLE_LOG(FATAL) << "Can't get here.";
+ return "";
+}
+
+std::string Int32ToString(int number) {
+ if (number == std::numeric_limits<int32_t>::min()) {
+ // This needs to be special-cased, see explanation here:
+ // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52661
+ return StrCat(number + 1, " - 1");
+ } else {
+ return StrCat(number);
+ }
+}
+
+static std::string Int64ToString(int64_t number) {
+ if (number == std::numeric_limits<int64_t>::min()) {
+ // This needs to be special-cased, see explanation here:
+ // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52661
+ return StrCat("int64_t{", number + 1, "} - 1");
+ }
+ return StrCat("int64_t{", number, "}");
+}
+
+static std::string UInt64ToString(uint64_t number) {
+ return StrCat("uint64_t{", number, "u}");
+}
+
+std::string DefaultValue(const FieldDescriptor* field) {
+ return DefaultValue(Options(), field);
+}
+
+std::string DefaultValue(const Options& options, const FieldDescriptor* field) {
+ switch (field->cpp_type()) {
+ case FieldDescriptor::CPPTYPE_INT32:
+ return Int32ToString(field->default_value_int32());
+ case FieldDescriptor::CPPTYPE_UINT32:
+ return StrCat(field->default_value_uint32()) + "u";
+ case FieldDescriptor::CPPTYPE_INT64:
+ return Int64ToString(field->default_value_int64());
+ case FieldDescriptor::CPPTYPE_UINT64:
+ return UInt64ToString(field->default_value_uint64());
+ case FieldDescriptor::CPPTYPE_DOUBLE: {
+ double value = field->default_value_double();
+ if (value == std::numeric_limits<double>::infinity()) {
+ return "std::numeric_limits<double>::infinity()";
+ } else if (value == -std::numeric_limits<double>::infinity()) {
+ return "-std::numeric_limits<double>::infinity()";
+ } else if (value != value) {
+ return "std::numeric_limits<double>::quiet_NaN()";
+ } else {
+ return SimpleDtoa(value);
+ }
+ }
+ case FieldDescriptor::CPPTYPE_FLOAT: {
+ float value = field->default_value_float();
+ if (value == std::numeric_limits<float>::infinity()) {
+ return "std::numeric_limits<float>::infinity()";
+ } else if (value == -std::numeric_limits<float>::infinity()) {
+ return "-std::numeric_limits<float>::infinity()";
+ } else if (value != value) {
+ return "std::numeric_limits<float>::quiet_NaN()";
+ } else {
+ std::string float_value = SimpleFtoa(value);
+ // If floating point value contains a period (.) or an exponent
+ // (either E or e), then append suffix 'f' to make it a float
+ // literal.
+ if (float_value.find_first_of(".eE") != std::string::npos) {
+ float_value.push_back('f');
+ }
+ return float_value;
+ }
+ }
+ case FieldDescriptor::CPPTYPE_BOOL:
+ return field->default_value_bool() ? "true" : "false";
+ case FieldDescriptor::CPPTYPE_ENUM:
+ // Lazy: Generate a static_cast because we don't have a helper function
+ // that constructs the full name of an enum value.
+ return strings::Substitute(
+ "static_cast< $0 >($1)", ClassName(field->enum_type(), true),
+ Int32ToString(field->default_value_enum()->number()));
+ case FieldDescriptor::CPPTYPE_STRING:
+ return "\"" +
+ EscapeTrigraphs(CEscape(field->default_value_string())) +
+ "\"";
+ case FieldDescriptor::CPPTYPE_MESSAGE:
+ return "*" + FieldMessageTypeName(field, options) +
+ "::internal_default_instance()";
+ }
+ // Can't actually get here; make compiler happy. (We could add a default
+ // case above but then we wouldn't get the nice compiler warning when a
+ // new type is added.)
+ GOOGLE_LOG(FATAL) << "Can't get here.";
+ return "";
+}
+
+// Convert a file name into a valid identifier.
+std::string FilenameIdentifier(const std::string& filename) {
+ std::string result;
+ for (int i = 0; i < filename.size(); i++) {
+ if (ascii_isalnum(filename[i])) {
+ result.push_back(filename[i]);
+ } else {
+ // Not alphanumeric. To avoid any possibility of name conflicts we
+ // use the hex code for the character.
+ StrAppend(&result, "_",
+ strings::Hex(static_cast<uint8_t>(filename[i])));
+ }
+ }
+ return result;
+}
+
+std::string UniqueName(const std::string& name, const std::string& filename,
+ const Options& options) {
+ return name + "_" + FilenameIdentifier(filename);
+}
+
+// Return the qualified C++ name for a file level symbol.
+std::string QualifiedFileLevelSymbol(const FileDescriptor* file,
+ const std::string& name,
+ const Options& options) {
+ if (file->package().empty()) {
+ return StrCat("::", name);
+ }
+ return StrCat(Namespace(file, options), "::", name);
+}
+
+// Escape C++ trigraphs by escaping question marks to \?
+std::string EscapeTrigraphs(const std::string& to_escape) {
+ return StringReplace(to_escape, "?", "\\?", true);
+}
+
+// Escaped function name to eliminate naming conflict.
+std::string SafeFunctionName(const Descriptor* descriptor,
+ const FieldDescriptor* field,
+ const std::string& prefix) {
+ // Do not use FieldName() since it will escape keywords.
+ std::string name = field->name();
+ LowerString(&name);
+ std::string function_name = prefix + name;
+ if (descriptor->FindFieldByName(function_name)) {
+ // Single underscore will also make it conflicting with the private data
+ // member. We use double underscore to escape function names.
+ function_name.append("__");
+ } else if (kKeywords.count(name) > 0) {
+ // If the field name is a keyword, we append the underscore back to keep it
+ // consistent with other function names.
+ function_name.append("_");
+ }
+ return function_name;
+}
+
+bool IsStringInlined(const FieldDescriptor* descriptor,
+ const Options& options) {
+ (void)descriptor;
+ (void)options;
+ return false;
+}
+
+static bool HasLazyFields(const Descriptor* descriptor, const Options& options,
+ MessageSCCAnalyzer* scc_analyzer) {
+ for (int field_idx = 0; field_idx < descriptor->field_count(); field_idx++) {
+ if (IsLazy(descriptor->field(field_idx), options, scc_analyzer)) {
+ return true;
+ }
+ }
+ for (int idx = 0; idx < descriptor->extension_count(); idx++) {
+ if (IsLazy(descriptor->extension(idx), options, scc_analyzer)) {
+ return true;
+ }
+ }
+ for (int idx = 0; idx < descriptor->nested_type_count(); idx++) {
+ if (HasLazyFields(descriptor->nested_type(idx), options, scc_analyzer)) {
+ return true;
+ }
+ }
+ return false;
+}
+
+// Does the given FileDescriptor use lazy fields?
+bool HasLazyFields(const FileDescriptor* file, const Options& options,
+ MessageSCCAnalyzer* scc_analyzer) {
+ for (int i = 0; i < file->message_type_count(); i++) {
+ const Descriptor* descriptor(file->message_type(i));
+ if (HasLazyFields(descriptor, options, scc_analyzer)) {
+ return true;
+ }
+ }
+ for (int field_idx = 0; field_idx < file->extension_count(); field_idx++) {
+ if (IsLazy(file->extension(field_idx), options, scc_analyzer)) {
+ return true;
+ }
+ }
+ return false;
+}
+
+static bool HasRepeatedFields(const Descriptor* descriptor) {
+ for (int i = 0; i < descriptor->field_count(); ++i) {
+ if (descriptor->field(i)->label() == FieldDescriptor::LABEL_REPEATED) {
+ return true;
+ }
+ }
+ for (int i = 0; i < descriptor->nested_type_count(); ++i) {
+ if (HasRepeatedFields(descriptor->nested_type(i))) return true;
+ }
+ return false;
+}
+
+bool HasRepeatedFields(const FileDescriptor* file) {
+ for (int i = 0; i < file->message_type_count(); ++i) {
+ if (HasRepeatedFields(file->message_type(i))) return true;
+ }
+ return false;
+}
+
+static bool IsStringPieceField(const FieldDescriptor* field,
+ const Options& options) {
+ return field->cpp_type() == FieldDescriptor::CPPTYPE_STRING &&
+ EffectiveStringCType(field, options) == FieldOptions::STRING_PIECE;
+}
+
+static bool HasStringPieceFields(const Descriptor* descriptor,
+ const Options& options) {
+ for (int i = 0; i < descriptor->field_count(); ++i) {
+ if (IsStringPieceField(descriptor->field(i), options)) return true;
+ }
+ for (int i = 0; i < descriptor->nested_type_count(); ++i) {
+ if (HasStringPieceFields(descriptor->nested_type(i), options)) return true;
+ }
+ return false;
+}
+
+bool HasStringPieceFields(const FileDescriptor* file, const Options& options) {
+ for (int i = 0; i < file->message_type_count(); ++i) {
+ if (HasStringPieceFields(file->message_type(i), options)) return true;
+ }
+ return false;
+}
+
+static bool IsCordField(const FieldDescriptor* field, const Options& options) {
+ return field->cpp_type() == FieldDescriptor::CPPTYPE_STRING &&
+ EffectiveStringCType(field, options) == FieldOptions::CORD;
+}
+
+static bool HasCordFields(const Descriptor* descriptor,
+ const Options& options) {
+ for (int i = 0; i < descriptor->field_count(); ++i) {
+ if (IsCordField(descriptor->field(i), options)) return true;
+ }
+ for (int i = 0; i < descriptor->nested_type_count(); ++i) {
+ if (HasCordFields(descriptor->nested_type(i), options)) return true;
+ }
+ return false;
+}
+
+bool HasCordFields(const FileDescriptor* file, const Options& options) {
+ for (int i = 0; i < file->message_type_count(); ++i) {
+ if (HasCordFields(file->message_type(i), options)) return true;
+ }
+ return false;
+}
+
+static bool HasExtensionsOrExtendableMessage(const Descriptor* descriptor) {
+ if (descriptor->extension_range_count() > 0) return true;
+ if (descriptor->extension_count() > 0) return true;
+ for (int i = 0; i < descriptor->nested_type_count(); ++i) {
+ if (HasExtensionsOrExtendableMessage(descriptor->nested_type(i))) {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool HasExtensionsOrExtendableMessage(const FileDescriptor* file) {
+ if (file->extension_count() > 0) return true;
+ for (int i = 0; i < file->message_type_count(); ++i) {
+ if (HasExtensionsOrExtendableMessage(file->message_type(i))) return true;
+ }
+ return false;
+}
+
+static bool HasMapFields(const Descriptor* descriptor) {
+ for (int i = 0; i < descriptor->field_count(); ++i) {
+ if (descriptor->field(i)->is_map()) {
+ return true;
+ }
+ }
+ for (int i = 0; i < descriptor->nested_type_count(); ++i) {
+ if (HasMapFields(descriptor->nested_type(i))) return true;
+ }
+ return false;
+}
+
+bool HasMapFields(const FileDescriptor* file) {
+ for (int i = 0; i < file->message_type_count(); ++i) {
+ if (HasMapFields(file->message_type(i))) return true;
+ }
+ return false;
+}
+
+static bool HasEnumDefinitions(const Descriptor* message_type) {
+ if (message_type->enum_type_count() > 0) return true;
+ for (int i = 0; i < message_type->nested_type_count(); ++i) {
+ if (HasEnumDefinitions(message_type->nested_type(i))) return true;
+ }
+ return false;
+}
+
+bool HasEnumDefinitions(const FileDescriptor* file) {
+ if (file->enum_type_count() > 0) return true;
+ for (int i = 0; i < file->message_type_count(); ++i) {
+ if (HasEnumDefinitions(file->message_type(i))) return true;
+ }
+ return false;
+}
+
+bool ShouldVerify(const Descriptor* descriptor, const Options& options,
+ MessageSCCAnalyzer* scc_analyzer) {
+ (void)descriptor;
+ (void)options;
+ (void)scc_analyzer;
+ return false;
+}
+
+bool ShouldVerify(const FileDescriptor* file, const Options& options,
+ MessageSCCAnalyzer* scc_analyzer) {
+ (void)file;
+ (void)options;
+ (void)scc_analyzer;
+ return false;
+}
+
+bool IsStringOrMessage(const FieldDescriptor* field) {
+ 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:
+ return false;
+ case FieldDescriptor::CPPTYPE_STRING:
+ case FieldDescriptor::CPPTYPE_MESSAGE:
+ return true;
+ }
+
+ GOOGLE_LOG(FATAL) << "Can't get here.";
+ return false;
+}
+
+FieldOptions::CType EffectiveStringCType(const FieldDescriptor* field,
+ const Options& options) {
+ GOOGLE_DCHECK(field->cpp_type() == FieldDescriptor::CPPTYPE_STRING);
+ if (options.opensource_runtime) {
+ // Open-source protobuf release only supports STRING ctype.
+ return FieldOptions::STRING;
+ } else {
+ // Google-internal supports all ctypes.
+ return field->options().ctype();
+ }
+}
+
+bool IsAnyMessage(const FileDescriptor* descriptor, const Options& options) {
+ return descriptor->name() == kAnyProtoFile;
+}
+
+bool IsAnyMessage(const Descriptor* descriptor, const Options& options) {
+ return descriptor->name() == kAnyMessageName &&
+ IsAnyMessage(descriptor->file(), options);
+}
+
+bool IsWellKnownMessage(const FileDescriptor* file) {
+ static const std::unordered_set<std::string> well_known_files{
+ "google/protobuf/any.proto",
+ "google/protobuf/api.proto",
+ "google/protobuf/compiler/plugin.proto",
+ "google/protobuf/descriptor.proto",
+ "google/protobuf/duration.proto",
+ "google/protobuf/empty.proto",
+ "google/protobuf/field_mask.proto",
+ "google/protobuf/source_context.proto",
+ "google/protobuf/struct.proto",
+ "google/protobuf/timestamp.proto",
+ "google/protobuf/type.proto",
+ "google/protobuf/wrappers.proto",
+ };
+ return well_known_files.find(file->name()) != well_known_files.end();
+}
+
+static bool FieldEnforceUtf8(const FieldDescriptor* field,
+ const Options& options) {
+ return true;
+}
+
+static bool FileUtf8Verification(const FileDescriptor* file,
+ const Options& options) {
+ return true;
+}
+
+// Which level of UTF-8 enforcemant is placed on this file.
+Utf8CheckMode GetUtf8CheckMode(const FieldDescriptor* field,
+ const Options& options) {
+ if (field->file()->syntax() == FileDescriptor::SYNTAX_PROTO3 &&
+ FieldEnforceUtf8(field, options)) {
+ return Utf8CheckMode::kStrict;
+ } else if (GetOptimizeFor(field->file(), options) !=
+ FileOptions::LITE_RUNTIME &&
+ FileUtf8Verification(field->file(), options)) {
+ return Utf8CheckMode::kVerify;
+ } else {
+ return Utf8CheckMode::kNone;
+ }
+}
+
+static void GenerateUtf8CheckCode(const FieldDescriptor* field,
+ const Options& options, bool for_parse,
+ const char* parameters,
+ const char* strict_function,
+ const char* verify_function,
+ const Formatter& format) {
+ switch (GetUtf8CheckMode(field, options)) {
+ case Utf8CheckMode::kStrict: {
+ if (for_parse) {
+ format("DO_(");
+ }
+ format("::$proto_ns$::internal::WireFormatLite::$1$(\n", strict_function);
+ format.Indent();
+ format(parameters);
+ if (for_parse) {
+ format("::$proto_ns$::internal::WireFormatLite::PARSE,\n");
+ } else {
+ format("::$proto_ns$::internal::WireFormatLite::SERIALIZE,\n");
+ }
+ format("\"$1$\")", field->full_name());
+ if (for_parse) {
+ format(")");
+ }
+ format(";\n");
+ format.Outdent();
+ break;
+ }
+ case Utf8CheckMode::kVerify: {
+ format("::$proto_ns$::internal::WireFormat::$1$(\n", verify_function);
+ format.Indent();
+ format(parameters);
+ if (for_parse) {
+ format("::$proto_ns$::internal::WireFormat::PARSE,\n");
+ } else {
+ format("::$proto_ns$::internal::WireFormat::SERIALIZE,\n");
+ }
+ format("\"$1$\");\n", field->full_name());
+ format.Outdent();
+ break;
+ }
+ case Utf8CheckMode::kNone:
+ break;
+ }
+}
+
+void GenerateUtf8CheckCodeForString(const FieldDescriptor* field,
+ const Options& options, bool for_parse,
+ const char* parameters,
+ const Formatter& format) {
+ GenerateUtf8CheckCode(field, options, for_parse, parameters,
+ "VerifyUtf8String", "VerifyUTF8StringNamedField",
+ format);
+}
+
+void GenerateUtf8CheckCodeForCord(const FieldDescriptor* field,
+ const Options& options, bool for_parse,
+ const char* parameters,
+ const Formatter& format) {
+ GenerateUtf8CheckCode(field, options, for_parse, parameters, "VerifyUtf8Cord",
+ "VerifyUTF8CordNamedField", format);
+}
+
+void FlattenMessagesInFile(const FileDescriptor* file,
+ std::vector<const Descriptor*>* result) {
+ for (int i = 0; i < file->message_type_count(); i++) {
+ ForEachMessage(file->message_type(i), [&](const Descriptor* descriptor) {
+ result->push_back(descriptor);
+ });
+ }
+}
+
+bool HasWeakFields(const Descriptor* descriptor, const Options& options) {
+ for (int i = 0; i < descriptor->field_count(); i++) {
+ if (IsWeak(descriptor->field(i), options)) return true;
+ }
+ return false;
+}
+
+bool HasWeakFields(const FileDescriptor* file, const Options& options) {
+ for (int i = 0; i < file->message_type_count(); ++i) {
+ if (HasWeakFields(file->message_type(i), options)) return true;
+ }
+ return false;
+}
+
+bool UsingImplicitWeakFields(const FileDescriptor* file,
+ const Options& options) {
+ return options.lite_implicit_weak_fields &&
+ GetOptimizeFor(file, options) == FileOptions::LITE_RUNTIME;
+}
+
+bool IsImplicitWeakField(const FieldDescriptor* field, const Options& options,
+ MessageSCCAnalyzer* scc_analyzer) {
+ return UsingImplicitWeakFields(field->file(), options) &&
+ field->type() == FieldDescriptor::TYPE_MESSAGE &&
+ !field->is_required() && !field->is_map() && !field->is_extension() &&
+ !field->real_containing_oneof() &&
+ !IsWellKnownMessage(field->message_type()->file()) &&
+ field->message_type()->file()->name() !=
+ "net/proto2/proto/descriptor.proto" &&
+ // We do not support implicit weak fields between messages in the same
+ // strongly-connected component.
+ scc_analyzer->GetSCC(field->containing_type()) !=
+ scc_analyzer->GetSCC(field->message_type());
+}
+
+MessageAnalysis MessageSCCAnalyzer::GetSCCAnalysis(const SCC* scc) {
+ if (analysis_cache_.count(scc)) return analysis_cache_[scc];
+ MessageAnalysis result;
+ if (UsingImplicitWeakFields(scc->GetFile(), options_)) {
+ result.contains_weak = true;
+ }
+ for (int i = 0; i < scc->descriptors.size(); i++) {
+ const Descriptor* descriptor = scc->descriptors[i];
+ if (descriptor->extension_range_count() > 0) {
+ result.contains_extension = true;
+ }
+ for (int j = 0; j < descriptor->field_count(); j++) {
+ const FieldDescriptor* field = descriptor->field(j);
+ if (field->is_required()) {
+ result.contains_required = true;
+ }
+ if (field->options().weak()) {
+ result.contains_weak = true;
+ }
+ switch (field->type()) {
+ case FieldDescriptor::TYPE_STRING:
+ case FieldDescriptor::TYPE_BYTES: {
+ if (field->options().ctype() == FieldOptions::CORD) {
+ result.contains_cord = true;
+ }
+ break;
+ }
+ case FieldDescriptor::TYPE_GROUP:
+ case FieldDescriptor::TYPE_MESSAGE: {
+ const SCC* child = analyzer_.GetSCC(field->message_type());
+ if (child != scc) {
+ MessageAnalysis analysis = GetSCCAnalysis(child);
+ result.contains_cord |= analysis.contains_cord;
+ result.contains_extension |= analysis.contains_extension;
+ if (!ShouldIgnoreRequiredFieldCheck(field, options_)) {
+ result.contains_required |= analysis.contains_required;
+ }
+ result.contains_weak |= analysis.contains_weak;
+ } else {
+ // This field points back into the same SCC hence the messages
+ // in the SCC are recursive. Note if SCC contains more than two
+ // nodes it has to be recursive, however this test also works for
+ // a single node that is recursive.
+ result.is_recursive = true;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ }
+ // We deliberately only insert the result here. After we contracted the SCC
+ // in the graph, the graph should be a DAG. Hence we shouldn't need to mark
+ // nodes visited as we can never return to them. By inserting them here
+ // we will go in an infinite loop if the SCC is not correct.
+ return analysis_cache_[scc] = result;
+}
+
+void ListAllFields(const Descriptor* d,
+ std::vector<const FieldDescriptor*>* fields) {
+ // Collect sub messages
+ for (int i = 0; i < d->nested_type_count(); i++) {
+ ListAllFields(d->nested_type(i), fields);
+ }
+ // Collect message level extensions.
+ for (int i = 0; i < d->extension_count(); i++) {
+ fields->push_back(d->extension(i));
+ }
+ // Add types of fields necessary
+ for (int i = 0; i < d->field_count(); i++) {
+ fields->push_back(d->field(i));
+ }
+}
+
+void ListAllFields(const FileDescriptor* d,
+ std::vector<const FieldDescriptor*>* fields) {
+ // Collect file level message.
+ for (int i = 0; i < d->message_type_count(); i++) {
+ ListAllFields(d->message_type(i), fields);
+ }
+ // Collect message level extensions.
+ for (int i = 0; i < d->extension_count(); i++) {
+ fields->push_back(d->extension(i));
+ }
+}
+
+void ListAllTypesForServices(const FileDescriptor* fd,
+ std::vector<const Descriptor*>* types) {
+ for (int i = 0; i < fd->service_count(); i++) {
+ const ServiceDescriptor* sd = fd->service(i);
+ for (int j = 0; j < sd->method_count(); j++) {
+ const MethodDescriptor* method = sd->method(j);
+ types->push_back(method->input_type());
+ types->push_back(method->output_type());
+ }
+ }
+}
+
+bool GetBootstrapBasename(const Options& options, const std::string& basename,
+ std::string* bootstrap_basename) {
+ if (options.opensource_runtime) {
+ return false;
+ }
+
+ std::unordered_map<std::string, std::string> bootstrap_mapping{
+ {"net/proto2/proto/descriptor",
+ "net/proto2/internal/descriptor"},
+ {"net/proto2/compiler/proto/plugin",
+ "net/proto2/compiler/proto/plugin"},
+ {"net/proto2/compiler/proto/profile",
+ "net/proto2/compiler/proto/profile_bootstrap"},
+ };
+ auto iter = bootstrap_mapping.find(basename);
+ if (iter == bootstrap_mapping.end()) {
+ *bootstrap_basename = basename;
+ return false;
+ } else {
+ *bootstrap_basename = iter->second;
+ return true;
+ }
+}
+
+bool IsBootstrapProto(const Options& options, const FileDescriptor* file) {
+ std::string my_name = StripProto(file->name());
+ return GetBootstrapBasename(options, my_name, &my_name);
+}
+
+bool MaybeBootstrap(const Options& options, GeneratorContext* generator_context,
+ bool bootstrap_flag, std::string* basename) {
+ std::string bootstrap_basename;
+ if (!GetBootstrapBasename(options, *basename, &bootstrap_basename)) {
+ return false;
+ }
+
+ if (bootstrap_flag) {
+ // Adjust basename, but don't abort code generation.
+ *basename = bootstrap_basename;
+ return false;
+ } else {
+ std::string forward_to_basename = bootstrap_basename;
+
+ // Generate forwarding headers and empty .pb.cc.
+ {
+ std::unique_ptr<io::ZeroCopyOutputStream> output(
+ generator_context->Open(*basename + ".pb.h"));
+ io::Printer printer(output.get(), '$', nullptr);
+ printer.Print(
+ "#ifndef PROTOBUF_INCLUDED_$filename_identifier$_FORWARD_PB_H\n"
+ "#define PROTOBUF_INCLUDED_$filename_identifier$_FORWARD_PB_H\n"
+ "#include \"$forward_to_basename$.pb.h\" // IWYU pragma: export\n"
+ "#endif // PROTOBUF_INCLUDED_$filename_identifier$_FORWARD_PB_H\n",
+ "forward_to_basename", forward_to_basename, "filename_identifier",
+ FilenameIdentifier(*basename));
+
+ if (!options.opensource_runtime) {
+ // HACK HACK HACK, tech debt from the deeps of proto1 and SWIG
+ // protocoltype is SWIG'ed and we need to forward
+ if (*basename == "net/proto/protocoltype") {
+ printer.Print(
+ "#ifdef SWIG\n"
+ "%include \"$forward_to_basename$.pb.h\"\n"
+ "#endif // SWIG\n",
+ "forward_to_basename", forward_to_basename);
+ }
+ }
+ }
+
+ {
+ std::unique_ptr<io::ZeroCopyOutputStream> output(
+ generator_context->Open(*basename + ".proto.h"));
+ io::Printer printer(output.get(), '$', nullptr);
+ printer.Print(
+ "#ifndef PROTOBUF_INCLUDED_$filename_identifier$_FORWARD_PROTO_H\n"
+ "#define PROTOBUF_INCLUDED_$filename_identifier$_FORWARD_PROTO_H\n"
+ "#include \"$forward_to_basename$.proto.h\" // IWYU pragma: "
+ "export\n"
+ "#endif // "
+ "PROTOBUF_INCLUDED_$filename_identifier$_FORWARD_PROTO_H\n",
+ "forward_to_basename", forward_to_basename, "filename_identifier",
+ FilenameIdentifier(*basename));
+ }
+
+ {
+ std::unique_ptr<io::ZeroCopyOutputStream> output(
+ generator_context->Open(*basename + ".pb.cc"));
+ io::Printer printer(output.get(), '$', nullptr);
+ printer.Print("\n");
+ }
+
+ {
+ std::unique_ptr<io::ZeroCopyOutputStream> output(
+ generator_context->Open(*basename + ".pb.h.meta"));
+ }
+
+ {
+ std::unique_ptr<io::ZeroCopyOutputStream> output(
+ generator_context->Open(*basename + ".proto.h.meta"));
+ }
+
+ // Abort code generation.
+ return true;
+ }
+}
+
+static bool HasExtensionFromFile(const Message& msg, const FileDescriptor* file,
+ const Options& options,
+ bool* has_opt_codesize_extension) {
+ std::vector<const FieldDescriptor*> fields;
+ auto reflection = msg.GetReflection();
+ reflection->ListFields(msg, &fields);
+ for (auto field : fields) {
+ const auto* field_msg = field->message_type();
+ if (field_msg == nullptr) {
+ // It so happens that enums Is_Valid are still generated so enums work.
+ // Only messages have potential problems.
+ continue;
+ }
+ // If this option has an extension set AND that extension is defined in the
+ // same file we have bootstrap problem.
+ if (field->is_extension()) {
+ const auto* msg_extension_file = field->message_type()->file();
+ if (msg_extension_file == file) return true;
+ if (has_opt_codesize_extension &&
+ GetOptimizeFor(msg_extension_file, options) ==
+ FileOptions::CODE_SIZE) {
+ *has_opt_codesize_extension = true;
+ }
+ }
+ // Recurse in this field to see if there is a problem in there
+ if (field->is_repeated()) {
+ for (int i = 0; i < reflection->FieldSize(msg, field); i++) {
+ if (HasExtensionFromFile(reflection->GetRepeatedMessage(msg, field, i),
+ file, options, has_opt_codesize_extension)) {
+ return true;
+ }
+ }
+ } else {
+ if (HasExtensionFromFile(reflection->GetMessage(msg, field), file,
+ options, has_opt_codesize_extension)) {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+static bool HasBootstrapProblem(const FileDescriptor* file,
+ const Options& options,
+ bool* has_opt_codesize_extension) {
+ static auto& cache = *new std::unordered_map<const FileDescriptor*, bool>;
+ auto it = cache.find(file);
+ if (it != cache.end()) return it->second;
+ // In order to build the data structures for the reflective parse, it needs
+ // to parse the serialized descriptor describing all the messages defined in
+ // this file. Obviously this presents a bootstrap problem for descriptor
+ // messages.
+ if (file->name() == "net/proto2/proto/descriptor.proto" ||
+ file->name() == "google/protobuf/descriptor.proto") {
+ return true;
+ }
+ // Unfortunately we're not done yet. The descriptor option messages allow
+ // for extensions. So we need to be able to parse these extensions in order
+ // to parse the file descriptor for a file that has custom options. This is a
+ // problem when these custom options extensions are defined in the same file.
+ FileDescriptorProto linkedin_fd_proto;
+ const DescriptorPool* pool = file->pool();
+ const Descriptor* fd_proto_descriptor =
+ pool->FindMessageTypeByName(linkedin_fd_proto.GetTypeName());
+ // Not all pools have descriptor.proto in them. In these cases there for sure
+ // are no custom options.
+ if (fd_proto_descriptor == nullptr) return false;
+
+ // It's easier to inspect file as a proto, because we can use reflection on
+ // the proto to iterate over all content.
+ file->CopyTo(&linkedin_fd_proto);
+
+ // linkedin_fd_proto is a generated proto linked in the proto compiler. As
+ // such it doesn't know the extensions that are potentially present in the
+ // descriptor pool constructed from the protos that are being compiled. These
+ // custom options are therefore in the unknown fields.
+ // By building the corresponding FileDescriptorProto in the pool constructed
+ // by the protos that are being compiled, ie. file's pool, the unknown fields
+ // are converted to extensions.
+ DynamicMessageFactory factory(pool);
+ Message* fd_proto = factory.GetPrototype(fd_proto_descriptor)->New();
+ fd_proto->ParseFromString(linkedin_fd_proto.SerializeAsString());
+
+ bool& res = cache[file];
+ res = HasExtensionFromFile(*fd_proto, file, options,
+ has_opt_codesize_extension);
+ delete fd_proto;
+ return res;
+}
+
+FileOptions_OptimizeMode GetOptimizeFor(const FileDescriptor* file,
+ const Options& options,
+ bool* has_opt_codesize_extension) {
+ if (has_opt_codesize_extension) *has_opt_codesize_extension = false;
+ switch (options.enforce_mode) {
+ case EnforceOptimizeMode::kSpeed:
+ return FileOptions::SPEED;
+ case EnforceOptimizeMode::kLiteRuntime:
+ return FileOptions::LITE_RUNTIME;
+ case EnforceOptimizeMode::kCodeSize:
+ if (file->options().optimize_for() == FileOptions::LITE_RUNTIME) {
+ return FileOptions::LITE_RUNTIME;
+ }
+ if (HasBootstrapProblem(file, options, has_opt_codesize_extension)) {
+ return FileOptions::SPEED;
+ }
+ return FileOptions::CODE_SIZE;
+ case EnforceOptimizeMode::kNoEnforcement:
+ if (file->options().optimize_for() == FileOptions::CODE_SIZE) {
+ if (HasBootstrapProblem(file, options, has_opt_codesize_extension)) {
+ GOOGLE_LOG(WARNING) << "Proto states optimize_for = CODE_SIZE, but we "
+ "cannot honor that because it contains custom option "
+ "extensions defined in the same proto.";
+ return FileOptions::SPEED;
+ }
+ }
+ return file->options().optimize_for();
+ }
+
+ GOOGLE_LOG(FATAL) << "Unknown optimization enforcement requested.";
+ // The phony return below serves to silence a warning from GCC 8.
+ return FileOptions::SPEED;
+}
+
+bool EnableMessageOwnedArena(const Descriptor* desc) {
+ (void)desc;
+ return false;
+}
+
+} // namespace cpp
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_helpers.h b/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_helpers.h
new file mode 100644
index 00000000..dd380c7e
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_helpers.h
@@ -0,0 +1,971 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 GOOGLE_PROTOBUF_COMPILER_CPP_HELPERS_H__
+#define GOOGLE_PROTOBUF_COMPILER_CPP_HELPERS_H__
+
+#include <algorithm>
+#include <cstdint>
+#include <iterator>
+#include <map>
+#include <string>
+
+#include <compiler/cpp/cpp_options.h>
+#include <compiler/cpp/cpp_names.h>
+#include <compiler/scc.h>
+#include <compiler/code_generator.h>
+#include <descriptor.pb.h>
+#include <io/printer.h>
+#include <descriptor.h>
+#include <port.h>
+#include <stubs/strutil.h>
+
+// Must be included last.
+#include <port_def.inc>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+inline std::string ProtobufNamespace(const Options& /* options */) {
+ return "PROTOBUF_NAMESPACE_ID";
+}
+
+inline std::string MacroPrefix(const Options& /* options */) {
+ return "GOOGLE_PROTOBUF";
+}
+
+inline std::string DeprecatedAttribute(const Options& /* options */,
+ const FieldDescriptor* d) {
+ return d->options().deprecated() ? "PROTOBUF_DEPRECATED " : "";
+}
+
+inline std::string DeprecatedAttribute(const Options& /* options */,
+ const EnumValueDescriptor* d) {
+ return d->options().deprecated() ? "PROTOBUF_DEPRECATED_ENUM " : "";
+}
+
+// Commonly-used separator comments. Thick is a line of '=', thin is a line
+// of '-'.
+extern const char kThickSeparator[];
+extern const char kThinSeparator[];
+
+void SetCommonVars(const Options& options,
+ std::map<std::string, std::string>* variables);
+
+void SetUnknownFieldsVariable(const Descriptor* descriptor,
+ const Options& options,
+ std::map<std::string, std::string>* variables);
+
+bool GetBootstrapBasename(const Options& options, const std::string& basename,
+ std::string* bootstrap_basename);
+bool MaybeBootstrap(const Options& options, GeneratorContext* generator_context,
+ bool bootstrap_flag, std::string* basename);
+bool IsBootstrapProto(const Options& options, const FileDescriptor* file);
+
+// Name space of the proto file. This namespace is such that the string
+// "<namespace>::some_name" is the correct fully qualified namespace.
+// This means if the package is empty the namespace is "", and otherwise
+// the namespace is "::foo::bar::...::baz" without trailing semi-colons.
+std::string Namespace(const FileDescriptor* d, const Options& options);
+std::string Namespace(const Descriptor* d, const Options& options);
+std::string Namespace(const FieldDescriptor* d, const Options& options);
+std::string Namespace(const EnumDescriptor* d, const Options& options);
+
+// Returns true if it's safe to reset "field" to zero.
+bool CanInitializeByZeroing(const FieldDescriptor* field);
+
+std::string ClassName(const Descriptor* descriptor);
+std::string ClassName(const EnumDescriptor* enum_descriptor);
+
+std::string QualifiedClassName(const Descriptor* d, const Options& options);
+std::string QualifiedClassName(const EnumDescriptor* d, const Options& options);
+
+std::string QualifiedClassName(const Descriptor* d);
+std::string QualifiedClassName(const EnumDescriptor* d);
+
+// DEPRECATED just use ClassName or QualifiedClassName, a boolean is very
+// unreadable at the callsite.
+// Returns the non-nested type name for the given type. If "qualified" is
+// true, prefix the type with the full namespace. For example, if you had:
+// package foo.bar;
+// message Baz { message Qux {} }
+// Then the qualified ClassName for Qux would be:
+// ::foo::bar::Baz_Qux
+// While the non-qualified version would be:
+// Baz_Qux
+inline std::string ClassName(const Descriptor* descriptor, bool qualified) {
+ return qualified ? QualifiedClassName(descriptor, Options())
+ : ClassName(descriptor);
+}
+
+inline std::string ClassName(const EnumDescriptor* descriptor, bool qualified) {
+ return qualified ? QualifiedClassName(descriptor, Options())
+ : ClassName(descriptor);
+}
+
+// Returns the extension name prefixed with the class name if nested but without
+// the package name.
+std::string ExtensionName(const FieldDescriptor* d);
+
+std::string QualifiedExtensionName(const FieldDescriptor* d,
+ const Options& options);
+std::string QualifiedExtensionName(const FieldDescriptor* d);
+
+// Type name of default instance.
+std::string DefaultInstanceType(const Descriptor* descriptor,
+ const Options& options);
+
+// Non-qualified name of the default_instance of this message.
+std::string DefaultInstanceName(const Descriptor* descriptor,
+ const Options& options);
+
+// Non-qualified name of the default instance pointer. This is used only for
+// implicit weak fields, where we need an extra indirection.
+std::string DefaultInstancePtr(const Descriptor* descriptor,
+ const Options& options);
+
+// Fully qualified name of the default_instance of this message.
+std::string QualifiedDefaultInstanceName(const Descriptor* descriptor,
+ const Options& options);
+
+// Fully qualified name of the default instance pointer.
+std::string QualifiedDefaultInstancePtr(const Descriptor* descriptor,
+ const Options& options);
+
+// DescriptorTable variable name.
+std::string DescriptorTableName(const FileDescriptor* file,
+ const Options& options);
+
+// When declaring symbol externs from another file, this macro will supply the
+// dllexport needed for the target file, if any.
+std::string FileDllExport(const FileDescriptor* file, const Options& options);
+
+// Name of the base class: google::protobuf::Message or google::protobuf::MessageLite.
+std::string SuperClassName(const Descriptor* descriptor,
+ const Options& options);
+
+// Adds an underscore if necessary to prevent conflicting with a keyword.
+std::string ResolveKeyword(const std::string& name);
+
+// Get the (unqualified) name that should be used for this field in C++ code.
+// The name is coerced to lower-case to emulate proto1 behavior. People
+// should be using lowercase-with-underscores style for proto field names
+// anyway, so normally this just returns field->name().
+std::string FieldName(const FieldDescriptor* field);
+
+// Returns an estimate of the compiler's alignment for the field. This
+// can't guarantee to be correct because the generated code could be compiled on
+// different systems with different alignment rules. The estimates below assume
+// 64-bit pointers.
+int EstimateAlignmentSize(const FieldDescriptor* field);
+
+// Get the unqualified name that should be used for a field's field
+// number constant.
+std::string FieldConstantName(const FieldDescriptor* field);
+
+// Returns the scope where the field was defined (for extensions, this is
+// different from the message type to which the field applies).
+inline const Descriptor* FieldScope(const FieldDescriptor* field) {
+ return field->is_extension() ? field->extension_scope()
+ : field->containing_type();
+}
+
+// Returns the fully-qualified type name field->message_type(). Usually this
+// is just ClassName(field->message_type(), true);
+std::string FieldMessageTypeName(const FieldDescriptor* field,
+ const Options& options);
+
+// Get the C++ type name for a primitive type (e.g. "double", "::google::protobuf::int32", etc.).
+const char* PrimitiveTypeName(FieldDescriptor::CppType type);
+std::string PrimitiveTypeName(const Options& options,
+ FieldDescriptor::CppType type);
+
+// Get the declared type name in CamelCase format, as is used e.g. for the
+// methods of WireFormat. For example, TYPE_INT32 becomes "Int32".
+const char* DeclaredTypeMethodName(FieldDescriptor::Type type);
+
+// Return the code that evaluates to the number when compiled.
+std::string Int32ToString(int number);
+
+// Get code that evaluates to the field's default value.
+std::string DefaultValue(const Options& options, const FieldDescriptor* field);
+
+// Compatibility function for callers outside proto2.
+std::string DefaultValue(const FieldDescriptor* field);
+
+// Convert a file name into a valid identifier.
+std::string FilenameIdentifier(const std::string& filename);
+
+// For each .proto file generates a unique name. To prevent collisions of
+// symbols in the global namespace
+std::string UniqueName(const std::string& name, const std::string& filename,
+ const Options& options);
+inline std::string UniqueName(const std::string& name, const FileDescriptor* d,
+ const Options& options) {
+ return UniqueName(name, d->name(), options);
+}
+inline std::string UniqueName(const std::string& name, const Descriptor* d,
+ const Options& options) {
+ return UniqueName(name, d->file(), options);
+}
+inline std::string UniqueName(const std::string& name, const EnumDescriptor* d,
+ const Options& options) {
+ return UniqueName(name, d->file(), options);
+}
+inline std::string UniqueName(const std::string& name,
+ const ServiceDescriptor* d,
+ const Options& options) {
+ return UniqueName(name, d->file(), options);
+}
+
+// Versions for call sites that only support the internal runtime (like proto1
+// support).
+inline Options InternalRuntimeOptions() {
+ Options options;
+ options.opensource_runtime = false;
+ return options;
+}
+inline std::string UniqueName(const std::string& name,
+ const std::string& filename) {
+ return UniqueName(name, filename, InternalRuntimeOptions());
+}
+inline std::string UniqueName(const std::string& name,
+ const FileDescriptor* d) {
+ return UniqueName(name, d->name(), InternalRuntimeOptions());
+}
+inline std::string UniqueName(const std::string& name, const Descriptor* d) {
+ return UniqueName(name, d->file(), InternalRuntimeOptions());
+}
+inline std::string UniqueName(const std::string& name,
+ const EnumDescriptor* d) {
+ return UniqueName(name, d->file(), InternalRuntimeOptions());
+}
+inline std::string UniqueName(const std::string& name,
+ const ServiceDescriptor* d) {
+ return UniqueName(name, d->file(), InternalRuntimeOptions());
+}
+
+// Return the qualified C++ name for a file level symbol.
+std::string QualifiedFileLevelSymbol(const FileDescriptor* file,
+ const std::string& name,
+ const Options& options);
+
+// Escape C++ trigraphs by escaping question marks to \?
+std::string EscapeTrigraphs(const std::string& to_escape);
+
+// Escaped function name to eliminate naming conflict.
+std::string SafeFunctionName(const Descriptor* descriptor,
+ const FieldDescriptor* field,
+ const std::string& prefix);
+
+// Returns true if generated messages have public unknown fields accessors
+inline bool PublicUnknownFieldsAccessors(const Descriptor* message) {
+ return message->file()->syntax() != FileDescriptor::SYNTAX_PROTO3;
+}
+
+// Returns the optimize mode for <file>, respecting <options.enforce_lite>.
+FileOptions_OptimizeMode GetOptimizeFor(const FileDescriptor* file,
+ const Options& options);
+
+// Determines whether unknown fields will be stored in an UnknownFieldSet or
+// a string.
+inline bool UseUnknownFieldSet(const FileDescriptor* file,
+ const Options& options) {
+ return GetOptimizeFor(file, options) != FileOptions::LITE_RUNTIME;
+}
+
+inline bool IsWeak(const FieldDescriptor* field, const Options& options) {
+ if (field->options().weak()) {
+ GOOGLE_CHECK(!options.opensource_runtime);
+ return true;
+ }
+ return false;
+}
+
+bool IsStringInlined(const FieldDescriptor* descriptor, const Options& options);
+
+// For a string field, returns the effective ctype. If the actual ctype is
+// not supported, returns the default of STRING.
+FieldOptions::CType EffectiveStringCType(const FieldDescriptor* field,
+ const Options& options);
+
+inline bool IsCord(const FieldDescriptor* field, const Options& options) {
+ return field->cpp_type() == FieldDescriptor::CPPTYPE_STRING &&
+ EffectiveStringCType(field, options) == FieldOptions::CORD;
+}
+
+inline bool IsString(const FieldDescriptor* field, const Options& options) {
+ return field->cpp_type() == FieldDescriptor::CPPTYPE_STRING &&
+ EffectiveStringCType(field, options) == FieldOptions::STRING;
+}
+
+inline bool IsStringPiece(const FieldDescriptor* field,
+ const Options& options) {
+ return field->cpp_type() == FieldDescriptor::CPPTYPE_STRING &&
+ EffectiveStringCType(field, options) == FieldOptions::STRING_PIECE;
+}
+
+class MessageSCCAnalyzer;
+
+// Does the given FileDescriptor use lazy fields?
+bool HasLazyFields(const FileDescriptor* file, const Options& options,
+ MessageSCCAnalyzer* scc_analyzer);
+
+// Is the given field a supported lazy field?
+bool IsLazy(const FieldDescriptor* field, const Options& options,
+ MessageSCCAnalyzer* scc_analyzer);
+
+inline bool IsLazilyVerifiedLazy(const FieldDescriptor* field,
+ const Options& options) {
+ return field->options().lazy() && !field->is_repeated() &&
+ field->type() == FieldDescriptor::TYPE_MESSAGE &&
+ GetOptimizeFor(field->file(), options) != FileOptions::LITE_RUNTIME &&
+ !options.opensource_runtime;
+}
+
+inline bool IsEagerlyVerifiedLazy(const FieldDescriptor* field,
+ const Options& options,
+ MessageSCCAnalyzer* scc_analyzer) {
+ return IsLazy(field, options, scc_analyzer) && !field->options().lazy();
+}
+
+inline bool IsFieldUsed(const FieldDescriptor* /* field */,
+ const Options& /* options */) {
+ return true;
+}
+
+// Returns true if "field" is stripped.
+inline bool IsFieldStripped(const FieldDescriptor* /*field*/,
+ const Options& /*options*/) {
+ return false;
+}
+
+// Does the file contain any definitions that need extension_set.h?
+bool HasExtensionsOrExtendableMessage(const FileDescriptor* file);
+
+// Does the file have any repeated fields, necessitating the file to include
+// repeated_field.h? This does not include repeated extensions, since those are
+// all stored internally in an ExtensionSet, not a separate RepeatedField*.
+bool HasRepeatedFields(const FileDescriptor* file);
+
+// Does the file have any string/bytes fields with ctype=STRING_PIECE? This
+// does not include extensions, since ctype is ignored for extensions.
+bool HasStringPieceFields(const FileDescriptor* file, const Options& options);
+
+// Does the file have any string/bytes fields with ctype=CORD? This does not
+// include extensions, since ctype is ignored for extensions.
+bool HasCordFields(const FileDescriptor* file, const Options& options);
+
+// Does the file have any map fields, necessitating the file to include
+// map_field_inl.h and map.h.
+bool HasMapFields(const FileDescriptor* file);
+
+// Does this file have any enum type definitions?
+bool HasEnumDefinitions(const FileDescriptor* file);
+
+// Does this file have generated parsing, serialization, and other
+// standard methods for which reflection-based fallback implementations exist?
+inline bool HasGeneratedMethods(const FileDescriptor* file,
+ const Options& options) {
+ return GetOptimizeFor(file, options) != FileOptions::CODE_SIZE;
+}
+
+// Do message classes in this file have descriptor and reflection methods?
+inline bool HasDescriptorMethods(const FileDescriptor* file,
+ const Options& options) {
+ return GetOptimizeFor(file, options) != FileOptions::LITE_RUNTIME;
+}
+
+// Should we generate generic services for this file?
+inline bool HasGenericServices(const FileDescriptor* file,
+ const Options& options) {
+ return file->service_count() > 0 &&
+ GetOptimizeFor(file, options) != FileOptions::LITE_RUNTIME &&
+ file->options().cc_generic_services();
+}
+
+inline bool IsProto2MessageSet(const Descriptor* descriptor,
+ const Options& options) {
+ return !options.opensource_runtime &&
+ options.enforce_mode != EnforceOptimizeMode::kLiteRuntime &&
+ !options.lite_implicit_weak_fields &&
+ descriptor->options().message_set_wire_format() &&
+ descriptor->full_name() == "google.protobuf.bridge.MessageSet";
+}
+
+inline bool IsMapEntryMessage(const Descriptor* descriptor) {
+ return descriptor->options().map_entry();
+}
+
+// Returns true if the field's CPPTYPE is string or message.
+bool IsStringOrMessage(const FieldDescriptor* field);
+
+std::string UnderscoresToCamelCase(const std::string& input,
+ bool cap_next_letter);
+
+inline bool IsProto3(const FileDescriptor* file) {
+ return file->syntax() == FileDescriptor::SYNTAX_PROTO3;
+}
+
+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();
+}
+
+// Returns true if 'enum' semantics are such that unknown values are preserved
+// in the enum field itself, rather than going to the UnknownFieldSet.
+inline bool HasPreservingUnknownEnumSemantics(const FieldDescriptor* field) {
+ return field->file()->syntax() == FileDescriptor::SYNTAX_PROTO3;
+}
+
+inline bool IsCrossFileMessage(const FieldDescriptor* field) {
+ return field->type() == FieldDescriptor::TYPE_MESSAGE &&
+ field->message_type()->file() != field->file();
+}
+
+inline std::string MakeDefaultName(const FieldDescriptor* field) {
+ return "_i_give_permission_to_break_this_code_default_" + FieldName(field) +
+ "_";
+}
+
+bool IsAnyMessage(const FileDescriptor* descriptor, const Options& options);
+bool IsAnyMessage(const Descriptor* descriptor, const Options& options);
+
+bool IsWellKnownMessage(const FileDescriptor* descriptor);
+
+inline std::string IncludeGuard(const FileDescriptor* file, bool pb_h,
+ const Options& options) {
+ // If we are generating a .pb.h file and the proto_h option is enabled, then
+ // the .pb.h gets an extra suffix.
+ std::string filename_identifier = FilenameIdentifier(
+ file->name() + (pb_h && options.proto_h ? ".pb.h" : ""));
+
+ if (IsWellKnownMessage(file)) {
+ // For well-known messages we need third_party/protobuf and net/proto2 to
+ // have distinct include guards, because some source files include both and
+ // both need to be defined (the third_party copies will be in the
+ // google::protobuf_opensource namespace).
+ return MacroPrefix(options) + "_INCLUDED_" + filename_identifier;
+ } else {
+ // Ideally this case would use distinct include guards for opensource and
+ // google3 protos also. (The behavior of "first #included wins" is not
+ // ideal). But unfortunately some legacy code includes both and depends on
+ // the identical include guards to avoid compile errors.
+ //
+ // We should clean this up so that this case can be removed.
+ return "GOOGLE_PROTOBUF_INCLUDED_" + filename_identifier;
+ }
+}
+
+// Returns the OptimizeMode for this file, furthermore it updates a status
+// bool if has_opt_codesize_extension is non-null. If this status bool is true
+// it means this file contains an extension that itself is defined as
+// optimized_for = CODE_SIZE.
+FileOptions_OptimizeMode GetOptimizeFor(const FileDescriptor* file,
+ const Options& options,
+ bool* has_opt_codesize_extension);
+inline FileOptions_OptimizeMode GetOptimizeFor(const FileDescriptor* file,
+ const Options& options) {
+ return GetOptimizeFor(file, options, nullptr);
+}
+inline bool NeedsEagerDescriptorAssignment(const FileDescriptor* file,
+ const Options& options) {
+ bool has_opt_codesize_extension;
+ if (GetOptimizeFor(file, options, &has_opt_codesize_extension) ==
+ FileOptions::CODE_SIZE &&
+ has_opt_codesize_extension) {
+ // If this filedescriptor contains an extension from another file which
+ // is optimized_for = CODE_SIZE. We need to be careful in the ordering so
+ // we eagerly build the descriptors in the dependencies before building
+ // the descriptors of this file.
+ return true;
+ } else {
+ // If we have a generated code based parser we never need eager
+ // initialization of descriptors of our deps.
+ return false;
+ }
+}
+
+// This orders the messages in a .pb.cc as it's outputted by file.cc
+void FlattenMessagesInFile(const FileDescriptor* file,
+ std::vector<const Descriptor*>* result);
+inline std::vector<const Descriptor*> FlattenMessagesInFile(
+ const FileDescriptor* file) {
+ std::vector<const Descriptor*> result;
+ FlattenMessagesInFile(file, &result);
+ return result;
+}
+
+template <typename F>
+void ForEachMessage(const Descriptor* descriptor, F&& func) {
+ for (int i = 0; i < descriptor->nested_type_count(); i++)
+ ForEachMessage(descriptor->nested_type(i), std::forward<F&&>(func));
+ func(descriptor);
+}
+
+template <typename F>
+void ForEachMessage(const FileDescriptor* descriptor, F&& func) {
+ for (int i = 0; i < descriptor->message_type_count(); i++)
+ ForEachMessage(descriptor->message_type(i), std::forward<F&&>(func));
+}
+
+bool HasWeakFields(const Descriptor* desc, const Options& options);
+bool HasWeakFields(const FileDescriptor* desc, const Options& options);
+
+// Returns true if the "required" restriction check should be ignored for the
+// given field.
+inline static bool ShouldIgnoreRequiredFieldCheck(const FieldDescriptor* field,
+ const Options& options) {
+ // Do not check "required" for lazily verified lazy fields.
+ return IsLazilyVerifiedLazy(field, options);
+}
+
+struct MessageAnalysis {
+ bool is_recursive = false;
+ bool contains_cord = false;
+ bool contains_extension = false;
+ bool contains_required = false;
+ bool contains_weak = false; // Implicit weak as well.
+};
+
+// This class is used in FileGenerator, to ensure linear instead of
+// quadratic performance, if we do this per message we would get O(V*(V+E)).
+// Logically this is just only used in message.cc, but in the header for
+// FileGenerator to help share it.
+class PROTOC_EXPORT MessageSCCAnalyzer {
+ public:
+ explicit MessageSCCAnalyzer(const Options& options) : options_(options) {}
+
+ MessageAnalysis GetSCCAnalysis(const SCC* scc);
+
+ bool HasRequiredFields(const Descriptor* descriptor) {
+ MessageAnalysis result = GetSCCAnalysis(GetSCC(descriptor));
+ return result.contains_required || result.contains_extension;
+ }
+ bool HasWeakField(const Descriptor* descriptor) {
+ MessageAnalysis result = GetSCCAnalysis(GetSCC(descriptor));
+ return result.contains_weak;
+ }
+ const SCC* GetSCC(const Descriptor* descriptor) {
+ return analyzer_.GetSCC(descriptor);
+ }
+
+ private:
+ struct DepsGenerator {
+ std::vector<const Descriptor*> operator()(const Descriptor* desc) const {
+ std::vector<const Descriptor*> deps;
+ for (int i = 0; i < desc->field_count(); i++) {
+ if (desc->field(i)->message_type()) {
+ deps.push_back(desc->field(i)->message_type());
+ }
+ }
+ return deps;
+ }
+ };
+ SCCAnalyzer<DepsGenerator> analyzer_;
+ Options options_;
+ std::map<const SCC*, MessageAnalysis> analysis_cache_;
+};
+
+void ListAllFields(const Descriptor* d,
+ std::vector<const FieldDescriptor*>* fields);
+void ListAllFields(const FileDescriptor* d,
+ std::vector<const FieldDescriptor*>* fields);
+
+template <class T>
+void ForEachField(const Descriptor* d, T&& func) {
+ for (int i = 0; i < d->nested_type_count(); i++) {
+ ForEachField(d->nested_type(i), std::forward<T&&>(func));
+ }
+ for (int i = 0; i < d->extension_count(); i++) {
+ func(d->extension(i));
+ }
+ for (int i = 0; i < d->field_count(); i++) {
+ func(d->field(i));
+ }
+}
+
+template <class T>
+void ForEachField(const FileDescriptor* d, T&& func) {
+ for (int i = 0; i < d->message_type_count(); i++) {
+ ForEachField(d->message_type(i), std::forward<T&&>(func));
+ }
+ for (int i = 0; i < d->extension_count(); i++) {
+ func(d->extension(i));
+ }
+}
+
+void ListAllTypesForServices(const FileDescriptor* fd,
+ std::vector<const Descriptor*>* types);
+
+// Indicates whether we should use implicit weak fields for this file.
+bool UsingImplicitWeakFields(const FileDescriptor* file,
+ const Options& options);
+
+// Indicates whether to treat this field as implicitly weak.
+bool IsImplicitWeakField(const FieldDescriptor* field, const Options& options,
+ MessageSCCAnalyzer* scc_analyzer);
+
+inline bool HasSimpleBaseClass(const Descriptor* desc, const Options& options) {
+ if (!HasDescriptorMethods(desc->file(), options)) return false;
+ if (desc->extension_range_count() != 0) return false;
+ if (desc->field_count() == 0) return true;
+ // TODO(jorg): Support additional common message types with only one
+ // or two fields
+ return false;
+}
+
+inline bool HasSimpleBaseClasses(const FileDescriptor* file,
+ const Options& options) {
+ bool v = false;
+ ForEachMessage(file, [&v, &options](const Descriptor* desc) {
+ v |= HasSimpleBaseClass(desc, options);
+ });
+ return v;
+}
+
+inline std::string SimpleBaseClass(const Descriptor* desc,
+ const Options& options) {
+ if (!HasDescriptorMethods(desc->file(), options)) return "";
+ if (desc->extension_range_count() != 0) return "";
+ if (desc->field_count() == 0) {
+ return "ZeroFieldsBase";
+ }
+ // TODO(jorg): Support additional common message types with only one
+ // or two fields
+ return "";
+}
+
+// Formatter is a functor class which acts as a closure around printer and
+// the variable map. It's much like printer->Print except it supports both named
+// variables that are substituted using a key value map and direct arguments. In
+// the format string $1$, $2$, etc... are substituted for the first, second, ...
+// direct argument respectively in the format call, it accepts both strings and
+// integers. The implementation verifies all arguments are used and are "first"
+// used in order of appearance in the argument list. For example,
+//
+// Format("return array[$1$];", 3) -> "return array[3];"
+// Format("array[$2$] = $1$;", "Bla", 3) -> FATAL error (wrong order)
+// Format("array[$1$] = $2$;", 3, "Bla") -> "array[3] = Bla;"
+//
+// The arguments can be used more than once like
+//
+// Format("array[$1$] = $2$; // Index = $1$", 3, "Bla") ->
+// "array[3] = Bla; // Index = 3"
+//
+// If you use more arguments use the following style to help the reader,
+//
+// Format("int $1$() {\n"
+// " array[$2$] = $3$;\n"
+// " return $4$;"
+// "}\n",
+// funname, // 1
+// idx, // 2
+// varname, // 3
+// retval); // 4
+//
+// but consider using named variables. Named variables like $foo$, with some
+// identifier foo, are looked up in the map. One additional feature is that
+// spaces are accepted between the '$' delimiters, $ foo$ will
+// substiture to " bar" if foo stands for "bar", but in case it's empty
+// will substitute to "". Hence, for example,
+//
+// Format(vars, "$dllexport $void fun();") -> "void fun();"
+// "__declspec(export) void fun();"
+//
+// which is convenient to prevent double, leading or trailing spaces.
+class PROTOC_EXPORT Formatter {
+ public:
+ explicit Formatter(io::Printer* printer) : printer_(printer) {}
+ Formatter(io::Printer* printer,
+ const std::map<std::string, std::string>& vars)
+ : printer_(printer), vars_(vars) {}
+
+ template <typename T>
+ void Set(const std::string& key, const T& value) {
+ vars_[key] = ToString(value);
+ }
+
+ void AddMap(const std::map<std::string, std::string>& vars) {
+ for (const auto& keyval : vars) vars_[keyval.first] = keyval.second;
+ }
+
+ template <typename... Args>
+ void operator()(const char* format, const Args&... args) const {
+ printer_->FormatInternal({ToString(args)...}, vars_, format);
+ }
+
+ void Indent() const { printer_->Indent(); }
+ void Outdent() const { printer_->Outdent(); }
+ io::Printer* printer() const { return printer_; }
+
+ class PROTOC_EXPORT ScopedIndenter {
+ public:
+ explicit ScopedIndenter(Formatter* format) : format_(format) {
+ format_->Indent();
+ }
+ ~ScopedIndenter() { format_->Outdent(); }
+
+ private:
+ Formatter* format_;
+ };
+
+ PROTOBUF_NODISCARD ScopedIndenter ScopedIndent() {
+ return ScopedIndenter(this);
+ }
+ template <typename... Args>
+ PROTOBUF_NODISCARD ScopedIndenter ScopedIndent(const char* format,
+ const Args&&... args) {
+ (*this)(format, static_cast<Args&&>(args)...);
+ return ScopedIndenter(this);
+ }
+
+ class PROTOC_EXPORT SaveState {
+ public:
+ explicit SaveState(Formatter* format)
+ : format_(format), vars_(format->vars_) {}
+ ~SaveState() { format_->vars_.swap(vars_); }
+
+ private:
+ Formatter* format_;
+ std::map<std::string, std::string> vars_;
+ };
+
+ private:
+ io::Printer* printer_;
+ std::map<std::string, std::string> vars_;
+
+ // Convenience overloads to accept different types as arguments.
+ static std::string ToString(const std::string& s) { return s; }
+ template <typename I, typename = typename std::enable_if<
+ std::is_integral<I>::value>::type>
+ static std::string ToString(I x) {
+ return StrCat(x);
+ }
+ static std::string ToString(strings::Hex x) { return StrCat(x); }
+ static std::string ToString(const FieldDescriptor* d) { return Payload(d); }
+ static std::string ToString(const Descriptor* d) { return Payload(d); }
+ static std::string ToString(const EnumDescriptor* d) { return Payload(d); }
+ static std::string ToString(const EnumValueDescriptor* d) {
+ return Payload(d);
+ }
+ static std::string ToString(const OneofDescriptor* d) { return Payload(d); }
+
+ template <typename Descriptor>
+ static std::string Payload(const Descriptor* descriptor) {
+ std::vector<int> path;
+ descriptor->GetLocationPath(&path);
+ GeneratedCodeInfo::Annotation annotation;
+ for (int index : path) {
+ annotation.add_path(index);
+ }
+ annotation.set_source_file(descriptor->file()->name());
+ return annotation.SerializeAsString();
+ }
+};
+
+template <class T>
+void PrintFieldComment(const Formatter& format, const T* field) {
+ // Print the field's (or oneof's) proto-syntax definition as a comment.
+ // We don't want to print group bodies so we cut off after the first
+ // line.
+ DebugStringOptions options;
+ options.elide_group_body = true;
+ options.elide_oneof_body = true;
+ std::string def = field->DebugStringWithOptions(options);
+ format("// $1$\n", def.substr(0, def.find_first_of('\n')));
+}
+
+class PROTOC_EXPORT NamespaceOpener {
+ public:
+ explicit NamespaceOpener(const Formatter& format)
+ : printer_(format.printer()) {}
+ NamespaceOpener(const std::string& name, const Formatter& format)
+ : NamespaceOpener(format) {
+ ChangeTo(name);
+ }
+ ~NamespaceOpener() { ChangeTo(""); }
+
+ void ChangeTo(const std::string& name) {
+ std::vector<std::string> new_stack_ =
+ Split(name, "::", true);
+ size_t len = std::min(name_stack_.size(), new_stack_.size());
+ size_t common_idx = 0;
+ while (common_idx < len) {
+ if (name_stack_[common_idx] != new_stack_[common_idx]) break;
+ common_idx++;
+ }
+ for (auto it = name_stack_.crbegin();
+ it != name_stack_.crend() - common_idx; ++it) {
+ if (*it == "PROTOBUF_NAMESPACE_ID") {
+ printer_->Print("PROTOBUF_NAMESPACE_CLOSE\n");
+ } else {
+ printer_->Print("} // namespace $ns$\n", "ns", *it);
+ }
+ }
+ name_stack_.swap(new_stack_);
+ for (size_t i = common_idx; i < name_stack_.size(); ++i) {
+ if (name_stack_[i] == "PROTOBUF_NAMESPACE_ID") {
+ printer_->Print("PROTOBUF_NAMESPACE_OPEN\n");
+ } else {
+ printer_->Print("namespace $ns$ {\n", "ns", name_stack_[i]);
+ }
+ }
+ }
+
+ private:
+ io::Printer* printer_;
+ std::vector<std::string> name_stack_;
+};
+
+enum class Utf8CheckMode {
+ kStrict = 0, // Parsing will fail if non UTF-8 data is in string fields.
+ kVerify = 1, // Only log an error but parsing will succeed.
+ kNone = 2, // No UTF-8 check.
+};
+
+Utf8CheckMode GetUtf8CheckMode(const FieldDescriptor* field,
+ const Options& options);
+
+void GenerateUtf8CheckCodeForString(const FieldDescriptor* field,
+ const Options& options, bool for_parse,
+ const char* parameters,
+ const Formatter& format);
+
+void GenerateUtf8CheckCodeForCord(const FieldDescriptor* field,
+ const Options& options, bool for_parse,
+ const char* parameters,
+ const Formatter& format);
+
+template <typename T>
+struct FieldRangeImpl {
+ struct Iterator {
+ using iterator_category = std::forward_iterator_tag;
+ using value_type = const FieldDescriptor*;
+ using difference_type = int;
+
+ value_type operator*() { return descriptor->field(idx); }
+
+ friend bool operator==(const Iterator& a, const Iterator& b) {
+ GOOGLE_DCHECK(a.descriptor == b.descriptor);
+ return a.idx == b.idx;
+ }
+ friend bool operator!=(const Iterator& a, const Iterator& b) {
+ return !(a == b);
+ }
+
+ Iterator& operator++() {
+ idx++;
+ return *this;
+ }
+
+ int idx;
+ const T* descriptor;
+ };
+
+ Iterator begin() const { return {0, descriptor}; }
+ Iterator end() const { return {descriptor->field_count(), descriptor}; }
+
+ const T* descriptor;
+};
+
+template <typename T>
+FieldRangeImpl<T> FieldRange(const T* desc) {
+ return {desc};
+}
+
+struct OneOfRangeImpl {
+ struct Iterator {
+ using iterator_category = std::forward_iterator_tag;
+ using value_type = const OneofDescriptor*;
+ using difference_type = int;
+
+ value_type operator*() { return descriptor->oneof_decl(idx); }
+
+ friend bool operator==(const Iterator& a, const Iterator& b) {
+ GOOGLE_DCHECK(a.descriptor == b.descriptor);
+ return a.idx == b.idx;
+ }
+ friend bool operator!=(const Iterator& a, const Iterator& b) {
+ return !(a == b);
+ }
+
+ Iterator& operator++() {
+ idx++;
+ return *this;
+ }
+
+ int idx;
+ const Descriptor* descriptor;
+ };
+
+ Iterator begin() const { return {0, descriptor}; }
+ Iterator end() const {
+ return {descriptor->real_oneof_decl_count(), descriptor};
+ }
+
+ const Descriptor* descriptor;
+};
+
+inline OneOfRangeImpl OneOfRange(const Descriptor* desc) { return {desc}; }
+
+PROTOC_EXPORT std::string StripProto(const std::string& filename);
+
+bool EnableMessageOwnedArena(const Descriptor* desc);
+
+bool ShouldVerify(const Descriptor* descriptor, const Options& options,
+ MessageSCCAnalyzer* scc_analyzer);
+bool ShouldVerify(const FileDescriptor* file, const Options& options,
+ MessageSCCAnalyzer* scc_analyzer);
+} // namespace cpp
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#include <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_COMPILER_CPP_HELPERS_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_map_field.cc b/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_map_field.cc
new file mode 100644
index 00000000..3626a360
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_map_field.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.
+
+#include <compiler/cpp/cpp_map_field.h>
+
+#include <compiler/cpp/cpp_helpers.h>
+#include <io/printer.h>
+#include <wire_format.h>
+#include <stubs/strutil.h>
+
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+bool IsProto3Field(const FieldDescriptor* field_descriptor) {
+ const FileDescriptor* file_descriptor = field_descriptor->file();
+ return file_descriptor->syntax() == FileDescriptor::SYNTAX_PROTO3;
+}
+
+void SetMessageVariables(const FieldDescriptor* descriptor,
+ std::map<std::string, std::string>* variables,
+ const Options& options) {
+ SetCommonFieldVariables(descriptor, variables, options);
+ (*variables)["type"] = ClassName(descriptor->message_type(), false);
+ (*variables)["full_name"] = descriptor->full_name();
+
+ const FieldDescriptor* key =
+ descriptor->message_type()->FindFieldByName("key");
+ const FieldDescriptor* val =
+ descriptor->message_type()->FindFieldByName("value");
+ (*variables)["key_cpp"] = PrimitiveTypeName(options, key->cpp_type());
+ switch (val->cpp_type()) {
+ case FieldDescriptor::CPPTYPE_MESSAGE:
+ (*variables)["val_cpp"] = FieldMessageTypeName(val, options);
+ break;
+ case FieldDescriptor::CPPTYPE_ENUM:
+ (*variables)["val_cpp"] = ClassName(val->enum_type(), true);
+ break;
+ default:
+ (*variables)["val_cpp"] = PrimitiveTypeName(options, val->cpp_type());
+ }
+ (*variables)["key_wire_type"] =
+ "TYPE_" + ToUpper(DeclaredTypeMethodName(key->type()));
+ (*variables)["val_wire_type"] =
+ "TYPE_" + ToUpper(DeclaredTypeMethodName(val->type()));
+ (*variables)["map_classname"] = ClassName(descriptor->message_type(), false);
+ (*variables)["number"] = StrCat(descriptor->number());
+ (*variables)["tag"] = StrCat(internal::WireFormat::MakeTag(descriptor));
+
+ if (HasDescriptorMethods(descriptor->file(), options)) {
+ (*variables)["lite"] = "";
+ } else {
+ (*variables)["lite"] = "Lite";
+ }
+}
+
+MapFieldGenerator::MapFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options,
+ MessageSCCAnalyzer* scc_analyzer)
+ : FieldGenerator(descriptor, options),
+ has_required_fields_(
+ scc_analyzer->HasRequiredFields(descriptor->message_type())) {
+ SetMessageVariables(descriptor, &variables_, options);
+}
+
+MapFieldGenerator::~MapFieldGenerator() {}
+
+void MapFieldGenerator::GeneratePrivateMembers(io::Printer* printer) const {
+ Formatter format(printer, variables_);
+ format(
+ "::$proto_ns$::internal::MapField$lite$<\n"
+ " $map_classname$,\n"
+ " $key_cpp$, $val_cpp$,\n"
+ " ::$proto_ns$::internal::WireFormatLite::$key_wire_type$,\n"
+ " ::$proto_ns$::internal::WireFormatLite::$val_wire_type$> "
+ "$name$_;\n");
+}
+
+void MapFieldGenerator::GenerateAccessorDeclarations(
+ io::Printer* printer) const {
+ Formatter format(printer, variables_);
+ format(
+ "private:\n"
+ "const ::$proto_ns$::Map< $key_cpp$, $val_cpp$ >&\n"
+ " ${1$_internal_$name$$}$() const;\n"
+ "::$proto_ns$::Map< $key_cpp$, $val_cpp$ >*\n"
+ " ${1$_internal_mutable_$name$$}$();\n"
+ "public:\n"
+ "$deprecated_attr$const ::$proto_ns$::Map< $key_cpp$, $val_cpp$ >&\n"
+ " ${1$$name$$}$() const;\n"
+ "$deprecated_attr$::$proto_ns$::Map< $key_cpp$, $val_cpp$ >*\n"
+ " ${1$mutable_$name$$}$();\n",
+ descriptor_);
+}
+
+void MapFieldGenerator::GenerateInlineAccessorDefinitions(
+ io::Printer* printer) const {
+ Formatter format(printer, variables_);
+ format(
+ "inline const ::$proto_ns$::Map< $key_cpp$, $val_cpp$ >&\n"
+ "$classname$::_internal_$name$() const {\n"
+ " return $name$_.GetMap();\n"
+ "}\n"
+ "inline const ::$proto_ns$::Map< $key_cpp$, $val_cpp$ >&\n"
+ "$classname$::$name$() const {\n"
+ "$annotate_get$"
+ " // @@protoc_insertion_point(field_map:$full_name$)\n"
+ " return _internal_$name$();\n"
+ "}\n"
+ "inline ::$proto_ns$::Map< $key_cpp$, $val_cpp$ >*\n"
+ "$classname$::_internal_mutable_$name$() {\n"
+ " return $name$_.MutableMap();\n"
+ "}\n"
+ "inline ::$proto_ns$::Map< $key_cpp$, $val_cpp$ >*\n"
+ "$classname$::mutable_$name$() {\n"
+ "$annotate_mutable$"
+ " // @@protoc_insertion_point(field_mutable_map:$full_name$)\n"
+ " return _internal_mutable_$name$();\n"
+ "}\n");
+}
+
+void MapFieldGenerator::GenerateClearingCode(io::Printer* printer) const {
+ Formatter format(printer, variables_);
+ format("$name$_.Clear();\n");
+}
+
+void MapFieldGenerator::GenerateMergingCode(io::Printer* printer) const {
+ Formatter format(printer, variables_);
+ format("$name$_.MergeFrom(from.$name$_);\n");
+}
+
+void MapFieldGenerator::GenerateSwappingCode(io::Printer* printer) const {
+ Formatter format(printer, variables_);
+ format("$name$_.InternalSwap(&other->$name$_);\n");
+}
+
+void MapFieldGenerator::GenerateCopyConstructorCode(
+ io::Printer* printer) const {
+ GenerateConstructorCode(printer);
+ GenerateMergingCode(printer);
+}
+
+static void GenerateSerializationLoop(const Formatter& format, bool string_key,
+ bool string_value,
+ bool is_deterministic) {
+ std::string ptr;
+ if (is_deterministic) {
+ format("for (size_type i = 0; i < n; i++) {\n");
+ ptr = string_key ? "items[static_cast<ptrdiff_t>(i)]"
+ : "items[static_cast<ptrdiff_t>(i)].second";
+ } else {
+ format(
+ "for (::$proto_ns$::Map< $key_cpp$, $val_cpp$ >::const_iterator\n"
+ " it = this->_internal_$name$().begin();\n"
+ " it != this->_internal_$name$().end(); ++it) {\n");
+ ptr = "it";
+ }
+ format.Indent();
+
+ format(
+ "target = $map_classname$::Funcs::InternalSerialize($number$, "
+ "$1$->first, $1$->second, target, stream);\n",
+ ptr);
+
+ if (string_key || string_value) {
+ // ptr is either an actual pointer or an iterator, either way we can
+ // create a pointer by taking the address after de-referencing it.
+ format("Utf8Check::Check(&(*$1$));\n", ptr);
+ }
+
+ format.Outdent();
+ format("}\n");
+}
+
+void MapFieldGenerator::GenerateSerializeWithCachedSizesToArray(
+ io::Printer* printer) const {
+ Formatter format(printer, variables_);
+ format("if (!this->_internal_$name$().empty()) {\n");
+ format.Indent();
+ const FieldDescriptor* key_field =
+ descriptor_->message_type()->FindFieldByName("key");
+ const FieldDescriptor* value_field =
+ descriptor_->message_type()->FindFieldByName("value");
+ const bool string_key = key_field->type() == FieldDescriptor::TYPE_STRING;
+ const bool string_value = value_field->type() == FieldDescriptor::TYPE_STRING;
+
+ format(
+ "typedef ::$proto_ns$::Map< $key_cpp$, $val_cpp$ >::const_pointer\n"
+ " ConstPtr;\n");
+ if (string_key) {
+ format(
+ "typedef ConstPtr SortItem;\n"
+ "typedef ::$proto_ns$::internal::"
+ "CompareByDerefFirst<SortItem> Less;\n");
+ } else {
+ format(
+ "typedef ::$proto_ns$::internal::SortItem< $key_cpp$, ConstPtr > "
+ "SortItem;\n"
+ "typedef ::$proto_ns$::internal::CompareByFirstField<SortItem> "
+ "Less;\n");
+ }
+ bool utf8_check = string_key || string_value;
+ if (utf8_check) {
+ format(
+ "struct Utf8Check {\n"
+ " static void Check(ConstPtr p) {\n"
+ // p may be unused when GetUtf8CheckMode evaluates to kNone,
+ // thus disabling the validation.
+ " (void)p;\n");
+ format.Indent();
+ format.Indent();
+ if (string_key) {
+ GenerateUtf8CheckCodeForString(
+ key_field, options_, false,
+ "p->first.data(), static_cast<int>(p->first.length()),\n", format);
+ }
+ if (string_value) {
+ GenerateUtf8CheckCodeForString(
+ value_field, options_, false,
+ "p->second.data(), static_cast<int>(p->second.length()),\n", format);
+ }
+ format.Outdent();
+ format.Outdent();
+ format(
+ " }\n"
+ "};\n");
+ }
+
+ format(
+ "\n"
+ "if (stream->IsSerializationDeterministic() &&\n"
+ " this->_internal_$name$().size() > 1) {\n"
+ " ::std::unique_ptr<SortItem[]> items(\n"
+ " new SortItem[this->_internal_$name$().size()]);\n"
+ " typedef ::$proto_ns$::Map< $key_cpp$, $val_cpp$ >::size_type "
+ "size_type;\n"
+ " size_type n = 0;\n"
+ " for (::$proto_ns$::Map< $key_cpp$, $val_cpp$ >::const_iterator\n"
+ " it = this->_internal_$name$().begin();\n"
+ " it != this->_internal_$name$().end(); ++it, ++n) {\n"
+ " items[static_cast<ptrdiff_t>(n)] = SortItem(&*it);\n"
+ " }\n"
+ " ::std::sort(&items[0], &items[static_cast<ptrdiff_t>(n)], Less());\n");
+ format.Indent();
+ GenerateSerializationLoop(format, string_key, string_value, true);
+ format.Outdent();
+ format("} else {\n");
+ format.Indent();
+ GenerateSerializationLoop(format, string_key, string_value, false);
+ format.Outdent();
+ format("}\n");
+ format.Outdent();
+ format("}\n");
+}
+
+void MapFieldGenerator::GenerateByteSize(io::Printer* printer) const {
+ Formatter format(printer, variables_);
+ format(
+ "total_size += $tag_size$ *\n"
+ " "
+ "::$proto_ns$::internal::FromIntSize(this->_internal_$name$_size());\n"
+ "for (::$proto_ns$::Map< $key_cpp$, $val_cpp$ >::const_iterator\n"
+ " it = this->_internal_$name$().begin();\n"
+ " it != this->_internal_$name$().end(); ++it) {\n"
+ " total_size += $map_classname$::Funcs::ByteSizeLong(it->first, "
+ "it->second);\n"
+ "}\n");
+}
+
+void MapFieldGenerator::GenerateIsInitialized(io::Printer* printer) const {
+ if (!has_required_fields_) return;
+
+ Formatter format(printer, variables_);
+ format(
+ "if (!::$proto_ns$::internal::AllAreInitialized($name$_)) return "
+ "false;\n");
+}
+
+void MapFieldGenerator::GenerateConstinitInitializer(
+ io::Printer* printer) const {
+ Formatter format(printer, variables_);
+ if (HasDescriptorMethods(descriptor_->file(), options_)) {
+ format("$name$_(::$proto_ns$::internal::ConstantInitialized{})");
+ } else {
+ format("$name$_()");
+ }
+}
+
+bool MapFieldGenerator::GenerateArenaDestructorCode(
+ io::Printer* printer) const {
+ Formatter format(printer, variables_);
+ if (HasDescriptorMethods(descriptor_->file(), options_)) {
+ // _this is the object being destructed (we are inside a static method
+ // here).
+ format("_this->$name$_. ~MapField();\n");
+ return true;
+ } else {
+ return false;
+ }
+}
+
+} // namespace cpp
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_map_field.h b/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_map_field.h
new file mode 100644
index 00000000..8287e536
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_map_field.h
@@ -0,0 +1,78 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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_COMPILER_CPP_MAP_FIELD_H__
+#define GOOGLE_PROTOBUF_COMPILER_CPP_MAP_FIELD_H__
+
+#include <map>
+#include <string>
+
+#include <compiler/cpp/cpp_helpers.h>
+#include <compiler/cpp/cpp_message_field.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+class MapFieldGenerator : public FieldGenerator {
+ public:
+ MapFieldGenerator(const FieldDescriptor* descriptor, const Options& options,
+ MessageSCCAnalyzer* scc_analyzer);
+ ~MapFieldGenerator() override;
+
+ // implements FieldGenerator ---------------------------------------
+ void GeneratePrivateMembers(io::Printer* printer) const override;
+ void GenerateAccessorDeclarations(io::Printer* printer) const override;
+ void GenerateInlineAccessorDefinitions(io::Printer* printer) const override;
+ void GenerateClearingCode(io::Printer* printer) const override;
+ void GenerateMergingCode(io::Printer* printer) const override;
+ void GenerateSwappingCode(io::Printer* printer) const override;
+ void GenerateConstructorCode(io::Printer* printer) const override {}
+ void GenerateCopyConstructorCode(io::Printer* printer) const override;
+ void GenerateSerializeWithCachedSizesToArray(
+ io::Printer* printer) const override;
+ void GenerateByteSize(io::Printer* printer) const override;
+ void GenerateIsInitialized(io::Printer* printer) const override;
+ void GenerateConstinitInitializer(io::Printer* printer) const override;
+ bool GenerateArenaDestructorCode(io::Printer* printer) const override;
+
+ private:
+ const bool has_required_fields_;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MapFieldGenerator);
+};
+
+} // namespace cpp
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_COMPILER_CPP_MAP_FIELD_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_message.cc b/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_message.cc
new file mode 100644
index 00000000..b541017f
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_message.cc
@@ -0,0 +1,4584 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 <compiler/cpp/cpp_message.h>
+
+#include <algorithm>
+#include <cstdint>
+#include <functional>
+#include <map>
+#include <memory>
+#include <unordered_map>
+#include <utility>
+#include <vector>
+
+#include <stubs/common.h>
+#include <compiler/cpp/cpp_enum.h>
+#include <compiler/cpp/cpp_extension.h>
+#include <compiler/cpp/cpp_field.h>
+#include <compiler/cpp/cpp_helpers.h>
+#include <compiler/cpp/cpp_padding_optimizer.h>
+#include <compiler/cpp/cpp_parse_function_generator.h>
+#include <descriptor.pb.h>
+#include <io/coded_stream.h>
+#include <io/printer.h>
+#include <descriptor.h>
+#include <generated_message_table_driven.h>
+#include <generated_message_util.h>
+#include <map_entry_lite.h>
+#include <wire_format.h>
+#include <stubs/strutil.h>
+#include <stubs/substitute.h>
+#include <stubs/hash.h>
+
+
+// Must be included last.
+#include <port_def.inc>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+using internal::WireFormat;
+using internal::WireFormatLite;
+
+namespace {
+
+static constexpr int kNoHasbit = -1;
+
+// Create an expression that evaluates to
+// "for all i, (_has_bits_[i] & masks[i]) == masks[i]"
+// masks is allowed to be shorter than _has_bits_, but at least one element of
+// masks must be non-zero.
+std::string ConditionalToCheckBitmasks(
+ const std::vector<uint32_t>& masks, bool return_success = true,
+ StringPiece has_bits_var = "_has_bits_") {
+ std::vector<std::string> parts;
+ for (int i = 0; i < masks.size(); i++) {
+ if (masks[i] == 0) continue;
+ std::string m = StrCat("0x", strings::Hex(masks[i], strings::ZERO_PAD_8));
+ // Each xor evaluates to 0 if the expected bits are present.
+ parts.push_back(
+ StrCat("((", has_bits_var, "[", i, "] & ", m, ") ^ ", m, ")"));
+ }
+ GOOGLE_CHECK(!parts.empty());
+ // If we have multiple parts, each expected to be 0, then bitwise-or them.
+ std::string result =
+ parts.size() == 1
+ ? parts[0]
+ : StrCat("(", Join(parts, "\n | "), ")");
+ return result + (return_success ? " == 0" : " != 0");
+}
+
+void PrintPresenceCheck(const Formatter& format, const FieldDescriptor* field,
+ const std::vector<int>& has_bit_indices,
+ io::Printer* printer, int* cached_has_word_index) {
+ if (!field->options().weak()) {
+ int has_bit_index = has_bit_indices[field->index()];
+ if (*cached_has_word_index != (has_bit_index / 32)) {
+ *cached_has_word_index = (has_bit_index / 32);
+ format("cached_has_bits = _has_bits_[$1$];\n", *cached_has_word_index);
+ }
+ const std::string mask =
+ StrCat(strings::Hex(1u << (has_bit_index % 32), strings::ZERO_PAD_8));
+ format("if (cached_has_bits & 0x$1$u) {\n", mask);
+ } else {
+ format("if (has_$1$()) {\n", FieldName(field));
+ }
+ format.Indent();
+}
+
+struct FieldOrderingByNumber {
+ inline bool operator()(const FieldDescriptor* a,
+ const FieldDescriptor* b) const {
+ return a->number() < b->number();
+ }
+};
+
+// Sort the fields of the given Descriptor by number into a new[]'d array
+// and return it.
+std::vector<const FieldDescriptor*> SortFieldsByNumber(
+ const Descriptor* descriptor) {
+ std::vector<const FieldDescriptor*> fields(descriptor->field_count());
+ for (int i = 0; i < descriptor->field_count(); i++) {
+ fields[i] = descriptor->field(i);
+ }
+ std::sort(fields.begin(), fields.end(), FieldOrderingByNumber());
+ return fields;
+}
+
+// Functor for sorting extension ranges by their "start" field number.
+struct ExtensionRangeSorter {
+ bool operator()(const Descriptor::ExtensionRange* left,
+ const Descriptor::ExtensionRange* right) const {
+ return left->start < right->start;
+ }
+};
+
+bool IsPOD(const FieldDescriptor* field) {
+ if (field->is_repeated() || field->is_extension()) return false;
+ switch (field->cpp_type()) {
+ case FieldDescriptor::CPPTYPE_ENUM:
+ case FieldDescriptor::CPPTYPE_INT32:
+ case FieldDescriptor::CPPTYPE_INT64:
+ case FieldDescriptor::CPPTYPE_UINT32:
+ case FieldDescriptor::CPPTYPE_UINT64:
+ case FieldDescriptor::CPPTYPE_FLOAT:
+ case FieldDescriptor::CPPTYPE_DOUBLE:
+ case FieldDescriptor::CPPTYPE_BOOL:
+ return true;
+ case FieldDescriptor::CPPTYPE_STRING:
+ return false;
+ default:
+ return false;
+ }
+}
+
+// Helper for the code that emits the SharedCtor() and InternalSwap() methods.
+// Anything that is a POD or a "normal" message (represented by a pointer) can
+// be manipulated as raw bytes.
+bool CanBeManipulatedAsRawBytes(const FieldDescriptor* field,
+ const Options& options,
+ MessageSCCAnalyzer* scc_analyzer) {
+ bool ret = CanInitializeByZeroing(field);
+
+ // Non-repeated, non-lazy message fields are simply raw pointers, so we can
+ // swap them or use memset to initialize these in SharedCtor. We cannot use
+ // this in Clear, as we need to potentially delete the existing value.
+ ret =
+ ret || (!field->is_repeated() && !IsLazy(field, options, scc_analyzer) &&
+ field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE);
+ return ret;
+}
+
+bool StrContains(const std::string& haystack, const std::string& needle) {
+ return haystack.find(needle) != std::string::npos;
+}
+
+// Finds runs of fields for which `predicate` is true.
+// RunMap maps from fields that start each run to the number of fields in that
+// run. This is optimized for the common case that there are very few runs in
+// a message and that most of the eligible fields appear together.
+using RunMap = std::unordered_map<const FieldDescriptor*, size_t>;
+RunMap FindRuns(const std::vector<const FieldDescriptor*>& fields,
+ const std::function<bool(const FieldDescriptor*)>& predicate) {
+ RunMap runs;
+ const FieldDescriptor* last_start = nullptr;
+
+ for (auto field : fields) {
+ if (predicate(field)) {
+ if (last_start == nullptr) {
+ last_start = field;
+ }
+
+ runs[last_start]++;
+ } else {
+ last_start = nullptr;
+ }
+ }
+ return runs;
+}
+
+// Emits an if-statement with a condition that evaluates to true if |field| is
+// considered non-default (will be sent over the wire), for message types
+// without true field presence. Should only be called if
+// !HasHasbit(field).
+bool EmitFieldNonDefaultCondition(io::Printer* printer,
+ const std::string& prefix,
+ const FieldDescriptor* field) {
+ GOOGLE_CHECK(!HasHasbit(field));
+ Formatter format(printer);
+ format.Set("prefix", prefix);
+ format.Set("name", FieldName(field));
+ // Merge and serialize semantics: primitive fields are merged/serialized only
+ // if non-zero (numeric) or non-empty (string).
+ if (!field->is_repeated() && !field->containing_oneof()) {
+ if (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING) {
+ format("if (!$prefix$_internal_$name$().empty()) {\n");
+ } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+ // Message fields still have has_$name$() methods.
+ format("if ($prefix$_internal_has_$name$()) {\n");
+ } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_FLOAT) {
+ format(
+ "static_assert(sizeof(uint32_t) == sizeof(float), \"Code assumes "
+ "uint32_t and float are the same size.\");\n"
+ "float tmp_$name$ = $prefix$_internal_$name$();\n"
+ "uint32_t raw_$name$;\n"
+ "memcpy(&raw_$name$, &tmp_$name$, sizeof(tmp_$name$));\n"
+ "if (raw_$name$ != 0) {\n");
+ } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_DOUBLE) {
+ format(
+ "static_assert(sizeof(uint64_t) == sizeof(double), \"Code assumes "
+ "uint64_t and double are the same size.\");\n"
+ "double tmp_$name$ = $prefix$_internal_$name$();\n"
+ "uint64_t raw_$name$;\n"
+ "memcpy(&raw_$name$, &tmp_$name$, sizeof(tmp_$name$));\n"
+ "if (raw_$name$ != 0) {\n");
+ } else {
+ format("if ($prefix$_internal_$name$() != 0) {\n");
+ }
+ format.Indent();
+ return true;
+ } else if (field->real_containing_oneof()) {
+ format("if (_internal_has_$name$()) {\n");
+ format.Indent();
+ return true;
+ }
+ return false;
+}
+
+// Does the given field have a has_$name$() method?
+bool HasHasMethod(const FieldDescriptor* field) {
+ if (!IsProto3(field->file())) {
+ // In proto1/proto2, every field has a has_$name$() method.
+ return true;
+ }
+ // For message types without true field presence, only fields with a message
+ // type or inside an one-of have a has_$name$() method.
+ return field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE ||
+ field->has_optional_keyword() || field->real_containing_oneof();
+}
+
+// Collects map entry message type information.
+void CollectMapInfo(const Options& options, const Descriptor* descriptor,
+ std::map<std::string, std::string>* variables) {
+ GOOGLE_CHECK(IsMapEntryMessage(descriptor));
+ std::map<std::string, std::string>& vars = *variables;
+ const FieldDescriptor* key = descriptor->FindFieldByName("key");
+ const FieldDescriptor* val = descriptor->FindFieldByName("value");
+ vars["key_cpp"] = PrimitiveTypeName(options, key->cpp_type());
+ switch (val->cpp_type()) {
+ case FieldDescriptor::CPPTYPE_MESSAGE:
+ vars["val_cpp"] = FieldMessageTypeName(val, options);
+ break;
+ case FieldDescriptor::CPPTYPE_ENUM:
+ vars["val_cpp"] = ClassName(val->enum_type(), true);
+ break;
+ default:
+ vars["val_cpp"] = PrimitiveTypeName(options, val->cpp_type());
+ }
+ vars["key_wire_type"] =
+ "TYPE_" + ToUpper(DeclaredTypeMethodName(key->type()));
+ vars["val_wire_type"] =
+ "TYPE_" + ToUpper(DeclaredTypeMethodName(val->type()));
+}
+
+// Does the given field have a private (internal helper only) has_$name$()
+// method?
+bool HasPrivateHasMethod(const FieldDescriptor* field) {
+ // Only for oneofs in message types with no field presence. has_$name$(),
+ // based on the oneof case, is still useful internally for generated code.
+ return IsProto3(field->file()) && field->real_containing_oneof();
+}
+
+// TODO(ckennelly): Cull these exclusions if/when these protos do not have
+// their methods overridden by subclasses.
+
+bool ShouldMarkClassAsFinal(const Descriptor* descriptor,
+ const Options& options) {
+ return true;
+}
+
+
+// Returns true to make the message serialize in order, decided by the following
+// factors in the order of precedence.
+// --options().message_set_wire_format() == true
+// --the message is in the allowlist (true)
+// --GOOGLE_PROTOBUF_SHUFFLE_SERIALIZE is defined (false)
+// --a ranage of message names that are allowed to stay in order (true)
+bool ShouldSerializeInOrder(const Descriptor* descriptor,
+ const Options& options) {
+ return true;
+}
+
+bool TableDrivenParsingEnabled(const Descriptor* descriptor,
+ const Options& options,
+ MessageSCCAnalyzer* scc_analyzer) {
+ if (!options.table_driven_parsing) {
+ return false;
+ }
+
+ // Consider table-driven parsing. We only do this if:
+ // - We have has_bits for fields. This avoids a check on every field we set
+ // when are present (the common case).
+ bool has_hasbit = false;
+ for (int i = 0; i < descriptor->field_count(); i++) {
+ if (HasHasbit(descriptor->field(i))) {
+ has_hasbit = true;
+ break;
+ }
+ }
+
+ if (!has_hasbit) return false;
+
+ const double table_sparseness = 0.5;
+ int max_field_number = 0;
+ for (auto field : FieldRange(descriptor)) {
+ if (max_field_number < field->number()) {
+ max_field_number = field->number();
+ }
+
+ // - There are no weak fields.
+ if (IsWeak(field, options)) {
+ return false;
+ }
+
+ // - There are no lazy fields (they require the non-lite library).
+ if (IsLazy(field, options, scc_analyzer)) {
+ return false;
+ }
+ }
+
+ // - There range of field numbers is "small"
+ if (max_field_number >= (2 << 14)) {
+ return false;
+ }
+
+ // - Field numbers are relatively dense within the actual number of fields.
+ // We check for strictly greater than in the case where there are no fields
+ // (only extensions) so max_field_number == descriptor->field_count() == 0.
+ if (max_field_number * table_sparseness > descriptor->field_count()) {
+ return false;
+ }
+
+ // - This is not a MapEntryMessage.
+ if (IsMapEntryMessage(descriptor)) {
+ return false;
+ }
+
+ return true;
+}
+
+bool IsCrossFileMapField(const FieldDescriptor* field) {
+ if (!field->is_map()) {
+ return false;
+ }
+
+ const Descriptor* d = field->message_type();
+ const FieldDescriptor* value = d->FindFieldByNumber(2);
+
+ return IsCrossFileMessage(value);
+}
+
+bool IsCrossFileMaybeMap(const FieldDescriptor* field) {
+ if (IsCrossFileMapField(field)) {
+ return true;
+ }
+
+ return IsCrossFileMessage(field);
+}
+
+bool IsRequired(const std::vector<const FieldDescriptor*>& v) {
+ return v.front()->is_required();
+}
+
+bool HasSingularString(const Descriptor* desc, const Options& options) {
+ for (const auto* field : FieldRange(desc)) {
+ if (IsString(field, options) && !IsStringInlined(field, options) &&
+ !field->is_repeated() && !field->real_containing_oneof()) {
+ return true;
+ }
+ }
+ return false;
+}
+
+// Collects neighboring fields based on a given criteria (equivalent predicate).
+template <typename Predicate>
+std::vector<std::vector<const FieldDescriptor*>> CollectFields(
+ const std::vector<const FieldDescriptor*>& fields,
+ const Predicate& equivalent) {
+ std::vector<std::vector<const FieldDescriptor*>> chunks;
+ for (auto field : fields) {
+ if (chunks.empty() || !equivalent(chunks.back().back(), field)) {
+ chunks.emplace_back();
+ }
+ chunks.back().push_back(field);
+ }
+ return chunks;
+}
+
+// Returns a bit mask based on has_bit index of "fields" that are typically on
+// the same chunk. It is used in a group presence check where _has_bits_ is
+// masked to tell if any thing in "fields" is present.
+uint32_t GenChunkMask(const std::vector<const FieldDescriptor*>& fields,
+ const std::vector<int>& has_bit_indices) {
+ GOOGLE_CHECK(!fields.empty());
+ int first_index_offset = has_bit_indices[fields.front()->index()] / 32;
+ uint32_t chunk_mask = 0;
+ for (auto field : fields) {
+ // "index" defines where in the _has_bits_ the field appears.
+ int index = has_bit_indices[field->index()];
+ GOOGLE_CHECK_EQ(first_index_offset, index / 32);
+ chunk_mask |= static_cast<uint32_t>(1) << (index % 32);
+ }
+ GOOGLE_CHECK_NE(0, chunk_mask);
+ return chunk_mask;
+}
+
+// Return the number of bits set in n, a non-negative integer.
+static int popcnt(uint32_t n) {
+ int result = 0;
+ while (n != 0) {
+ result += (n & 1);
+ n = n / 2;
+ }
+ return result;
+}
+
+// For a run of cold chunks, opens and closes an external if statement that
+// checks multiple has_bits words to skip bulk of cold fields.
+class ColdChunkSkipper {
+ public:
+ ColdChunkSkipper(
+ const Options& options,
+ const std::vector<std::vector<const FieldDescriptor*>>& chunks,
+ const std::vector<int>& has_bit_indices, const double cold_threshold)
+ : chunks_(chunks),
+ has_bit_indices_(has_bit_indices),
+ access_info_map_(options.access_info_map),
+ cold_threshold_(cold_threshold) {
+ SetCommonVars(options, &variables_);
+ }
+
+ // May open an external if check for a batch of cold fields. "from" is the
+ // prefix to _has_bits_ to allow MergeFrom to use "from._has_bits_".
+ // Otherwise, it should be "".
+ void OnStartChunk(int chunk, int cached_has_word_index,
+ const std::string& from, io::Printer* printer);
+ bool OnEndChunk(int chunk, io::Printer* printer);
+
+ private:
+ bool IsColdChunk(int chunk);
+
+ int HasbitWord(int chunk, int offset) {
+ return has_bit_indices_[chunks_[chunk][offset]->index()] / 32;
+ }
+
+ const std::vector<std::vector<const FieldDescriptor*>>& chunks_;
+ const std::vector<int>& has_bit_indices_;
+ const AccessInfoMap* access_info_map_;
+ const double cold_threshold_;
+ std::map<std::string, std::string> variables_;
+ int limit_chunk_ = -1;
+};
+
+// Tuning parameters for ColdChunkSkipper.
+const double kColdRatio = 0.005;
+
+bool ColdChunkSkipper::IsColdChunk(int chunk) {
+ // Mark this variable as used until it is actually used
+ (void)cold_threshold_;
+ return false;
+}
+
+
+void ColdChunkSkipper::OnStartChunk(int chunk, int cached_has_word_index,
+ const std::string& from,
+ io::Printer* printer) {
+ Formatter format(printer, variables_);
+ if (!access_info_map_) {
+ return;
+ } else if (chunk < limit_chunk_) {
+ // We are already inside a run of cold chunks.
+ return;
+ } else if (!IsColdChunk(chunk)) {
+ // We can't start a run of cold chunks.
+ return;
+ }
+
+ // Find the end of consecutive cold chunks.
+ limit_chunk_ = chunk;
+ while (limit_chunk_ < chunks_.size() && IsColdChunk(limit_chunk_)) {
+ limit_chunk_++;
+ }
+
+ if (limit_chunk_ <= chunk + 1) {
+ // Require at least two chunks to emit external has_bit checks.
+ limit_chunk_ = -1;
+ return;
+ }
+
+ // Emit has_bit check for each has_bit_dword index.
+ format("if (PROTOBUF_PREDICT_FALSE(");
+ int first_word = HasbitWord(chunk, 0);
+ while (chunk < limit_chunk_) {
+ uint32_t mask = 0;
+ int this_word = HasbitWord(chunk, 0);
+ // Generate mask for chunks on the same word.
+ for (; chunk < limit_chunk_ && HasbitWord(chunk, 0) == this_word; chunk++) {
+ for (auto field : chunks_[chunk]) {
+ int hasbit_index = has_bit_indices_[field->index()];
+ // Fields on a chunk must be in the same word.
+ GOOGLE_CHECK_EQ(this_word, hasbit_index / 32);
+ mask |= 1 << (hasbit_index % 32);
+ }
+ }
+
+ if (this_word != first_word) {
+ format(" ||\n ");
+ }
+ format.Set("mask", strings::Hex(mask, strings::ZERO_PAD_8));
+ if (this_word == cached_has_word_index) {
+ format("(cached_has_bits & 0x$mask$u) != 0");
+ } else {
+ format("($1$_has_bits_[$2$] & 0x$mask$u) != 0", from, this_word);
+ }
+ }
+ format(")) {\n");
+ format.Indent();
+}
+
+bool ColdChunkSkipper::OnEndChunk(int chunk, io::Printer* printer) {
+ Formatter format(printer, variables_);
+ if (chunk != limit_chunk_ - 1) {
+ return false;
+ }
+ format.Outdent();
+ format("}\n");
+ return true;
+}
+
+void MaySetAnnotationVariable(const Options& options,
+ StringPiece annotation_name,
+ StringPiece injector_template_prefix,
+ StringPiece injector_template_suffix,
+ std::map<std::string, std::string>* variables) {
+ if (options.field_listener_options.forbidden_field_listener_events.count(
+ std::string(annotation_name)))
+ return;
+ (*variables)[StrCat("annotate_", annotation_name)] = strings::Substitute(
+ StrCat(injector_template_prefix, injector_template_suffix),
+ (*variables)["classtype"]);
+}
+
+void GenerateExtensionAnnotations(
+ const Descriptor* descriptor, const Options& options,
+ std::map<std::string, std::string>* variables) {
+ const std::map<std::string, std::string> accessor_annotations_to_hooks = {
+ {"annotate_extension_has", "OnHasExtension"},
+ {"annotate_extension_clear", "OnClearExtension"},
+ {"annotate_extension_repeated_size", "OnExtensionSize"},
+ {"annotate_extension_get", "OnGetExtension"},
+ {"annotate_extension_mutable", "OnMutableExtension"},
+ {"annotate_extension_set", "OnSetExtension"},
+ {"annotate_extension_release", "OnReleaseExtension"},
+ {"annotate_repeated_extension_get", "OnGetExtension"},
+ {"annotate_repeated_extension_mutable", "OnMutableExtension"},
+ {"annotate_repeated_extension_set", "OnSetExtension"},
+ {"annotate_repeated_extension_add", "OnAddExtension"},
+ {"annotate_repeated_extension_add_mutable", "OnAddMutableExtension"},
+ {"annotate_repeated_extension_list", "OnListExtension"},
+ {"annotate_repeated_extension_list_mutable", "OnMutableListExtension"},
+ };
+ for (const auto& annotation : accessor_annotations_to_hooks) {
+ (*variables)[annotation.first] = "";
+ }
+ if (!options.field_listener_options.inject_field_listener_events ||
+ descriptor->file()->options().optimize_for() ==
+ google::protobuf::FileOptions::LITE_RUNTIME) {
+ return;
+ }
+ for (const auto& annotation : accessor_annotations_to_hooks) {
+ const std::string& annotation_name = annotation.first;
+ const std::string& listener_call = annotation.second;
+ if (!StrContains(annotation_name, "repeated") &&
+ !StrContains(annotation_name, "size") &&
+ !StrContains(annotation_name, "clear")) {
+ // Primitive fields accessors.
+ // "Has" is here as users calling "has" on a repeated field is a mistake.
+ (*variables)[annotation_name] = StrCat(
+ " _tracker_.", listener_call,
+ "(this, id.number(), _proto_TypeTraits::GetPtr(id.number(), "
+ "_extensions_, id.default_value_ref()));");
+ } else if (StrContains(annotation_name, "repeated") &&
+ !StrContains(annotation_name, "list") &&
+ !StrContains(annotation_name, "size")) {
+ // Repeated index accessors.
+ std::string str_index = "index";
+ if (StrContains(annotation_name, "add")) {
+ str_index = "_extensions_.ExtensionSize(id.number()) - 1";
+ }
+ (*variables)[annotation_name] =
+ StrCat(" _tracker_.", listener_call,
+ "(this, id.number(), "
+ "_proto_TypeTraits::GetPtr(id.number(), _extensions_, ",
+ str_index, "));");
+ } else if (StrContains(annotation_name, "list") ||
+ StrContains(annotation_name, "size")) {
+ // Repeated full accessors.
+ (*variables)[annotation_name] = StrCat(
+ " _tracker_.", listener_call,
+ "(this, id.number(), _proto_TypeTraits::GetRepeatedPtr(id.number(), "
+ "_extensions_));");
+ } else {
+ // Generic accessors such as "clear".
+ // TODO(b/190614678): Generalize clear from both repeated and non repeated
+ // calls, currently their underlying memory interfaces are very different.
+ // Or think of removing clear callback as no usages are needed and no
+ // memory exist after calling clear().
+ }
+ }
+}
+
+} // anonymous namespace
+
+// ===================================================================
+
+MessageGenerator::MessageGenerator(
+ const Descriptor* descriptor,
+ const std::map<std::string, std::string>& vars, int index_in_file_messages,
+ const Options& options, MessageSCCAnalyzer* scc_analyzer)
+ : descriptor_(descriptor),
+ index_in_file_messages_(index_in_file_messages),
+ classname_(ClassName(descriptor, false)),
+ options_(options),
+ field_generators_(descriptor, options, scc_analyzer),
+ max_has_bit_index_(0),
+ max_inlined_string_index_(0),
+ num_weak_fields_(0),
+ scc_analyzer_(scc_analyzer),
+ variables_(vars) {
+ if (!message_layout_helper_) {
+ message_layout_helper_.reset(new PaddingOptimizer());
+ }
+
+ // Variables that apply to this class
+ variables_["classname"] = classname_;
+ variables_["classtype"] = QualifiedClassName(descriptor_, options);
+ variables_["full_name"] = descriptor_->full_name();
+ variables_["superclass"] = SuperClassName(descriptor_, options_);
+ variables_["annotate_serialize"] = "";
+ variables_["annotate_deserialize"] = "";
+ variables_["annotate_reflection"] = "";
+ variables_["annotate_bytesize"] = "";
+ variables_["annotate_mergefrom"] = "";
+
+ if (options.field_listener_options.inject_field_listener_events &&
+ descriptor->file()->options().optimize_for() !=
+ google::protobuf::FileOptions::LITE_RUNTIME) {
+ const std::string injector_template = " _tracker_.";
+
+ MaySetAnnotationVariable(options, "serialize", injector_template,
+ "OnSerialize(this);\n", &variables_);
+ MaySetAnnotationVariable(options, "deserialize", injector_template,
+ "OnDeserialize(this);\n", &variables_);
+ // TODO(danilak): Ideally annotate_reflection should not exist and we need
+ // to annotate all reflective calls on our own, however, as this is a cause
+ // for side effects, i.e. reading values dynamically, we want the users know
+ // that dynamic access can happen.
+ MaySetAnnotationVariable(options, "reflection", injector_template,
+ "OnGetMetadata();\n", &variables_);
+ MaySetAnnotationVariable(options, "bytesize", injector_template,
+ "OnByteSize(this);\n", &variables_);
+ MaySetAnnotationVariable(options, "mergefrom", injector_template,
+ "OnMergeFrom(this, &from);\n", &variables_);
+ }
+
+ GenerateExtensionAnnotations(descriptor_, options_, &variables_);
+
+ SetUnknownFieldsVariable(descriptor_, options_, &variables_);
+
+ // Compute optimized field order to be used for layout and initialization
+ // purposes.
+ for (auto field : FieldRange(descriptor_)) {
+ if (IsFieldStripped(field, options_)) {
+ continue;
+ }
+
+ if (IsWeak(field, options_)) {
+ num_weak_fields_++;
+ } else if (!field->real_containing_oneof()) {
+ optimized_order_.push_back(field);
+ }
+ }
+
+ message_layout_helper_->OptimizeLayout(&optimized_order_, options_,
+ scc_analyzer_);
+
+ // This message has hasbits iff one or more fields need one.
+ for (auto field : optimized_order_) {
+ if (HasHasbit(field)) {
+ if (has_bit_indices_.empty()) {
+ has_bit_indices_.resize(descriptor_->field_count(), kNoHasbit);
+ }
+ has_bit_indices_[field->index()] = max_has_bit_index_++;
+ }
+ if (IsStringInlined(field, options_)) {
+ if (inlined_string_indices_.empty()) {
+ inlined_string_indices_.resize(descriptor_->field_count(), kNoHasbit);
+ }
+ inlined_string_indices_[field->index()] = max_inlined_string_index_++;
+ }
+ }
+
+ if (!has_bit_indices_.empty()) {
+ field_generators_.SetHasBitIndices(has_bit_indices_);
+ }
+
+ if (!inlined_string_indices_.empty()) {
+ field_generators_.SetInlinedStringIndices(inlined_string_indices_);
+ }
+
+ num_required_fields_ = 0;
+ for (int i = 0; i < descriptor->field_count(); i++) {
+ if (descriptor->field(i)->is_required()) {
+ ++num_required_fields_;
+ }
+ }
+
+ table_driven_ =
+ TableDrivenParsingEnabled(descriptor_, options_, scc_analyzer_);
+ parse_function_generator_.reset(new ParseFunctionGenerator(
+ descriptor_, max_has_bit_index_, has_bit_indices_,
+ inlined_string_indices_, options_, scc_analyzer_, variables_));
+}
+
+MessageGenerator::~MessageGenerator() = default;
+
+size_t MessageGenerator::HasBitsSize() const {
+ return (max_has_bit_index_ + 31) / 32;
+}
+
+size_t MessageGenerator::InlinedStringDonatedSize() const {
+ return (max_inlined_string_index_ + 31) / 32;
+}
+
+int MessageGenerator::HasBitIndex(const FieldDescriptor* field) const {
+ return has_bit_indices_.empty() ? kNoHasbit
+ : has_bit_indices_[field->index()];
+}
+
+int MessageGenerator::HasByteIndex(const FieldDescriptor* field) const {
+ int hasbit = HasBitIndex(field);
+ return hasbit == kNoHasbit ? kNoHasbit : hasbit / 8;
+}
+
+int MessageGenerator::HasWordIndex(const FieldDescriptor* field) const {
+ int hasbit = HasBitIndex(field);
+ return hasbit == kNoHasbit ? kNoHasbit : hasbit / 32;
+}
+
+void MessageGenerator::AddGenerators(
+ std::vector<std::unique_ptr<EnumGenerator>>* enum_generators,
+ std::vector<std::unique_ptr<ExtensionGenerator>>* extension_generators) {
+ for (int i = 0; i < descriptor_->enum_type_count(); i++) {
+ enum_generators->emplace_back(
+ new EnumGenerator(descriptor_->enum_type(i), variables_, options_));
+ enum_generators_.push_back(enum_generators->back().get());
+ }
+ for (int i = 0; i < descriptor_->extension_count(); i++) {
+ extension_generators->emplace_back(new ExtensionGenerator(
+ descriptor_->extension(i), options_, scc_analyzer_));
+ extension_generators_.push_back(extension_generators->back().get());
+ }
+}
+
+void MessageGenerator::GenerateFieldAccessorDeclarations(io::Printer* printer) {
+ Formatter format(printer, variables_);
+ // optimized_fields_ does not contain fields where
+ // field->real_containing_oneof()
+ // so we need to iterate over those as well.
+ //
+ // We place the non-oneof fields in optimized_order_, as that controls the
+ // order of the _has_bits_ entries and we want GDB's pretty printers to be
+ // able to infer these indices from the k[FIELDNAME]FieldNumber order.
+ std::vector<const FieldDescriptor*> ordered_fields;
+ ordered_fields.reserve(descriptor_->field_count());
+
+ ordered_fields.insert(ordered_fields.begin(), optimized_order_.begin(),
+ optimized_order_.end());
+ for (auto field : FieldRange(descriptor_)) {
+ if (!field->real_containing_oneof() && !field->options().weak() &&
+ !IsFieldStripped(field, options_)) {
+ continue;
+ }
+ ordered_fields.push_back(field);
+ }
+
+ if (!ordered_fields.empty()) {
+ format("enum : int {\n");
+ for (auto field : ordered_fields) {
+ Formatter::SaveState save(&format);
+
+ std::map<std::string, std::string> vars;
+ SetCommonFieldVariables(field, &vars, options_);
+ format.AddMap(vars);
+ format(" ${1$$2$$}$ = $number$,\n", field, FieldConstantName(field));
+ }
+ format("};\n");
+ }
+ for (auto field : ordered_fields) {
+ PrintFieldComment(format, field);
+
+ Formatter::SaveState save(&format);
+
+ std::map<std::string, std::string> vars;
+ SetCommonFieldVariables(field, &vars, options_);
+ format.AddMap(vars);
+
+ if (field->is_repeated()) {
+ format("$deprecated_attr$int ${1$$name$_size$}$() const$2$\n", field,
+ !IsFieldStripped(field, options_) ? ";" : " {__builtin_trap();}");
+ if (!IsFieldStripped(field, options_)) {
+ format(
+ "private:\n"
+ "int ${1$_internal_$name$_size$}$() const;\n"
+ "public:\n",
+ field);
+ }
+ } else if (HasHasMethod(field)) {
+ format("$deprecated_attr$bool ${1$has_$name$$}$() const$2$\n", field,
+ !IsFieldStripped(field, options_) ? ";" : " {__builtin_trap();}");
+ if (!IsFieldStripped(field, options_)) {
+ format(
+ "private:\n"
+ "bool _internal_has_$name$() const;\n"
+ "public:\n");
+ }
+ } else if (HasPrivateHasMethod(field)) {
+ if (!IsFieldStripped(field, options_)) {
+ format(
+ "private:\n"
+ "bool ${1$_internal_has_$name$$}$() const;\n"
+ "public:\n",
+ field);
+ }
+ }
+ format("$deprecated_attr$void ${1$clear_$name$$}$()$2$\n", field,
+ !IsFieldStripped(field, options_) ? ";" : "{__builtin_trap();}");
+
+ // Generate type-specific accessor declarations.
+ field_generators_.get(field).GenerateAccessorDeclarations(printer);
+
+ format("\n");
+ }
+
+ if (descriptor_->extension_range_count() > 0) {
+ // Generate accessors for extensions.
+ // We use "_proto_TypeTraits" as a type name below because "TypeTraits"
+ // causes problems if the class has a nested message or enum type with that
+ // name and "_TypeTraits" is technically reserved for the C++ library since
+ // it starts with an underscore followed by a capital letter.
+ //
+ // For similar reason, we use "_field_type" and "_is_packed" as parameter
+ // names below, so that "field_type" and "is_packed" can be used as field
+ // names.
+ format(R"(
+template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+inline bool HasExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ $classname$, _proto_TypeTraits, _field_type, _is_packed>& id) const {
+$annotate_extension_has$
+ return _extensions_.Has(id.number());
+}
+
+template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+inline void ClearExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ $classname$, _proto_TypeTraits, _field_type, _is_packed>& id) {
+ _extensions_.ClearExtension(id.number());
+$annotate_extension_clear$
+}
+
+template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+inline int ExtensionSize(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ $classname$, _proto_TypeTraits, _field_type, _is_packed>& id) const {
+$annotate_extension_repeated_size$
+ return _extensions_.ExtensionSize(id.number());
+}
+
+template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+inline typename _proto_TypeTraits::Singular::ConstType GetExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ $classname$, _proto_TypeTraits, _field_type, _is_packed>& id) const {
+$annotate_extension_get$
+ return _proto_TypeTraits::Get(id.number(), _extensions_,
+ id.default_value());
+}
+
+template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+inline typename _proto_TypeTraits::Singular::MutableType MutableExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ $classname$, _proto_TypeTraits, _field_type, _is_packed>& id) {
+$annotate_extension_mutable$
+ return _proto_TypeTraits::Mutable(id.number(), _field_type,
+ &_extensions_);
+}
+
+template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+inline void SetExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ $classname$, _proto_TypeTraits, _field_type, _is_packed>& id,
+ typename _proto_TypeTraits::Singular::ConstType value) {
+ _proto_TypeTraits::Set(id.number(), _field_type, value, &_extensions_);
+$annotate_extension_set$
+}
+
+template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+inline void SetAllocatedExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ $classname$, _proto_TypeTraits, _field_type, _is_packed>& id,
+ typename _proto_TypeTraits::Singular::MutableType value) {
+ _proto_TypeTraits::SetAllocated(id.number(), _field_type, value,
+ &_extensions_);
+$annotate_extension_set$
+}
+template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+inline void UnsafeArenaSetAllocatedExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ $classname$, _proto_TypeTraits, _field_type, _is_packed>& id,
+ typename _proto_TypeTraits::Singular::MutableType value) {
+ _proto_TypeTraits::UnsafeArenaSetAllocated(id.number(), _field_type,
+ value, &_extensions_);
+$annotate_extension_set$
+}
+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<
+ $classname$, _proto_TypeTraits, _field_type, _is_packed>& id) {
+$annotate_extension_release$
+ return _proto_TypeTraits::Release(id.number(), _field_type,
+ &_extensions_);
+}
+template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+inline typename _proto_TypeTraits::Singular::MutableType
+UnsafeArenaReleaseExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ $classname$, _proto_TypeTraits, _field_type, _is_packed>& id) {
+$annotate_extension_release$
+ return _proto_TypeTraits::UnsafeArenaRelease(id.number(), _field_type,
+ &_extensions_);
+}
+
+template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+inline typename _proto_TypeTraits::Repeated::ConstType GetExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ $classname$, _proto_TypeTraits, _field_type, _is_packed>& id,
+ int index) const {
+$annotate_repeated_extension_get$
+ return _proto_TypeTraits::Get(id.number(), _extensions_, index);
+}
+
+template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+inline typename _proto_TypeTraits::Repeated::MutableType MutableExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ $classname$, _proto_TypeTraits, _field_type, _is_packed>& id,
+ int index) {
+$annotate_repeated_extension_mutable$
+ return _proto_TypeTraits::Mutable(id.number(), index, &_extensions_);
+}
+
+template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+inline void SetExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ $classname$, _proto_TypeTraits, _field_type, _is_packed>& id,
+ int index, typename _proto_TypeTraits::Repeated::ConstType value) {
+ _proto_TypeTraits::Set(id.number(), index, value, &_extensions_);
+$annotate_repeated_extension_set$
+}
+
+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<
+ $classname$, _proto_TypeTraits, _field_type, _is_packed>& id) {
+ typename _proto_TypeTraits::Repeated::MutableType to_add =
+ _proto_TypeTraits::Add(id.number(), _field_type, &_extensions_);
+$annotate_repeated_extension_add_mutable$
+ 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<
+ $classname$, _proto_TypeTraits, _field_type, _is_packed>& id,
+ typename _proto_TypeTraits::Repeated::ConstType value) {
+ _proto_TypeTraits::Add(id.number(), _field_type, _is_packed, value,
+ &_extensions_);
+$annotate_repeated_extension_add$
+}
+
+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<
+ $classname$, _proto_TypeTraits, _field_type, _is_packed>& id) const {
+$annotate_repeated_extension_list$
+ return _proto_TypeTraits::GetRepeated(id.number(), _extensions_);
+}
+
+template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+inline typename _proto_TypeTraits::Repeated::RepeatedFieldType*
+MutableRepeatedExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ $classname$, _proto_TypeTraits, _field_type, _is_packed>& id) {
+$annotate_repeated_extension_list_mutable$
+ return _proto_TypeTraits::MutableRepeated(id.number(), _field_type,
+ _is_packed, &_extensions_);
+}
+
+)");
+ // Generate MessageSet specific APIs for proto2 MessageSet.
+ // For testing purposes we don't check for bridge.MessageSet, so
+ // we don't use IsProto2MessageSet
+ if (descriptor_->options().message_set_wire_format() &&
+ !options_.opensource_runtime && !options_.lite_implicit_weak_fields) {
+ // Special-case MessageSet
+ format("GOOGLE_PROTOBUF_EXTENSION_MESSAGE_SET_ACCESSORS($classname$)\n");
+ }
+ }
+
+ for (auto oneof : OneOfRange(descriptor_)) {
+ Formatter::SaveState saver(&format);
+ format.Set("oneof_name", oneof->name());
+ format.Set("camel_oneof_name", UnderscoresToCamelCase(oneof->name(), true));
+ format(
+ "void ${1$clear_$oneof_name$$}$();\n"
+ "$camel_oneof_name$Case $oneof_name$_case() const;\n",
+ oneof);
+ }
+}
+
+void MessageGenerator::GenerateSingularFieldHasBits(
+ const FieldDescriptor* field, Formatter format) {
+ if (IsFieldStripped(field, options_)) {
+ format(
+ "inline bool $classname$::has_$name$() const { "
+ "__builtin_trap(); }\n");
+ return;
+ }
+ if (field->options().weak()) {
+ format(
+ "inline bool $classname$::has_$name$() const {\n"
+ "$annotate_has$"
+ " return _weak_field_map_.Has($number$);\n"
+ "}\n");
+ return;
+ }
+ if (HasHasbit(field)) {
+ int has_bit_index = HasBitIndex(field);
+ GOOGLE_CHECK_NE(has_bit_index, kNoHasbit);
+
+ format.Set("has_array_index", has_bit_index / 32);
+ format.Set("has_mask",
+ strings::Hex(1u << (has_bit_index % 32), strings::ZERO_PAD_8));
+ format(
+ "inline bool $classname$::_internal_has_$name$() const {\n"
+ " bool value = "
+ "(_has_bits_[$has_array_index$] & 0x$has_mask$u) != 0;\n");
+
+ if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
+ !IsLazy(field, options_, scc_analyzer_)) {
+ // We maintain the invariant that for a submessage x, has_x() returning
+ // true implies that x_ is not null. By giving this information to the
+ // compiler, we allow it to eliminate unnecessary null checks later on.
+ format(" PROTOBUF_ASSUME(!value || $name$_ != nullptr);\n");
+ }
+
+ format(
+ " return value;\n"
+ "}\n"
+ "inline bool $classname$::has_$name$() const {\n"
+ "$annotate_has$"
+ " return _internal_has_$name$();\n"
+ "}\n");
+ } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+ // Message fields have a has_$name$() method.
+ if (IsLazy(field, options_, scc_analyzer_)) {
+ format(
+ "inline bool $classname$::_internal_has_$name$() const {\n"
+ " return !$name$_.IsCleared();\n"
+ "}\n");
+ } else {
+ format(
+ "inline bool $classname$::_internal_has_$name$() const {\n"
+ " return this != internal_default_instance() "
+ "&& $name$_ != nullptr;\n"
+ "}\n");
+ }
+ format(
+ "inline bool $classname$::has_$name$() const {\n"
+ "$annotate_has$"
+ " return _internal_has_$name$();\n"
+ "}\n");
+ }
+}
+
+void MessageGenerator::GenerateOneofHasBits(io::Printer* printer) {
+ Formatter format(printer, variables_);
+ for (auto oneof : OneOfRange(descriptor_)) {
+ format.Set("oneof_name", oneof->name());
+ format.Set("oneof_index", oneof->index());
+ format.Set("cap_oneof_name", ToUpper(oneof->name()));
+ format(
+ "inline bool $classname$::has_$oneof_name$() const {\n"
+ " return $oneof_name$_case() != $cap_oneof_name$_NOT_SET;\n"
+ "}\n"
+ "inline void $classname$::clear_has_$oneof_name$() {\n"
+ " _oneof_case_[$oneof_index$] = $cap_oneof_name$_NOT_SET;\n"
+ "}\n");
+ }
+}
+
+void MessageGenerator::GenerateOneofMemberHasBits(const FieldDescriptor* field,
+ const Formatter& format) {
+ if (IsFieldStripped(field, options_)) {
+ if (HasHasMethod(field)) {
+ format(
+ "inline bool $classname$::has_$name$() const { "
+ "__builtin_trap(); }\n");
+ }
+ format(
+ "inline void $classname$::set_has_$name$() { __builtin_trap(); "
+ "}\n");
+ return;
+ }
+ // Singular field in a oneof
+ // N.B.: Without field presence, we do not use has-bits or generate
+ // has_$name$() methods, but oneofs still have set_has_$name$().
+ // Oneofs also have has_$name$() but only as a private helper
+ // method, so that generated code is slightly cleaner (vs. comparing
+ // _oneof_case_[index] against a constant everywhere).
+ //
+ // If has_$name$() is private, there is no need to add an internal accessor.
+ // Only annotate public accessors.
+ if (HasHasMethod(field)) {
+ format(
+ "inline bool $classname$::_internal_has_$name$() const {\n"
+ " return $oneof_name$_case() == k$field_name$;\n"
+ "}\n"
+ "inline bool $classname$::has_$name$() const {\n"
+ "$annotate_has$"
+ " return _internal_has_$name$();\n"
+ "}\n");
+ } else if (HasPrivateHasMethod(field)) {
+ format(
+ "inline bool $classname$::_internal_has_$name$() const {\n"
+ " return $oneof_name$_case() == k$field_name$;\n"
+ "}\n");
+ }
+ // set_has_$name$() for oneof fields is always private; hence should not be
+ // annotated.
+ format(
+ "inline void $classname$::set_has_$name$() {\n"
+ " _oneof_case_[$oneof_index$] = k$field_name$;\n"
+ "}\n");
+}
+
+void MessageGenerator::GenerateFieldClear(const FieldDescriptor* field,
+ bool is_inline, Formatter format) {
+ if (IsFieldStripped(field, options_)) {
+ format("void $classname$::clear_$name$() { __builtin_trap(); }\n");
+ return;
+ }
+
+ // Generate clear_$name$().
+ if (is_inline) {
+ format("inline ");
+ }
+ format("void $classname$::clear_$name$() {\n");
+
+ format.Indent();
+
+ if (field->real_containing_oneof()) {
+ // Clear this field only if it is the active field in this oneof,
+ // otherwise ignore
+ format("if (_internal_has_$name$()) {\n");
+ format.Indent();
+ field_generators_.get(field).GenerateClearingCode(format.printer());
+ format("clear_has_$oneof_name$();\n");
+ format.Outdent();
+ format("}\n");
+ } else {
+ field_generators_.get(field).GenerateClearingCode(format.printer());
+ if (HasHasbit(field)) {
+ int has_bit_index = HasBitIndex(field);
+ format.Set("has_array_index", has_bit_index / 32);
+ format.Set("has_mask",
+ strings::Hex(1u << (has_bit_index % 32), strings::ZERO_PAD_8));
+ format("_has_bits_[$has_array_index$] &= ~0x$has_mask$u;\n");
+ }
+ }
+ format("$annotate_clear$");
+ format.Outdent();
+ format("}\n");
+}
+
+void MessageGenerator::GenerateFieldAccessorDefinitions(io::Printer* printer) {
+ Formatter format(printer, variables_);
+ format("// $classname$\n\n");
+
+ for (auto field : FieldRange(descriptor_)) {
+ PrintFieldComment(format, field);
+
+ if (IsFieldStripped(field, options_)) {
+ continue;
+ }
+
+ std::map<std::string, std::string> vars;
+ SetCommonFieldVariables(field, &vars, options_);
+
+ Formatter::SaveState saver(&format);
+ format.AddMap(vars);
+
+ // Generate has_$name$() or $name$_size().
+ if (field->is_repeated()) {
+ if (IsFieldStripped(field, options_)) {
+ format(
+ "inline int $classname$::$name$_size() const { "
+ "__builtin_trap(); }\n");
+ } else {
+ format(
+ "inline int $classname$::_internal_$name$_size() const {\n"
+ " return $name$_$1$.size();\n"
+ "}\n"
+ "inline int $classname$::$name$_size() const {\n"
+ "$annotate_size$"
+ " return _internal_$name$_size();\n"
+ "}\n",
+ IsImplicitWeakField(field, options_, scc_analyzer_) &&
+ field->message_type()
+ ? ".weak"
+ : "");
+ }
+ } else if (field->real_containing_oneof()) {
+ format.Set("field_name", UnderscoresToCamelCase(field->name(), true));
+ format.Set("oneof_name", field->containing_oneof()->name());
+ format.Set("oneof_index",
+ StrCat(field->containing_oneof()->index()));
+ GenerateOneofMemberHasBits(field, format);
+ } else {
+ // Singular field.
+ GenerateSingularFieldHasBits(field, format);
+ }
+
+ if (!IsCrossFileMaybeMap(field)) {
+ GenerateFieldClear(field, true, format);
+ }
+
+ // Generate type-specific accessors.
+ if (!IsFieldStripped(field, options_)) {
+ field_generators_.get(field).GenerateInlineAccessorDefinitions(printer);
+ }
+
+ format("\n");
+ }
+
+ // Generate has_$name$() and clear_has_$name$() functions for oneofs.
+ GenerateOneofHasBits(printer);
+}
+
+void MessageGenerator::GenerateClassDefinition(io::Printer* printer) {
+ Formatter format(printer, variables_);
+ format.Set("class_final",
+ ShouldMarkClassAsFinal(descriptor_, options_) ? "final" : "");
+
+ if (IsMapEntryMessage(descriptor_)) {
+ std::map<std::string, std::string> vars;
+ CollectMapInfo(options_, descriptor_, &vars);
+ vars["lite"] =
+ HasDescriptorMethods(descriptor_->file(), options_) ? "" : "Lite";
+ format.AddMap(vars);
+ format(
+ "class $classname$ : public "
+ "::$proto_ns$::internal::MapEntry$lite$<$classname$, \n"
+ " $key_cpp$, $val_cpp$,\n"
+ " ::$proto_ns$::internal::WireFormatLite::$key_wire_type$,\n"
+ " ::$proto_ns$::internal::WireFormatLite::$val_wire_type$> {\n"
+ "public:\n"
+ " typedef ::$proto_ns$::internal::MapEntry$lite$<$classname$, \n"
+ " $key_cpp$, $val_cpp$,\n"
+ " ::$proto_ns$::internal::WireFormatLite::$key_wire_type$,\n"
+ " ::$proto_ns$::internal::WireFormatLite::$val_wire_type$> "
+ "SuperType;\n"
+ " $classname$();\n"
+ " explicit constexpr $classname$(\n"
+ " ::$proto_ns$::internal::ConstantInitialized);\n"
+ " explicit $classname$(::$proto_ns$::Arena* arena);\n"
+ " void MergeFrom(const $classname$& other);\n"
+ " static const $classname$* internal_default_instance() { return "
+ "reinterpret_cast<const "
+ "$classname$*>(&_$classname$_default_instance_); }\n");
+ auto utf8_check = GetUtf8CheckMode(descriptor_->field(0), options_);
+ if (descriptor_->field(0)->type() == FieldDescriptor::TYPE_STRING &&
+ utf8_check != Utf8CheckMode::kNone) {
+ if (utf8_check == Utf8CheckMode::kStrict) {
+ format(
+ " static bool ValidateKey(std::string* s) {\n"
+ " return ::$proto_ns$::internal::WireFormatLite::"
+ "VerifyUtf8String(s->data(), static_cast<int>(s->size()), "
+ "::$proto_ns$::internal::WireFormatLite::PARSE, \"$1$\");\n"
+ " }\n",
+ descriptor_->field(0)->full_name());
+ } else {
+ GOOGLE_CHECK(utf8_check == Utf8CheckMode::kVerify);
+ format(
+ " static bool ValidateKey(std::string* s) {\n"
+ "#ifndef NDEBUG\n"
+ " ::$proto_ns$::internal::WireFormatLite::VerifyUtf8String(\n"
+ " s->data(), static_cast<int>(s->size()), "
+ "::$proto_ns$::internal::"
+ "WireFormatLite::PARSE, \"$1$\");\n"
+ "#else\n"
+ " (void) s;\n"
+ "#endif\n"
+ " return true;\n"
+ " }\n",
+ descriptor_->field(0)->full_name());
+ }
+ } else {
+ format(" static bool ValidateKey(void*) { return true; }\n");
+ }
+ if (descriptor_->field(1)->type() == FieldDescriptor::TYPE_STRING &&
+ utf8_check != Utf8CheckMode::kNone) {
+ if (utf8_check == Utf8CheckMode::kStrict) {
+ format(
+ " static bool ValidateValue(std::string* s) {\n"
+ " return ::$proto_ns$::internal::WireFormatLite::"
+ "VerifyUtf8String(s->data(), static_cast<int>(s->size()), "
+ "::$proto_ns$::internal::WireFormatLite::PARSE, \"$1$\");\n"
+ " }\n",
+ descriptor_->field(1)->full_name());
+ } else {
+ GOOGLE_CHECK(utf8_check == Utf8CheckMode::kVerify);
+ format(
+ " static bool ValidateValue(std::string* s) {\n"
+ "#ifndef NDEBUG\n"
+ " ::$proto_ns$::internal::WireFormatLite::VerifyUtf8String(\n"
+ " s->data(), static_cast<int>(s->size()), "
+ "::$proto_ns$::internal::"
+ "WireFormatLite::PARSE, \"$1$\");\n"
+ "#else\n"
+ " (void) s;\n"
+ "#endif\n"
+ " return true;\n"
+ " }\n",
+ descriptor_->field(1)->full_name());
+ }
+ } else {
+ format(" static bool ValidateValue(void*) { return true; }\n");
+ }
+ if (HasDescriptorMethods(descriptor_->file(), options_)) {
+ format(
+ " using ::$proto_ns$::Message::MergeFrom;\n"
+ ""
+ " ::$proto_ns$::Metadata GetMetadata() const final;\n");
+ }
+ format("};\n");
+ return;
+ }
+
+ format(
+ "class $dllexport_decl $${1$$classname$$}$$ class_final$ :\n"
+ " public $superclass$ /* @@protoc_insertion_point("
+ "class_definition:$full_name$) */ {\n",
+ descriptor_);
+ format(" public:\n");
+ format.Indent();
+
+ if (EnableMessageOwnedArena(descriptor_)) {
+ format(
+ "inline $classname$() : $classname$("
+ "::$proto_ns$::Arena::InternalHelper<$classname$>::\n"
+ " CreateMessageOwnedArena(), true) {}\n");
+ } else {
+ format("inline $classname$() : $classname$(nullptr) {}\n");
+ }
+ if (!HasSimpleBaseClass(descriptor_, options_)) {
+ format("~$classname$() override;\n");
+ }
+ format(
+ "explicit constexpr "
+ "$classname$(::$proto_ns$::internal::ConstantInitialized);\n"
+ "\n"
+ "$classname$(const $classname$& from);\n"
+ "$classname$($classname$&& from) noexcept\n"
+ " : $classname$() {\n"
+ " *this = ::std::move(from);\n"
+ "}\n"
+ "\n"
+ "inline $classname$& operator=(const $classname$& from) {\n"
+ " CopyFrom(from);\n"
+ " return *this;\n"
+ "}\n"
+ "inline $classname$& operator=($classname$&& from) noexcept {\n"
+ " if (this == &from) return *this;\n"
+ " if (GetOwningArena() == from.GetOwningArena()\n"
+ "#ifdef PROTOBUF_FORCE_COPY_IN_MOVE\n"
+ " && GetOwningArena() != nullptr\n"
+ "#endif // !PROTOBUF_FORCE_COPY_IN_MOVE\n"
+ " ) {\n"
+ " InternalSwap(&from);\n"
+ " } else {\n"
+ " CopyFrom(from);\n"
+ " }\n"
+ " return *this;\n"
+ "}\n"
+ "\n");
+
+ if (options_.table_driven_serialization) {
+ format(
+ "private:\n"
+ "const void* InternalGetTable() const override;\n"
+ "public:\n"
+ "\n");
+ }
+
+ if (PublicUnknownFieldsAccessors(descriptor_)) {
+ format(
+ "inline const $unknown_fields_type$& unknown_fields() const {\n"
+ " return $unknown_fields$;\n"
+ "}\n"
+ "inline $unknown_fields_type$* mutable_unknown_fields() {\n"
+ " return $mutable_unknown_fields$;\n"
+ "}\n"
+ "\n");
+ }
+
+ // Only generate this member if it's not disabled.
+ if (HasDescriptorMethods(descriptor_->file(), options_) &&
+ !descriptor_->options().no_standard_descriptor_accessor()) {
+ format(
+ "static const ::$proto_ns$::Descriptor* descriptor() {\n"
+ " return GetDescriptor();\n"
+ "}\n");
+ }
+
+ if (HasDescriptorMethods(descriptor_->file(), options_)) {
+ // These shadow non-static methods of the same names in Message. We
+ // redefine them here because calls directly on the generated class can be
+ // statically analyzed -- we know what descriptor types are being requested.
+ // It also avoids a vtable dispatch.
+ //
+ // We would eventually like to eliminate the methods in Message, and having
+ // this separate also lets us track calls to the base class methods
+ // separately.
+ format(
+ "static const ::$proto_ns$::Descriptor* GetDescriptor() {\n"
+ " return default_instance().GetMetadata().descriptor;\n"
+ "}\n"
+ "static const ::$proto_ns$::Reflection* GetReflection() {\n"
+ " return default_instance().GetMetadata().reflection;\n"
+ "}\n");
+ }
+
+ format(
+ "static const $classname$& default_instance() {\n"
+ " return *internal_default_instance();\n"
+ "}\n");
+
+ // Generate enum values for every field in oneofs. One list is generated for
+ // each oneof with an additional *_NOT_SET value.
+ for (auto oneof : OneOfRange(descriptor_)) {
+ format("enum $1$Case {\n", UnderscoresToCamelCase(oneof->name(), true));
+ format.Indent();
+ for (auto field : FieldRange(oneof)) {
+ format("$1$ = $2$,\n", OneofCaseConstantName(field), // 1
+ field->number()); // 2
+ }
+ format("$1$_NOT_SET = 0,\n", ToUpper(oneof->name()));
+ format.Outdent();
+ format(
+ "};\n"
+ "\n");
+ }
+
+ // TODO(gerbens) make this private, while still granting other protos access.
+ format(
+ "static inline const $classname$* internal_default_instance() {\n"
+ " return reinterpret_cast<const $classname$*>(\n"
+ " &_$classname$_default_instance_);\n"
+ "}\n"
+ "static constexpr int kIndexInFileMessages =\n"
+ " $1$;\n"
+ "\n",
+ index_in_file_messages_);
+
+ if (IsAnyMessage(descriptor_, options_)) {
+ format(
+ "// implements Any -----------------------------------------------\n"
+ "\n");
+ if (HasDescriptorMethods(descriptor_->file(), options_)) {
+ format(
+ "bool PackFrom(const ::$proto_ns$::Message& message) {\n"
+ " return _any_metadata_.PackFrom(GetArena(), message);\n"
+ "}\n"
+ "bool PackFrom(const ::$proto_ns$::Message& message,\n"
+ " ::PROTOBUF_NAMESPACE_ID::ConstStringParam "
+ "type_url_prefix) {\n"
+ " return _any_metadata_.PackFrom(GetArena(), message, "
+ "type_url_prefix);\n"
+ "}\n"
+ "bool UnpackTo(::$proto_ns$::Message* message) const {\n"
+ " return _any_metadata_.UnpackTo(message);\n"
+ "}\n"
+ "static bool GetAnyFieldDescriptors(\n"
+ " const ::$proto_ns$::Message& message,\n"
+ " const ::$proto_ns$::FieldDescriptor** type_url_field,\n"
+ " const ::$proto_ns$::FieldDescriptor** value_field);\n"
+ "template <typename T, class = typename std::enable_if<"
+ "!std::is_convertible<T, const ::$proto_ns$::Message&>"
+ "::value>::type>\n"
+ "bool PackFrom(const T& message) {\n"
+ " return _any_metadata_.PackFrom<T>(GetArena(), message);\n"
+ "}\n"
+ "template <typename T, class = typename std::enable_if<"
+ "!std::is_convertible<T, const ::$proto_ns$::Message&>"
+ "::value>::type>\n"
+ "bool PackFrom(const T& message,\n"
+ " ::PROTOBUF_NAMESPACE_ID::ConstStringParam "
+ "type_url_prefix) {\n"
+ " return _any_metadata_.PackFrom<T>(GetArena(), message, "
+ "type_url_prefix);"
+ "}\n"
+ "template <typename T, class = typename std::enable_if<"
+ "!std::is_convertible<T, const ::$proto_ns$::Message&>"
+ "::value>::type>\n"
+ "bool UnpackTo(T* message) const {\n"
+ " return _any_metadata_.UnpackTo<T>(message);\n"
+ "}\n");
+ } else {
+ format(
+ "template <typename T>\n"
+ "bool PackFrom(const T& message) {\n"
+ " return _any_metadata_.PackFrom(GetArena(), message);\n"
+ "}\n"
+ "template <typename T>\n"
+ "bool PackFrom(const T& message,\n"
+ " ::PROTOBUF_NAMESPACE_ID::ConstStringParam "
+ "type_url_prefix) {\n"
+ " return _any_metadata_.PackFrom(GetArena(), message, "
+ "type_url_prefix);\n"
+ "}\n"
+ "template <typename T>\n"
+ "bool UnpackTo(T* message) const {\n"
+ " return _any_metadata_.UnpackTo(message);\n"
+ "}\n");
+ }
+ format(
+ "template<typename T> bool Is() const {\n"
+ " return _any_metadata_.Is<T>();\n"
+ "}\n"
+ "static bool ParseAnyTypeUrl(::PROTOBUF_NAMESPACE_ID::ConstStringParam "
+ "type_url,\n"
+ " std::string* full_type_name);\n");
+ }
+
+ format(
+ "friend void swap($classname$& a, $classname$& b) {\n"
+ " a.Swap(&b);\n"
+ "}\n"
+ "inline void Swap($classname$* other) {\n"
+ " if (other == this) return;\n"
+ "#ifdef PROTOBUF_FORCE_COPY_IN_SWAP\n"
+ " if (GetOwningArena() != nullptr &&\n"
+ " GetOwningArena() == other->GetOwningArena()) {\n "
+ "#else // PROTOBUF_FORCE_COPY_IN_SWAP\n"
+ " if (GetOwningArena() == other->GetOwningArena()) {\n"
+ "#endif // !PROTOBUF_FORCE_COPY_IN_SWAP\n"
+ " InternalSwap(other);\n"
+ " } else {\n"
+ " ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);\n"
+ " }\n"
+ "}\n"
+ "void UnsafeArenaSwap($classname$* other) {\n"
+ " if (other == this) return;\n"
+ " $DCHK$(GetOwningArena() == other->GetOwningArena());\n"
+ " InternalSwap(other);\n"
+ "}\n");
+
+ format(
+ "\n"
+ "// implements Message ----------------------------------------------\n"
+ "\n"
+ "$classname$* New(::$proto_ns$::Arena* arena = nullptr) const final {\n"
+ " return CreateMaybeMessage<$classname$>(arena);\n"
+ "}\n");
+
+ // For instances that derive from Message (rather than MessageLite), some
+ // methods are virtual and should be marked as final.
+ format.Set("full_final", HasDescriptorMethods(descriptor_->file(), options_)
+ ? "final"
+ : "");
+
+ if (HasGeneratedMethods(descriptor_->file(), options_)) {
+ if (HasDescriptorMethods(descriptor_->file(), options_)) {
+ if (!HasSimpleBaseClass(descriptor_, options_)) {
+ format(
+ // Use Message's built-in MergeFrom and CopyFrom when the passed-in
+ // argument is a generic Message instance, and only define the
+ // custom MergeFrom and CopyFrom instances when the source of the
+ // merge/copy is known to be the same class as the destination.
+ // TODO(jorg): Define MergeFrom in terms of MergeImpl, rather than
+ // the other way around, to save even more code size.
+ "using $superclass$::CopyFrom;\n"
+ "void CopyFrom(const $classname$& from);\n"
+ ""
+ "using $superclass$::MergeFrom;\n"
+ "void MergeFrom(const $classname$& from);\n"
+ "private:\n"
+ "static void MergeImpl(::$proto_ns$::Message* to, const "
+ "::$proto_ns$::Message& from);\n"
+ "public:\n");
+ } else {
+ format(
+ "using $superclass$::CopyFrom;\n"
+ "inline void CopyFrom(const $classname$& from) {\n"
+ " $superclass$::CopyImpl(this, from);\n"
+ "}\n"
+ ""
+ "using $superclass$::MergeFrom;\n"
+ "void MergeFrom(const $classname$& from) {\n"
+ " $superclass$::MergeImpl(this, from);\n"
+ "}\n"
+ "public:\n");
+ }
+ } else {
+ format(
+ "void CheckTypeAndMergeFrom(const ::$proto_ns$::MessageLite& from)"
+ " final;\n"
+ "void CopyFrom(const $classname$& from);\n"
+ "void MergeFrom(const $classname$& from);\n");
+ }
+
+ if (!HasSimpleBaseClass(descriptor_, options_)) {
+ format(
+ "PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;\n"
+ "bool IsInitialized() const final;\n"
+ "\n"
+ "size_t ByteSizeLong() const final;\n");
+
+ parse_function_generator_->GenerateMethodDecls(printer);
+
+ format(
+ "$uint8$* _InternalSerialize(\n"
+ " $uint8$* target, ::$proto_ns$::io::EpsCopyOutputStream* stream) "
+ "const final;\n");
+ }
+ }
+
+ if (options_.field_listener_options.inject_field_listener_events) {
+ format("static constexpr int _kInternalFieldNumber = $1$;\n",
+ descriptor_->field_count());
+ }
+
+ if (!HasSimpleBaseClass(descriptor_, options_)) {
+ format(
+ "int GetCachedSize() const final { return _cached_size_.Get(); }"
+ "\n\nprivate:\n"
+ "void SharedCtor();\n"
+ "void SharedDtor();\n"
+ "void SetCachedSize(int size) const$ full_final$;\n"
+ "void InternalSwap($classname$* other);\n");
+ }
+
+ format(
+ // Friend AnyMetadata so that it can call this FullMessageName() method.
+ "\nprivate:\n"
+ "friend class ::$proto_ns$::internal::AnyMetadata;\n"
+ "static $1$ FullMessageName() {\n"
+ " return \"$full_name$\";\n"
+ "}\n",
+ options_.opensource_runtime ? "::PROTOBUF_NAMESPACE_ID::StringPiece"
+ : "::StringPiece");
+
+ format(
+ // TODO(gerbens) Make this private! Currently people are deriving from
+ // protos to give access to this constructor, breaking the invariants
+ // we rely on.
+ "protected:\n"
+ "explicit $classname$(::$proto_ns$::Arena* arena,\n"
+ " bool is_message_owned = false);\n"
+ "private:\n");
+
+ if (!HasSimpleBaseClass(descriptor_, options_)) {
+ format(
+ "static void ArenaDtor(void* object);\n"
+ "inline void RegisterArenaDtor(::$proto_ns$::Arena* arena);\n");
+ }
+
+ format(
+ "public:\n"
+ "\n");
+
+ if (HasDescriptorMethods(descriptor_->file(), options_)) {
+ if (HasGeneratedMethods(descriptor_->file(), options_)) {
+ format(
+ "static const ClassData _class_data_;\n"
+ "const ::$proto_ns$::Message::ClassData*"
+ "GetClassData() const final;\n"
+ "\n");
+ }
+ format(
+ "::$proto_ns$::Metadata GetMetadata() const final;\n"
+ "\n");
+ } else {
+ format(
+ "std::string GetTypeName() const final;\n"
+ "\n");
+ }
+
+ format(
+ "// nested types ----------------------------------------------------\n"
+ "\n");
+
+ // Import all nested message classes into this class's scope with typedefs.
+ for (int i = 0; i < descriptor_->nested_type_count(); i++) {
+ const Descriptor* nested_type = descriptor_->nested_type(i);
+ if (!IsMapEntryMessage(nested_type)) {
+ format.Set("nested_full_name", ClassName(nested_type, false));
+ format.Set("nested_name", ResolveKeyword(nested_type->name()));
+ format("typedef ${1$$nested_full_name$$}$ ${1$$nested_name$$}$;\n",
+ nested_type);
+ }
+ }
+
+ if (descriptor_->nested_type_count() > 0) {
+ format("\n");
+ }
+
+ // Import all nested enums and their values into this class's scope with
+ // typedefs and constants.
+ for (int i = 0; i < descriptor_->enum_type_count(); i++) {
+ enum_generators_[i]->GenerateSymbolImports(printer);
+ format("\n");
+ }
+
+ format(
+ "// accessors -------------------------------------------------------\n"
+ "\n");
+
+ // Generate accessor methods for all fields.
+ GenerateFieldAccessorDeclarations(printer);
+
+ // Declare extension identifiers.
+ for (int i = 0; i < descriptor_->extension_count(); i++) {
+ extension_generators_[i]->GenerateDeclaration(printer);
+ }
+
+
+ format("// @@protoc_insertion_point(class_scope:$full_name$)\n");
+
+ // Generate private members.
+ format.Outdent();
+ format(" private:\n");
+ format.Indent();
+ // TODO(seongkim): Remove hack to track field access and remove this class.
+ format("class _Internal;\n");
+
+ for (auto field : FieldRange(descriptor_)) {
+ // set_has_***() generated in all oneofs.
+ if (!field->is_repeated() && !field->options().weak() &&
+ field->real_containing_oneof()) {
+ format("void set_has_$1$();\n", FieldName(field));
+ }
+ }
+ format("\n");
+
+ // Generate oneof function declarations
+ for (auto oneof : OneOfRange(descriptor_)) {
+ format(
+ "inline bool has_$1$() const;\n"
+ "inline void clear_has_$1$();\n\n",
+ oneof->name());
+ }
+
+ if (HasGeneratedMethods(descriptor_->file(), options_) &&
+ !descriptor_->options().message_set_wire_format() &&
+ num_required_fields_ > 1) {
+ format(
+ "// helper for ByteSizeLong()\n"
+ "size_t RequiredFieldsByteSizeFallback() const;\n\n");
+ }
+
+ if (HasGeneratedMethods(descriptor_->file(), options_)) {
+ parse_function_generator_->GenerateDataDecls(printer);
+ }
+
+ // Prepare decls for _cached_size_ and _has_bits_. Their position in the
+ // output will be determined later.
+
+ bool need_to_emit_cached_size = true;
+ const std::string cached_size_decl =
+ "mutable ::$proto_ns$::internal::CachedSize _cached_size_;\n";
+
+ const size_t sizeof_has_bits = HasBitsSize();
+ const std::string has_bits_decl =
+ sizeof_has_bits == 0 ? ""
+ : StrCat("::$proto_ns$::internal::HasBits<",
+ sizeof_has_bits, "> _has_bits_;\n");
+
+ // To minimize padding, data members are divided into three sections:
+ // (1) members assumed to align to 8 bytes
+ // (2) members corresponding to message fields, re-ordered to optimize
+ // alignment.
+ // (3) members assumed to align to 4 bytes.
+
+ // Members assumed to align to 8 bytes:
+
+ if (descriptor_->extension_range_count() > 0) {
+ format(
+ "::$proto_ns$::internal::ExtensionSet _extensions_;\n"
+ "\n");
+ }
+
+ if (options_.field_listener_options.inject_field_listener_events &&
+ descriptor_->file()->options().optimize_for() !=
+ google::protobuf::FileOptions::LITE_RUNTIME) {
+ format("static ::$proto_ns$::AccessListener<$1$> _tracker_;\n",
+ ClassName(descriptor_));
+ }
+
+ // Generate _inlined_string_donated_ for inlined string type.
+ // TODO(congliu): To avoid affecting the locality of `_has_bits_`, should this
+ // be below or above `_has_bits_`?
+ if (!inlined_string_indices_.empty()) {
+ format("::$proto_ns$::internal::HasBits<$1$> _inlined_string_donated_;\n",
+ InlinedStringDonatedSize());
+ }
+
+ format(
+ "template <typename T> friend class "
+ "::$proto_ns$::Arena::InternalHelper;\n"
+ "typedef void InternalArenaConstructable_;\n"
+ "typedef void DestructorSkippable_;\n");
+
+ if (!has_bit_indices_.empty()) {
+ // _has_bits_ is frequently accessed, so to reduce code size and improve
+ // speed, it should be close to the start of the object. Placing
+ // _cached_size_ together with _has_bits_ improves cache locality despite
+ // potential alignment padding.
+ format(has_bits_decl.c_str());
+ format(cached_size_decl.c_str());
+ need_to_emit_cached_size = false;
+ }
+
+ // Field members:
+
+ // Emit some private and static members
+ for (auto field : optimized_order_) {
+ const FieldGenerator& generator = field_generators_.get(field);
+ generator.GenerateStaticMembers(printer);
+ generator.GeneratePrivateMembers(printer);
+ }
+
+ // For each oneof generate a union
+ for (auto oneof : OneOfRange(descriptor_)) {
+ std::string camel_oneof_name = UnderscoresToCamelCase(oneof->name(), true);
+ format("union $1$Union {\n", camel_oneof_name);
+ format.Indent();
+ format(
+ // explicit empty constructor is needed when union contains
+ // ArenaStringPtr members for string fields.
+ "constexpr $1$Union() : _constinit_{} {}\n"
+ " ::$proto_ns$::internal::ConstantInitialized _constinit_;\n",
+ camel_oneof_name);
+ for (auto field : FieldRange(oneof)) {
+ if (!IsFieldStripped(field, options_)) {
+ field_generators_.get(field).GeneratePrivateMembers(printer);
+ }
+ }
+ format.Outdent();
+ format("} $1$_;\n", oneof->name());
+ for (auto field : FieldRange(oneof)) {
+ if (!IsFieldStripped(field, options_)) {
+ field_generators_.get(field).GenerateStaticMembers(printer);
+ }
+ }
+ }
+
+ // Members assumed to align to 4 bytes:
+
+ if (need_to_emit_cached_size) {
+ format(cached_size_decl.c_str());
+ need_to_emit_cached_size = false;
+ }
+
+ // Generate _oneof_case_.
+ if (descriptor_->real_oneof_decl_count() > 0) {
+ format(
+ "$uint32$ _oneof_case_[$1$];\n"
+ "\n",
+ descriptor_->real_oneof_decl_count());
+ }
+
+ if (num_weak_fields_) {
+ format("::$proto_ns$::internal::WeakFieldMap _weak_field_map_;\n");
+ }
+ // Generate _any_metadata_ for the Any type.
+ if (IsAnyMessage(descriptor_, options_)) {
+ format("::$proto_ns$::internal::AnyMetadata _any_metadata_;\n");
+ }
+
+ // The TableStruct struct needs access to the private parts, in order to
+ // construct the offsets of all members.
+ format("friend struct ::$tablename$;\n");
+
+ format.Outdent();
+ format("};");
+ GOOGLE_DCHECK(!need_to_emit_cached_size);
+} // NOLINT(readability/fn_size)
+
+void MessageGenerator::GenerateInlineMethods(io::Printer* printer) {
+ if (IsMapEntryMessage(descriptor_)) return;
+ GenerateFieldAccessorDefinitions(printer);
+
+ // Generate oneof_case() functions.
+ for (auto oneof : OneOfRange(descriptor_)) {
+ Formatter format(printer, variables_);
+ format.Set("camel_oneof_name", UnderscoresToCamelCase(oneof->name(), true));
+ format.Set("oneof_name", oneof->name());
+ format.Set("oneof_index", oneof->index());
+ format(
+ "inline $classname$::$camel_oneof_name$Case $classname$::"
+ "${1$$oneof_name$_case$}$() const {\n"
+ " return $classname$::$camel_oneof_name$Case("
+ "_oneof_case_[$oneof_index$]);\n"
+ "}\n",
+ oneof);
+ }
+}
+
+bool MessageGenerator::GenerateParseTable(io::Printer* printer, size_t offset,
+ size_t aux_offset) {
+ Formatter format(printer, variables_);
+
+ if (!table_driven_) {
+ format("{ nullptr, nullptr, 0, -1, -1, -1, -1, nullptr, false },\n");
+ return false;
+ }
+
+ int max_field_number = 0;
+ for (auto field : FieldRange(descriptor_)) {
+ if (max_field_number < field->number()) {
+ max_field_number = field->number();
+ }
+ }
+
+ format("{\n");
+ format.Indent();
+
+ format(
+ "$tablename$::entries + $1$,\n"
+ "$tablename$::aux + $2$,\n"
+ "$3$,\n",
+ offset, aux_offset, max_field_number);
+
+ if (has_bit_indices_.empty()) {
+ // If no fields have hasbits, then _has_bits_ does not exist.
+ format("-1,\n");
+ } else {
+ format("PROTOBUF_FIELD_OFFSET($classtype$, _has_bits_),\n");
+ }
+
+ if (descriptor_->real_oneof_decl_count() > 0) {
+ format("PROTOBUF_FIELD_OFFSET($classtype$, _oneof_case_),\n");
+ } else {
+ format("-1, // no _oneof_case_\n");
+ }
+
+ if (descriptor_->extension_range_count() > 0) {
+ format("PROTOBUF_FIELD_OFFSET($classtype$, _extensions_),\n");
+ } else {
+ format("-1, // no _extensions_\n");
+ }
+
+ // TODO(ckennelly): Consolidate this with the calculation for
+ // AuxiliaryParseTableField.
+ format(
+ "PROTOBUF_FIELD_OFFSET($classtype$, _internal_metadata_),\n"
+ "&$package_ns$::_$classname$_default_instance_,\n");
+
+ if (UseUnknownFieldSet(descriptor_->file(), options_)) {
+ format("true,\n");
+ } else {
+ format("false,\n");
+ }
+
+ format.Outdent();
+ format("},\n");
+ return true;
+}
+
+void MessageGenerator::GenerateSchema(io::Printer* printer, int offset,
+ int has_offset) {
+ Formatter format(printer, variables_);
+ has_offset = !has_bit_indices_.empty() || IsMapEntryMessage(descriptor_)
+ ? offset + has_offset
+ : -1;
+ int inlined_string_indices_offset;
+ if (inlined_string_indices_.empty()) {
+ inlined_string_indices_offset = -1;
+ } else {
+ GOOGLE_DCHECK_NE(has_offset, -1);
+ GOOGLE_DCHECK(!IsMapEntryMessage(descriptor_));
+ inlined_string_indices_offset = has_offset + has_bit_indices_.size();
+ }
+
+ format("{ $1$, $2$, $3$, sizeof($classtype$)},\n", offset, has_offset,
+ inlined_string_indices_offset);
+}
+
+namespace {
+
+// We need to calculate for each field what function the table driven code
+// should use to serialize it. This returns the index in a lookup table.
+uint32_t CalcFieldNum(const FieldGenerator& generator,
+ const FieldDescriptor* field, const Options& options) {
+ bool is_a_map = IsMapEntryMessage(field->containing_type());
+ int type = field->type();
+ if (type == FieldDescriptor::TYPE_STRING ||
+ type == FieldDescriptor::TYPE_BYTES) {
+ // string field
+ if (generator.IsInlined()) {
+ type = internal::FieldMetadata::kInlinedType;
+ } else if (IsCord(field, options)) {
+ type = internal::FieldMetadata::kCordType;
+ } else if (IsStringPiece(field, options)) {
+ type = internal::FieldMetadata::kStringPieceType;
+ }
+ }
+
+ if (field->real_containing_oneof()) {
+ return internal::FieldMetadata::CalculateType(
+ type, internal::FieldMetadata::kOneOf);
+ } else if (field->is_packed()) {
+ return internal::FieldMetadata::CalculateType(
+ type, internal::FieldMetadata::kPacked);
+ } else if (field->is_repeated()) {
+ return internal::FieldMetadata::CalculateType(
+ type, internal::FieldMetadata::kRepeated);
+ } else if (HasHasbit(field) || field->real_containing_oneof() || is_a_map) {
+ return internal::FieldMetadata::CalculateType(
+ type, internal::FieldMetadata::kPresence);
+ } else {
+ return internal::FieldMetadata::CalculateType(
+ type, internal::FieldMetadata::kNoPresence);
+ }
+}
+
+int FindMessageIndexInFile(const Descriptor* descriptor) {
+ std::vector<const Descriptor*> flatten =
+ FlattenMessagesInFile(descriptor->file());
+ return std::find(flatten.begin(), flatten.end(), descriptor) -
+ flatten.begin();
+}
+
+} // namespace
+
+int MessageGenerator::GenerateFieldMetadata(io::Printer* printer) {
+ Formatter format(printer, variables_);
+ if (!options_.table_driven_serialization) {
+ return 0;
+ }
+
+ std::vector<const FieldDescriptor*> sorted = SortFieldsByNumber(descriptor_);
+ if (IsMapEntryMessage(descriptor_)) {
+ for (int i = 0; i < 2; i++) {
+ const FieldDescriptor* field = sorted[i];
+ const FieldGenerator& generator = field_generators_.get(field);
+
+ uint32_t tag = internal::WireFormatLite::MakeTag(
+ field->number(), WireFormat::WireTypeForFieldType(field->type()));
+
+ std::map<std::string, std::string> vars;
+ vars["classtype"] = QualifiedClassName(descriptor_, options_);
+ vars["field_name"] = FieldName(field);
+ vars["tag"] = StrCat(tag);
+ vars["hasbit"] = StrCat(i);
+ vars["type"] = StrCat(CalcFieldNum(generator, field, options_));
+ vars["ptr"] = "nullptr";
+ if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+ GOOGLE_CHECK(!IsMapEntryMessage(field->message_type()));
+ vars["ptr"] =
+ "::" + UniqueName("TableStruct", field->message_type(), options_) +
+ "::serialization_table + " +
+ StrCat(FindMessageIndexInFile(field->message_type()));
+ }
+ Formatter::SaveState saver(&format);
+ format.AddMap(vars);
+ format(
+ "{PROTOBUF_FIELD_OFFSET("
+ "::$proto_ns$::internal::MapEntryHelper<$classtype$::"
+ "SuperType>, $field_name$_), $tag$,"
+ "PROTOBUF_FIELD_OFFSET("
+ "::$proto_ns$::internal::MapEntryHelper<$classtype$::"
+ "SuperType>, _has_bits_) * 8 + $hasbit$, $type$, "
+ "$ptr$},\n");
+ }
+ return 2;
+ }
+ format(
+ "{PROTOBUF_FIELD_OFFSET($classtype$, _cached_size_),"
+ " 0, 0, 0, nullptr},\n");
+ std::vector<const Descriptor::ExtensionRange*> sorted_extensions;
+ sorted_extensions.reserve(descriptor_->extension_range_count());
+ for (int i = 0; i < descriptor_->extension_range_count(); ++i) {
+ sorted_extensions.push_back(descriptor_->extension_range(i));
+ }
+ std::sort(sorted_extensions.begin(), sorted_extensions.end(),
+ ExtensionRangeSorter());
+ for (int i = 0, extension_idx = 0; /* no range */; i++) {
+ for (; extension_idx < sorted_extensions.size() &&
+ (i == sorted.size() ||
+ sorted_extensions[extension_idx]->start < sorted[i]->number());
+ extension_idx++) {
+ const Descriptor::ExtensionRange* range =
+ sorted_extensions[extension_idx];
+ format(
+ "{PROTOBUF_FIELD_OFFSET($classtype$, _extensions_), "
+ "$1$, $2$, ::$proto_ns$::internal::FieldMetadata::kSpecial, "
+ "reinterpret_cast<const "
+ "void*>(::$proto_ns$::internal::ExtensionSerializer)},\n",
+ range->start, range->end);
+ }
+ if (i == sorted.size()) break;
+ const FieldDescriptor* field = sorted[i];
+
+ uint32_t tag = internal::WireFormatLite::MakeTag(
+ field->number(), WireFormat::WireTypeForFieldType(field->type()));
+ if (field->is_packed()) {
+ tag = internal::WireFormatLite::MakeTag(
+ field->number(), WireFormatLite::WIRETYPE_LENGTH_DELIMITED);
+ }
+
+ std::string classfieldname = FieldName(field);
+ if (field->real_containing_oneof()) {
+ classfieldname = field->containing_oneof()->name();
+ }
+ format.Set("field_name", classfieldname);
+ std::string ptr = "nullptr";
+ if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+ if (IsMapEntryMessage(field->message_type())) {
+ format(
+ "{PROTOBUF_FIELD_OFFSET($classtype$, $field_name$_), $1$, $2$, "
+ "::$proto_ns$::internal::FieldMetadata::kSpecial, "
+ "reinterpret_cast<const void*>(static_cast< "
+ "::$proto_ns$::internal::SpecialSerializer>("
+ "::$proto_ns$::internal::MapFieldSerializer< "
+ "::$proto_ns$::internal::MapEntryToMapField<"
+ "$3$>::MapFieldType, "
+ "$tablename$::serialization_table>))},\n",
+ tag, FindMessageIndexInFile(field->message_type()),
+ QualifiedClassName(field->message_type(), options_));
+ continue;
+ } else if (!field->message_type()->options().message_set_wire_format()) {
+ // message_set doesn't have the usual table and we need to
+ // dispatch to generated serializer, hence ptr stays zero.
+ ptr =
+ "::" + UniqueName("TableStruct", field->message_type(), options_) +
+ "::serialization_table + " +
+ StrCat(FindMessageIndexInFile(field->message_type()));
+ }
+ }
+
+ const FieldGenerator& generator = field_generators_.get(field);
+ int type = CalcFieldNum(generator, field, options_);
+
+ if (IsLazy(field, options_, scc_analyzer_)) {
+ type = internal::FieldMetadata::kSpecial;
+ ptr = "reinterpret_cast<const void*>(::" + variables_["proto_ns"] +
+ "::internal::LazyFieldSerializer";
+ if (field->real_containing_oneof()) {
+ ptr += "OneOf";
+ } else if (!HasHasbit(field)) {
+ ptr += "NoPresence";
+ }
+ ptr += ")";
+ }
+
+ if (field->options().weak()) {
+ // TODO(gerbens) merge weak fields into ranges
+ format(
+ "{PROTOBUF_FIELD_OFFSET("
+ "$classtype$, _weak_field_map_), $1$, $1$, "
+ "::$proto_ns$::internal::FieldMetadata::kSpecial, "
+ "reinterpret_cast<const "
+ "void*>(::$proto_ns$::internal::WeakFieldSerializer)},\n",
+ tag);
+ } else if (field->real_containing_oneof()) {
+ format.Set("oneofoffset",
+ sizeof(uint32_t) * field->containing_oneof()->index());
+ format(
+ "{PROTOBUF_FIELD_OFFSET($classtype$, $field_name$_), $1$,"
+ " PROTOBUF_FIELD_OFFSET($classtype$, _oneof_case_) + "
+ "$oneofoffset$, $2$, $3$},\n",
+ tag, type, ptr);
+ } else if (HasHasbit(field)) {
+ format.Set("hasbitsoffset", has_bit_indices_[field->index()]);
+ format(
+ "{PROTOBUF_FIELD_OFFSET($classtype$, $field_name$_), "
+ "$1$, PROTOBUF_FIELD_OFFSET($classtype$, _has_bits_) * 8 + "
+ "$hasbitsoffset$, $2$, $3$},\n",
+ tag, type, ptr);
+ } else {
+ format(
+ "{PROTOBUF_FIELD_OFFSET($classtype$, $field_name$_), "
+ "$1$, ~0u, $2$, $3$},\n",
+ tag, type, ptr);
+ }
+ }
+ int num_field_metadata = 1 + sorted.size() + sorted_extensions.size();
+ num_field_metadata++;
+ std::string serializer = UseUnknownFieldSet(descriptor_->file(), options_)
+ ? "UnknownFieldSetSerializer"
+ : "UnknownFieldSerializerLite";
+ format(
+ "{PROTOBUF_FIELD_OFFSET($classtype$, _internal_metadata_), 0, ~0u, "
+ "::$proto_ns$::internal::FieldMetadata::kSpecial, reinterpret_cast<const "
+ "void*>(::$proto_ns$::internal::$1$)},\n",
+ serializer);
+ return num_field_metadata;
+}
+
+void MessageGenerator::GenerateClassMethods(io::Printer* printer) {
+ Formatter format(printer, variables_);
+ if (IsMapEntryMessage(descriptor_)) {
+ format(
+ "$classname$::$classname$() {}\n"
+ "$classname$::$classname$(::$proto_ns$::Arena* arena)\n"
+ " : SuperType(arena) {}\n"
+ "void $classname$::MergeFrom(const $classname$& other) {\n"
+ " MergeFromInternal(other);\n"
+ "}\n");
+ if (HasDescriptorMethods(descriptor_->file(), options_)) {
+ if (!descriptor_->options().map_entry()) {
+ format(
+ "::$proto_ns$::Metadata $classname$::GetMetadata() const {\n"
+ "$annotate_reflection$"
+ " return ::$proto_ns$::internal::AssignDescriptors(\n"
+ " &$desc_table$_getter, &$desc_table$_once,\n"
+ " $file_level_metadata$[$1$]);\n"
+ "}\n",
+ index_in_file_messages_);
+ } else {
+ format(
+ "::$proto_ns$::Metadata $classname$::GetMetadata() const {\n"
+ " return ::$proto_ns$::internal::AssignDescriptors(\n"
+ " &$desc_table$_getter, &$desc_table$_once,\n"
+ " $file_level_metadata$[$1$]);\n"
+ "}\n",
+ index_in_file_messages_);
+ }
+ }
+ return;
+ }
+
+ if (IsAnyMessage(descriptor_, options_)) {
+ if (HasDescriptorMethods(descriptor_->file(), options_)) {
+ format(
+ "bool $classname$::GetAnyFieldDescriptors(\n"
+ " const ::$proto_ns$::Message& message,\n"
+ " const ::$proto_ns$::FieldDescriptor** type_url_field,\n"
+ " const ::$proto_ns$::FieldDescriptor** value_field) {\n"
+ " return ::$proto_ns$::internal::GetAnyFieldDescriptors(\n"
+ " message, type_url_field, value_field);\n"
+ "}\n");
+ }
+ format(
+ "bool $classname$::ParseAnyTypeUrl(\n"
+ " ::PROTOBUF_NAMESPACE_ID::ConstStringParam type_url,\n"
+ " std::string* full_type_name) {\n"
+ " return ::$proto_ns$::internal::ParseAnyTypeUrl(type_url,\n"
+ " full_type_name);\n"
+ "}\n"
+ "\n");
+ }
+
+ format(
+ "class $classname$::_Internal {\n"
+ " public:\n");
+ format.Indent();
+ if (!has_bit_indices_.empty()) {
+ format(
+ "using HasBits = decltype(std::declval<$classname$>()._has_bits_);\n");
+ }
+ for (auto field : FieldRange(descriptor_)) {
+ field_generators_.get(field).GenerateInternalAccessorDeclarations(printer);
+ if (IsFieldStripped(field, options_)) {
+ continue;
+ }
+ if (HasHasbit(field)) {
+ int has_bit_index = HasBitIndex(field);
+ GOOGLE_CHECK_NE(has_bit_index, kNoHasbit) << field->full_name();
+ format(
+ "static void set_has_$1$(HasBits* has_bits) {\n"
+ " (*has_bits)[$2$] |= $3$u;\n"
+ "}\n",
+ FieldName(field), has_bit_index / 32, (1u << (has_bit_index % 32)));
+ }
+ }
+ if (num_required_fields_ > 0) {
+ const std::vector<uint32_t> masks_for_has_bits = RequiredFieldsBitMask();
+ format(
+ "static bool MissingRequiredFields(const HasBits& has_bits) "
+ "{\n"
+ " return $1$;\n"
+ "}\n",
+ ConditionalToCheckBitmasks(masks_for_has_bits, false, "has_bits"));
+ }
+
+ format.Outdent();
+ format("};\n\n");
+ for (auto field : FieldRange(descriptor_)) {
+ if (!IsFieldStripped(field, options_)) {
+ field_generators_.get(field).GenerateInternalAccessorDefinitions(printer);
+ }
+ }
+
+ // Generate non-inline field definitions.
+ for (auto field : FieldRange(descriptor_)) {
+ if (IsFieldStripped(field, options_)) {
+ continue;
+ }
+ field_generators_.get(field).GenerateNonInlineAccessorDefinitions(printer);
+ if (IsCrossFileMaybeMap(field)) {
+ Formatter::SaveState saver(&format);
+ std::map<std::string, std::string> vars;
+ SetCommonFieldVariables(field, &vars, options_);
+ if (field->real_containing_oneof()) {
+ SetCommonOneofFieldVariables(field, &vars);
+ }
+ format.AddMap(vars);
+ GenerateFieldClear(field, false, format);
+ }
+ }
+
+ GenerateStructors(printer);
+ format("\n");
+
+ if (descriptor_->real_oneof_decl_count() > 0) {
+ GenerateOneofClear(printer);
+ format("\n");
+ }
+
+ if (HasGeneratedMethods(descriptor_->file(), options_)) {
+ GenerateClear(printer);
+ format("\n");
+
+ if (!HasSimpleBaseClass(descriptor_, options_)) {
+ parse_function_generator_->GenerateMethodImpls(printer);
+ format("\n");
+
+ parse_function_generator_->GenerateDataDefinitions(printer);
+ }
+
+ GenerateSerializeWithCachedSizesToArray(printer);
+ format("\n");
+
+ GenerateByteSize(printer);
+ format("\n");
+
+ GenerateMergeFrom(printer);
+ format("\n");
+
+ GenerateClassSpecificMergeFrom(printer);
+ format("\n");
+
+ GenerateCopyFrom(printer);
+ format("\n");
+
+ GenerateIsInitialized(printer);
+ format("\n");
+ }
+
+ GenerateVerify(printer);
+
+ GenerateSwap(printer);
+ format("\n");
+
+ if (options_.table_driven_serialization) {
+ format(
+ "const void* $classname$::InternalGetTable() const {\n"
+ " return ::$tablename$::serialization_table + $1$;\n"
+ "}\n"
+ "\n",
+ index_in_file_messages_);
+ }
+ if (HasDescriptorMethods(descriptor_->file(), options_)) {
+ if (!descriptor_->options().map_entry()) {
+ format(
+ "::$proto_ns$::Metadata $classname$::GetMetadata() const {\n"
+ "$annotate_reflection$"
+ " return ::$proto_ns$::internal::AssignDescriptors(\n"
+ " &$desc_table$_getter, &$desc_table$_once,\n"
+ " $file_level_metadata$[$1$]);\n"
+ "}\n",
+ index_in_file_messages_);
+ } else {
+ format(
+ "::$proto_ns$::Metadata $classname$::GetMetadata() const {\n"
+ " return ::$proto_ns$::internal::AssignDescriptors(\n"
+ " &$desc_table$_getter, &$desc_table$_once,\n"
+ " $file_level_metadata$[$1$]);\n"
+ "}\n",
+ index_in_file_messages_);
+ }
+ } else {
+ format(
+ "std::string $classname$::GetTypeName() const {\n"
+ " return \"$full_name$\";\n"
+ "}\n"
+ "\n");
+ }
+
+ if (options_.field_listener_options.inject_field_listener_events &&
+ descriptor_->file()->options().optimize_for() !=
+ google::protobuf::FileOptions::LITE_RUNTIME) {
+ format(
+ "::$proto_ns$::AccessListener<$classtype$> "
+ "$1$::_tracker_(&FullMessageName);\n",
+ ClassName(descriptor_));
+ }
+}
+
+size_t MessageGenerator::GenerateParseOffsets(io::Printer* printer) {
+ Formatter format(printer, variables_);
+
+ if (!table_driven_) {
+ return 0;
+ }
+
+ // Field "0" is special: We use it in our switch statement of processing
+ // types to handle the successful end tag case.
+ format("{0, 0, 0, ::$proto_ns$::internal::kInvalidMask, 0, 0},\n");
+ int last_field_number = 1;
+
+ std::vector<const FieldDescriptor*> ordered_fields =
+ SortFieldsByNumber(descriptor_);
+
+ for (auto field : ordered_fields) {
+ Formatter::SaveState saver(&format);
+ GOOGLE_CHECK_GE(field->number(), last_field_number);
+
+ for (; last_field_number < field->number(); last_field_number++) {
+ format(
+ "{ 0, 0, ::$proto_ns$::internal::kInvalidMask,\n"
+ " ::$proto_ns$::internal::kInvalidMask, 0, 0 },\n");
+ }
+ last_field_number++;
+
+ unsigned char normal_wiretype, packed_wiretype, processing_type;
+ normal_wiretype = WireFormat::WireTypeForFieldType(field->type());
+
+ if (field->is_packable()) {
+ packed_wiretype = WireFormatLite::WIRETYPE_LENGTH_DELIMITED;
+ } else {
+ packed_wiretype = internal::kNotPackedMask;
+ }
+
+ processing_type = static_cast<unsigned>(field->type());
+ const FieldGenerator& generator = field_generators_.get(field);
+ if (field->type() == FieldDescriptor::TYPE_STRING) {
+ switch (EffectiveStringCType(field, options_)) {
+ case FieldOptions::STRING:
+ if (generator.IsInlined()) {
+ processing_type = internal::TYPE_STRING_INLINED;
+ }
+ break;
+ case FieldOptions::CORD:
+ processing_type = internal::TYPE_STRING_CORD;
+ break;
+ case FieldOptions::STRING_PIECE:
+ processing_type = internal::TYPE_STRING_STRING_PIECE;
+ break;
+ }
+ } else if (field->type() == FieldDescriptor::TYPE_BYTES) {
+ switch (EffectiveStringCType(field, options_)) {
+ case FieldOptions::STRING:
+ if (generator.IsInlined()) {
+ processing_type = internal::TYPE_BYTES_INLINED;
+ }
+ break;
+ case FieldOptions::CORD:
+ processing_type = internal::TYPE_BYTES_CORD;
+ break;
+ case FieldOptions::STRING_PIECE:
+ processing_type = internal::TYPE_BYTES_STRING_PIECE;
+ break;
+ }
+ }
+
+ processing_type |= static_cast<unsigned>(
+ field->is_repeated() ? internal::kRepeatedMask : 0);
+ processing_type |= static_cast<unsigned>(
+ field->real_containing_oneof() ? internal::kOneofMask : 0);
+
+ if (field->is_map()) {
+ processing_type = internal::TYPE_MAP;
+ }
+
+ const unsigned char tag_size =
+ WireFormat::TagSize(field->number(), field->type());
+
+ std::map<std::string, std::string> vars;
+ if (field->real_containing_oneof()) {
+ vars["name"] = field->containing_oneof()->name();
+ vars["presence"] = StrCat(field->containing_oneof()->index());
+ } else {
+ vars["name"] = FieldName(field);
+ vars["presence"] = StrCat(has_bit_indices_[field->index()]);
+ }
+ vars["nwtype"] = StrCat(normal_wiretype);
+ vars["pwtype"] = StrCat(packed_wiretype);
+ vars["ptype"] = StrCat(processing_type);
+ vars["tag_size"] = StrCat(tag_size);
+
+ format.AddMap(vars);
+
+ format(
+ "{\n"
+ " PROTOBUF_FIELD_OFFSET($classtype$, $name$_),\n"
+ " static_cast<$uint32$>($presence$),\n"
+ " $nwtype$, $pwtype$, $ptype$, $tag_size$\n"
+ "},\n");
+ }
+
+ return last_field_number;
+}
+
+size_t MessageGenerator::GenerateParseAuxTable(io::Printer* printer) {
+ Formatter format(printer, variables_);
+
+ if (!table_driven_) {
+ return 0;
+ }
+
+ std::vector<const FieldDescriptor*> ordered_fields =
+ SortFieldsByNumber(descriptor_);
+
+ format("::$proto_ns$::internal::AuxiliaryParseTableField(),\n");
+ int last_field_number = 1;
+ for (auto field : ordered_fields) {
+ Formatter::SaveState saver(&format);
+
+ GOOGLE_CHECK_GE(field->number(), last_field_number);
+ for (; last_field_number < field->number(); last_field_number++) {
+ format("::$proto_ns$::internal::AuxiliaryParseTableField(),\n");
+ }
+
+ std::map<std::string, std::string> vars;
+ SetCommonFieldVariables(field, &vars, options_);
+ format.AddMap(vars);
+
+ switch (field->cpp_type()) {
+ case FieldDescriptor::CPPTYPE_ENUM:
+ if (HasPreservingUnknownEnumSemantics(field)) {
+ format(
+ "{::$proto_ns$::internal::AuxiliaryParseTableField::enum_aux{"
+ "nullptr}},\n");
+ } else {
+ format(
+ "{::$proto_ns$::internal::AuxiliaryParseTableField::enum_aux{"
+ "$1$_IsValid}},\n",
+ ClassName(field->enum_type(), true));
+ }
+ last_field_number++;
+ break;
+ case FieldDescriptor::CPPTYPE_MESSAGE: {
+ if (field->is_map()) {
+ format(
+ "{::$proto_ns$::internal::AuxiliaryParseTableField::map_"
+ "aux{&::$proto_ns$::internal::ParseMap<$1$>}},\n",
+ QualifiedClassName(field->message_type(), options_));
+ last_field_number++;
+ break;
+ }
+ format.Set("field_classname", ClassName(field->message_type(), false));
+ format.Set("default_instance", QualifiedDefaultInstanceName(
+ field->message_type(), options_));
+
+ format(
+ "{::$proto_ns$::internal::AuxiliaryParseTableField::message_aux{\n"
+ " &$default_instance$}},\n");
+ last_field_number++;
+ break;
+ }
+ case FieldDescriptor::CPPTYPE_STRING: {
+ std::string default_val;
+ switch (EffectiveStringCType(field, options_)) {
+ case FieldOptions::STRING:
+ default_val = field->default_value_string().empty()
+ ? "&::" + variables_["proto_ns"] +
+ "::internal::fixed_address_empty_string"
+ : "&" +
+ QualifiedClassName(descriptor_, options_) +
+ "::" + MakeDefaultName(field);
+ break;
+ case FieldOptions::CORD:
+ case FieldOptions::STRING_PIECE:
+ default_val =
+ "\"" + CEscape(field->default_value_string()) + "\"";
+ break;
+ }
+ format(
+ "{::$proto_ns$::internal::AuxiliaryParseTableField::string_aux{\n"
+ " $1$,\n"
+ " \"$2$\"\n"
+ "}},\n",
+ default_val, field->full_name());
+ last_field_number++;
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+ return last_field_number;
+}
+
+std::pair<size_t, size_t> MessageGenerator::GenerateOffsets(
+ io::Printer* printer) {
+ Formatter format(printer, variables_);
+
+ if (!has_bit_indices_.empty() || IsMapEntryMessage(descriptor_)) {
+ format("PROTOBUF_FIELD_OFFSET($classtype$, _has_bits_),\n");
+ } else {
+ format("~0u, // no _has_bits_\n");
+ }
+ format("PROTOBUF_FIELD_OFFSET($classtype$, _internal_metadata_),\n");
+ if (descriptor_->extension_range_count() > 0) {
+ format("PROTOBUF_FIELD_OFFSET($classtype$, _extensions_),\n");
+ } else {
+ format("~0u, // no _extensions_\n");
+ }
+ if (descriptor_->real_oneof_decl_count() > 0) {
+ format("PROTOBUF_FIELD_OFFSET($classtype$, _oneof_case_[0]),\n");
+ } else {
+ format("~0u, // no _oneof_case_\n");
+ }
+ if (num_weak_fields_ > 0) {
+ format("PROTOBUF_FIELD_OFFSET($classtype$, _weak_field_map_),\n");
+ } else {
+ format("~0u, // no _weak_field_map_\n");
+ }
+ if (!inlined_string_indices_.empty()) {
+ format("PROTOBUF_FIELD_OFFSET($classtype$, _inlined_string_donated_),\n");
+ } else {
+ format("~0u, // no _inlined_string_donated_\n");
+ }
+ const int kNumGenericOffsets = 6; // the number of fixed offsets above
+ const size_t offsets = kNumGenericOffsets + descriptor_->field_count() +
+ descriptor_->real_oneof_decl_count();
+ size_t entries = offsets;
+ for (auto field : FieldRange(descriptor_)) {
+ if (IsFieldStripped(field, options_)) {
+ format("~0u, // stripped\n");
+ continue;
+ }
+ // TODO(sbenza): We should not have an entry in the offset table for fields
+ // that do not use them.
+ if (field->options().weak() || field->real_containing_oneof()) {
+ // Mark the field to prevent unintentional access through reflection.
+ // Don't use the top bit because that is for unused fields.
+ format("::$proto_ns$::internal::kInvalidFieldOffsetTag");
+ } else {
+ format("PROTOBUF_FIELD_OFFSET($classtype$, $1$_)", FieldName(field));
+ }
+
+ // Some information about a field is in the pdproto profile. The profile is
+ // only available at compile time. So we embed such information in the
+ // offset of the field, so that the information is available when
+ // reflectively accessing the field at run time.
+ //
+ // Embed whether the field is used to the MSB of the offset.
+ if (!IsFieldUsed(field, options_)) {
+ format(" | 0x80000000u // unused\n");
+ }
+
+ // Embed whether the field is eagerly verified lazy or inlined string to the
+ // LSB of the offset.
+ if (IsEagerlyVerifiedLazy(field, options_, scc_analyzer_)) {
+ format(" | 0x1u // eagerly verified lazy\n");
+ } else if (IsStringInlined(field, options_)) {
+ format(" | 0x1u // inlined\n");
+ }
+ format(",\n");
+ }
+
+ int count = 0;
+ for (auto oneof : OneOfRange(descriptor_)) {
+ format("PROTOBUF_FIELD_OFFSET($classtype$, $1$_),\n", oneof->name());
+ count++;
+ }
+ GOOGLE_CHECK_EQ(count, descriptor_->real_oneof_decl_count());
+
+ if (IsMapEntryMessage(descriptor_)) {
+ entries += 2;
+ format(
+ "0,\n"
+ "1,\n");
+ } else if (!has_bit_indices_.empty()) {
+ entries += has_bit_indices_.size();
+ for (int i = 0; i < has_bit_indices_.size(); i++) {
+ const std::string index =
+ has_bit_indices_[i] >= 0 ? StrCat(has_bit_indices_[i]) : "~0u";
+ format("$1$,\n", index);
+ }
+ }
+ if (!inlined_string_indices_.empty()) {
+ entries += inlined_string_indices_.size();
+ for (int inlined_string_indice : inlined_string_indices_) {
+ const std::string index = inlined_string_indice >= 0
+ ? StrCat(inlined_string_indice)
+ : "~0u";
+ format("$1$,\n", index);
+ }
+ }
+
+ return std::make_pair(entries, offsets);
+}
+
+void MessageGenerator::GenerateSharedConstructorCode(io::Printer* printer) {
+ if (HasSimpleBaseClass(descriptor_, options_)) return;
+ Formatter format(printer, variables_);
+
+ format("inline void $classname$::SharedCtor() {\n");
+
+ std::vector<bool> processed(optimized_order_.size(), false);
+ GenerateConstructorBody(printer, processed, false);
+
+ for (auto oneof : OneOfRange(descriptor_)) {
+ format("clear_has_$1$();\n", oneof->name());
+ }
+
+ format("}\n\n");
+}
+
+void MessageGenerator::GenerateSharedDestructorCode(io::Printer* printer) {
+ if (HasSimpleBaseClass(descriptor_, options_)) return;
+ Formatter format(printer, variables_);
+
+ format("inline void $classname$::SharedDtor() {\n");
+ format.Indent();
+ format("$DCHK$(GetArenaForAllocation() == nullptr);\n");
+ // Write the destructors for each field except oneof members.
+ // optimized_order_ does not contain oneof fields.
+ for (auto field : optimized_order_) {
+ field_generators_.get(field).GenerateDestructorCode(printer);
+ }
+
+ // Generate code to destruct oneofs. Clearing should do the work.
+ for (auto oneof : OneOfRange(descriptor_)) {
+ format(
+ "if (has_$1$()) {\n"
+ " clear_$1$();\n"
+ "}\n",
+ oneof->name());
+ }
+
+ if (num_weak_fields_) {
+ format("_weak_field_map_.ClearAll();\n");
+ }
+ format.Outdent();
+ format(
+ "}\n"
+ "\n");
+}
+
+void MessageGenerator::GenerateArenaDestructorCode(io::Printer* printer) {
+ if (HasSimpleBaseClass(descriptor_, options_)) return;
+ Formatter format(printer, variables_);
+
+ // Generate the ArenaDtor() method. Track whether any fields actually produced
+ // code that needs to be called.
+ format("void $classname$::ArenaDtor(void* object) {\n");
+ format.Indent();
+
+ // This code is placed inside a static method, rather than an ordinary one,
+ // since that simplifies Arena's destructor list (ordinary function pointers
+ // rather than member function pointers). _this is the object being
+ // destructed.
+ format(
+ "$classname$* _this = reinterpret_cast< $classname$* >(object);\n"
+ // avoid an "unused variable" warning in case no fields have dtor code.
+ "(void)_this;\n");
+
+ bool need_registration = false;
+ // Process non-oneof fields first.
+ for (auto field : optimized_order_) {
+ if (field_generators_.get(field).GenerateArenaDestructorCode(printer)) {
+ need_registration = true;
+ }
+ }
+
+ // Process oneof fields.
+ //
+ // Note: As of 10/5/2016, GenerateArenaDestructorCode does not emit anything
+ // and returns false for oneof fields.
+ for (auto oneof : OneOfRange(descriptor_)) {
+ for (auto field : FieldRange(oneof)) {
+ if (!IsFieldStripped(field, options_) &&
+ field_generators_.get(field).GenerateArenaDestructorCode(printer)) {
+ need_registration = true;
+ }
+ }
+ }
+
+ format.Outdent();
+ format("}\n");
+
+ if (need_registration) {
+ format(
+ "inline void $classname$::RegisterArenaDtor(::$proto_ns$::Arena* "
+ "arena) {\n"
+ " if (arena != nullptr) {\n"
+ " arena->OwnCustomDestructor(this, &$classname$::ArenaDtor);\n"
+ " }\n"
+ "}\n");
+ } else {
+ format(
+ "void $classname$::RegisterArenaDtor(::$proto_ns$::Arena*) {\n"
+ "}\n");
+ }
+}
+
+void MessageGenerator::GenerateConstexprConstructor(io::Printer* printer) {
+ Formatter format(printer, variables_);
+
+ format(
+ "constexpr $classname$::$classname$(\n"
+ " ::$proto_ns$::internal::ConstantInitialized)");
+ format.Indent();
+ const char* field_sep = ":";
+ const auto put_sep = [&] {
+ format("\n$1$ ", field_sep);
+ field_sep = ",";
+ };
+
+ if (!IsMapEntryMessage(descriptor_)) {
+ // Process non-oneof fields first.
+ for (auto field : optimized_order_) {
+ auto& gen = field_generators_.get(field);
+ put_sep();
+ gen.GenerateConstinitInitializer(printer);
+ }
+
+ if (IsAnyMessage(descriptor_, options_)) {
+ put_sep();
+ format("_any_metadata_(&type_url_, &value_)");
+ }
+
+ if (descriptor_->real_oneof_decl_count() != 0) {
+ put_sep();
+ format("_oneof_case_{}");
+ }
+ }
+
+ format.Outdent();
+ format("{}\n");
+}
+
+void MessageGenerator::GenerateConstructorBody(io::Printer* printer,
+ std::vector<bool> processed,
+ bool copy_constructor) const {
+ Formatter format(printer, variables_);
+
+ const RunMap runs = FindRuns(
+ optimized_order_, [copy_constructor, this](const FieldDescriptor* field) {
+ return (copy_constructor && IsPOD(field)) ||
+ (!copy_constructor &&
+ CanBeManipulatedAsRawBytes(field, options_, scc_analyzer_));
+ });
+
+ std::string pod_template;
+ if (copy_constructor) {
+ pod_template =
+ "::memcpy(&$first$_, &from.$first$_,\n"
+ " static_cast<size_t>(reinterpret_cast<char*>(&$last$_) -\n"
+ " reinterpret_cast<char*>(&$first$_)) + sizeof($last$_));\n";
+ } else {
+ pod_template =
+ "::memset(reinterpret_cast<char*>(this) + static_cast<size_t>(\n"
+ " reinterpret_cast<char*>(&$first$_) - "
+ "reinterpret_cast<char*>(this)),\n"
+ " 0, static_cast<size_t>(reinterpret_cast<char*>(&$last$_) -\n"
+ " reinterpret_cast<char*>(&$first$_)) + sizeof($last$_));\n";
+ }
+
+ for (int i = 0; i < optimized_order_.size(); ++i) {
+ if (processed[i]) {
+ continue;
+ }
+
+ const FieldDescriptor* field = optimized_order_[i];
+ const auto it = runs.find(field);
+
+ // We only apply the memset technique to runs of more than one field, as
+ // assignment is better than memset for generated code clarity.
+ if (it != runs.end() && it->second > 1) {
+ // Use a memset, then skip run_length fields.
+ const size_t run_length = it->second;
+ const std::string first_field_name = FieldName(field);
+ const std::string last_field_name =
+ FieldName(optimized_order_[i + run_length - 1]);
+
+ format.Set("first", first_field_name);
+ format.Set("last", last_field_name);
+
+ format(pod_template.c_str());
+
+ i += run_length - 1;
+ // ++i at the top of the loop.
+ } else {
+ if (copy_constructor) {
+ field_generators_.get(field).GenerateCopyConstructorCode(printer);
+ } else {
+ field_generators_.get(field).GenerateConstructorCode(printer);
+ }
+ }
+ }
+}
+
+void MessageGenerator::GenerateStructors(io::Printer* printer) {
+ Formatter format(printer, variables_);
+
+ std::string superclass;
+ superclass = SuperClassName(descriptor_, options_);
+ std::string initializer_with_arena = superclass + "(arena, is_message_owned)";
+
+ if (descriptor_->extension_range_count() > 0) {
+ initializer_with_arena += ",\n _extensions_(arena)";
+ }
+
+ // Initialize member variables with arena constructor.
+ for (auto field : optimized_order_) {
+ GOOGLE_DCHECK(!IsFieldStripped(field, options_));
+ bool has_arena_constructor = field->is_repeated();
+ if (!field->real_containing_oneof() &&
+ (IsLazy(field, options_, scc_analyzer_) ||
+ IsStringPiece(field, options_) ||
+ (IsString(field, options_) && IsStringInlined(field, options_)))) {
+ has_arena_constructor = true;
+ }
+ if (has_arena_constructor) {
+ initializer_with_arena +=
+ std::string(",\n ") + FieldName(field) + std::string("_(arena)");
+ }
+ }
+
+ if (IsAnyMessage(descriptor_, options_)) {
+ initializer_with_arena += ",\n _any_metadata_(&type_url_, &value_)";
+ }
+ if (num_weak_fields_ > 0) {
+ initializer_with_arena += ", _weak_field_map_(arena)";
+ }
+
+ std::string initializer_null = superclass + "()";
+ if (IsAnyMessage(descriptor_, options_)) {
+ initializer_null += ", _any_metadata_(&type_url_, &value_)";
+ }
+ if (num_weak_fields_ > 0) {
+ initializer_null += ", _weak_field_map_(nullptr)";
+ }
+
+ format(
+ "$classname$::$classname$(::$proto_ns$::Arena* arena,\n"
+ " bool is_message_owned)\n"
+ " : $1$ {\n",
+ initializer_with_arena);
+
+ if (!inlined_string_indices_.empty()) {
+ // Donate inline string fields.
+ format(" if (arena != nullptr) {\n");
+ for (size_t i = 0; i < InlinedStringDonatedSize(); ++i) {
+ format(" _inlined_string_donated_[$1$] = ~0u;\n", i);
+ }
+ format(" }\n");
+ }
+
+ if (!HasSimpleBaseClass(descriptor_, options_)) {
+ format(
+ " SharedCtor();\n"
+ " if (!is_message_owned) {\n"
+ " RegisterArenaDtor(arena);\n"
+ " }\n");
+ }
+ format(
+ " // @@protoc_insertion_point(arena_constructor:$full_name$)\n"
+ "}\n");
+
+ std::map<std::string, std::string> vars;
+ SetUnknownFieldsVariable(descriptor_, options_, &vars);
+ format.AddMap(vars);
+
+ // Generate the copy constructor.
+ if (UsingImplicitWeakFields(descriptor_->file(), options_)) {
+ // If we are in lite mode and using implicit weak fields, we generate a
+ // one-liner copy constructor that delegates to MergeFrom. This saves some
+ // code size and also cuts down on the complexity of implicit weak fields.
+ // We might eventually want to do this for all lite protos.
+ format(
+ "$classname$::$classname$(const $classname$& from)\n"
+ " : $classname$() {\n"
+ " MergeFrom(from);\n"
+ "}\n");
+ } else {
+ format(
+ "$classname$::$classname$(const $classname$& from)\n"
+ " : $superclass$()");
+ format.Indent();
+ format.Indent();
+ format.Indent();
+
+ // Do not copy inlined_string_donated_, because this is not an arena
+ // constructor.
+
+ if (!has_bit_indices_.empty()) {
+ format(",\n_has_bits_(from._has_bits_)");
+ }
+
+ std::vector<bool> processed(optimized_order_.size(), false);
+ for (int i = 0; i < optimized_order_.size(); i++) {
+ auto field = optimized_order_[i];
+ if (!(field->is_repeated() && !(field->is_map())) &&
+ !IsCord(field, options_)) {
+ continue;
+ }
+
+ processed[i] = true;
+ format(",\n$1$_(from.$1$_)", FieldName(field));
+ }
+
+ if (IsAnyMessage(descriptor_, options_)) {
+ format(",\n_any_metadata_(&type_url_, &value_)");
+ }
+ if (num_weak_fields_ > 0) {
+ format(",\n_weak_field_map_(from._weak_field_map_)");
+ }
+
+ format.Outdent();
+ format.Outdent();
+ format(" {\n");
+
+ format(
+ "_internal_metadata_.MergeFrom<$unknown_fields_type$>(from._internal_"
+ "metadata_);\n");
+
+ if (descriptor_->extension_range_count() > 0) {
+ format(
+ "_extensions_.MergeFrom(internal_default_instance(), "
+ "from._extensions_);\n");
+ }
+
+ GenerateConstructorBody(printer, processed, true);
+
+ // Copy oneof fields. Oneof field requires oneof case check.
+ for (auto oneof : OneOfRange(descriptor_)) {
+ format(
+ "clear_has_$1$();\n"
+ "switch (from.$1$_case()) {\n",
+ oneof->name());
+ format.Indent();
+ for (auto field : FieldRange(oneof)) {
+ format("case k$1$: {\n", UnderscoresToCamelCase(field->name(), true));
+ format.Indent();
+ if (!IsFieldStripped(field, options_)) {
+ field_generators_.get(field).GenerateMergingCode(printer);
+ }
+ format("break;\n");
+ format.Outdent();
+ format("}\n");
+ }
+ format(
+ "case $1$_NOT_SET: {\n"
+ " break;\n"
+ "}\n",
+ ToUpper(oneof->name()));
+ format.Outdent();
+ format("}\n");
+ }
+
+ format.Outdent();
+ format(
+ " // @@protoc_insertion_point(copy_constructor:$full_name$)\n"
+ "}\n"
+ "\n");
+ }
+
+ // Generate the shared constructor code.
+ GenerateSharedConstructorCode(printer);
+
+ // Generate the destructor.
+ if (!HasSimpleBaseClass(descriptor_, options_)) {
+ format(
+ "$classname$::~$classname$() {\n"
+ " // @@protoc_insertion_point(destructor:$full_name$)\n"
+ " if (GetArenaForAllocation() != nullptr) return;\n"
+ " SharedDtor();\n"
+ " _internal_metadata_.Delete<$unknown_fields_type$>();\n"
+ "}\n"
+ "\n");
+ } else {
+ // For messages using simple base classes, having no destructor
+ // allows our vtable to share the same destructor as every other
+ // message with a simple base class. This works only as long as
+ // we have no fields needing destruction, of course. (No strings
+ // or extensions)
+ }
+
+ // Generate the shared destructor code.
+ GenerateSharedDestructorCode(printer);
+
+ // Generate the arena-specific destructor code.
+ GenerateArenaDestructorCode(printer);
+
+ if (!HasSimpleBaseClass(descriptor_, options_)) {
+ // Generate SetCachedSize.
+ format(
+ "void $classname$::SetCachedSize(int size) const {\n"
+ " _cached_size_.Set(size);\n"
+ "}\n");
+ }
+}
+
+void MessageGenerator::GenerateSourceInProto2Namespace(io::Printer* printer) {
+ Formatter format(printer, variables_);
+ format(
+ "template<> "
+ "PROTOBUF_NOINLINE "
+ "$classtype$* Arena::CreateMaybeMessage< $classtype$ >(Arena* arena) {\n"
+ " return Arena::CreateMessageInternal< $classtype$ >(arena);\n"
+ "}\n");
+}
+
+void MessageGenerator::GenerateClear(io::Printer* printer) {
+ if (HasSimpleBaseClass(descriptor_, options_)) return;
+ Formatter format(printer, variables_);
+
+ // The maximum number of bytes we will memset to zero without checking their
+ // hasbit to see if a zero-init is necessary.
+ const int kMaxUnconditionalPrimitiveBytesClear = 4;
+
+ format(
+ "void $classname$::Clear() {\n"
+ "// @@protoc_insertion_point(message_clear_start:$full_name$)\n");
+ format.Indent();
+
+ format(
+ // TODO(jwb): It would be better to avoid emitting this if it is not used,
+ // rather than emitting a workaround for the resulting warning.
+ "$uint32$ cached_has_bits = 0;\n"
+ "// Prevent compiler warnings about cached_has_bits being unused\n"
+ "(void) cached_has_bits;\n\n");
+
+ if (descriptor_->extension_range_count() > 0) {
+ format("_extensions_.Clear();\n");
+ }
+
+ // Collect fields into chunks. Each chunk may have an if() condition that
+ // checks all hasbits in the chunk and skips it if none are set.
+ int zero_init_bytes = 0;
+ for (const auto& field : optimized_order_) {
+ if (CanInitializeByZeroing(field)) {
+ zero_init_bytes += EstimateAlignmentSize(field);
+ }
+ }
+ bool merge_zero_init = zero_init_bytes > kMaxUnconditionalPrimitiveBytesClear;
+ int chunk_count = 0;
+
+ std::vector<std::vector<const FieldDescriptor*>> chunks = CollectFields(
+ optimized_order_,
+ [&](const FieldDescriptor* a, const FieldDescriptor* b) -> bool {
+ chunk_count++;
+ // This predicate guarantees that there is only a single zero-init
+ // (memset) per chunk, and if present it will be at the beginning.
+ bool same = HasByteIndex(a) == HasByteIndex(b) &&
+ a->is_repeated() == b->is_repeated() &&
+ (CanInitializeByZeroing(a) == CanInitializeByZeroing(b) ||
+ (CanInitializeByZeroing(a) &&
+ (chunk_count == 1 || merge_zero_init)));
+ if (!same) chunk_count = 0;
+ return same;
+ });
+
+ ColdChunkSkipper cold_skipper(options_, chunks, has_bit_indices_, kColdRatio);
+ int cached_has_word_index = -1;
+
+ for (int chunk_index = 0; chunk_index < chunks.size(); chunk_index++) {
+ std::vector<const FieldDescriptor*>& chunk = chunks[chunk_index];
+ cold_skipper.OnStartChunk(chunk_index, cached_has_word_index, "", printer);
+
+ const FieldDescriptor* memset_start = nullptr;
+ const FieldDescriptor* memset_end = nullptr;
+ bool saw_non_zero_init = false;
+
+ for (const auto& field : chunk) {
+ if (CanInitializeByZeroing(field)) {
+ GOOGLE_CHECK(!saw_non_zero_init);
+ if (!memset_start) memset_start = field;
+ memset_end = field;
+ } else {
+ saw_non_zero_init = true;
+ }
+ }
+
+ // Whether we wrap this chunk in:
+ // if (cached_has_bits & <chunk hasbits) { /* chunk. */ }
+ // We can omit the if() for chunk size 1, or if our fields do not have
+ // hasbits. I don't understand the rationale for the last part of the
+ // condition, but it matches the old logic.
+ const bool have_outer_if = HasBitIndex(chunk.front()) != kNoHasbit &&
+ chunk.size() > 1 &&
+ (memset_end != chunk.back() || merge_zero_init);
+
+ if (have_outer_if) {
+ // Emit an if() that will let us skip the whole chunk if none are set.
+ uint32_t chunk_mask = GenChunkMask(chunk, has_bit_indices_);
+ std::string chunk_mask_str =
+ StrCat(strings::Hex(chunk_mask, strings::ZERO_PAD_8));
+
+ // Check (up to) 8 has_bits at a time if we have more than one field in
+ // this chunk. Due to field layout ordering, we may check
+ // _has_bits_[last_chunk * 8 / 32] multiple times.
+ GOOGLE_DCHECK_LE(2, popcnt(chunk_mask));
+ GOOGLE_DCHECK_GE(8, popcnt(chunk_mask));
+
+ if (cached_has_word_index != HasWordIndex(chunk.front())) {
+ cached_has_word_index = HasWordIndex(chunk.front());
+ format("cached_has_bits = _has_bits_[$1$];\n", cached_has_word_index);
+ }
+ format("if (cached_has_bits & 0x$1$u) {\n", chunk_mask_str);
+ format.Indent();
+ }
+
+ if (memset_start) {
+ if (memset_start == memset_end) {
+ // For clarity, do not memset a single field.
+ field_generators_.get(memset_start)
+ .GenerateMessageClearingCode(printer);
+ } else {
+ format(
+ "::memset(&$1$_, 0, static_cast<size_t>(\n"
+ " reinterpret_cast<char*>(&$2$_) -\n"
+ " reinterpret_cast<char*>(&$1$_)) + sizeof($2$_));\n",
+ FieldName(memset_start), FieldName(memset_end));
+ }
+ }
+
+ // Clear all non-zero-initializable fields in the chunk.
+ for (const auto& field : chunk) {
+ if (CanInitializeByZeroing(field)) continue;
+ // It's faster to just overwrite primitive types, but we should only
+ // clear strings and messages if they were set.
+ //
+ // TODO(kenton): Let the CppFieldGenerator decide this somehow.
+ bool have_enclosing_if =
+ HasBitIndex(field) != kNoHasbit &&
+ (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE ||
+ field->cpp_type() == FieldDescriptor::CPPTYPE_STRING);
+
+ if (have_enclosing_if) {
+ PrintPresenceCheck(format, field, has_bit_indices_, printer,
+ &cached_has_word_index);
+ }
+
+ field_generators_.get(field).GenerateMessageClearingCode(printer);
+
+ if (have_enclosing_if) {
+ format.Outdent();
+ format("}\n");
+ }
+ }
+
+ if (have_outer_if) {
+ format.Outdent();
+ format("}\n");
+ }
+
+ if (cold_skipper.OnEndChunk(chunk_index, printer)) {
+ // Reset here as it may have been updated in just closed if statement.
+ cached_has_word_index = -1;
+ }
+ }
+
+ // Step 4: Unions.
+ for (auto oneof : OneOfRange(descriptor_)) {
+ format("clear_$1$();\n", oneof->name());
+ }
+
+ if (num_weak_fields_) {
+ format("_weak_field_map_.ClearAll();\n");
+ }
+
+ // We don't clear donated status.
+
+ if (!has_bit_indices_.empty()) {
+ // Step 5: Everything else.
+ format("_has_bits_.Clear();\n");
+ }
+
+ std::map<std::string, std::string> vars;
+ SetUnknownFieldsVariable(descriptor_, options_, &vars);
+ format.AddMap(vars);
+ format("_internal_metadata_.Clear<$unknown_fields_type$>();\n");
+
+ format.Outdent();
+ format("}\n");
+}
+
+void MessageGenerator::GenerateOneofClear(io::Printer* printer) {
+ // Generated function clears the active field and union case (e.g. foo_case_).
+ int i = 0;
+ for (auto oneof : OneOfRange(descriptor_)) {
+ Formatter format(printer, variables_);
+ format.Set("oneofname", oneof->name());
+
+ format(
+ "void $classname$::clear_$oneofname$() {\n"
+ "// @@protoc_insertion_point(one_of_clear_start:$full_name$)\n");
+ format.Indent();
+ format("switch ($oneofname$_case()) {\n");
+ format.Indent();
+ for (auto field : FieldRange(oneof)) {
+ format("case k$1$: {\n", UnderscoresToCamelCase(field->name(), true));
+ format.Indent();
+ // We clear only allocated objects in oneofs
+ if (!IsStringOrMessage(field) || IsFieldStripped(field, options_)) {
+ format("// No need to clear\n");
+ } else {
+ field_generators_.get(field).GenerateClearingCode(printer);
+ }
+ format("break;\n");
+ format.Outdent();
+ format("}\n");
+ }
+ format(
+ "case $1$_NOT_SET: {\n"
+ " break;\n"
+ "}\n",
+ ToUpper(oneof->name()));
+ format.Outdent();
+ format(
+ "}\n"
+ "_oneof_case_[$1$] = $2$_NOT_SET;\n",
+ i, ToUpper(oneof->name()));
+ format.Outdent();
+ format(
+ "}\n"
+ "\n");
+ i++;
+ }
+}
+
+void MessageGenerator::GenerateSwap(io::Printer* printer) {
+ if (HasSimpleBaseClass(descriptor_, options_)) return;
+ Formatter format(printer, variables_);
+
+ format("void $classname$::InternalSwap($classname$* other) {\n");
+ format.Indent();
+ format("using std::swap;\n");
+
+ if (HasGeneratedMethods(descriptor_->file(), options_)) {
+ if (descriptor_->extension_range_count() > 0) {
+ format("_extensions_.InternalSwap(&other->_extensions_);\n");
+ }
+
+ std::map<std::string, std::string> vars;
+ SetUnknownFieldsVariable(descriptor_, options_, &vars);
+ format.AddMap(vars);
+ if (HasSingularString(descriptor_, options_)) {
+ format(
+ "auto* lhs_arena = GetArenaForAllocation();\n"
+ "auto* rhs_arena = other->GetArenaForAllocation();\n");
+ }
+ format("_internal_metadata_.InternalSwap(&other->_internal_metadata_);\n");
+
+ if (!has_bit_indices_.empty()) {
+ for (int i = 0; i < HasBitsSize(); ++i) {
+ format("swap(_has_bits_[$1$], other->_has_bits_[$1$]);\n", i);
+ }
+ }
+
+ // If possible, we swap several fields at once, including padding.
+ const RunMap runs =
+ FindRuns(optimized_order_, [this](const FieldDescriptor* field) {
+ return CanBeManipulatedAsRawBytes(field, options_, scc_analyzer_);
+ });
+
+ for (int i = 0; i < optimized_order_.size(); ++i) {
+ const FieldDescriptor* field = optimized_order_[i];
+ const auto it = runs.find(field);
+
+ // We only apply the memswap technique to runs of more than one field, as
+ // `swap(field_, other.field_)` is better than
+ // `memswap<...>(&field_, &other.field_)` for generated code readability.
+ if (it != runs.end() && it->second > 1) {
+ // Use a memswap, then skip run_length fields.
+ const size_t run_length = it->second;
+ const std::string first_field_name = FieldName(field);
+ const std::string last_field_name =
+ FieldName(optimized_order_[i + run_length - 1]);
+
+ format.Set("first", first_field_name);
+ format.Set("last", last_field_name);
+
+ format(
+ "::PROTOBUF_NAMESPACE_ID::internal::memswap<\n"
+ " PROTOBUF_FIELD_OFFSET($classname$, $last$_)\n"
+ " + sizeof($classname$::$last$_)\n"
+ " - PROTOBUF_FIELD_OFFSET($classname$, $first$_)>(\n"
+ " reinterpret_cast<char*>(&$first$_),\n"
+ " reinterpret_cast<char*>(&other->$first$_));\n");
+
+ i += run_length - 1;
+ // ++i at the top of the loop.
+ } else {
+ field_generators_.get(field).GenerateSwappingCode(printer);
+ }
+ }
+
+ for (auto oneof : OneOfRange(descriptor_)) {
+ format("swap($1$_, other->$1$_);\n", oneof->name());
+ }
+
+ for (int i = 0; i < descriptor_->real_oneof_decl_count(); i++) {
+ format("swap(_oneof_case_[$1$], other->_oneof_case_[$1$]);\n", i);
+ }
+
+ if (num_weak_fields_) {
+ format("_weak_field_map_.UnsafeArenaSwap(&other->_weak_field_map_);\n");
+ }
+ } else {
+ format("GetReflection()->Swap(this, other);");
+ }
+
+ format.Outdent();
+ format("}\n");
+}
+
+void MessageGenerator::GenerateMergeFrom(io::Printer* printer) {
+ Formatter format(printer, variables_);
+ if (!HasSimpleBaseClass(descriptor_, options_)) {
+ if (HasDescriptorMethods(descriptor_->file(), options_)) {
+ // We don't override the generalized MergeFrom (aka that which
+ // takes in the Message base class as a parameter); instead we just
+ // let the base Message::MergeFrom take care of it. The base MergeFrom
+ // knows how to quickly confirm the types exactly match, and if so, will
+ // use GetClassData() to retrieve the address of MergeImpl, which calls
+ // the fast MergeFrom overload. Most callers avoid all this by passing
+ // a "from" message that is the same type as the message being merged
+ // into, rather than a generic Message.
+
+ format(
+ "const ::$proto_ns$::Message::ClassData "
+ "$classname$::_class_data_ = {\n"
+ " ::$proto_ns$::Message::CopyWithSizeCheck,\n"
+ " $classname$::MergeImpl\n"
+ "};\n"
+ "const ::$proto_ns$::Message::ClassData*"
+ "$classname$::GetClassData() const { return &_class_data_; }\n"
+ "\n"
+ "void $classname$::MergeImpl(::$proto_ns$::Message* to,\n"
+ " const ::$proto_ns$::Message& from) {\n"
+ " static_cast<$classname$ *>(to)->MergeFrom(\n"
+ " static_cast<const $classname$ &>(from));\n"
+ "}\n"
+ "\n");
+ } else {
+ // Generate CheckTypeAndMergeFrom().
+ format(
+ "void $classname$::CheckTypeAndMergeFrom(\n"
+ " const ::$proto_ns$::MessageLite& from) {\n"
+ " MergeFrom(*::$proto_ns$::internal::DownCast<const $classname$*>(\n"
+ " &from));\n"
+ "}\n");
+ }
+ } else {
+ // In the simple case, we just define ClassData that vectors back to the
+ // simple implementation of Copy and Merge.
+ format(
+ "const ::$proto_ns$::Message::ClassData "
+ "$classname$::_class_data_ = {\n"
+ " $superclass$::CopyImpl,\n"
+ " $superclass$::MergeImpl,\n"
+ "};\n"
+ "const ::$proto_ns$::Message::ClassData*"
+ "$classname$::GetClassData() const { return &_class_data_; }\n"
+ "\n"
+ "\n");
+ }
+}
+
+void MessageGenerator::GenerateClassSpecificMergeFrom(io::Printer* printer) {
+ if (HasSimpleBaseClass(descriptor_, options_)) return;
+ // Generate the class-specific MergeFrom, which avoids the GOOGLE_CHECK and cast.
+ Formatter format(printer, variables_);
+ format(
+ "void $classname$::MergeFrom(const $classname$& from) {\n"
+ "$annotate_mergefrom$"
+ "// @@protoc_insertion_point(class_specific_merge_from_start:"
+ "$full_name$)\n"
+ " $DCHK$_NE(&from, this);\n");
+ format.Indent();
+
+ format(
+ "$uint32$ cached_has_bits = 0;\n"
+ "(void) cached_has_bits;\n\n");
+
+ std::vector<std::vector<const FieldDescriptor*>> chunks = CollectFields(
+ optimized_order_,
+ [&](const FieldDescriptor* a, const FieldDescriptor* b) -> bool {
+ return HasByteIndex(a) == HasByteIndex(b);
+ });
+
+ ColdChunkSkipper cold_skipper(options_, chunks, has_bit_indices_, kColdRatio);
+
+ // cached_has_word_index maintains that:
+ // cached_has_bits = from._has_bits_[cached_has_word_index]
+ // for cached_has_word_index >= 0
+ int cached_has_word_index = -1;
+
+ for (int chunk_index = 0; chunk_index < chunks.size(); chunk_index++) {
+ const std::vector<const FieldDescriptor*>& chunk = chunks[chunk_index];
+ bool have_outer_if =
+ chunk.size() > 1 && HasByteIndex(chunk.front()) != kNoHasbit;
+ cold_skipper.OnStartChunk(chunk_index, cached_has_word_index, "from.",
+ printer);
+
+ if (have_outer_if) {
+ // Emit an if() that will let us skip the whole chunk if none are set.
+ uint32_t chunk_mask = GenChunkMask(chunk, has_bit_indices_);
+ std::string chunk_mask_str =
+ StrCat(strings::Hex(chunk_mask, strings::ZERO_PAD_8));
+
+ // Check (up to) 8 has_bits at a time if we have more than one field in
+ // this chunk. Due to field layout ordering, we may check
+ // _has_bits_[last_chunk * 8 / 32] multiple times.
+ GOOGLE_DCHECK_LE(2, popcnt(chunk_mask));
+ GOOGLE_DCHECK_GE(8, popcnt(chunk_mask));
+
+ if (cached_has_word_index != HasWordIndex(chunk.front())) {
+ cached_has_word_index = HasWordIndex(chunk.front());
+ format("cached_has_bits = from._has_bits_[$1$];\n",
+ cached_has_word_index);
+ }
+
+ format("if (cached_has_bits & 0x$1$u) {\n", chunk_mask_str);
+ format.Indent();
+ }
+
+ // Go back and emit merging code for each of the fields we processed.
+ bool deferred_has_bit_changes = false;
+ for (const auto field : chunk) {
+ const FieldGenerator& generator = field_generators_.get(field);
+
+ if (field->is_repeated()) {
+ generator.GenerateMergingCode(printer);
+ } else if (field->is_optional() && !HasHasbit(field)) {
+ // Merge semantics without true field presence: primitive fields are
+ // merged only if non-zero (numeric) or non-empty (string).
+ bool have_enclosing_if =
+ EmitFieldNonDefaultCondition(printer, "from.", field);
+ generator.GenerateMergingCode(printer);
+ if (have_enclosing_if) {
+ format.Outdent();
+ format("}\n");
+ }
+ } else if (field->options().weak() ||
+ cached_has_word_index != HasWordIndex(field)) {
+ // Check hasbit, not using cached bits.
+ GOOGLE_CHECK(HasHasbit(field));
+ format("if (from._internal_has_$1$()) {\n", FieldName(field));
+ format.Indent();
+ generator.GenerateMergingCode(printer);
+ format.Outdent();
+ format("}\n");
+ } else {
+ // Check hasbit, using cached bits.
+ GOOGLE_CHECK(HasHasbit(field));
+ int has_bit_index = has_bit_indices_[field->index()];
+ const std::string mask = StrCat(
+ strings::Hex(1u << (has_bit_index % 32), strings::ZERO_PAD_8));
+ format("if (cached_has_bits & 0x$1$u) {\n", mask);
+ format.Indent();
+
+ if (have_outer_if && IsPOD(field)) {
+ // Defer hasbit modification until the end of chunk.
+ // This can reduce the number of loads/stores by up to 7 per 8 fields.
+ deferred_has_bit_changes = true;
+ generator.GenerateCopyConstructorCode(printer);
+ } else {
+ generator.GenerateMergingCode(printer);
+ }
+
+ format.Outdent();
+ format("}\n");
+ }
+ }
+
+ if (have_outer_if) {
+ if (deferred_has_bit_changes) {
+ // Flush the has bits for the primitives we deferred.
+ GOOGLE_CHECK_LE(0, cached_has_word_index);
+ format("_has_bits_[$1$] |= cached_has_bits;\n", cached_has_word_index);
+ }
+
+ format.Outdent();
+ format("}\n");
+ }
+
+ if (cold_skipper.OnEndChunk(chunk_index, printer)) {
+ // Reset here as it may have been updated in just closed if statement.
+ cached_has_word_index = -1;
+ }
+ }
+
+ // Merge oneof fields. Oneof field requires oneof case check.
+ for (auto oneof : OneOfRange(descriptor_)) {
+ format("switch (from.$1$_case()) {\n", oneof->name());
+ format.Indent();
+ for (auto field : FieldRange(oneof)) {
+ format("case k$1$: {\n", UnderscoresToCamelCase(field->name(), true));
+ format.Indent();
+ if (!IsFieldStripped(field, options_)) {
+ field_generators_.get(field).GenerateMergingCode(printer);
+ }
+ format("break;\n");
+ format.Outdent();
+ format("}\n");
+ }
+ format(
+ "case $1$_NOT_SET: {\n"
+ " break;\n"
+ "}\n",
+ ToUpper(oneof->name()));
+ format.Outdent();
+ format("}\n");
+ }
+ if (num_weak_fields_) {
+ format("_weak_field_map_.MergeFrom(from._weak_field_map_);\n");
+ }
+
+ // Merging of extensions and unknown fields is done last, to maximize
+ // the opportunity for tail calls.
+ if (descriptor_->extension_range_count() > 0) {
+ format(
+ "_extensions_.MergeFrom(internal_default_instance(), "
+ "from._extensions_);\n");
+ }
+
+ format(
+ "_internal_metadata_.MergeFrom<$unknown_fields_type$>(from._internal_"
+ "metadata_);\n");
+
+ format.Outdent();
+ format("}\n");
+}
+
+void MessageGenerator::GenerateCopyFrom(io::Printer* printer) {
+ if (HasSimpleBaseClass(descriptor_, options_)) return;
+ Formatter format(printer, variables_);
+ if (HasDescriptorMethods(descriptor_->file(), options_)) {
+ // We don't override the generalized CopyFrom (aka that which
+ // takes in the Message base class as a parameter); instead we just
+ // let the base Message::CopyFrom take care of it. The base MergeFrom
+ // knows how to quickly confirm the types exactly match, and if so, will
+ // use GetClassData() to get the address of Message::CopyWithSizeCheck,
+ // which calls Clear() and then MergeFrom(), as well as making sure that
+ // clearing the destination message doesn't alter the size of the source,
+ // when in debug builds.
+ // Most callers avoid this by passing a "from" message that is the same
+ // type as the message being merged into, rather than a generic Message.
+ }
+
+ // Generate the class-specific CopyFrom.
+ format(
+ "void $classname$::CopyFrom(const $classname$& from) {\n"
+ "// @@protoc_insertion_point(class_specific_copy_from_start:"
+ "$full_name$)\n");
+ format.Indent();
+
+ format("if (&from == this) return;\n");
+
+ if (!options_.opensource_runtime) {
+ // This check is disabled in the opensource release because we're
+ // concerned that many users do not define NDEBUG in their release builds.
+ format(
+ "#ifndef NDEBUG\n"
+ "size_t from_size = from.ByteSizeLong();\n"
+ "#endif\n"
+ "Clear();\n"
+ "#ifndef NDEBUG\n"
+ "$CHK$_EQ(from_size, from.ByteSizeLong())\n"
+ " << \"Source of CopyFrom changed when clearing target. Either \"\n"
+ " \"source is a nested message in target (not allowed), or \"\n"
+ " \"another thread is modifying the source.\";\n"
+ "#endif\n");
+ } else {
+ format("Clear();\n");
+ }
+ format("MergeFrom(from);\n");
+
+ format.Outdent();
+ format("}\n");
+}
+
+void MessageGenerator::GenerateVerify(io::Printer* printer) {
+}
+
+void MessageGenerator::GenerateSerializeOneofFields(
+ io::Printer* printer, const std::vector<const FieldDescriptor*>& fields) {
+ Formatter format(printer, variables_);
+ GOOGLE_CHECK(!fields.empty());
+ if (fields.size() == 1) {
+ GenerateSerializeOneField(printer, fields[0], -1);
+ return;
+ }
+ // We have multiple mutually exclusive choices. Emit a switch statement.
+ const OneofDescriptor* oneof = fields[0]->containing_oneof();
+ format("switch ($1$_case()) {\n", oneof->name());
+ format.Indent();
+ for (auto field : fields) {
+ format("case k$1$: {\n", UnderscoresToCamelCase(field->name(), true));
+ format.Indent();
+ field_generators_.get(field).GenerateSerializeWithCachedSizesToArray(
+ printer);
+ format("break;\n");
+ format.Outdent();
+ format("}\n");
+ }
+ format.Outdent();
+ // Doing nothing is an option.
+ format(
+ " default: ;\n"
+ "}\n");
+}
+
+void MessageGenerator::GenerateSerializeOneField(io::Printer* printer,
+ const FieldDescriptor* field,
+ int cached_has_bits_index) {
+ Formatter format(printer, variables_);
+ if (!field->options().weak()) {
+ // For weakfields, PrintFieldComment is called during iteration.
+ PrintFieldComment(format, field);
+ }
+
+ bool have_enclosing_if = false;
+ if (field->options().weak()) {
+ } else if (HasHasbit(field)) {
+ // Attempt to use the state of cached_has_bits, if possible.
+ int has_bit_index = HasBitIndex(field);
+ if (cached_has_bits_index == has_bit_index / 32) {
+ const std::string mask =
+ StrCat(strings::Hex(1u << (has_bit_index % 32), strings::ZERO_PAD_8));
+
+ format("if (cached_has_bits & 0x$1$u) {\n", mask);
+ } else {
+ format("if (_internal_has_$1$()) {\n", FieldName(field));
+ }
+
+ format.Indent();
+ have_enclosing_if = true;
+ } else if (field->is_optional() && !HasHasbit(field)) {
+ have_enclosing_if = EmitFieldNonDefaultCondition(printer, "this->", field);
+ }
+
+ field_generators_.get(field).GenerateSerializeWithCachedSizesToArray(printer);
+
+ if (have_enclosing_if) {
+ format.Outdent();
+ format("}\n");
+ }
+ format("\n");
+}
+
+void MessageGenerator::GenerateSerializeOneExtensionRange(
+ io::Printer* printer, const Descriptor::ExtensionRange* range) {
+ std::map<std::string, std::string> vars = variables_;
+ vars["start"] = StrCat(range->start);
+ vars["end"] = StrCat(range->end);
+ Formatter format(printer, vars);
+ format("// Extension range [$start$, $end$)\n");
+ format(
+ "target = _extensions_._InternalSerialize(\n"
+ "internal_default_instance(), $start$, $end$, target, stream);\n\n");
+}
+
+void MessageGenerator::GenerateSerializeWithCachedSizesToArray(
+ io::Printer* printer) {
+ if (HasSimpleBaseClass(descriptor_, options_)) return;
+ Formatter format(printer, variables_);
+ if (descriptor_->options().message_set_wire_format()) {
+ // Special-case MessageSet.
+ format(
+ "$uint8$* $classname$::_InternalSerialize(\n"
+ " $uint8$* target, ::$proto_ns$::io::EpsCopyOutputStream* stream) "
+ "const {\n"
+ "$annotate_serialize$"
+ " target = _extensions_."
+ "InternalSerializeMessageSetWithCachedSizesToArray(\n" //
+ "internal_default_instance(), target, stream);\n");
+ std::map<std::string, std::string> vars;
+ SetUnknownFieldsVariable(descriptor_, options_, &vars);
+ format.AddMap(vars);
+ format(
+ " target = ::$proto_ns$::internal::"
+ "InternalSerializeUnknownMessageSetItemsToArray(\n"
+ " $unknown_fields$, target, stream);\n");
+ format(
+ " return target;\n"
+ "}\n");
+ return;
+ }
+
+ format(
+ "$uint8$* $classname$::_InternalSerialize(\n"
+ " $uint8$* target, ::$proto_ns$::io::EpsCopyOutputStream* stream) "
+ "const {\n"
+ "$annotate_serialize$");
+ format.Indent();
+
+ format("// @@protoc_insertion_point(serialize_to_array_start:$full_name$)\n");
+
+ if (!ShouldSerializeInOrder(descriptor_, options_)) {
+ format.Outdent();
+ format("#ifdef NDEBUG\n");
+ format.Indent();
+ }
+
+ GenerateSerializeWithCachedSizesBody(printer);
+
+ if (!ShouldSerializeInOrder(descriptor_, options_)) {
+ format.Outdent();
+ format("#else // NDEBUG\n");
+ format.Indent();
+
+ GenerateSerializeWithCachedSizesBodyShuffled(printer);
+
+ format.Outdent();
+ format("#endif // !NDEBUG\n");
+ format.Indent();
+ }
+
+ format("// @@protoc_insertion_point(serialize_to_array_end:$full_name$)\n");
+
+ format.Outdent();
+ format(
+ " return target;\n"
+ "}\n");
+}
+
+void MessageGenerator::GenerateSerializeWithCachedSizesBody(
+ io::Printer* printer) {
+ if (HasSimpleBaseClass(descriptor_, options_)) return;
+ Formatter format(printer, variables_);
+ // If there are multiple fields in a row from the same oneof then we
+ // coalesce them and emit a switch statement. This is more efficient
+ // because it lets the C++ compiler know this is a "at most one can happen"
+ // situation. If we emitted "if (has_x()) ...; if (has_y()) ..." the C++
+ // compiler's emitted code might check has_y() even when has_x() is true.
+ class LazySerializerEmitter {
+ public:
+ LazySerializerEmitter(MessageGenerator* mg, io::Printer* printer)
+ : mg_(mg),
+ format_(printer),
+ eager_(IsProto3(mg->descriptor_->file())),
+ cached_has_bit_index_(kNoHasbit) {}
+
+ ~LazySerializerEmitter() { Flush(); }
+
+ // If conditions allow, try to accumulate a run of fields from the same
+ // oneof, and handle them at the next Flush().
+ void Emit(const FieldDescriptor* field) {
+ if (eager_ || MustFlush(field)) {
+ Flush();
+ }
+ if (!field->real_containing_oneof()) {
+ // TODO(ckennelly): Defer non-oneof fields similarly to oneof fields.
+
+ if (!field->options().weak() && !field->is_repeated() && !eager_) {
+ // We speculatively load the entire _has_bits_[index] contents, even
+ // if it is for only one field. Deferring non-oneof emitting would
+ // allow us to determine whether this is going to be useful.
+ int has_bit_index = mg_->has_bit_indices_[field->index()];
+ if (cached_has_bit_index_ != has_bit_index / 32) {
+ // Reload.
+ int new_index = has_bit_index / 32;
+
+ format_("cached_has_bits = _has_bits_[$1$];\n", new_index);
+
+ cached_has_bit_index_ = new_index;
+ }
+ }
+
+ mg_->GenerateSerializeOneField(format_.printer(), field,
+ cached_has_bit_index_);
+ } else {
+ v_.push_back(field);
+ }
+ }
+
+ void EmitIfNotNull(const FieldDescriptor* field) {
+ if (field != nullptr) {
+ Emit(field);
+ }
+ }
+
+ void Flush() {
+ if (!v_.empty()) {
+ mg_->GenerateSerializeOneofFields(format_.printer(), v_);
+ v_.clear();
+ }
+ }
+
+ private:
+ // If we have multiple fields in v_ then they all must be from the same
+ // oneof. Would adding field to v_ break that invariant?
+ bool MustFlush(const FieldDescriptor* field) {
+ return !v_.empty() &&
+ v_[0]->containing_oneof() != field->containing_oneof();
+ }
+
+ MessageGenerator* mg_;
+ Formatter format_;
+ const bool eager_;
+ std::vector<const FieldDescriptor*> v_;
+
+ // cached_has_bit_index_ maintains that:
+ // cached_has_bits = from._has_bits_[cached_has_bit_index_]
+ // for cached_has_bit_index_ >= 0
+ int cached_has_bit_index_;
+ };
+
+ class LazyExtensionRangeEmitter {
+ public:
+ LazyExtensionRangeEmitter(MessageGenerator* mg, io::Printer* printer)
+ : mg_(mg), format_(printer) {}
+
+ void AddToRange(const Descriptor::ExtensionRange* range) {
+ if (!has_current_range_) {
+ current_combined_range_ = *range;
+ has_current_range_ = true;
+ } else {
+ current_combined_range_.start =
+ std::min(current_combined_range_.start, range->start);
+ current_combined_range_.end =
+ std::max(current_combined_range_.end, range->end);
+ }
+ }
+
+ void Flush() {
+ if (has_current_range_) {
+ mg_->GenerateSerializeOneExtensionRange(format_.printer(),
+ &current_combined_range_);
+ }
+ has_current_range_ = false;
+ }
+
+ private:
+ MessageGenerator* mg_;
+ Formatter format_;
+ bool has_current_range_ = false;
+ Descriptor::ExtensionRange current_combined_range_;
+ };
+
+ // We need to track the largest weak field, because weak fields are serialized
+ // differently than normal fields. The WeakFieldMap::FieldWriter will
+ // serialize all weak fields that are ordinally between the last serialized
+ // weak field and the current field. In order to guarantee that all weak
+ // fields are serialized, we need to make sure to emit the code to serialize
+ // the largest weak field present at some point.
+ class LargestWeakFieldHolder {
+ public:
+ const FieldDescriptor* Release() {
+ const FieldDescriptor* result = field_;
+ field_ = nullptr;
+ return result;
+ }
+ void ReplaceIfLarger(const FieldDescriptor* field) {
+ if (field_ == nullptr || field_->number() < field->number()) {
+ field_ = field;
+ }
+ }
+
+ private:
+ const FieldDescriptor* field_ = nullptr;
+ };
+
+ std::vector<const FieldDescriptor*> ordered_fields =
+ SortFieldsByNumber(descriptor_);
+
+ std::vector<const Descriptor::ExtensionRange*> sorted_extensions;
+ sorted_extensions.reserve(descriptor_->extension_range_count());
+ for (int i = 0; i < descriptor_->extension_range_count(); ++i) {
+ sorted_extensions.push_back(descriptor_->extension_range(i));
+ }
+ std::sort(sorted_extensions.begin(), sorted_extensions.end(),
+ ExtensionRangeSorter());
+ if (num_weak_fields_) {
+ format(
+ "::$proto_ns$::internal::WeakFieldMap::FieldWriter field_writer("
+ "_weak_field_map_);\n");
+ }
+
+ format(
+ "$uint32$ cached_has_bits = 0;\n"
+ "(void) cached_has_bits;\n\n");
+
+ // Merge the fields and the extension ranges, both sorted by field number.
+ {
+ LazySerializerEmitter e(this, printer);
+ LazyExtensionRangeEmitter re(this, printer);
+ LargestWeakFieldHolder largest_weak_field;
+ int i, j;
+ for (i = 0, j = 0;
+ i < ordered_fields.size() || j < sorted_extensions.size();) {
+ if ((j == sorted_extensions.size()) ||
+ (i < descriptor_->field_count() &&
+ ordered_fields[i]->number() < sorted_extensions[j]->start)) {
+ const FieldDescriptor* field = ordered_fields[i++];
+ if (IsFieldStripped(field, options_)) {
+ continue;
+ }
+ re.Flush();
+ if (field->options().weak()) {
+ largest_weak_field.ReplaceIfLarger(field);
+ PrintFieldComment(format, field);
+ } else {
+ e.EmitIfNotNull(largest_weak_field.Release());
+ e.Emit(field);
+ }
+ } else {
+ e.EmitIfNotNull(largest_weak_field.Release());
+ e.Flush();
+ re.AddToRange(sorted_extensions[j++]);
+ }
+ }
+ re.Flush();
+ e.EmitIfNotNull(largest_weak_field.Release());
+ }
+
+ std::map<std::string, std::string> vars;
+ SetUnknownFieldsVariable(descriptor_, options_, &vars);
+ format.AddMap(vars);
+ format("if (PROTOBUF_PREDICT_FALSE($have_unknown_fields$)) {\n");
+ format.Indent();
+ if (UseUnknownFieldSet(descriptor_->file(), options_)) {
+ format(
+ "target = "
+ "::$proto_ns$::internal::WireFormat::"
+ "InternalSerializeUnknownFieldsToArray(\n"
+ " $unknown_fields$, target, stream);\n");
+ } else {
+ format(
+ "target = stream->WriteRaw($unknown_fields$.data(),\n"
+ " static_cast<int>($unknown_fields$.size()), target);\n");
+ }
+ format.Outdent();
+ format("}\n");
+}
+
+void MessageGenerator::GenerateSerializeWithCachedSizesBodyShuffled(
+ io::Printer* printer) {
+ Formatter format(printer, variables_);
+
+ std::vector<const FieldDescriptor*> ordered_fields =
+ SortFieldsByNumber(descriptor_);
+ ordered_fields.erase(
+ std::remove_if(ordered_fields.begin(), ordered_fields.end(),
+ [this](const FieldDescriptor* f) {
+ return !IsFieldUsed(f, options_);
+ }),
+ ordered_fields.end());
+
+ std::vector<const Descriptor::ExtensionRange*> sorted_extensions;
+ sorted_extensions.reserve(descriptor_->extension_range_count());
+ for (int i = 0; i < descriptor_->extension_range_count(); ++i) {
+ sorted_extensions.push_back(descriptor_->extension_range(i));
+ }
+ std::sort(sorted_extensions.begin(), sorted_extensions.end(),
+ ExtensionRangeSorter());
+
+ int num_fields = ordered_fields.size() + sorted_extensions.size();
+ constexpr int kLargePrime = 1000003;
+ GOOGLE_CHECK_LT(num_fields, kLargePrime)
+ << "Prime offset must be greater than the number of fields to ensure "
+ "those are coprime.";
+
+ if (num_weak_fields_) {
+ format(
+ "::$proto_ns$::internal::WeakFieldMap::FieldWriter field_writer("
+ "_weak_field_map_);\n");
+ }
+
+ format("for (int i = $1$; i >= 0; i-- ) {\n", num_fields - 1);
+
+ format.Indent();
+ format("switch(i) {\n");
+ format.Indent();
+
+ int index = 0;
+ for (const auto* f : ordered_fields) {
+ format("case $1$: {\n", index++);
+ format.Indent();
+
+ GenerateSerializeOneField(printer, f, -1);
+
+ format("break;\n");
+ format.Outdent();
+ format("}\n");
+ }
+
+ for (const auto* r : sorted_extensions) {
+ format("case $1$: {\n", index++);
+ format.Indent();
+
+ GenerateSerializeOneExtensionRange(printer, r);
+
+ format("break;\n");
+ format.Outdent();
+ format("}\n");
+ }
+
+ format(
+ "default: {\n"
+ " $DCHK$(false) << \"Unexpected index: \" << i;\n"
+ "}\n");
+ format.Outdent();
+ format("}\n");
+
+ format.Outdent();
+ format("}\n");
+
+ std::map<std::string, std::string> vars;
+ SetUnknownFieldsVariable(descriptor_, options_, &vars);
+ format.AddMap(vars);
+ format("if (PROTOBUF_PREDICT_FALSE($have_unknown_fields$)) {\n");
+ format.Indent();
+ if (UseUnknownFieldSet(descriptor_->file(), options_)) {
+ format(
+ "target = "
+ "::$proto_ns$::internal::WireFormat::"
+ "InternalSerializeUnknownFieldsToArray(\n"
+ " $unknown_fields$, target, stream);\n");
+ } else {
+ format(
+ "target = stream->WriteRaw($unknown_fields$.data(),\n"
+ " static_cast<int>($unknown_fields$.size()), target);\n");
+ }
+ format.Outdent();
+ format("}\n");
+}
+
+std::vector<uint32_t> MessageGenerator::RequiredFieldsBitMask() const {
+ const int array_size = HasBitsSize();
+ std::vector<uint32_t> masks(array_size, 0);
+
+ for (auto field : FieldRange(descriptor_)) {
+ if (!field->is_required()) {
+ continue;
+ }
+
+ const int has_bit_index = has_bit_indices_[field->index()];
+ masks[has_bit_index / 32] |= static_cast<uint32_t>(1)
+ << (has_bit_index % 32);
+ }
+ return masks;
+}
+
+void MessageGenerator::GenerateByteSize(io::Printer* printer) {
+ if (HasSimpleBaseClass(descriptor_, options_)) return;
+ Formatter format(printer, variables_);
+
+ if (descriptor_->options().message_set_wire_format()) {
+ // Special-case MessageSet.
+ std::map<std::string, std::string> vars;
+ SetUnknownFieldsVariable(descriptor_, options_, &vars);
+ format.AddMap(vars);
+ format(
+ "size_t $classname$::ByteSizeLong() const {\n"
+ "$annotate_bytesize$"
+ "// @@protoc_insertion_point(message_set_byte_size_start:$full_name$)\n"
+ " size_t total_size = _extensions_.MessageSetByteSize();\n"
+ " if ($have_unknown_fields$) {\n"
+ " total_size += ::$proto_ns$::internal::\n"
+ " ComputeUnknownMessageSetItemsSize($unknown_fields$);\n"
+ " }\n"
+ " int cached_size = "
+ "::$proto_ns$::internal::ToCachedSize(total_size);\n"
+ " SetCachedSize(cached_size);\n"
+ " return total_size;\n"
+ "}\n");
+ return;
+ }
+
+ if (num_required_fields_ > 1) {
+ // Emit a function (rarely used, we hope) that handles the required fields
+ // by checking for each one individually.
+ format(
+ "size_t $classname$::RequiredFieldsByteSizeFallback() const {\n"
+ "// @@protoc_insertion_point(required_fields_byte_size_fallback_start:"
+ "$full_name$)\n");
+ format.Indent();
+ format("size_t total_size = 0;\n");
+ for (auto field : optimized_order_) {
+ if (field->is_required()) {
+ format(
+ "\n"
+ "if (_internal_has_$1$()) {\n",
+ FieldName(field));
+ format.Indent();
+ PrintFieldComment(format, field);
+ field_generators_.get(field).GenerateByteSize(printer);
+ format.Outdent();
+ format("}\n");
+ }
+ }
+ format(
+ "\n"
+ "return total_size;\n");
+ format.Outdent();
+ format("}\n");
+ }
+
+ format(
+ "size_t $classname$::ByteSizeLong() const {\n"
+ "$annotate_bytesize$"
+ "// @@protoc_insertion_point(message_byte_size_start:$full_name$)\n");
+ format.Indent();
+ format(
+ "size_t total_size = 0;\n"
+ "\n");
+
+ if (descriptor_->extension_range_count() > 0) {
+ format(
+ "total_size += _extensions_.ByteSize();\n"
+ "\n");
+ }
+
+ std::map<std::string, std::string> vars;
+ SetUnknownFieldsVariable(descriptor_, options_, &vars);
+ format.AddMap(vars);
+
+ // Handle required fields (if any). We expect all of them to be
+ // present, so emit one conditional that checks for that. If they are all
+ // present then the fast path executes; otherwise the slow path executes.
+ if (num_required_fields_ > 1) {
+ // The fast path works if all required fields are present.
+ const std::vector<uint32_t> masks_for_has_bits = RequiredFieldsBitMask();
+ format("if ($1$) { // All required fields are present.\n",
+ ConditionalToCheckBitmasks(masks_for_has_bits));
+ format.Indent();
+ // Oneof fields cannot be required, so optimized_order_ contains all of the
+ // fields that we need to potentially emit.
+ for (auto field : optimized_order_) {
+ if (!field->is_required()) continue;
+ PrintFieldComment(format, field);
+ field_generators_.get(field).GenerateByteSize(printer);
+ format("\n");
+ }
+ format.Outdent();
+ format(
+ "} else {\n" // the slow path
+ " total_size += RequiredFieldsByteSizeFallback();\n"
+ "}\n");
+ } else {
+ // num_required_fields_ <= 1: no need to be tricky
+ for (auto field : optimized_order_) {
+ if (!field->is_required()) continue;
+ PrintFieldComment(format, field);
+ format("if (_internal_has_$1$()) {\n", FieldName(field));
+ format.Indent();
+ field_generators_.get(field).GenerateByteSize(printer);
+ format.Outdent();
+ format("}\n");
+ }
+ }
+
+ std::vector<std::vector<const FieldDescriptor*>> chunks = CollectFields(
+ optimized_order_,
+ [&](const FieldDescriptor* a, const FieldDescriptor* b) -> bool {
+ return a->label() == b->label() && HasByteIndex(a) == HasByteIndex(b);
+ });
+
+ // Remove chunks with required fields.
+ chunks.erase(std::remove_if(chunks.begin(), chunks.end(), IsRequired),
+ chunks.end());
+
+ ColdChunkSkipper cold_skipper(options_, chunks, has_bit_indices_, kColdRatio);
+ int cached_has_word_index = -1;
+
+ format(
+ "$uint32$ cached_has_bits = 0;\n"
+ "// Prevent compiler warnings about cached_has_bits being unused\n"
+ "(void) cached_has_bits;\n\n");
+
+ for (int chunk_index = 0; chunk_index < chunks.size(); chunk_index++) {
+ const std::vector<const FieldDescriptor*>& chunk = chunks[chunk_index];
+ const bool have_outer_if =
+ chunk.size() > 1 && HasWordIndex(chunk[0]) != kNoHasbit;
+ cold_skipper.OnStartChunk(chunk_index, cached_has_word_index, "", printer);
+
+ if (have_outer_if) {
+ // Emit an if() that will let us skip the whole chunk if none are set.
+ uint32_t chunk_mask = GenChunkMask(chunk, has_bit_indices_);
+ std::string chunk_mask_str =
+ StrCat(strings::Hex(chunk_mask, strings::ZERO_PAD_8));
+
+ // Check (up to) 8 has_bits at a time if we have more than one field in
+ // this chunk. Due to field layout ordering, we may check
+ // _has_bits_[last_chunk * 8 / 32] multiple times.
+ GOOGLE_DCHECK_LE(2, popcnt(chunk_mask));
+ GOOGLE_DCHECK_GE(8, popcnt(chunk_mask));
+
+ if (cached_has_word_index != HasWordIndex(chunk.front())) {
+ cached_has_word_index = HasWordIndex(chunk.front());
+ format("cached_has_bits = _has_bits_[$1$];\n", cached_has_word_index);
+ }
+ format("if (cached_has_bits & 0x$1$u) {\n", chunk_mask_str);
+ format.Indent();
+ }
+
+ // Go back and emit checks for each of the fields we processed.
+ for (int j = 0; j < chunk.size(); j++) {
+ const FieldDescriptor* field = chunk[j];
+ const FieldGenerator& generator = field_generators_.get(field);
+ bool have_enclosing_if = false;
+ bool need_extra_newline = false;
+
+ PrintFieldComment(format, field);
+
+ if (field->is_repeated()) {
+ // No presence check is required.
+ need_extra_newline = true;
+ } else if (HasHasbit(field)) {
+ PrintPresenceCheck(format, field, has_bit_indices_, printer,
+ &cached_has_word_index);
+ have_enclosing_if = true;
+ } else {
+ // Without field presence: field is serialized only if it has a
+ // non-default value.
+ have_enclosing_if =
+ EmitFieldNonDefaultCondition(printer, "this->", field);
+ }
+
+ generator.GenerateByteSize(printer);
+
+ if (have_enclosing_if) {
+ format.Outdent();
+ format(
+ "}\n"
+ "\n");
+ }
+ if (need_extra_newline) {
+ format("\n");
+ }
+ }
+
+ if (have_outer_if) {
+ format.Outdent();
+ format("}\n");
+ }
+
+ if (cold_skipper.OnEndChunk(chunk_index, printer)) {
+ // Reset here as it may have been updated in just closed if statement.
+ cached_has_word_index = -1;
+ }
+ }
+
+ // Fields inside a oneof don't use _has_bits_ so we count them in a separate
+ // pass.
+ for (auto oneof : OneOfRange(descriptor_)) {
+ format("switch ($1$_case()) {\n", oneof->name());
+ format.Indent();
+ for (auto field : FieldRange(oneof)) {
+ PrintFieldComment(format, field);
+ format("case k$1$: {\n", UnderscoresToCamelCase(field->name(), true));
+ format.Indent();
+ if (!IsFieldStripped(field, options_)) {
+ field_generators_.get(field).GenerateByteSize(printer);
+ }
+ format("break;\n");
+ format.Outdent();
+ format("}\n");
+ }
+ format(
+ "case $1$_NOT_SET: {\n"
+ " break;\n"
+ "}\n",
+ ToUpper(oneof->name()));
+ format.Outdent();
+ format("}\n");
+ }
+
+ if (num_weak_fields_) {
+ // TagSize + MessageSize
+ format("total_size += _weak_field_map_.ByteSizeLong();\n");
+ }
+
+ if (UseUnknownFieldSet(descriptor_->file(), options_)) {
+ // We go out of our way to put the computation of the uncommon path of
+ // unknown fields in tail position. This allows for better code generation
+ // of this function for simple protos.
+ format(
+ "return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_);\n");
+ } else {
+ format("if (PROTOBUF_PREDICT_FALSE($have_unknown_fields$)) {\n");
+ format(" total_size += $unknown_fields$.size();\n");
+ format("}\n");
+
+ // We update _cached_size_ even though this is a const method. Because
+ // const methods might be called concurrently this needs to be atomic
+ // operations or the program is undefined. In practice, since any
+ // concurrent writes will be writing the exact same value, normal writes
+ // will work on all common processors. We use a dedicated wrapper class to
+ // abstract away the underlying atomic. This makes it easier on platforms
+ // where even relaxed memory order might have perf impact to replace it with
+ // ordinary loads and stores.
+ format(
+ "int cached_size = ::$proto_ns$::internal::ToCachedSize(total_size);\n"
+ "SetCachedSize(cached_size);\n"
+ "return total_size;\n");
+ }
+
+ format.Outdent();
+ format("}\n");
+}
+
+void MessageGenerator::GenerateIsInitialized(io::Printer* printer) {
+ if (HasSimpleBaseClass(descriptor_, options_)) return;
+ Formatter format(printer, variables_);
+ format("bool $classname$::IsInitialized() const {\n");
+ format.Indent();
+
+ if (descriptor_->extension_range_count() > 0) {
+ format(
+ "if (!_extensions_.IsInitialized()) {\n"
+ " return false;\n"
+ "}\n\n");
+ }
+
+ if (num_required_fields_ > 0) {
+ format(
+ "if (_Internal::MissingRequiredFields(_has_bits_))"
+ " return false;\n");
+ }
+
+ // Now check that all non-oneof embedded messages are initialized.
+ for (auto field : optimized_order_) {
+ field_generators_.get(field).GenerateIsInitialized(printer);
+ }
+ if (num_weak_fields_) {
+ // For Weak fields.
+ format("if (!_weak_field_map_.IsInitialized()) return false;\n");
+ }
+ // Go through the oneof fields, emitting a switch if any might have required
+ // fields.
+ for (auto oneof : OneOfRange(descriptor_)) {
+ bool has_required_fields = false;
+ for (auto field : FieldRange(oneof)) {
+ if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
+ !ShouldIgnoreRequiredFieldCheck(field, options_) &&
+ scc_analyzer_->HasRequiredFields(field->message_type())) {
+ has_required_fields = true;
+ break;
+ }
+ }
+
+ if (!has_required_fields) {
+ continue;
+ }
+
+ format("switch ($1$_case()) {\n", oneof->name());
+ format.Indent();
+ for (auto field : FieldRange(oneof)) {
+ format("case k$1$: {\n", UnderscoresToCamelCase(field->name(), true));
+ format.Indent();
+ if (!IsFieldStripped(field, options_)) {
+ field_generators_.get(field).GenerateIsInitialized(printer);
+ }
+ format("break;\n");
+ format.Outdent();
+ format("}\n");
+ }
+ format(
+ "case $1$_NOT_SET: {\n"
+ " break;\n"
+ "}\n",
+ ToUpper(oneof->name()));
+ format.Outdent();
+ format("}\n");
+ }
+
+ format.Outdent();
+ format(
+ " return true;\n"
+ "}\n");
+}
+
+} // namespace cpp
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#include <port_undef.inc>
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_message.h b/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_message.h
new file mode 100644
index 00000000..592af570
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_message.h
@@ -0,0 +1,231 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 GOOGLE_PROTOBUF_COMPILER_CPP_MESSAGE_H__
+#define GOOGLE_PROTOBUF_COMPILER_CPP_MESSAGE_H__
+
+#include <cstdint>
+#include <memory>
+#include <set>
+#include <string>
+
+#include <compiler/cpp/cpp_field.h>
+#include <compiler/cpp/cpp_helpers.h>
+#include <compiler/cpp/cpp_message_layout_helper.h>
+#include <compiler/cpp/cpp_options.h>
+#include <compiler/cpp/cpp_parse_function_generator.h>
+
+namespace google {
+namespace protobuf {
+namespace io {
+class Printer; // printer.h
+}
+} // namespace protobuf
+} // namespace google
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+class EnumGenerator; // enum.h
+class ExtensionGenerator; // extension.h
+
+class MessageGenerator {
+ public:
+ // See generator.cc for the meaning of dllexport_decl.
+ MessageGenerator(const Descriptor* descriptor,
+ const std::map<std::string, std::string>& vars,
+ int index_in_file_messages, const Options& options,
+ MessageSCCAnalyzer* scc_analyzer);
+ ~MessageGenerator();
+
+ // Append the two types of nested generators to the corresponding vector.
+ void AddGenerators(
+ std::vector<std::unique_ptr<EnumGenerator>>* enum_generators,
+ std::vector<std::unique_ptr<ExtensionGenerator>>* extension_generators);
+
+ // Generate definitions for this class and all its nested types.
+ void GenerateClassDefinition(io::Printer* printer);
+
+ // Generate definitions of inline methods (placed at the end of the header
+ // file).
+ void GenerateInlineMethods(io::Printer* printer);
+
+ // Source file stuff.
+
+ // Generate all non-inline methods for this class.
+ void GenerateClassMethods(io::Printer* printer);
+
+ // Generate source file code that should go outside any namespace.
+ void GenerateSourceInProto2Namespace(io::Printer* printer);
+
+ private:
+ // Generate declarations and definitions of accessors for fields.
+ void GenerateFieldAccessorDeclarations(io::Printer* printer);
+ void GenerateFieldAccessorDefinitions(io::Printer* printer);
+
+ // Generate the table-driven parsing array. Returns the number of entries
+ // generated.
+ size_t GenerateParseOffsets(io::Printer* printer);
+ size_t GenerateParseAuxTable(io::Printer* printer);
+ // Generates a ParseTable entry. Returns whether the proto uses
+ // table-driven parsing.
+ bool GenerateParseTable(io::Printer* printer, size_t offset,
+ size_t aux_offset);
+
+ // Generate the field offsets array. Returns the a pair of the total number
+ // of entries generated and the index of the first has_bit entry.
+ std::pair<size_t, size_t> GenerateOffsets(io::Printer* printer);
+ void GenerateSchema(io::Printer* printer, int offset, int has_offset);
+ // For each field generates a table entry describing the field for the
+ // table driven serializer.
+ int GenerateFieldMetadata(io::Printer* printer);
+
+ // Generate constructors and destructor.
+ void GenerateStructors(io::Printer* printer);
+
+ // The compiler typically generates multiple copies of each constructor and
+ // destructor: http://gcc.gnu.org/bugs.html#nonbugs_cxx
+ // Placing common code in a separate method reduces the generated code size.
+ //
+ // Generate the shared constructor code.
+ void GenerateSharedConstructorCode(io::Printer* printer);
+ // Generate the shared destructor code.
+ void GenerateSharedDestructorCode(io::Printer* printer);
+ // Generate the arena-specific destructor code.
+ void GenerateArenaDestructorCode(io::Printer* printer);
+
+ // Generate the constexpr constructor for constant initialization of the
+ // default instance.
+ void GenerateConstexprConstructor(io::Printer* printer);
+
+ // Generate standard Message methods.
+ void GenerateClear(io::Printer* printer);
+ void GenerateOneofClear(io::Printer* printer);
+ void GenerateVerify(io::Printer* printer);
+ void GenerateSerializeWithCachedSizes(io::Printer* printer);
+ void GenerateSerializeWithCachedSizesToArray(io::Printer* printer);
+ void GenerateSerializeWithCachedSizesBody(io::Printer* printer);
+ void GenerateSerializeWithCachedSizesBodyShuffled(io::Printer* printer);
+ void GenerateByteSize(io::Printer* printer);
+ void GenerateMergeFrom(io::Printer* printer);
+ void GenerateClassSpecificMergeFrom(io::Printer* printer);
+ void GenerateCopyFrom(io::Printer* printer);
+ void GenerateSwap(io::Printer* printer);
+ void GenerateIsInitialized(io::Printer* printer);
+
+ // Helpers for GenerateSerializeWithCachedSizes().
+ //
+ // cached_has_bit_index maintains that:
+ // cached_has_bits = _has_bits_[cached_has_bit_index]
+ // for cached_has_bit_index >= 0
+ void GenerateSerializeOneField(io::Printer* printer,
+ const FieldDescriptor* field,
+ int cached_has_bits_index);
+ // Generate a switch statement to serialize 2+ fields from the same oneof.
+ // Or, if fields.size() == 1, just call GenerateSerializeOneField().
+ void GenerateSerializeOneofFields(
+ io::Printer* printer, const std::vector<const FieldDescriptor*>& fields);
+ void GenerateSerializeOneExtensionRange(
+ io::Printer* printer, const Descriptor::ExtensionRange* range);
+
+ // Generates has_foo() functions and variables for singular field has-bits.
+ void GenerateSingularFieldHasBits(const FieldDescriptor* field,
+ Formatter format);
+ // Generates has_foo() functions and variables for oneof field has-bits.
+ void GenerateOneofHasBits(io::Printer* printer);
+ // Generates has_foo_bar() functions for oneof members.
+ void GenerateOneofMemberHasBits(const FieldDescriptor* field,
+ const Formatter& format);
+ // Generates the clear_foo() method for a field.
+ void GenerateFieldClear(const FieldDescriptor* field, bool is_inline,
+ Formatter format);
+
+ void GenerateConstructorBody(io::Printer* printer,
+ std::vector<bool> already_processed,
+ bool copy_constructor) const;
+
+ size_t HasBitsSize() const;
+ size_t InlinedStringDonatedSize() const;
+ int HasBitIndex(const FieldDescriptor* a) const;
+ int HasByteIndex(const FieldDescriptor* a) const;
+ int HasWordIndex(const FieldDescriptor* a) const;
+ bool SameHasByte(const FieldDescriptor* a, const FieldDescriptor* b) const;
+ std::vector<uint32_t> RequiredFieldsBitMask() const;
+
+ const Descriptor* descriptor_;
+ int index_in_file_messages_;
+ std::string classname_;
+ Options options_;
+ FieldGeneratorMap field_generators_;
+ // optimized_order_ is the order we layout the message's fields in the
+ // class. This is reused to initialize the fields in-order for cache
+ // efficiency.
+ //
+ // optimized_order_ excludes oneof fields and weak fields.
+ std::vector<const FieldDescriptor*> optimized_order_;
+ std::vector<int> has_bit_indices_;
+ int max_has_bit_index_;
+
+ // A map from field index to inlined_string index. For non-inlined-string
+ // fields, the element is -1.
+ std::vector<int> inlined_string_indices_;
+ // The count of inlined_string fields in the message.
+ int max_inlined_string_index_;
+
+ std::vector<const EnumGenerator*> enum_generators_;
+ std::vector<const ExtensionGenerator*> extension_generators_;
+ int num_required_fields_;
+ int num_weak_fields_;
+ // table_driven_ indicates the generated message uses table-driven parsing.
+ bool table_driven_;
+
+ std::unique_ptr<MessageLayoutHelper> message_layout_helper_;
+ std::unique_ptr<ParseFunctionGenerator> parse_function_generator_;
+
+ MessageSCCAnalyzer* scc_analyzer_;
+
+ std::map<std::string, std::string> variables_;
+
+ friend class FileGenerator;
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageGenerator);
+};
+
+} // namespace cpp
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_COMPILER_CPP_MESSAGE_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_message_field.cc b/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_message_field.cc
new file mode 100644
index 00000000..a0b80bd0
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_message_field.cc
@@ -0,0 +1,892 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 <compiler/cpp/cpp_message_field.h>
+#include <compiler/cpp/cpp_helpers.h>
+#include <io/printer.h>
+
+#include <stubs/strutil.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+namespace {
+std::string ReinterpretCast(const std::string& type,
+ const std::string& expression,
+ bool implicit_weak_field) {
+ if (implicit_weak_field) {
+ return "reinterpret_cast< " + type + " >(" + expression + ")";
+ } else {
+ return expression;
+ }
+}
+
+void SetMessageVariables(const FieldDescriptor* descriptor,
+ const Options& options, bool implicit_weak,
+ std::map<std::string, std::string>* variables) {
+ SetCommonFieldVariables(descriptor, variables, options);
+ (*variables)["type"] = FieldMessageTypeName(descriptor, options);
+ (*variables)["casted_member"] = ReinterpretCast(
+ (*variables)["type"] + "*", (*variables)["name"] + "_", implicit_weak);
+ (*variables)["type_default_instance"] =
+ QualifiedDefaultInstanceName(descriptor->message_type(), options);
+ (*variables)["type_default_instance_ptr"] =
+ QualifiedDefaultInstancePtr(descriptor->message_type(), options);
+ (*variables)["type_reference_function"] =
+ implicit_weak ? (" ::" + (*variables)["proto_ns"] +
+ "::internal::StrongReference(reinterpret_cast<const " +
+ (*variables)["type"] + "&>(\n" +
+ (*variables)["type_default_instance"] + "));\n")
+ : "";
+ // NOTE: Escaped here to unblock proto1->proto2 migration.
+ // TODO(liujisi): Extend this to apply for other conflicting methods.
+ (*variables)["release_name"] =
+ SafeFunctionName(descriptor->containing_type(), descriptor, "release_");
+ (*variables)["full_name"] = descriptor->full_name();
+}
+
+} // namespace
+
+// ===================================================================
+
+MessageFieldGenerator::MessageFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options,
+ MessageSCCAnalyzer* scc_analyzer)
+ : FieldGenerator(descriptor, options),
+ implicit_weak_field_(
+ IsImplicitWeakField(descriptor, options, scc_analyzer)),
+ has_required_fields_(
+ scc_analyzer->HasRequiredFields(descriptor->message_type())) {
+ SetMessageVariables(descriptor, options, implicit_weak_field_, &variables_);
+}
+
+MessageFieldGenerator::~MessageFieldGenerator() {}
+
+void MessageFieldGenerator::GeneratePrivateMembers(io::Printer* printer) const {
+ Formatter format(printer, variables_);
+ if (implicit_weak_field_) {
+ format("::$proto_ns$::MessageLite* $name$_;\n");
+ } else {
+ format("$type$* $name$_;\n");
+ }
+}
+
+void MessageFieldGenerator::GenerateAccessorDeclarations(
+ io::Printer* printer) const {
+ Formatter format(printer, variables_);
+ if (IsFieldStripped(descriptor_, options_)) {
+ format(
+ "$deprecated_attr$const $type$& ${1$$name$$}$() const { "
+ "__builtin_trap(); }\n"
+ "PROTOBUF_NODISCARD $deprecated_attr$$type$* "
+ "${1$$release_name$$}$() { "
+ "__builtin_trap(); }\n"
+ "$deprecated_attr$$type$* ${1$mutable_$name$$}$() { "
+ "__builtin_trap(); }\n"
+ "$deprecated_attr$void ${1$set_allocated_$name$$}$"
+ "($type$* $name$) { __builtin_trap(); }\n"
+ "$deprecated_attr$void "
+ "${1$unsafe_arena_set_allocated_$name$$}$(\n"
+ " $type$* $name$) { __builtin_trap(); }\n"
+ "$deprecated_attr$$type$* ${1$unsafe_arena_release_$name$$}$() { "
+ "__builtin_trap(); }\n",
+ descriptor_);
+ return;
+ }
+ format(
+ "$deprecated_attr$const $type$& ${1$$name$$}$() const;\n"
+ "PROTOBUF_NODISCARD $deprecated_attr$$type$* "
+ "${1$$release_name$$}$();\n"
+ "$deprecated_attr$$type$* ${1$mutable_$name$$}$();\n"
+ "$deprecated_attr$void ${1$set_allocated_$name$$}$"
+ "($type$* $name$);\n",
+ descriptor_);
+ if (!IsFieldStripped(descriptor_, options_)) {
+ format(
+ "private:\n"
+ "const $type$& ${1$_internal_$name$$}$() const;\n"
+ "$type$* ${1$_internal_mutable_$name$$}$();\n"
+ "public:\n",
+ descriptor_);
+ }
+ format(
+ "$deprecated_attr$void "
+ "${1$unsafe_arena_set_allocated_$name$$}$(\n"
+ " $type$* $name$);\n"
+ "$deprecated_attr$$type$* ${1$unsafe_arena_release_$name$$}$();\n",
+ descriptor_);
+}
+
+void MessageFieldGenerator::GenerateNonInlineAccessorDefinitions(
+ io::Printer* printer) const {
+}
+
+void MessageFieldGenerator::GenerateInlineAccessorDefinitions(
+ io::Printer* printer) const {
+ Formatter format(printer, variables_);
+ format(
+ "inline const $type$& $classname$::_internal_$name$() const {\n"
+ "$type_reference_function$"
+ " const $type$* p = $casted_member$;\n"
+ " return p != nullptr ? *p : reinterpret_cast<const $type$&>(\n"
+ " $type_default_instance$);\n"
+ "}\n"
+ "inline const $type$& $classname$::$name$() const {\n"
+ "$annotate_get$"
+ " // @@protoc_insertion_point(field_get:$full_name$)\n"
+ " return _internal_$name$();\n"
+ "}\n");
+
+ format(
+ "inline void $classname$::unsafe_arena_set_allocated_$name$(\n"
+ " $type$* $name$) {\n"
+ // If we're not on an arena, free whatever we were holding before.
+ // (If we are on arena, we can just forget the earlier pointer.)
+ " if (GetArenaForAllocation() == nullptr) {\n"
+ " delete reinterpret_cast<::$proto_ns$::MessageLite*>($name$_);\n"
+ " }\n");
+ if (implicit_weak_field_) {
+ format(
+ " $name$_ = "
+ "reinterpret_cast<::$proto_ns$::MessageLite*>($name$);\n");
+ } else {
+ format(" $name$_ = $name$;\n");
+ }
+ format(
+ " if ($name$) {\n"
+ " $set_hasbit$\n"
+ " } else {\n"
+ " $clear_hasbit$\n"
+ " }\n"
+ "$annotate_set$"
+ " // @@protoc_insertion_point(field_unsafe_arena_set_allocated"
+ ":$full_name$)\n"
+ "}\n");
+ format(
+ "inline $type$* $classname$::$release_name$() {\n"
+ "$type_reference_function$"
+ "$annotate_release$"
+ " $clear_hasbit$\n"
+ " $type$* temp = $casted_member$;\n"
+ " $name$_ = nullptr;\n"
+ "#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE\n"
+ " auto* old = reinterpret_cast<::$proto_ns$::MessageLite*>(temp);\n"
+ " temp = ::$proto_ns$::internal::DuplicateIfNonNull(temp);\n"
+ " if (GetArenaForAllocation() == nullptr) { delete old; }\n"
+ "#else // PROTOBUF_FORCE_COPY_IN_RELEASE\n"
+ " if (GetArenaForAllocation() != nullptr) {\n"
+ " temp = ::$proto_ns$::internal::DuplicateIfNonNull(temp);\n"
+ " }\n"
+ "#endif // !PROTOBUF_FORCE_COPY_IN_RELEASE\n"
+ " return temp;\n"
+ "}\n"
+ "inline $type$* $classname$::unsafe_arena_release_$name$() {\n"
+ "$annotate_release$"
+ " // @@protoc_insertion_point(field_release:$full_name$)\n"
+ "$type_reference_function$"
+ " $clear_hasbit$\n"
+ " $type$* temp = $casted_member$;\n"
+ " $name$_ = nullptr;\n"
+ " return temp;\n"
+ "}\n");
+
+ format(
+ "inline $type$* $classname$::_internal_mutable_$name$() {\n"
+ "$type_reference_function$"
+ " $set_hasbit$\n"
+ " if ($name$_ == nullptr) {\n"
+ " auto* p = CreateMaybeMessage<$type$>(GetArenaForAllocation());\n");
+ if (implicit_weak_field_) {
+ format(" $name$_ = reinterpret_cast<::$proto_ns$::MessageLite*>(p);\n");
+ } else {
+ format(" $name$_ = p;\n");
+ }
+ format(
+ " }\n"
+ " return $casted_member$;\n"
+ "}\n"
+ "inline $type$* $classname$::mutable_$name$() {\n"
+ " $type$* _msg = _internal_mutable_$name$();\n"
+ "$annotate_mutable$"
+ " // @@protoc_insertion_point(field_mutable:$full_name$)\n"
+ " return _msg;\n"
+ "}\n");
+
+ // We handle the most common case inline, and delegate less common cases to
+ // the slow fallback function.
+ format(
+ "inline void $classname$::set_allocated_$name$($type$* $name$) {\n"
+ " ::$proto_ns$::Arena* message_arena = GetArenaForAllocation();\n");
+ format(" if (message_arena == nullptr) {\n");
+ if (IsCrossFileMessage(descriptor_)) {
+ format(
+ " delete reinterpret_cast< ::$proto_ns$::MessageLite*>($name$_);\n");
+ } else {
+ format(" delete $name$_;\n");
+ }
+ format(
+ " }\n"
+ " if ($name$) {\n");
+ if (IsCrossFileMessage(descriptor_)) {
+ // We have to read the arena through the virtual method, because the type
+ // isn't defined in this file.
+ format(
+ " ::$proto_ns$::Arena* submessage_arena =\n"
+ " ::$proto_ns$::Arena::InternalHelper<\n"
+ " ::$proto_ns$::MessageLite>::GetOwningArena(\n"
+ " reinterpret_cast<::$proto_ns$::MessageLite*>("
+ "$name$));\n");
+ } else {
+ format(
+ " ::$proto_ns$::Arena* submessage_arena =\n"
+ " ::$proto_ns$::Arena::InternalHelper<$type$>::GetOwningArena("
+ "$name$);\n");
+ }
+ format(
+ " if (message_arena != submessage_arena) {\n"
+ " $name$ = ::$proto_ns$::internal::GetOwnedMessage(\n"
+ " message_arena, $name$, submessage_arena);\n"
+ " }\n"
+ " $set_hasbit$\n"
+ " } else {\n"
+ " $clear_hasbit$\n"
+ " }\n");
+ if (implicit_weak_field_) {
+ format(" $name$_ = reinterpret_cast<MessageLite*>($name$);\n");
+ } else {
+ format(" $name$_ = $name$;\n");
+ }
+ format(
+ "$annotate_set$"
+ " // @@protoc_insertion_point(field_set_allocated:$full_name$)\n"
+ "}\n");
+}
+
+void MessageFieldGenerator::GenerateInternalAccessorDeclarations(
+ io::Printer* printer) const {
+ Formatter format(printer, variables_);
+ if (implicit_weak_field_) {
+ format(
+ "static const ::$proto_ns$::MessageLite& $name$("
+ "const $classname$* msg);\n"
+ "static ::$proto_ns$::MessageLite* mutable_$name$("
+ "$classname$* msg);\n");
+ } else {
+ format("static const $type$& $name$(const $classname$* msg);\n");
+ }
+}
+
+void MessageFieldGenerator::GenerateInternalAccessorDefinitions(
+ io::Printer* printer) const {
+ // In theory, these accessors could be inline in _Internal. However, in
+ // practice, the linker is then not able to throw them out making implicit
+ // weak dependencies not work at all.
+ Formatter format(printer, variables_);
+ if (implicit_weak_field_) {
+ // These private accessors are used by MergeFrom and
+ // MergePartialFromCodedStream, and their purpose is to provide access to
+ // the field without creating a strong dependency on the message type.
+ format(
+ "const ::$proto_ns$::MessageLite& $classname$::_Internal::$name$(\n"
+ " const $classname$* msg) {\n"
+ " if (msg->$name$_ != nullptr) {\n"
+ " return *msg->$name$_;\n"
+ " } else if ($type_default_instance_ptr$ != nullptr) {\n"
+ " return *reinterpret_cast<const ::$proto_ns$::MessageLite*>(\n"
+ " $type_default_instance_ptr$);\n"
+ " } else {\n"
+ " return "
+ "*::$proto_ns$::internal::ImplicitWeakMessage::default_instance();\n"
+ " }\n"
+ "}\n");
+ format(
+ "::$proto_ns$::MessageLite*\n"
+ "$classname$::_Internal::mutable_$name$($classname$* msg) {\n");
+ if (HasHasbit(descriptor_)) {
+ format(" msg->$set_hasbit$\n");
+ }
+ format(
+ " if (msg->$name$_ == nullptr) {\n"
+ " if ($type_default_instance_ptr$ == nullptr) {\n"
+ " msg->$name$_ = ::$proto_ns$::Arena::CreateMessage<\n"
+ " ::$proto_ns$::internal::ImplicitWeakMessage>(\n"
+ " msg->GetArenaForAllocation());\n"
+ " } else {\n"
+ " msg->$name$_ = \n"
+ " reinterpret_cast<const ::$proto_ns$::MessageLite*>(\n"
+ " $type_default_instance_ptr$)->New(\n"
+ " msg->GetArenaForAllocation());\n"
+ " }\n"
+ " }\n"
+ " return msg->$name$_;\n"
+ "}\n");
+ } else {
+ // This inline accessor directly returns member field and is used in
+ // Serialize such that AFDO profile correctly captures access information to
+ // message fields under serialize.
+ format(
+ "const $type$&\n"
+ "$classname$::_Internal::$name$(const $classname$* msg) {\n"
+ " return *msg->$field_member$;\n"
+ "}\n");
+ }
+}
+
+void MessageFieldGenerator::GenerateClearingCode(io::Printer* printer) const {
+ GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
+
+ Formatter format(printer, variables_);
+ if (!HasHasbit(descriptor_)) {
+ // If we don't have has-bits, message presence is indicated only by ptr !=
+ // NULL. Thus on clear, we need to delete the object.
+ format(
+ "if (GetArenaForAllocation() == nullptr && $name$_ != nullptr) {\n"
+ " delete $name$_;\n"
+ "}\n"
+ "$name$_ = nullptr;\n");
+ } else {
+ format("if ($name$_ != nullptr) $name$_->Clear();\n");
+ }
+}
+
+void MessageFieldGenerator::GenerateMessageClearingCode(
+ io::Printer* printer) const {
+ GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
+
+ Formatter format(printer, variables_);
+ if (!HasHasbit(descriptor_)) {
+ // If we don't have has-bits, message presence is indicated only by ptr !=
+ // NULL. Thus on clear, we need to delete the object.
+ format(
+ "if (GetArenaForAllocation() == nullptr && $name$_ != nullptr) {\n"
+ " delete $name$_;\n"
+ "}\n"
+ "$name$_ = nullptr;\n");
+ } else {
+ format(
+ "$DCHK$($name$_ != nullptr);\n"
+ "$name$_->Clear();\n");
+ }
+}
+
+void MessageFieldGenerator::GenerateMergingCode(io::Printer* printer) const {
+ GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
+
+ Formatter format(printer, variables_);
+ if (implicit_weak_field_) {
+ format(
+ "_Internal::mutable_$name$(this)->CheckTypeAndMergeFrom(\n"
+ " _Internal::$name$(&from));\n");
+ } else {
+ format(
+ "_internal_mutable_$name$()->$type$::MergeFrom(from._internal_$name$())"
+ ";\n");
+ }
+}
+
+void MessageFieldGenerator::GenerateSwappingCode(io::Printer* printer) const {
+ GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
+
+ Formatter format(printer, variables_);
+ format("swap($name$_, other->$name$_);\n");
+}
+
+void MessageFieldGenerator::GenerateDestructorCode(io::Printer* printer) const {
+ GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
+
+ Formatter format(printer, variables_);
+ if (options_.opensource_runtime) {
+ // TODO(gerbens) Remove this when we don't need to destruct default
+ // instances. In google3 a default instance will never get deleted so we
+ // don't need to worry about that but in opensource protobuf default
+ // instances are deleted in shutdown process and we need to take special
+ // care when handling them.
+ format("if (this != internal_default_instance()) ");
+ }
+ format("delete $name$_;\n");
+}
+
+void MessageFieldGenerator::GenerateConstructorCode(
+ io::Printer* printer) const {
+ GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
+
+ Formatter format(printer, variables_);
+ format("$name$_ = nullptr;\n");
+}
+
+void MessageFieldGenerator::GenerateCopyConstructorCode(
+ io::Printer* printer) const {
+ GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
+
+ Formatter format(printer, variables_);
+ format(
+ "if (from._internal_has_$name$()) {\n"
+ " $name$_ = new $type$(*from.$name$_);\n"
+ "} else {\n"
+ " $name$_ = nullptr;\n"
+ "}\n");
+}
+
+void MessageFieldGenerator::GenerateSerializeWithCachedSizesToArray(
+ io::Printer* printer) const {
+ GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
+
+ Formatter format(printer, variables_);
+ format(
+ "target = stream->EnsureSpace(target);\n"
+ "target = ::$proto_ns$::internal::WireFormatLite::\n"
+ " InternalWrite$declared_type$(\n"
+ " $number$, _Internal::$name$(this), target, stream);\n");
+}
+
+void MessageFieldGenerator::GenerateByteSize(io::Printer* printer) const {
+ GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
+
+ Formatter format(printer, variables_);
+ format(
+ "total_size += $tag_size$ +\n"
+ " ::$proto_ns$::internal::WireFormatLite::$declared_type$Size(\n"
+ " *$field_member$);\n");
+}
+
+void MessageFieldGenerator::GenerateIsInitialized(io::Printer* printer) const {
+ GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
+
+ if (!has_required_fields_) return;
+
+ Formatter format(printer, variables_);
+ format(
+ "if (_internal_has_$name$()) {\n"
+ " if (!$name$_->IsInitialized()) return false;\n"
+ "}\n");
+}
+
+void MessageFieldGenerator::GenerateConstinitInitializer(
+ io::Printer* printer) const {
+ Formatter format(printer, variables_);
+ format("$name$_(nullptr)");
+}
+
+// ===================================================================
+
+MessageOneofFieldGenerator::MessageOneofFieldGenerator(
+ const FieldDescriptor* descriptor, const Options& options,
+ MessageSCCAnalyzer* scc_analyzer)
+ : MessageFieldGenerator(descriptor, options, scc_analyzer) {
+ SetCommonOneofFieldVariables(descriptor, &variables_);
+}
+
+MessageOneofFieldGenerator::~MessageOneofFieldGenerator() {}
+
+void MessageOneofFieldGenerator::GenerateNonInlineAccessorDefinitions(
+ io::Printer* printer) const {
+ Formatter format(printer, variables_);
+ format(
+ "void $classname$::set_allocated_$name$($type$* $name$) {\n"
+ " ::$proto_ns$::Arena* message_arena = GetArenaForAllocation();\n"
+ " clear_$oneof_name$();\n"
+ " if ($name$) {\n");
+ if (descriptor_->file() != descriptor_->message_type()->file()) {
+ // We have to read the arena through the virtual method, because the type
+ // isn't defined in this file.
+ format(
+ " ::$proto_ns$::Arena* submessage_arena =\n"
+ " ::$proto_ns$::Arena::InternalHelper<\n"
+ " ::$proto_ns$::MessageLite>::GetOwningArena(\n"
+ " reinterpret_cast<::$proto_ns$::MessageLite*>("
+ "$name$));\n");
+ } else {
+ format(
+ " ::$proto_ns$::Arena* submessage_arena =\n"
+ " ::$proto_ns$::Arena::InternalHelper<"
+ "$type$>::GetOwningArena($name$);\n");
+ }
+ format(
+ " if (message_arena != submessage_arena) {\n"
+ " $name$ = ::$proto_ns$::internal::GetOwnedMessage(\n"
+ " message_arena, $name$, submessage_arena);\n"
+ " }\n"
+ " set_has_$name$();\n"
+ " $field_member$ = $name$;\n"
+ " }\n"
+ "$annotate_set$"
+ " // @@protoc_insertion_point(field_set_allocated:$full_name$)\n"
+ "}\n");
+}
+
+void MessageOneofFieldGenerator::GenerateInlineAccessorDefinitions(
+ io::Printer* printer) const {
+ Formatter format(printer, variables_);
+ format(
+ "inline $type$* $classname$::$release_name$() {\n"
+ "$annotate_release$"
+ " // @@protoc_insertion_point(field_release:$full_name$)\n"
+ " if (_internal_has_$name$()) {\n"
+ " clear_has_$oneof_name$();\n"
+ " $type$* temp = $field_member$;\n"
+ " if (GetArenaForAllocation() != nullptr) {\n"
+ " temp = ::$proto_ns$::internal::DuplicateIfNonNull(temp);\n"
+ " }\n"
+ " $field_member$ = nullptr;\n"
+ " return temp;\n"
+ " } else {\n"
+ " return nullptr;\n"
+ " }\n"
+ "}\n");
+
+ format(
+ "inline const $type$& $classname$::_internal_$name$() const {\n"
+ " return _internal_has_$name$()\n"
+ " ? *$field_member$\n"
+ " : reinterpret_cast< $type$&>($type_default_instance$);\n"
+ "}\n"
+ "inline const $type$& $classname$::$name$() const {\n"
+ "$annotate_get$"
+ " // @@protoc_insertion_point(field_get:$full_name$)\n"
+ " return _internal_$name$();\n"
+ "}\n"
+ "inline $type$* $classname$::unsafe_arena_release_$name$() {\n"
+ "$annotate_release$"
+ " // @@protoc_insertion_point(field_unsafe_arena_release"
+ ":$full_name$)\n"
+ " if (_internal_has_$name$()) {\n"
+ " clear_has_$oneof_name$();\n"
+ " $type$* temp = $field_member$;\n"
+ " $field_member$ = nullptr;\n"
+ " return temp;\n"
+ " } else {\n"
+ " return nullptr;\n"
+ " }\n"
+ "}\n"
+ "inline void $classname$::unsafe_arena_set_allocated_$name$"
+ "($type$* $name$) {\n"
+ // We rely on the oneof clear method to free the earlier contents of
+ // this oneof. We can directly use the pointer we're given to set the
+ // new value.
+ " clear_$oneof_name$();\n"
+ " if ($name$) {\n"
+ " set_has_$name$();\n"
+ " $field_member$ = $name$;\n"
+ " }\n"
+ "$annotate_set$"
+ " // @@protoc_insertion_point(field_unsafe_arena_set_allocated:"
+ "$full_name$)\n"
+ "}\n"
+ "inline $type$* $classname$::_internal_mutable_$name$() {\n"
+ " if (!_internal_has_$name$()) {\n"
+ " clear_$oneof_name$();\n"
+ " set_has_$name$();\n"
+ " $field_member$ = CreateMaybeMessage< $type$ "
+ ">(GetArenaForAllocation());\n"
+ " }\n"
+ " return $field_member$;\n"
+ "}\n"
+ "inline $type$* $classname$::mutable_$name$() {\n"
+ " $type$* _msg = _internal_mutable_$name$();\n"
+ "$annotate_mutable$"
+ " // @@protoc_insertion_point(field_mutable:$full_name$)\n"
+ " return _msg;\n"
+ "}\n");
+}
+
+void MessageOneofFieldGenerator::GenerateClearingCode(
+ io::Printer* printer) const {
+ GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
+
+ Formatter format(printer, variables_);
+ format(
+ "if (GetArenaForAllocation() == nullptr) {\n"
+ " delete $field_member$;\n"
+ "}\n");
+}
+
+void MessageOneofFieldGenerator::GenerateMessageClearingCode(
+ io::Printer* printer) const {
+ GenerateClearingCode(printer);
+}
+
+void MessageOneofFieldGenerator::GenerateSwappingCode(
+ io::Printer* printer) const {
+ // Don't print any swapping code. Swapping the union will swap this field.
+}
+
+void MessageOneofFieldGenerator::GenerateDestructorCode(
+ io::Printer* printer) const {
+ // We inherit from MessageFieldGenerator, so we need to override the default
+ // behavior.
+}
+
+void MessageOneofFieldGenerator::GenerateConstructorCode(
+ io::Printer* printer) const {
+ // Don't print any constructor code. The field is in a union. We allocate
+ // space only when this field is used.
+}
+
+void MessageOneofFieldGenerator::GenerateIsInitialized(
+ io::Printer* printer) const {
+ if (!has_required_fields_) return;
+
+ Formatter format(printer, variables_);
+ format(
+ "if (_internal_has_$name$()) {\n"
+ " if (!$field_member$->IsInitialized()) return false;\n"
+ "}\n");
+}
+
+// ===================================================================
+
+RepeatedMessageFieldGenerator::RepeatedMessageFieldGenerator(
+ const FieldDescriptor* descriptor, const Options& options,
+ MessageSCCAnalyzer* scc_analyzer)
+ : FieldGenerator(descriptor, options),
+ implicit_weak_field_(
+ IsImplicitWeakField(descriptor, options, scc_analyzer)),
+ has_required_fields_(
+ scc_analyzer->HasRequiredFields(descriptor->message_type())) {
+ SetMessageVariables(descriptor, options, implicit_weak_field_, &variables_);
+}
+
+RepeatedMessageFieldGenerator::~RepeatedMessageFieldGenerator() {}
+
+void RepeatedMessageFieldGenerator::GeneratePrivateMembers(
+ io::Printer* printer) const {
+ Formatter format(printer, variables_);
+ if (implicit_weak_field_) {
+ format("::$proto_ns$::WeakRepeatedPtrField< $type$ > $name$_;\n");
+ } else {
+ format("::$proto_ns$::RepeatedPtrField< $type$ > $name$_;\n");
+ }
+}
+
+void RepeatedMessageFieldGenerator::GenerateAccessorDeclarations(
+ io::Printer* printer) const {
+ Formatter format(printer, variables_);
+ if (IsFieldStripped(descriptor_, options_)) {
+ format(
+ "$deprecated_attr$$type$* ${1$mutable_$name$$}$(int index) { "
+ "__builtin_trap(); }\n"
+ "$deprecated_attr$::$proto_ns$::RepeatedPtrField< $type$ >*\n"
+ " ${1$mutable_$name$$}$() { __builtin_trap(); }\n"
+ "$deprecated_attr$const $type$& ${1$$name$$}$(int index) const { "
+ "__builtin_trap(); }\n"
+ "$deprecated_attr$$type$* ${1$add_$name$$}$() { "
+ "__builtin_trap(); }\n"
+ "$deprecated_attr$const ::$proto_ns$::RepeatedPtrField< $type$ >&\n"
+ " ${1$$name$$}$() const { __builtin_trap(); }\n",
+ descriptor_);
+ return;
+ }
+ format(
+ "$deprecated_attr$$type$* ${1$mutable_$name$$}$(int index);\n"
+ "$deprecated_attr$::$proto_ns$::RepeatedPtrField< $type$ >*\n"
+ " ${1$mutable_$name$$}$();\n",
+ descriptor_);
+ if (!IsFieldStripped(descriptor_, options_)) {
+ format(
+ "private:\n"
+ "const $type$& ${1$_internal_$name$$}$(int index) const;\n"
+ "$type$* ${1$_internal_add_$name$$}$();\n"
+ "public:\n",
+ descriptor_);
+ }
+ format(
+ "$deprecated_attr$const $type$& ${1$$name$$}$(int index) const;\n"
+ "$deprecated_attr$$type$* ${1$add_$name$$}$();\n"
+ "$deprecated_attr$const ::$proto_ns$::RepeatedPtrField< $type$ >&\n"
+ " ${1$$name$$}$() const;\n",
+ descriptor_);
+}
+
+void RepeatedMessageFieldGenerator::GenerateInlineAccessorDefinitions(
+ io::Printer* printer) const {
+ Formatter format(printer, variables_);
+ format.Set("weak", implicit_weak_field_ ? ".weak" : "");
+
+ format(
+ "inline $type$* $classname$::mutable_$name$(int index) {\n"
+ "$annotate_mutable$"
+ // TODO(dlj): move insertion points
+ " // @@protoc_insertion_point(field_mutable:$full_name$)\n"
+ "$type_reference_function$"
+ " return $name$_$weak$.Mutable(index);\n"
+ "}\n"
+ "inline ::$proto_ns$::RepeatedPtrField< $type$ >*\n"
+ "$classname$::mutable_$name$() {\n"
+ "$annotate_mutable_list$"
+ " // @@protoc_insertion_point(field_mutable_list:$full_name$)\n"
+ "$type_reference_function$"
+ " return &$name$_$weak$;\n"
+ "}\n");
+
+ if (options_.safe_boundary_check) {
+ format(
+ "inline const $type$& $classname$::_internal_$name$(int index) const "
+ "{\n"
+ " return $name$_$weak$.InternalCheckedGet(index,\n"
+ " reinterpret_cast<const $type$&>($type_default_instance$));\n"
+ "}\n");
+ } else {
+ format(
+ "inline const $type$& $classname$::_internal_$name$(int index) const "
+ "{\n"
+ "$type_reference_function$"
+ " return $name$_$weak$.Get(index);\n"
+ "}\n");
+ }
+
+ format(
+ "inline const $type$& $classname$::$name$(int index) const {\n"
+ "$annotate_get$"
+ " // @@protoc_insertion_point(field_get:$full_name$)\n"
+ " return _internal_$name$(index);\n"
+ "}\n"
+ "inline $type$* $classname$::_internal_add_$name$() {\n"
+ " return $name$_$weak$.Add();\n"
+ "}\n"
+ "inline $type$* $classname$::add_$name$() {\n"
+ " $type$* _add = _internal_add_$name$();\n"
+ "$annotate_add_mutable$"
+ " // @@protoc_insertion_point(field_add:$full_name$)\n"
+ " return _add;\n"
+ "}\n");
+
+ format(
+ "inline const ::$proto_ns$::RepeatedPtrField< $type$ >&\n"
+ "$classname$::$name$() const {\n"
+ "$annotate_list$"
+ " // @@protoc_insertion_point(field_list:$full_name$)\n"
+ "$type_reference_function$"
+ " return $name$_$weak$;\n"
+ "}\n");
+}
+
+void RepeatedMessageFieldGenerator::GenerateClearingCode(
+ io::Printer* printer) const {
+ GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
+
+ Formatter format(printer, variables_);
+ format("$name$_.Clear();\n");
+}
+
+void RepeatedMessageFieldGenerator::GenerateMergingCode(
+ io::Printer* printer) const {
+ GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
+
+ Formatter format(printer, variables_);
+ format("$name$_.MergeFrom(from.$name$_);\n");
+}
+
+void RepeatedMessageFieldGenerator::GenerateSwappingCode(
+ io::Printer* printer) const {
+ GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
+
+ Formatter format(printer, variables_);
+ format("$name$_.InternalSwap(&other->$name$_);\n");
+}
+
+void RepeatedMessageFieldGenerator::GenerateConstructorCode(
+ io::Printer* printer) const {
+ // Not needed for repeated fields.
+}
+
+void RepeatedMessageFieldGenerator::GenerateSerializeWithCachedSizesToArray(
+ io::Printer* printer) const {
+ GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
+
+ Formatter format(printer, variables_);
+ if (implicit_weak_field_) {
+ format(
+ "for (auto it = this->$name$_.pointer_begin(),\n"
+ " end = this->$name$_.pointer_end(); it < end; ++it) {\n"
+ " target = stream->EnsureSpace(target);\n"
+ " target = ::$proto_ns$::internal::WireFormatLite::\n"
+ " InternalWrite$declared_type$($number$, **it, target, stream);\n"
+ "}\n");
+ } else {
+ format(
+ "for (unsigned int i = 0,\n"
+ " n = static_cast<unsigned int>(this->_internal_$name$_size()); i < "
+ "n; i++) "
+ "{\n"
+ " target = stream->EnsureSpace(target);\n"
+ " target = ::$proto_ns$::internal::WireFormatLite::\n"
+ " InternalWrite$declared_type$($number$, "
+ "this->_internal_$name$(i), target, stream);\n"
+ "}\n");
+ }
+}
+
+void RepeatedMessageFieldGenerator::GenerateByteSize(
+ io::Printer* printer) const {
+ GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
+
+ Formatter format(printer, variables_);
+ format(
+ "total_size += $tag_size$UL * this->_internal_$name$_size();\n"
+ "for (const auto& msg : this->$name$_) {\n"
+ " total_size +=\n"
+ " ::$proto_ns$::internal::WireFormatLite::$declared_type$Size(msg);\n"
+ "}\n");
+}
+
+void RepeatedMessageFieldGenerator::GenerateIsInitialized(
+ io::Printer* printer) const {
+ GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
+
+ if (!has_required_fields_) return;
+
+ Formatter format(printer, variables_);
+ if (implicit_weak_field_) {
+ format(
+ "if (!::$proto_ns$::internal::AllAreInitializedWeak($name$_.weak))\n"
+ " return false;\n");
+ } else {
+ format(
+ "if (!::$proto_ns$::internal::AllAreInitialized($name$_))\n"
+ " return false;\n");
+ }
+}
+
+void RepeatedMessageFieldGenerator::GenerateConstinitInitializer(
+ io::Printer* printer) const {
+ Formatter format(printer, variables_);
+ format("$name$_()");
+}
+
+} // namespace cpp
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_message_field.h b/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_message_field.h
new file mode 100644
index 00000000..88744299
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_message_field.h
@@ -0,0 +1,144 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 GOOGLE_PROTOBUF_COMPILER_CPP_MESSAGE_FIELD_H__
+#define GOOGLE_PROTOBUF_COMPILER_CPP_MESSAGE_FIELD_H__
+
+#include <map>
+#include <string>
+#include <compiler/cpp/cpp_field.h>
+#include <compiler/cpp/cpp_helpers.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+class MessageFieldGenerator : public FieldGenerator {
+ public:
+ MessageFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options,
+ MessageSCCAnalyzer* scc_analyzer);
+ ~MessageFieldGenerator() override;
+
+ // implements FieldGenerator ---------------------------------------
+ void GeneratePrivateMembers(io::Printer* printer) const override;
+ void GenerateAccessorDeclarations(io::Printer* printer) const override;
+ void GenerateInlineAccessorDefinitions(io::Printer* printer) const override;
+ void GenerateNonInlineAccessorDefinitions(
+ io::Printer* printer) const override;
+ void GenerateInternalAccessorDeclarations(
+ io::Printer* printer) const override;
+ void GenerateInternalAccessorDefinitions(io::Printer* printer) const override;
+ void GenerateClearingCode(io::Printer* printer) const override;
+ void GenerateMessageClearingCode(io::Printer* printer) const override;
+ void GenerateMergingCode(io::Printer* printer) const override;
+ void GenerateSwappingCode(io::Printer* printer) const override;
+ void GenerateDestructorCode(io::Printer* printer) const override;
+ void GenerateConstructorCode(io::Printer* printer) const override;
+ void GenerateCopyConstructorCode(io::Printer* printer) const override;
+ void GenerateSerializeWithCachedSizesToArray(
+ io::Printer* printer) const override;
+ void GenerateByteSize(io::Printer* printer) const override;
+ void GenerateIsInitialized(io::Printer* printer) const override;
+ void GenerateConstinitInitializer(io::Printer* printer) const override;
+
+ protected:
+ const bool implicit_weak_field_;
+ const bool has_required_fields_;
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageFieldGenerator);
+};
+
+class MessageOneofFieldGenerator : public MessageFieldGenerator {
+ public:
+ MessageOneofFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options,
+ MessageSCCAnalyzer* scc_analyzer);
+ ~MessageOneofFieldGenerator() override;
+
+ // implements FieldGenerator ---------------------------------------
+ void GenerateInlineAccessorDefinitions(io::Printer* printer) const override;
+ void GenerateNonInlineAccessorDefinitions(
+ io::Printer* printer) const override;
+ void GenerateClearingCode(io::Printer* printer) const override;
+
+ // MessageFieldGenerator, from which we inherit, overrides this so we need to
+ // override it as well.
+ void GenerateMessageClearingCode(io::Printer* printer) const override;
+ void GenerateSwappingCode(io::Printer* printer) const override;
+ void GenerateDestructorCode(io::Printer* printer) const override;
+ void GenerateConstructorCode(io::Printer* printer) const override;
+ void GenerateIsInitialized(io::Printer* printer) const override;
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageOneofFieldGenerator);
+};
+
+class RepeatedMessageFieldGenerator : public FieldGenerator {
+ public:
+ RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options,
+ MessageSCCAnalyzer* scc_analyzer);
+ ~RepeatedMessageFieldGenerator() override;
+
+ // implements FieldGenerator ---------------------------------------
+ void GeneratePrivateMembers(io::Printer* printer) const override;
+ void GenerateAccessorDeclarations(io::Printer* printer) const override;
+ void GenerateInlineAccessorDefinitions(io::Printer* printer) const override;
+ void GenerateClearingCode(io::Printer* printer) const override;
+ void GenerateMergingCode(io::Printer* printer) const override;
+ void GenerateSwappingCode(io::Printer* printer) const override;
+ void GenerateConstructorCode(io::Printer* printer) const override;
+ void GenerateCopyConstructorCode(io::Printer* printer) const override {}
+ void GenerateSerializeWithCachedSizesToArray(
+ io::Printer* printer) const override;
+ void GenerateByteSize(io::Printer* printer) const override;
+ void GenerateIsInitialized(io::Printer* printer) const override;
+ void GenerateConstinitInitializer(io::Printer* printer) const override;
+
+ private:
+ const bool implicit_weak_field_;
+ const bool has_required_fields_;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedMessageFieldGenerator);
+};
+
+} // namespace cpp
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_COMPILER_CPP_MESSAGE_FIELD_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_message_layout_helper.h b/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_message_layout_helper.h
new file mode 100644
index 00000000..aa088a2a
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_message_layout_helper.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.
+
+// Author: seongkim@google.com (Seong Beom Kim)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_MESSAGE_LAYOUT_HELPER_H__
+#define GOOGLE_PROTOBUF_COMPILER_CPP_MESSAGE_LAYOUT_HELPER_H__
+
+#include <compiler/cpp/cpp_options.h>
+#include <descriptor.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+class MessageSCCAnalyzer;
+
+// Provides an abstract interface to optimize message layout
+// by rearranging the fields of a message.
+class MessageLayoutHelper {
+ public:
+ virtual ~MessageLayoutHelper() {}
+
+ virtual void OptimizeLayout(std::vector<const FieldDescriptor*>* fields,
+ const Options& options,
+ MessageSCCAnalyzer* scc_analyzer) = 0;
+};
+
+} // namespace cpp
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_COMPILER_CPP_MESSAGE_LAYOUT_HELPER_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_move_unittest.cc b/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_move_unittest.cc
new file mode 100644
index 00000000..ccb83acf
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_move_unittest.cc
@@ -0,0 +1,169 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 <stubs/common.h>
+#include <test_util.h>
+#include <unittest.pb.h>
+#include <gtest/gtest.h>
+
+#if LANG_CXX11
+#include <type_traits>
+#endif
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+// Can't use an anonymous namespace here due to brokenness of Tru64 compiler.
+namespace cpp_unittest {
+
+// Moves are enabled only when compiling with a C++11 compiler or newer.
+#if LANG_CXX11
+
+TEST(MovableMessageTest, MoveConstructor) {
+ protobuf_unittest::TestAllTypes message1;
+ TestUtil::SetAllFields(&message1);
+ const auto* nested = &message1.optional_nested_message();
+
+ protobuf_unittest::TestAllTypes message2(std::move(message1));
+ TestUtil::ExpectAllFieldsSet(message2);
+
+ // Check if the optional_nested_message was actually moved (and not just
+ // copied).
+ EXPECT_EQ(nested, &message2.optional_nested_message());
+ EXPECT_NE(nested, &message1.optional_nested_message());
+}
+
+TEST(MovableMessageTest, MoveAssignmentOperator) {
+ protobuf_unittest::TestAllTypes message1;
+ TestUtil::SetAllFields(&message1);
+ const auto* nested = &message1.optional_nested_message();
+
+ protobuf_unittest::TestAllTypes message2;
+ message2 = std::move(message1);
+ TestUtil::ExpectAllFieldsSet(message2);
+
+ // Check if the optional_nested_message was actually moved (and not just
+ // copied).
+ EXPECT_EQ(nested, &message2.optional_nested_message());
+ EXPECT_NE(nested, &message1.optional_nested_message());
+}
+
+TEST(MovableMessageTest, SelfMoveAssignment) {
+ // The `self` reference is necessary to defeat -Wself-move.
+ protobuf_unittest::TestAllTypes message, &self = message;
+ TestUtil::SetAllFields(&message);
+ message = std::move(self);
+ TestUtil::ExpectAllFieldsSet(message);
+}
+
+TEST(MovableMessageTest, MoveSameArena) {
+ Arena arena;
+
+ auto* message1_on_arena =
+ Arena::CreateMessage<protobuf_unittest::TestAllTypes>(&arena);
+ TestUtil::SetAllFields(message1_on_arena);
+ const auto* nested = &message1_on_arena->optional_nested_message();
+
+ auto* message2_on_arena =
+ Arena::CreateMessage<protobuf_unittest::TestAllTypes>(&arena);
+
+ // Moving messages on the same arena should lead to swapped pointers.
+ *message2_on_arena = std::move(*message1_on_arena);
+ EXPECT_EQ(nested, &message2_on_arena->optional_nested_message());
+}
+
+TEST(MovableMessageTest, MoveDifferentArenas) {
+ Arena arena1, arena2;
+
+ auto* message1_on_arena =
+ Arena::CreateMessage<protobuf_unittest::TestAllTypes>(&arena1);
+ TestUtil::SetAllFields(message1_on_arena);
+ const auto* nested = &message1_on_arena->optional_nested_message();
+
+ auto* message2_on_arena =
+ Arena::CreateMessage<protobuf_unittest::TestAllTypes>(&arena2);
+
+ // Moving messages on two different arenas should lead to a copy.
+ *message2_on_arena = std::move(*message1_on_arena);
+ EXPECT_NE(nested, &message2_on_arena->optional_nested_message());
+ TestUtil::ExpectAllFieldsSet(*message1_on_arena);
+ TestUtil::ExpectAllFieldsSet(*message2_on_arena);
+}
+
+TEST(MovableMessageTest, MoveFromArena) {
+ Arena arena;
+
+ auto* message1_on_arena =
+ Arena::CreateMessage<protobuf_unittest::TestAllTypes>(&arena);
+ TestUtil::SetAllFields(message1_on_arena);
+ const auto* nested = &message1_on_arena->optional_nested_message();
+
+ protobuf_unittest::TestAllTypes message2;
+
+ // Moving from a message on the arena should lead to a copy.
+ message2 = std::move(*message1_on_arena);
+ EXPECT_NE(nested, &message2.optional_nested_message());
+ TestUtil::ExpectAllFieldsSet(*message1_on_arena);
+ TestUtil::ExpectAllFieldsSet(message2);
+}
+
+TEST(MovableMessageTest, MoveToArena) {
+ Arena arena;
+
+ protobuf_unittest::TestAllTypes message1;
+ TestUtil::SetAllFields(&message1);
+ const auto* nested = &message1.optional_nested_message();
+
+ auto* message2_on_arena =
+ Arena::CreateMessage<protobuf_unittest::TestAllTypes>(&arena);
+
+ // Moving to a message on the arena should lead to a copy.
+ *message2_on_arena = std::move(message1);
+ EXPECT_NE(nested, &message2_on_arena->optional_nested_message());
+ TestUtil::ExpectAllFieldsSet(message1);
+ TestUtil::ExpectAllFieldsSet(*message2_on_arena);
+}
+
+TEST(MovableMessageTest, Noexcept) {
+ EXPECT_TRUE(
+ std::is_nothrow_move_constructible<protobuf_unittest::TestAllTypes>());
+ EXPECT_TRUE(std::is_nothrow_move_assignable<protobuf_unittest::TestAllTypes>());
+}
+
+#endif // LANG_CXX11
+
+} // namespace cpp_unittest
+
+} // namespace cpp
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_names.h b/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_names.h
new file mode 100644
index 00000000..81090017
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_names.h
@@ -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.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_NAMES_H__
+#define GOOGLE_PROTOBUF_COMPILER_CPP_NAMES_H__
+
+#include <string>
+
+#include <port_def.inc>
+
+namespace google {
+namespace protobuf {
+
+class Descriptor;
+class EnumDescriptor;
+class EnumValueDescriptor;
+class FieldDescriptor;
+
+namespace compiler {
+namespace cpp {
+
+// Returns the unqualified C++ name.
+//
+// For example, if you had:
+// package foo.bar;
+// message Baz { message Qux {} }
+// Then the non-qualified version would be:
+// Baz_Qux
+std::string ClassName(const Descriptor* descriptor);
+std::string ClassName(const EnumDescriptor* enum_descriptor);
+
+// Returns the fully qualified C++ name.
+//
+// For example, if you had:
+// package foo.bar;
+// message Baz { message Qux {} }
+// Then the qualified ClassName for Qux would be:
+// ::foo::bar::Baz_Qux
+std::string QualifiedClassName(const Descriptor* d);
+std::string QualifiedClassName(const EnumDescriptor* d);
+std::string QualifiedExtensionName(const FieldDescriptor* d);
+
+// Get the (unqualified) name that should be used for this field in C++ code.
+// The name is coerced to lower-case to emulate proto1 behavior. People
+// should be using lowercase-with-underscores style for proto field names
+// anyway, so normally this just returns field->name().
+std::string FieldName(const FieldDescriptor* field);
+
+// Requires that this field is in a oneof. Returns the (unqualified) case
+// constant for this field.
+std::string OneofCaseConstantName(const FieldDescriptor* field);
+// Returns the quafilied case constant for this field.
+std::string QualifiedOneofCaseConstantName(const FieldDescriptor* field);
+
+// Get the (unqualified) name that should be used for this enum value in C++
+// code.
+std::string EnumValueName(const EnumValueDescriptor* enum_value);
+
+// Strips ".proto" or ".protodevel" from the end of a filename.
+PROTOC_EXPORT std::string StripProto(const std::string& filename);
+
+} // namespace cpp
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#include <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_COMPILER_CPP_NAMES_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_options.h b/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_options.h
new file mode 100644
index 00000000..d0f16d03
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_options.h
@@ -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.
+
+// Author: rennie@google.com (Jeffrey Rennie)
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_OPTIONS_H__
+#define GOOGLE_PROTOBUF_COMPILER_CPP_OPTIONS_H__
+
+#include <set>
+#include <string>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+class AccessInfoMap;
+
+namespace cpp {
+
+enum class EnforceOptimizeMode {
+ kNoEnforcement, // Use the runtime specified by the file specific options.
+ kSpeed, // Full runtime with a generated code implementation.
+ kCodeSize, // Full runtime with a reflective implementation.
+ kLiteRuntime,
+};
+
+struct FieldListenerOptions {
+ bool inject_field_listener_events = false;
+ std::set<std::string> forbidden_field_listener_events;
+};
+
+// Generator options (see generator.cc for a description of each):
+struct Options {
+ std::string dllexport_decl;
+ bool safe_boundary_check = false;
+ bool proto_h = false;
+ bool transitive_pb_h = true;
+ bool annotate_headers = false;
+ EnforceOptimizeMode enforce_mode = EnforceOptimizeMode::kNoEnforcement;
+ bool table_driven_parsing = false;
+ bool table_driven_serialization = false;
+ bool lite_implicit_weak_fields = false;
+ bool bootstrap = false;
+ bool opensource_runtime = false;
+ bool annotate_accessor = false;
+ bool unused_field_stripping = false;
+ bool profile_driven_inline_string = true;
+ bool force_inline_string = false;
+ std::string runtime_include_base;
+ int num_cc_files = 0;
+ std::string annotation_pragma_name;
+ std::string annotation_guard_name;
+ const AccessInfoMap* access_info_map = nullptr;
+ enum {
+ kTCTableNever,
+ kTCTableGuarded,
+ kTCTableAlways
+ } tctable_mode = kTCTableNever;
+ FieldListenerOptions field_listener_options;
+ bool eagerly_verified_lazy = false;
+ bool force_eagerly_verified_lazy = false;
+};
+
+} // namespace cpp
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_COMPILER_CPP_OPTIONS_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_padding_optimizer.cc b/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_padding_optimizer.cc
new file mode 100644
index 00000000..a6384a7f
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_padding_optimizer.cc
@@ -0,0 +1,228 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 <compiler/cpp/cpp_padding_optimizer.h>
+
+#include <compiler/cpp/cpp_helpers.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+namespace {
+
+// FieldGroup is just a helper for PaddingOptimizer below. It holds a vector of
+// fields that are grouped together because they have compatible alignment, and
+// a preferred location in the final field ordering.
+class FieldGroup {
+ public:
+ FieldGroup() : preferred_location_(0) {}
+
+ // A group with a single field.
+ FieldGroup(float preferred_location, const FieldDescriptor* field)
+ : preferred_location_(preferred_location), fields_(1, field) {}
+
+ // Append the fields in 'other' to this group.
+ void Append(const FieldGroup& other) {
+ if (other.fields_.empty()) {
+ return;
+ }
+ // Preferred location is the average among all the fields, so we weight by
+ // the number of fields on each FieldGroup object.
+ preferred_location_ = (preferred_location_ * fields_.size() +
+ (other.preferred_location_ * other.fields_.size())) /
+ (fields_.size() + other.fields_.size());
+ fields_.insert(fields_.end(), other.fields_.begin(), other.fields_.end());
+ }
+
+ void SetPreferredLocation(float location) { preferred_location_ = location; }
+ const std::vector<const FieldDescriptor*>& fields() const { return fields_; }
+
+ // FieldGroup objects sort by their preferred location.
+ bool operator<(const FieldGroup& other) const {
+ return preferred_location_ < other.preferred_location_;
+ }
+
+ private:
+ // "preferred_location_" is an estimate of where this group should go in the
+ // final list of fields. We compute this by taking the average index of each
+ // field in this group in the original ordering of fields. This is very
+ // approximate, but should put this group close to where its member fields
+ // originally went.
+ float preferred_location_;
+ std::vector<const FieldDescriptor*> fields_;
+ // We rely on the default copy constructor and operator= so this type can be
+ // used in a vector.
+};
+
+} // namespace
+
+// Reorder 'fields' so that if the fields are output into a c++ class in the new
+// order, fields of similar family (see below) are together and within each
+// family, alignment padding is minimized.
+//
+// We try to do this while keeping each field as close as possible to its field
+// number order so that we don't reduce cache locality much for function that
+// access each field in order. Originally, OptimizePadding used declaration
+// order for its decisions, but generated code minus the serializer/parsers uses
+// the output of OptimizePadding as well (stored in
+// MessageGenerator::optimized_order_). Since the serializers use field number
+// order, we use that as a tie-breaker.
+//
+// We classify each field into a particular "family" of fields, that we perform
+// the same operation on in our generated functions.
+//
+// REPEATED is placed first, as the C++ compiler automatically initializes
+// these fields in layout order.
+//
+// STRING is grouped next, as our Clear/SharedCtor/SharedDtor walks it and
+// calls ArenaStringPtr::Destroy on each.
+//
+// LAZY_MESSAGE is grouped next, as it interferes with the ability to memset
+// non-repeated fields otherwise.
+//
+// MESSAGE is grouped next, as our Clear/SharedDtor code walks it and calls
+// delete on each. We initialize these fields with a NULL pointer (see
+// MessageFieldGenerator::GenerateConstructorCode), which allows them to be
+// memset.
+//
+// ZERO_INITIALIZABLE is memset in Clear/SharedCtor
+//
+// OTHER these fields are initialized one-by-one.
+void PaddingOptimizer::OptimizeLayout(
+ std::vector<const FieldDescriptor*>* fields, const Options& options,
+ MessageSCCAnalyzer* scc_analyzer) {
+ // The sorted numeric order of Family determines the declaration order in the
+ // memory layout.
+ enum Family {
+ REPEATED = 0,
+ STRING = 1,
+ // Laying out LAZY_MESSAGE before MESSAGE allows a single memset to zero
+ // MESSAGE and ZERO_INITIALIZABLE fields together.
+ LAZY_MESSAGE = 2,
+ MESSAGE = 3,
+ ZERO_INITIALIZABLE = 4,
+ OTHER = 5,
+ kMaxFamily
+ };
+
+ // First divide fields into those that align to 1 byte, 4 bytes or 8 bytes.
+ std::vector<FieldGroup> aligned_to_1[kMaxFamily];
+ std::vector<FieldGroup> aligned_to_4[kMaxFamily];
+ std::vector<FieldGroup> aligned_to_8[kMaxFamily];
+ for (int i = 0; i < fields->size(); ++i) {
+ const FieldDescriptor* field = (*fields)[i];
+
+ Family f = OTHER;
+ if (field->is_repeated()) {
+ f = REPEATED;
+ } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING) {
+ f = STRING;
+ } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+ f = MESSAGE;
+ if (IsLazy(field, options, scc_analyzer)) {
+ f = LAZY_MESSAGE;
+ }
+ } else if (CanInitializeByZeroing(field)) {
+ f = ZERO_INITIALIZABLE;
+ }
+
+ const int j = field->number();
+ switch (EstimateAlignmentSize(field)) {
+ case 1:
+ aligned_to_1[f].push_back(FieldGroup(j, field));
+ break;
+ case 4:
+ aligned_to_4[f].push_back(FieldGroup(j, field));
+ break;
+ case 8:
+ aligned_to_8[f].push_back(FieldGroup(j, field));
+ break;
+ default:
+ GOOGLE_LOG(FATAL) << "Unknown alignment size " << EstimateAlignmentSize(field)
+ << "for a field " << field->full_name() << ".";
+ }
+ }
+
+ // For each family, group fields to optimize padding.
+ for (int f = 0; f < kMaxFamily; f++) {
+ // Now group fields aligned to 1 byte into sets of 4, and treat those like a
+ // single field aligned to 4 bytes.
+ for (int i = 0; i < aligned_to_1[f].size(); i += 4) {
+ FieldGroup field_group;
+ for (int j = i; j < aligned_to_1[f].size() && j < i + 4; ++j) {
+ field_group.Append(aligned_to_1[f][j]);
+ }
+ aligned_to_4[f].push_back(field_group);
+ }
+ // Sort by preferred location to keep fields as close to their field number
+ // order as possible. Using stable_sort ensures that the output is
+ // consistent across runs.
+ std::stable_sort(aligned_to_4[f].begin(), aligned_to_4[f].end());
+
+ // Now group fields aligned to 4 bytes (or the 4-field groups created above)
+ // into pairs, and treat those like a single field aligned to 8 bytes.
+ for (int i = 0; i < aligned_to_4[f].size(); i += 2) {
+ FieldGroup field_group;
+ for (int j = i; j < aligned_to_4[f].size() && j < i + 2; ++j) {
+ field_group.Append(aligned_to_4[f][j]);
+ }
+ if (i == aligned_to_4[f].size() - 1) {
+ if (f == OTHER) {
+ // Move incomplete 4-byte block to the beginning. This is done to
+ // pair with the (possible) leftover blocks from the
+ // ZERO_INITIALIZABLE family.
+ field_group.SetPreferredLocation(-1);
+ } else {
+ // Move incomplete 4-byte block to the end.
+ field_group.SetPreferredLocation(fields->size() + 1);
+ }
+ }
+ aligned_to_8[f].push_back(field_group);
+ }
+ // Sort by preferred location.
+ std::stable_sort(aligned_to_8[f].begin(), aligned_to_8[f].end());
+ }
+
+ // Now pull out all the FieldDescriptors in order.
+ fields->clear();
+ for (int f = 0; f < kMaxFamily; ++f) {
+ for (int i = 0; i < aligned_to_8[f].size(); ++i) {
+ fields->insert(fields->end(), aligned_to_8[f][i].fields().begin(),
+ aligned_to_8[f][i].fields().end());
+ }
+ }
+}
+
+} // namespace cpp
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_padding_optimizer.h b/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_padding_optimizer.h
new file mode 100644
index 00000000..c08fa8dc
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_padding_optimizer.h
@@ -0,0 +1,65 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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: seongkim@google.com (Seong Beom Kim)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_PADDING_OPTIMIZER_H__
+#define GOOGLE_PROTOBUF_COMPILER_CPP_PADDING_OPTIMIZER_H__
+
+#include <compiler/cpp/cpp_message_layout_helper.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+// Rearranges the fields of a message to minimize padding.
+// Fields are grouped by the type and the size.
+// For example, grouping four boolean fields and one int32
+// field results in zero padding overhead. See OptimizeLayout's
+// comment for details.
+class PaddingOptimizer : public MessageLayoutHelper {
+ public:
+ PaddingOptimizer() {}
+ ~PaddingOptimizer() override {}
+
+ void OptimizeLayout(std::vector<const FieldDescriptor*>* fields,
+ const Options& options,
+ MessageSCCAnalyzer* scc_analyzer) override;
+};
+
+} // namespace cpp
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_COMPILER_CPP_PADDING_OPTIMIZER_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_parse_function_generator.cc b/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_parse_function_generator.cc
new file mode 100644
index 00000000..8eed2224
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_parse_function_generator.cc
@@ -0,0 +1,1303 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 <compiler/cpp/cpp_parse_function_generator.h>
+
+#include <algorithm>
+#include <limits>
+#include <string>
+
+#include <compiler/cpp/cpp_helpers.h>
+#include <wire_format.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+namespace {
+using google::protobuf::internal::TcFieldData;
+using google::protobuf::internal::WireFormat;
+using google::protobuf::internal::WireFormatLite;
+
+std::vector<const FieldDescriptor*> GetOrderedFields(
+ const Descriptor* descriptor, const Options& options) {
+ std::vector<const FieldDescriptor*> ordered_fields;
+ for (auto field : FieldRange(descriptor)) {
+ if (!IsFieldStripped(field, options)) {
+ ordered_fields.push_back(field);
+ }
+ }
+ std::sort(ordered_fields.begin(), ordered_fields.end(),
+ [](const FieldDescriptor* a, const FieldDescriptor* b) {
+ return a->number() < b->number();
+ });
+ return ordered_fields;
+}
+
+bool HasInternalAccessors(const FieldOptions::CType ctype) {
+ return ctype == FieldOptions::STRING || ctype == FieldOptions::CORD;
+}
+
+int TagSize(uint32_t field_number) {
+ if (field_number < 16) return 1;
+ GOOGLE_CHECK_LT(field_number, (1 << 14))
+ << "coded tag for " << field_number << " too big for uint16_t";
+ return 2;
+}
+
+const char* CodedTagType(int tag_size) {
+ return tag_size == 1 ? "uint8_t" : "uint16_t";
+}
+
+const char* TagType(const FieldDescriptor* field) {
+ return CodedTagType(TagSize(field->number()));
+}
+
+std::string TcParserName(const Options& options) {
+ return StrCat("::", ProtobufNamespace(options),
+ "::internal::TcParser::");
+}
+
+std::string MessageTcParseFunctionName(const FieldDescriptor* field,
+ const Options& options) {
+ if (field->message_type()->field_count() == 0 ||
+ !HasGeneratedMethods(field->message_type()->file(), options)) {
+ // For files with `option optimize_for = CODE_SIZE`, or which derive from
+ // `ZeroFieldsBase`, we need to call the `_InternalParse` function, because
+ // there is no generated tailcall function. For tailcall parsing, this is
+ // done by helpers in TcParser.
+ return StrCat(TcParserName(options),
+ (field->is_repeated() ? "Repeated" : "Singular"),
+ "ParseMessage<",
+ QualifiedClassName(field->message_type()), //
+ ", ", TagType(field), ">");
+ }
+ // This matches macros in generated_message_tctable_impl.h:
+ return StrCat("PROTOBUF_TC_PARSE_",
+ (field->is_repeated() ? "REPEATED" : "SINGULAR"),
+ TagSize(field->number()), "(",
+ QualifiedClassName(field->message_type()), ")");
+}
+
+std::string FieldParseFunctionName(const FieldDescriptor* field,
+ const Options& options);
+
+} // namespace
+
+TailCallTableInfo::TailCallTableInfo(const Descriptor* descriptor,
+ const Options& options,
+ const std::vector<int>& has_bit_indices,
+ MessageSCCAnalyzer* scc_analyzer) {
+ std::vector<const FieldDescriptor*> ordered_fields =
+ GetOrderedFields(descriptor, options);
+
+ // The table size is rounded up to the nearest power of 2, clamping at 2^5.
+ // Note that this is a naive approach: a better approach should only consider
+ // table-eligible fields. We may also want to push rarely-encountered fields
+ // into the fallback, to make the table smaller.
+ table_size_log2 = ordered_fields.size() >= 16 ? 5
+ : ordered_fields.size() >= 8 ? 4
+ : ordered_fields.size() >= 4 ? 3
+ : ordered_fields.size() >= 2 ? 2
+ : 1;
+ const unsigned table_size = 1 << table_size_log2;
+
+ // Construct info for each possible entry. Fields that do not use table-driven
+ // parsing will still have an entry that nominates the fallback function.
+ fast_path_fields.resize(table_size);
+
+ for (const auto* field : ordered_fields) {
+ // Eagerly assume slow path. If we can handle this field on the fast path,
+ // we will pop its entry from `fallback_fields`.
+ fallback_fields.push_back(field);
+
+ // Anything difficult slow path:
+ if (field->is_map()) continue;
+ if (field->real_containing_oneof()) continue;
+ if (field->options().weak()) continue;
+ if (IsImplicitWeakField(field, options, scc_analyzer)) continue;
+ if (IsLazy(field, options, scc_analyzer)) continue;
+
+ // The largest tag that can be read by the tailcall parser is two bytes
+ // when varint-coded. This allows 14 bits for the numeric tag value:
+ // byte 0 byte 1
+ // 1nnnnttt 0nnnnnnn
+ // ^^^^^^^ ^^^^^^^
+ uint32_t tag = WireFormat::MakeTag(field);
+ if (tag >= 1 << 14) {
+ continue;
+ } else if (tag >= 1 << 7) {
+ tag = ((tag << 1) & 0x7F00) | 0x80 | (tag & 0x7F);
+ }
+ // The field index is determined by the low bits of the field number, where
+ // the table size determines the width of the mask. The largest table
+ // supported is 32 entries. The parse loop uses these bits directly, so that
+ // the dispatch does not require arithmetic:
+ // byte 0 byte 1
+ // 1nnnnttt 0nnnnnnn
+ // ^^^^^
+ // This means that any field number that does not fit in the lower 4 bits
+ // will always have the top bit of its table index asserted:
+ uint32_t idx = (tag >> 3) & (table_size - 1);
+ // If this entry in the table is already used, then this field will be
+ // handled by the generated fallback function.
+ if (!fast_path_fields[idx].func_name.empty()) continue;
+
+ // Determine the hasbit mask for this field, if needed. (Note that fields
+ // without hasbits use different parse functions.)
+ int hasbit_idx;
+ if (HasHasbit(field)) {
+ hasbit_idx = has_bit_indices[field->index()];
+ GOOGLE_CHECK_NE(-1, hasbit_idx) << field->DebugString();
+ // The tailcall parser can only update the first 32 hasbits. If this
+ // field's has-bit is beyond that, then it will need to be handled by the
+ // fallback parse function.
+ if (hasbit_idx >= 32) continue;
+ } else {
+ // The tailcall parser only ever syncs 32 has-bits, so if there is no
+ // presence, set a bit that will not be used.
+ hasbit_idx = 63;
+ }
+
+ // Determine the name of the fastpath parse function to use for this field.
+ std::string name;
+
+ switch (field->type()) {
+ case FieldDescriptor::TYPE_MESSAGE:
+ name = MessageTcParseFunctionName(field, options);
+ break;
+
+ case FieldDescriptor::TYPE_FIXED64:
+ case FieldDescriptor::TYPE_FIXED32:
+ case FieldDescriptor::TYPE_SFIXED64:
+ case FieldDescriptor::TYPE_SFIXED32:
+ case FieldDescriptor::TYPE_DOUBLE:
+ case FieldDescriptor::TYPE_FLOAT:
+ case FieldDescriptor::TYPE_INT64:
+ case FieldDescriptor::TYPE_INT32:
+ case FieldDescriptor::TYPE_UINT64:
+ case FieldDescriptor::TYPE_UINT32:
+ case FieldDescriptor::TYPE_SINT64:
+ case FieldDescriptor::TYPE_SINT32:
+ case FieldDescriptor::TYPE_BOOL:
+ name = FieldParseFunctionName(field, options);
+ break;
+
+ case FieldDescriptor::TYPE_BYTES:
+ if (field->options().ctype() == FieldOptions::STRING &&
+ field->default_value_string().empty() &&
+ !IsStringInlined(field, options)) {
+ name = FieldParseFunctionName(field, options);
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ if (name.empty()) {
+ continue;
+ }
+ // This field made it into the fast path, so remove it from the fallback
+ // fields and fill in the table entry.
+ fallback_fields.pop_back();
+ fast_path_fields[idx].func_name = name;
+ fast_path_fields[idx].bits = TcFieldData(tag, hasbit_idx, 0);
+ fast_path_fields[idx].field = field;
+ }
+
+ // If there are no fallback fields, and at most one extension range, the
+ // parser can use a generic fallback function. Otherwise, a message-specific
+ // fallback routine is needed.
+ use_generated_fallback =
+ !fallback_fields.empty() || descriptor->extension_range_count() > 1;
+}
+
+ParseFunctionGenerator::ParseFunctionGenerator(
+ const Descriptor* descriptor, int max_has_bit_index,
+ const std::vector<int>& has_bit_indices,
+ const std::vector<int>& inlined_string_indices, const Options& options,
+ MessageSCCAnalyzer* scc_analyzer,
+ const std::map<std::string, std::string>& vars)
+ : descriptor_(descriptor),
+ scc_analyzer_(scc_analyzer),
+ options_(options),
+ variables_(vars),
+ inlined_string_indices_(inlined_string_indices),
+ num_hasbits_(max_has_bit_index) {
+ if (should_generate_tctable()) {
+ tc_table_info_.reset(new TailCallTableInfo(descriptor_, options_,
+ has_bit_indices, scc_analyzer));
+ }
+ SetCommonVars(options_, &variables_);
+ SetUnknownFieldsVariable(descriptor_, options_, &variables_);
+ variables_["classname"] = ClassName(descriptor, false);
+}
+
+void ParseFunctionGenerator::GenerateMethodDecls(io::Printer* printer) {
+ Formatter format(printer, variables_);
+ if (should_generate_tctable()) {
+ auto declare_function = [&format](const char* name,
+ const std::string& guard) {
+ if (!guard.empty()) {
+ format.Outdent();
+ format("#if $1$\n", guard);
+ format.Indent();
+ }
+ format("static const char* $1$(PROTOBUF_TC_PARAM_DECL);\n", name);
+ if (!guard.empty()) {
+ format.Outdent();
+ format("#endif // $1$\n", guard);
+ format.Indent();
+ }
+ };
+ if (should_generate_guarded_tctable()) {
+ format.Outdent();
+ format("#ifdef PROTOBUF_TAIL_CALL_TABLE_PARSER_ENABLED\n");
+ format.Indent();
+ }
+ format("// The Tct_* functions are internal to the protobuf runtime:\n");
+ // These guards are defined in port_def.inc:
+ declare_function("Tct_ParseS1", "PROTOBUF_TC_STATIC_PARSE_SINGULAR1");
+ declare_function("Tct_ParseS2", "PROTOBUF_TC_STATIC_PARSE_SINGULAR2");
+ declare_function("Tct_ParseR1", "PROTOBUF_TC_STATIC_PARSE_REPEATED1");
+ declare_function("Tct_ParseR2", "PROTOBUF_TC_STATIC_PARSE_REPEATED2");
+ if (tc_table_info_->use_generated_fallback) {
+ format.Outdent();
+ format(
+ " private:\n"
+ " ");
+ declare_function("Tct_ParseFallback", "");
+ format(" public:\n");
+ format.Indent();
+ }
+ if (should_generate_guarded_tctable()) {
+ format.Outdent();
+ format("#endif\n");
+ format.Indent();
+ }
+ }
+ format(
+ "const char* _InternalParse(const char* ptr, "
+ "::$proto_ns$::internal::ParseContext* ctx) final;\n");
+}
+
+void ParseFunctionGenerator::GenerateMethodImpls(io::Printer* printer) {
+ Formatter format(printer, variables_);
+ bool need_parse_function = true;
+ if (descriptor_->options().message_set_wire_format()) {
+ // Special-case MessageSet.
+ need_parse_function = false;
+ format(
+ "const char* $classname$::_InternalParse(const char* ptr,\n"
+ " ::$proto_ns$::internal::ParseContext* ctx) {\n"
+ "$annotate_deserialize$"
+ " return _extensions_.ParseMessageSet(ptr, \n"
+ " internal_default_instance(), &_internal_metadata_, ctx);\n"
+ "}\n");
+ }
+ if (!should_generate_tctable()) {
+ if (need_parse_function) {
+ GenerateLoopingParseFunction(format);
+ }
+ return;
+ }
+ if (should_generate_guarded_tctable()) {
+ format("#ifdef PROTOBUF_TAIL_CALL_TABLE_PARSER_ENABLED\n\n");
+ }
+ if (need_parse_function) {
+ GenerateTailcallParseFunction(format);
+ }
+ if (tc_table_info_->use_generated_fallback) {
+ GenerateTailcallFallbackFunction(format);
+ }
+ GenerateTailcallFieldParseFunctions(format);
+ if (should_generate_guarded_tctable()) {
+ if (need_parse_function) {
+ format("\n#else // PROTOBUF_TAIL_CALL_TABLE_PARSER_ENABLED\n\n");
+ GenerateLoopingParseFunction(format);
+ }
+ format("\n#endif // PROTOBUF_TAIL_CALL_TABLE_PARSER_ENABLED\n");
+ }
+}
+
+bool ParseFunctionGenerator::should_generate_tctable() const {
+ if (options_.tctable_mode == Options::kTCTableNever) {
+ return false;
+ }
+ return true;
+}
+
+void ParseFunctionGenerator::GenerateTailcallParseFunction(Formatter& format) {
+ GOOGLE_CHECK(should_generate_tctable());
+
+ // Generate an `_InternalParse` that starts the tail-calling loop.
+ format(
+ "const char* $classname$::_InternalParse(\n"
+ " const char* ptr, ::$proto_ns$::internal::ParseContext* ctx) {\n"
+ "$annotate_deserialize$"
+ " ptr = ::$proto_ns$::internal::TcParser::ParseLoop(\n"
+ " this, ptr, ctx, &_table_.header);\n");
+ format(
+ " return ptr;\n"
+ "}\n\n");
+}
+
+void ParseFunctionGenerator::GenerateTailcallFallbackFunction(
+ Formatter& format) {
+ GOOGLE_CHECK(should_generate_tctable());
+ format(
+ "const char* $classname$::Tct_ParseFallback(PROTOBUF_TC_PARAM_DECL) {\n"
+ "#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) return nullptr\n");
+ format.Indent();
+ format("auto* typed_msg = static_cast<$classname$*>(msg);\n");
+
+ if (num_hasbits_ > 0) {
+ // Sync hasbits
+ format("typed_msg->_has_bits_[0] = hasbits;\n");
+ }
+
+ format.Set("msg", "typed_msg->");
+ format.Set("this", "typed_msg");
+ format.Set("has_bits", "typed_msg->_has_bits_");
+ format.Set("next_tag", "goto next_tag");
+ GenerateParseIterationBody(format, descriptor_,
+ tc_table_info_->fallback_fields);
+
+ format.Outdent();
+ format(
+ "next_tag:\n"
+ "message_done:\n"
+ " return ptr;\n"
+ "#undef CHK_\n"
+ "}\n");
+}
+
+void ParseFunctionGenerator::GenerateTailcallFieldParseFunctions(
+ Formatter& format) {
+ GOOGLE_CHECK(should_generate_tctable());
+ // There are four cases where a tailcall target are needed for messages:
+ // {singular, repeated} x {1, 2}-byte tag
+ struct {
+ const char* type;
+ int size;
+ } const kTagLayouts[] = {
+ {"uint8_t", 1},
+ {"uint16_t", 2},
+ };
+ // Singular:
+ for (const auto& layout : kTagLayouts) {
+ // Guard macros are defined in port_def.inc.
+ format(
+ "#if PROTOBUF_TC_STATIC_PARSE_SINGULAR$1$\n"
+ "const char* $classname$::Tct_ParseS$1$(PROTOBUF_TC_PARAM_DECL) {\n"
+ " if (PROTOBUF_PREDICT_FALSE(data.coded_tag<$2$>() != 0))\n"
+ " PROTOBUF_MUSTTAIL "
+ "return table->fallback(PROTOBUF_TC_PARAM_PASS);\n"
+ " ptr += $1$;\n"
+ " hasbits |= (uint64_t{1} << data.hasbit_idx());\n"
+ " ::$proto_ns$::internal::TcParser::SyncHasbits"
+ "(msg, hasbits, table);\n"
+ " auto& field = ::$proto_ns$::internal::TcParser::"
+ "RefAt<$classtype$*>(msg, data.offset());\n"
+ " if (field == nullptr)\n"
+ " field = CreateMaybeMessage<$classtype$>(ctx->data().arena);\n"
+ " return ctx->ParseMessage(field, ptr);\n"
+ "}\n"
+ "#endif // PROTOBUF_TC_STATIC_PARSE_SINGULAR$1$\n",
+ layout.size, layout.type);
+ }
+ // Repeated:
+ for (const auto& layout : kTagLayouts) {
+ // Guard macros are defined in port_def.inc.
+ format(
+ "#if PROTOBUF_TC_STATIC_PARSE_REPEATED$1$\n"
+ "const char* $classname$::Tct_ParseR$1$(PROTOBUF_TC_PARAM_DECL) {\n"
+ " if (PROTOBUF_PREDICT_FALSE(data.coded_tag<$2$>() != 0)) {\n"
+ " PROTOBUF_MUSTTAIL "
+ "return table->fallback(PROTOBUF_TC_PARAM_PASS);\n"
+ " }\n"
+ " ptr += $1$;\n"
+ " auto& field = ::$proto_ns$::internal::TcParser::RefAt<"
+ "::$proto_ns$::RepeatedPtrField<$classname$>>(msg, data.offset());\n"
+ " ::$proto_ns$::internal::TcParser::SyncHasbits"
+ "(msg, hasbits, table);\n"
+ " ptr = ctx->ParseMessage(field.Add(), ptr);\n"
+ " return ptr;\n"
+ "}\n"
+ "#endif // PROTOBUF_TC_STATIC_PARSE_REPEATED$1$\n",
+ layout.size, layout.type);
+ }
+}
+
+void ParseFunctionGenerator::GenerateDataDecls(io::Printer* printer) {
+ if (!should_generate_tctable()) {
+ return;
+ }
+ Formatter format(printer, variables_);
+ if (should_generate_guarded_tctable()) {
+ format.Outdent();
+ format("#ifdef PROTOBUF_TAIL_CALL_TABLE_PARSER_ENABLED\n");
+ format.Indent();
+ }
+ format(
+ "static const ::$proto_ns$::internal::TcParseTable<$1$>\n"
+ " _table_;\n",
+ tc_table_info_->table_size_log2);
+ if (should_generate_guarded_tctable()) {
+ format.Outdent();
+ format("#endif // PROTOBUF_TAIL_CALL_TABLE_PARSER_ENABLED\n");
+ format.Indent();
+ }
+}
+
+void ParseFunctionGenerator::GenerateDataDefinitions(io::Printer* printer) {
+ if (!should_generate_tctable()) {
+ return;
+ }
+ Formatter format(printer, variables_);
+ if (should_generate_guarded_tctable()) {
+ format("#ifdef PROTOBUF_TAIL_CALL_TABLE_PARSER_ENABLED\n");
+ }
+ GenerateTailCallTable(format);
+ if (should_generate_guarded_tctable()) {
+ format("#endif // PROTOBUF_TAIL_CALL_TABLE_PARSER_ENABLED\n");
+ }
+}
+
+void ParseFunctionGenerator::GenerateLoopingParseFunction(Formatter& format) {
+ format(
+ "const char* $classname$::_InternalParse(const char* ptr, "
+ "::$proto_ns$::internal::ParseContext* ctx) {\n"
+ "$annotate_deserialize$"
+ "#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure\n");
+ format.Indent();
+ format.Set("msg", "");
+ format.Set("this", "this");
+ int hasbits_size = 0;
+ if (num_hasbits_ > 0) {
+ hasbits_size = (num_hasbits_ + 31) / 32;
+ }
+ // For now only optimize small hasbits.
+ if (hasbits_size != 1) hasbits_size = 0;
+ if (hasbits_size) {
+ format("_Internal::HasBits has_bits{};\n");
+ format.Set("has_bits", "has_bits");
+ } else {
+ format.Set("has_bits", "_has_bits_");
+ }
+ format.Set("next_tag", "continue");
+ format("while (!ctx->Done(&ptr)) {\n");
+ format.Indent();
+
+ GenerateParseIterationBody(format, descriptor_,
+ GetOrderedFields(descriptor_, options_));
+
+ format.Outdent();
+ format("} // while\n");
+
+ format.Outdent();
+ format("message_done:\n");
+ if (hasbits_size) format(" _has_bits_.Or(has_bits);\n");
+
+ format(
+ " return ptr;\n"
+ "failure:\n"
+ " ptr = nullptr;\n"
+ " goto message_done;\n"
+ "#undef CHK_\n"
+ "}\n");
+}
+
+void ParseFunctionGenerator::GenerateTailCallTable(Formatter& format) {
+ GOOGLE_CHECK(should_generate_tctable());
+ // All entries without a fast-path parsing function need a fallback.
+ std::string fallback;
+ if (tc_table_info_->use_generated_fallback) {
+ fallback = ClassName(descriptor_) + "::Tct_ParseFallback";
+ } else {
+ fallback = TcParserName(options_) + "GenericFallback";
+ if (GetOptimizeFor(descriptor_->file(), options_) ==
+ FileOptions::LITE_RUNTIME) {
+ fallback += "Lite";
+ }
+ }
+
+ // For simplicity and speed, the table is not covering all proto
+ // configurations. This model uses a fallback to cover all situations that
+ // the table can't accommodate, together with unknown fields or extensions.
+ // These are number of fields over 32, fields with 3 or more tag bytes,
+ // maps, weak fields, lazy, more than 1 extension range. In the cases
+ // the table is sufficient we can use a generic routine, that just handles
+ // unknown fields and potentially an extension range.
+ format(
+ "const ::$proto_ns$::internal::TcParseTable<$1$>\n"
+ " $classname$::_table_ = {\n",
+ tc_table_info_->table_size_log2);
+ {
+ auto table_scope = format.ScopedIndent();
+ format("{\n");
+ {
+ auto header_scope = format.ScopedIndent();
+ if (num_hasbits_ > 0 || IsMapEntryMessage(descriptor_)) {
+ format("PROTOBUF_FIELD_OFFSET($classname$, _has_bits_),\n");
+ } else {
+ format("0, // no _has_bits_\n");
+ }
+ if (descriptor_->extension_range_count() == 1) {
+ format(
+ "PROTOBUF_FIELD_OFFSET($classname$, _extensions_),\n"
+ "$1$, $2$, // extension_range_{low,high}\n",
+ descriptor_->extension_range(0)->start,
+ descriptor_->extension_range(0)->end);
+ } else {
+ format("0, 0, 0, // no _extensions_\n");
+ }
+ format(
+ "$1$, 0, $2$, // fast_idx_mask, reserved, num_fields\n"
+ "&$3$._instance,\n"
+ "$4$ // fallback\n",
+ (((1 << tc_table_info_->table_size_log2) - 1) << 3),
+ descriptor_->field_count(),
+ DefaultInstanceName(descriptor_, options_), fallback);
+ }
+ format("}, {\n");
+ {
+ auto fast_scope = format.ScopedIndent();
+ GenerateFastFieldEntries(format, fallback);
+ }
+ format("},\n"); // entries[]
+ }
+ format("};\n\n"); // _table_
+}
+
+void ParseFunctionGenerator::GenerateFastFieldEntries(
+ Formatter& format, const std::string& fallback) {
+ for (const auto& info : tc_table_info_->fast_path_fields) {
+ if (info.field != nullptr) {
+ PrintFieldComment(format, info.field);
+ }
+ format("{$1$, ", info.func_name.empty() ? fallback : info.func_name);
+ if (info.bits.data) {
+ GOOGLE_DCHECK_NE(nullptr, info.field);
+ format(
+ "{$1$, $2$, "
+ "static_cast<uint16_t>(PROTOBUF_FIELD_OFFSET($classname$, $3$_))}",
+ info.bits.coded_tag(), info.bits.hasbit_idx(), FieldName(info.field));
+ } else {
+ format("{}");
+ }
+ format("},\n");
+ }
+}
+
+void ParseFunctionGenerator::GenerateArenaString(Formatter& format,
+ const FieldDescriptor* field) {
+ if (HasHasbit(field)) {
+ format("_Internal::set_has_$1$(&$has_bits$);\n", FieldName(field));
+ }
+ std::string default_string =
+ field->default_value_string().empty()
+ ? "::" + ProtobufNamespace(options_) +
+ "::internal::GetEmptyStringAlreadyInited()"
+ : QualifiedClassName(field->containing_type(), options_) +
+ "::" + MakeDefaultName(field) + ".get()";
+ format(
+ "if (arena != nullptr) {\n"
+ " ptr = ctx->ReadArenaString(ptr, &$msg$$name$_, arena");
+ if (IsStringInlined(field, options_)) {
+ GOOGLE_DCHECK(!inlined_string_indices_.empty());
+ int inlined_string_index = inlined_string_indices_[field->index()];
+ GOOGLE_DCHECK_GE(inlined_string_index, 0);
+ format(
+ ", $msg$_internal_$name$_donated()"
+ ", &$msg$_inlined_string_donated_[$1$]"
+ ", ~0x$2$u",
+ inlined_string_index / 32,
+ strings::Hex(1u << (inlined_string_index % 32), strings::ZERO_PAD_8));
+ } else {
+ GOOGLE_DCHECK(field->default_value_string().empty());
+ }
+ format(
+ ");\n"
+ "} else {\n"
+ " ptr = ::$proto_ns$::internal::InlineGreedyStringParser("
+ "$msg$$name$_.MutableNoArenaNoDefault(&$1$), ptr, ctx);\n"
+ "}\n"
+ "const std::string* str = &$msg$$name$_.Get(); (void)str;\n",
+ default_string);
+}
+
+void ParseFunctionGenerator::GenerateStrings(Formatter& format,
+ const FieldDescriptor* field,
+ bool check_utf8) {
+ FieldOptions::CType ctype = FieldOptions::STRING;
+ if (!options_.opensource_runtime) {
+ // Open source doesn't support other ctypes;
+ ctype = field->options().ctype();
+ }
+ if (!field->is_repeated() && !options_.opensource_runtime &&
+ GetOptimizeFor(field->file(), options_) != FileOptions::LITE_RUNTIME &&
+ // For now only use arena string for strings with empty defaults.
+ field->default_value_string().empty() &&
+ !field->real_containing_oneof() && ctype == FieldOptions::STRING) {
+ GenerateArenaString(format, field);
+ } else {
+ std::string parser_name;
+ switch (ctype) {
+ case FieldOptions::STRING:
+ parser_name = "GreedyStringParser";
+ break;
+ case FieldOptions::CORD:
+ parser_name = "CordParser";
+ break;
+ case FieldOptions::STRING_PIECE:
+ parser_name = "StringPieceParser";
+ break;
+ }
+ format(
+ "auto str = $msg$$1$$2$_$name$();\n"
+ "ptr = ::$proto_ns$::internal::Inline$3$(str, ptr, ctx);\n",
+ HasInternalAccessors(ctype) ? "_internal_" : "",
+ field->is_repeated() && !field->is_packable() ? "add" : "mutable",
+ parser_name);
+ }
+ if (!check_utf8) return; // return if this is a bytes field
+ auto level = GetUtf8CheckMode(field, options_);
+ switch (level) {
+ case Utf8CheckMode::kNone:
+ return;
+ case Utf8CheckMode::kVerify:
+ format("#ifndef NDEBUG\n");
+ break;
+ case Utf8CheckMode::kStrict:
+ format("CHK_(");
+ break;
+ }
+ std::string field_name;
+ field_name = "nullptr";
+ if (HasDescriptorMethods(field->file(), options_)) {
+ field_name = StrCat("\"", field->full_name(), "\"");
+ }
+ format("::$proto_ns$::internal::VerifyUTF8(str, $1$)", field_name);
+ switch (level) {
+ case Utf8CheckMode::kNone:
+ return;
+ case Utf8CheckMode::kVerify:
+ format(
+ ";\n"
+ "#endif // !NDEBUG\n");
+ break;
+ case Utf8CheckMode::kStrict:
+ format(");\n");
+ break;
+ }
+}
+
+void ParseFunctionGenerator::GenerateLengthDelim(Formatter& format,
+ const FieldDescriptor* field) {
+ if (field->is_packable()) {
+ if (field->type() == FieldDescriptor::TYPE_ENUM &&
+ !HasPreservingUnknownEnumSemantics(field)) {
+ std::string enum_type = QualifiedClassName(field->enum_type(), options_);
+ format(
+ "ptr = "
+ "::$proto_ns$::internal::Packed$1$Parser<$unknown_fields_type$>("
+ "$msg$_internal_mutable_$name$(), ptr, ctx, $2$_IsValid, "
+ "&$msg$_internal_metadata_, $3$);\n",
+ DeclaredTypeMethodName(field->type()), enum_type, field->number());
+ } else {
+ format(
+ "ptr = ::$proto_ns$::internal::Packed$1$Parser("
+ "$msg$_internal_mutable_$name$(), ptr, ctx);\n",
+ DeclaredTypeMethodName(field->type()));
+ }
+ } else {
+ auto field_type = field->type();
+ switch (field_type) {
+ case FieldDescriptor::TYPE_STRING:
+ GenerateStrings(format, field, true /* utf8 */);
+ break;
+ case FieldDescriptor::TYPE_BYTES:
+ GenerateStrings(format, field, false /* utf8 */);
+ break;
+ case FieldDescriptor::TYPE_MESSAGE: {
+ if (field->is_map()) {
+ const FieldDescriptor* val =
+ field->message_type()->FindFieldByName("value");
+ GOOGLE_CHECK(val);
+ if (val->type() == FieldDescriptor::TYPE_ENUM &&
+ !HasPreservingUnknownEnumSemantics(field)) {
+ format(
+ "auto object = "
+ "::$proto_ns$::internal::InitEnumParseWrapper<"
+ "$unknown_fields_type$>(&$msg$$name$_, $1$_IsValid, "
+ "$2$, &$msg$_internal_metadata_);\n"
+ "ptr = ctx->ParseMessage(&object, ptr);\n",
+ QualifiedClassName(val->enum_type(), options_),
+ field->number());
+ } else {
+ format("ptr = ctx->ParseMessage(&$msg$$name$_, ptr);\n");
+ }
+ } else if (IsLazy(field, options_, scc_analyzer_)) {
+ if (field->real_containing_oneof()) {
+ format(
+ "if (!$msg$_internal_has_$name$()) {\n"
+ " $msg$clear_$1$();\n"
+ " $msg$$1$_.$name$_ = ::$proto_ns$::Arena::CreateMessage<\n"
+ " ::$proto_ns$::internal::LazyField>("
+ "$msg$GetArenaForAllocation());\n"
+ " $msg$set_has_$name$();\n"
+ "}\n"
+ "auto* lazy_field = $msg$$1$_.$name$_;\n",
+ field->containing_oneof()->name());
+ } else if (HasHasbit(field)) {
+ format(
+ "_Internal::set_has_$name$(&$has_bits$);\n"
+ "auto* lazy_field = &$msg$$name$_;\n");
+ } else {
+ format("auto* lazy_field = &$msg$$name$_;\n");
+ }
+ format(
+ "::$proto_ns$::internal::LazyFieldParseHelper<\n"
+ " ::$proto_ns$::internal::LazyField> parse_helper(\n"
+ " $1$::default_instance(),\n"
+ " $msg$GetArenaForAllocation(), lazy_field);\n"
+ "ptr = ctx->ParseMessage(&parse_helper, ptr);\n",
+ FieldMessageTypeName(field, options_));
+ } else if (IsImplicitWeakField(field, options_, scc_analyzer_)) {
+ if (!field->is_repeated()) {
+ format(
+ "ptr = ctx->ParseMessage(_Internal::mutable_$name$($this$), "
+ "ptr);\n");
+ } else {
+ format(
+ "ptr = ctx->ParseMessage($msg$$name$_.AddWeak("
+ "reinterpret_cast<const ::$proto_ns$::MessageLite*>($1$ptr_)"
+ "), ptr);\n",
+ QualifiedDefaultInstanceName(field->message_type(), options_));
+ }
+ } else if (IsWeak(field, options_)) {
+ format(
+ "{\n"
+ " auto* default_ = &reinterpret_cast<const Message&>($1$);\n"
+ " ptr = ctx->ParseMessage($msg$_weak_field_map_.MutableMessage("
+ "$2$, default_), ptr);\n"
+ "}\n",
+ QualifiedDefaultInstanceName(field->message_type(), options_),
+ field->number());
+ } else {
+ format(
+ "ptr = ctx->ParseMessage($msg$_internal_$mutable_field$(), "
+ "ptr);\n");
+ }
+ break;
+ }
+ default:
+ GOOGLE_LOG(FATAL) << "Illegal combination for length delimited wiretype "
+ << " filed type is " << field->type();
+ }
+ }
+}
+
+static bool ShouldRepeat(const FieldDescriptor* descriptor,
+ WireFormatLite::WireType wiretype) {
+ constexpr int kMaxTwoByteFieldNumber = 16 * 128;
+ return descriptor->number() < kMaxTwoByteFieldNumber &&
+ descriptor->is_repeated() &&
+ (!descriptor->is_packable() ||
+ wiretype != WireFormatLite::WIRETYPE_LENGTH_DELIMITED);
+}
+
+void ParseFunctionGenerator::GenerateFieldBody(
+ Formatter& format, WireFormatLite::WireType wiretype,
+ const FieldDescriptor* field) {
+ Formatter::SaveState formatter_state(&format);
+ format.AddMap(
+ {{"name", FieldName(field)},
+ {"primitive_type", PrimitiveTypeName(options_, field->cpp_type())}});
+ if (field->is_repeated()) {
+ format.AddMap({{"put_field", StrCat("add_", FieldName(field))},
+ {"mutable_field", StrCat("add_", FieldName(field))}});
+ } else {
+ format.AddMap(
+ {{"put_field", StrCat("set_", FieldName(field))},
+ {"mutable_field", StrCat("mutable_", FieldName(field))}});
+ }
+ uint32_t tag = WireFormatLite::MakeTag(field->number(), wiretype);
+ switch (wiretype) {
+ case WireFormatLite::WIRETYPE_VARINT: {
+ std::string type = PrimitiveTypeName(options_, field->cpp_type());
+ if (field->type() == FieldDescriptor::TYPE_ENUM) {
+ format.Set("enum_type",
+ QualifiedClassName(field->enum_type(), options_));
+ format(
+ "$uint64$ val = ::$proto_ns$::internal::ReadVarint64(&ptr);\n"
+ "CHK_(ptr);\n");
+ if (!HasPreservingUnknownEnumSemantics(field)) {
+ format("if (PROTOBUF_PREDICT_TRUE($enum_type$_IsValid(val))) {\n");
+ format.Indent();
+ }
+ format("$msg$_internal_$put_field$(static_cast<$enum_type$>(val));\n");
+ if (!HasPreservingUnknownEnumSemantics(field)) {
+ format.Outdent();
+ format(
+ "} else {\n"
+ " ::$proto_ns$::internal::WriteVarint("
+ "$1$, val, $msg$mutable_unknown_fields());\n"
+ "}\n",
+ field->number());
+ }
+ } else {
+ std::string size = (field->type() == FieldDescriptor::TYPE_INT32 ||
+ field->type() == FieldDescriptor::TYPE_SINT32 ||
+ field->type() == FieldDescriptor::TYPE_UINT32)
+ ? "32"
+ : "64";
+ std::string zigzag;
+ if ((field->type() == FieldDescriptor::TYPE_SINT32 ||
+ field->type() == FieldDescriptor::TYPE_SINT64)) {
+ zigzag = "ZigZag";
+ }
+ if (field->is_repeated() || field->real_containing_oneof()) {
+ format(
+ "$msg$_internal_$put_field$("
+ "::$proto_ns$::internal::ReadVarint$1$$2$(&ptr));\n"
+ "CHK_(ptr);\n",
+ zigzag, size);
+ } else {
+ if (HasHasbit(field)) {
+ format("_Internal::set_has_$name$(&$has_bits$);\n");
+ }
+ format(
+ "$msg$$name$_ = ::$proto_ns$::internal::ReadVarint$1$$2$(&ptr);\n"
+ "CHK_(ptr);\n",
+ zigzag, size);
+ }
+ }
+ break;
+ }
+ case WireFormatLite::WIRETYPE_FIXED32:
+ case WireFormatLite::WIRETYPE_FIXED64: {
+ if (field->is_repeated() || field->real_containing_oneof()) {
+ format(
+ "$msg$_internal_$put_field$("
+ "::$proto_ns$::internal::UnalignedLoad<$primitive_type$>(ptr));\n"
+ "ptr += sizeof($primitive_type$);\n");
+ } else {
+ if (HasHasbit(field)) {
+ format("_Internal::set_has_$name$(&$has_bits$);\n");
+ }
+ format(
+ "$msg$$name$_ = "
+ "::$proto_ns$::internal::UnalignedLoad<$primitive_type$>(ptr);\n"
+ "ptr += sizeof($primitive_type$);\n");
+ }
+ break;
+ }
+ case WireFormatLite::WIRETYPE_LENGTH_DELIMITED: {
+ GenerateLengthDelim(format, field);
+ format("CHK_(ptr);\n");
+ break;
+ }
+ case WireFormatLite::WIRETYPE_START_GROUP: {
+ format(
+ "ptr = ctx->ParseGroup($msg$_internal_$mutable_field$(), ptr, $1$);\n"
+ "CHK_(ptr);\n",
+ tag);
+ break;
+ }
+ case WireFormatLite::WIRETYPE_END_GROUP: {
+ GOOGLE_LOG(FATAL) << "Can't have end group field\n";
+ break;
+ }
+ } // switch (wire_type)
+}
+
+// Returns the tag for this field and in case of repeated packable fields,
+// sets a fallback tag in fallback_tag_ptr.
+static uint32_t ExpectedTag(const FieldDescriptor* field,
+ uint32_t* fallback_tag_ptr) {
+ uint32_t expected_tag;
+ if (field->is_packable()) {
+ auto expected_wiretype = WireFormat::WireTypeForFieldType(field->type());
+ expected_tag = WireFormatLite::MakeTag(field->number(), expected_wiretype);
+ GOOGLE_CHECK(expected_wiretype != WireFormatLite::WIRETYPE_LENGTH_DELIMITED);
+ auto fallback_wiretype = WireFormatLite::WIRETYPE_LENGTH_DELIMITED;
+ uint32_t fallback_tag =
+ WireFormatLite::MakeTag(field->number(), fallback_wiretype);
+
+ if (field->is_packed()) std::swap(expected_tag, fallback_tag);
+ *fallback_tag_ptr = fallback_tag;
+ } else {
+ auto expected_wiretype = WireFormat::WireTypeForField(field);
+ expected_tag = WireFormatLite::MakeTag(field->number(), expected_wiretype);
+ }
+ return expected_tag;
+}
+
+// These variables are used by the generated parse iteration, and must already
+// be defined in the generated code:
+// - `const char* ptr`: the input buffer.
+// - `ParseContext* ctx`: the associated context for `ptr`.
+// - implicit `this`: i.e., we must be in a non-static member function.
+//
+// The macro `CHK_(x)` must be defined. It should return an error condition if
+// the macro parameter is false.
+//
+// Whenever an END_GROUP tag was read, or tag 0 was read, the generated code
+// branches to the label `message_done`.
+//
+// These formatter variables are used:
+// - `next_tag`: a single statement to begin parsing the next tag.
+//
+// At the end of the generated code, the enclosing function should proceed to
+// parse the next tag in the stream.
+void ParseFunctionGenerator::GenerateParseIterationBody(
+ Formatter& format, const Descriptor* descriptor,
+ const std::vector<const FieldDescriptor*>& ordered_fields) {
+ format(
+ "$uint32$ tag;\n"
+ "ptr = ::$proto_ns$::internal::ReadTag(ptr, &tag);\n");
+
+ if (!ordered_fields.empty()) {
+ GenerateFieldSwitch(format, ordered_fields);
+ // Each field `case` only considers field number. Field numbers that are
+ // not defined in the message, or tags with an incompatible wire type, are
+ // considered "unusual" cases. They will be handled by the logic below.
+ format.Outdent();
+ format("handle_unusual:\n");
+ format.Indent();
+ }
+
+ // Unusual/extension/unknown case:
+ format(
+ "if ((tag == 0) || ((tag & 7) == 4)) {\n"
+ " CHK_(ptr);\n"
+ " ctx->SetLastTag(tag);\n"
+ " goto message_done;\n"
+ "}\n");
+ if (IsMapEntryMessage(descriptor)) {
+ format("$next_tag$;\n");
+ } else {
+ if (descriptor->extension_range_count() > 0) {
+ format("if (");
+ for (int i = 0; i < descriptor->extension_range_count(); i++) {
+ const Descriptor::ExtensionRange* range =
+ descriptor->extension_range(i);
+ if (i > 0) format(" ||\n ");
+
+ uint32_t start_tag = WireFormatLite::MakeTag(
+ range->start, static_cast<WireFormatLite::WireType>(0));
+ uint32_t end_tag = WireFormatLite::MakeTag(
+ range->end, static_cast<WireFormatLite::WireType>(0));
+
+ if (range->end > FieldDescriptor::kMaxNumber) {
+ format("($1$u <= tag)", start_tag);
+ } else {
+ format("($1$u <= tag && tag < $2$u)", start_tag, end_tag);
+ }
+ }
+ format(
+ ") {\n"
+ " ptr = $msg$_extensions_.ParseField(tag, ptr, "
+ "internal_default_instance(), &$msg$_internal_metadata_, ctx);\n"
+ " CHK_(ptr != nullptr);\n"
+ " $next_tag$;\n"
+ "}\n");
+ }
+ format(
+ "ptr = UnknownFieldParse(\n"
+ " tag,\n"
+ " $msg$_internal_metadata_.mutable_unknown_fields<"
+ "$unknown_fields_type$>(),\n"
+ " ptr, ctx);\n"
+ "CHK_(ptr != nullptr);\n");
+ }
+}
+
+void ParseFunctionGenerator::GenerateFieldSwitch(
+ Formatter& format,
+ const std::vector<const FieldDescriptor*>& ordered_fields) {
+ format("switch (tag >> 3) {\n");
+ format.Indent();
+
+ for (const auto* field : ordered_fields) {
+ PrintFieldComment(format, field);
+ format("case $1$:\n", field->number());
+ format.Indent();
+ uint32_t fallback_tag = 0;
+ uint32_t expected_tag = ExpectedTag(field, &fallback_tag);
+ format("if (PROTOBUF_PREDICT_TRUE(static_cast<$uint8$>(tag) == $1$)) {\n",
+ expected_tag & 0xFF);
+ format.Indent();
+ auto wiretype = WireFormatLite::GetTagWireType(expected_tag);
+ uint32_t tag = WireFormatLite::MakeTag(field->number(), wiretype);
+ int tag_size = io::CodedOutputStream::VarintSize32(tag);
+ bool is_repeat = ShouldRepeat(field, wiretype);
+ if (is_repeat) {
+ format(
+ "ptr -= $1$;\n"
+ "do {\n"
+ " ptr += $1$;\n",
+ tag_size);
+ format.Indent();
+ }
+ GenerateFieldBody(format, wiretype, field);
+ if (is_repeat) {
+ format.Outdent();
+ format(
+ " if (!ctx->DataAvailable(ptr)) break;\n"
+ "} while (::$proto_ns$::internal::ExpectTag<$1$>(ptr));\n",
+ tag);
+ }
+ format.Outdent();
+ if (fallback_tag) {
+ format("} else if (static_cast<$uint8$>(tag) == $1$) {\n",
+ fallback_tag & 0xFF);
+ format.Indent();
+ GenerateFieldBody(format, WireFormatLite::GetTagWireType(fallback_tag),
+ field);
+ format.Outdent();
+ }
+ format(
+ "} else\n"
+ " goto handle_unusual;\n"
+ "$next_tag$;\n");
+ format.Outdent();
+ } // for loop over ordered fields
+
+ format(
+ "default:\n"
+ " goto handle_unusual;\n");
+ format.Outdent();
+ format("} // switch\n");
+}
+
+namespace {
+
+std::string FieldParseFunctionName(const FieldDescriptor* field,
+ const Options& options) {
+ ParseCardinality card = //
+ field->is_packed() ? ParseCardinality::kPacked
+ : field->is_repeated() ? ParseCardinality::kRepeated
+ : field->real_containing_oneof() ? ParseCardinality::kOneof
+ : ParseCardinality::kSingular;
+
+ TypeFormat type_format;
+ switch (field->type()) {
+ case FieldDescriptor::TYPE_FIXED64:
+ case FieldDescriptor::TYPE_SFIXED64:
+ case FieldDescriptor::TYPE_DOUBLE:
+ type_format = TypeFormat::kFixed64;
+ break;
+
+ case FieldDescriptor::TYPE_FIXED32:
+ case FieldDescriptor::TYPE_SFIXED32:
+ case FieldDescriptor::TYPE_FLOAT:
+ type_format = TypeFormat::kFixed32;
+ break;
+
+ case FieldDescriptor::TYPE_INT64:
+ case FieldDescriptor::TYPE_UINT64:
+ type_format = TypeFormat::kVar64;
+ break;
+
+ case FieldDescriptor::TYPE_INT32:
+ case FieldDescriptor::TYPE_UINT32:
+ type_format = TypeFormat::kVar32;
+ break;
+
+ case FieldDescriptor::TYPE_SINT64:
+ type_format = TypeFormat::kSInt64;
+ break;
+
+ case FieldDescriptor::TYPE_SINT32:
+ type_format = TypeFormat::kSInt32;
+ break;
+
+ case FieldDescriptor::TYPE_BOOL:
+ type_format = TypeFormat::kBool;
+ break;
+
+ case FieldDescriptor::TYPE_BYTES:
+ type_format = TypeFormat::kBytes;
+ break;
+
+ case FieldDescriptor::TYPE_STRING:
+ switch (GetUtf8CheckMode(field, options)) {
+ case Utf8CheckMode::kNone:
+ type_format = TypeFormat::kBytes;
+ break;
+ case Utf8CheckMode::kStrict:
+ type_format = TypeFormat::kString;
+ break;
+ case Utf8CheckMode::kVerify:
+ type_format = TypeFormat::kStringValidateOnly;
+ break;
+ default:
+ GOOGLE_LOG(DFATAL) << "Mode not handled: "
+ << static_cast<int>(GetUtf8CheckMode(field, options));
+ return "";
+ }
+ break;
+
+ default:
+ GOOGLE_LOG(DFATAL) << "Type not handled: " << field->DebugString();
+ return "";
+ }
+
+ return "::" + ProtobufNamespace(options) + "::internal::TcParser::" +
+ GetTailCallFieldHandlerName(card, type_format,
+ TagSize(field->number()), options);
+}
+
+} // namespace
+
+std::string GetTailCallFieldHandlerName(ParseCardinality card,
+ TypeFormat type_format,
+ int tag_length_bytes,
+ const Options& options) {
+ std::string name;
+
+ // The field implementation functions are prefixed by cardinality:
+ // `Singular` for optional or implicit fields.
+ // `Repeated` for non-packed repeated.
+ // `Packed` for packed repeated.
+ switch (card) {
+ case ParseCardinality::kSingular:
+ name.append("Singular");
+ break;
+ case ParseCardinality::kOneof:
+ name.append("Oneof");
+ break;
+ case ParseCardinality::kRepeated:
+ name.append("Repeated");
+ break;
+ case ParseCardinality::kPacked:
+ name.append("Packed");
+ break;
+ }
+
+ // Next in the function name is the TypeFormat-specific name.
+ switch (type_format) {
+ case TypeFormat::kFixed64:
+ case TypeFormat::kFixed32:
+ name.append("Fixed");
+ break;
+
+ case TypeFormat::kVar64:
+ case TypeFormat::kVar32:
+ case TypeFormat::kSInt64:
+ case TypeFormat::kSInt32:
+ case TypeFormat::kBool:
+ name.append("Varint");
+ break;
+
+ case TypeFormat::kBytes:
+ case TypeFormat::kString:
+ case TypeFormat::kStringValidateOnly:
+ name.append("String");
+ break;
+
+ default:
+ break;
+ }
+
+ name.append("<");
+
+ // Determine the numeric layout type for the parser to use, independent of
+ // the specific parsing logic used.
+ switch (type_format) {
+ case TypeFormat::kVar64:
+ case TypeFormat::kFixed64:
+ name.append("uint64_t, ");
+ break;
+
+ case TypeFormat::kSInt64:
+ name.append("int64_t, ");
+ break;
+
+ case TypeFormat::kVar32:
+ case TypeFormat::kFixed32:
+ name.append("uint32_t, ");
+ break;
+
+ case TypeFormat::kSInt32:
+ name.append("int32_t, ");
+ break;
+
+ case TypeFormat::kBool:
+ name.append("bool, ");
+ break;
+
+ default:
+ break;
+ }
+
+ name.append(CodedTagType(tag_length_bytes));
+
+ switch (type_format) {
+ case TypeFormat::kVar64:
+ case TypeFormat::kVar32:
+ case TypeFormat::kBool:
+ StrAppend(&name, ", ", TcParserName(options), "kNoConversion");
+ break;
+
+ case TypeFormat::kSInt64:
+ case TypeFormat::kSInt32:
+ StrAppend(&name, ", ", TcParserName(options), "kZigZag");
+ break;
+
+ case TypeFormat::kBytes:
+ StrAppend(&name, ", ", TcParserName(options), "kNoUtf8");
+ break;
+
+ case TypeFormat::kString:
+ StrAppend(&name, ", ", TcParserName(options), "kUtf8");
+ break;
+
+ case TypeFormat::kStringValidateOnly:
+ StrAppend(&name, ", ", TcParserName(options), "kUtf8ValidateOnly");
+ break;
+
+ default:
+ break;
+ }
+
+ name.append(">");
+ return name;
+}
+
+} // namespace cpp
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_parse_function_generator.h b/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_parse_function_generator.h
new file mode 100644
index 00000000..54c0a36d
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_parse_function_generator.h
@@ -0,0 +1,199 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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_COMPILER_CPP_PARSE_FUNCTION_GENERATOR_H__
+#define GOOGLE_PROTOBUF_COMPILER_CPP_PARSE_FUNCTION_GENERATOR_H__
+
+#include <map>
+#include <string>
+#include <vector>
+
+#include <compiler/cpp/cpp_helpers.h>
+#include <compiler/cpp/cpp_options.h>
+#include <io/printer.h>
+#include <descriptor.h>
+#include <generated_message_tctable_decl.h>
+#include <wire_format_lite.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+// Helper class for generating tailcall parsing functions.
+struct TailCallTableInfo {
+ TailCallTableInfo(const Descriptor* descriptor, const Options& options,
+ const std::vector<int>& has_bit_indices,
+ MessageSCCAnalyzer* scc_analyzer);
+ // Information to generate field entries.
+ struct FieldInfo {
+ const FieldDescriptor* field;
+ google::protobuf::internal::TcFieldData bits;
+ std::string func_name;
+ };
+ // Fields parsed by the table fast-path.
+ std::vector<FieldInfo> fast_path_fields;
+ // Fields parsed by slow-path fallback.
+ std::vector<const FieldDescriptor*> fallback_fields;
+ // Table size.
+ int table_size_log2;
+ // Mask for has-bits of required fields.
+ uint32_t has_hasbits_required_mask;
+ // True if a generated fallback function is required instead of generic.
+ bool use_generated_fallback;
+};
+
+// ParseFunctionGenerator generates the _InternalParse function for a message
+// (and any associated supporting members).
+class ParseFunctionGenerator {
+ public:
+ ParseFunctionGenerator(const Descriptor* descriptor, int max_has_bit_index,
+ const std::vector<int>& has_bit_indices,
+ const std::vector<int>& inlined_string_indices,
+ const Options& options,
+ MessageSCCAnalyzer* scc_analyzer,
+ const std::map<std::string, std::string>& vars);
+
+ // Emits class-level method declarations to `printer`:
+ void GenerateMethodDecls(io::Printer* printer);
+
+ // Emits out-of-class method implementation definitions to `printer`:
+ void GenerateMethodImpls(io::Printer* printer);
+
+ // Emits class-level data member declarations to `printer`:
+ void GenerateDataDecls(io::Printer* printer);
+
+ // Emits out-of-class data member definitions to `printer`:
+ void GenerateDataDefinitions(io::Printer* printer);
+
+ private:
+ // Returns true if tailcall table code should be generated.
+ bool should_generate_tctable() const;
+
+ // Returns true if tailcall table code should be generated, but inside an
+ // #ifdef guard.
+ bool should_generate_guarded_tctable() const {
+ return should_generate_tctable() &&
+ options_.tctable_mode == Options::kTCTableGuarded;
+ }
+
+ // Generates a tail-calling `_InternalParse` function.
+ void GenerateTailcallParseFunction(Formatter& format);
+
+ // Generates a fallback function for tailcall table-based parsing.
+ void GenerateTailcallFallbackFunction(Formatter& format);
+
+ // Generates functions for parsing this message as a field.
+ void GenerateTailcallFieldParseFunctions(Formatter& format);
+
+ // Generates a looping `_InternalParse` function.
+ void GenerateLoopingParseFunction(Formatter& format);
+
+ // Generates the tail-call table definition.
+ void GenerateTailCallTable(Formatter& format);
+ void GenerateFastFieldEntries(Formatter& format, const std::string& fallback);
+
+ // Generates parsing code for an `ArenaString` field.
+ void GenerateArenaString(Formatter& format, const FieldDescriptor* field);
+
+ // Generates parsing code for a string-typed field.
+ void GenerateStrings(Formatter& format, const FieldDescriptor* field,
+ bool check_utf8);
+
+ // Generates parsing code for a length-delimited field (strings, messages,
+ // etc.).
+ void GenerateLengthDelim(Formatter& format, const FieldDescriptor* field);
+
+ // Generates the parsing code for a known field.
+ void GenerateFieldBody(Formatter& format,
+ google::protobuf::internal::WireFormatLite::WireType wiretype,
+ const FieldDescriptor* field);
+
+ // Generates code to parse the next field from the input stream.
+ void GenerateParseIterationBody(
+ Formatter& format, const Descriptor* descriptor,
+ const std::vector<const FieldDescriptor*>& ordered_fields);
+
+ // Generates a `switch` statement to parse each of `ordered_fields`.
+ void GenerateFieldSwitch(
+ Formatter& format,
+ const std::vector<const FieldDescriptor*>& ordered_fields);
+
+ const Descriptor* descriptor_;
+ MessageSCCAnalyzer* scc_analyzer_;
+ const Options& options_;
+ std::map<std::string, std::string> variables_;
+ std::unique_ptr<TailCallTableInfo> tc_table_info_;
+ std::vector<int> inlined_string_indices_;
+ int num_hasbits_;
+};
+
+enum class ParseCardinality {
+ kSingular,
+ kOneof,
+ kRepeated,
+ kPacked,
+};
+
+// TypeFormat defines parsing types, which encapsulates the expected wire
+// format, conversion or validation, and the in-memory layout.
+enum class TypeFormat {
+ // Fixed types:
+ kFixed64, // fixed64, sfixed64, double
+ kFixed32, // fixed32, sfixed32, float
+
+ // Varint types:
+ kVar64, // int64, uint64
+ kVar32, // int32, uint32
+ kSInt64, // sint64
+ kSInt32, // sint32
+ kBool, // bool
+
+ // Length-delimited types:
+ kBytes, // bytes
+ kString, // string (proto3/UTF-8 strict)
+ kStringValidateOnly, // string (proto2/UTF-8 validate only)
+};
+
+// Returns the name of a field parser function.
+//
+// These are out-of-line functions generated by
+// parse_function_inc_generator_main.
+std::string GetTailCallFieldHandlerName(ParseCardinality card,
+ TypeFormat type_format,
+ int tag_length_bytes,
+ const Options& options);
+
+} // namespace cpp
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_COMPILER_CPP_PARSE_FUNCTION_GENERATOR_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_plugin_unittest.cc b/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_plugin_unittest.cc
new file mode 100644
index 00000000..3e7bebf7
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_plugin_unittest.cc
@@ -0,0 +1,236 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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)
+//
+// TODO(kenton): Share code with the versions of this test in other languages?
+// It seemed like parameterizing it would add more complexity than it is
+// worth.
+
+#include <memory>
+
+#include <testing/file.h>
+#include <testing/file.h>
+#include <compiler/cpp/cpp_generator.h>
+#include <compiler/command_line_interface.h>
+#include <io/printer.h>
+#include <io/zero_copy_stream.h>
+#include <testing/googletest.h>
+#include <gtest/gtest.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+namespace {
+
+class TestGenerator : public CodeGenerator {
+ public:
+ TestGenerator() {}
+ ~TestGenerator() {}
+
+ virtual bool Generate(const FileDescriptor* file,
+ const std::string& parameter, GeneratorContext* context,
+ std::string* error) const {
+ TryInsert("test.pb.h", "includes", context);
+ TryInsert("test.pb.h", "namespace_scope", context);
+ TryInsert("test.pb.h", "global_scope", context);
+ TryInsert("test.pb.h", "class_scope:foo.Bar", context);
+ TryInsert("test.pb.h", "class_scope:foo.Bar.Baz", context);
+
+ TryInsert("test.pb.cc", "includes", context);
+ TryInsert("test.pb.cc", "namespace_scope", context);
+ TryInsert("test.pb.cc", "global_scope", context);
+
+ // Check field accessors for an optional int32:
+ TryInsert("test.pb.h", "field_get:foo.Bar.optInt", context);
+ TryInsert("test.pb.h", "field_set:foo.Bar.optInt", context);
+
+ // Check field accessors for a repeated int32:
+ TryInsert("test.pb.h", "field_get:foo.Bar.repeatedInt", context);
+ TryInsert("test.pb.h", "field_set:foo.Bar.repeatedInt", context);
+
+ // Check field accessors for a required string:
+ TryInsert("test.pb.h", "field_get:foo.Bar.requiredString", context);
+ TryInsert("test.pb.h", "field_set:foo.Bar.requiredString", context);
+ TryInsert("test.pb.h", "field_mutable:foo.Bar.requiredString", context);
+ TryInsert("test.pb.h", "field_set_allocated:foo.Bar.requiredString",
+ context);
+
+ // Check field accessors for a repeated string:
+ TryInsert("test.pb.h", "field_get:foo.Bar.repeatedString", context);
+ TryInsert("test.pb.h", "field_set:foo.Bar.repeatedString", context);
+ TryInsert("test.pb.h", "field_set_char:foo.Bar.repeatedString", context);
+ TryInsert("test.pb.h", "field_set_pointer:foo.Bar.repeatedString", context);
+ TryInsert("test.pb.h", "field_mutable:foo.Bar.repeatedString", context);
+ TryInsert("test.pb.h", "field_set_char:foo.Bar.repeatedString", context);
+ TryInsert("test.pb.h", "field_set_pointer:foo.Bar.repeatedString", context);
+
+ // Check field accessors for an int inside oneof{}:
+ TryInsert("test.pb.h", "field_get:foo.Bar.oneOfInt", context);
+ TryInsert("test.pb.h", "field_set:foo.Bar.oneOfInt", context);
+
+ // Check field accessors for a string inside oneof{}:
+ TryInsert("test.pb.h", "field_get:foo.Bar.oneOfString", context);
+ TryInsert("test.pb.h", "field_set:foo.Bar.oneOfString", context);
+ TryInsert("test.pb.h", "field_mutable:foo.Bar.oneOfString", context);
+ TryInsert("test.pb.h", "field_set_allocated:foo.Bar.oneOfString", context);
+
+ // Check field accessors for an optional message:
+ TryInsert("test.pb.h", "field_get:foo.Bar.optMessage", context);
+ TryInsert("test.pb.h", "field_mutable:foo.Bar.optMessage", context);
+ TryInsert("test.pb.h", "field_set_allocated:foo.Bar.optMessage", context);
+
+ // Check field accessors for a repeated message:
+ TryInsert("test.pb.h", "field_add:foo.Bar.repeatedMessage", context);
+ TryInsert("test.pb.h", "field_get:foo.Bar.repeatedMessage", context);
+ TryInsert("test.pb.h", "field_list:foo.Bar.repeatedMessage", context);
+ TryInsert("test.pb.h", "field_mutable:foo.Bar.repeatedMessage", context);
+ TryInsert("test.pb.h", "field_mutable_list:foo.Bar.repeatedMessage",
+ context);
+
+ // Check field accessors for a message inside oneof{}:
+ TryInsert("test.pb.h", "field_get:foo.Bar.oneOfMessage", context);
+ TryInsert("test.pb.h", "field_mutable:foo.Bar.oneOfMessage", context);
+ TryInsert("test.pb.cc", "field_set_allocated:foo.Bar.oneOfMessage",
+ context);
+
+ // Check field accessors for an optional enum:
+ TryInsert("test.pb.h", "field_get:foo.Bar.optEnum", context);
+ TryInsert("test.pb.h", "field_set:foo.Bar.optEnum", context);
+
+ // Check field accessors for a repeated enum:
+ TryInsert("test.pb.h", "field_get:foo.Bar.repeatedEnum", context);
+ TryInsert("test.pb.h", "field_set:foo.Bar.repeatedEnum", context);
+ TryInsert("test.pb.h", "field_add:foo.Bar.repeatedEnum", context);
+ TryInsert("test.pb.h", "field_list:foo.Bar.repeatedEnum", context);
+ TryInsert("test.pb.h", "field_mutable_list:foo.Bar.repeatedEnum", context);
+
+ // Check field accessors for an enum inside oneof{}:
+ TryInsert("test.pb.h", "field_get:foo.Bar.oneOfEnum", context);
+ TryInsert("test.pb.h", "field_set:foo.Bar.oneOfEnum", context);
+
+ // Check field accessors for a required cord:
+ TryInsert("test.pb.h", "field_get:foo.Bar.requiredCord", context);
+ TryInsert("test.pb.h", "field_set:foo.Bar.requiredCord", context);
+ TryInsert("test.pb.h", "field_mutable:foo.Bar.requiredCord", context);
+
+ // Check field accessors for a repeated cord:
+ TryInsert("test.pb.h", "field_get:foo.Bar.repeatedCord", context);
+ TryInsert("test.pb.h", "field_set:foo.Bar.repeatedCord", context);
+ TryInsert("test.pb.h", "field_add:foo.Bar.repeatedCord", context);
+ TryInsert("test.pb.h", "field_list:foo.Bar.repeatedCord", context);
+ TryInsert("test.pb.h", "field_mutable:foo.Bar.repeatedCord", context);
+ TryInsert("test.pb.h", "field_mutable_list:foo.Bar.repeatedCord", context);
+
+ // Check field accessors for a cord inside oneof{}:
+ TryInsert("test.pb.h", "field_get:foo.Bar.oneOfCord", context);
+ TryInsert("test.pb.h", "field_set:foo.Bar.oneOfCord", context);
+ TryInsert("test.pb.h", "field_mutable:foo.Bar.oneOfCord", context);
+
+ return true;
+ }
+
+ void TryInsert(const std::string& filename,
+ const std::string& insertion_point,
+ GeneratorContext* context) const {
+ std::unique_ptr<io::ZeroCopyOutputStream> output(
+ context->OpenForInsert(filename, insertion_point));
+ io::Printer printer(output.get(), '$');
+ printer.Print("// inserted $name$\n", "name", insertion_point);
+ }
+};
+
+// This test verifies that all the expected insertion points exist. It does
+// not verify that they are correctly-placed; that would require actually
+// compiling the output which is a bit more than I care to do for this test.
+TEST(CppPluginTest, PluginTest) {
+ GOOGLE_CHECK_OK(File::SetContents(TestTempDir() + "/test.proto",
+ "syntax = \"proto2\";\n"
+ "package foo;\n"
+ "\n"
+ "enum Thud { VALUE = 0; }\n"
+ "\n"
+ "message Bar {\n"
+ " message Baz {}\n"
+ " optional int32 optInt = 1;\n"
+ " repeated int32 repeatedInt = 2;\n"
+ "\n"
+ " required string requiredString = 3;\n"
+ " repeated string repeatedString = 4;\n"
+ "\n"
+ " optional Baz optMessage = 6;\n"
+ " repeated Baz repeatedMessage = 7;\n"
+ "\n"
+ " optional Thud optEnum = 8;\n"
+ " repeated Thud repeatedEnum = 9;\n"
+ "\n"
+ " required string requiredCord = 10 [\n"
+ " ctype = CORD\n"
+ " ];\n"
+ " repeated string repeatedCord = 11 [\n"
+ " ctype = CORD\n"
+ " ];\n"
+ "\n"
+ " oneof Qux {\n"
+ " int64 oneOfInt = 20;\n"
+ " string oneOfString = 21;\n"
+ " Baz oneOfMessage = 22;\n"
+ " Thud oneOfEnum = 23;"
+ " string oneOfCord = 24 [\n"
+ " ctype = CORD\n"
+ " ];\n"
+ " }\n"
+ "}\n",
+ true));
+
+ CommandLineInterface cli;
+ cli.SetInputsAreProtoPathRelative(true);
+
+ CppGenerator cpp_generator;
+ TestGenerator test_generator;
+ cli.RegisterGenerator("--cpp_out", &cpp_generator, "");
+ cli.RegisterGenerator("--test_out", &test_generator, "");
+
+ std::string proto_path = "-I" + TestTempDir();
+ std::string cpp_out = "--cpp_out=" + TestTempDir();
+ std::string test_out = "--test_out=" + TestTempDir();
+
+ const char* argv[] = {"protoc", proto_path.c_str(), cpp_out.c_str(),
+ test_out.c_str(), "test.proto"};
+
+ EXPECT_EQ(0, cli.Run(5, argv));
+}
+
+} // namespace
+} // namespace cpp
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_primitive_field.cc b/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_primitive_field.cc
new file mode 100644
index 00000000..06037b95
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_primitive_field.cc
@@ -0,0 +1,505 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 <compiler/cpp/cpp_primitive_field.h>
+
+#include <compiler/cpp/cpp_helpers.h>
+#include <io/printer.h>
+#include <wire_format.h>
+#include <stubs/strutil.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+using internal::WireFormatLite;
+
+namespace {
+
+// For encodings with fixed sizes, returns that size in bytes. Otherwise
+// returns -1.
+int FixedSize(FieldDescriptor::Type type) {
+ switch (type) {
+ case FieldDescriptor::TYPE_INT32:
+ return -1;
+ case FieldDescriptor::TYPE_INT64:
+ return -1;
+ case FieldDescriptor::TYPE_UINT32:
+ return -1;
+ case FieldDescriptor::TYPE_UINT64:
+ return -1;
+ case FieldDescriptor::TYPE_SINT32:
+ return -1;
+ case FieldDescriptor::TYPE_SINT64:
+ return -1;
+ case FieldDescriptor::TYPE_FIXED32:
+ return WireFormatLite::kFixed32Size;
+ case FieldDescriptor::TYPE_FIXED64:
+ return WireFormatLite::kFixed64Size;
+ case FieldDescriptor::TYPE_SFIXED32:
+ return WireFormatLite::kSFixed32Size;
+ case FieldDescriptor::TYPE_SFIXED64:
+ return WireFormatLite::kSFixed64Size;
+ case FieldDescriptor::TYPE_FLOAT:
+ return WireFormatLite::kFloatSize;
+ case FieldDescriptor::TYPE_DOUBLE:
+ return WireFormatLite::kDoubleSize;
+
+ case FieldDescriptor::TYPE_BOOL:
+ return WireFormatLite::kBoolSize;
+ case FieldDescriptor::TYPE_ENUM:
+ return -1;
+
+ case FieldDescriptor::TYPE_STRING:
+ return -1;
+ case FieldDescriptor::TYPE_BYTES:
+ return -1;
+ case FieldDescriptor::TYPE_GROUP:
+ return -1;
+ case FieldDescriptor::TYPE_MESSAGE:
+ return -1;
+
+ // No default because we want the compiler to complain if any new
+ // types are added.
+ }
+ GOOGLE_LOG(FATAL) << "Can't get here.";
+ return -1;
+}
+
+void SetPrimitiveVariables(const FieldDescriptor* descriptor,
+ std::map<std::string, std::string>* variables,
+ const Options& options) {
+ SetCommonFieldVariables(descriptor, variables, options);
+ (*variables)["type"] = PrimitiveTypeName(options, descriptor->cpp_type());
+ (*variables)["default"] = DefaultValue(options, descriptor);
+ (*variables)["tag"] = StrCat(internal::WireFormat::MakeTag(descriptor));
+ int fixed_size = FixedSize(descriptor->type());
+ if (fixed_size != -1) {
+ (*variables)["fixed_size"] = StrCat(fixed_size);
+ }
+ (*variables)["wire_format_field_type"] = FieldDescriptorProto_Type_Name(
+ static_cast<FieldDescriptorProto_Type>(descriptor->type()));
+ (*variables)["full_name"] = descriptor->full_name();
+}
+
+} // namespace
+
+// ===================================================================
+
+PrimitiveFieldGenerator::PrimitiveFieldGenerator(
+ const FieldDescriptor* descriptor, const Options& options)
+ : FieldGenerator(descriptor, options) {
+ SetPrimitiveVariables(descriptor, &variables_, options);
+}
+
+PrimitiveFieldGenerator::~PrimitiveFieldGenerator() {}
+
+void PrimitiveFieldGenerator::GeneratePrivateMembers(
+ io::Printer* printer) const {
+ Formatter format(printer, variables_);
+ format("$type$ $name$_;\n");
+}
+
+void PrimitiveFieldGenerator::GenerateAccessorDeclarations(
+ io::Printer* printer) const {
+ Formatter format(printer, variables_);
+ format(
+ "$deprecated_attr$$type$ ${1$$name$$}$() const;\n"
+ "$deprecated_attr$void ${1$set_$name$$}$($type$ value);\n"
+ "private:\n"
+ "$type$ ${1$_internal_$name$$}$() const;\n"
+ "void ${1$_internal_set_$name$$}$($type$ value);\n"
+ "public:\n",
+ descriptor_);
+}
+
+void PrimitiveFieldGenerator::GenerateInlineAccessorDefinitions(
+ io::Printer* printer) const {
+ Formatter format(printer, variables_);
+ format(
+ "inline $type$ $classname$::_internal_$name$() const {\n"
+ " return $name$_;\n"
+ "}\n"
+ "inline $type$ $classname$::$name$() const {\n"
+ "$annotate_get$"
+ " // @@protoc_insertion_point(field_get:$full_name$)\n"
+ " return _internal_$name$();\n"
+ "}\n"
+ "inline void $classname$::_internal_set_$name$($type$ value) {\n"
+ " $set_hasbit$\n"
+ " $name$_ = value;\n"
+ "}\n"
+ "inline void $classname$::set_$name$($type$ value) {\n"
+ " _internal_set_$name$(value);\n"
+ "$annotate_set$"
+ " // @@protoc_insertion_point(field_set:$full_name$)\n"
+ "}\n");
+}
+
+void PrimitiveFieldGenerator::GenerateClearingCode(io::Printer* printer) const {
+ Formatter format(printer, variables_);
+ format("$name$_ = $default$;\n");
+}
+
+void PrimitiveFieldGenerator::GenerateMergingCode(io::Printer* printer) const {
+ Formatter format(printer, variables_);
+ format("_internal_set_$name$(from._internal_$name$());\n");
+}
+
+void PrimitiveFieldGenerator::GenerateSwappingCode(io::Printer* printer) const {
+ Formatter format(printer, variables_);
+ format("swap($name$_, other->$name$_);\n");
+}
+
+void PrimitiveFieldGenerator::GenerateConstructorCode(
+ io::Printer* printer) const {
+ Formatter format(printer, variables_);
+ format("$name$_ = $default$;\n");
+}
+
+void PrimitiveFieldGenerator::GenerateCopyConstructorCode(
+ io::Printer* printer) const {
+ Formatter format(printer, variables_);
+ format("$name$_ = from.$name$_;\n");
+}
+
+void PrimitiveFieldGenerator::GenerateSerializeWithCachedSizesToArray(
+ io::Printer* printer) const {
+ Formatter format(printer, variables_);
+ format(
+ "target = stream->EnsureSpace(target);\n"
+ "target = "
+ "::$proto_ns$::internal::WireFormatLite::Write$declared_type$ToArray("
+ "$number$, this->_internal_$name$(), target);\n");
+}
+
+void PrimitiveFieldGenerator::GenerateByteSize(io::Printer* printer) const {
+ Formatter format(printer, variables_);
+ int fixed_size = FixedSize(descriptor_->type());
+ if (fixed_size == -1) {
+ if (internal::WireFormat::TagSize(descriptor_->number(),
+ descriptor_->type()) == 1) {
+ // Adding one is very common and it turns out it can be done for
+ // free inside of WireFormatLite, so we can save an instruction here.
+ format(
+ "total_size += ::$proto_ns$::internal::WireFormatLite::"
+ "$declared_type$SizePlusOne(this->_internal_$name$());\n");
+ } else {
+ format(
+ "total_size += $tag_size$ +\n"
+ " ::$proto_ns$::internal::WireFormatLite::$declared_type$Size(\n"
+ " this->_internal_$name$());\n");
+ }
+ } else {
+ format("total_size += $tag_size$ + $fixed_size$;\n");
+ }
+}
+
+void PrimitiveFieldGenerator::GenerateConstinitInitializer(
+ io::Printer* printer) const {
+ Formatter format(printer, variables_);
+ format("$name$_($default$)");
+}
+
+// ===================================================================
+
+PrimitiveOneofFieldGenerator::PrimitiveOneofFieldGenerator(
+ const FieldDescriptor* descriptor, const Options& options)
+ : PrimitiveFieldGenerator(descriptor, options) {
+ SetCommonOneofFieldVariables(descriptor, &variables_);
+}
+
+PrimitiveOneofFieldGenerator::~PrimitiveOneofFieldGenerator() {}
+
+void PrimitiveOneofFieldGenerator::GenerateInlineAccessorDefinitions(
+ io::Printer* printer) const {
+ Formatter format(printer, variables_);
+ format(
+ "inline $type$ $classname$::_internal_$name$() const {\n"
+ " if (_internal_has_$name$()) {\n"
+ " return $field_member$;\n"
+ " }\n"
+ " return $default$;\n"
+ "}\n"
+ "inline void $classname$::_internal_set_$name$($type$ value) {\n"
+ " if (!_internal_has_$name$()) {\n"
+ " clear_$oneof_name$();\n"
+ " set_has_$name$();\n"
+ " }\n"
+ " $field_member$ = value;\n"
+ "}\n"
+ "inline $type$ $classname$::$name$() const {\n"
+ "$annotate_get$"
+ " // @@protoc_insertion_point(field_get:$full_name$)\n"
+ " return _internal_$name$();\n"
+ "}\n"
+ "inline void $classname$::set_$name$($type$ value) {\n"
+ " _internal_set_$name$(value);\n"
+ "$annotate_set$"
+ " // @@protoc_insertion_point(field_set:$full_name$)\n"
+ "}\n");
+}
+
+void PrimitiveOneofFieldGenerator::GenerateClearingCode(
+ io::Printer* printer) const {
+ Formatter format(printer, variables_);
+ format("$field_member$ = $default$;\n");
+}
+
+void PrimitiveOneofFieldGenerator::GenerateSwappingCode(
+ io::Printer* printer) const {
+ // Don't print any swapping code. Swapping the union will swap this field.
+}
+
+void PrimitiveOneofFieldGenerator::GenerateConstructorCode(
+ io::Printer* printer) const {
+ Formatter format(printer, variables_);
+ format("$ns$::_$classname$_default_instance_.$name$_ = $default$;\n");
+}
+
+// ===================================================================
+
+RepeatedPrimitiveFieldGenerator::RepeatedPrimitiveFieldGenerator(
+ const FieldDescriptor* descriptor, const Options& options)
+ : FieldGenerator(descriptor, options) {
+ SetPrimitiveVariables(descriptor, &variables_, options);
+
+ if (descriptor->is_packed()) {
+ variables_["packed_reader"] = "ReadPackedPrimitive";
+ variables_["repeated_reader"] = "ReadRepeatedPrimitiveNoInline";
+ } else {
+ variables_["packed_reader"] = "ReadPackedPrimitiveNoInline";
+ variables_["repeated_reader"] = "ReadRepeatedPrimitive";
+ }
+}
+
+RepeatedPrimitiveFieldGenerator::~RepeatedPrimitiveFieldGenerator() {}
+
+void RepeatedPrimitiveFieldGenerator::GeneratePrivateMembers(
+ io::Printer* printer) const {
+ Formatter format(printer, variables_);
+ format("::$proto_ns$::RepeatedField< $type$ > $name$_;\n");
+ if (descriptor_->is_packed() && FixedSize(descriptor_->type()) == -1 &&
+ HasGeneratedMethods(descriptor_->file(), options_)) {
+ format("mutable std::atomic<int> _$name$_cached_byte_size_;\n");
+ }
+}
+
+void RepeatedPrimitiveFieldGenerator::GenerateAccessorDeclarations(
+ io::Printer* printer) const {
+ Formatter format(printer, variables_);
+ format(
+ "private:\n"
+ "$type$ ${1$_internal_$name$$}$(int index) const;\n"
+ "const ::$proto_ns$::RepeatedField< $type$ >&\n"
+ " ${1$_internal_$name$$}$() const;\n"
+ "void ${1$_internal_add_$name$$}$($type$ value);\n"
+ "::$proto_ns$::RepeatedField< $type$ >*\n"
+ " ${1$_internal_mutable_$name$$}$();\n"
+ "public:\n"
+ "$deprecated_attr$$type$ ${1$$name$$}$(int index) const;\n"
+ "$deprecated_attr$void ${1$set_$name$$}$(int index, $type$ value);\n"
+ "$deprecated_attr$void ${1$add_$name$$}$($type$ value);\n"
+ "$deprecated_attr$const ::$proto_ns$::RepeatedField< $type$ >&\n"
+ " ${1$$name$$}$() const;\n"
+ "$deprecated_attr$::$proto_ns$::RepeatedField< $type$ >*\n"
+ " ${1$mutable_$name$$}$();\n",
+ descriptor_);
+}
+
+void RepeatedPrimitiveFieldGenerator::GenerateInlineAccessorDefinitions(
+ io::Printer* printer) const {
+ Formatter format(printer, variables_);
+ format(
+ "inline $type$ $classname$::_internal_$name$(int index) const {\n"
+ " return $name$_.Get(index);\n"
+ "}\n"
+ "inline $type$ $classname$::$name$(int index) const {\n"
+ "$annotate_get$"
+ " // @@protoc_insertion_point(field_get:$full_name$)\n"
+ " return _internal_$name$(index);\n"
+ "}\n"
+ "inline void $classname$::set_$name$(int index, $type$ value) {\n"
+ "$annotate_set$"
+ " $name$_.Set(index, value);\n"
+ " // @@protoc_insertion_point(field_set:$full_name$)\n"
+ "}\n"
+ "inline void $classname$::_internal_add_$name$($type$ value) {\n"
+ " $name$_.Add(value);\n"
+ "}\n"
+ "inline void $classname$::add_$name$($type$ value) {\n"
+ " _internal_add_$name$(value);\n"
+ "$annotate_add$"
+ " // @@protoc_insertion_point(field_add:$full_name$)\n"
+ "}\n"
+ "inline const ::$proto_ns$::RepeatedField< $type$ >&\n"
+ "$classname$::_internal_$name$() const {\n"
+ " return $name$_;\n"
+ "}\n"
+ "inline const ::$proto_ns$::RepeatedField< $type$ >&\n"
+ "$classname$::$name$() const {\n"
+ "$annotate_list$"
+ " // @@protoc_insertion_point(field_list:$full_name$)\n"
+ " return _internal_$name$();\n"
+ "}\n"
+ "inline ::$proto_ns$::RepeatedField< $type$ >*\n"
+ "$classname$::_internal_mutable_$name$() {\n"
+ " return &$name$_;\n"
+ "}\n"
+ "inline ::$proto_ns$::RepeatedField< $type$ >*\n"
+ "$classname$::mutable_$name$() {\n"
+ "$annotate_mutable_list$"
+ " // @@protoc_insertion_point(field_mutable_list:$full_name$)\n"
+ " return _internal_mutable_$name$();\n"
+ "}\n");
+}
+
+void RepeatedPrimitiveFieldGenerator::GenerateClearingCode(
+ io::Printer* printer) const {
+ Formatter format(printer, variables_);
+ format("$name$_.Clear();\n");
+}
+
+void RepeatedPrimitiveFieldGenerator::GenerateMergingCode(
+ io::Printer* printer) const {
+ Formatter format(printer, variables_);
+ format("$name$_.MergeFrom(from.$name$_);\n");
+}
+
+void RepeatedPrimitiveFieldGenerator::GenerateSwappingCode(
+ io::Printer* printer) const {
+ Formatter format(printer, variables_);
+ format("$name$_.InternalSwap(&other->$name$_);\n");
+}
+
+void RepeatedPrimitiveFieldGenerator::GenerateConstructorCode(
+ io::Printer* printer) const {
+ // Not needed for repeated fields.
+}
+
+void RepeatedPrimitiveFieldGenerator::GenerateCopyConstructorCode(
+ io::Printer* printer) const {
+ Formatter format(printer, variables_);
+ format("$name$_.CopyFrom(from.$name$_);\n");
+}
+
+void RepeatedPrimitiveFieldGenerator::GenerateSerializeWithCachedSizesToArray(
+ io::Printer* printer) const {
+ Formatter format(printer, variables_);
+ if (descriptor_->is_packed()) {
+ if (FixedSize(descriptor_->type()) == -1) {
+ format(
+ "{\n"
+ " int byte_size = "
+ "_$name$_cached_byte_size_.load(std::memory_order_relaxed);\n"
+ " if (byte_size > 0) {\n"
+ " target = stream->Write$declared_type$Packed(\n"
+ " $number$, _internal_$name$(), byte_size, target);\n"
+ " }\n"
+ "}\n");
+ } else {
+ format(
+ "if (this->_internal_$name$_size() > 0) {\n"
+ " target = stream->WriteFixedPacked($number$, _internal_$name$(), "
+ "target);\n"
+ "}\n");
+ }
+ } else {
+ format(
+ "for (int i = 0, n = this->_internal_$name$_size(); i < n; i++) {\n"
+ " target = stream->EnsureSpace(target);\n"
+ " target = ::$proto_ns$::internal::WireFormatLite::"
+ "Write$declared_type$ToArray($number$, this->_internal_$name$(i), "
+ "target);\n"
+ "}\n");
+ }
+}
+
+void RepeatedPrimitiveFieldGenerator::GenerateByteSize(
+ io::Printer* printer) const {
+ Formatter format(printer, variables_);
+ format("{\n");
+ format.Indent();
+ int fixed_size = FixedSize(descriptor_->type());
+ if (fixed_size == -1) {
+ format(
+ "size_t data_size = ::$proto_ns$::internal::WireFormatLite::\n"
+ " $declared_type$Size(this->$name$_);\n");
+ } else {
+ format(
+ "unsigned int count = static_cast<unsigned "
+ "int>(this->_internal_$name$_size());\n"
+ "size_t data_size = $fixed_size$UL * count;\n");
+ }
+
+ if (descriptor_->is_packed()) {
+ format(
+ "if (data_size > 0) {\n"
+ " total_size += $tag_size$ +\n"
+ " ::$proto_ns$::internal::WireFormatLite::Int32Size(\n"
+ " static_cast<$int32$>(data_size));\n"
+ "}\n");
+ if (FixedSize(descriptor_->type()) == -1) {
+ format(
+ "int cached_size = ::$proto_ns$::internal::ToCachedSize(data_size);\n"
+ "_$name$_cached_byte_size_.store(cached_size,\n"
+ " std::memory_order_relaxed);\n");
+ }
+ format("total_size += data_size;\n");
+ } else {
+ format(
+ "total_size += $tag_size$ *\n"
+ " "
+ "::$proto_ns$::internal::FromIntSize(this->_internal_$name$_size());\n"
+ "total_size += data_size;\n");
+ }
+ format.Outdent();
+ format("}\n");
+}
+
+void RepeatedPrimitiveFieldGenerator::GenerateConstinitInitializer(
+ io::Printer* printer) const {
+ Formatter format(printer, variables_);
+ format("$name$_()");
+ if (descriptor_->is_packed() && FixedSize(descriptor_->type()) == -1 &&
+ HasGeneratedMethods(descriptor_->file(), options_)) {
+ format("\n, _$name$_cached_byte_size_(0)");
+ }
+}
+
+} // namespace cpp
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_primitive_field.h b/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_primitive_field.h
new file mode 100644
index 00000000..28f18ce0
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_primitive_field.h
@@ -0,0 +1,116 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_PRIMITIVE_FIELD_H__
+#define GOOGLE_PROTOBUF_COMPILER_CPP_PRIMITIVE_FIELD_H__
+
+#include <map>
+#include <string>
+#include <compiler/cpp/cpp_field.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+class PrimitiveFieldGenerator : public FieldGenerator {
+ public:
+ PrimitiveFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options);
+ ~PrimitiveFieldGenerator();
+
+ // implements FieldGenerator ---------------------------------------
+ void GeneratePrivateMembers(io::Printer* printer) const override;
+ void GenerateAccessorDeclarations(io::Printer* printer) const override;
+ void GenerateInlineAccessorDefinitions(io::Printer* printer) const override;
+ void GenerateClearingCode(io::Printer* printer) const override;
+ void GenerateMergingCode(io::Printer* printer) const override;
+ void GenerateSwappingCode(io::Printer* printer) const override;
+ void GenerateConstructorCode(io::Printer* printer) const override;
+ void GenerateCopyConstructorCode(io::Printer* printer) const override;
+ void GenerateSerializeWithCachedSizesToArray(
+ io::Printer* printer) const override;
+ void GenerateByteSize(io::Printer* printer) const override;
+ void GenerateConstinitInitializer(io::Printer* printer) const override;
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(PrimitiveFieldGenerator);
+};
+
+class PrimitiveOneofFieldGenerator : public PrimitiveFieldGenerator {
+ public:
+ PrimitiveOneofFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options);
+ ~PrimitiveOneofFieldGenerator();
+
+ // implements FieldGenerator ---------------------------------------
+ void GenerateInlineAccessorDefinitions(io::Printer* printer) const override;
+ void GenerateClearingCode(io::Printer* printer) const override;
+ void GenerateSwappingCode(io::Printer* printer) const override;
+ void GenerateConstructorCode(io::Printer* printer) const override;
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(PrimitiveOneofFieldGenerator);
+};
+
+class RepeatedPrimitiveFieldGenerator : public FieldGenerator {
+ public:
+ RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options);
+ ~RepeatedPrimitiveFieldGenerator();
+
+ // implements FieldGenerator ---------------------------------------
+ void GeneratePrivateMembers(io::Printer* printer) const override;
+ void GenerateAccessorDeclarations(io::Printer* printer) const override;
+ void GenerateInlineAccessorDefinitions(io::Printer* printer) const override;
+ void GenerateClearingCode(io::Printer* printer) const override;
+ void GenerateMergingCode(io::Printer* printer) const override;
+ void GenerateSwappingCode(io::Printer* printer) const override;
+ void GenerateConstructorCode(io::Printer* printer) const override;
+ void GenerateCopyConstructorCode(io::Printer* printer) const override;
+ void GenerateSerializeWithCachedSizesToArray(
+ io::Printer* printer) const override;
+ void GenerateByteSize(io::Printer* printer) const override;
+ void GenerateConstinitInitializer(io::Printer* printer) const override;
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedPrimitiveFieldGenerator);
+};
+
+} // namespace cpp
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_COMPILER_CPP_PRIMITIVE_FIELD_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_service.cc b/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_service.cc
new file mode 100644
index 00000000..807a4cd9
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_service.cc
@@ -0,0 +1,327 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <compiler/cpp/cpp_service.h>
+#include <compiler/cpp/cpp_helpers.h>
+#include <io/printer.h>
+#include <stubs/strutil.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+namespace {
+
+void InitMethodVariables(const MethodDescriptor* method, const Options& options,
+ Formatter* format) {
+ format->Set("name", method->name());
+ format->Set("input_type", QualifiedClassName(method->input_type(), options));
+ format->Set("output_type",
+ QualifiedClassName(method->output_type(), options));
+}
+
+} // namespace
+
+ServiceGenerator::ServiceGenerator(
+ const ServiceDescriptor* descriptor,
+ const std::map<std::string, std::string>& vars, const Options& options)
+ : descriptor_(descriptor), vars_(vars), options_(options) {
+ vars_["classname"] = descriptor_->name();
+ vars_["full_name"] = descriptor_->full_name();
+}
+
+ServiceGenerator::~ServiceGenerator() {}
+
+void ServiceGenerator::GenerateDeclarations(io::Printer* printer) {
+ Formatter format(printer, vars_);
+ // Forward-declare the stub type.
+ format(
+ "class $classname$_Stub;\n"
+ "\n");
+
+ GenerateInterface(printer);
+ GenerateStubDefinition(printer);
+}
+
+void ServiceGenerator::GenerateInterface(io::Printer* printer) {
+ Formatter format(printer, vars_);
+ format(
+ "class $dllexport_decl $$classname$ : public ::$proto_ns$::Service {\n"
+ " protected:\n"
+ " // This class should be treated as an abstract interface.\n"
+ " inline $classname$() {};\n"
+ " public:\n"
+ " virtual ~$classname$();\n");
+ printer->Indent();
+
+ format(
+ "\n"
+ "typedef $classname$_Stub Stub;\n"
+ "\n"
+ "static const ::$proto_ns$::ServiceDescriptor* descriptor();\n"
+ "\n");
+
+ GenerateMethodSignatures(VIRTUAL, printer);
+
+ format(
+ "\n"
+ "// implements Service ----------------------------------------------\n"
+ "\n"
+ "const ::$proto_ns$::ServiceDescriptor* GetDescriptor();\n"
+ "void CallMethod(const ::$proto_ns$::MethodDescriptor* method,\n"
+ " ::$proto_ns$::RpcController* controller,\n"
+ " const ::$proto_ns$::Message* request,\n"
+ " ::$proto_ns$::Message* response,\n"
+ " ::google::protobuf::Closure* done);\n"
+ "const ::$proto_ns$::Message& GetRequestPrototype(\n"
+ " const ::$proto_ns$::MethodDescriptor* method) const;\n"
+ "const ::$proto_ns$::Message& GetResponsePrototype(\n"
+ " const ::$proto_ns$::MethodDescriptor* method) const;\n");
+
+ printer->Outdent();
+ format(
+ "\n"
+ " private:\n"
+ " GOOGLE_DISALLOW_EVIL_CONSTRUCTORS($classname$);\n"
+ "};\n"
+ "\n");
+}
+
+void ServiceGenerator::GenerateStubDefinition(io::Printer* printer) {
+ Formatter format(printer, vars_);
+ format(
+ "class $dllexport_decl $$classname$_Stub : public $classname$ {\n"
+ " public:\n");
+
+ printer->Indent();
+
+ format(
+ "$classname$_Stub(::$proto_ns$::RpcChannel* channel);\n"
+ "$classname$_Stub(::$proto_ns$::RpcChannel* channel,\n"
+ " ::$proto_ns$::Service::ChannelOwnership ownership);\n"
+ "~$classname$_Stub();\n"
+ "\n"
+ "inline ::$proto_ns$::RpcChannel* channel() { return channel_; }\n"
+ "\n"
+ "// implements $classname$ ------------------------------------------\n"
+ "\n");
+
+ GenerateMethodSignatures(NON_VIRTUAL, printer);
+
+ printer->Outdent();
+ format(
+ " private:\n"
+ " ::$proto_ns$::RpcChannel* channel_;\n"
+ " bool owns_channel_;\n"
+ " GOOGLE_DISALLOW_EVIL_CONSTRUCTORS($classname$_Stub);\n"
+ "};\n"
+ "\n");
+}
+
+void ServiceGenerator::GenerateMethodSignatures(VirtualOrNon virtual_or_non,
+ io::Printer* printer) {
+ for (int i = 0; i < descriptor_->method_count(); i++) {
+ const MethodDescriptor* method = descriptor_->method(i);
+ Formatter format(printer, vars_);
+ InitMethodVariables(method, options_, &format);
+ format.Set("virtual", virtual_or_non == VIRTUAL ? "virtual " : "");
+ format(
+ "$virtual$void $name$(::$proto_ns$::RpcController* controller,\n"
+ " const $input_type$* request,\n"
+ " $output_type$* response,\n"
+ " ::google::protobuf::Closure* done);\n");
+ }
+}
+
+// ===================================================================
+
+void ServiceGenerator::GenerateImplementation(io::Printer* printer) {
+ Formatter format(printer, vars_);
+ format(
+ "$classname$::~$classname$() {}\n"
+ "\n"
+ "const ::$proto_ns$::ServiceDescriptor* $classname$::descriptor() {\n"
+ " "
+ "::$proto_ns$::internal::AssignDescriptors(&$desc_table$);\n"
+ " return $file_level_service_descriptors$[$1$];\n"
+ "}\n"
+ "\n"
+ "const ::$proto_ns$::ServiceDescriptor* $classname$::GetDescriptor() {\n"
+ " return descriptor();\n"
+ "}\n"
+ "\n",
+ index_in_metadata_);
+
+ // Generate methods of the interface.
+ GenerateNotImplementedMethods(printer);
+ GenerateCallMethod(printer);
+ GenerateGetPrototype(REQUEST, printer);
+ GenerateGetPrototype(RESPONSE, printer);
+
+ // Generate stub implementation.
+ format(
+ "$classname$_Stub::$classname$_Stub(::$proto_ns$::RpcChannel* channel)\n"
+ " : channel_(channel), owns_channel_(false) {}\n"
+ "$classname$_Stub::$classname$_Stub(\n"
+ " ::$proto_ns$::RpcChannel* channel,\n"
+ " ::$proto_ns$::Service::ChannelOwnership ownership)\n"
+ " : channel_(channel),\n"
+ " owns_channel_(ownership == "
+ "::$proto_ns$::Service::STUB_OWNS_CHANNEL) "
+ "{}\n"
+ "$classname$_Stub::~$classname$_Stub() {\n"
+ " if (owns_channel_) delete channel_;\n"
+ "}\n"
+ "\n");
+
+ GenerateStubMethods(printer);
+}
+
+void ServiceGenerator::GenerateNotImplementedMethods(io::Printer* printer) {
+ for (int i = 0; i < descriptor_->method_count(); i++) {
+ const MethodDescriptor* method = descriptor_->method(i);
+ Formatter format(printer, vars_);
+ InitMethodVariables(method, options_, &format);
+ format(
+ "void $classname$::$name$(::$proto_ns$::RpcController* controller,\n"
+ " const $input_type$*,\n"
+ " $output_type$*,\n"
+ " ::google::protobuf::Closure* done) {\n"
+ " controller->SetFailed(\"Method $name$() not implemented.\");\n"
+ " done->Run();\n"
+ "}\n"
+ "\n");
+ }
+}
+
+void ServiceGenerator::GenerateCallMethod(io::Printer* printer) {
+ Formatter format(printer, vars_);
+ format(
+ "void $classname$::CallMethod(const ::$proto_ns$::MethodDescriptor* "
+ "method,\n"
+ " ::$proto_ns$::RpcController* controller,\n"
+ " const ::$proto_ns$::Message* request,\n"
+ " ::$proto_ns$::Message* response,\n"
+ " ::google::protobuf::Closure* done) {\n"
+ " GOOGLE_DCHECK_EQ(method->service(), $file_level_service_descriptors$[$1$]);\n"
+ " switch(method->index()) {\n",
+ index_in_metadata_);
+
+ for (int i = 0; i < descriptor_->method_count(); i++) {
+ const MethodDescriptor* method = descriptor_->method(i);
+ Formatter format_method(printer, vars_);
+ InitMethodVariables(method, options_, &format_method);
+
+ // Note: down_cast does not work here because it only works on pointers,
+ // not references.
+ format_method(
+ " case $1$:\n"
+ " $name$(controller,\n"
+ " ::$proto_ns$::internal::DownCast<const $input_type$*>(\n"
+ " request),\n"
+ " ::$proto_ns$::internal::DownCast<$output_type$*>(\n"
+ " response),\n"
+ " done);\n"
+ " break;\n",
+ i);
+ }
+
+ format(
+ " default:\n"
+ " GOOGLE_LOG(FATAL) << \"Bad method index; this should never happen.\";\n"
+ " break;\n"
+ " }\n"
+ "}\n"
+ "\n");
+}
+
+void ServiceGenerator::GenerateGetPrototype(RequestOrResponse which,
+ io::Printer* printer) {
+ Formatter format(printer, vars_);
+ if (which == REQUEST) {
+ format("const ::$proto_ns$::Message& $classname$::GetRequestPrototype(\n");
+ } else {
+ format("const ::$proto_ns$::Message& $classname$::GetResponsePrototype(\n");
+ }
+
+ format(
+ " const ::$proto_ns$::MethodDescriptor* method) const {\n"
+ " GOOGLE_DCHECK_EQ(method->service(), descriptor());\n"
+ " switch(method->index()) {\n");
+
+ for (int i = 0; i < descriptor_->method_count(); i++) {
+ const MethodDescriptor* method = descriptor_->method(i);
+ const Descriptor* type =
+ (which == REQUEST) ? method->input_type() : method->output_type();
+
+ format(
+ " case $1$:\n"
+ " return $2$::default_instance();\n",
+ i, QualifiedClassName(type, options_));
+ }
+
+ format(
+ " default:\n"
+ " GOOGLE_LOG(FATAL) << \"Bad method index; this should never happen.\";\n"
+ " return *::$proto_ns$::MessageFactory::generated_factory()\n"
+ " ->GetPrototype(method->$1$_type());\n"
+ " }\n"
+ "}\n"
+ "\n",
+ which == REQUEST ? "input" : "output");
+}
+
+void ServiceGenerator::GenerateStubMethods(io::Printer* printer) {
+ for (int i = 0; i < descriptor_->method_count(); i++) {
+ const MethodDescriptor* method = descriptor_->method(i);
+ Formatter format(printer, vars_);
+ InitMethodVariables(method, options_, &format);
+ format(
+ "void $classname$_Stub::$name$(::$proto_ns$::RpcController* "
+ "controller,\n"
+ " const $input_type$* request,\n"
+ " $output_type$* response,\n"
+ " ::google::protobuf::Closure* done) {\n"
+ " channel_->CallMethod(descriptor()->method($1$),\n"
+ " controller, request, response, done);\n"
+ "}\n",
+ i);
+ }
+}
+
+} // namespace cpp
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_service.h b/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_service.h
new file mode 100644
index 00000000..7d1a1880
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_service.h
@@ -0,0 +1,122 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 GOOGLE_PROTOBUF_COMPILER_CPP_SERVICE_H__
+#define GOOGLE_PROTOBUF_COMPILER_CPP_SERVICE_H__
+
+#include <map>
+#include <string>
+#include <compiler/cpp/cpp_options.h>
+#include <descriptor.h>
+
+namespace google {
+namespace protobuf {
+namespace io {
+class Printer; // printer.h
+}
+} // namespace protobuf
+} // namespace google
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+class ServiceGenerator {
+ public:
+ // See generator.cc for the meaning of dllexport_decl.
+ explicit ServiceGenerator(const ServiceDescriptor* descriptor,
+ const std::map<std::string, std::string>& vars,
+ const Options& options);
+ ~ServiceGenerator();
+
+ // Header stuff.
+
+ // Generate the class definitions for the service's interface and the
+ // stub implementation.
+ void GenerateDeclarations(io::Printer* printer);
+
+ // Source file stuff.
+
+ // Generate implementations of everything declared by
+ // GenerateDeclarations().
+ void GenerateImplementation(io::Printer* printer);
+
+ private:
+ enum RequestOrResponse { REQUEST, RESPONSE };
+ enum VirtualOrNon { VIRTUAL, NON_VIRTUAL };
+
+ // Header stuff.
+
+ // Generate the service abstract interface.
+ void GenerateInterface(io::Printer* printer);
+
+ // Generate the stub class definition.
+ void GenerateStubDefinition(io::Printer* printer);
+
+ // Prints signatures for all methods in the
+ void GenerateMethodSignatures(VirtualOrNon virtual_or_non,
+ io::Printer* printer);
+
+ // Source file stuff.
+
+ // Generate the default implementations of the service methods, which
+ // produce a "not implemented" error.
+ void GenerateNotImplementedMethods(io::Printer* printer);
+
+ // Generate the CallMethod() method of the service.
+ void GenerateCallMethod(io::Printer* printer);
+
+ // Generate the Get{Request,Response}Prototype() methods.
+ void GenerateGetPrototype(RequestOrResponse which, io::Printer* printer);
+
+ // Generate the stub's implementations of the service methods.
+ void GenerateStubMethods(io::Printer* printer);
+
+ const ServiceDescriptor* descriptor_;
+ std::map<std::string, std::string> vars_;
+ const Options& options_;
+
+ int index_in_metadata_;
+
+ friend class FileGenerator;
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ServiceGenerator);
+};
+
+} // namespace cpp
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_COMPILER_CPP_SERVICE_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_string_field.cc b/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_string_field.cc
new file mode 100644
index 00000000..0faa2eea
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_string_field.cc
@@ -0,0 +1,915 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 <compiler/cpp/cpp_string_field.h>
+#include <compiler/cpp/cpp_helpers.h>
+#include <descriptor.pb.h>
+#include <io/printer.h>
+#include <stubs/strutil.h>
+
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+namespace {
+
+void SetStringVariables(const FieldDescriptor* descriptor,
+ std::map<std::string, std::string>* variables,
+ const Options& options) {
+ SetCommonFieldVariables(descriptor, variables, options);
+ (*variables)["default"] = DefaultValue(options, descriptor);
+ (*variables)["default_length"] =
+ StrCat(descriptor->default_value_string().length());
+ std::string default_variable_string = MakeDefaultName(descriptor);
+ (*variables)["default_variable_name"] = default_variable_string;
+
+ if (!descriptor->default_value_string().empty()) {
+ (*variables)["lazy_variable"] =
+ QualifiedClassName(descriptor->containing_type(), options) +
+ "::" + default_variable_string;
+ }
+
+ (*variables)["default_string"] =
+ descriptor->default_value_string().empty()
+ ? "::" + (*variables)["proto_ns"] +
+ "::internal::GetEmptyStringAlreadyInited()"
+ : (*variables)["lazy_variable"] + ".get()";
+ (*variables)["init_value"] =
+ descriptor->default_value_string().empty()
+ ? "&::" + (*variables)["proto_ns"] +
+ "::internal::GetEmptyStringAlreadyInited()"
+ : "nullptr";
+ (*variables)["default_value_tag"] =
+ "::" + (*variables)["proto_ns"] + "::internal::ArenaStringPtr::" +
+ (descriptor->default_value_string().empty() ? "Empty" : "NonEmpty") +
+ "Default{}";
+ (*variables)["default_variable_or_tag"] =
+ (*variables)[descriptor->default_value_string().empty()
+ ? "default_value_tag"
+ : "lazy_variable"];
+ (*variables)["pointer_type"] =
+ descriptor->type() == FieldDescriptor::TYPE_BYTES ? "void" : "char";
+ (*variables)["setter"] =
+ descriptor->type() == FieldDescriptor::TYPE_BYTES ? "SetBytes" : "Set";
+ (*variables)["null_check"] = (*variables)["DCHK"] + "(value != nullptr);\n";
+ // NOTE: Escaped here to unblock proto1->proto2 migration.
+ // TODO(liujisi): Extend this to apply for other conflicting methods.
+ (*variables)["release_name"] =
+ SafeFunctionName(descriptor->containing_type(), descriptor, "release_");
+ (*variables)["full_name"] = descriptor->full_name();
+
+ if (options.opensource_runtime) {
+ (*variables)["string_piece"] = "::std::string";
+ } else {
+ (*variables)["string_piece"] = "::StringPiece";
+ }
+}
+
+} // namespace
+
+// ===================================================================
+
+StringFieldGenerator::StringFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options)
+ : FieldGenerator(descriptor, options),
+ inlined_(IsStringInlined(descriptor, options)) {
+ SetStringVariables(descriptor, &variables_, options);
+}
+
+StringFieldGenerator::~StringFieldGenerator() {}
+
+void StringFieldGenerator::GeneratePrivateMembers(io::Printer* printer) const {
+ Formatter format(printer, variables_);
+ if (!inlined_) {
+ format("::$proto_ns$::internal::ArenaStringPtr $name$_;\n");
+ } else {
+ // `_init_inline_xxx` is used for initializing default instances.
+ format(
+ "::$proto_ns$::internal::InlinedStringField $name$_;\n"
+ "static std::true_type _init_inline_$name$_;\n");
+ }
+}
+
+void StringFieldGenerator::GenerateStaticMembers(io::Printer* printer) const {
+ Formatter format(printer, variables_);
+ if (!descriptor_->default_value_string().empty()) {
+ format(
+ "static const ::$proto_ns$::internal::LazyString"
+ " $default_variable_name$;\n");
+ }
+}
+
+void StringFieldGenerator::GenerateAccessorDeclarations(
+ io::Printer* printer) const {
+ Formatter format(printer, variables_);
+ // If we're using StringFieldGenerator for a field with a ctype, it's
+ // because that ctype isn't actually implemented. In particular, this is
+ // true of ctype=CORD and ctype=STRING_PIECE in the open source release.
+ // We aren't releasing Cord because it has too many Google-specific
+ // dependencies and we aren't releasing StringPiece because it's hardly
+ // useful outside of Google and because it would get confusing to have
+ // multiple instances of the StringPiece class in different libraries (PCRE
+ // already includes it for their C++ bindings, which came from Google).
+ //
+ // In any case, we make all the accessors private while still actually
+ // using a string to represent the field internally. This way, we can
+ // guarantee that if we do ever implement the ctype, it won't break any
+ // existing users who might be -- for whatever reason -- already using .proto
+ // files that applied the ctype. The field can still be accessed via the
+ // reflection interface since the reflection interface is independent of
+ // the string's underlying representation.
+
+ bool unknown_ctype = descriptor_->options().ctype() !=
+ EffectiveStringCType(descriptor_, options_);
+
+ if (unknown_ctype) {
+ format.Outdent();
+ format(
+ " private:\n"
+ " // Hidden due to unknown ctype option.\n");
+ format.Indent();
+ }
+
+ format(
+ "$deprecated_attr$const std::string& ${1$$name$$}$() const;\n"
+ "template <typename ArgT0 = const std::string&, typename... ArgT>\n"
+ "$deprecated_attr$void ${1$set_$name$$}$(ArgT0&& arg0, ArgT... args);\n",
+ descriptor_);
+ format(
+ "$deprecated_attr$std::string* ${1$mutable_$name$$}$();\n"
+ "PROTOBUF_NODISCARD $deprecated_attr$std::string* "
+ "${1$$release_name$$}$();\n"
+ "$deprecated_attr$void ${1$set_allocated_$name$$}$(std::string* "
+ "$name$);\n",
+ descriptor_);
+ format(
+ "private:\n"
+ "const std::string& _internal_$name$() const;\n"
+ "inline PROTOBUF_ALWAYS_INLINE void "
+ "_internal_set_$name$(const std::string& value);\n"
+ "std::string* _internal_mutable_$name$();\n");
+ if (inlined_) {
+ format(
+ "inline PROTOBUF_ALWAYS_INLINE bool _internal_$name$_donated() "
+ "const;\n");
+ }
+ format("public:\n");
+
+ if (unknown_ctype) {
+ format.Outdent();
+ format(" public:\n");
+ format.Indent();
+ }
+}
+
+void StringFieldGenerator::GenerateInlineAccessorDefinitions(
+ io::Printer* printer) const {
+ Formatter format(printer, variables_);
+ format(
+ "inline const std::string& $classname$::$name$() const {\n"
+ "$annotate_get$"
+ " // @@protoc_insertion_point(field_get:$full_name$)\n");
+ if (!descriptor_->default_value_string().empty()) {
+ format(
+ " if ($name$_.IsDefault(nullptr)) return "
+ "$default_variable_name$.get();\n");
+ }
+ format(
+ " return _internal_$name$();\n"
+ "}\n");
+ if (!inlined_) {
+ format(
+ "template <typename ArgT0, typename... ArgT>\n"
+ "inline PROTOBUF_ALWAYS_INLINE\n"
+ "void $classname$::set_$name$(ArgT0&& arg0, ArgT... args) {\n"
+ " $set_hasbit$\n"
+ " $name$_.$setter$($default_value_tag$, static_cast<ArgT0 &&>(arg0),"
+ " args..., GetArenaForAllocation());\n"
+ "$annotate_set$"
+ " // @@protoc_insertion_point(field_set:$full_name$)\n"
+ "}\n");
+ } else {
+ format(
+ "template <typename ArgT0, typename... ArgT>\n"
+ "inline PROTOBUF_ALWAYS_INLINE\n"
+ "void $classname$::set_$name$(ArgT0&& arg0, ArgT... args) {\n"
+ " $set_hasbit$\n"
+ " $name$_.$setter$(nullptr, static_cast<ArgT0 &&>(arg0),"
+ " args..., GetArenaForAllocation(), _internal_$name$_donated(), "
+ "&$donating_states_word$, $mask_for_undonate$);\n"
+ "$annotate_set$"
+ " // @@protoc_insertion_point(field_set:$full_name$)\n"
+ "}\n"
+ "inline bool $classname$::_internal_$name$_donated() const {\n"
+ " bool value = $inlined_string_donated$\n"
+ " return value;\n"
+ "}\n");
+ }
+ format(
+ "inline std::string* $classname$::mutable_$name$() {\n"
+ " std::string* _s = _internal_mutable_$name$();\n"
+ "$annotate_mutable$"
+ " // @@protoc_insertion_point(field_mutable:$full_name$)\n"
+ " return _s;\n"
+ "}\n"
+ "inline const std::string& $classname$::_internal_$name$() const {\n"
+ " return $name$_.Get();\n"
+ "}\n"
+ "inline void $classname$::_internal_set_$name$(const std::string& "
+ "value) {\n"
+ " $set_hasbit$\n");
+ if (!inlined_) {
+ format(
+ " $name$_.Set($default_value_tag$, value, GetArenaForAllocation());\n"
+ "}\n");
+ } else {
+ format(
+ " $name$_.Set(nullptr, value, GetArenaForAllocation(),\n"
+ " _internal_$name$_donated(), &$donating_states_word$, "
+ "$mask_for_undonate$);\n"
+ "}\n");
+ }
+ format(
+ "inline std::string* $classname$::_internal_mutable_$name$() {\n"
+ " $set_hasbit$\n");
+ if (!inlined_) {
+ format(
+ " return $name$_.Mutable($default_variable_or_tag$, "
+ "GetArenaForAllocation());\n"
+ "}\n");
+ } else {
+ format(
+ " return $name$_.Mutable($default_variable_or_tag$, "
+ "GetArenaForAllocation(), _internal_$name$_donated(), "
+ "&$donating_states_word$, $mask_for_undonate$);\n"
+ "}\n");
+ }
+ format(
+ "inline std::string* $classname$::$release_name$() {\n"
+ "$annotate_release$"
+ " // @@protoc_insertion_point(field_release:$full_name$)\n");
+
+ if (HasHasbit(descriptor_)) {
+ format(
+ " if (!_internal_has_$name$()) {\n"
+ " return nullptr;\n"
+ " }\n"
+ " $clear_hasbit$\n");
+ if (!inlined_) {
+ format(
+ " auto* p = $name$_.ReleaseNonDefault($init_value$, "
+ "GetArenaForAllocation());\n");
+ if (descriptor_->default_value_string().empty()) {
+ format(
+ "#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING\n"
+ " if ($name$_.IsDefault($init_value$)) {\n"
+ " $name$_.Set($init_value$, \"\", GetArenaForAllocation());\n"
+ " }\n"
+ "#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING\n");
+ }
+ format(" return p;\n");
+ } else {
+ format(
+ " return $name$_.Release(nullptr, GetArenaForAllocation(), "
+ "_internal_$name$_donated());\n");
+ }
+ } else {
+ format(
+ " return $name$_.Release($init_value$, GetArenaForAllocation());\n");
+ }
+
+ format(
+ "}\n"
+ "inline void $classname$::set_allocated_$name$(std::string* $name$) {\n"
+ " if ($name$ != nullptr) {\n"
+ " $set_hasbit$\n"
+ " } else {\n"
+ " $clear_hasbit$\n"
+ " }\n");
+ if (!inlined_) {
+ format(
+ " $name$_.SetAllocated($init_value$, $name$,\n"
+ " GetArenaForAllocation());\n");
+ if (descriptor_->default_value_string().empty()) {
+ format(
+ "#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING\n"
+ " if ($name$_.IsDefault($init_value$)) {\n"
+ " $name$_.Set($init_value$, \"\", GetArenaForAllocation());\n"
+ " }\n"
+ "#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING\n");
+ }
+ } else {
+ // Currently, string fields with default value can't be inlined.
+ format(
+ " $name$_.SetAllocated(nullptr, $name$, GetArenaForAllocation(), "
+ "_internal_$name$_donated(), &$donating_states_word$, "
+ "$mask_for_undonate$);\n");
+ }
+ format(
+ "$annotate_set$"
+ " // @@protoc_insertion_point(field_set_allocated:$full_name$)\n"
+ "}\n");
+}
+
+void StringFieldGenerator::GenerateNonInlineAccessorDefinitions(
+ io::Printer* printer) const {
+ Formatter format(printer, variables_);
+ if (!descriptor_->default_value_string().empty()) {
+ format(
+ "const ::$proto_ns$::internal::LazyString "
+ "$classname$::$default_variable_name$"
+ "{{{$default$, $default_length$}}, {nullptr}};\n");
+ }
+}
+
+void StringFieldGenerator::GenerateClearingCode(io::Printer* printer) const {
+ Formatter format(printer, variables_);
+ if (descriptor_->default_value_string().empty()) {
+ format("$name$_.ClearToEmpty();\n");
+ } else {
+ GOOGLE_DCHECK(!inlined_);
+ format(
+ "$name$_.ClearToDefault($lazy_variable$, GetArenaForAllocation());\n");
+ }
+}
+
+void StringFieldGenerator::GenerateMessageClearingCode(
+ io::Printer* printer) const {
+ Formatter format(printer, variables_);
+ // Two-dimension specialization here: supporting arenas, field presence, or
+ // not, and default value is the empty string or not. Complexity here ensures
+ // the minimal number of branches / amount of extraneous code at runtime
+ // (given that the below methods are inlined one-liners)!
+
+ // If we have a hasbit, then the Clear() method of the protocol buffer
+ // will have checked that this field is set. If so, we can avoid redundant
+ // checks against the default variable.
+ const bool must_be_present = HasHasbit(descriptor_);
+
+ if (inlined_ && must_be_present) {
+ // Calling mutable_$name$() gives us a string reference and sets the has bit
+ // for $name$ (in proto2). We may get here when the string field is inlined
+ // but the string's contents have not been changed by the user, so we cannot
+ // make an assertion about the contents of the string and could never make
+ // an assertion about the string instance.
+ //
+ // For non-inlined strings, we distinguish from non-default by comparing
+ // instances, rather than contents.
+ format("$DCHK$(!$name$_.IsDefault(nullptr));\n");
+ }
+
+ if (descriptor_->default_value_string().empty()) {
+ if (must_be_present) {
+ format("$name$_.ClearNonDefaultToEmpty();\n");
+ } else {
+ format("$name$_.ClearToEmpty();\n");
+ }
+ } else {
+ // Clear to a non-empty default is more involved, as we try to use the
+ // Arena if one is present and may need to reallocate the string.
+ format(
+ "$name$_.ClearToDefault($lazy_variable$, GetArenaForAllocation());\n ");
+ }
+}
+
+void StringFieldGenerator::GenerateMergingCode(io::Printer* printer) const {
+ Formatter format(printer, variables_);
+ // TODO(gpike): improve this
+ format("_internal_set_$name$(from._internal_$name$());\n");
+}
+
+void StringFieldGenerator::GenerateSwappingCode(io::Printer* printer) const {
+ Formatter format(printer, variables_);
+ if (!inlined_) {
+ format(
+ "::$proto_ns$::internal::ArenaStringPtr::InternalSwap(\n"
+ " $init_value$,\n"
+ " &$name$_, lhs_arena,\n"
+ " &other->$name$_, rhs_arena\n"
+ ");\n");
+ } else {
+ // At this point, it's guaranteed that the two fields being swapped are on
+ // the same arena.
+ format(
+ "$name$_.Swap(&other->$name$_, nullptr, GetArenaForAllocation(), "
+ "_internal_$name$_donated(), other->_internal_$name$_donated(), "
+ "&$donating_states_word$, &(other->$donating_states_word$), "
+ "$mask_for_undonate$);\n");
+ }
+}
+
+void StringFieldGenerator::GenerateConstructorCode(io::Printer* printer) const {
+ Formatter format(printer, variables_);
+ if (inlined_ && descriptor_->default_value_string().empty()) {
+ // Automatic initialization will construct the string.
+ return;
+ }
+ GOOGLE_DCHECK(!inlined_);
+ format("$name$_.UnsafeSetDefault($init_value$);\n");
+ if (IsString(descriptor_, options_) &&
+ descriptor_->default_value_string().empty()) {
+ format(
+ "#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING\n"
+ " $name$_.Set($init_value$, \"\", GetArenaForAllocation());\n"
+ "#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING\n");
+ }
+}
+
+void StringFieldGenerator::GenerateCopyConstructorCode(
+ io::Printer* printer) const {
+ Formatter format(printer, variables_);
+ GenerateConstructorCode(printer);
+
+ if (HasHasbit(descriptor_)) {
+ format("if (from._internal_has_$name$()) {\n");
+ } else {
+ format("if (!from._internal_$name$().empty()) {\n");
+ }
+
+ format.Indent();
+
+ if (!inlined_) {
+ format(
+ "$name$_.Set($default_value_tag$, from._internal_$name$(), \n"
+ " GetArenaForAllocation());\n");
+ } else {
+ format(
+ "$name$_.Set(nullptr, from._internal_$name$(),\n"
+ " GetArenaForAllocation(), _internal_$name$_donated(), "
+ "&$donating_states_word$, $mask_for_undonate$);\n");
+ }
+
+ format.Outdent();
+ format("}\n");
+}
+
+void StringFieldGenerator::GenerateDestructorCode(io::Printer* printer) const {
+ Formatter format(printer, variables_);
+ if (inlined_) {
+ // The destructor is automatically invoked.
+ return;
+ }
+
+ format("$name$_.DestroyNoArena($init_value$);\n");
+}
+
+void StringFieldGenerator::GenerateSerializeWithCachedSizesToArray(
+ io::Printer* printer) const {
+ Formatter format(printer, variables_);
+ if (descriptor_->type() == FieldDescriptor::TYPE_STRING) {
+ GenerateUtf8CheckCodeForString(
+ descriptor_, options_, false,
+ "this->_internal_$name$().data(), "
+ "static_cast<int>(this->_internal_$name$().length()),\n",
+ format);
+ }
+ format(
+ "target = stream->Write$declared_type$MaybeAliased(\n"
+ " $number$, this->_internal_$name$(), target);\n");
+}
+
+void StringFieldGenerator::GenerateByteSize(io::Printer* printer) const {
+ Formatter format(printer, variables_);
+ format(
+ "total_size += $tag_size$ +\n"
+ " ::$proto_ns$::internal::WireFormatLite::$declared_type$Size(\n"
+ " this->_internal_$name$());\n");
+}
+
+void StringFieldGenerator::GenerateConstinitInitializer(
+ io::Printer* printer) const {
+ Formatter format(printer, variables_);
+ if (inlined_) {
+ format("$name$_(nullptr, false)");
+ return;
+ }
+ if (descriptor_->default_value_string().empty()) {
+ format("$name$_(&::$proto_ns$::internal::fixed_address_empty_string)");
+ } else {
+ format("$name$_(nullptr)");
+ }
+}
+
+// ===================================================================
+
+StringOneofFieldGenerator::StringOneofFieldGenerator(
+ const FieldDescriptor* descriptor, const Options& options)
+ : StringFieldGenerator(descriptor, options) {
+ SetCommonOneofFieldVariables(descriptor, &variables_);
+ variables_["field_name"] = UnderscoresToCamelCase(descriptor->name(), true);
+ variables_["oneof_index"] =
+ StrCat(descriptor->containing_oneof()->index());
+}
+
+StringOneofFieldGenerator::~StringOneofFieldGenerator() {}
+
+void StringOneofFieldGenerator::GenerateInlineAccessorDefinitions(
+ io::Printer* printer) const {
+ Formatter format(printer, variables_);
+ format(
+ "inline const std::string& $classname$::$name$() const {\n"
+ "$annotate_get$"
+ " // @@protoc_insertion_point(field_get:$full_name$)\n"
+ " return _internal_$name$();\n"
+ "}\n"
+ "template <typename ArgT0, typename... ArgT>\n"
+ "inline void $classname$::set_$name$(ArgT0&& arg0, ArgT... args) {\n"
+ " if (!_internal_has_$name$()) {\n"
+ " clear_$oneof_name$();\n"
+ " set_has_$name$();\n"
+ " $field_member$.UnsafeSetDefault($init_value$);\n"
+ " }\n"
+ " $field_member$.$setter$($default_value_tag$,"
+ " static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());\n"
+ "$annotate_set$"
+ " // @@protoc_insertion_point(field_set:$full_name$)\n"
+ "}\n"
+ "inline std::string* $classname$::mutable_$name$() {\n"
+ " std::string* _s = _internal_mutable_$name$();\n"
+ "$annotate_mutable$"
+ " // @@protoc_insertion_point(field_mutable:$full_name$)\n"
+ " return _s;\n"
+ "}\n"
+ "inline const std::string& $classname$::_internal_$name$() const {\n"
+ " if (_internal_has_$name$()) {\n"
+ " return $field_member$.Get();\n"
+ " }\n"
+ " return $default_string$;\n"
+ "}\n"
+ "inline void $classname$::_internal_set_$name$(const std::string& "
+ "value) {\n"
+ " if (!_internal_has_$name$()) {\n"
+ " clear_$oneof_name$();\n"
+ " set_has_$name$();\n"
+ " $field_member$.UnsafeSetDefault($init_value$);\n"
+ " }\n"
+ " $field_member$.Set($default_value_tag$, value, "
+ "GetArenaForAllocation());\n"
+ "}\n");
+ format(
+ "inline std::string* $classname$::_internal_mutable_$name$() {\n"
+ " if (!_internal_has_$name$()) {\n"
+ " clear_$oneof_name$();\n"
+ " set_has_$name$();\n"
+ " $field_member$.UnsafeSetDefault($init_value$);\n"
+ " }\n"
+ " return $field_member$.Mutable(\n"
+ " $default_variable_or_tag$, GetArenaForAllocation());\n"
+ "}\n"
+ "inline std::string* $classname$::$release_name$() {\n"
+ "$annotate_release$"
+ " // @@protoc_insertion_point(field_release:$full_name$)\n"
+ " if (_internal_has_$name$()) {\n"
+ " clear_has_$oneof_name$();\n"
+ " return $field_member$.ReleaseNonDefault($init_value$, "
+ "GetArenaForAllocation());\n"
+ " } else {\n"
+ " return nullptr;\n"
+ " }\n"
+ "}\n"
+ "inline void $classname$::set_allocated_$name$(std::string* $name$) {\n"
+ " if (has_$oneof_name$()) {\n"
+ " clear_$oneof_name$();\n"
+ " }\n"
+ " if ($name$ != nullptr) {\n"
+ " set_has_$name$();\n"
+ " $field_member$.UnsafeSetDefault($name$);\n"
+ " ::$proto_ns$::Arena* arena = GetArenaForAllocation();\n"
+ " if (arena != nullptr) {\n"
+ " arena->Own($name$);\n"
+ " }\n"
+ " }\n"
+ "$annotate_set$"
+ " // @@protoc_insertion_point(field_set_allocated:$full_name$)\n"
+ "}\n");
+}
+
+void StringOneofFieldGenerator::GenerateClearingCode(
+ io::Printer* printer) const {
+ Formatter format(printer, variables_);
+ format(
+ "$field_member$.Destroy($default_value_tag$, "
+ "GetArenaForAllocation());\n");
+}
+
+void StringOneofFieldGenerator::GenerateMessageClearingCode(
+ io::Printer* printer) const {
+ return GenerateClearingCode(printer);
+}
+
+void StringOneofFieldGenerator::GenerateSwappingCode(
+ io::Printer* printer) const {
+ // Don't print any swapping code. Swapping the union will swap this field.
+}
+
+void StringOneofFieldGenerator::GenerateConstructorCode(
+ io::Printer* printer) const {
+ // Nothing required here.
+}
+
+// ===================================================================
+
+RepeatedStringFieldGenerator::RepeatedStringFieldGenerator(
+ const FieldDescriptor* descriptor, const Options& options)
+ : FieldGenerator(descriptor, options) {
+ SetStringVariables(descriptor, &variables_, options);
+}
+
+RepeatedStringFieldGenerator::~RepeatedStringFieldGenerator() {}
+
+void RepeatedStringFieldGenerator::GeneratePrivateMembers(
+ io::Printer* printer) const {
+ Formatter format(printer, variables_);
+ format("::$proto_ns$::RepeatedPtrField<std::string> $name$_;\n");
+}
+
+void RepeatedStringFieldGenerator::GenerateAccessorDeclarations(
+ io::Printer* printer) const {
+ Formatter format(printer, variables_);
+ // See comment above about unknown ctypes.
+ bool unknown_ctype = descriptor_->options().ctype() !=
+ EffectiveStringCType(descriptor_, options_);
+
+ if (unknown_ctype) {
+ format.Outdent();
+ format(
+ " private:\n"
+ " // Hidden due to unknown ctype option.\n");
+ format.Indent();
+ }
+
+ format(
+ "$deprecated_attr$const std::string& ${1$$name$$}$(int index) const;\n"
+ "$deprecated_attr$std::string* ${1$mutable_$name$$}$(int index);\n"
+ "$deprecated_attr$void ${1$set_$name$$}$(int index, const "
+ "std::string& value);\n"
+ "$deprecated_attr$void ${1$set_$name$$}$(int index, std::string&& "
+ "value);\n"
+ "$deprecated_attr$void ${1$set_$name$$}$(int index, const "
+ "char* value);\n",
+ descriptor_);
+ if (!options_.opensource_runtime) {
+ format(
+ "$deprecated_attr$void ${1$set_$name$$}$(int index, "
+ "StringPiece value);\n",
+ descriptor_);
+ }
+ format(
+ "$deprecated_attr$void ${1$set_$name$$}$("
+ "int index, const $pointer_type$* value, size_t size);\n"
+ "$deprecated_attr$std::string* ${1$add_$name$$}$();\n"
+ "$deprecated_attr$void ${1$add_$name$$}$(const std::string& value);\n"
+ "$deprecated_attr$void ${1$add_$name$$}$(std::string&& value);\n"
+ "$deprecated_attr$void ${1$add_$name$$}$(const char* value);\n",
+ descriptor_);
+ if (!options_.opensource_runtime) {
+ format(
+ "$deprecated_attr$void ${1$add_$name$$}$(StringPiece value);\n",
+ descriptor_);
+ }
+ format(
+ "$deprecated_attr$void ${1$add_$name$$}$(const $pointer_type$* "
+ "value, size_t size)"
+ ";\n"
+ "$deprecated_attr$const ::$proto_ns$::RepeatedPtrField<std::string>& "
+ "${1$$name$$}$() "
+ "const;\n"
+ "$deprecated_attr$::$proto_ns$::RepeatedPtrField<std::string>* "
+ "${1$mutable_$name$$}$()"
+ ";\n"
+ "private:\n"
+ "const std::string& ${1$_internal_$name$$}$(int index) const;\n"
+ "std::string* _internal_add_$name$();\n"
+ "public:\n",
+ descriptor_);
+
+ if (unknown_ctype) {
+ format.Outdent();
+ format(" public:\n");
+ format.Indent();
+ }
+}
+
+void RepeatedStringFieldGenerator::GenerateInlineAccessorDefinitions(
+ io::Printer* printer) const {
+ Formatter format(printer, variables_);
+ format(
+ "inline std::string* $classname$::add_$name$() {\n"
+ " std::string* _s = _internal_add_$name$();\n"
+ "$annotate_add_mutable$"
+ " // @@protoc_insertion_point(field_add_mutable:$full_name$)\n"
+ " return _s;\n"
+ "}\n");
+ if (options_.safe_boundary_check) {
+ format(
+ "inline const std::string& $classname$::_internal_$name$(int index) "
+ "const {\n"
+ " return $name$_.InternalCheckedGet(\n"
+ " index, ::$proto_ns$::internal::GetEmptyStringAlreadyInited());\n"
+ "}\n");
+ } else {
+ format(
+ "inline const std::string& $classname$::_internal_$name$(int index) "
+ "const {\n"
+ " return $name$_.Get(index);\n"
+ "}\n");
+ }
+ format(
+ "inline const std::string& $classname$::$name$(int index) const {\n"
+ "$annotate_get$"
+ " // @@protoc_insertion_point(field_get:$full_name$)\n"
+ " return _internal_$name$(index);\n"
+ "}\n"
+ "inline std::string* $classname$::mutable_$name$(int index) {\n"
+ "$annotate_mutable$"
+ " // @@protoc_insertion_point(field_mutable:$full_name$)\n"
+ " return $name$_.Mutable(index);\n"
+ "}\n"
+ "inline void $classname$::set_$name$(int index, const std::string& "
+ "value) "
+ "{\n"
+ " $name$_.Mutable(index)->assign(value);\n"
+ "$annotate_set$"
+ " // @@protoc_insertion_point(field_set:$full_name$)\n"
+ "}\n"
+ "inline void $classname$::set_$name$(int index, std::string&& value) {\n"
+ " $name$_.Mutable(index)->assign(std::move(value));\n"
+ "$annotate_set$"
+ " // @@protoc_insertion_point(field_set:$full_name$)\n"
+ "}\n"
+ "inline void $classname$::set_$name$(int index, const char* value) {\n"
+ " $null_check$"
+ " $name$_.Mutable(index)->assign(value);\n"
+ "$annotate_set$"
+ " // @@protoc_insertion_point(field_set_char:$full_name$)\n"
+ "}\n");
+ if (!options_.opensource_runtime) {
+ format(
+ "inline void "
+ "$classname$::set_$name$(int index, StringPiece value) {\n"
+ " $name$_.Mutable(index)->assign(value.data(), value.size());\n"
+ "$annotate_set$"
+ " // @@protoc_insertion_point(field_set_string_piece:$full_name$)\n"
+ "}\n");
+ }
+ format(
+ "inline void "
+ "$classname$::set_$name$"
+ "(int index, const $pointer_type$* value, size_t size) {\n"
+ " $name$_.Mutable(index)->assign(\n"
+ " reinterpret_cast<const char*>(value), size);\n"
+ "$annotate_set$"
+ " // @@protoc_insertion_point(field_set_pointer:$full_name$)\n"
+ "}\n"
+ "inline std::string* $classname$::_internal_add_$name$() {\n"
+ " return $name$_.Add();\n"
+ "}\n"
+ "inline void $classname$::add_$name$(const std::string& value) {\n"
+ " $name$_.Add()->assign(value);\n"
+ "$annotate_add$"
+ " // @@protoc_insertion_point(field_add:$full_name$)\n"
+ "}\n"
+ "inline void $classname$::add_$name$(std::string&& value) {\n"
+ " $name$_.Add(std::move(value));\n"
+ "$annotate_add$"
+ " // @@protoc_insertion_point(field_add:$full_name$)\n"
+ "}\n"
+ "inline void $classname$::add_$name$(const char* value) {\n"
+ " $null_check$"
+ " $name$_.Add()->assign(value);\n"
+ "$annotate_add$"
+ " // @@protoc_insertion_point(field_add_char:$full_name$)\n"
+ "}\n");
+ if (!options_.opensource_runtime) {
+ format(
+ "inline void $classname$::add_$name$(StringPiece value) {\n"
+ " $name$_.Add()->assign(value.data(), value.size());\n"
+ "$annotate_add$"
+ " // @@protoc_insertion_point(field_add_string_piece:$full_name$)\n"
+ "}\n");
+ }
+ format(
+ "inline void "
+ "$classname$::add_$name$(const $pointer_type$* value, size_t size) {\n"
+ " $name$_.Add()->assign(reinterpret_cast<const char*>(value), size);\n"
+ "$annotate_add$"
+ " // @@protoc_insertion_point(field_add_pointer:$full_name$)\n"
+ "}\n"
+ "inline const ::$proto_ns$::RepeatedPtrField<std::string>&\n"
+ "$classname$::$name$() const {\n"
+ "$annotate_list$"
+ " // @@protoc_insertion_point(field_list:$full_name$)\n"
+ " return $name$_;\n"
+ "}\n"
+ "inline ::$proto_ns$::RepeatedPtrField<std::string>*\n"
+ "$classname$::mutable_$name$() {\n"
+ "$annotate_mutable_list$"
+ " // @@protoc_insertion_point(field_mutable_list:$full_name$)\n"
+ " return &$name$_;\n"
+ "}\n");
+}
+
+void RepeatedStringFieldGenerator::GenerateClearingCode(
+ io::Printer* printer) const {
+ Formatter format(printer, variables_);
+ format("$name$_.Clear();\n");
+}
+
+void RepeatedStringFieldGenerator::GenerateMergingCode(
+ io::Printer* printer) const {
+ Formatter format(printer, variables_);
+ format("$name$_.MergeFrom(from.$name$_);\n");
+}
+
+void RepeatedStringFieldGenerator::GenerateSwappingCode(
+ io::Printer* printer) const {
+ Formatter format(printer, variables_);
+ format("$name$_.InternalSwap(&other->$name$_);\n");
+}
+
+void RepeatedStringFieldGenerator::GenerateConstructorCode(
+ io::Printer* printer) const {
+ // Not needed for repeated fields.
+}
+
+void RepeatedStringFieldGenerator::GenerateCopyConstructorCode(
+ io::Printer* printer) const {
+ Formatter format(printer, variables_);
+ format("$name$_.CopyFrom(from.$name$_);");
+}
+
+void RepeatedStringFieldGenerator::GenerateSerializeWithCachedSizesToArray(
+ io::Printer* printer) const {
+ Formatter format(printer, variables_);
+ format(
+ "for (int i = 0, n = this->_internal_$name$_size(); i < n; i++) {\n"
+ " const auto& s = this->_internal_$name$(i);\n");
+ // format("for (const std::string& s : this->$name$()) {\n");
+ format.Indent();
+ if (descriptor_->type() == FieldDescriptor::TYPE_STRING) {
+ GenerateUtf8CheckCodeForString(descriptor_, options_, false,
+ "s.data(), static_cast<int>(s.length()),\n",
+ format);
+ }
+ format.Outdent();
+ format(
+ " target = stream->Write$declared_type$($number$, s, target);\n"
+ "}\n");
+}
+
+void RepeatedStringFieldGenerator::GenerateByteSize(
+ io::Printer* printer) const {
+ Formatter format(printer, variables_);
+ format(
+ "total_size += $tag_size$ *\n"
+ " ::$proto_ns$::internal::FromIntSize($name$_.size());\n"
+ "for (int i = 0, n = $name$_.size(); i < n; i++) {\n"
+ " total_size += "
+ "::$proto_ns$::internal::WireFormatLite::$declared_type$Size(\n"
+ " $name$_.Get(i));\n"
+ "}\n");
+}
+
+void RepeatedStringFieldGenerator::GenerateConstinitInitializer(
+ io::Printer* printer) const {
+ Formatter format(printer, variables_);
+ format("$name$_()");
+}
+
+} // namespace cpp
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_string_field.h b/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_string_field.h
new file mode 100644
index 00000000..c3240355
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_string_field.h
@@ -0,0 +1,127 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_STRING_FIELD_H__
+#define GOOGLE_PROTOBUF_COMPILER_CPP_STRING_FIELD_H__
+
+#include <map>
+#include <string>
+#include <compiler/cpp/cpp_field.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+class StringFieldGenerator : public FieldGenerator {
+ public:
+ StringFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options);
+ ~StringFieldGenerator();
+
+ // implements FieldGenerator ---------------------------------------
+ void GeneratePrivateMembers(io::Printer* printer) const override;
+ void GenerateStaticMembers(io::Printer* printer) const override;
+ void GenerateAccessorDeclarations(io::Printer* printer) const override;
+ void GenerateInlineAccessorDefinitions(io::Printer* printer) const override;
+ void GenerateNonInlineAccessorDefinitions(
+ io::Printer* printer) const override;
+ void GenerateClearingCode(io::Printer* printer) const override;
+ void GenerateMessageClearingCode(io::Printer* printer) const override;
+ void GenerateMergingCode(io::Printer* printer) const override;
+ void GenerateSwappingCode(io::Printer* printer) const override;
+ void GenerateConstructorCode(io::Printer* printer) const override;
+ void GenerateCopyConstructorCode(io::Printer* printer) const override;
+ void GenerateDestructorCode(io::Printer* printer) const override;
+ void GenerateSerializeWithCachedSizesToArray(
+ io::Printer* printer) const override;
+ void GenerateByteSize(io::Printer* printer) const override;
+ void GenerateConstinitInitializer(io::Printer* printer) const override;
+ bool IsInlined() const override { return inlined_; }
+
+ private:
+ bool inlined_;
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(StringFieldGenerator);
+};
+
+class StringOneofFieldGenerator : public StringFieldGenerator {
+ public:
+ StringOneofFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options);
+ ~StringOneofFieldGenerator();
+
+ // implements FieldGenerator ---------------------------------------
+ void GenerateInlineAccessorDefinitions(io::Printer* printer) const override;
+ void GenerateClearingCode(io::Printer* printer) const override;
+
+ // StringFieldGenerator, from which we inherit, overrides this so we need to
+ // override it as well.
+ void GenerateMessageClearingCode(io::Printer* printer) const override;
+ void GenerateSwappingCode(io::Printer* printer) const override;
+ void GenerateConstructorCode(io::Printer* printer) const override;
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(StringOneofFieldGenerator);
+};
+
+class RepeatedStringFieldGenerator : public FieldGenerator {
+ public:
+ RepeatedStringFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options);
+ ~RepeatedStringFieldGenerator();
+
+ // implements FieldGenerator ---------------------------------------
+ void GeneratePrivateMembers(io::Printer* printer) const override;
+ void GenerateAccessorDeclarations(io::Printer* printer) const override;
+ void GenerateInlineAccessorDefinitions(io::Printer* printer) const override;
+ void GenerateClearingCode(io::Printer* printer) const override;
+ void GenerateMergingCode(io::Printer* printer) const override;
+ void GenerateSwappingCode(io::Printer* printer) const override;
+ void GenerateConstructorCode(io::Printer* printer) const override;
+ void GenerateCopyConstructorCode(io::Printer* printer) const override;
+ void GenerateSerializeWithCachedSizesToArray(
+ io::Printer* printer) const override;
+ void GenerateByteSize(io::Printer* printer) const override;
+ void GenerateConstinitInitializer(io::Printer* printer) const override;
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedStringFieldGenerator);
+};
+
+} // namespace cpp
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_COMPILER_CPP_STRING_FIELD_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_test_bad_identifiers.proto b/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_test_bad_identifiers.proto
new file mode 100644
index 00000000..466a8419
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_test_bad_identifiers.proto
@@ -0,0 +1,184 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// This file tests that various identifiers work as field and type names even
+// though the same identifiers are used internally by the C++ code generator.
+
+// LINT: LEGACY_NAMES
+
+syntax = "proto2";
+
+// Some generic_services option(s) added automatically.
+// See: http://go/proto2-generic-services-default
+option cc_generic_services = true; // auto-added
+
+// We don't put this in a package within proto2 because we need to make sure
+// that the generated code doesn't depend on being in the proto2 namespace.
+package protobuf_unittest;
+
+// Test that fields can have names like "input" and "i" which are also used
+// internally by the code generator for local variables.
+message TestConflictingSymbolNames {
+ message BuildDescriptors {}
+ message TypeTraits {}
+
+ optional int32 input = 1;
+ optional int32 output = 2;
+ optional string length = 3;
+ repeated int32 i = 4;
+ repeated string new_element = 5 [ctype = STRING_PIECE];
+ optional int32 total_size = 6;
+ optional int32 tag = 7;
+
+ enum TestEnum { FOO = 0; }
+ message Data1 {
+ repeated int32 data = 1;
+ }
+ message Data2 {
+ repeated TestEnum data = 1;
+ }
+ message Data3 {
+ repeated string data = 1;
+ }
+ message Data4 {
+ repeated Data4 data = 1;
+ }
+ message Data5 {
+ repeated string data = 1 [ctype = STRING_PIECE];
+ }
+ message Data6 {
+ repeated string data = 1 [ctype = CORD];
+ }
+
+ optional int32 source = 8;
+ optional int32 value = 9;
+ optional int32 file = 10;
+ optional int32 from = 11;
+ optional int32 handle_uninterpreted = 12;
+ repeated int32 index = 13;
+ optional int32 controller = 14;
+ optional int32 already_here = 15;
+
+ optional uint32 uint32 = 16;
+ optional uint64 uint64 = 17;
+ optional string string = 18;
+ optional int32 memset = 19;
+ optional int32 int32 = 20;
+ optional int64 int64 = 21;
+
+ optional uint32 cached_size = 22;
+ optional uint32 extensions = 23;
+ optional uint32 bit = 24;
+ optional uint32 bits = 25;
+ optional uint32 offsets = 26;
+ optional uint32 reflection = 27;
+
+ message Cord {}
+ optional string some_cord = 28 [ctype = CORD];
+
+ message StringPiece {}
+ optional string some_string_piece = 29 [ctype = STRING_PIECE];
+
+ // Some keywords.
+ optional uint32 int = 30;
+ optional uint32 friend = 31;
+ optional uint32 class = 37;
+ optional uint32 typedecl = 39;
+ optional uint32 auto = 40;
+
+ // The generator used to #define a macro called "DO" inside the .cc file.
+ message DO {}
+ optional DO do = 32;
+
+ // Some template parameter names for extensions.
+ optional int32 field_type = 33;
+ optional bool is_packed = 34;
+
+ // test conflicting release_$name$. "length" and "do" field in this message
+ // must remain string or message fields to make the test valid.
+ optional string release_length = 35;
+ // A more extreme case, the field name "do" here is a keyword, which will be
+ // escaped to "do_" already. Test there is no conflict even with escaped field
+ // names.
+ optional DO release_do = 36;
+
+ // For clashing local variables in Serialize and ByteSize calculation.
+ optional string target = 38;
+
+ extensions 1000 to max; // NO_PROTO3
+}
+
+message TestConflictingSymbolNamesExtension { // NO_PROTO3
+ extend TestConflictingSymbolNames { // NO_PROTO3
+ repeated int32 repeated_int32_ext = 20423638 [packed = true]; // NO_PROTO3
+ } // NO_PROTO3
+} // NO_PROTO3
+
+message TestConflictingEnumNames { // NO_PROTO3
+ enum while { // NO_PROTO3
+ default = 0; // NO_PROTO3
+ and = 1; // NO_PROTO3
+ class = 2; // NO_PROTO3
+ int = 3; // NO_PROTO3
+ typedef = 4; // NO_PROTO3
+ XOR = 5; // NO_PROTO3
+ } // NO_PROTO3
+
+ optional while conflicting_enum = 1; // NO_PROTO3
+} // NO_PROTO3
+
+enum bool { // NO_PROTO3
+ default = 0; // NO_PROTO3
+ NOT_EQ = 1; // NO_PROTO3
+ volatile = 2; // NO_PROTO3
+ return = 3; // NO_PROTO3
+} // NO_PROTO3
+
+message DummyMessage {}
+
+message NULL {
+ optional int32 int = 1;
+}
+
+extend TestConflictingSymbolNames { // NO_PROTO3
+ optional int32 void = 314253; // NO_PROTO3
+} // NO_PROTO3
+
+// Message names that could conflict.
+message Shutdown {}
+message TableStruct {}
+
+service TestConflictingMethodNames {
+ rpc Closure(DummyMessage) returns (DummyMessage);
+}
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_test_large_enum_value.proto b/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_test_large_enum_value.proto
new file mode 100644
index 00000000..cb6ca1b1
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_test_large_enum_value.proto
@@ -0,0 +1,43 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Test that proto2 compiler can generate valid code when the enum value
+// is INT_MAX. Note that this is a compile-only test and this proto is not
+// referenced in any C++ code.
+syntax = "proto2";
+
+package protobuf_unittest;
+
+message TestLargeEnumValue {
+ enum EnumWithLargeValue {
+ VALUE_1 = 1;
+ VALUE_MAX = 0x7fffffff;
+ }
+}
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_unittest.cc b/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_unittest.cc
new file mode 100644
index 00000000..fa6f4d02
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_unittest.cc
@@ -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.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// To test the code generator, we actually use it to generate code for
+// net/proto2/internal/unittest.proto, then test that. This means that we
+// are actually testing the parser and other parts of the system at the same
+// time, and that problems in the generator may show up as compile-time errors
+// rather than unittest failures, which may be surprising. However, testing
+// the output of the C++ generator directly would be very hard. We can't very
+// well just check it against golden files since those files would have to be
+// updated for any small change; such a test would be very brittle and probably
+// not very helpful. What we really want to test is that the code compiles
+// correctly and produces the interfaces we expect, which is why this test
+// is written this way.
+
+#include <compiler/cpp/cpp_unittest.h>
+
+#include <unittest.pb.h>
+#include <unittest_embed_optimize_for.pb.h>
+#include <unittest_optimize_for.pb.h>
+
+#include <test_util.h>
+
+#define MESSAGE_TEST_NAME MessageTest
+#define GENERATED_DESCRIPTOR_TEST_NAME GeneratedDescriptorTest
+#define GENERATED_MESSAGE_TEST_NAME GeneratedMessageTest
+#define GENERATED_ENUM_TEST_NAME GeneratedEnumTest
+#define GENERATED_SERVICE_TEST_NAME GeneratedServiceTest
+#define HELPERS_TEST_NAME HelpersTest
+#define DESCRIPTOR_INIT_TEST_NAME DescriptorInitializationTest
+
+#define UNITTEST_PROTO_PATH "net/proto2/internal/unittest.proto"
+#define UNITTEST ::protobuf_unittest
+#define UNITTEST_IMPORT ::protobuf_unittest_import
+
+// Must include after the above macros.
+#include <compiler/cpp/cpp_unittest.inc>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+// Can't use an anonymous namespace here due to brokenness of Tru64 compiler.
+namespace cpp_unittest {
+
+namespace protobuf_unittest = ::protobuf_unittest;
+
+TEST(GENERATED_MESSAGE_TEST_NAME, TestConflictingSymbolNames) {
+ // test_bad_identifiers.proto successfully compiled, then it works. The
+ // following is just a token usage to insure that the code is, in fact,
+ // being compiled and linked.
+
+ protobuf_unittest::TestConflictingSymbolNames message;
+ message.set_uint32(1);
+ EXPECT_EQ(3, message.ByteSizeLong());
+
+ message.set_friend_(5);
+ EXPECT_EQ(5, message.friend_());
+
+ message.set_class_(6);
+ EXPECT_EQ(6, message.class_());
+
+ // Instantiate extension template functions to test conflicting template
+ // parameter names.
+ typedef protobuf_unittest::TestConflictingSymbolNamesExtension ExtensionMessage;
+ message.AddExtension(ExtensionMessage::repeated_int32_ext, 123);
+ EXPECT_EQ(123, message.GetExtension(ExtensionMessage::repeated_int32_ext, 0));
+}
+
+TEST(GENERATED_MESSAGE_TEST_NAME, TestConflictingEnumNames) {
+ protobuf_unittest::TestConflictingEnumNames message;
+ message.set_conflicting_enum(
+ protobuf_unittest::TestConflictingEnumNames_while_and_);
+ EXPECT_EQ(1, message.conflicting_enum());
+ message.set_conflicting_enum(
+ protobuf_unittest::TestConflictingEnumNames_while_XOR);
+ EXPECT_EQ(5, message.conflicting_enum());
+
+ protobuf_unittest::bool_ conflicting_enum;
+ conflicting_enum = protobuf_unittest::NOT_EQ;
+ EXPECT_EQ(1, conflicting_enum);
+ conflicting_enum = protobuf_unittest::return_;
+ EXPECT_EQ(3, conflicting_enum);
+}
+
+TEST(GENERATED_MESSAGE_TEST_NAME, TestConflictingMessageNames) {
+ protobuf_unittest::NULL_ message;
+ message.set_int_(123);
+ EXPECT_EQ(message.int_(), 123);
+}
+
+TEST(GENERATED_MESSAGE_TEST_NAME, TestConflictingExtension) {
+ protobuf_unittest::TestConflictingSymbolNames message;
+ message.SetExtension(protobuf_unittest::void_, 123);
+ EXPECT_EQ(123, message.GetExtension(protobuf_unittest::void_));
+}
+
+} // namespace cpp_unittest
+} // namespace cpp
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_unittest.h b/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_unittest.h
new file mode 100644
index 00000000..c5dc767a
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_unittest.h
@@ -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.
+
+// This header declares the namespace google::protobuf::protobuf_unittest in order to expose
+// any problems with the generated class names. We use this header to ensure
+// unittest.cc will declare the namespace prior to other includes, while obeying
+// normal include ordering.
+//
+// When generating a class name of "foo.Bar" we must ensure we prefix the class
+// name with "::", in case the namespace google::protobuf::foo exists. We intentionally
+// trigger that case here by declaring google::protobuf::protobuf_unittest.
+//
+// See ClassName in helpers.h for more details.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_UNITTEST_H__
+#define GOOGLE_PROTOBUF_COMPILER_CPP_UNITTEST_H__
+
+namespace google {
+namespace protobuf {
+namespace protobuf_unittest {}
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_COMPILER_CPP_UNITTEST_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_unittest.inc b/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_unittest.inc
new file mode 100644
index 00000000..effb7de4
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/cpp/cpp_unittest.inc
@@ -0,0 +1,2234 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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.
+//
+// To test the code generator, we actually use it to generate code for
+// net/proto2/internal/unittest.proto, then test that. This means that we
+// are actually testing the parser and other parts of the system at the same
+// time, and that problems in the generator may show up as compile-time errors
+// rather than unittest failures, which may be surprising. However, testing
+// the output of the C++ generator directly would be very hard. We can't very
+// well just check it against golden files since those files would have to be
+// updated for any small change; such a test would be very brittle and probably
+// not very helpful. What we really want to test is that the code compiles
+// correctly and produces the interfaces we expect, which is why this test
+// is written this way.
+
+#include <cstdint>
+#include <limits>
+#include <memory>
+#include <vector>
+
+#include <compiler/cpp/cpp_unittest.h>
+#include <stubs/strutil.h>
+#if !defined(GOOGLE_PROTOBUF_CMAKE_BUILD) && !defined(_MSC_VER)
+// We exclude this large proto from cmake build because it's too large for
+// visual studio to compile (report internal errors).
+#include <unittest_enormous_descriptor.pb.h>
+#endif
+#include <compiler/cpp/cpp_helpers.h>
+#include <compiler/cpp/cpp_test_bad_identifiers.pb.h>
+#include <compiler/scc.h>
+#include <compiler/importer.h>
+#include <test_util2.h>
+#include <unittest_no_generic_services.pb.h>
+#include <io/coded_stream.h>
+#include <io/zero_copy_stream_impl.h>
+#include <descriptor.pb.h>
+#include <arena.h>
+#include <descriptor.h>
+#include <dynamic_message.h>
+
+#include <stubs/callback.h>
+#include <stubs/common.h>
+#include <stubs/logging.h>
+#include <testing/googletest.h>
+#include <gtest/gtest.h>
+#include <stubs/casts.h>
+#include <stubs/substitute.h>
+#include <stubs/stl_util.h>
+
+// Must be included last.
+#include <port_def.inc>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+// Can't use an anonymous namespace here due to brokenness of Tru64 compiler.
+namespace cpp_unittest {
+
+
+void DoNothing() {}
+
+class MockErrorCollector : public MultiFileErrorCollector {
+ public:
+ MockErrorCollector() {}
+ ~MockErrorCollector() {}
+
+ std::string text_;
+
+ // implements ErrorCollector ---------------------------------------
+ void AddError(const std::string& filename, int line, int column,
+ const std::string& message) override {
+ strings::SubstituteAndAppend(&text_, "$0:$1:$2: $3\n", filename, line, column,
+ message);
+ }
+};
+
+#ifndef PROTOBUF_TEST_NO_DESCRIPTORS
+
+// Test that generated code has proper descriptors:
+// Parse a descriptor directly (using google::protobuf::compiler::Importer) and
+// compare it to the one that was produced by generated code.
+TEST(GENERATED_DESCRIPTOR_TEST_NAME, IdenticalDescriptors) {
+ const FileDescriptor* generated_descriptor =
+ UNITTEST::TestAllTypes::descriptor()->file();
+
+ // Set up the Importer.
+ MockErrorCollector error_collector;
+ DiskSourceTree source_tree;
+ source_tree.MapPath("", TestUtil::TestSourceDir());
+ Importer importer(&source_tree, &error_collector);
+
+ // Import (parse) unittest.proto.
+ const FileDescriptor* parsed_descriptor =
+ importer.Import(TestUtil::MaybeTranslatePath(UNITTEST_PROTO_PATH));
+ EXPECT_EQ("", error_collector.text_);
+ ASSERT_TRUE(parsed_descriptor != NULL);
+
+ // Test that descriptors are generated correctly by converting them to
+ // FileDescriptorProtos and comparing.
+ FileDescriptorProto generated_descriptor_proto, parsed_descriptor_proto;
+ generated_descriptor->CopyTo(&generated_descriptor_proto);
+ parsed_descriptor->CopyTo(&parsed_descriptor_proto);
+
+ EXPECT_EQ(parsed_descriptor_proto.DebugString(),
+ generated_descriptor_proto.DebugString());
+}
+
+#if !defined(GOOGLE_PROTOBUF_CMAKE_BUILD) && !defined(_MSC_VER)
+// Test that generated code has proper descriptors:
+// Touch a descriptor generated from an enormous message to validate special
+// handling for descriptors exceeding the C++ standard's recommended minimum
+// limit for string literal size
+TEST(GENERATED_DESCRIPTOR_TEST_NAME, EnormousDescriptor) {
+ const Descriptor* generated_descriptor =
+ ::protobuf_unittest::TestEnormousDescriptor::descriptor();
+
+ EXPECT_TRUE(generated_descriptor != NULL);
+}
+#endif
+
+#endif // !PROTOBUF_TEST_NO_DESCRIPTORS
+
+// ===================================================================
+
+TEST(GENERATED_MESSAGE_TEST_NAME, Defaults) {
+ // Check that all default values are set correctly in the initial message.
+ UNITTEST::TestAllTypes message;
+
+ TestUtil::ExpectClear(message);
+
+ // Messages should return pointers to default instances until first use.
+ // (This is not checked by ExpectClear() since it is not actually true after
+ // the fields have been set and then cleared.)
+ EXPECT_EQ(&UNITTEST::TestAllTypes::OptionalGroup::default_instance(),
+ &message.optionalgroup());
+ EXPECT_EQ(&UNITTEST::TestAllTypes::NestedMessage::default_instance(),
+ &message.optional_nested_message());
+ EXPECT_EQ(&UNITTEST::ForeignMessage::default_instance(),
+ &message.optional_foreign_message());
+ EXPECT_EQ(&UNITTEST_IMPORT::ImportMessage::default_instance(),
+ &message.optional_import_message());
+}
+
+TEST(GENERATED_MESSAGE_TEST_NAME, FloatingPointDefaults) {
+ const UNITTEST::TestExtremeDefaultValues& extreme_default =
+ UNITTEST::TestExtremeDefaultValues::default_instance();
+
+ EXPECT_EQ(0.0f, extreme_default.zero_float());
+ EXPECT_EQ(1.0f, extreme_default.one_float());
+ EXPECT_EQ(1.5f, extreme_default.small_float());
+ EXPECT_EQ(-1.0f, extreme_default.negative_one_float());
+ EXPECT_EQ(-1.5f, extreme_default.negative_float());
+ EXPECT_EQ(2.0e8f, extreme_default.large_float());
+ EXPECT_EQ(-8e-28f, extreme_default.small_negative_float());
+ EXPECT_EQ(std::numeric_limits<double>::infinity(),
+ extreme_default.inf_double());
+ EXPECT_EQ(-std::numeric_limits<double>::infinity(),
+ extreme_default.neg_inf_double());
+ EXPECT_TRUE(extreme_default.nan_double() != extreme_default.nan_double());
+ EXPECT_EQ(std::numeric_limits<float>::infinity(),
+ extreme_default.inf_float());
+ EXPECT_EQ(-std::numeric_limits<float>::infinity(),
+ extreme_default.neg_inf_float());
+ EXPECT_TRUE(extreme_default.nan_float() != extreme_default.nan_float());
+}
+
+TEST(GENERATED_MESSAGE_TEST_NAME, Trigraph) {
+ const UNITTEST::TestExtremeDefaultValues& extreme_default =
+ UNITTEST::TestExtremeDefaultValues::default_instance();
+
+ EXPECT_EQ("? ? ?? ?? ??? ?\?/ ?\?-", extreme_default.cpp_trigraph());
+}
+
+TEST(GENERATED_MESSAGE_TEST_NAME, ExtremeSmallIntegerDefault) {
+ const UNITTEST::TestExtremeDefaultValues& extreme_default =
+ UNITTEST::TestExtremeDefaultValues::default_instance();
+ EXPECT_EQ(std::numeric_limits<int32_t>::min(),
+ extreme_default.really_small_int32());
+ EXPECT_EQ(std::numeric_limits<int64_t>::min(),
+ extreme_default.really_small_int64());
+}
+
+TEST(GENERATED_MESSAGE_TEST_NAME, Accessors) {
+ // Set every field to a unique value then go back and check all those
+ // values.
+ UNITTEST::TestAllTypes message;
+
+ TestUtil::SetAllFields(&message);
+ TestUtil::ExpectAllFieldsSet(message);
+
+ TestUtil::ModifyRepeatedFields(&message);
+ TestUtil::ExpectRepeatedFieldsModified(message);
+}
+
+TEST(GENERATED_MESSAGE_TEST_NAME, MutableStringDefault) {
+ // mutable_foo() for a string should return a string initialized to its
+ // default value.
+ UNITTEST::TestAllTypes message;
+
+ EXPECT_EQ("hello", *message.mutable_default_string());
+
+ // Note that the first time we call mutable_foo(), we get a newly-allocated
+ // string, but if we clear it and call it again, we get the same object again.
+ // We should verify that it has its default value in both cases.
+ message.set_default_string("blah");
+ message.Clear();
+
+ EXPECT_EQ("hello", *message.mutable_default_string());
+}
+
+TEST(GENERATED_MESSAGE_TEST_NAME, StringDefaults) {
+ UNITTEST::TestExtremeDefaultValues message;
+ // Check if '\000' can be used in default string value.
+ EXPECT_EQ(std::string("hel\000lo", 6), message.string_with_zero());
+ EXPECT_EQ(std::string("wor\000ld", 6), message.bytes_with_zero());
+}
+
+TEST(GENERATED_MESSAGE_TEST_NAME, ReleaseString) {
+ // Check that release_foo() starts out NULL, and gives us a value
+ // that we can delete after it's been set.
+ UNITTEST::TestAllTypes message;
+
+ EXPECT_EQ(NULL, message.release_default_string());
+ EXPECT_FALSE(message.has_default_string());
+ EXPECT_EQ("hello", message.default_string());
+
+ message.set_default_string("blah");
+ EXPECT_TRUE(message.has_default_string());
+ std::unique_ptr<std::string> str(message.release_default_string());
+ EXPECT_FALSE(message.has_default_string());
+ ASSERT_TRUE(str != NULL);
+ EXPECT_EQ("blah", *str);
+
+ EXPECT_EQ(NULL, message.release_default_string());
+ EXPECT_FALSE(message.has_default_string());
+ EXPECT_EQ("hello", message.default_string());
+}
+
+TEST(GENERATED_MESSAGE_TEST_NAME, ReleaseMessage) {
+ // Check that release_foo() starts out NULL, and gives us a value
+ // that we can delete after it's been set.
+ UNITTEST::TestAllTypes message;
+
+ EXPECT_EQ(NULL, message.release_optional_nested_message());
+ EXPECT_FALSE(message.has_optional_nested_message());
+
+ message.mutable_optional_nested_message()->set_bb(1);
+ std::unique_ptr<UNITTEST::TestAllTypes::NestedMessage> nest(
+ message.release_optional_nested_message());
+ EXPECT_FALSE(message.has_optional_nested_message());
+ ASSERT_TRUE(nest != NULL);
+ EXPECT_EQ(1, nest->bb());
+
+ EXPECT_EQ(NULL, message.release_optional_nested_message());
+ EXPECT_FALSE(message.has_optional_nested_message());
+}
+
+TEST(GENERATED_MESSAGE_TEST_NAME, SetAllocatedString) {
+ // Check that set_allocated_foo() works for strings.
+ UNITTEST::TestAllTypes message;
+
+ EXPECT_FALSE(message.has_optional_string());
+ const std::string kHello("hello");
+ message.set_optional_string(kHello);
+ EXPECT_TRUE(message.has_optional_string());
+
+ message.set_allocated_optional_string(NULL);
+ EXPECT_FALSE(message.has_optional_string());
+ EXPECT_EQ("", message.optional_string());
+
+ message.set_allocated_optional_string(new std::string(kHello));
+ EXPECT_TRUE(message.has_optional_string());
+ EXPECT_EQ(kHello, message.optional_string());
+}
+
+TEST(GENERATED_MESSAGE_TEST_NAME, SetAllocatedMessage) {
+ // Check that set_allocated_foo() can be called in all cases.
+ UNITTEST::TestAllTypes message;
+
+ EXPECT_FALSE(message.has_optional_nested_message());
+
+ message.mutable_optional_nested_message()->set_bb(1);
+ EXPECT_TRUE(message.has_optional_nested_message());
+
+ message.set_allocated_optional_nested_message(NULL);
+ EXPECT_FALSE(message.has_optional_nested_message());
+ EXPECT_EQ(&UNITTEST::TestAllTypes::NestedMessage::default_instance(),
+ &message.optional_nested_message());
+
+ message.mutable_optional_nested_message()->set_bb(1);
+ UNITTEST::TestAllTypes::NestedMessage* nest =
+ message.release_optional_nested_message();
+ ASSERT_TRUE(nest != NULL);
+ EXPECT_FALSE(message.has_optional_nested_message());
+
+ message.set_allocated_optional_nested_message(nest);
+ EXPECT_TRUE(message.has_optional_nested_message());
+ EXPECT_EQ(1, message.optional_nested_message().bb());
+}
+
+TEST(GENERATED_MESSAGE_TEST_NAME, Clear) {
+ // Set every field to a unique value, clear the message, then check that
+ // it is cleared.
+ UNITTEST::TestAllTypes message;
+
+ TestUtil::SetAllFields(&message);
+ message.Clear();
+ TestUtil::ExpectClear(message);
+
+ // Unlike with the defaults test, we do NOT expect that requesting embedded
+ // messages will return a pointer to the default instance. Instead, they
+ // should return the objects that were created when mutable_blah() was
+ // called.
+ EXPECT_NE(&UNITTEST::TestAllTypes::OptionalGroup::default_instance(),
+ &message.optionalgroup());
+ EXPECT_NE(&UNITTEST::TestAllTypes::NestedMessage::default_instance(),
+ &message.optional_nested_message());
+ EXPECT_NE(&UNITTEST::ForeignMessage::default_instance(),
+ &message.optional_foreign_message());
+ EXPECT_NE(&UNITTEST_IMPORT::ImportMessage::default_instance(),
+ &message.optional_import_message());
+}
+
+TEST(GENERATED_MESSAGE_TEST_NAME, EmbeddedNullsInBytesCharStar) {
+ UNITTEST::TestAllTypes message;
+
+ const char* value = "\0lalala\0\0";
+ message.set_optional_bytes(value, 9);
+ ASSERT_EQ(9, message.optional_bytes().size());
+ EXPECT_EQ(0, memcmp(value, message.optional_bytes().data(), 9));
+
+ message.add_repeated_bytes(value, 9);
+ ASSERT_EQ(9, message.repeated_bytes(0).size());
+ EXPECT_EQ(0, memcmp(value, message.repeated_bytes(0).data(), 9));
+}
+
+TEST(GENERATED_MESSAGE_TEST_NAME, ClearOneField) {
+ // Set every field to a unique value, then clear one value and insure that
+ // only that one value is cleared.
+ UNITTEST::TestAllTypes message;
+
+ TestUtil::SetAllFields(&message);
+ int64_t original_value = message.optional_int64();
+
+ // Clear the field and make sure it shows up as cleared.
+ message.clear_optional_int64();
+ EXPECT_FALSE(message.has_optional_int64());
+ EXPECT_EQ(0, message.optional_int64());
+
+ // Other adjacent fields should not be cleared.
+ EXPECT_TRUE(message.has_optional_int32());
+ EXPECT_TRUE(message.has_optional_uint32());
+
+ // Make sure if we set it again, then all fields are set.
+ message.set_optional_int64(original_value);
+ TestUtil::ExpectAllFieldsSet(message);
+}
+
+TEST(GENERATED_MESSAGE_TEST_NAME, StringCharStarLength) {
+ // Verify that we can use a char*,length to set one of the string fields.
+ UNITTEST::TestAllTypes message;
+ message.set_optional_string("abcdef", 3);
+ EXPECT_EQ("abc", message.optional_string());
+
+ // Verify that we can use a char*,length to add to a repeated string field.
+ message.add_repeated_string("abcdef", 3);
+ EXPECT_EQ(1, message.repeated_string_size());
+ EXPECT_EQ("abc", message.repeated_string(0));
+
+ // Verify that we can use a char*,length to set a repeated string field.
+ message.set_repeated_string(0, "wxyz", 2);
+ EXPECT_EQ("wx", message.repeated_string(0));
+}
+
+
+TEST(GENERATED_MESSAGE_TEST_NAME, CopyFrom) {
+ UNITTEST::TestAllTypes message1, message2;
+
+ TestUtil::SetAllFields(&message1);
+ message2.CopyFrom(message1);
+ TestUtil::ExpectAllFieldsSet(message2);
+
+ // Copying from self should be a no-op.
+ message2.CopyFrom(message2);
+ TestUtil::ExpectAllFieldsSet(message2);
+}
+
+
+TEST(GENERATED_MESSAGE_TEST_NAME, SwapWithEmpty) {
+ UNITTEST::TestAllTypes message1, message2;
+ TestUtil::SetAllFields(&message1);
+
+ TestUtil::ExpectAllFieldsSet(message1);
+ TestUtil::ExpectClear(message2);
+ message1.Swap(&message2);
+ TestUtil::ExpectAllFieldsSet(message2);
+ TestUtil::ExpectClear(message1);
+}
+
+TEST(GENERATED_MESSAGE_TEST_NAME, SwapWithSelf) {
+ UNITTEST::TestAllTypes message;
+ TestUtil::SetAllFields(&message);
+ TestUtil::ExpectAllFieldsSet(message);
+ message.Swap(&message);
+ TestUtil::ExpectAllFieldsSet(message);
+}
+
+TEST(GENERATED_MESSAGE_TEST_NAME, SwapWithOther) {
+ UNITTEST::TestAllTypes message1, message2;
+
+ message1.set_optional_int32(123);
+ message1.set_optional_string("abc");
+ message1.mutable_optional_nested_message()->set_bb(1);
+ message1.set_optional_nested_enum(UNITTEST::TestAllTypes::FOO);
+ message1.add_repeated_int32(1);
+ message1.add_repeated_int32(2);
+ message1.add_repeated_string("a");
+ message1.add_repeated_string("b");
+ message1.add_repeated_nested_message()->set_bb(7);
+ message1.add_repeated_nested_message()->set_bb(8);
+ message1.add_repeated_nested_enum(UNITTEST::TestAllTypes::FOO);
+ message1.add_repeated_nested_enum(UNITTEST::TestAllTypes::BAR);
+
+ message2.set_optional_int32(456);
+ message2.set_optional_string("def");
+ message2.mutable_optional_nested_message()->set_bb(2);
+ message2.set_optional_nested_enum(UNITTEST::TestAllTypes::BAR);
+ message2.add_repeated_int32(3);
+ message2.add_repeated_string("c");
+ message2.add_repeated_nested_message()->set_bb(9);
+ message2.add_repeated_nested_enum(UNITTEST::TestAllTypes::BAZ);
+
+ message1.Swap(&message2);
+
+ EXPECT_EQ(456, message1.optional_int32());
+ EXPECT_EQ("def", message1.optional_string());
+ EXPECT_EQ(2, message1.optional_nested_message().bb());
+ EXPECT_EQ(UNITTEST::TestAllTypes::BAR, message1.optional_nested_enum());
+ ASSERT_EQ(1, message1.repeated_int32_size());
+ EXPECT_EQ(3, message1.repeated_int32(0));
+ ASSERT_EQ(1, message1.repeated_string_size());
+ EXPECT_EQ("c", message1.repeated_string(0));
+ ASSERT_EQ(1, message1.repeated_nested_message_size());
+ EXPECT_EQ(9, message1.repeated_nested_message(0).bb());
+ ASSERT_EQ(1, message1.repeated_nested_enum_size());
+ EXPECT_EQ(UNITTEST::TestAllTypes::BAZ, message1.repeated_nested_enum(0));
+
+ EXPECT_EQ(123, message2.optional_int32());
+ EXPECT_EQ("abc", message2.optional_string());
+ EXPECT_EQ(1, message2.optional_nested_message().bb());
+ EXPECT_EQ(UNITTEST::TestAllTypes::FOO, message2.optional_nested_enum());
+ ASSERT_EQ(2, message2.repeated_int32_size());
+ EXPECT_EQ(1, message2.repeated_int32(0));
+ EXPECT_EQ(2, message2.repeated_int32(1));
+ ASSERT_EQ(2, message2.repeated_string_size());
+ EXPECT_EQ("a", message2.repeated_string(0));
+ EXPECT_EQ("b", message2.repeated_string(1));
+ ASSERT_EQ(2, message2.repeated_nested_message_size());
+ EXPECT_EQ(7, message2.repeated_nested_message(0).bb());
+ EXPECT_EQ(8, message2.repeated_nested_message(1).bb());
+ ASSERT_EQ(2, message2.repeated_nested_enum_size());
+ EXPECT_EQ(UNITTEST::TestAllTypes::FOO, message2.repeated_nested_enum(0));
+ EXPECT_EQ(UNITTEST::TestAllTypes::BAR, message2.repeated_nested_enum(1));
+}
+
+TEST(GENERATED_MESSAGE_TEST_NAME, ADLSwap) {
+ UNITTEST::TestAllTypes message1, message2;
+ TestUtil::SetAllFields(&message1);
+
+ // Note the address of one of the repeated fields, to verify it was swapped
+ // rather than copied.
+ const int32_t* addr = &message1.repeated_int32().Get(0);
+
+ using std::swap;
+ swap(message1, message2);
+
+ TestUtil::ExpectAllFieldsSet(message2);
+ TestUtil::ExpectClear(message1);
+
+#ifdef PROTOBUF_FORCE_COPY_IN_SWAP
+ EXPECT_NE(addr, &message2.repeated_int32().Get(0));
+ EXPECT_EQ(*addr, message2.repeated_int32().Get(0));
+#else
+ EXPECT_EQ(addr, &message2.repeated_int32().Get(0));
+#endif
+}
+
+TEST(GENERATED_MESSAGE_TEST_NAME, CopyConstructor) {
+ // All set.
+ {
+ UNITTEST::TestAllTypes message1;
+ TestUtil::SetAllFields(&message1);
+
+ UNITTEST::TestAllTypes message2(message1);
+ TestUtil::ExpectAllFieldsSet(message2);
+ }
+
+ // None set.
+ {
+ UNITTEST::TestAllTypes message1;
+ UNITTEST::TestAllTypes message2(message1);
+
+ EXPECT_FALSE(message1.has_optional_string());
+ EXPECT_FALSE(message2.has_optional_string());
+ EXPECT_EQ(message1.optional_string(), message2.optional_string());
+
+ EXPECT_FALSE(message1.has_optional_bytes());
+ EXPECT_FALSE(message2.has_optional_bytes());
+ EXPECT_EQ(message1.optional_bytes(), message2.optional_bytes());
+
+ EXPECT_FALSE(message1.has_optional_nested_message());
+ EXPECT_FALSE(message2.has_optional_nested_message());
+ EXPECT_EQ(&message1.optional_nested_message(),
+ &message2.optional_nested_message());
+
+ EXPECT_FALSE(message1.has_optional_foreign_message());
+ EXPECT_FALSE(message2.has_optional_foreign_message());
+ EXPECT_EQ(&message1.optional_foreign_message(),
+ &message2.optional_foreign_message());
+
+ EXPECT_FALSE(message1.has_optional_import_message());
+ EXPECT_FALSE(message2.has_optional_import_message());
+ EXPECT_EQ(&message1.optional_import_message(),
+ &message2.optional_import_message());
+
+ EXPECT_FALSE(message1.has_optional_public_import_message());
+ EXPECT_FALSE(message2.has_optional_public_import_message());
+ EXPECT_EQ(&message1.optional_public_import_message(),
+ &message2.optional_public_import_message());
+
+ EXPECT_FALSE(message1.has_optional_lazy_message());
+ EXPECT_FALSE(message2.has_optional_lazy_message());
+ EXPECT_EQ(&message1.optional_lazy_message(),
+ &message2.optional_lazy_message());
+ }
+}
+
+TEST(GENERATED_MESSAGE_TEST_NAME, CopyConstructorWithArenas) {
+ Arena arena;
+ UNITTEST::TestAllTypes* message1 =
+ Arena::CreateMessage<UNITTEST::TestAllTypes>(&arena);
+ TestUtil::SetAllFields(message1);
+
+ UNITTEST::TestAllTypes message2_stack(*message1);
+ TestUtil::ExpectAllFieldsSet(message2_stack);
+
+ std::unique_ptr<UNITTEST::TestAllTypes> message2_heap(
+ new UNITTEST::TestAllTypes(*message1));
+ TestUtil::ExpectAllFieldsSet(*message2_heap);
+
+ arena.Reset();
+
+ // Verify that the copies are still intact.
+ TestUtil::ExpectAllFieldsSet(message2_stack);
+ TestUtil::ExpectAllFieldsSet(*message2_heap);
+}
+
+TEST(GENERATED_MESSAGE_TEST_NAME, CopyAssignmentOperator) {
+ UNITTEST::TestAllTypes message1;
+ TestUtil::SetAllFields(&message1);
+
+ UNITTEST::TestAllTypes message2;
+ message2 = message1;
+ TestUtil::ExpectAllFieldsSet(message2);
+
+ // Make sure that self-assignment does something sane.
+ message2.operator=(message2);
+ TestUtil::ExpectAllFieldsSet(message2);
+}
+
+#if !defined(PROTOBUF_TEST_NO_DESCRIPTORS) || PROTOBUF_RTTI
+TEST(GENERATED_MESSAGE_TEST_NAME, UpcastCopyFrom) {
+ // Test the CopyFrom method that takes in the generic const Message&
+ // parameter.
+ UNITTEST::TestAllTypes message1, message2;
+
+ TestUtil::SetAllFields(&message1);
+
+ const Message* source = implicit_cast<const Message*>(&message1);
+ message2.CopyFrom(*source);
+
+ TestUtil::ExpectAllFieldsSet(message2);
+}
+#endif
+
+#ifndef PROTOBUF_TEST_NO_DESCRIPTORS
+
+TEST(GENERATED_MESSAGE_TEST_NAME, DynamicMessageCopyFrom) {
+ // Test copying from a DynamicMessage, which must fall back to using
+ // reflection.
+ UNITTEST::TestAllTypes message2;
+
+ // Construct a new version of the dynamic message via the factory.
+ DynamicMessageFactory factory;
+ std::unique_ptr<Message> message1;
+ message1.reset(factory.GetPrototype(
+ UNITTEST::TestAllTypes::descriptor())->New());
+
+ TestUtil::ReflectionTester reflection_tester(
+ UNITTEST::TestAllTypes::descriptor());
+ reflection_tester.SetAllFieldsViaReflection(message1.get());
+
+ message2.CopyFrom(*message1);
+
+ TestUtil::ExpectAllFieldsSet(message2);
+}
+
+#endif // !PROTOBUF_TEST_NO_DESCRIPTORS
+
+TEST(GENERATED_MESSAGE_TEST_NAME, NonEmptyMergeFrom) {
+ // Test merging with a non-empty message. Code is a modified form
+ // of that found in net/proto2/internal/reflection_ops_unittest.cc.
+ UNITTEST::TestAllTypes message1, message2;
+
+ TestUtil::SetAllFields(&message1);
+
+ // This field will test merging into an empty spot.
+ message2.set_optional_int32(message1.optional_int32());
+ message1.clear_optional_int32();
+
+ // This tests overwriting.
+ message2.set_optional_string(message1.optional_string());
+ message1.set_optional_string("something else");
+
+ // This tests concatenating.
+ message2.add_repeated_int32(message1.repeated_int32(1));
+ int32_t i = message1.repeated_int32(0);
+ message1.clear_repeated_int32();
+ message1.add_repeated_int32(i);
+
+ message1.MergeFrom(message2);
+
+ TestUtil::ExpectAllFieldsSet(message1);
+}
+
+
+// Test the generated SerializeWithCachedSizesToArray(),
+TEST(GENERATED_MESSAGE_TEST_NAME, SerializationToArray) {
+ UNITTEST::TestAllTypes message1, message2;
+ std::string data;
+ TestUtil::SetAllFields(&message1);
+ int size = message1.ByteSizeLong();
+ data.resize(size);
+ uint8_t* start = reinterpret_cast<uint8_t*>(::google::protobuf::string_as_array(&data));
+ uint8_t* end = message1.SerializeWithCachedSizesToArray(start);
+ EXPECT_EQ(size, end - start);
+ EXPECT_TRUE(message2.ParseFromString(data));
+ TestUtil::ExpectAllFieldsSet(message2);
+
+}
+
+TEST(GENERATED_MESSAGE_TEST_NAME, PackedFieldsSerializationToArray) {
+ UNITTEST::TestPackedTypes packed_message1, packed_message2;
+ std::string packed_data;
+ TestUtil::SetPackedFields(&packed_message1);
+ int packed_size = packed_message1.ByteSizeLong();
+ packed_data.resize(packed_size);
+ uint8_t* start =
+ reinterpret_cast<uint8_t*>(::google::protobuf::string_as_array(&packed_data));
+ uint8_t* end = packed_message1.SerializeWithCachedSizesToArray(start);
+ EXPECT_EQ(packed_size, end - start);
+ EXPECT_TRUE(packed_message2.ParseFromString(packed_data));
+ TestUtil::ExpectPackedFieldsSet(packed_message2);
+}
+
+// Test the generated SerializeWithCachedSizes() by forcing the buffer to write
+// one byte at a time.
+TEST(GENERATED_MESSAGE_TEST_NAME, SerializationToStream) {
+ UNITTEST::TestAllTypes message1, message2;
+ TestUtil::SetAllFields(&message1);
+ int size = message1.ByteSizeLong();
+ std::string data;
+ data.resize(size);
+ {
+ // Allow the output stream to buffer only one byte at a time.
+ io::ArrayOutputStream array_stream(::google::protobuf::string_as_array(&data), size, 1);
+ io::CodedOutputStream output_stream(&array_stream);
+ message1.SerializeWithCachedSizes(&output_stream);
+ EXPECT_FALSE(output_stream.HadError());
+ EXPECT_EQ(size, output_stream.ByteCount());
+ }
+ EXPECT_TRUE(message2.ParseFromString(data));
+ TestUtil::ExpectAllFieldsSet(message2);
+
+}
+
+TEST(GENERATED_MESSAGE_TEST_NAME, PackedFieldsSerializationToStream) {
+ UNITTEST::TestPackedTypes message1, message2;
+ TestUtil::SetPackedFields(&message1);
+ int size = message1.ByteSizeLong();
+ std::string data;
+ data.resize(size);
+ {
+ // Allow the output stream to buffer only one byte at a time.
+ io::ArrayOutputStream array_stream(::google::protobuf::string_as_array(&data), size, 1);
+ io::CodedOutputStream output_stream(&array_stream);
+ message1.SerializeWithCachedSizes(&output_stream);
+ EXPECT_FALSE(output_stream.HadError());
+ EXPECT_EQ(size, output_stream.ByteCount());
+ }
+ EXPECT_TRUE(message2.ParseFromString(data));
+ TestUtil::ExpectPackedFieldsSet(message2);
+}
+
+
+TEST(GENERATED_MESSAGE_TEST_NAME, Required) {
+ // Test that IsInitialized() returns false if required fields are missing.
+ UNITTEST::TestRequired message;
+
+ EXPECT_FALSE(message.IsInitialized());
+ message.set_a(1);
+ EXPECT_FALSE(message.IsInitialized());
+ message.set_b(2);
+ EXPECT_FALSE(message.IsInitialized());
+ message.set_c(3);
+ EXPECT_TRUE(message.IsInitialized());
+}
+
+TEST(GENERATED_MESSAGE_TEST_NAME, RequiredForeign) {
+ // Test that IsInitialized() returns false if required fields in nested
+ // messages are missing.
+ UNITTEST::TestRequiredForeign message;
+
+ EXPECT_TRUE(message.IsInitialized());
+
+ message.mutable_optional_message();
+ EXPECT_FALSE(message.IsInitialized());
+
+ message.mutable_optional_message()->set_a(1);
+ message.mutable_optional_message()->set_b(2);
+ message.mutable_optional_message()->set_c(3);
+ EXPECT_TRUE(message.IsInitialized());
+
+ message.add_repeated_message();
+ EXPECT_FALSE(message.IsInitialized());
+
+ message.mutable_repeated_message(0)->set_a(1);
+ message.mutable_repeated_message(0)->set_b(2);
+ message.mutable_repeated_message(0)->set_c(3);
+ EXPECT_TRUE(message.IsInitialized());
+}
+
+TEST(GENERATED_MESSAGE_TEST_NAME, ForeignNested) {
+ // Test that TestAllTypes::NestedMessage can be embedded directly into
+ // another message.
+ UNITTEST::TestForeignNested message;
+
+ // If this compiles and runs without crashing, it must work. We have
+ // nothing more to test.
+ UNITTEST::TestAllTypes::NestedMessage* nested =
+ message.mutable_foreign_nested();
+ nested->set_bb(1);
+}
+
+TEST(GENERATED_MESSAGE_TEST_NAME, ReallyLargeTagNumber) {
+ // Test that really large tag numbers don't break anything.
+ UNITTEST::TestReallyLargeTagNumber message1, message2;
+ std::string data;
+
+ // For the most part, if this compiles and runs then we're probably good.
+ // (The most likely cause for failure would be if something were attempting
+ // to allocate a lookup table of some sort using tag numbers as the index.)
+ // We'll try serializing just for fun.
+ message1.set_a(1234);
+ message1.set_bb(5678);
+ message1.SerializeToString(&data);
+ EXPECT_TRUE(message2.ParseFromString(data));
+ EXPECT_EQ(1234, message2.a());
+ EXPECT_EQ(5678, message2.bb());
+}
+
+TEST(GENERATED_MESSAGE_TEST_NAME, MutualRecursion) {
+ // Test that mutually-recursive message types work.
+ UNITTEST::TestMutualRecursionA message;
+ UNITTEST::TestMutualRecursionA* nested = message.mutable_bb()->mutable_a();
+ UNITTEST::TestMutualRecursionA* nested2 = nested->mutable_bb()->mutable_a();
+
+ // Again, if the above compiles and runs, that's all we really have to
+ // test, but just for run we'll check that the system didn't somehow come
+ // up with a pointer loop...
+ EXPECT_NE(&message, nested);
+ EXPECT_NE(&message, nested2);
+ EXPECT_NE(nested, nested2);
+}
+
+TEST(GENERATED_MESSAGE_TEST_NAME, CamelCaseFieldNames) {
+ // This test is mainly checking that the following compiles, which verifies
+ // that the field names were coerced to lower-case.
+ //
+ // Protocol buffers standard style is to use lowercase-with-underscores for
+ // field names. Some old proto1 .protos unfortunately used camel-case field
+ // names. In proto1, these names were forced to lower-case. So, we do the
+ // same thing in proto2.
+
+ UNITTEST::TestCamelCaseFieldNames message;
+
+ message.set_primitivefield(2);
+ message.set_stringfield("foo");
+ message.set_enumfield(UNITTEST::FOREIGN_FOO);
+ message.mutable_messagefield()->set_c(6);
+
+ message.add_repeatedprimitivefield(8);
+ message.add_repeatedstringfield("qux");
+ message.add_repeatedenumfield(UNITTEST::FOREIGN_BAR);
+ message.add_repeatedmessagefield()->set_c(15);
+
+ EXPECT_EQ(2, message.primitivefield());
+ EXPECT_EQ("foo", message.stringfield());
+ EXPECT_EQ(UNITTEST::FOREIGN_FOO, message.enumfield());
+ EXPECT_EQ(6, message.messagefield().c());
+
+ EXPECT_EQ(8, message.repeatedprimitivefield(0));
+ EXPECT_EQ("qux", message.repeatedstringfield(0));
+ EXPECT_EQ(UNITTEST::FOREIGN_BAR, message.repeatedenumfield(0));
+ EXPECT_EQ(15, message.repeatedmessagefield(0).c());
+}
+
+#ifndef PROTOBUF_TEST_NO_DESCRIPTORS
+
+TEST(GENERATED_MESSAGE_TEST_NAME, TestOptimizedForSize) {
+ // We rely on the tests in reflection_ops_unittest and wire_format_unittest
+ // to really test that reflection-based methods work. Here we are mostly
+ // just making sure that TestOptimizedForSize actually builds and seems to
+ // function.
+
+ UNITTEST::TestOptimizedForSize message, message2;
+ message.set_i(1);
+ message.mutable_msg()->set_c(2);
+ message2.CopyFrom(message);
+ EXPECT_EQ(1, message2.i());
+ EXPECT_EQ(2, message2.msg().c());
+}
+
+TEST(GENERATED_MESSAGE_TEST_NAME, TestEmbedOptimizedForSize) {
+ // Verifies that something optimized for speed can contain something optimized
+ // for size.
+
+ UNITTEST::TestEmbedOptimizedForSize message, message2;
+ message.mutable_optional_message()->set_i(1);
+ message.add_repeated_message()->mutable_msg()->set_c(2);
+ std::string data;
+ message.SerializeToString(&data);
+ ASSERT_TRUE(message2.ParseFromString(data));
+ EXPECT_EQ(1, message2.optional_message().i());
+ EXPECT_EQ(2, message2.repeated_message(0).msg().c());
+}
+
+TEST(GENERATED_MESSAGE_TEST_NAME, TestSpaceUsed) {
+ UNITTEST::TestAllTypes message1;
+ // sizeof provides a lower bound on SpaceUsedLong().
+ EXPECT_LE(sizeof(UNITTEST::TestAllTypes), message1.SpaceUsedLong());
+ const size_t empty_message_size = message1.SpaceUsedLong();
+
+ // Setting primitive types shouldn't affect the space used.
+ message1.set_optional_int32(123);
+ message1.set_optional_int64(12345);
+ message1.set_optional_uint32(123);
+ message1.set_optional_uint64(12345);
+ EXPECT_EQ(empty_message_size, message1.SpaceUsedLong());
+
+ // On some STL implementations, setting the string to a small value should
+ // only increase SpaceUsedLong() by the size of a string object, though this
+ // is not true everywhere.
+ message1.set_optional_string("abc");
+ EXPECT_LE(empty_message_size + message1.optional_string().size(),
+ message1.SpaceUsedLong());
+
+ // Setting a string to a value larger than the string object itself should
+ // increase SpaceUsedLong(), because it cannot store the value internally.
+ message1.set_optional_string(std::string(sizeof(std::string) + 1, 'x'));
+ int min_expected_increase = message1.optional_string().capacity();
+ EXPECT_LE(empty_message_size + min_expected_increase,
+ message1.SpaceUsedLong());
+
+ size_t previous_size = message1.SpaceUsedLong();
+ // Adding an optional message should increase the size by the size of the
+ // nested message type. NestedMessage is simple enough (1 int field) that it
+ // is equal to sizeof(NestedMessage)
+ message1.mutable_optional_nested_message();
+ ASSERT_EQ(sizeof(UNITTEST::TestAllTypes::NestedMessage),
+ message1.optional_nested_message().SpaceUsedLong());
+ EXPECT_EQ(previous_size +
+ sizeof(UNITTEST::TestAllTypes::NestedMessage),
+ message1.SpaceUsedLong());
+}
+
+TEST(GENERATED_MESSAGE_TEST_NAME, TestOneofSpaceUsed) {
+ UNITTEST::TestOneof2 message1;
+ EXPECT_LE(sizeof(UNITTEST::TestOneof2), message1.SpaceUsedLong());
+
+ const size_t empty_message_size = message1.SpaceUsedLong();
+ // Setting primitive types shouldn't affect the space used.
+ message1.set_foo_int(123);
+ message1.set_bar_int(12345);
+ EXPECT_EQ(empty_message_size, message1.SpaceUsedLong());
+
+ // Setting a string in oneof to a small value should only increase
+ // SpaceUsedLong() by the size of a string object.
+ message1.set_foo_string("abc");
+ EXPECT_LE(empty_message_size + sizeof(std::string), message1.SpaceUsedLong());
+
+ // Setting a string in oneof to a value larger than the string object itself
+ // should increase SpaceUsedLong(), because it cannot store the value
+ // internally.
+ message1.set_foo_string(std::string(sizeof(std::string) + 1, 'x'));
+ int min_expected_increase =
+ message1.foo_string().capacity() + sizeof(std::string);
+ EXPECT_LE(empty_message_size + min_expected_increase,
+ message1.SpaceUsedLong());
+
+ // Setting a message in oneof should delete the other fields and increase the
+ // size by the size of the nested message type. NestedMessage is simple enough
+ // that it is equal to sizeof(NestedMessage). It may be backed by LazyField,
+ // increasing space used by LazyField and backing Cord.
+ message1.mutable_foo_message();
+ ASSERT_EQ(sizeof(UNITTEST::TestOneof2::NestedMessage),
+ message1.foo_message().SpaceUsedLong());
+ EXPECT_LE(empty_message_size + sizeof(UNITTEST::TestOneof2::NestedMessage),
+ message1.SpaceUsedLong());
+}
+
+#endif // !PROTOBUF_TEST_NO_DESCRIPTORS
+
+
+TEST(GENERATED_MESSAGE_TEST_NAME, FieldConstantValues) {
+ UNITTEST::TestRequired message;
+ EXPECT_EQ(UNITTEST::TestAllTypes_NestedMessage::kBbFieldNumber, 1);
+ EXPECT_EQ(UNITTEST::TestAllTypes::kOptionalInt32FieldNumber, 1);
+ EXPECT_EQ(UNITTEST::TestAllTypes::kOptionalgroupFieldNumber, 16);
+ EXPECT_EQ(UNITTEST::TestAllTypes::kOptionalNestedMessageFieldNumber, 18);
+ EXPECT_EQ(UNITTEST::TestAllTypes::kOptionalNestedEnumFieldNumber, 21);
+ EXPECT_EQ(UNITTEST::TestAllTypes::kRepeatedInt32FieldNumber, 31);
+ EXPECT_EQ(UNITTEST::TestAllTypes::kRepeatedgroupFieldNumber, 46);
+ EXPECT_EQ(UNITTEST::TestAllTypes::kRepeatedNestedMessageFieldNumber, 48);
+ EXPECT_EQ(UNITTEST::TestAllTypes::kRepeatedNestedEnumFieldNumber, 51);
+}
+
+TEST(GENERATED_MESSAGE_TEST_NAME, ExtensionConstantValues) {
+ EXPECT_EQ(UNITTEST::TestRequired::kSingleFieldNumber, 1000);
+ EXPECT_EQ(UNITTEST::TestRequired::kMultiFieldNumber, 1001);
+ EXPECT_EQ(UNITTEST::kOptionalInt32ExtensionFieldNumber, 1);
+ EXPECT_EQ(UNITTEST::kOptionalgroupExtensionFieldNumber, 16);
+ EXPECT_EQ(UNITTEST::kOptionalNestedMessageExtensionFieldNumber, 18);
+ EXPECT_EQ(UNITTEST::kOptionalNestedEnumExtensionFieldNumber, 21);
+ EXPECT_EQ(UNITTEST::kRepeatedInt32ExtensionFieldNumber, 31);
+ EXPECT_EQ(UNITTEST::kRepeatedgroupExtensionFieldNumber, 46);
+ EXPECT_EQ(UNITTEST::kRepeatedNestedMessageExtensionFieldNumber, 48);
+ EXPECT_EQ(UNITTEST::kRepeatedNestedEnumExtensionFieldNumber, 51);
+}
+
+TEST(GENERATED_MESSAGE_TEST_NAME, ParseFromTruncated) {
+ const std::string long_string = std::string(128, 'q');
+ FileDescriptorProto p;
+ p.add_extension()->set_name(long_string);
+ const std::string msg = p.SerializeAsString();
+ int successful_count = 0;
+ for (int i = 0; i <= msg.size(); i++) {
+ if (p.ParseFromArray(msg.c_str(), i)) {
+ ++successful_count;
+ }
+ }
+ // We don't really care about how often we succeeded.
+ // As long as we didn't crash, we're happy.
+ EXPECT_GE(successful_count, 1);
+}
+
+// ===================================================================
+
+TEST(GENERATED_ENUM_TEST_NAME, EnumValuesAsSwitchCases) {
+ // Test that our nested enum values can be used as switch cases. This test
+ // doesn't actually do anything, the proof that it works is that it
+ // compiles.
+ int i =0;
+ UNITTEST::TestAllTypes::NestedEnum a = UNITTEST::TestAllTypes::BAR;
+ switch (a) {
+ case UNITTEST::TestAllTypes::FOO:
+ i = 1;
+ break;
+ case UNITTEST::TestAllTypes::BAR:
+ i = 2;
+ break;
+ case UNITTEST::TestAllTypes::BAZ:
+ i = 3;
+ break;
+ case UNITTEST::TestAllTypes::NEG:
+ i = -1;
+ break;
+ // no default case: We want to make sure the compiler recognizes that
+ // all cases are covered. (GCC warns if you do not cover all cases of
+ // an enum in a switch.)
+ }
+
+ // Token check just for fun.
+ EXPECT_EQ(2, i);
+}
+
+TEST(GENERATED_ENUM_TEST_NAME, IsValidValue) {
+ // Test enum IsValidValue.
+ EXPECT_TRUE(UNITTEST::TestAllTypes::NestedEnum_IsValid(1));
+ EXPECT_TRUE(UNITTEST::TestAllTypes::NestedEnum_IsValid(2));
+ EXPECT_TRUE(UNITTEST::TestAllTypes::NestedEnum_IsValid(3));
+
+ EXPECT_FALSE(UNITTEST::TestAllTypes::NestedEnum_IsValid(0));
+ EXPECT_FALSE(UNITTEST::TestAllTypes::NestedEnum_IsValid(4));
+
+ // Make sure it also works when there are dups.
+ EXPECT_TRUE(UNITTEST::TestEnumWithDupValue_IsValid(1));
+ EXPECT_TRUE(UNITTEST::TestEnumWithDupValue_IsValid(2));
+ EXPECT_TRUE(UNITTEST::TestEnumWithDupValue_IsValid(3));
+
+ EXPECT_FALSE(UNITTEST::TestEnumWithDupValue_IsValid(0));
+ EXPECT_FALSE(UNITTEST::TestEnumWithDupValue_IsValid(4));
+}
+
+TEST(GENERATED_ENUM_TEST_NAME, MinAndMax) {
+ EXPECT_EQ(UNITTEST::TestAllTypes::NEG,
+ UNITTEST::TestAllTypes::NestedEnum_MIN);
+ EXPECT_EQ(UNITTEST::TestAllTypes::BAZ,
+ UNITTEST::TestAllTypes::NestedEnum_MAX);
+ EXPECT_EQ(4, UNITTEST::TestAllTypes::NestedEnum_ARRAYSIZE);
+
+ EXPECT_EQ(UNITTEST::FOREIGN_FOO, UNITTEST::ForeignEnum_MIN);
+ EXPECT_EQ(UNITTEST::FOREIGN_BAZ, UNITTEST::ForeignEnum_MAX);
+ EXPECT_EQ(7, UNITTEST::ForeignEnum_ARRAYSIZE);
+
+ EXPECT_EQ(1, UNITTEST::TestEnumWithDupValue_MIN);
+ EXPECT_EQ(3, UNITTEST::TestEnumWithDupValue_MAX);
+ EXPECT_EQ(4, UNITTEST::TestEnumWithDupValue_ARRAYSIZE);
+
+ EXPECT_EQ(UNITTEST::SPARSE_E, UNITTEST::TestSparseEnum_MIN);
+ EXPECT_EQ(UNITTEST::SPARSE_C, UNITTEST::TestSparseEnum_MAX);
+ EXPECT_EQ(12589235, UNITTEST::TestSparseEnum_ARRAYSIZE);
+
+ // Make sure we can take the address of _MIN, _MAX and _ARRAYSIZE.
+ void* null_pointer = 0; // NULL may be integer-type, not pointer-type.
+ EXPECT_NE(null_pointer, &UNITTEST::TestAllTypes::NestedEnum_MIN);
+ EXPECT_NE(null_pointer, &UNITTEST::TestAllTypes::NestedEnum_MAX);
+ EXPECT_NE(null_pointer, &UNITTEST::TestAllTypes::NestedEnum_ARRAYSIZE);
+
+ EXPECT_NE(null_pointer, &UNITTEST::ForeignEnum_MIN);
+ EXPECT_NE(null_pointer, &UNITTEST::ForeignEnum_MAX);
+ EXPECT_NE(null_pointer, &UNITTEST::ForeignEnum_ARRAYSIZE);
+
+ // Make sure we can use _MIN and _MAX as switch cases.
+ switch (UNITTEST::SPARSE_A) {
+ case UNITTEST::TestSparseEnum_MIN:
+ case UNITTEST::TestSparseEnum_MAX:
+ break;
+ default:
+ break;
+ }
+}
+
+#ifndef PROTOBUF_TEST_NO_DESCRIPTORS
+
+TEST(GENERATED_ENUM_TEST_NAME, Name) {
+ // "Names" in the presence of dup values map to the first alias.
+ EXPECT_EQ("FOO1", UNITTEST::TestEnumWithDupValue_Name(UNITTEST::FOO1));
+ EXPECT_EQ("FOO1", UNITTEST::TestEnumWithDupValue_Name(UNITTEST::FOO2));
+
+ EXPECT_EQ("SPARSE_A", UNITTEST::TestSparseEnum_Name(UNITTEST::SPARSE_A));
+ EXPECT_EQ("SPARSE_B", UNITTEST::TestSparseEnum_Name(UNITTEST::SPARSE_B));
+ EXPECT_EQ("SPARSE_C", UNITTEST::TestSparseEnum_Name(UNITTEST::SPARSE_C));
+ EXPECT_EQ("SPARSE_D", UNITTEST::TestSparseEnum_Name(UNITTEST::SPARSE_D));
+ EXPECT_EQ("SPARSE_E", UNITTEST::TestSparseEnum_Name(UNITTEST::SPARSE_E));
+ EXPECT_EQ("SPARSE_F", UNITTEST::TestSparseEnum_Name(UNITTEST::SPARSE_F));
+ EXPECT_EQ("SPARSE_G", UNITTEST::TestSparseEnum_Name(UNITTEST::SPARSE_G));
+}
+
+TEST(GENERATED_ENUM_TEST_NAME, Parse) {
+ UNITTEST::TestEnumWithDupValue dup_value = UNITTEST::FOO1;
+ EXPECT_TRUE(UNITTEST::TestEnumWithDupValue_Parse("FOO1", &dup_value));
+ EXPECT_EQ(UNITTEST::FOO1, dup_value);
+ EXPECT_TRUE(UNITTEST::TestEnumWithDupValue_Parse("FOO2", &dup_value));
+ EXPECT_EQ(UNITTEST::FOO2, dup_value);
+ EXPECT_FALSE(UNITTEST::TestEnumWithDupValue_Parse("FOO", &dup_value));
+}
+
+TEST(GENERATED_ENUM_TEST_NAME, GetEnumDescriptor) {
+ EXPECT_EQ(UNITTEST::TestAllTypes::NestedEnum_descriptor(),
+ GetEnumDescriptor<UNITTEST::TestAllTypes::NestedEnum>());
+ EXPECT_EQ(UNITTEST::ForeignEnum_descriptor(),
+ GetEnumDescriptor<UNITTEST::ForeignEnum>());
+ EXPECT_EQ(UNITTEST::TestEnumWithDupValue_descriptor(),
+ GetEnumDescriptor<UNITTEST::TestEnumWithDupValue>());
+ EXPECT_EQ(UNITTEST::TestSparseEnum_descriptor(),
+ GetEnumDescriptor<UNITTEST::TestSparseEnum>());
+}
+
+enum NonProtoEnum {
+ kFoo = 1,
+};
+
+TEST(GENERATED_ENUM_TEST_NAME, IsProtoEnumTypeTrait) {
+ EXPECT_TRUE(is_proto_enum<UNITTEST::TestAllTypes::NestedEnum>::value);
+ EXPECT_TRUE(is_proto_enum<UNITTEST::ForeignEnum>::value);
+ EXPECT_TRUE(is_proto_enum<UNITTEST::TestEnumWithDupValue>::value);
+ EXPECT_TRUE(is_proto_enum<UNITTEST::TestSparseEnum>::value);
+
+ EXPECT_FALSE(is_proto_enum<int>::value);
+ EXPECT_FALSE(is_proto_enum<NonProtoEnum>::value);
+}
+
+#endif // PROTOBUF_TEST_NO_DESCRIPTORS
+
+// ===================================================================
+
+#ifndef PROTOBUF_TEST_NO_DESCRIPTORS
+
+// Support code for testing services.
+class GENERATED_SERVICE_TEST_NAME : public testing::Test {
+ protected:
+ class MockTestService : public UNITTEST::TestService {
+ public:
+ MockTestService()
+ : called_(false),
+ method_(""),
+ controller_(NULL),
+ request_(NULL),
+ response_(NULL),
+ done_(NULL) {}
+
+ ~MockTestService() {}
+
+ void Reset() { called_ = false; }
+
+ // implements TestService ----------------------------------------
+
+ void Foo(RpcController* controller, const UNITTEST::FooRequest* request,
+ UNITTEST::FooResponse* response, Closure* done) override {
+ ASSERT_FALSE(called_);
+ called_ = true;
+ method_ = "Foo";
+ controller_ = controller;
+ request_ = request;
+ response_ = response;
+ done_ = done;
+ }
+
+ void Bar(RpcController* controller, const UNITTEST::BarRequest* request,
+ UNITTEST::BarResponse* response, Closure* done) override {
+ ASSERT_FALSE(called_);
+ called_ = true;
+ method_ = "Bar";
+ controller_ = controller;
+ request_ = request;
+ response_ = response;
+ done_ = done;
+ }
+
+ // ---------------------------------------------------------------
+
+ bool called_;
+ std::string method_;
+ RpcController* controller_;
+ const Message* request_;
+ Message* response_;
+ Closure* done_;
+ };
+
+ class MockRpcChannel : public RpcChannel {
+ public:
+ MockRpcChannel()
+ : called_(false),
+ method_(NULL),
+ controller_(NULL),
+ request_(NULL),
+ response_(NULL),
+ done_(NULL),
+ destroyed_(NULL) {}
+
+ ~MockRpcChannel() {
+ if (destroyed_ != NULL) *destroyed_ = true;
+ }
+
+ void Reset() { called_ = false; }
+
+ // implements TestService ----------------------------------------
+
+ void CallMethod(const MethodDescriptor* method, RpcController* controller,
+ const Message* request, Message* response,
+ Closure* done) override {
+ ASSERT_FALSE(called_);
+ called_ = true;
+ method_ = method;
+ controller_ = controller;
+ request_ = request;
+ response_ = response;
+ done_ = done;
+ }
+
+ // ---------------------------------------------------------------
+
+ bool called_;
+ const MethodDescriptor* method_;
+ RpcController* controller_;
+ const Message* request_;
+ Message* response_;
+ Closure* done_;
+ bool* destroyed_;
+ };
+
+ class MockController : public RpcController {
+ public:
+ void Reset() override {
+ ADD_FAILURE() << "Reset() not expected during this test.";
+ }
+ bool Failed() const override {
+ ADD_FAILURE() << "Failed() not expected during this test.";
+ return false;
+ }
+ std::string ErrorText() const override {
+ ADD_FAILURE() << "ErrorText() not expected during this test.";
+ return "";
+ }
+ void StartCancel() override {
+ ADD_FAILURE() << "StartCancel() not expected during this test.";
+ }
+ void SetFailed(const std::string& reason) override {
+ ADD_FAILURE() << "SetFailed() not expected during this test.";
+ }
+ bool IsCanceled() const override {
+ ADD_FAILURE() << "IsCanceled() not expected during this test.";
+ return false;
+ }
+ void NotifyOnCancel(Closure* callback) override {
+ ADD_FAILURE() << "NotifyOnCancel() not expected during this test.";
+ }
+ };
+
+ GENERATED_SERVICE_TEST_NAME()
+ : descriptor_(UNITTEST::TestService::descriptor()),
+ foo_(descriptor_->FindMethodByName("Foo")),
+ bar_(descriptor_->FindMethodByName("Bar")),
+ stub_(&mock_channel_),
+ done_(::google::protobuf::NewPermanentCallback(&DoNothing)) {}
+
+ void SetUp() override {
+ ASSERT_TRUE(foo_ != NULL);
+ ASSERT_TRUE(bar_ != NULL);
+ }
+
+ const ServiceDescriptor* descriptor_;
+ const MethodDescriptor* foo_;
+ const MethodDescriptor* bar_;
+
+ MockTestService mock_service_;
+ MockController mock_controller_;
+
+ MockRpcChannel mock_channel_;
+ UNITTEST::TestService::Stub stub_;
+
+ // Just so we don't have to re-define these with every test.
+ UNITTEST::FooRequest foo_request_;
+ UNITTEST::FooResponse foo_response_;
+ UNITTEST::BarRequest bar_request_;
+ UNITTEST::BarResponse bar_response_;
+ std::unique_ptr<Closure> done_;
+};
+
+TEST_F(GENERATED_SERVICE_TEST_NAME, GetDescriptor) {
+ // Test that GetDescriptor() works.
+
+ EXPECT_EQ(descriptor_, mock_service_.GetDescriptor());
+}
+
+TEST_F(GENERATED_SERVICE_TEST_NAME, GetChannel) {
+ EXPECT_EQ(&mock_channel_, stub_.channel());
+}
+
+TEST_F(GENERATED_SERVICE_TEST_NAME, OwnsChannel) {
+ MockRpcChannel* channel = new MockRpcChannel;
+ bool destroyed = false;
+ channel->destroyed_ = &destroyed;
+
+ {
+ UNITTEST::TestService::Stub owning_stub(channel,
+ Service::STUB_OWNS_CHANNEL);
+ EXPECT_FALSE(destroyed);
+ }
+
+ EXPECT_TRUE(destroyed);
+}
+
+TEST_F(GENERATED_SERVICE_TEST_NAME, CallMethod) {
+ // Test that CallMethod() works.
+
+ // Call Foo() via CallMethod().
+ mock_service_.CallMethod(foo_, &mock_controller_,
+ &foo_request_, &foo_response_, done_.get());
+
+ ASSERT_TRUE(mock_service_.called_);
+
+ EXPECT_EQ("Foo" , mock_service_.method_ );
+ EXPECT_EQ(&mock_controller_, mock_service_.controller_);
+ EXPECT_EQ(&foo_request_ , mock_service_.request_ );
+ EXPECT_EQ(&foo_response_ , mock_service_.response_ );
+ EXPECT_EQ(done_.get() , mock_service_.done_ );
+
+ // Try again, but call Bar() instead.
+ mock_service_.Reset();
+ mock_service_.CallMethod(bar_, &mock_controller_,
+ &bar_request_, &bar_response_, done_.get());
+
+ ASSERT_TRUE(mock_service_.called_);
+ EXPECT_EQ("Bar", mock_service_.method_);
+}
+
+TEST_F(GENERATED_SERVICE_TEST_NAME, CallMethodTypeFailure) {
+ // Verify death if we call Foo() with Bar's message types.
+
+#ifdef PROTOBUF_HAS_DEATH_TEST // death tests do not work on Windows yet
+ EXPECT_DEBUG_DEATH(
+ mock_service_.CallMethod(foo_, &mock_controller_,
+ &foo_request_, &bar_response_, done_.get()),
+ "dynamic_cast");
+
+ mock_service_.Reset();
+ EXPECT_DEBUG_DEATH(
+ mock_service_.CallMethod(foo_, &mock_controller_,
+ &bar_request_, &foo_response_, done_.get()),
+ "dynamic_cast");
+#endif // PROTOBUF_HAS_DEATH_TEST
+}
+
+TEST_F(GENERATED_SERVICE_TEST_NAME, GetPrototypes) {
+ // Test Get{Request,Response}Prototype() methods.
+
+ EXPECT_EQ(&UNITTEST::FooRequest::default_instance(),
+ &mock_service_.GetRequestPrototype(foo_));
+ EXPECT_EQ(&UNITTEST::BarRequest::default_instance(),
+ &mock_service_.GetRequestPrototype(bar_));
+
+ EXPECT_EQ(&UNITTEST::FooResponse::default_instance(),
+ &mock_service_.GetResponsePrototype(foo_));
+ EXPECT_EQ(&UNITTEST::BarResponse::default_instance(),
+ &mock_service_.GetResponsePrototype(bar_));
+}
+
+TEST_F(GENERATED_SERVICE_TEST_NAME, Stub) {
+ // Test that the stub class works.
+
+ // Call Foo() via the stub.
+ stub_.Foo(&mock_controller_, &foo_request_, &foo_response_, done_.get());
+
+ ASSERT_TRUE(mock_channel_.called_);
+
+ EXPECT_EQ(foo_ , mock_channel_.method_ );
+ EXPECT_EQ(&mock_controller_, mock_channel_.controller_);
+ EXPECT_EQ(&foo_request_ , mock_channel_.request_ );
+ EXPECT_EQ(&foo_response_ , mock_channel_.response_ );
+ EXPECT_EQ(done_.get() , mock_channel_.done_ );
+
+ // Call Bar() via the stub.
+ mock_channel_.Reset();
+ stub_.Bar(&mock_controller_, &bar_request_, &bar_response_, done_.get());
+
+ ASSERT_TRUE(mock_channel_.called_);
+ EXPECT_EQ(bar_, mock_channel_.method_);
+}
+
+TEST_F(GENERATED_SERVICE_TEST_NAME, NotImplemented) {
+ // Test that failing to implement a method of a service causes it to fail
+ // with a "not implemented" error message.
+
+ // A service which doesn't implement any methods.
+ class UnimplementedService : public UNITTEST::TestService {
+ public:
+ UnimplementedService() {}
+ };
+
+ UnimplementedService unimplemented_service;
+
+ // And a controller which expects to get a "not implemented" error.
+ class ExpectUnimplementedController : public MockController {
+ public:
+ ExpectUnimplementedController() : called_(false) {}
+
+ void SetFailed(const std::string& reason) override {
+ EXPECT_FALSE(called_);
+ called_ = true;
+ EXPECT_EQ("Method Foo() not implemented.", reason);
+ }
+
+ bool called_;
+ };
+
+ ExpectUnimplementedController controller;
+
+ // Call Foo.
+ unimplemented_service.Foo(&controller, &foo_request_, &foo_response_,
+ done_.get());
+
+ EXPECT_TRUE(controller.called_);
+}
+
+// ===================================================================
+
+class OneofTest : public testing::Test {
+ protected:
+ void SetUp() override {}
+
+ void ExpectEnumCasesWork(const UNITTEST::TestOneof2 &message) {
+ switch (message.foo_case()) {
+ case UNITTEST::TestOneof2::kFooInt:
+ EXPECT_TRUE(message.has_foo_int());
+ break;
+ case UNITTEST::TestOneof2::kFooString:
+ EXPECT_TRUE(message.has_foo_string());
+ break;
+ case UNITTEST::TestOneof2::kFooCord:
+ EXPECT_TRUE(message.has_foo_cord());
+ break;
+ case UNITTEST::TestOneof2::kFooStringPiece:
+ EXPECT_TRUE(message.has_foo_string_piece());
+ break;
+ case UNITTEST::TestOneof2::kFooBytes:
+ EXPECT_TRUE(message.has_foo_bytes());
+ break;
+ case UNITTEST::TestOneof2::kFooEnum:
+ EXPECT_TRUE(message.has_foo_enum());
+ break;
+ case UNITTEST::TestOneof2::kFooMessage:
+ EXPECT_TRUE(message.has_foo_message());
+ break;
+ case UNITTEST::TestOneof2::kFoogroup:
+ EXPECT_TRUE(message.has_foogroup());
+ break;
+ case UNITTEST::TestOneof2::kFooLazyMessage:
+ EXPECT_TRUE(message.has_foo_lazy_message());
+ break;
+ case UNITTEST::TestOneof2::FOO_NOT_SET:
+ break;
+ }
+ }
+};
+
+TEST_F(OneofTest, SettingOneFieldClearsOthers) {
+ UNITTEST::TestOneof2 message;
+
+ message.set_foo_int(123);
+ EXPECT_TRUE(message.has_foo_int());
+ TestUtil::ExpectAtMostOneFieldSetInOneof(message);
+
+ message.set_foo_string("foo");
+ EXPECT_TRUE(message.has_foo_string());
+ TestUtil::ExpectAtMostOneFieldSetInOneof(message);
+
+
+ message.set_foo_bytes("qux");
+ EXPECT_TRUE(message.has_foo_bytes());
+ TestUtil::ExpectAtMostOneFieldSetInOneof(message);
+
+ message.set_foo_enum(UNITTEST::TestOneof2::FOO);
+ EXPECT_TRUE(message.has_foo_enum());
+ TestUtil::ExpectAtMostOneFieldSetInOneof(message);
+
+ message.mutable_foo_message()->set_qux_int(234);
+ EXPECT_TRUE(message.has_foo_message());
+ TestUtil::ExpectAtMostOneFieldSetInOneof(message);
+
+ message.mutable_foogroup()->set_a(345);
+ EXPECT_TRUE(message.has_foogroup());
+ TestUtil::ExpectAtMostOneFieldSetInOneof(message);
+
+
+ // we repeat this because we didn't test if this properly clears other fields
+ // at the beginning.
+ message.set_foo_int(123);
+ EXPECT_TRUE(message.has_foo_int());
+ TestUtil::ExpectAtMostOneFieldSetInOneof(message);
+}
+
+TEST_F(OneofTest, EnumCases) {
+ UNITTEST::TestOneof2 message;
+
+ message.set_foo_int(123);
+ ExpectEnumCasesWork(message);
+ message.set_foo_string("foo");
+ ExpectEnumCasesWork(message);
+ message.set_foo_bytes("qux");
+ ExpectEnumCasesWork(message);
+ message.set_foo_enum(UNITTEST::TestOneof2::FOO);
+ ExpectEnumCasesWork(message);
+ message.mutable_foo_message()->set_qux_int(234);
+ ExpectEnumCasesWork(message);
+ message.mutable_foogroup()->set_a(345);
+ ExpectEnumCasesWork(message);
+}
+
+TEST_F(OneofTest, PrimitiveType) {
+ UNITTEST::TestOneof2 message;
+ // Unset field returns default value
+ EXPECT_EQ(message.foo_int(), 0);
+
+ message.set_foo_int(123);
+ EXPECT_TRUE(message.has_foo_int());
+ EXPECT_EQ(message.foo_int(), 123);
+ message.clear_foo_int();
+ EXPECT_FALSE(message.has_foo_int());
+}
+
+TEST_F(OneofTest, EnumType) {
+ UNITTEST::TestOneof2 message;
+ // Unset field returns default value
+ EXPECT_EQ(message.foo_enum(), 1);
+
+ message.set_foo_enum(UNITTEST::TestOneof2::FOO);
+ EXPECT_TRUE(message.has_foo_enum());
+ EXPECT_EQ(message.foo_enum(), UNITTEST::TestOneof2::FOO);
+ message.clear_foo_enum();
+ EXPECT_FALSE(message.has_foo_enum());
+}
+
+TEST_F(OneofTest, SetString) {
+ // Check that setting a string field in various ways works
+ UNITTEST::TestOneof2 message;
+
+ // Unset field returns default value
+ EXPECT_EQ(message.foo_string(), "");
+
+ message.set_foo_string("foo");
+ EXPECT_TRUE(message.has_foo_string());
+ EXPECT_EQ(message.foo_string(), "foo");
+ message.clear_foo_string();
+ EXPECT_FALSE(message.has_foo_string());
+
+ message.set_foo_string(std::string("bar"));
+ EXPECT_TRUE(message.has_foo_string());
+ EXPECT_EQ(message.foo_string(), "bar");
+ message.clear_foo_string();
+ EXPECT_FALSE(message.has_foo_string());
+
+
+ message.set_foo_string("qux", 3);
+ EXPECT_TRUE(message.has_foo_string());
+ EXPECT_EQ(message.foo_string(), "qux");
+ message.clear_foo_string();
+ EXPECT_FALSE(message.has_foo_string());
+
+ message.mutable_foo_string()->assign("quux");
+ EXPECT_TRUE(message.has_foo_string());
+ EXPECT_EQ(message.foo_string(), "quux");
+ message.clear_foo_string();
+ EXPECT_FALSE(message.has_foo_string());
+
+ message.set_foo_string("corge");
+ EXPECT_TRUE(message.has_foo_string());
+ EXPECT_EQ(message.foo_string(), "corge");
+ message.clear_foo_string();
+ EXPECT_FALSE(message.has_foo_string());
+}
+
+TEST_F(OneofTest, ReleaseString) {
+ // Check that release_foo() starts out NULL, and gives us a value
+ // that we can delete after it's been set.
+ UNITTEST::TestOneof2 message;
+
+ EXPECT_EQ(NULL, message.release_foo_string());
+ EXPECT_FALSE(message.has_foo_string());
+
+ message.set_foo_string("blah");
+ EXPECT_TRUE(message.has_foo_string());
+ std::unique_ptr<std::string> str(message.release_foo_string());
+ EXPECT_FALSE(message.has_foo_string());
+ ASSERT_TRUE(str != NULL);
+ EXPECT_EQ("blah", *str);
+
+ EXPECT_EQ(NULL, message.release_foo_string());
+ EXPECT_FALSE(message.has_foo_string());
+}
+
+TEST_F(OneofTest, SetAllocatedString) {
+ // Check that set_allocated_foo() works for strings.
+ UNITTEST::TestOneof2 message;
+
+ EXPECT_FALSE(message.has_foo_string());
+ const std::string kHello("hello");
+ message.set_foo_string(kHello);
+ EXPECT_TRUE(message.has_foo_string());
+
+ message.set_allocated_foo_string(NULL);
+ EXPECT_FALSE(message.has_foo_string());
+ EXPECT_EQ("", message.foo_string());
+
+ message.set_allocated_foo_string(new std::string(kHello));
+ EXPECT_TRUE(message.has_foo_string());
+ EXPECT_EQ(kHello, message.foo_string());
+}
+
+TEST_F(OneofTest, ArenaSetAllocatedString) {
+ // Check that set_allocated_foo() works for strings.
+ Arena arena;
+ UNITTEST::TestOneof2* message =
+ Arena::CreateMessage<UNITTEST::TestOneof2>(&arena);
+
+ EXPECT_FALSE(message->has_foo_string());
+ const std::string kHello("hello");
+ message->set_foo_string(kHello);
+ EXPECT_TRUE(message->has_foo_string());
+
+ message->set_allocated_foo_string(NULL);
+ EXPECT_FALSE(message->has_foo_string());
+ EXPECT_EQ("", message->foo_string());
+
+ message->set_allocated_foo_string(new std::string(kHello));
+ EXPECT_TRUE(message->has_foo_string());
+ EXPECT_EQ(kHello, message->foo_string());
+}
+
+
+TEST_F(OneofTest, SetMessage) {
+ // Check that setting a message field works
+ UNITTEST::TestOneof2 message;
+
+ // Unset field returns default instance
+ EXPECT_EQ(&message.foo_message(),
+ &UNITTEST::TestOneof2_NestedMessage::default_instance());
+ EXPECT_EQ(message.foo_message().qux_int(), 0);
+
+ message.mutable_foo_message()->set_qux_int(234);
+ EXPECT_TRUE(message.has_foo_message());
+ EXPECT_EQ(message.foo_message().qux_int(), 234);
+ message.clear_foo_message();
+ EXPECT_FALSE(message.has_foo_message());
+}
+
+TEST_F(OneofTest, ReleaseMessage) {
+ // Check that release_foo() starts out NULL, and gives us a value
+ // that we can delete after it's been set.
+ UNITTEST::TestOneof2 message;
+
+ EXPECT_EQ(NULL, message.release_foo_message());
+ EXPECT_FALSE(message.has_foo_message());
+
+ message.mutable_foo_message()->set_qux_int(1);
+ EXPECT_TRUE(message.has_foo_message());
+ std::unique_ptr<UNITTEST::TestOneof2_NestedMessage> mes(
+ message.release_foo_message());
+ EXPECT_FALSE(message.has_foo_message());
+ ASSERT_TRUE(mes != NULL);
+ EXPECT_EQ(1, mes->qux_int());
+
+ EXPECT_EQ(NULL, message.release_foo_message());
+ EXPECT_FALSE(message.has_foo_message());
+}
+
+TEST_F(OneofTest, SetAllocatedMessage) {
+ // Check that set_allocated_foo() works for messages.
+ UNITTEST::TestOneof2 message;
+
+ EXPECT_FALSE(message.has_foo_message());
+
+ message.mutable_foo_message()->set_qux_int(1);
+ EXPECT_TRUE(message.has_foo_message());
+
+ message.set_allocated_foo_message(NULL);
+ EXPECT_FALSE(message.has_foo_message());
+ EXPECT_EQ(&message.foo_message(),
+ &UNITTEST::TestOneof2_NestedMessage::default_instance());
+
+ message.mutable_foo_message()->set_qux_int(1);
+ UNITTEST::TestOneof2_NestedMessage* mes = message.release_foo_message();
+ ASSERT_TRUE(mes != NULL);
+ EXPECT_FALSE(message.has_foo_message());
+
+ message.set_allocated_foo_message(mes);
+ EXPECT_TRUE(message.has_foo_message());
+ EXPECT_EQ(1, message.foo_message().qux_int());
+}
+
+
+TEST_F(OneofTest, Clear) {
+ UNITTEST::TestOneof2 message;
+
+ message.set_foo_int(1);
+ EXPECT_TRUE(message.has_foo_int());
+ message.clear_foo_int();
+ EXPECT_FALSE(message.has_foo_int());
+}
+
+TEST_F(OneofTest, Defaults) {
+ UNITTEST::TestOneof2 message;
+
+ EXPECT_FALSE(message.has_foo_int());
+ EXPECT_EQ(message.foo_int(), 0);
+
+ EXPECT_FALSE(message.has_foo_string());
+ EXPECT_EQ(message.foo_string(), "");
+
+
+ EXPECT_FALSE(message.has_foo_bytes());
+ EXPECT_EQ(message.foo_bytes(), "");
+
+ EXPECT_FALSE(message.has_foo_enum());
+ EXPECT_EQ(message.foo_enum(), 1);
+
+ EXPECT_FALSE(message.has_foo_message());
+ EXPECT_EQ(message.foo_message().qux_int(), 0);
+
+ EXPECT_FALSE(message.has_foogroup());
+ EXPECT_EQ(message.foogroup().a(), 0);
+
+
+ EXPECT_FALSE(message.has_bar_int());
+ EXPECT_EQ(message.bar_int(), 5);
+
+ EXPECT_FALSE(message.has_bar_string());
+ EXPECT_EQ(message.bar_string(), "STRING");
+
+
+ EXPECT_FALSE(message.has_bar_bytes());
+ EXPECT_EQ(message.bar_bytes(), "BYTES");
+
+ EXPECT_FALSE(message.has_bar_enum());
+ EXPECT_EQ(message.bar_enum(), 2);
+}
+
+TEST_F(OneofTest, SwapWithEmpty) {
+ UNITTEST::TestOneof2 message1, message2;
+ message1.set_foo_string("FOO");
+ EXPECT_TRUE(message1.has_foo_string());
+ message1.Swap(&message2);
+ EXPECT_FALSE(message1.has_foo_string());
+ EXPECT_TRUE(message2.has_foo_string());
+ EXPECT_EQ(message2.foo_string(), "FOO");
+}
+
+TEST_F(OneofTest, SwapWithSelf) {
+ UNITTEST::TestOneof2 message;
+ message.set_foo_string("FOO");
+ EXPECT_TRUE(message.has_foo_string());
+ message.Swap(&message);
+ EXPECT_TRUE(message.has_foo_string());
+ EXPECT_EQ(message.foo_string(), "FOO");
+}
+
+TEST_F(OneofTest, SwapBothHasFields) {
+ UNITTEST::TestOneof2 message1, message2;
+
+ message1.set_foo_string("FOO");
+ EXPECT_TRUE(message1.has_foo_string());
+ message2.mutable_foo_message()->set_qux_int(1);
+ EXPECT_TRUE(message2.has_foo_message());
+
+ message1.Swap(&message2);
+ EXPECT_FALSE(message1.has_foo_string());
+ EXPECT_FALSE(message2.has_foo_message());
+ EXPECT_TRUE(message1.has_foo_message());
+ EXPECT_EQ(message1.foo_message().qux_int(), 1);
+ EXPECT_TRUE(message2.has_foo_string());
+ EXPECT_EQ(message2.foo_string(), "FOO");
+}
+
+TEST_F(OneofTest, CopyConstructor) {
+ UNITTEST::TestOneof2 message1;
+ message1.set_foo_bytes("FOO");
+
+ UNITTEST::TestOneof2 message2(message1);
+ EXPECT_TRUE(message2.has_foo_bytes());
+ EXPECT_EQ(message2.foo_bytes(), "FOO");
+}
+
+TEST_F(OneofTest, CopyFrom) {
+ UNITTEST::TestOneof2 message1, message2;
+ message1.set_foo_enum(UNITTEST::TestOneof2::BAR);
+ EXPECT_TRUE(message1.has_foo_enum());
+
+ message2.CopyFrom(message1);
+ EXPECT_TRUE(message2.has_foo_enum());
+ EXPECT_EQ(message2.foo_enum(), UNITTEST::TestOneof2::BAR);
+
+ // Copying from self should be a no-op.
+ message2.CopyFrom(message2);
+ EXPECT_TRUE(message2.has_foo_enum());
+ EXPECT_EQ(message2.foo_enum(), UNITTEST::TestOneof2::BAR);
+}
+
+TEST_F(OneofTest, CopyAssignmentOperator) {
+ UNITTEST::TestOneof2 message1;
+ message1.mutable_foo_message()->set_qux_int(123);
+ EXPECT_TRUE(message1.has_foo_message());
+
+ UNITTEST::TestOneof2 message2;
+ message2 = message1;
+ EXPECT_EQ(message2.foo_message().qux_int(), 123);
+
+ // Make sure that self-assignment does something sane.
+ message2 = *&message2; // Avoid -Wself-assign.
+ EXPECT_EQ(message2.foo_message().qux_int(), 123);
+}
+
+TEST_F(OneofTest, UpcastCopyFrom) {
+ // Test the CopyFrom method that takes in the generic const Message&
+ // parameter.
+ UNITTEST::TestOneof2 message1, message2;
+ message1.mutable_foogroup()->set_a(123);
+ EXPECT_TRUE(message1.has_foogroup());
+
+ const Message* source = implicit_cast<const Message*>(&message1);
+ message2.CopyFrom(*source);
+
+ EXPECT_TRUE(message2.has_foogroup());
+ EXPECT_EQ(message2.foogroup().a(), 123);
+}
+
+// Test the generated SerializeWithCachedSizesToArray(),
+// This indirectly tests MergePartialFromCodedStream()
+// We have to test each field type separately because we cannot set them at the
+// same time
+TEST_F(OneofTest, SerializationToArray) {
+ // Primitive type
+ {
+ UNITTEST::TestOneof2 message1, message2;
+std::string data;
+message1.set_foo_int(123);
+int size = message1.ByteSizeLong();
+data.resize(size);
+uint8_t* start = reinterpret_cast<uint8_t*>(::google::protobuf::string_as_array(&data));
+uint8_t* end = message1.SerializeWithCachedSizesToArray(start);
+EXPECT_EQ(size, end - start);
+EXPECT_TRUE(message2.ParseFromString(data));
+EXPECT_EQ(message2.foo_int(), 123);
+ }
+
+ // String
+ {
+ UNITTEST::TestOneof2 message1, message2;
+ std::string data;
+ message1.set_foo_string("foo");
+ int size = message1.ByteSizeLong();
+ data.resize(size);
+ uint8_t* start = reinterpret_cast<uint8_t*>(::google::protobuf::string_as_array(&data));
+ uint8_t* end = message1.SerializeWithCachedSizesToArray(start);
+ EXPECT_EQ(size, end - start);
+ EXPECT_TRUE(message2.ParseFromString(data));
+ EXPECT_EQ(message2.foo_string(), "foo");
+ }
+
+
+ // Bytes
+ {
+ UNITTEST::TestOneof2 message1, message2;
+ std::string data;
+ message1.set_foo_bytes("qux");
+ int size = message1.ByteSizeLong();
+ data.resize(size);
+ uint8_t* start = reinterpret_cast<uint8_t*>(::google::protobuf::string_as_array(&data));
+ uint8_t* end = message1.SerializeWithCachedSizesToArray(start);
+ EXPECT_EQ(size, end - start);
+ EXPECT_TRUE(message2.ParseFromString(data));
+ EXPECT_EQ(message2.foo_bytes(), "qux");
+ }
+
+ // Enum
+ {
+ UNITTEST::TestOneof2 message1, message2;
+ std::string data;
+ message1.set_foo_enum(UNITTEST::TestOneof2::FOO);
+ int size = message1.ByteSizeLong();
+ data.resize(size);
+ uint8_t* start = reinterpret_cast<uint8_t*>(::google::protobuf::string_as_array(&data));
+ uint8_t* end = message1.SerializeWithCachedSizesToArray(start);
+ EXPECT_EQ(size, end - start);
+ EXPECT_TRUE(message2.ParseFromString(data));
+ EXPECT_EQ(message2.foo_enum(), UNITTEST::TestOneof2::FOO);
+ }
+
+ // Message
+ {
+ UNITTEST::TestOneof2 message1, message2;
+ std::string data;
+ message1.mutable_foo_message()->set_qux_int(234);
+ int size = message1.ByteSizeLong();
+ data.resize(size);
+ uint8_t* start = reinterpret_cast<uint8_t*>(::google::protobuf::string_as_array(&data));
+ uint8_t* end = message1.SerializeWithCachedSizesToArray(start);
+ EXPECT_EQ(size, end - start);
+ EXPECT_TRUE(message2.ParseFromString(data));
+ EXPECT_EQ(message2.foo_message().qux_int(), 234);
+ }
+
+ // Group
+ {
+ UNITTEST::TestOneof2 message1, message2;
+ std::string data;
+ message1.mutable_foogroup()->set_a(345);
+ int size = message1.ByteSizeLong();
+ data.resize(size);
+ uint8_t* start = reinterpret_cast<uint8_t*>(::google::protobuf::string_as_array(&data));
+ uint8_t* end = message1.SerializeWithCachedSizesToArray(start);
+ EXPECT_EQ(size, end - start);
+ EXPECT_TRUE(message2.ParseFromString(data));
+ EXPECT_EQ(message2.foogroup().a(), 345);
+ }
+
+}
+
+// Test the generated SerializeWithCachedSizes() by forcing the buffer to write
+// one byte at a time.
+// This indirectly tests MergePartialFromCodedStream()
+// We have to test each field type separately because we cannot set them at the
+// same time
+TEST_F(OneofTest, SerializationToStream) {
+ // Primitive type
+ {
+ UNITTEST::TestOneof2 message1, message2;
+std::string data;
+message1.set_foo_int(123);
+int size = message1.ByteSizeLong();
+data.resize(size);
+
+{
+ // Allow the output stream to buffer only one byte at a time.
+ io::ArrayOutputStream array_stream(::google::protobuf::string_as_array(&data), size, 1);
+ io::CodedOutputStream output_stream(&array_stream);
+ message1.SerializeWithCachedSizes(&output_stream);
+ EXPECT_FALSE(output_stream.HadError());
+ EXPECT_EQ(size, output_stream.ByteCount());
+}
+
+ EXPECT_TRUE(message2.ParseFromString(data));
+ EXPECT_EQ(message2.foo_int(), 123);
+ }
+
+ // String
+ {
+ UNITTEST::TestOneof2 message1, message2;
+ std::string data;
+ message1.set_foo_string("foo");
+ int size = message1.ByteSizeLong();
+ data.resize(size);
+
+ {
+ // Allow the output stream to buffer only one byte at a time.
+ io::ArrayOutputStream array_stream(::google::protobuf::string_as_array(&data), size, 1);
+ io::CodedOutputStream output_stream(&array_stream);
+ message1.SerializeWithCachedSizes(&output_stream);
+ EXPECT_FALSE(output_stream.HadError());
+ EXPECT_EQ(size, output_stream.ByteCount());
+ }
+
+ EXPECT_TRUE(message2.ParseFromString(data));
+ EXPECT_EQ(message2.foo_string(), "foo");
+ }
+
+
+ // Bytes
+ {
+ UNITTEST::TestOneof2 message1, message2;
+ std::string data;
+ message1.set_foo_bytes("qux");
+ int size = message1.ByteSizeLong();
+ data.resize(size);
+
+ {
+ // Allow the output stream to buffer only one byte at a time.
+ io::ArrayOutputStream array_stream(::google::protobuf::string_as_array(&data), size, 1);
+ io::CodedOutputStream output_stream(&array_stream);
+ message1.SerializeWithCachedSizes(&output_stream);
+ EXPECT_FALSE(output_stream.HadError());
+ EXPECT_EQ(size, output_stream.ByteCount());
+ }
+
+ EXPECT_TRUE(message2.ParseFromString(data));
+ EXPECT_EQ(message2.foo_bytes(), "qux");
+ }
+
+ // Enum
+ {
+ UNITTEST::TestOneof2 message1, message2;
+ std::string data;
+ message1.set_foo_enum(UNITTEST::TestOneof2::FOO);
+ int size = message1.ByteSizeLong();
+ data.resize(size);
+
+ {
+ // Allow the output stream to buffer only one byte at a time.
+ io::ArrayOutputStream array_stream(::google::protobuf::string_as_array(&data), size, 1);
+ io::CodedOutputStream output_stream(&array_stream);
+ message1.SerializeWithCachedSizes(&output_stream);
+ EXPECT_FALSE(output_stream.HadError());
+ EXPECT_EQ(size, output_stream.ByteCount());
+ }
+
+ EXPECT_TRUE(message2.ParseFromString(data));
+ EXPECT_EQ(message2.foo_enum(), UNITTEST::TestOneof2::FOO);
+ }
+
+ // Message
+ {
+ UNITTEST::TestOneof2 message1, message2;
+ std::string data;
+ message1.mutable_foo_message()->set_qux_int(234);
+ int size = message1.ByteSizeLong();
+ data.resize(size);
+
+ {
+ // Allow the output stream to buffer only one byte at a time.
+ io::ArrayOutputStream array_stream(::google::protobuf::string_as_array(&data), size, 1);
+ io::CodedOutputStream output_stream(&array_stream);
+ message1.SerializeWithCachedSizes(&output_stream);
+ EXPECT_FALSE(output_stream.HadError());
+ EXPECT_EQ(size, output_stream.ByteCount());
+ }
+
+ EXPECT_TRUE(message2.ParseFromString(data));
+ EXPECT_EQ(message2.foo_message().qux_int(), 234);
+ }
+
+ // Group
+ {
+ UNITTEST::TestOneof2 message1, message2;
+ std::string data;
+ message1.mutable_foogroup()->set_a(345);
+ int size = message1.ByteSizeLong();
+ data.resize(size);
+
+ {
+ // Allow the output stream to buffer only one byte at a time.
+ io::ArrayOutputStream array_stream(::google::protobuf::string_as_array(&data), size, 1);
+ io::CodedOutputStream output_stream(&array_stream);
+ message1.SerializeWithCachedSizes(&output_stream);
+ EXPECT_FALSE(output_stream.HadError());
+ EXPECT_EQ(size, output_stream.ByteCount());
+ }
+
+ EXPECT_TRUE(message2.ParseFromString(data));
+ EXPECT_EQ(message2.foogroup().a(), 345);
+ }
+
+}
+
+TEST_F(OneofTest, MergeFrom) {
+ UNITTEST::TestOneof2 message1, message2;
+
+ message1.set_foo_int(123);
+ message2.MergeFrom(message1);
+ TestUtil::ExpectAtMostOneFieldSetInOneof(message2);
+ EXPECT_TRUE(message2.has_foo_int());
+ EXPECT_EQ(message2.foo_int(), 123);
+
+ message1.set_foo_string("foo");
+ message2.MergeFrom(message1);
+ TestUtil::ExpectAtMostOneFieldSetInOneof(message2);
+ EXPECT_TRUE(message2.has_foo_string());
+ EXPECT_EQ(message2.foo_string(), "foo");
+
+
+ message1.set_foo_bytes("qux");
+ message2.MergeFrom(message1);
+ TestUtil::ExpectAtMostOneFieldSetInOneof(message2);
+ EXPECT_TRUE(message2.has_foo_bytes());
+ EXPECT_EQ(message2.foo_bytes(), "qux");
+
+ message1.set_foo_enum(UNITTEST::TestOneof2::FOO);
+ message2.MergeFrom(message1);
+ TestUtil::ExpectAtMostOneFieldSetInOneof(message2);
+ EXPECT_TRUE(message2.has_foo_enum());
+ EXPECT_EQ(message2.foo_enum(), UNITTEST::TestOneof2::FOO);
+
+ message1.mutable_foo_message()->set_qux_int(234);
+ message2.MergeFrom(message1);
+ TestUtil::ExpectAtMostOneFieldSetInOneof(message2);
+ EXPECT_TRUE(message2.has_foo_message());
+ EXPECT_EQ(message2.foo_message().qux_int(), 234);
+
+ message1.mutable_foogroup()->set_a(345);
+ message2.MergeFrom(message1);
+ TestUtil::ExpectAtMostOneFieldSetInOneof(message2);
+ EXPECT_TRUE(message2.has_foogroup());
+ EXPECT_EQ(message2.foogroup().a(), 345);
+
+}
+
+TEST(HELPERS_TEST_NAME, TestSCC) {
+ UNITTEST::TestMutualRecursionA a;
+ MessageSCCAnalyzer scc_analyzer((Options()));
+ const SCC* scc = scc_analyzer.GetSCC(a.GetDescriptor());
+ std::vector<std::string> names;
+ names.reserve(scc->descriptors.size());
+ for (int i = 0; i < scc->descriptors.size(); i++) {
+ names.push_back(scc->descriptors[i]->full_name());
+ }
+ std::string package = a.GetDescriptor()->file()->package();
+ ASSERT_EQ(names.size(), 4);
+ std::sort(names.begin(), names.end());
+ EXPECT_EQ(names[0], package + ".TestMutualRecursionA");
+ EXPECT_EQ(names[1], package + ".TestMutualRecursionA.SubGroup");
+ EXPECT_EQ(names[2], package + ".TestMutualRecursionA.SubMessage");
+ EXPECT_EQ(names[3], package + ".TestMutualRecursionB");
+
+ MessageAnalysis result = scc_analyzer.GetSCCAnalysis(scc);
+ EXPECT_EQ(result.is_recursive, true);
+ EXPECT_EQ(result.contains_required, false);
+ EXPECT_EQ(result.contains_cord, true); // TestAllTypes
+ EXPECT_EQ(result.contains_extension, false); // TestAllTypes
+}
+
+TEST(HELPERS_TEST_NAME, TestSCCAnalysis) {
+ {
+ UNITTEST::TestRecursiveMessage msg;
+ MessageSCCAnalyzer scc_analyzer((Options()));
+ const SCC* scc = scc_analyzer.GetSCC(msg.GetDescriptor());
+ MessageAnalysis result = scc_analyzer.GetSCCAnalysis(scc);
+ EXPECT_EQ(result.is_recursive, true);
+ EXPECT_EQ(result.contains_required, false);
+ EXPECT_EQ(result.contains_cord, false);
+ EXPECT_EQ(result.contains_extension, false);
+ }
+ {
+ UNITTEST::TestAllExtensions msg;
+ MessageSCCAnalyzer scc_analyzer((Options()));
+ const SCC* scc = scc_analyzer.GetSCC(msg.GetDescriptor());
+ MessageAnalysis result = scc_analyzer.GetSCCAnalysis(scc);
+ EXPECT_EQ(result.is_recursive, false);
+ EXPECT_EQ(result.contains_required, false);
+ EXPECT_EQ(result.contains_cord, false);
+ EXPECT_EQ(result.contains_extension, true);
+ }
+ {
+ UNITTEST::TestRequired msg;
+ MessageSCCAnalyzer scc_analyzer((Options()));
+ const SCC* scc = scc_analyzer.GetSCC(msg.GetDescriptor());
+ MessageAnalysis result = scc_analyzer.GetSCCAnalysis(scc);
+ EXPECT_EQ(result.is_recursive, false);
+ EXPECT_EQ(result.contains_required, true);
+ EXPECT_EQ(result.contains_cord, false);
+ EXPECT_EQ(result.contains_extension, false);
+ }
+}
+
+} // namespace cpp_unittest
+} // namespace cpp
+} // namespace compiler
+
+namespace no_generic_services_test {
+ // Verify that no class called "TestService" was defined in
+ // unittest_no_generic_services.pb.h by defining a different type by the same
+ // name. If such a service was generated, this will not compile.
+ struct TestService {
+ int i;
+ };
+}
+
+namespace compiler {
+namespace cpp {
+namespace cpp_unittest {
+
+TEST_F(GENERATED_SERVICE_TEST_NAME, NoGenericServices) {
+ // Verify that non-services in unittest_no_generic_services.proto were
+ // generated.
+ ::protobuf_unittest::no_generic_services_test::TestMessage message;
+ message.set_a(1);
+ message.SetExtension(
+ ::protobuf_unittest::no_generic_services_test::test_extension, 123);
+ ::protobuf_unittest::no_generic_services_test::TestEnum e =
+ ::protobuf_unittest::no_generic_services_test::FOO;
+ EXPECT_EQ(e, 1);
+
+ // Verify that a ServiceDescriptor is generated for the service even if the
+ // class itself is not.
+ const FileDescriptor* file =
+ ::google::protobuf::unittest::no_generic_services_test::TestMessage::descriptor()
+ ->file();
+
+ ASSERT_EQ(1, file->service_count());
+ EXPECT_EQ("TestService", file->service(0)->name());
+ ASSERT_EQ(1, file->service(0)->method_count());
+ EXPECT_EQ("Foo", file->service(0)->method(0)->name());
+}
+
+#endif // !PROTOBUF_TEST_NO_DESCRIPTORS
+
+// ===================================================================
+
+// This test must run last. It verifies that descriptors were or were not
+// initialized depending on whether PROTOBUF_TEST_NO_DESCRIPTORS was defined.
+// When this is defined, we skip all tests which are expected to trigger
+// descriptor initialization. This verifies that everything else still works
+// if descriptors are not initialized.
+TEST(DESCRIPTOR_INIT_TEST_NAME, Initialized) {
+#ifdef PROTOBUF_TEST_NO_DESCRIPTORS
+ bool should_have_descriptors = false;
+#else
+ bool should_have_descriptors = true;
+#endif
+
+ EXPECT_EQ(should_have_descriptors,
+ DescriptorPool::generated_pool()->InternalIsFileLoaded(
+ TestUtil::MaybeTranslatePath(UNITTEST_PROTO_PATH)));
+}
+
+} // namespace cpp_unittest
+
+} // namespace cpp
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#include <port_undef.inc>
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/cpp/metadata_test.cc b/NorthstarDedicatedTest/include/protobuf/compiler/cpp/metadata_test.cc
new file mode 100644
index 00000000..bbd043d1
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/cpp/metadata_test.cc
@@ -0,0 +1,161 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <memory>
+
+#include <testing/file.h>
+#include <testing/file.h>
+#include <compiler/cpp/cpp_helpers.h>
+#include <compiler/cpp/cpp_generator.h>
+#include <compiler/annotation_test_util.h>
+#include <compiler/command_line_interface.h>
+#include <descriptor.pb.h>
+#include <testing/googletest.h>
+#include <gtest/gtest.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+namespace atu = annotation_test_util;
+
+namespace {
+
+class CppMetadataTest : public ::testing::Test {
+ public:
+ // Tries to capture a FileDescriptorProto, GeneratedCodeInfo, and output
+ // code from the previously added file with name `filename`. Returns true on
+ // success. If pb_h is non-null, expects a .pb.h and a .pb.h.meta (copied to
+ // pb_h and pb_h_info respecfively); similarly for proto_h and proto_h_info.
+ bool CaptureMetadata(const std::string& filename, FileDescriptorProto* file,
+ std::string* pb_h, GeneratedCodeInfo* pb_h_info,
+ std::string* proto_h, GeneratedCodeInfo* proto_h_info,
+ std::string* pb_cc) {
+ CommandLineInterface cli;
+ CppGenerator cpp_generator;
+ cli.RegisterGenerator("--cpp_out", &cpp_generator, "");
+ std::string cpp_out =
+ "--cpp_out=annotate_headers=true,"
+ "annotation_pragma_name=pragma_name,"
+ "annotation_guard_name=guard_name:" +
+ TestTempDir();
+
+ const bool result = atu::RunProtoCompiler(filename, cpp_out, &cli, file);
+
+ if (!result) {
+ return result;
+ }
+
+ std::string output_base = TestTempDir() + "/" + StripProto(filename);
+
+ if (pb_cc != NULL) {
+ GOOGLE_CHECK_OK(
+ File::GetContents(output_base + ".pb.cc", pb_cc, true));
+ }
+
+ if (pb_h != NULL && pb_h_info != NULL) {
+ GOOGLE_CHECK_OK(
+ File::GetContents(output_base + ".pb.h", pb_h, true));
+ if (!atu::DecodeMetadata(output_base + ".pb.h.meta", pb_h_info)) {
+ return false;
+ }
+ }
+
+ if (proto_h != NULL && proto_h_info != NULL) {
+ GOOGLE_CHECK_OK(File::GetContents(output_base + ".proto.h", proto_h,
+ true));
+ if (!atu::DecodeMetadata(output_base + ".proto.h.meta", proto_h_info)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+};
+
+const char kSmallTestFile[] =
+ "syntax = \"proto2\";\n"
+ "package foo;\n"
+ "enum Enum { VALUE = 0; }\n"
+ "message Message { }\n";
+
+TEST_F(CppMetadataTest, CapturesEnumNames) {
+ FileDescriptorProto file;
+ GeneratedCodeInfo info;
+ std::string pb_h;
+ atu::AddFile("test.proto", kSmallTestFile);
+ EXPECT_TRUE(
+ CaptureMetadata("test.proto", &file, &pb_h, &info, NULL, NULL, NULL));
+ EXPECT_EQ("Enum", file.enum_type(0).name());
+ std::vector<int> enum_path;
+ enum_path.push_back(FileDescriptorProto::kEnumTypeFieldNumber);
+ enum_path.push_back(0);
+ const GeneratedCodeInfo::Annotation* enum_annotation =
+ atu::FindAnnotationOnPath(info, "test.proto", enum_path);
+ EXPECT_TRUE(NULL != enum_annotation);
+ EXPECT_TRUE(atu::AnnotationMatchesSubstring(pb_h, enum_annotation, "Enum"));
+}
+
+TEST_F(CppMetadataTest, AddsPragma) {
+ FileDescriptorProto file;
+ GeneratedCodeInfo info;
+ std::string pb_h;
+ atu::AddFile("test.proto", kSmallTestFile);
+ EXPECT_TRUE(
+ CaptureMetadata("test.proto", &file, &pb_h, &info, NULL, NULL, NULL));
+ EXPECT_TRUE(pb_h.find("#ifdef guard_name") != std::string::npos);
+ EXPECT_TRUE(pb_h.find("#pragma pragma_name \"test.pb.h.meta\"") !=
+ std::string::npos);
+}
+
+TEST_F(CppMetadataTest, CapturesMessageNames) {
+ FileDescriptorProto file;
+ GeneratedCodeInfo info;
+ std::string pb_h;
+ atu::AddFile("test.proto", kSmallTestFile);
+ EXPECT_TRUE(
+ CaptureMetadata("test.proto", &file, &pb_h, &info, NULL, NULL, NULL));
+ EXPECT_EQ("Message", file.message_type(0).name());
+ std::vector<int> message_path;
+ message_path.push_back(FileDescriptorProto::kMessageTypeFieldNumber);
+ message_path.push_back(0);
+ const GeneratedCodeInfo::Annotation* message_annotation =
+ atu::FindAnnotationOnPath(info, "test.proto", message_path);
+ EXPECT_TRUE(NULL != message_annotation);
+ EXPECT_TRUE(
+ atu::AnnotationMatchesSubstring(pb_h, message_annotation, "Message"));
+}
+
+} // namespace
+} // namespace cpp
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_bootstrap_unittest.cc b/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_bootstrap_unittest.cc
new file mode 100644
index 00000000..371b12ca
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_bootstrap_unittest.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.
+
+// This test insures that
+// csharp/src/Google.Protobuf/Reflection/Descriptor.cs match exactly
+// what would be generated by the protocol compiler. The file is not
+// generated automatically at build time.
+//
+// If this test fails, run the script
+// "generate_descriptor_proto.sh" and add the changed files under
+// csharp/src/ to your changelist.
+
+#include <map>
+
+#include <compiler/csharp/csharp_generator.h>
+#include <compiler/importer.h>
+#include <descriptor.h>
+#include <io/zero_copy_stream_impl.h>
+#include <stubs/map_util.h>
+#include <stubs/stl_util.h>
+#include <stubs/strutil.h>
+#include <stubs/substitute.h>
+
+#include <testing/file.h>
+#include <testing/file.h>
+#include <testing/googletest.h>
+#include <gtest/gtest.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace csharp {
+
+namespace {
+
+class MockErrorCollector : public MultiFileErrorCollector {
+ public:
+ MockErrorCollector() {}
+ ~MockErrorCollector() {}
+
+ std::string text_;
+
+ // implements ErrorCollector ---------------------------------------
+ void AddError(const std::string& filename, int line, int column,
+ const std::string& message) {
+ strings::SubstituteAndAppend(&text_, "$0:$1:$2: $3\n",
+ filename, line, column, message);
+ }
+};
+
+class MockGeneratorContext : public GeneratorContext {
+ public:
+ void ExpectFileMatches(const std::string& virtual_filename,
+ const std::string& physical_filename) {
+ auto it = files_.find(virtual_filename);
+ ASSERT_TRUE(it != files_.end())
+ << "Generator failed to generate file: " << virtual_filename;
+ std::string expected_contents = *it->second;
+
+ std::string actual_contents;
+ GOOGLE_CHECK_OK(
+ File::GetContentsAsText(TestSourceDir() + "/" + physical_filename,
+ &actual_contents, true))
+ << "Unable to get " << physical_filename;
+ EXPECT_TRUE(actual_contents == expected_contents)
+ << physical_filename << " needs to be regenerated. Please run "
+ "generate_descriptor_proto.sh. Then add this file "
+ "to your CL.";
+ }
+
+ // implements GeneratorContext --------------------------------------
+
+ virtual io::ZeroCopyOutputStream* Open(const std::string& filename) {
+ auto& map_slot = files_[filename];
+ map_slot.reset(new std::string);
+ return new io::StringOutputStream(map_slot.get());
+ }
+
+ private:
+ std::map<std::string, std::unique_ptr<std::string>> files_;
+};
+
+class GenerateAndTest {
+ public:
+ GenerateAndTest() {}
+ void Run(const FileDescriptor* proto_file, std::string file1, std::string file2) {
+ ASSERT_TRUE(proto_file != NULL) << TestSourceDir();
+ ASSERT_TRUE(generator_.Generate(proto_file, parameter_,
+ &context_, &error_));
+ context_.ExpectFileMatches(file1, file2);
+ }
+ void SetParameter(string parameter) {
+ parameter_ = parameter;
+ }
+
+ private:
+ Generator generator_;
+ MockGeneratorContext context_;
+ std::string error_;
+ std::string parameter_;
+};
+
+TEST(CsharpBootstrapTest, GeneratedCsharpDescriptorMatches) {
+ // Skip this whole test if the csharp directory doesn't exist (i.e., a C++11
+ // only distribution).
+ std::string descriptor_file_name =
+ "../csharp/src/Google.Protobuf/Reflection/Descriptor.cs";
+ if (!File::Exists(TestSourceDir() + "/" + descriptor_file_name)) {
+ return;
+ }
+
+ MockErrorCollector error_collector;
+ DiskSourceTree source_tree;
+ Importer importer(&source_tree, &error_collector);
+ GenerateAndTest generate_test;
+
+ generate_test.SetParameter("base_namespace=Google.Protobuf");
+ source_tree.MapPath("", TestSourceDir());
+ generate_test.Run(importer.Import("google/protobuf/descriptor.proto"),
+ "Reflection/Descriptor.cs",
+ "../csharp/src/Google.Protobuf/Reflection/Descriptor.cs");
+ generate_test.Run(importer.Import("google/protobuf/any.proto"),
+ "WellKnownTypes/Any.cs",
+ "../csharp/src/Google.Protobuf/WellKnownTypes/Any.cs");
+ generate_test.Run(importer.Import("google/protobuf/api.proto"),
+ "WellKnownTypes/Api.cs",
+ "../csharp/src/Google.Protobuf/WellKnownTypes/Api.cs");
+ generate_test.Run(importer.Import("google/protobuf/duration.proto"),
+ "WellKnownTypes/Duration.cs",
+ "../csharp/src/Google.Protobuf/WellKnownTypes/Duration.cs");
+ generate_test.Run(importer.Import("google/protobuf/empty.proto"),
+ "WellKnownTypes/Empty.cs",
+ "../csharp/src/Google.Protobuf/WellKnownTypes/Empty.cs");
+ generate_test.Run(importer.Import("google/protobuf/field_mask.proto"),
+ "WellKnownTypes/FieldMask.cs",
+ "../csharp/src/Google.Protobuf/WellKnownTypes/FieldMask.cs");
+ generate_test.Run(importer.Import("google/protobuf/source_context.proto"),
+ "WellKnownTypes/SourceContext.cs",
+ "../csharp/src/Google.Protobuf/WellKnownTypes/SourceContext.cs");
+ generate_test.Run(importer.Import("google/protobuf/struct.proto"),
+ "WellKnownTypes/Struct.cs",
+ "../csharp/src/Google.Protobuf/WellKnownTypes/Struct.cs");
+ generate_test.Run(importer.Import("google/protobuf/timestamp.proto"),
+ "WellKnownTypes/Timestamp.cs",
+ "../csharp/src/Google.Protobuf/WellKnownTypes/Timestamp.cs");
+ generate_test.Run(importer.Import("google/protobuf/type.proto"),
+ "WellKnownTypes/Type.cs",
+ "../csharp/src/Google.Protobuf/WellKnownTypes/Type.cs");
+ generate_test.Run(importer.Import("google/protobuf/wrappers.proto"),
+ "WellKnownTypes/Wrappers.cs",
+ "../csharp/src/Google.Protobuf/WellKnownTypes/Wrappers.cs");
+
+ generate_test.SetParameter("");
+ source_tree.MapPath("", TestSourceDir() + "/../conformance");
+ generate_test.Run(importer.Import("conformance.proto"),
+ "Conformance.cs",
+ "../csharp/src/Google.Protobuf.Conformance/Conformance.cs");
+
+ EXPECT_EQ("", error_collector.text_);
+}
+
+} // namespace
+
+} // namespace csharp
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_doc_comment.cc b/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_doc_comment.cc
new file mode 100644
index 00000000..12dabe04
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_doc_comment.cc
@@ -0,0 +1,116 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+#include <compiler/csharp/csharp_doc_comment.h>
+#include <descriptor.h>
+#include <io/printer.h>
+#include <stubs/strutil.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace csharp {
+
+// Functions to create C# XML documentation comments.
+// Currently this only includes documentation comments containing text specified as comments
+// in the .proto file; documentation comments generated just from field/message/enum/proto names
+// is inlined in the relevant code. If more control is required, that code can be moved here.
+
+void WriteDocCommentBodyImpl(io::Printer* printer, SourceLocation location) {
+ std::string comments = location.leading_comments.empty() ?
+ location.trailing_comments : location.leading_comments;
+ if (comments.empty()) {
+ return;
+ }
+ // XML escaping... no need for apostrophes etc as the whole text is going to be a child
+ // node of a summary element, not part of an attribute.
+ comments = StringReplace(comments, "&", "&amp;", true);
+ comments = StringReplace(comments, "<", "&lt;", true);
+ std::vector<std::string> lines;
+ lines = Split(comments, "\n", false);
+ // TODO: We really should work out which part to put in the summary and which to put in the remarks...
+ // but that needs to be part of a bigger effort to understand the markdown better anyway.
+ printer->Print("/// <summary>\n");
+ bool last_was_empty = false;
+ // We squash multiple blank lines down to one, and remove any trailing blank lines. We need
+ // to preserve the blank lines themselves, as this is relevant in the markdown.
+ // Note that we can't remove leading or trailing whitespace as *that's* relevant in markdown too.
+ // (We don't skip "just whitespace" lines, either.)
+ for (std::vector<std::string>::iterator it = lines.begin();
+ it != lines.end(); ++it) {
+ std::string line = *it;
+ if (line.empty()) {
+ last_was_empty = true;
+ } else {
+ if (last_was_empty) {
+ printer->Print("///\n");
+ }
+ last_was_empty = false;
+ printer->Print("///$line$\n", "line", *it);
+ }
+ }
+ printer->Print("/// </summary>\n");
+}
+
+template <typename DescriptorType>
+static void WriteDocCommentBody(
+ io::Printer* printer, const DescriptorType* descriptor) {
+ SourceLocation location;
+ if (descriptor->GetSourceLocation(&location)) {
+ WriteDocCommentBodyImpl(printer, location);
+ }
+}
+
+void WriteMessageDocComment(io::Printer* printer, const Descriptor* message) {
+ WriteDocCommentBody(printer, message);
+}
+
+void WritePropertyDocComment(io::Printer* printer, const FieldDescriptor* field) {
+ WriteDocCommentBody(printer, field);
+}
+
+void WriteEnumDocComment(io::Printer* printer, const EnumDescriptor* enumDescriptor) {
+ WriteDocCommentBody(printer, enumDescriptor);
+}
+void WriteEnumValueDocComment(io::Printer* printer, const EnumValueDescriptor* value) {
+ WriteDocCommentBody(printer, value);
+}
+
+void WriteMethodDocComment(io::Printer* printer, const MethodDescriptor* method) {
+ WriteDocCommentBody(printer, method);
+}
+
+} // namespace csharp
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_doc_comment.h b/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_doc_comment.h
new file mode 100644
index 00000000..ca78e251
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_doc_comment.h
@@ -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.
+
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_CSHARP_DOC_COMMENT_H__
+#define GOOGLE_PROTOBUF_COMPILER_CSHARP_DOC_COMMENT_H__
+
+#include <io/printer.h>
+#include <descriptor.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace csharp {
+ void WriteMessageDocComment(io::Printer* printer, const Descriptor* message);
+ void WritePropertyDocComment(io::Printer* printer, const FieldDescriptor* field);
+ void WriteEnumDocComment(io::Printer* printer, const EnumDescriptor* enumDescriptor);
+ void WriteEnumValueDocComment(io::Printer* printer, const EnumValueDescriptor* value);
+ void WriteMethodDocComment(io::Printer* printer, const MethodDescriptor* method);
+} // namespace csharp
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+#endif // GOOGLE_PROTOBUF_COMPILER_CSHARP_DOC_COMMENT_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_enum.cc b/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_enum.cc
new file mode 100644
index 00000000..fd96c571
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_enum.cc
@@ -0,0 +1,99 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <sstream>
+
+#include <compiler/code_generator.h>
+#include <descriptor.h>
+#include <descriptor.pb.h>
+#include <io/printer.h>
+#include <io/zero_copy_stream.h>
+#include <stubs/strutil.h>
+
+#include <compiler/csharp/csharp_doc_comment.h>
+#include <compiler/csharp/csharp_enum.h>
+#include <compiler/csharp/csharp_helpers.h>
+#include <compiler/csharp/csharp_options.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace csharp {
+
+EnumGenerator::EnumGenerator(const EnumDescriptor* descriptor, const Options* options) :
+ SourceGeneratorBase(options),
+ descriptor_(descriptor) {
+}
+
+EnumGenerator::~EnumGenerator() {
+}
+
+void EnumGenerator::Generate(io::Printer* printer) {
+ WriteEnumDocComment(printer, descriptor_);
+ printer->Print("$access_level$ enum $name$ {\n",
+ "access_level", class_access_level(),
+ "name", descriptor_->name());
+ printer->Indent();
+ std::set<std::string> used_names;
+ std::set<int> used_number;
+ for (int i = 0; i < descriptor_->value_count(); i++) {
+ WriteEnumValueDocComment(printer, descriptor_->value(i));
+ std::string original_name = descriptor_->value(i)->name();
+ std::string name =
+ GetEnumValueName(descriptor_->name(), descriptor_->value(i)->name());
+ // Make sure we don't get any duplicate names due to prefix removal.
+ while (!used_names.insert(name).second) {
+ // It's possible we'll end up giving this warning multiple times, but that's better than not at all.
+ GOOGLE_LOG(WARNING) << "Duplicate enum value " << name << " (originally " << original_name
+ << ") in " << descriptor_->name() << "; adding underscore to distinguish";
+ name += "_";
+ }
+ int number = descriptor_->value(i)->number();
+ if (!used_number.insert(number).second) {
+ printer->Print("[pbr::OriginalName(\"$original_name$\", PreferredAlias = false)] $name$ = $number$,\n",
+ "original_name", original_name,
+ "name", name,
+ "number", StrCat(number));
+ } else {
+ printer->Print("[pbr::OriginalName(\"$original_name$\")] $name$ = $number$,\n",
+ "original_name", original_name,
+ "name", name,
+ "number", StrCat(number));
+ }
+ }
+ printer->Outdent();
+ printer->Print("}\n");
+ printer->Print("\n");
+}
+
+} // namespace csharp
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_enum.h b/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_enum.h
new file mode 100644
index 00000000..d589ae50
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_enum.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.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_CSHARP_ENUM_H__
+#define GOOGLE_PROTOBUF_COMPILER_CSHARP_ENUM_H__
+
+#include <string>
+
+#include <compiler/code_generator.h>
+#include <compiler/csharp/csharp_source_generator_base.h>
+#include <descriptor.h>
+#include <io/printer.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace csharp {
+
+class EnumGenerator : public SourceGeneratorBase {
+ public:
+ EnumGenerator(const EnumDescriptor* descriptor, const Options* options);
+ ~EnumGenerator();
+
+ EnumGenerator(const EnumGenerator&) = delete;
+ EnumGenerator& operator=(const EnumGenerator&) = delete;
+
+ void Generate(io::Printer* printer);
+
+ private:
+ const EnumDescriptor* descriptor_;
+};
+
+} // namespace csharp
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_COMPILER_CSHARP_ENUM_H__
+
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_enum_field.cc b/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_enum_field.cc
new file mode 100644
index 00000000..76a47674
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_enum_field.cc
@@ -0,0 +1,135 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 <sstream>
+
+#include <compiler/code_generator.h>
+#include <descriptor.h>
+#include <descriptor.pb.h>
+#include <io/printer.h>
+#include <io/zero_copy_stream.h>
+
+#include <compiler/csharp/csharp_doc_comment.h>
+#include <compiler/csharp/csharp_helpers.h>
+#include <compiler/csharp/csharp_options.h>
+#include <compiler/csharp/csharp_enum_field.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace csharp {
+
+EnumFieldGenerator::EnumFieldGenerator(const FieldDescriptor* descriptor,
+ int presenceIndex, const Options *options)
+ : PrimitiveFieldGenerator(descriptor, presenceIndex, options) {
+}
+
+EnumFieldGenerator::~EnumFieldGenerator() {
+}
+
+void EnumFieldGenerator::GenerateParsingCode(io::Printer* printer) {
+ printer->Print(variables_,
+ "$property_name$ = ($type_name$) input.ReadEnum();\n");
+}
+
+void EnumFieldGenerator::GenerateSerializationCode(io::Printer* printer) {
+ printer->Print(variables_,
+ "if ($has_property_check$) {\n"
+ " output.WriteRawTag($tag_bytes$);\n"
+ " output.WriteEnum((int) $property_name$);\n"
+ "}\n");
+}
+
+void EnumFieldGenerator::GenerateSerializedSizeCode(io::Printer* printer) {
+ printer->Print(
+ variables_,
+ "if ($has_property_check$) {\n"
+ " size += $tag_size$ + pb::CodedOutputStream.ComputeEnumSize((int) $property_name$);\n"
+ "}\n");
+}
+
+void EnumFieldGenerator::GenerateCodecCode(io::Printer* printer) {
+ printer->Print(
+ variables_,
+ "pb::FieldCodec.ForEnum($tag$, x => (int) x, x => ($type_name$) x, $default_value$)");
+}
+
+void EnumFieldGenerator::GenerateExtensionCode(io::Printer* printer) {
+ WritePropertyDocComment(printer, descriptor_);
+ AddDeprecatedFlag(printer);
+ printer->Print(
+ variables_,
+ "$access_level$ static readonly pb::Extension<$extended_type$, $type_name$> $property_name$ =\n"
+ " new pb::Extension<$extended_type$, $type_name$>($number$, ");
+ GenerateCodecCode(printer);
+ printer->Print(");\n");
+}
+
+EnumOneofFieldGenerator::EnumOneofFieldGenerator(
+ const FieldDescriptor* descriptor, int presenceIndex, const Options *options)
+ : PrimitiveOneofFieldGenerator(descriptor, presenceIndex, options) {
+}
+
+EnumOneofFieldGenerator::~EnumOneofFieldGenerator() {
+}
+
+void EnumOneofFieldGenerator::GenerateMergingCode(io::Printer* printer) {
+ printer->Print(variables_, "$property_name$ = other.$property_name$;\n");
+}
+
+void EnumOneofFieldGenerator::GenerateParsingCode(io::Printer* printer) {
+ // TODO(jonskeet): What about if we read the default value?
+ printer->Print(
+ variables_,
+ "$oneof_name$_ = input.ReadEnum();\n"
+ "$oneof_name$Case_ = $oneof_property_name$OneofCase.$property_name$;\n");
+}
+
+void EnumOneofFieldGenerator::GenerateSerializationCode(io::Printer* printer) {
+ printer->Print(
+ variables_,
+ "if ($has_property_check$) {\n"
+ " output.WriteRawTag($tag_bytes$);\n"
+ " output.WriteEnum((int) $property_name$);\n"
+ "}\n");
+}
+
+void EnumOneofFieldGenerator::GenerateSerializedSizeCode(io::Printer* printer) {
+ printer->Print(
+ variables_,
+ "if ($has_property_check$) {\n"
+ " size += $tag_size$ + pb::CodedOutputStream.ComputeEnumSize((int) $property_name$);\n"
+ "}\n");
+}
+
+} // namespace csharp
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_enum_field.h b/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_enum_field.h
new file mode 100644
index 00000000..791ff21a
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_enum_field.h
@@ -0,0 +1,83 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_CSHARP_ENUM_FIELD_H__
+#define GOOGLE_PROTOBUF_COMPILER_CSHARP_ENUM_FIELD_H__
+
+#include <string>
+
+#include <compiler/code_generator.h>
+#include <compiler/csharp/csharp_primitive_field.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace csharp {
+
+class EnumFieldGenerator : public PrimitiveFieldGenerator {
+ public:
+ EnumFieldGenerator(const FieldDescriptor* descriptor,
+ int presenceIndex,
+ const Options *options);
+ ~EnumFieldGenerator();
+
+ EnumFieldGenerator(const EnumFieldGenerator&) = delete;
+ EnumFieldGenerator& operator=(const EnumFieldGenerator&) = delete;
+
+ virtual void GenerateCodecCode(io::Printer* printer) override;
+ virtual void GenerateParsingCode(io::Printer* printer) override;
+ virtual void GenerateSerializationCode(io::Printer* printer) override;
+ virtual void GenerateSerializedSizeCode(io::Printer* printer) override;
+ virtual void GenerateExtensionCode(io::Printer* printer) override;
+};
+
+class EnumOneofFieldGenerator : public PrimitiveOneofFieldGenerator {
+ public:
+ EnumOneofFieldGenerator(const FieldDescriptor* descriptor,
+ int presenceIndex,
+ const Options *options);
+ ~EnumOneofFieldGenerator();
+
+ EnumOneofFieldGenerator(const EnumOneofFieldGenerator&) = delete;
+ EnumOneofFieldGenerator& operator=(const EnumOneofFieldGenerator&) = delete;
+
+ virtual void GenerateMergingCode(io::Printer* printer) override;
+ virtual void GenerateParsingCode(io::Printer* printer) override;
+ virtual void GenerateSerializationCode(io::Printer* printer) override;
+ virtual void GenerateSerializedSizeCode(io::Printer* printer) override;
+};
+
+} // namespace csharp
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_COMPILER_CSHARP_ENUM_FIELD_H__
+
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_field_base.cc b/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_field_base.cc
new file mode 100644
index 00000000..52934b04
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_field_base.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.
+
+#include <cmath>
+#include <limits>
+#include <sstream>
+
+#include <compiler/code_generator.h>
+#include <descriptor.h>
+#include <descriptor.pb.h>
+#include <io/coded_stream.h>
+#include <io/printer.h>
+#include <io/zero_copy_stream.h>
+#include <stubs/strutil.h>
+#include <wire_format.h>
+
+#include <compiler/csharp/csharp_field_base.h>
+#include <compiler/csharp/csharp_helpers.h>
+#include <compiler/csharp/csharp_names.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace csharp {
+
+void FieldGeneratorBase::SetCommonFieldVariables(
+ std::map<std::string, std::string>* variables) {
+ // Note: this will be valid even though the tag emitted for packed and unpacked versions of
+ // repeated fields varies by wire format. The wire format is encoded in the bottom 3 bits, which
+ // never effects the tag size.
+ int tag_size = internal::WireFormat::TagSize(descriptor_->number(), descriptor_->type());
+ int part_tag_size = tag_size;
+ if (descriptor_->type() == FieldDescriptor::TYPE_GROUP) {
+ part_tag_size /= 2;
+ }
+ uint tag = internal::WireFormat::MakeTag(descriptor_);
+ uint8 tag_array[5];
+ io::CodedOutputStream::WriteTagToArray(tag, tag_array);
+ std::string tag_bytes = StrCat(tag_array[0]);
+ for (int i = 1; i < part_tag_size; i++) {
+ tag_bytes += ", " + StrCat(tag_array[i]);
+ }
+
+ (*variables)["tag"] = StrCat(tag);
+ (*variables)["tag_size"] = StrCat(tag_size);
+ (*variables)["tag_bytes"] = tag_bytes;
+
+ if (descriptor_->type() == FieldDescriptor::Type::TYPE_GROUP) {
+ tag = internal::WireFormatLite::MakeTag(
+ descriptor_->number(),
+ internal::WireFormatLite::WIRETYPE_END_GROUP);
+ io::CodedOutputStream::WriteTagToArray(tag, tag_array);
+ tag_bytes = StrCat(tag_array[0]);
+ for (int i = 1; i < part_tag_size; i++) {
+ tag_bytes += ", " + StrCat(tag_array[i]);
+ }
+
+ variables_["end_tag"] = StrCat(tag);
+ variables_["end_tag_bytes"] = tag_bytes;
+ }
+
+ (*variables)["access_level"] = "public";
+
+ (*variables)["property_name"] = property_name();
+ (*variables)["type_name"] = type_name();
+ (*variables)["extended_type"] = GetClassName(descriptor_->containing_type());
+ (*variables)["name"] = name();
+ (*variables)["descriptor_name"] = descriptor_->name();
+ (*variables)["default_value"] = default_value();
+ (*variables)["capitalized_type_name"] = capitalized_type_name();
+ (*variables)["number"] = number();
+ if (has_default_value() && !SupportsPresenceApi(descriptor_)) {
+ (*variables)["name_def_message"] =
+ (*variables)["name"] + "_ = " + (*variables)["default_value"];
+ } else {
+ (*variables)["name_def_message"] = (*variables)["name"] + "_";
+ }
+ if (SupportsPresenceApi(descriptor_)) {
+ (*variables)["has_property_check"] = "Has" + (*variables)["property_name"];
+ (*variables)["other_has_property_check"] = "other.Has" + (*variables)["property_name"];
+ (*variables)["has_not_property_check"] = "!" + (*variables)["has_property_check"];
+ (*variables)["other_has_not_property_check"] = "!" + (*variables)["other_has_property_check"];
+ if (presenceIndex_ != -1) {
+ std::string hasBitsNumber = StrCat(presenceIndex_ / 32);
+ std::string hasBitsMask = StrCat(1 << (presenceIndex_ % 32));
+ (*variables)["has_field_check"] = "(_hasBits" + hasBitsNumber + " & " + hasBitsMask + ") != 0";
+ (*variables)["set_has_field"] = "_hasBits" + hasBitsNumber + " |= " + hasBitsMask;
+ (*variables)["clear_has_field"] = "_hasBits" + hasBitsNumber + " &= ~" + hasBitsMask;
+ }
+ } else {
+ (*variables)["has_property_check"] =
+ (*variables)["property_name"] + " != " + (*variables)["default_value"];
+ (*variables)["other_has_property_check"] = "other." +
+ (*variables)["property_name"] + " != " + (*variables)["default_value"];
+ }
+}
+
+void FieldGeneratorBase::SetCommonOneofFieldVariables(
+ std::map<std::string, std::string>* variables) {
+ (*variables)["oneof_name"] = oneof_name();
+ if (SupportsPresenceApi(descriptor_)) {
+ (*variables)["has_property_check"] = "Has" + property_name();
+ } else {
+ (*variables)["has_property_check"] =
+ oneof_name() + "Case_ == " + oneof_property_name() +
+ "OneofCase." + property_name();
+ }
+ (*variables)["oneof_property_name"] = oneof_property_name();
+}
+
+FieldGeneratorBase::FieldGeneratorBase(const FieldDescriptor* descriptor,
+ int presenceIndex, const Options* options)
+ : SourceGeneratorBase(options),
+ descriptor_(descriptor),
+ presenceIndex_(presenceIndex) {
+ SetCommonFieldVariables(&variables_);
+}
+
+FieldGeneratorBase::~FieldGeneratorBase() {
+}
+
+void FieldGeneratorBase::GenerateFreezingCode(io::Printer* printer) {
+ // No-op: only message fields and repeated fields need
+ // special handling for freezing, so default to not generating any code.
+}
+
+void FieldGeneratorBase::GenerateCodecCode(io::Printer* printer) {
+ // No-op: expect this to be overridden by appropriate types.
+ // Could fail if we get called here though...
+}
+
+void FieldGeneratorBase::GenerateExtensionCode(io::Printer* printer) {
+ // No-op: only message fields, enum fields, primitives,
+ // and repeated fields need this default is to not generate any code
+}
+
+void FieldGeneratorBase::GenerateParsingCode(io::Printer* printer, bool use_parse_context) {
+ // for some field types the value of "use_parse_context" doesn't matter,
+ // so we fallback to the default implementation.
+ GenerateParsingCode(printer);
+}
+
+void FieldGeneratorBase::GenerateSerializationCode(io::Printer* printer, bool use_write_context) {
+ // for some field types the value of "use_write_context" doesn't matter,
+ // so we fallback to the default implementation.
+ GenerateSerializationCode(printer);
+}
+
+void FieldGeneratorBase::AddDeprecatedFlag(io::Printer* printer) {
+ if (descriptor_->options().deprecated()) {
+ printer->Print("[global::System.ObsoleteAttribute]\n");
+ } else if (descriptor_->type() == FieldDescriptor::TYPE_MESSAGE &&
+ descriptor_->message_type()->options().deprecated()) {
+ printer->Print("[global::System.ObsoleteAttribute]\n");
+ }
+}
+
+void FieldGeneratorBase::AddPublicMemberAttributes(io::Printer* printer) {
+ AddDeprecatedFlag(printer);
+ WriteGeneratedCodeAttributes(printer);
+}
+
+std::string FieldGeneratorBase::oneof_property_name() {
+ return UnderscoresToCamelCase(descriptor_->containing_oneof()->name(), true);
+}
+
+std::string FieldGeneratorBase::oneof_name() {
+ return UnderscoresToCamelCase(descriptor_->containing_oneof()->name(), false);
+}
+
+std::string FieldGeneratorBase::property_name() {
+ return GetPropertyName(descriptor_);
+}
+
+std::string FieldGeneratorBase::name() {
+ return UnderscoresToCamelCase(GetFieldName(descriptor_), false);
+}
+
+std::string FieldGeneratorBase::type_name() {
+ return type_name(descriptor_);
+}
+
+std::string FieldGeneratorBase::type_name(const FieldDescriptor* descriptor) {
+ switch (descriptor->type()) {
+ case FieldDescriptor::TYPE_ENUM:
+ return GetClassName(descriptor->enum_type());
+ case FieldDescriptor::TYPE_MESSAGE:
+ case FieldDescriptor::TYPE_GROUP:
+ if (IsWrapperType(descriptor)) {
+ const FieldDescriptor* wrapped_field =
+ descriptor->message_type()->field(0);
+ std::string wrapped_field_type_name = type_name(wrapped_field);
+ // String and ByteString go to the same type; other wrapped types
+ // go to the nullable equivalent.
+ if (wrapped_field->type() == FieldDescriptor::TYPE_STRING ||
+ wrapped_field->type() == FieldDescriptor::TYPE_BYTES) {
+ return wrapped_field_type_name;
+ } else {
+ return wrapped_field_type_name + "?";
+ }
+ }
+ return GetClassName(descriptor->message_type());
+ case FieldDescriptor::TYPE_DOUBLE:
+ return "double";
+ case FieldDescriptor::TYPE_FLOAT:
+ return "float";
+ case FieldDescriptor::TYPE_INT64:
+ return "long";
+ case FieldDescriptor::TYPE_UINT64:
+ return "ulong";
+ case FieldDescriptor::TYPE_INT32:
+ return "int";
+ case FieldDescriptor::TYPE_FIXED64:
+ return "ulong";
+ case FieldDescriptor::TYPE_FIXED32:
+ return "uint";
+ case FieldDescriptor::TYPE_BOOL:
+ return "bool";
+ case FieldDescriptor::TYPE_STRING:
+ return "string";
+ case FieldDescriptor::TYPE_BYTES:
+ return "pb::ByteString";
+ case FieldDescriptor::TYPE_UINT32:
+ return "uint";
+ case FieldDescriptor::TYPE_SFIXED32:
+ return "int";
+ case FieldDescriptor::TYPE_SFIXED64:
+ return "long";
+ case FieldDescriptor::TYPE_SINT32:
+ return "int";
+ case FieldDescriptor::TYPE_SINT64:
+ return "long";
+ default:
+ GOOGLE_LOG(FATAL)<< "Unknown field type.";
+ return "";
+ }
+}
+
+bool FieldGeneratorBase::has_default_value() {
+ switch (descriptor_->type()) {
+ case FieldDescriptor::TYPE_ENUM:
+ case FieldDescriptor::TYPE_MESSAGE:
+ case FieldDescriptor::TYPE_GROUP:
+ return true;
+ case FieldDescriptor::TYPE_DOUBLE:
+ return descriptor_->default_value_double() != 0.0;
+ case FieldDescriptor::TYPE_FLOAT:
+ return descriptor_->default_value_float() != 0.0;
+ case FieldDescriptor::TYPE_INT64:
+ return descriptor_->default_value_int64() != 0L;
+ case FieldDescriptor::TYPE_UINT64:
+ return descriptor_->default_value_uint64() != 0L;
+ case FieldDescriptor::TYPE_INT32:
+ return descriptor_->default_value_int32() != 0;
+ case FieldDescriptor::TYPE_FIXED64:
+ return descriptor_->default_value_uint64() != 0L;
+ case FieldDescriptor::TYPE_FIXED32:
+ return descriptor_->default_value_uint32() != 0;
+ case FieldDescriptor::TYPE_BOOL:
+ return descriptor_->default_value_bool();
+ case FieldDescriptor::TYPE_STRING:
+ return true;
+ case FieldDescriptor::TYPE_BYTES:
+ return true;
+ case FieldDescriptor::TYPE_UINT32:
+ return descriptor_->default_value_uint32() != 0;
+ case FieldDescriptor::TYPE_SFIXED32:
+ return descriptor_->default_value_int32() != 0;
+ case FieldDescriptor::TYPE_SFIXED64:
+ return descriptor_->default_value_int64() != 0L;
+ case FieldDescriptor::TYPE_SINT32:
+ return descriptor_->default_value_int32() != 0;
+ case FieldDescriptor::TYPE_SINT64:
+ return descriptor_->default_value_int64() != 0L;
+ default:
+ GOOGLE_LOG(FATAL)<< "Unknown field type.";
+ return true;
+ }
+}
+
+bool AllPrintableAscii(const std::string& text) {
+ for(int i = 0; i < text.size(); i++) {
+ if (text[i] < 0x20 || text[i] > 0x7e) {
+ return false;
+ }
+ }
+ return true;
+}
+
+std::string FieldGeneratorBase::GetStringDefaultValueInternal(const FieldDescriptor* descriptor) {
+ if (descriptor->default_value_string().empty())
+ return "\"\"";
+ else
+ return "global::System.Text.Encoding.UTF8.GetString(global::System."
+ "Convert.FromBase64String(\"" +
+ StringToBase64(descriptor->default_value_string()) + "\"), 0, " + StrCat(descriptor->default_value_string().length()) + ")";
+}
+
+std::string FieldGeneratorBase::GetBytesDefaultValueInternal(const FieldDescriptor* descriptor) {
+ if (descriptor->default_value_string().empty())
+ return "pb::ByteString.Empty";
+ else
+ return "pb::ByteString.FromBase64(\"" + StringToBase64(descriptor->default_value_string()) + "\")";
+}
+
+std::string FieldGeneratorBase::default_value() {
+ return default_value(descriptor_);
+}
+
+std::string FieldGeneratorBase::default_value(const FieldDescriptor* descriptor) {
+ switch (descriptor->type()) {
+ case FieldDescriptor::TYPE_ENUM:
+ return GetClassName(descriptor->default_value_enum()->type()) + "." +
+ GetEnumValueName(descriptor->default_value_enum()->type()->name(), descriptor->default_value_enum()->name());
+ case FieldDescriptor::TYPE_MESSAGE:
+ case FieldDescriptor::TYPE_GROUP:
+ if (IsWrapperType(descriptor)) {
+ const FieldDescriptor* wrapped_field = descriptor->message_type()->field(0);
+ return default_value(wrapped_field);
+ } else {
+ return "null";
+ }
+ case FieldDescriptor::TYPE_DOUBLE: {
+ double value = descriptor->default_value_double();
+ if (value == std::numeric_limits<double>::infinity()) {
+ return "double.PositiveInfinity";
+ } else if (value == -std::numeric_limits<double>::infinity()) {
+ return "double.NegativeInfinity";
+ } else if (std::isnan(value)) {
+ return "double.NaN";
+ }
+ return StrCat(value) + "D";
+ }
+ case FieldDescriptor::TYPE_FLOAT: {
+ float value = descriptor->default_value_float();
+ if (value == std::numeric_limits<float>::infinity()) {
+ return "float.PositiveInfinity";
+ } else if (value == -std::numeric_limits<float>::infinity()) {
+ return "float.NegativeInfinity";
+ } else if (std::isnan(value)) {
+ return "float.NaN";
+ }
+ return StrCat(value) + "F";
+ }
+ case FieldDescriptor::TYPE_INT64:
+ return StrCat(descriptor->default_value_int64()) + "L";
+ case FieldDescriptor::TYPE_UINT64:
+ return StrCat(descriptor->default_value_uint64()) + "UL";
+ case FieldDescriptor::TYPE_INT32:
+ return StrCat(descriptor->default_value_int32());
+ case FieldDescriptor::TYPE_FIXED64:
+ return StrCat(descriptor->default_value_uint64()) + "UL";
+ case FieldDescriptor::TYPE_FIXED32:
+ return StrCat(descriptor->default_value_uint32());
+ case FieldDescriptor::TYPE_BOOL:
+ if (descriptor->default_value_bool()) {
+ return "true";
+ } else {
+ return "false";
+ }
+ case FieldDescriptor::TYPE_STRING:
+ return GetStringDefaultValueInternal(descriptor);
+ case FieldDescriptor::TYPE_BYTES:
+ return GetBytesDefaultValueInternal(descriptor);
+ case FieldDescriptor::TYPE_UINT32:
+ return StrCat(descriptor->default_value_uint32());
+ case FieldDescriptor::TYPE_SFIXED32:
+ return StrCat(descriptor->default_value_int32());
+ case FieldDescriptor::TYPE_SFIXED64:
+ return StrCat(descriptor->default_value_int64()) + "L";
+ case FieldDescriptor::TYPE_SINT32:
+ return StrCat(descriptor->default_value_int32());
+ case FieldDescriptor::TYPE_SINT64:
+ return StrCat(descriptor->default_value_int64()) + "L";
+ default:
+ GOOGLE_LOG(FATAL)<< "Unknown field type.";
+ return "";
+ }
+}
+
+std::string FieldGeneratorBase::number() {
+ return StrCat(descriptor_->number());
+}
+
+std::string FieldGeneratorBase::capitalized_type_name() {
+ switch (descriptor_->type()) {
+ case FieldDescriptor::TYPE_ENUM:
+ return "Enum";
+ case FieldDescriptor::TYPE_MESSAGE:
+ return "Message";
+ case FieldDescriptor::TYPE_GROUP:
+ return "Group";
+ case FieldDescriptor::TYPE_DOUBLE:
+ return "Double";
+ case FieldDescriptor::TYPE_FLOAT:
+ return "Float";
+ case FieldDescriptor::TYPE_INT64:
+ return "Int64";
+ case FieldDescriptor::TYPE_UINT64:
+ return "UInt64";
+ case FieldDescriptor::TYPE_INT32:
+ return "Int32";
+ case FieldDescriptor::TYPE_FIXED64:
+ return "Fixed64";
+ case FieldDescriptor::TYPE_FIXED32:
+ return "Fixed32";
+ case FieldDescriptor::TYPE_BOOL:
+ return "Bool";
+ case FieldDescriptor::TYPE_STRING:
+ return "String";
+ case FieldDescriptor::TYPE_BYTES:
+ return "Bytes";
+ case FieldDescriptor::TYPE_UINT32:
+ return "UInt32";
+ case FieldDescriptor::TYPE_SFIXED32:
+ return "SFixed32";
+ case FieldDescriptor::TYPE_SFIXED64:
+ return "SFixed64";
+ case FieldDescriptor::TYPE_SINT32:
+ return "SInt32";
+ case FieldDescriptor::TYPE_SINT64:
+ return "SInt64";
+ default:
+ GOOGLE_LOG(FATAL)<< "Unknown field type.";
+ return "";
+ }
+}
+
+} // namespace csharp
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_field_base.h b/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_field_base.h
new file mode 100644
index 00000000..f0221b6c
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_field_base.h
@@ -0,0 +1,111 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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_COMPILER_CSHARP_FIELD_BASE_H__
+#define GOOGLE_PROTOBUF_COMPILER_CSHARP_FIELD_BASE_H__
+
+#include <string>
+#include <stubs/strutil.h>
+
+#include <compiler/code_generator.h>
+#include <compiler/csharp/csharp_source_generator_base.h>
+#include <descriptor.h>
+#include <io/printer.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace csharp {
+
+class FieldGeneratorBase : public SourceGeneratorBase {
+ public:
+ FieldGeneratorBase(const FieldDescriptor* descriptor,
+ int presenceIndex,
+ const Options* options);
+ ~FieldGeneratorBase();
+
+ FieldGeneratorBase(const FieldGeneratorBase&) = delete;
+ FieldGeneratorBase& operator=(const FieldGeneratorBase&) = delete;
+
+ virtual void GenerateCloningCode(io::Printer* printer) = 0;
+ virtual void GenerateFreezingCode(io::Printer* printer);
+ virtual void GenerateCodecCode(io::Printer* printer);
+ virtual void GenerateExtensionCode(io::Printer* printer);
+ virtual void GenerateMembers(io::Printer* printer) = 0;
+ virtual void GenerateMergingCode(io::Printer* printer) = 0;
+ virtual void GenerateParsingCode(io::Printer* printer) = 0;
+ virtual void GenerateParsingCode(io::Printer* printer, bool use_parse_context);
+ virtual void GenerateSerializationCode(io::Printer* printer) = 0;
+ virtual void GenerateSerializationCode(io::Printer* printer, bool use_write_context);
+ virtual void GenerateSerializedSizeCode(io::Printer* printer) = 0;
+
+ virtual void WriteHash(io::Printer* printer) = 0;
+ virtual void WriteEquals(io::Printer* printer) = 0;
+ // Currently unused, as we use reflection to generate JSON
+ virtual void WriteToString(io::Printer* printer) = 0;
+
+ protected:
+ const FieldDescriptor* descriptor_;
+ const int presenceIndex_;
+ std::map<std::string, std::string> variables_;
+
+ void AddDeprecatedFlag(io::Printer* printer);
+ void AddNullCheck(io::Printer* printer);
+ void AddNullCheck(io::Printer* printer, const std::string& name);
+
+ void AddPublicMemberAttributes(io::Printer* printer);
+ void SetCommonOneofFieldVariables(
+ std::map<std::string, std::string>* variables);
+
+ std::string oneof_property_name();
+ std::string oneof_name();
+ std::string property_name();
+ std::string name();
+ std::string type_name();
+ std::string type_name(const FieldDescriptor* descriptor);
+ bool has_default_value();
+ std::string default_value();
+ std::string default_value(const FieldDescriptor* descriptor);
+ std::string number();
+ std::string capitalized_type_name();
+
+ private:
+ void SetCommonFieldVariables(std::map<std::string, std::string>* variables);
+ std::string GetStringDefaultValueInternal(const FieldDescriptor* descriptor);
+ std::string GetBytesDefaultValueInternal(const FieldDescriptor* descriptor);
+};
+
+} // namespace csharp
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_COMPILER_CSHARP_FIELD_BASE_H__
+
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_generator.cc b/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_generator.cc
new file mode 100644
index 00000000..ded055fb
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_generator.cc
@@ -0,0 +1,112 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 <sstream>
+
+#include <compiler/code_generator.h>
+#include <descriptor.h>
+#include <descriptor.pb.h>
+#include <io/printer.h>
+#include <io/zero_copy_stream.h>
+#include <stubs/strutil.h>
+
+#include <compiler/csharp/csharp_generator.h>
+#include <compiler/csharp/csharp_helpers.h>
+#include <compiler/csharp/csharp_names.h>
+#include <compiler/csharp/csharp_options.h>
+#include <compiler/csharp/csharp_reflection_class.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace csharp {
+
+Generator::Generator() {}
+Generator::~Generator() {}
+
+uint64_t Generator::GetSupportedFeatures() const {
+ return CodeGenerator::Feature::FEATURE_PROTO3_OPTIONAL;
+}
+
+void GenerateFile(const FileDescriptor* file, io::Printer* printer,
+ const Options* options) {
+ ReflectionClassGenerator reflectionClassGenerator(file, options);
+ reflectionClassGenerator.Generate(printer);
+}
+
+bool Generator::Generate(const FileDescriptor* file,
+ const std::string& parameter,
+ GeneratorContext* generator_context,
+ std::string* error) const {
+ std::vector<std::pair<std::string, std::string> > options;
+ ParseGeneratorParameter(parameter, &options);
+
+ struct Options cli_options;
+
+ for (int i = 0; i < options.size(); i++) {
+ if (options[i].first == "file_extension") {
+ cli_options.file_extension = options[i].second;
+ } else if (options[i].first == "base_namespace") {
+ cli_options.base_namespace = options[i].second;
+ cli_options.base_namespace_specified = true;
+ } else if (options[i].first == "internal_access") {
+ cli_options.internal_access = true;
+ } else if (options[i].first == "serializable") {
+ cli_options.serializable = true;
+ } else {
+ *error = "Unknown generator option: " + options[i].first;
+ return false;
+ }
+ }
+
+ std::string filename_error = "";
+ std::string filename = GetOutputFile(file,
+ cli_options.file_extension,
+ cli_options.base_namespace_specified,
+ cli_options.base_namespace,
+ &filename_error);
+
+ if (filename.empty()) {
+ *error = filename_error;
+ return false;
+ }
+ std::unique_ptr<io::ZeroCopyOutputStream> output(
+ generator_context->Open(filename));
+ io::Printer printer(output.get(), '$');
+
+ GenerateFile(file, &printer, &cli_options);
+
+ return true;
+}
+
+} // namespace csharp
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_generator.h b/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_generator.h
new file mode 100644
index 00000000..6f030cb2
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_generator.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.
+
+// Generates C# code for a given .proto file.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_CSHARP_GENERATOR_H__
+#define GOOGLE_PROTOBUF_COMPILER_CSHARP_GENERATOR_H__
+
+#include <string>
+
+#include <compiler/code_generator.h>
+
+#include <port_def.inc>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace csharp {
+
+// CodeGenerator implementation which generates a C# source file and
+// header. If you create your own protocol compiler binary and you want
+// it to support C# output, you can do so by registering an instance of this
+// CodeGenerator with the CommandLineInterface in your main() function.
+class PROTOC_EXPORT Generator : public CodeGenerator {
+ public:
+ Generator();
+ ~Generator();
+ bool Generate(
+ const FileDescriptor* file,
+ const std::string& parameter,
+ GeneratorContext* generator_context,
+ std::string* error) const override;
+ uint64_t GetSupportedFeatures() const override;
+};
+
+} // namespace csharp
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#include <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_COMPILER_CSHARP_GENERATOR_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_generator_unittest.cc b/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_generator_unittest.cc
new file mode 100644
index 00000000..c03f8855
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_generator_unittest.cc
@@ -0,0 +1,70 @@
+// 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.
+
+#include <memory>
+
+#include <compiler/command_line_interface.h>
+#include <compiler/csharp/csharp_helpers.h>
+#include <io/zero_copy_stream.h>
+#include <io/printer.h>
+
+#include <testing/googletest.h>
+#include <gtest/gtest.h>
+#include <testing/file.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace csharp {
+namespace {
+
+TEST(CSharpEnumValue, PascalCasedPrefixStripping) {
+ EXPECT_EQ("Bar", GetEnumValueName("Foo", "BAR"));
+ EXPECT_EQ("BarBaz", GetEnumValueName("Foo", "BAR_BAZ"));
+ EXPECT_EQ("Bar", GetEnumValueName("Foo", "FOO_BAR"));
+ EXPECT_EQ("Bar", GetEnumValueName("Foo", "FOO__BAR"));
+ EXPECT_EQ("BarBaz", GetEnumValueName("Foo", "FOO_BAR_BAZ"));
+ EXPECT_EQ("BarBaz", GetEnumValueName("Foo", "Foo_BarBaz"));
+ EXPECT_EQ("Bar", GetEnumValueName("FO_O", "FOO_BAR"));
+ EXPECT_EQ("Bar", GetEnumValueName("FOO", "F_O_O_BAR"));
+ EXPECT_EQ("Bar", GetEnumValueName("Foo", "BAR"));
+ EXPECT_EQ("BarBaz", GetEnumValueName("Foo", "BAR_BAZ"));
+ EXPECT_EQ("Foo", GetEnumValueName("Foo", "FOO"));
+ EXPECT_EQ("Foo", GetEnumValueName("Foo", "FOO___"));
+ // Identifiers can't start with digits
+ EXPECT_EQ("_2Bar", GetEnumValueName("Foo", "FOO_2_BAR"));
+ EXPECT_EQ("_2", GetEnumValueName("Foo", "FOO___2"));
+}
+
+} // namespace
+} // namespace csharp
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_helpers.cc b/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_helpers.cc
new file mode 100644
index 00000000..b703187d
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_helpers.cc
@@ -0,0 +1,592 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 <limits>
+#include <vector>
+#include <sstream>
+
+#include <compiler/csharp/csharp_helpers.h>
+#include <compiler/csharp/csharp_names.h>
+#include <descriptor.pb.h>
+#include <io/printer.h>
+#include <wire_format.h>
+#include <stubs/strutil.h>
+
+#include <compiler/csharp/csharp_field_base.h>
+#include <compiler/csharp/csharp_enum_field.h>
+#include <compiler/csharp/csharp_map_field.h>
+#include <compiler/csharp/csharp_message_field.h>
+#include <compiler/csharp/csharp_options.h>
+#include <compiler/csharp/csharp_primitive_field.h>
+#include <compiler/csharp/csharp_repeated_enum_field.h>
+#include <compiler/csharp/csharp_repeated_message_field.h>
+#include <compiler/csharp/csharp_repeated_primitive_field.h>
+#include <compiler/csharp/csharp_wrapper_field.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace csharp {
+
+CSharpType GetCSharpType(FieldDescriptor::Type type) {
+ switch (type) {
+ case FieldDescriptor::TYPE_INT32:
+ return CSHARPTYPE_INT32;
+ case FieldDescriptor::TYPE_INT64:
+ return CSHARPTYPE_INT64;
+ case FieldDescriptor::TYPE_UINT32:
+ return CSHARPTYPE_UINT32;
+ case FieldDescriptor::TYPE_UINT64:
+ return CSHARPTYPE_UINT32;
+ case FieldDescriptor::TYPE_SINT32:
+ return CSHARPTYPE_INT32;
+ case FieldDescriptor::TYPE_SINT64:
+ return CSHARPTYPE_INT64;
+ case FieldDescriptor::TYPE_FIXED32:
+ return CSHARPTYPE_UINT32;
+ case FieldDescriptor::TYPE_FIXED64:
+ return CSHARPTYPE_UINT64;
+ case FieldDescriptor::TYPE_SFIXED32:
+ return CSHARPTYPE_INT32;
+ case FieldDescriptor::TYPE_SFIXED64:
+ return CSHARPTYPE_INT64;
+ case FieldDescriptor::TYPE_FLOAT:
+ return CSHARPTYPE_FLOAT;
+ case FieldDescriptor::TYPE_DOUBLE:
+ return CSHARPTYPE_DOUBLE;
+ case FieldDescriptor::TYPE_BOOL:
+ return CSHARPTYPE_BOOL;
+ case FieldDescriptor::TYPE_ENUM:
+ return CSHARPTYPE_ENUM;
+ case FieldDescriptor::TYPE_STRING:
+ return CSHARPTYPE_STRING;
+ case FieldDescriptor::TYPE_BYTES:
+ return CSHARPTYPE_BYTESTRING;
+ case FieldDescriptor::TYPE_GROUP:
+ return CSHARPTYPE_MESSAGE;
+ case FieldDescriptor::TYPE_MESSAGE:
+ return CSHARPTYPE_MESSAGE;
+
+ // No default because we want the compiler to complain if any new
+ // types are added.
+ }
+ GOOGLE_LOG(FATAL)<< "Can't get here.";
+ return (CSharpType) -1;
+}
+
+std::string StripDotProto(const std::string& proto_file) {
+ int lastindex = proto_file.find_last_of(".");
+ return proto_file.substr(0, lastindex);
+}
+
+std::string GetFileNamespace(const FileDescriptor* descriptor) {
+ if (descriptor->options().has_csharp_namespace()) {
+ return descriptor->options().csharp_namespace();
+ }
+ return UnderscoresToCamelCase(descriptor->package(), true, true);
+}
+
+// Returns the Pascal-cased last part of the proto file. For example,
+// input of "google/protobuf/foo_bar.proto" would result in "FooBar".
+std::string GetFileNameBase(const FileDescriptor* descriptor) {
+ std::string proto_file = descriptor->name();
+ int lastslash = proto_file.find_last_of("/");
+ std::string base = proto_file.substr(lastslash + 1);
+ return UnderscoresToPascalCase(StripDotProto(base));
+}
+
+std::string GetReflectionClassUnqualifiedName(const FileDescriptor* descriptor) {
+ // TODO: Detect collisions with existing messages,
+ // and append an underscore if necessary.
+ return GetFileNameBase(descriptor) + "Reflection";
+}
+
+std::string GetExtensionClassUnqualifiedName(const FileDescriptor* descriptor) {
+ // TODO: Detect collisions with existing messages,
+ // and append an underscore if necessary.
+ return GetFileNameBase(descriptor) + "Extensions";
+}
+
+// TODO(jtattermusch): can we reuse a utility function?
+std::string UnderscoresToCamelCase(const std::string& input,
+ bool cap_next_letter,
+ bool preserve_period) {
+ std::string result;
+ // Note: I distrust ctype.h due to locales.
+ for (int i = 0; i < input.size(); i++) {
+ if ('a' <= input[i] && input[i] <= 'z') {
+ if (cap_next_letter) {
+ result += input[i] + ('A' - 'a');
+ } else {
+ result += input[i];
+ }
+ cap_next_letter = false;
+ } else if ('A' <= input[i] && input[i] <= 'Z') {
+ if (i == 0 && !cap_next_letter) {
+ // Force first letter to lower-case unless explicitly told to
+ // capitalize it.
+ result += input[i] + ('a' - 'A');
+ } else {
+ // Capital letters after the first are left as-is.
+ result += input[i];
+ }
+ cap_next_letter = false;
+ } else if ('0' <= input[i] && input[i] <= '9') {
+ result += input[i];
+ cap_next_letter = true;
+ } else {
+ cap_next_letter = true;
+ if (input[i] == '.' && preserve_period) {
+ result += '.';
+ }
+ }
+ }
+ // Add a trailing "_" if the name should be altered.
+ if (input.size() > 0 && input[input.size() - 1] == '#') {
+ result += '_';
+ }
+ return result;
+}
+
+std::string UnderscoresToPascalCase(const std::string& input) {
+ return UnderscoresToCamelCase(input, true);
+}
+
+// Convert a string which is expected to be SHOUTY_CASE (but may not be *precisely* shouty)
+// into a PascalCase string. Precise rules implemented:
+
+// Previous input character Current character Case
+// Any Non-alphanumeric Skipped
+// None - first char of input Alphanumeric Upper
+// Non-letter (e.g. _ or 1) Alphanumeric Upper
+// Numeric Alphanumeric Upper
+// Lower letter Alphanumeric Same as current
+// Upper letter Alphanumeric Lower
+std::string ShoutyToPascalCase(const std::string& input) {
+ std::string result;
+ // Simple way of implementing "always start with upper"
+ char previous = '_';
+ for (int i = 0; i < input.size(); i++) {
+ char current = input[i];
+ if (!ascii_isalnum(current)) {
+ previous = current;
+ continue;
+ }
+ if (!ascii_isalnum(previous)) {
+ result += ascii_toupper(current);
+ } else if (ascii_isdigit(previous)) {
+ result += ascii_toupper(current);
+ } else if (ascii_islower(previous)) {
+ result += current;
+ } else {
+ result += ascii_tolower(current);
+ }
+ previous = current;
+ }
+ return result;
+}
+
+// Attempt to remove a prefix from a value, ignoring casing and skipping underscores.
+// (foo, foo_bar) => bar - underscore after prefix is skipped
+// (FOO, foo_bar) => bar - casing is ignored
+// (foo_bar, foobarbaz) => baz - underscore in prefix is ignored
+// (foobar, foo_barbaz) => baz - underscore in value is ignored
+// (foo, bar) => bar - prefix isn't matched; return original value
+std::string TryRemovePrefix(const std::string& prefix, const std::string& value) {
+ // First normalize to a lower-case no-underscores prefix to match against
+ std::string prefix_to_match = "";
+ for (size_t i = 0; i < prefix.size(); i++) {
+ if (prefix[i] != '_') {
+ prefix_to_match += ascii_tolower(prefix[i]);
+ }
+ }
+
+ // This keeps track of how much of value we've consumed
+ size_t prefix_index, value_index;
+ for (prefix_index = 0, value_index = 0;
+ prefix_index < prefix_to_match.size() && value_index < value.size();
+ value_index++) {
+ // Skip over underscores in the value
+ if (value[value_index] == '_') {
+ continue;
+ }
+ if (ascii_tolower(value[value_index]) != prefix_to_match[prefix_index++]) {
+ // Failed to match the prefix - bail out early.
+ return value;
+ }
+ }
+
+ // If we didn't finish looking through the prefix, we can't strip it.
+ if (prefix_index < prefix_to_match.size()) {
+ return value;
+ }
+
+ // Step over any underscores after the prefix
+ while (value_index < value.size() && value[value_index] == '_') {
+ value_index++;
+ }
+
+ // If there's nothing left (e.g. it was a prefix with only underscores afterwards), don't strip.
+ if (value_index == value.size()) {
+ return value;
+ }
+
+ return value.substr(value_index);
+}
+
+// Format the enum value name in a pleasant way for C#:
+// - Strip the enum name as a prefix if possible
+// - Convert to PascalCase.
+// For example, an enum called Color with a value of COLOR_BLUE should
+// result in an enum value in C# called just Blue
+std::string GetEnumValueName(const std::string& enum_name, const std::string& enum_value_name) {
+ std::string stripped = TryRemovePrefix(enum_name, enum_value_name);
+ std::string result = ShoutyToPascalCase(stripped);
+ // Just in case we have an enum name of FOO and a value of FOO_2... make sure the returned
+ // string is a valid identifier.
+ if (ascii_isdigit(result[0])) {
+ result = "_" + result;
+ }
+ return result;
+}
+
+uint GetGroupEndTag(const Descriptor* descriptor) {
+ const Descriptor* containing_type = descriptor->containing_type();
+ if (containing_type != NULL) {
+ const FieldDescriptor* field;
+ for (int i = 0; i < containing_type->field_count(); i++) {
+ field = containing_type->field(i);
+ if (field->type() == FieldDescriptor::Type::TYPE_GROUP &&
+ field->message_type() == descriptor) {
+ return internal::WireFormatLite::MakeTag(
+ field->number(), internal::WireFormatLite::WIRETYPE_END_GROUP);
+ }
+ }
+ for (int i = 0; i < containing_type->extension_count(); i++) {
+ field = containing_type->extension(i);
+ if (field->type() == FieldDescriptor::Type::TYPE_GROUP &&
+ field->message_type() == descriptor) {
+ return internal::WireFormatLite::MakeTag(
+ field->number(), internal::WireFormatLite::WIRETYPE_END_GROUP);
+ }
+ }
+ } else {
+ const FileDescriptor* containing_file = descriptor->file();
+ if (containing_file != NULL) {
+ const FieldDescriptor* field;
+ for (int i = 0; i < containing_file->extension_count(); i++) {
+ field = containing_file->extension(i);
+ if (field->type() == FieldDescriptor::Type::TYPE_GROUP &&
+ field->message_type() == descriptor) {
+ return internal::WireFormatLite::MakeTag(
+ field->number(), internal::WireFormatLite::WIRETYPE_END_GROUP);
+ }
+ }
+ }
+ }
+
+ return 0;
+}
+
+std::string ToCSharpName(const std::string& name, const FileDescriptor* file) {
+ std::string result = GetFileNamespace(file);
+ if (!result.empty()) {
+ result += '.';
+ }
+ std::string classname;
+ if (file->package().empty()) {
+ classname = name;
+ } else {
+ // Strip the proto package from full_name since we've replaced it with
+ // the C# namespace.
+ classname = name.substr(file->package().size() + 1);
+ }
+ result += StringReplace(classname, ".", ".Types.", true);
+ return "global::" + result;
+}
+
+std::string GetReflectionClassName(const FileDescriptor* descriptor) {
+ std::string result = GetFileNamespace(descriptor);
+ if (!result.empty()) {
+ result += '.';
+ }
+ result += GetReflectionClassUnqualifiedName(descriptor);
+ return "global::" + result;
+}
+
+std::string GetFullExtensionName(const FieldDescriptor* descriptor) {
+ if (descriptor->extension_scope()) {
+ return GetClassName(descriptor->extension_scope()) + ".Extensions." + GetPropertyName(descriptor);
+ }
+ else {
+ return GetExtensionClassUnqualifiedName(descriptor->file()) + "." + GetPropertyName(descriptor);
+ }
+}
+
+std::string GetClassName(const Descriptor* descriptor) {
+ return ToCSharpName(descriptor->full_name(), descriptor->file());
+}
+
+std::string GetClassName(const EnumDescriptor* descriptor) {
+ return ToCSharpName(descriptor->full_name(), descriptor->file());
+}
+
+// Groups are hacky: The name of the field is just the lower-cased name
+// of the group type. In C#, though, we would like to retain the original
+// capitalization of the type name.
+std::string GetFieldName(const FieldDescriptor* descriptor) {
+ if (descriptor->type() == FieldDescriptor::TYPE_GROUP) {
+ return descriptor->message_type()->name();
+ } else {
+ return descriptor->name();
+ }
+}
+
+std::string GetFieldConstantName(const FieldDescriptor* field) {
+ return GetPropertyName(field) + "FieldNumber";
+}
+
+std::string GetPropertyName(const FieldDescriptor* descriptor) {
+ // TODO(jtattermusch): consider introducing csharp_property_name field option
+ std::string property_name = UnderscoresToPascalCase(GetFieldName(descriptor));
+ // Avoid either our own type name or reserved names. Note that not all names
+ // are reserved - a field called to_string, write_to etc would still cause a problem.
+ // There are various ways of ending up with naming collisions, but we try to avoid obvious
+ // ones.
+ if (property_name == descriptor->containing_type()->name()
+ || property_name == "Types"
+ || property_name == "Descriptor") {
+ property_name += "_";
+ }
+ return property_name;
+}
+
+std::string GetOutputFile(const FileDescriptor* descriptor,
+ const std::string file_extension,
+ const bool generate_directories,
+ const std::string base_namespace,
+ std::string* error) {
+ std::string relative_filename = GetFileNameBase(descriptor) + file_extension;
+ if (!generate_directories) {
+ return relative_filename;
+ }
+ std::string ns = GetFileNamespace(descriptor);
+ std::string namespace_suffix = ns;
+ if (!base_namespace.empty()) {
+ // Check that the base_namespace is either equal to or a leading part of
+ // the file namespace. This isn't just a simple prefix; "Foo.B" shouldn't
+ // be regarded as a prefix of "Foo.Bar". The simplest option is to add "."
+ // to both.
+ std::string extended_ns = ns + ".";
+ if (extended_ns.find(base_namespace + ".") != 0) {
+ *error = "Namespace " + ns + " is not a prefix namespace of base namespace " + base_namespace;
+ return ""; // This will be ignored, because we've set an error.
+ }
+ namespace_suffix = ns.substr(base_namespace.length());
+ if (namespace_suffix.find(".") == 0) {
+ namespace_suffix = namespace_suffix.substr(1);
+ }
+ }
+
+ std::string namespace_dir = StringReplace(namespace_suffix, ".", "/", true);
+ if (!namespace_dir.empty()) {
+ namespace_dir += "/";
+ }
+ return namespace_dir + relative_filename;
+}
+
+// TODO: c&p from Java protoc plugin
+// For encodings with fixed sizes, returns that size in bytes. Otherwise
+// returns -1.
+int GetFixedSize(FieldDescriptor::Type type) {
+ switch (type) {
+ case FieldDescriptor::TYPE_INT32 : return -1;
+ case FieldDescriptor::TYPE_INT64 : return -1;
+ case FieldDescriptor::TYPE_UINT32 : return -1;
+ case FieldDescriptor::TYPE_UINT64 : return -1;
+ case FieldDescriptor::TYPE_SINT32 : return -1;
+ case FieldDescriptor::TYPE_SINT64 : return -1;
+ case FieldDescriptor::TYPE_FIXED32 : return internal::WireFormatLite::kFixed32Size;
+ case FieldDescriptor::TYPE_FIXED64 : return internal::WireFormatLite::kFixed64Size;
+ case FieldDescriptor::TYPE_SFIXED32: return internal::WireFormatLite::kSFixed32Size;
+ case FieldDescriptor::TYPE_SFIXED64: return internal::WireFormatLite::kSFixed64Size;
+ case FieldDescriptor::TYPE_FLOAT : return internal::WireFormatLite::kFloatSize;
+ case FieldDescriptor::TYPE_DOUBLE : return internal::WireFormatLite::kDoubleSize;
+
+ case FieldDescriptor::TYPE_BOOL : return internal::WireFormatLite::kBoolSize;
+ case FieldDescriptor::TYPE_ENUM : return -1;
+
+ case FieldDescriptor::TYPE_STRING : return -1;
+ case FieldDescriptor::TYPE_BYTES : return -1;
+ case FieldDescriptor::TYPE_GROUP : return -1;
+ case FieldDescriptor::TYPE_MESSAGE : return -1;
+
+ // No default because we want the compiler to complain if any new
+ // types are added.
+ }
+ GOOGLE_LOG(FATAL) << "Can't get here.";
+ return -1;
+}
+
+static const char base64_chars[] =
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+std::string StringToBase64(const std::string& input) {
+ std::string result;
+ size_t remaining = input.size();
+ const unsigned char *src = (const unsigned char*) input.c_str();
+ while (remaining > 2) {
+ result += base64_chars[src[0] >> 2];
+ result += base64_chars[((src[0] & 0x3) << 4) | (src[1] >> 4)];
+ result += base64_chars[((src[1] & 0xf) << 2) | (src[2] >> 6)];
+ result += base64_chars[src[2] & 0x3f];
+ remaining -= 3;
+ src += 3;
+ }
+ switch (remaining) {
+ case 2:
+ result += base64_chars[src[0] >> 2];
+ result += base64_chars[((src[0] & 0x3) << 4) | (src[1] >> 4)];
+ result += base64_chars[(src[1] & 0xf) << 2];
+ result += '=';
+ src += 2;
+ break;
+ case 1:
+ result += base64_chars[src[0] >> 2];
+ result += base64_chars[((src[0] & 0x3) << 4)];
+ result += '=';
+ result += '=';
+ src += 1;
+ break;
+ }
+ return result;
+}
+
+std::string FileDescriptorToBase64(const FileDescriptor* descriptor) {
+ std::string fdp_bytes;
+ FileDescriptorProto fdp;
+ descriptor->CopyTo(&fdp);
+ fdp.SerializeToString(&fdp_bytes);
+ return StringToBase64(fdp_bytes);
+}
+
+FieldGeneratorBase* CreateFieldGenerator(const FieldDescriptor* descriptor,
+ int presenceIndex,
+ const Options* options) {
+ switch (descriptor->type()) {
+ case FieldDescriptor::TYPE_GROUP:
+ case FieldDescriptor::TYPE_MESSAGE:
+ if (descriptor->is_repeated()) {
+ if (descriptor->is_map()) {
+ return new MapFieldGenerator(descriptor, presenceIndex, options);
+ } else {
+ return new RepeatedMessageFieldGenerator(descriptor, presenceIndex, options);
+ }
+ } else {
+ if (IsWrapperType(descriptor)) {
+ if (descriptor->real_containing_oneof()) {
+ return new WrapperOneofFieldGenerator(descriptor, presenceIndex, options);
+ } else {
+ return new WrapperFieldGenerator(descriptor, presenceIndex, options);
+ }
+ } else {
+ if (descriptor->real_containing_oneof()) {
+ return new MessageOneofFieldGenerator(descriptor, presenceIndex, options);
+ } else {
+ return new MessageFieldGenerator(descriptor, presenceIndex, options);
+ }
+ }
+ }
+ case FieldDescriptor::TYPE_ENUM:
+ if (descriptor->is_repeated()) {
+ return new RepeatedEnumFieldGenerator(descriptor, presenceIndex, options);
+ } else {
+ if (descriptor->real_containing_oneof()) {
+ return new EnumOneofFieldGenerator(descriptor, presenceIndex, options);
+ } else {
+ return new EnumFieldGenerator(descriptor, presenceIndex, options);
+ }
+ }
+ default:
+ if (descriptor->is_repeated()) {
+ return new RepeatedPrimitiveFieldGenerator(descriptor, presenceIndex, options);
+ } else {
+ if (descriptor->real_containing_oneof()) {
+ return new PrimitiveOneofFieldGenerator(descriptor, presenceIndex, options);
+ } else {
+ return new PrimitiveFieldGenerator(descriptor, presenceIndex, options);
+ }
+ }
+ }
+}
+
+bool IsNullable(const FieldDescriptor* descriptor) {
+ if (descriptor->is_repeated()) {
+ return true;
+ }
+
+ switch (descriptor->type()) {
+ case FieldDescriptor::TYPE_ENUM:
+ case FieldDescriptor::TYPE_DOUBLE:
+ case FieldDescriptor::TYPE_FLOAT:
+ case FieldDescriptor::TYPE_INT64:
+ case FieldDescriptor::TYPE_UINT64:
+ case FieldDescriptor::TYPE_INT32:
+ case FieldDescriptor::TYPE_FIXED64:
+ case FieldDescriptor::TYPE_FIXED32:
+ case FieldDescriptor::TYPE_BOOL:
+ case FieldDescriptor::TYPE_UINT32:
+ case FieldDescriptor::TYPE_SFIXED32:
+ case FieldDescriptor::TYPE_SFIXED64:
+ case FieldDescriptor::TYPE_SINT32:
+ case FieldDescriptor::TYPE_SINT64:
+ return false;
+
+ case FieldDescriptor::TYPE_MESSAGE:
+ case FieldDescriptor::TYPE_GROUP:
+ case FieldDescriptor::TYPE_STRING:
+ case FieldDescriptor::TYPE_BYTES:
+ return true;
+
+ default:
+ GOOGLE_LOG(FATAL) << "Unknown field type.";
+ return true;
+ }
+}
+
+} // namespace csharp
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_helpers.h b/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_helpers.h
new file mode 100644
index 00000000..74d97152
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_helpers.h
@@ -0,0 +1,195 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 GOOGLE_PROTOBUF_COMPILER_CSHARP_HELPERS_H__
+#define GOOGLE_PROTOBUF_COMPILER_CSHARP_HELPERS_H__
+
+#include <string>
+#include <port.h>
+#include <stubs/common.h>
+#include <descriptor.pb.h>
+#include <descriptor.h>
+#include <compiler/code_generator.h>
+#include <io/printer.h>
+
+#include <port_def.inc>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace csharp {
+
+struct Options;
+class FieldGeneratorBase;
+
+// TODO: start using this enum.
+enum CSharpType {
+ CSHARPTYPE_INT32 = 1,
+ CSHARPTYPE_INT64 = 2,
+ CSHARPTYPE_UINT32 = 3,
+ CSHARPTYPE_UINT64 = 4,
+ CSHARPTYPE_FLOAT = 5,
+ CSHARPTYPE_DOUBLE = 6,
+ CSHARPTYPE_BOOL = 7,
+ CSHARPTYPE_STRING = 8,
+ CSHARPTYPE_BYTESTRING = 9,
+ CSHARPTYPE_MESSAGE = 10,
+ CSHARPTYPE_ENUM = 11,
+ MAX_CSHARPTYPE = 11
+};
+
+// Converts field type to corresponding C# type.
+CSharpType GetCSharpType(FieldDescriptor::Type type);
+
+std::string StripDotProto(const std::string& proto_file);
+
+// Gets unqualified name of the reflection class
+std::string GetReflectionClassUnqualifiedName(const FileDescriptor* descriptor);
+// Gets unqualified name of the extension class
+std::string GetExtensionClassUnqualifiedName(const FileDescriptor* descriptor);
+
+std::string GetClassName(const EnumDescriptor* descriptor);
+
+std::string GetFieldName(const FieldDescriptor* descriptor);
+
+std::string GetFieldConstantName(const FieldDescriptor* field);
+
+std::string GetPropertyName(const FieldDescriptor* descriptor);
+
+int GetFixedSize(FieldDescriptor::Type type);
+
+std::string UnderscoresToCamelCase(const std::string& input,
+ bool cap_next_letter,
+ bool preserve_period);
+
+inline std::string UnderscoresToCamelCase(const std::string& input, bool cap_next_letter) {
+ return UnderscoresToCamelCase(input, cap_next_letter, false);
+}
+
+std::string UnderscoresToPascalCase(const std::string& input);
+
+// Note that we wouldn't normally want to export this (we're not expecting
+// it to be used outside libprotoc itself) but this exposes it for testing.
+std::string PROTOC_EXPORT GetEnumValueName(const std::string& enum_name,
+ const std::string& enum_value_name);
+
+// TODO(jtattermusch): perhaps we could move this to strutil
+std::string StringToBase64(const std::string& input);
+
+std::string FileDescriptorToBase64(const FileDescriptor* descriptor);
+
+FieldGeneratorBase* CreateFieldGenerator(const FieldDescriptor* descriptor,
+ int presenceIndex,
+ const Options* options);
+
+std::string GetFullExtensionName(const FieldDescriptor* descriptor);
+
+bool IsNullable(const FieldDescriptor* descriptor);
+
+// Determines whether the given message is a map entry message,
+// i.e. one implicitly created by protoc due to a map<key, value> field.
+inline bool IsMapEntryMessage(const Descriptor* descriptor) {
+ return descriptor->options().map_entry();
+}
+
+// Checks if this descriptor is for a group and gets its end tag or 0 if it's not a group
+uint GetGroupEndTag(const Descriptor* descriptor);
+
+// Determines whether we're generating code for the proto representation of
+// descriptors etc, for use in the runtime. This is the only type which is
+// allowed to use proto2 syntax, and it generates internal classes.
+inline bool IsDescriptorProto(const FileDescriptor* descriptor) {
+ return descriptor->name() == "google/protobuf/descriptor.proto";
+}
+
+// Determines whether the given message is an options message within descriptor.proto.
+inline bool IsDescriptorOptionMessage(const Descriptor* descriptor) {
+ if (!IsDescriptorProto(descriptor->file())) {
+ return false;
+ }
+ const std::string name = descriptor->full_name();
+ return name == "google.protobuf.FileOptions" ||
+ name == "google.protobuf.MessageOptions" ||
+ name == "google.protobuf.FieldOptions" ||
+ name == "google.protobuf.OneofOptions" ||
+ name == "google.protobuf.EnumOptions" ||
+ name == "google.protobuf.EnumValueOptions" ||
+ name == "google.protobuf.ServiceOptions" ||
+ name == "google.protobuf.MethodOptions";
+}
+
+inline bool IsWrapperType(const FieldDescriptor* descriptor) {
+ return descriptor->type() == FieldDescriptor::TYPE_MESSAGE &&
+ descriptor->message_type()->file()->name() == "google/protobuf/wrappers.proto";
+}
+
+inline bool IsProto2(const FileDescriptor* descriptor) {
+ return descriptor->syntax() == FileDescriptor::SYNTAX_PROTO2;
+}
+
+inline bool SupportsPresenceApi(const FieldDescriptor* descriptor) {
+ // Unlike most languages, we don't generate Has/Clear members for message
+ // types, because they can always be set to null in C#. They're not really
+ // needed for oneof fields in proto2 either, as everything can be done via
+ // oneof case, but we follow the convention from other languages. Proto3
+ // oneof fields never have Has/Clear members - but will also never have
+ // the explicit optional keyword either.
+ //
+ // None of the built-in helpers (descriptor->has_presence() etc) describe
+ // quite the behavior we want, so the rules are explicit below.
+
+ if (descriptor->is_repeated() ||
+ descriptor->type() == FieldDescriptor::TYPE_MESSAGE) {
+ return false;
+ }
+ // has_optional_keyword() has more complex rules for proto2, but that
+ // doesn't matter given the first part of this condition.
+ return IsProto2(descriptor->file()) || descriptor->has_optional_keyword();
+}
+
+inline bool RequiresPresenceBit(const FieldDescriptor* descriptor) {
+ return SupportsPresenceApi(descriptor) &&
+ !IsNullable(descriptor) &&
+ !descriptor->is_extension() &&
+ !descriptor->real_containing_oneof();
+}
+
+} // namespace csharp
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#include <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_COMPILER_CSHARP_HELPERS_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_map_field.cc b/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_map_field.cc
new file mode 100644
index 00000000..7b4015da
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_map_field.cc
@@ -0,0 +1,152 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2015 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 <sstream>
+
+#include <compiler/code_generator.h>
+#include <descriptor.h>
+#include <descriptor.pb.h>
+#include <io/printer.h>
+#include <io/zero_copy_stream.h>
+#include <stubs/strutil.h>
+
+#include <compiler/csharp/csharp_doc_comment.h>
+#include <compiler/csharp/csharp_helpers.h>
+#include <compiler/csharp/csharp_map_field.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace csharp {
+
+MapFieldGenerator::MapFieldGenerator(const FieldDescriptor* descriptor,
+ int presenceIndex,
+ const Options* options)
+ : FieldGeneratorBase(descriptor, presenceIndex, options) {
+}
+
+MapFieldGenerator::~MapFieldGenerator() {
+}
+
+void MapFieldGenerator::GenerateMembers(io::Printer* printer) {
+ const FieldDescriptor* key_descriptor =
+ descriptor_->message_type()->FindFieldByName("key");
+ const FieldDescriptor* value_descriptor =
+ descriptor_->message_type()->FindFieldByName("value");
+ variables_["key_type_name"] = type_name(key_descriptor);
+ variables_["value_type_name"] = type_name(value_descriptor);
+ std::unique_ptr<FieldGeneratorBase> key_generator(
+ CreateFieldGenerator(key_descriptor, 1, this->options()));
+ std::unique_ptr<FieldGeneratorBase> value_generator(
+ CreateFieldGenerator(value_descriptor, 2, this->options()));
+
+ printer->Print(
+ variables_,
+ "private static readonly pbc::MapField<$key_type_name$, $value_type_name$>.Codec _map_$name$_codec\n"
+ " = new pbc::MapField<$key_type_name$, $value_type_name$>.Codec(");
+ key_generator->GenerateCodecCode(printer);
+ printer->Print(", ");
+ value_generator->GenerateCodecCode(printer);
+ printer->Print(
+ variables_,
+ ", $tag$);\n"
+ "private readonly pbc::MapField<$key_type_name$, $value_type_name$> $name$_ = new pbc::MapField<$key_type_name$, $value_type_name$>();\n");
+ WritePropertyDocComment(printer, descriptor_);
+ AddPublicMemberAttributes(printer);
+ printer->Print(
+ variables_,
+ "$access_level$ pbc::MapField<$key_type_name$, $value_type_name$> $property_name$ {\n"
+ " get { return $name$_; }\n"
+ "}\n");
+}
+
+void MapFieldGenerator::GenerateMergingCode(io::Printer* printer) {
+ printer->Print(
+ variables_,
+ "$name$_.Add(other.$name$_);\n");
+}
+
+void MapFieldGenerator::GenerateParsingCode(io::Printer* printer) {
+ GenerateParsingCode(printer, true);
+}
+
+void MapFieldGenerator::GenerateParsingCode(io::Printer* printer, bool use_parse_context) {
+ printer->Print(
+ variables_,
+ use_parse_context
+ ? "$name$_.AddEntriesFrom(ref input, _map_$name$_codec);\n"
+ : "$name$_.AddEntriesFrom(input, _map_$name$_codec);\n");
+}
+
+void MapFieldGenerator::GenerateSerializationCode(io::Printer* printer) {
+ GenerateSerializationCode(printer, true);
+}
+
+void MapFieldGenerator::GenerateSerializationCode(io::Printer* printer, bool use_write_context) {
+ printer->Print(
+ variables_,
+ use_write_context
+ ? "$name$_.WriteTo(ref output, _map_$name$_codec);\n"
+ : "$name$_.WriteTo(output, _map_$name$_codec);\n");
+}
+
+void MapFieldGenerator::GenerateSerializedSizeCode(io::Printer* printer) {
+ printer->Print(
+ variables_,
+ "size += $name$_.CalculateSize(_map_$name$_codec);\n");
+}
+
+void MapFieldGenerator::WriteHash(io::Printer* printer) {
+ printer->Print(
+ variables_,
+ "hash ^= $property_name$.GetHashCode();\n");
+}
+void MapFieldGenerator::WriteEquals(io::Printer* printer) {
+ printer->Print(
+ variables_,
+ "if (!$property_name$.Equals(other.$property_name$)) return false;\n");
+}
+
+void MapFieldGenerator::WriteToString(io::Printer* printer) {
+ // TODO: If we ever actually use ToString, we'll need to impleme this...
+}
+
+void MapFieldGenerator::GenerateCloningCode(io::Printer* printer) {
+ printer->Print(variables_,
+ "$name$_ = other.$name$_.Clone();\n");
+}
+
+void MapFieldGenerator::GenerateFreezingCode(io::Printer* printer) {
+}
+
+} // namespace csharp
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_map_field.h b/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_map_field.h
new file mode 100644
index 00000000..de16588c
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_map_field.h
@@ -0,0 +1,75 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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_COMPILER_CSHARP_MAP_FIELD_H__
+#define GOOGLE_PROTOBUF_COMPILER_CSHARP_MAP_FIELD_H__
+
+#include <string>
+
+#include <compiler/code_generator.h>
+#include <compiler/csharp/csharp_field_base.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace csharp {
+
+class MapFieldGenerator : public FieldGeneratorBase {
+ public:
+ MapFieldGenerator(const FieldDescriptor* descriptor,
+ int presenceIndex,
+ const Options* options);
+ ~MapFieldGenerator();
+
+ MapFieldGenerator(const MapFieldGenerator&) = delete;
+ MapFieldGenerator& operator=(const MapFieldGenerator&) = delete;
+
+ virtual void GenerateCloningCode(io::Printer* printer) override;
+ virtual void GenerateFreezingCode(io::Printer* printer) override;
+ virtual void GenerateMembers(io::Printer* printer) override;
+ virtual void GenerateMergingCode(io::Printer* printer) override;
+ virtual void GenerateParsingCode(io::Printer* printer) override;
+ virtual void GenerateParsingCode(io::Printer* printer, bool use_parse_context) override;
+ virtual void GenerateSerializationCode(io::Printer* printer) override;
+ virtual void GenerateSerializationCode(io::Printer* printer, bool use_write_context) override;
+ virtual void GenerateSerializedSizeCode(io::Printer* printer) override;
+
+ virtual void WriteHash(io::Printer* printer) override;
+ virtual void WriteEquals(io::Printer* printer) override;
+ virtual void WriteToString(io::Printer* printer) override;
+};
+
+} // namespace csharp
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_COMPILER_CSHARP_MAP_FIELD_H__
+
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_message.cc b/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_message.cc
new file mode 100644
index 00000000..963b9c87
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_message.cc
@@ -0,0 +1,779 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <sstream>
+#include <algorithm>
+#include <map>
+
+#include <compiler/code_generator.h>
+#include <descriptor.h>
+#include <descriptor.pb.h>
+#include <io/printer.h>
+#include <io/zero_copy_stream.h>
+#include <stubs/strutil.h>
+#include <wire_format.h>
+#include <wire_format_lite.h>
+
+#include <compiler/csharp/csharp_options.h>
+#include <compiler/csharp/csharp_doc_comment.h>
+#include <compiler/csharp/csharp_enum.h>
+#include <compiler/csharp/csharp_field_base.h>
+#include <compiler/csharp/csharp_helpers.h>
+#include <compiler/csharp/csharp_message.h>
+#include <compiler/csharp/csharp_names.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace csharp {
+
+bool CompareFieldNumbers(const FieldDescriptor* d1, const FieldDescriptor* d2) {
+ return d1->number() < d2->number();
+}
+
+MessageGenerator::MessageGenerator(const Descriptor* descriptor,
+ const Options* options)
+ : SourceGeneratorBase(options),
+ descriptor_(descriptor),
+ has_bit_field_count_(0),
+ end_tag_(GetGroupEndTag(descriptor)),
+ has_extension_ranges_(descriptor->extension_range_count() > 0) {
+ // fields by number
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ fields_by_number_.push_back(descriptor_->field(i));
+ }
+ std::sort(fields_by_number_.begin(), fields_by_number_.end(),
+ CompareFieldNumbers);
+
+ int presence_bit_count = 0;
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ const FieldDescriptor* field = descriptor_->field(i);
+ if (RequiresPresenceBit(field)) {
+ presence_bit_count++;
+ if (has_bit_field_count_ == 0 || (presence_bit_count % 32) == 0) {
+ has_bit_field_count_++;
+ }
+ }
+ }
+}
+
+MessageGenerator::~MessageGenerator() {
+}
+
+std::string MessageGenerator::class_name() {
+ return descriptor_->name();
+}
+
+std::string MessageGenerator::full_class_name() {
+ return GetClassName(descriptor_);
+}
+
+const std::vector<const FieldDescriptor*>& MessageGenerator::fields_by_number() {
+ return fields_by_number_;
+}
+
+void MessageGenerator::AddDeprecatedFlag(io::Printer* printer) {
+ if (descriptor_->options().deprecated()) {
+ printer->Print("[global::System.ObsoleteAttribute]\n");
+ }
+}
+
+void MessageGenerator::AddSerializableAttribute(io::Printer* printer) {
+ if (this->options()->serializable) {
+ printer->Print("[global::System.SerializableAttribute]\n");
+ }
+}
+
+void MessageGenerator::Generate(io::Printer* printer) {
+ std::map<std::string, std::string> vars;
+ vars["class_name"] = class_name();
+ vars["access_level"] = class_access_level();
+
+ WriteMessageDocComment(printer, descriptor_);
+ AddDeprecatedFlag(printer);
+ AddSerializableAttribute(printer);
+
+ printer->Print(
+ vars,
+ "$access_level$ sealed partial class $class_name$ : ");
+
+ if (has_extension_ranges_) {
+ printer->Print(vars, "pb::IExtendableMessage<$class_name$>\n");
+ }
+ else {
+ printer->Print(vars, "pb::IMessage<$class_name$>\n");
+ }
+ printer->Print("#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE\n");
+ printer->Print(" , pb::IBufferMessage\n");
+ printer->Print("#endif\n");
+ printer->Print("{\n");
+ printer->Indent();
+
+ // All static fields and properties
+ printer->Print(
+ vars,
+ "private static readonly pb::MessageParser<$class_name$> _parser = new pb::MessageParser<$class_name$>(() => new $class_name$());\n");
+
+ printer->Print(
+ "private pb::UnknownFieldSet _unknownFields;\n");
+
+ if (has_extension_ranges_) {
+ if (IsDescriptorProto(descriptor_->file())) {
+ printer->Print(vars, "internal pb::ExtensionSet<$class_name$> _extensions;\n"); // CustomOptions compatibility
+ } else {
+ printer->Print(vars, "private pb::ExtensionSet<$class_name$> _extensions;\n");
+ }
+
+ // a read-only property for fast
+ // retrieval of the set in IsInitialized
+ printer->Print(vars,
+ "private pb::ExtensionSet<$class_name$> _Extensions { get { "
+ "return _extensions; } }\n");
+ }
+
+ for (int i = 0; i < has_bit_field_count_; i++) {
+ // don't use arrays since all arrays are heap allocated, saving allocations
+ // use ints instead of bytes since bytes lack bitwise operators, saving casts
+ printer->Print("private int _hasBits$i$;\n", "i", StrCat(i));
+ }
+
+ WriteGeneratedCodeAttributes(printer);
+
+ printer->Print(
+ vars,
+ "public static pb::MessageParser<$class_name$> Parser { get { return _parser; } }\n\n");
+
+ // Access the message descriptor via the relevant file descriptor or containing message descriptor.
+ if (!descriptor_->containing_type()) {
+ vars["descriptor_accessor"] = GetReflectionClassName(descriptor_->file())
+ + ".Descriptor.MessageTypes[" + StrCat(descriptor_->index()) + "]";
+ } else {
+ vars["descriptor_accessor"] = GetClassName(descriptor_->containing_type())
+ + ".Descriptor.NestedTypes[" + StrCat(descriptor_->index()) + "]";
+ }
+
+ WriteGeneratedCodeAttributes(printer);
+ printer->Print(
+ vars,
+ "public static pbr::MessageDescriptor Descriptor {\n"
+ " get { return $descriptor_accessor$; }\n"
+ "}\n"
+ "\n");
+ WriteGeneratedCodeAttributes(printer);
+ printer->Print(
+ vars,
+ "pbr::MessageDescriptor pb::IMessage.Descriptor {\n"
+ " get { return Descriptor; }\n"
+ "}\n"
+ "\n");
+
+ // Parameterless constructor and partial OnConstruction method.
+ WriteGeneratedCodeAttributes(printer);
+ printer->Print(
+ vars,
+ "public $class_name$() {\n"
+ " OnConstruction();\n"
+ "}\n\n"
+ "partial void OnConstruction();\n\n");
+
+ GenerateCloningCode(printer);
+ GenerateFreezingCode(printer);
+
+ // Fields/properties
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ const FieldDescriptor* fieldDescriptor = descriptor_->field(i);
+
+ // Rats: we lose the debug comment here :(
+ printer->Print(
+ "/// <summary>Field number for the \"$field_name$\" field.</summary>\n"
+ "public const int $field_constant_name$ = $index$;\n",
+ "field_name", fieldDescriptor->name(),
+ "field_constant_name", GetFieldConstantName(fieldDescriptor),
+ "index", StrCat(fieldDescriptor->number()));
+ std::unique_ptr<FieldGeneratorBase> generator(
+ CreateFieldGeneratorInternal(fieldDescriptor));
+ generator->GenerateMembers(printer);
+ printer->Print("\n");
+ }
+
+ // oneof properties (for real oneofs, which come before synthetic ones)
+ for (int i = 0; i < descriptor_->real_oneof_decl_count(); i++) {
+ const OneofDescriptor* oneof = descriptor_->oneof_decl(i);
+ vars["name"] = UnderscoresToCamelCase(oneof->name(), false);
+ vars["property_name"] = UnderscoresToCamelCase(oneof->name(), true);
+ vars["original_name"] = oneof->name();
+ printer->Print(
+ vars,
+ "private object $name$_;\n"
+ "/// <summary>Enum of possible cases for the \"$original_name$\" oneof.</summary>\n"
+ "public enum $property_name$OneofCase {\n");
+ printer->Indent();
+ printer->Print("None = 0,\n");
+ for (int j = 0; j < oneof->field_count(); j++) {
+ const FieldDescriptor* field = oneof->field(j);
+ printer->Print("$field_property_name$ = $index$,\n",
+ "field_property_name", GetPropertyName(field),
+ "index", StrCat(field->number()));
+ }
+ printer->Outdent();
+ printer->Print("}\n");
+ // TODO: Should we put the oneof .proto comments here?
+ // It's unclear exactly where they should go.
+ printer->Print(
+ vars,
+ "private $property_name$OneofCase $name$Case_ = $property_name$OneofCase.None;\n");
+ WriteGeneratedCodeAttributes(printer);
+ printer->Print(
+ vars,
+ "public $property_name$OneofCase $property_name$Case {\n"
+ " get { return $name$Case_; }\n"
+ "}\n\n");
+ WriteGeneratedCodeAttributes(printer);
+ printer->Print(
+ vars,
+ "public void Clear$property_name$() {\n"
+ " $name$Case_ = $property_name$OneofCase.None;\n"
+ " $name$_ = null;\n"
+ "}\n\n");
+ }
+
+ // Standard methods
+ GenerateFrameworkMethods(printer);
+ GenerateMessageSerializationMethods(printer);
+ GenerateMergingMethods(printer);
+
+ if (has_extension_ranges_) {
+ printer->Print(
+ vars,
+ "public TValue GetExtension<TValue>(pb::Extension<$class_name$, "
+ "TValue> extension) {\n"
+ " return pb::ExtensionSet.Get(ref _extensions, extension);\n"
+ "}\n"
+ "public pbc::RepeatedField<TValue> "
+ "GetExtension<TValue>(pb::RepeatedExtension<$class_name$, TValue> "
+ "extension) {\n"
+ " return pb::ExtensionSet.Get(ref _extensions, extension);\n"
+ "}\n"
+ "public pbc::RepeatedField<TValue> "
+ "GetOrInitializeExtension<TValue>(pb::RepeatedExtension<$class_name$, "
+ "TValue> extension) {\n"
+ " return pb::ExtensionSet.GetOrInitialize(ref _extensions, "
+ "extension);\n"
+ "}\n"
+ "public void SetExtension<TValue>(pb::Extension<$class_name$, TValue> "
+ "extension, TValue value) {\n"
+ " pb::ExtensionSet.Set(ref _extensions, extension, value);\n"
+ "}\n"
+ "public bool HasExtension<TValue>(pb::Extension<$class_name$, TValue> "
+ "extension) {\n"
+ " return pb::ExtensionSet.Has(ref _extensions, extension);\n"
+ "}\n"
+ "public void ClearExtension<TValue>(pb::Extension<$class_name$, "
+ "TValue> extension) {\n"
+ " pb::ExtensionSet.Clear(ref _extensions, extension);\n"
+ "}\n"
+ "public void "
+ "ClearExtension<TValue>(pb::RepeatedExtension<$class_name$, TValue> "
+ "extension) {\n"
+ " pb::ExtensionSet.Clear(ref _extensions, extension);\n"
+ "}\n\n");
+ }
+
+ // Nested messages and enums
+ if (HasNestedGeneratedTypes()) {
+ printer->Print(
+ vars,
+ "#region Nested types\n"
+ "/// <summary>Container for nested types declared in the $class_name$ message type.</summary>\n");
+ WriteGeneratedCodeAttributes(printer);
+ printer->Print("public static partial class Types {\n");
+ printer->Indent();
+ for (int i = 0; i < descriptor_->enum_type_count(); i++) {
+ EnumGenerator enumGenerator(descriptor_->enum_type(i), this->options());
+ enumGenerator.Generate(printer);
+ }
+ for (int i = 0; i < descriptor_->nested_type_count(); i++) {
+ // Don't generate nested types for maps...
+ if (!IsMapEntryMessage(descriptor_->nested_type(i))) {
+ MessageGenerator messageGenerator(
+ descriptor_->nested_type(i), this->options());
+ messageGenerator.Generate(printer);
+ }
+ }
+ printer->Outdent();
+ printer->Print("}\n"
+ "#endregion\n"
+ "\n");
+ }
+
+ if (descriptor_->extension_count() > 0) {
+ printer->Print(
+ vars,
+ "#region Extensions\n"
+ "/// <summary>Container for extensions for other messages declared in the $class_name$ message type.</summary>\n");
+ WriteGeneratedCodeAttributes(printer);
+ printer->Print("public static partial class Extensions {\n");
+ printer->Indent();
+ for (int i = 0; i < descriptor_->extension_count(); i++) {
+ std::unique_ptr<FieldGeneratorBase> generator(
+ CreateFieldGeneratorInternal(descriptor_->extension(i)));
+ generator->GenerateExtensionCode(printer);
+ }
+ printer->Outdent();
+ printer->Print(
+ "}\n"
+ "#endregion\n"
+ "\n");
+ }
+
+ printer->Outdent();
+ printer->Print("}\n");
+ printer->Print("\n");
+}
+
+// Helper to work out whether we need to generate a class to hold nested types/enums.
+// Only tricky because we don't want to generate map entry types.
+bool MessageGenerator::HasNestedGeneratedTypes()
+{
+ if (descriptor_->enum_type_count() > 0) {
+ return true;
+ }
+ for (int i = 0; i < descriptor_->nested_type_count(); i++) {
+ if (!IsMapEntryMessage(descriptor_->nested_type(i))) {
+ return true;
+ }
+ }
+ return false;
+}
+
+void MessageGenerator::GenerateCloningCode(io::Printer* printer) {
+ std::map<std::string, std::string> vars;
+ WriteGeneratedCodeAttributes(printer);
+ vars["class_name"] = class_name();
+ printer->Print(
+ vars,
+ "public $class_name$($class_name$ other) : this() {\n");
+ printer->Indent();
+ for (int i = 0; i < has_bit_field_count_; i++) {
+ printer->Print("_hasBits$i$ = other._hasBits$i$;\n", "i", StrCat(i));
+ }
+ // Clone non-oneof fields first (treating optional proto3 fields as non-oneof)
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ const FieldDescriptor* field = descriptor_->field(i);
+ if (field->real_containing_oneof()) {
+ continue;
+ }
+ std::unique_ptr<FieldGeneratorBase> generator(CreateFieldGeneratorInternal(field));
+ generator->GenerateCloningCode(printer);
+ }
+ // Clone just the right field for each real oneof
+ for (int i = 0; i < descriptor_->real_oneof_decl_count(); ++i) {
+ const OneofDescriptor* oneof = descriptor_->oneof_decl(i);
+ vars["name"] = UnderscoresToCamelCase(oneof->name(), false);
+ vars["property_name"] = UnderscoresToCamelCase(oneof->name(), true);
+ printer->Print(vars, "switch (other.$property_name$Case) {\n");
+ printer->Indent();
+ for (int j = 0; j < oneof->field_count(); j++) {
+ const FieldDescriptor* field = oneof->field(j);
+ std::unique_ptr<FieldGeneratorBase> generator(CreateFieldGeneratorInternal(field));
+ vars["field_property_name"] = GetPropertyName(field);
+ printer->Print(
+ vars,
+ "case $property_name$OneofCase.$field_property_name$:\n");
+ printer->Indent();
+ generator->GenerateCloningCode(printer);
+ printer->Print("break;\n");
+ printer->Outdent();
+ }
+ printer->Outdent();
+ printer->Print("}\n\n");
+ }
+ // Clone unknown fields
+ printer->Print(
+ "_unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);\n");
+ if (has_extension_ranges_) {
+ printer->Print(
+ "_extensions = pb::ExtensionSet.Clone(other._extensions);\n");
+ }
+
+ printer->Outdent();
+ printer->Print("}\n\n");
+
+ WriteGeneratedCodeAttributes(printer);
+ printer->Print(
+ vars,
+ "public $class_name$ Clone() {\n"
+ " return new $class_name$(this);\n"
+ "}\n\n");
+}
+
+void MessageGenerator::GenerateFreezingCode(io::Printer* printer) {
+}
+
+void MessageGenerator::GenerateFrameworkMethods(io::Printer* printer) {
+ std::map<std::string, std::string> vars;
+ vars["class_name"] = class_name();
+
+ // Equality
+ WriteGeneratedCodeAttributes(printer);
+ printer->Print(
+ vars,
+ "public override bool Equals(object other) {\n"
+ " return Equals(other as $class_name$);\n"
+ "}\n\n");
+ WriteGeneratedCodeAttributes(printer);
+ printer->Print(
+ vars,
+ "public bool Equals($class_name$ other) {\n"
+ " if (ReferenceEquals(other, null)) {\n"
+ " return false;\n"
+ " }\n"
+ " if (ReferenceEquals(other, this)) {\n"
+ " return true;\n"
+ " }\n");
+ printer->Indent();
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ std::unique_ptr<FieldGeneratorBase> generator(
+ CreateFieldGeneratorInternal(descriptor_->field(i)));
+ generator->WriteEquals(printer);
+ }
+ for (int i = 0; i < descriptor_->real_oneof_decl_count(); i++) {
+ printer->Print("if ($property_name$Case != other.$property_name$Case) return false;\n",
+ "property_name", UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), true));
+ }
+ if (has_extension_ranges_) {
+ printer->Print(
+ "if (!Equals(_extensions, other._extensions)) {\n"
+ " return false;\n"
+ "}\n");
+ }
+ printer->Outdent();
+ printer->Print(
+ " return Equals(_unknownFields, other._unknownFields);\n"
+ "}\n\n");
+
+ // GetHashCode
+ // Start with a non-zero value to easily distinguish between null and "empty" messages.
+ WriteGeneratedCodeAttributes(printer);
+ printer->Print(
+ "public override int GetHashCode() {\n"
+ " int hash = 1;\n");
+ printer->Indent();
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ std::unique_ptr<FieldGeneratorBase> generator(
+ CreateFieldGeneratorInternal(descriptor_->field(i)));
+ generator->WriteHash(printer);
+ }
+ for (int i = 0; i < descriptor_->real_oneof_decl_count(); i++) {
+ printer->Print("hash ^= (int) $name$Case_;\n",
+ "name", UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), false));
+ }
+ if (has_extension_ranges_) {
+ printer->Print(
+ "if (_extensions != null) {\n"
+ " hash ^= _extensions.GetHashCode();\n"
+ "}\n");
+ }
+ printer->Print(
+ "if (_unknownFields != null) {\n"
+ " hash ^= _unknownFields.GetHashCode();\n"
+ "}\n"
+ "return hash;\n");
+ printer->Outdent();
+ printer->Print("}\n\n");
+
+ WriteGeneratedCodeAttributes(printer);
+ printer->Print(
+ "public override string ToString() {\n"
+ " return pb::JsonFormatter.ToDiagnosticString(this);\n"
+ "}\n\n");
+}
+
+void MessageGenerator::GenerateMessageSerializationMethods(io::Printer* printer) {
+ WriteGeneratedCodeAttributes(printer);
+ printer->Print(
+ "public void WriteTo(pb::CodedOutputStream output) {\n");
+ printer->Print("#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE\n");
+ printer->Indent();
+ printer->Print("output.WriteRawMessage(this);\n");
+ printer->Outdent();
+ printer->Print("#else\n");
+ printer->Indent();
+ GenerateWriteToBody(printer, false);
+ printer->Outdent();
+ printer->Print("#endif\n");
+ printer->Print("}\n\n");
+
+ printer->Print("#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE\n");
+ WriteGeneratedCodeAttributes(printer);
+ printer->Print("void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {\n");
+ printer->Indent();
+ GenerateWriteToBody(printer, true);
+ printer->Outdent();
+ printer->Print("}\n");
+ printer->Print("#endif\n\n");
+
+ WriteGeneratedCodeAttributes(printer);
+ printer->Print(
+ "public int CalculateSize() {\n");
+ printer->Indent();
+ printer->Print("int size = 0;\n");
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ std::unique_ptr<FieldGeneratorBase> generator(
+ CreateFieldGeneratorInternal(descriptor_->field(i)));
+ generator->GenerateSerializedSizeCode(printer);
+ }
+
+ if (has_extension_ranges_) {
+ printer->Print(
+ "if (_extensions != null) {\n"
+ " size += _extensions.CalculateSize();\n"
+ "}\n");
+ }
+
+ printer->Print(
+ "if (_unknownFields != null) {\n"
+ " size += _unknownFields.CalculateSize();\n"
+ "}\n");
+
+ printer->Print("return size;\n");
+ printer->Outdent();
+ printer->Print("}\n\n");
+}
+
+void MessageGenerator::GenerateWriteToBody(io::Printer* printer, bool use_write_context) {
+ // Serialize all the fields
+ for (int i = 0; i < fields_by_number().size(); i++) {
+ std::unique_ptr<FieldGeneratorBase> generator(
+ CreateFieldGeneratorInternal(fields_by_number()[i]));
+ generator->GenerateSerializationCode(printer, use_write_context);
+ }
+
+ if (has_extension_ranges_) {
+ // Serialize extensions
+ printer->Print(
+ use_write_context
+ ? "if (_extensions != null) {\n"
+ " _extensions.WriteTo(ref output);\n"
+ "}\n"
+ : "if (_extensions != null) {\n"
+ " _extensions.WriteTo(output);\n"
+ "}\n");
+ }
+
+ // Serialize unknown fields
+ printer->Print(
+ use_write_context
+ ? "if (_unknownFields != null) {\n"
+ " _unknownFields.WriteTo(ref output);\n"
+ "}\n"
+ : "if (_unknownFields != null) {\n"
+ " _unknownFields.WriteTo(output);\n"
+ "}\n");
+
+ // TODO(jonskeet): Memoize size of frozen messages?
+}
+
+void MessageGenerator::GenerateMergingMethods(io::Printer* printer) {
+ // Note: These are separate from GenerateMessageSerializationMethods()
+ // because they need to be generated even for messages that are optimized
+ // for code size.
+ std::map<std::string, std::string> vars;
+ vars["class_name"] = class_name();
+
+ WriteGeneratedCodeAttributes(printer);
+ printer->Print(
+ vars,
+ "public void MergeFrom($class_name$ other) {\n");
+ printer->Indent();
+ printer->Print(
+ "if (other == null) {\n"
+ " return;\n"
+ "}\n");
+ // Merge non-oneof fields, treating optional proto3 fields as normal fields
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ const FieldDescriptor* field = descriptor_->field(i);
+ if (field->real_containing_oneof()) {
+ continue;
+ }
+ std::unique_ptr<FieldGeneratorBase> generator(CreateFieldGeneratorInternal(field));
+ generator->GenerateMergingCode(printer);
+ }
+ // Merge oneof fields (for non-synthetic oneofs)
+ for (int i = 0; i < descriptor_->real_oneof_decl_count(); ++i) {
+ const OneofDescriptor* oneof = descriptor_->oneof_decl(i);
+ vars["name"] = UnderscoresToCamelCase(oneof->name(), false);
+ vars["property_name"] = UnderscoresToCamelCase(oneof->name(), true);
+ printer->Print(vars, "switch (other.$property_name$Case) {\n");
+ printer->Indent();
+ for (int j = 0; j < oneof->field_count(); j++) {
+ const FieldDescriptor* field = oneof->field(j);
+ vars["field_property_name"] = GetPropertyName(field);
+ printer->Print(
+ vars,
+ "case $property_name$OneofCase.$field_property_name$:\n");
+ printer->Indent();
+ std::unique_ptr<FieldGeneratorBase> generator(CreateFieldGeneratorInternal(field));
+ generator->GenerateMergingCode(printer);
+ printer->Print("break;\n");
+ printer->Outdent();
+ }
+ printer->Outdent();
+ printer->Print("}\n\n");
+ }
+ // Merge extensions
+ if (has_extension_ranges_) {
+ printer->Print("pb::ExtensionSet.MergeFrom(ref _extensions, other._extensions);\n");
+ }
+
+ // Merge unknown fields.
+ printer->Print(
+ "_unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);\n");
+
+ printer->Outdent();
+ printer->Print("}\n\n");
+
+ WriteGeneratedCodeAttributes(printer);
+ printer->Print("public void MergeFrom(pb::CodedInputStream input) {\n");
+ printer->Print("#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE\n");
+ printer->Indent();
+ printer->Print("input.ReadRawMessage(this);\n");
+ printer->Outdent();
+ printer->Print("#else\n");
+ printer->Indent();
+ GenerateMainParseLoop(printer, false);
+ printer->Outdent();
+ printer->Print("#endif\n");
+ printer->Print("}\n\n");
+
+ printer->Print("#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE\n");
+ WriteGeneratedCodeAttributes(printer);
+ printer->Print("void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) {\n");
+ printer->Indent();
+ GenerateMainParseLoop(printer, true);
+ printer->Outdent();
+ printer->Print("}\n"); // method
+ printer->Print("#endif\n\n");
+
+}
+
+void MessageGenerator::GenerateMainParseLoop(io::Printer* printer, bool use_parse_context) {
+ std::map<std::string, std::string> vars;
+ vars["maybe_ref_input"] = use_parse_context ? "ref input" : "input";
+
+ printer->Print(
+ "uint tag;\n"
+ "while ((tag = input.ReadTag()) != 0) {\n"
+ " switch(tag) {\n");
+ printer->Indent();
+ printer->Indent();
+ if (end_tag_ != 0) {
+ printer->Print(
+ "case $end_tag$:\n"
+ " return;\n",
+ "end_tag", StrCat(end_tag_));
+ }
+ if (has_extension_ranges_) {
+ printer->Print(vars,
+ "default:\n"
+ " if (!pb::ExtensionSet.TryMergeFieldFrom(ref _extensions, $maybe_ref_input$)) {\n"
+ " _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, $maybe_ref_input$);\n"
+ " }\n"
+ " break;\n");
+ } else {
+ printer->Print(vars,
+ "default:\n"
+ " _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, $maybe_ref_input$);\n"
+ " break;\n");
+ }
+ for (int i = 0; i < fields_by_number().size(); i++) {
+ const FieldDescriptor* field = fields_by_number()[i];
+ internal::WireFormatLite::WireType wt =
+ internal::WireFormat::WireTypeForFieldType(field->type());
+ uint32 tag = internal::WireFormatLite::MakeTag(field->number(), wt);
+ // Handle both packed and unpacked repeated fields with the same Read*Array call;
+ // the two generated cases are the packed and unpacked tags.
+ // TODO(jonskeet): Check that is_packable is equivalent to
+ // is_repeated && wt in { VARINT, FIXED32, FIXED64 }.
+ // It looks like it is...
+ if (field->is_packable()) {
+ printer->Print(
+ "case $packed_tag$:\n",
+ "packed_tag",
+ StrCat(
+ internal::WireFormatLite::MakeTag(
+ field->number(),
+ internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED)));
+ }
+
+ printer->Print("case $tag$: {\n", "tag", StrCat(tag));
+ printer->Indent();
+ std::unique_ptr<FieldGeneratorBase> generator(
+ CreateFieldGeneratorInternal(field));
+ generator->GenerateParsingCode(printer, use_parse_context);
+ printer->Print("break;\n");
+ printer->Outdent();
+ printer->Print("}\n");
+ }
+ printer->Outdent();
+ printer->Print("}\n"); // switch
+ printer->Outdent();
+ printer->Print("}\n"); // while
+}
+
+// it's a waste of space to track presence for all values, so we only track them if they're not nullable
+int MessageGenerator::GetPresenceIndex(const FieldDescriptor* descriptor) {
+ if (!RequiresPresenceBit(descriptor)) {
+ return -1;
+ }
+
+ int index = 0;
+ for (int i = 0; i < fields_by_number().size(); i++) {
+ const FieldDescriptor* field = fields_by_number()[i];
+ if (field == descriptor) {
+ return index;
+ }
+ if (RequiresPresenceBit(field)) {
+ index++;
+ }
+ }
+ GOOGLE_LOG(DFATAL)<< "Could not find presence index for field " << descriptor->name();
+ return -1;
+}
+
+FieldGeneratorBase* MessageGenerator::CreateFieldGeneratorInternal(
+ const FieldDescriptor* descriptor) {
+ return CreateFieldGenerator(descriptor, GetPresenceIndex(descriptor), this->options());
+}
+
+} // namespace csharp
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_message.h b/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_message.h
new file mode 100644
index 00000000..cdb31f80
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_message.h
@@ -0,0 +1,94 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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_COMPILER_CSHARP_MESSAGE_H__
+#define GOOGLE_PROTOBUF_COMPILER_CSHARP_MESSAGE_H__
+
+#include <string>
+#include <vector>
+
+#include <compiler/code_generator.h>
+#include <compiler/csharp/csharp_source_generator_base.h>
+#include <compiler/csharp/csharp_helpers.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace csharp {
+
+class FieldGeneratorBase;
+
+class MessageGenerator : public SourceGeneratorBase {
+ public:
+ MessageGenerator(const Descriptor* descriptor, const Options* options);
+ ~MessageGenerator();
+
+ MessageGenerator(const MessageGenerator&) = delete;
+ MessageGenerator& operator=(const MessageGenerator&) = delete;
+
+ void GenerateCloningCode(io::Printer* printer);
+ void GenerateFreezingCode(io::Printer* printer);
+ void GenerateFrameworkMethods(io::Printer* printer);
+ void Generate(io::Printer* printer);
+
+ private:
+ const Descriptor* descriptor_;
+ std::vector<const FieldDescriptor*> fields_by_number_;
+ int has_bit_field_count_;
+ uint end_tag_;
+ bool has_extension_ranges_;
+
+ void GenerateMessageSerializationMethods(io::Printer* printer);
+ void GenerateWriteToBody(io::Printer* printer, bool use_write_context);
+ void GenerateMergingMethods(io::Printer* printer);
+ void GenerateMainParseLoop(io::Printer* printer, bool use_parse_context);
+
+ int GetPresenceIndex(const FieldDescriptor* descriptor);
+ FieldGeneratorBase* CreateFieldGeneratorInternal(
+ const FieldDescriptor* descriptor);
+
+ bool HasNestedGeneratedTypes();
+
+ void AddDeprecatedFlag(io::Printer* printer);
+ void AddSerializableAttribute(io::Printer* printer);
+
+ std::string class_name();
+ std::string full_class_name();
+
+ // field descriptors sorted by number
+ const std::vector<const FieldDescriptor*>& fields_by_number();
+};
+
+} // namespace csharp
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_COMPILER_CSHARP_MESSAGE_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_message_field.cc b/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_message_field.cc
new file mode 100644
index 00000000..1252202e
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_message_field.cc
@@ -0,0 +1,293 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <sstream>
+
+#include <compiler/code_generator.h>
+#include <descriptor.h>
+#include <descriptor.pb.h>
+#include <io/printer.h>
+#include <io/zero_copy_stream.h>
+#include <stubs/strutil.h>
+#include <wire_format.h>
+#include <wire_format_lite.h>
+
+#include <compiler/csharp/csharp_doc_comment.h>
+#include <compiler/csharp/csharp_helpers.h>
+#include <compiler/csharp/csharp_message_field.h>
+#include <compiler/csharp/csharp_options.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace csharp {
+
+MessageFieldGenerator::MessageFieldGenerator(const FieldDescriptor* descriptor,
+ int presenceIndex,
+ const Options *options)
+ : FieldGeneratorBase(descriptor, presenceIndex, options) {
+ if (!SupportsPresenceApi(descriptor_)) {
+ variables_["has_property_check"] = name() + "_ != null";
+ variables_["has_not_property_check"] = name() + "_ == null";
+ }
+}
+
+MessageFieldGenerator::~MessageFieldGenerator() {
+
+}
+
+void MessageFieldGenerator::GenerateMembers(io::Printer* printer) {
+ printer->Print(
+ variables_,
+ "private $type_name$ $name$_;\n");
+ WritePropertyDocComment(printer, descriptor_);
+ AddPublicMemberAttributes(printer);
+ printer->Print(
+ variables_,
+ "$access_level$ $type_name$ $property_name$ {\n"
+ " get { return $name$_; }\n"
+ " set {\n"
+ " $name$_ = value;\n"
+ " }\n"
+ "}\n");
+ if (SupportsPresenceApi(descriptor_)) {
+ printer->Print(
+ variables_,
+ "/// <summary>Gets whether the $descriptor_name$ field is set</summary>\n");
+ AddPublicMemberAttributes(printer);
+ printer->Print(
+ variables_,
+ "$access_level$ bool Has$property_name$ {\n"
+ " get { return $name$_ != null; }\n"
+ "}\n");
+ printer->Print(
+ variables_,
+ "/// <summary>Clears the value of the $descriptor_name$ field</summary>\n");
+ AddPublicMemberAttributes(printer);
+ printer->Print(
+ variables_,
+ "$access_level$ void Clear$property_name$() {\n"
+ " $name$_ = null;\n"
+ "}\n");
+ }
+}
+
+void MessageFieldGenerator::GenerateMergingCode(io::Printer* printer) {
+ printer->Print(
+ variables_,
+ "if (other.$has_property_check$) {\n"
+ " if ($has_not_property_check$) {\n"
+ " $property_name$ = new $type_name$();\n"
+ " }\n"
+ " $property_name$.MergeFrom(other.$property_name$);\n"
+ "}\n");
+}
+
+void MessageFieldGenerator::GenerateParsingCode(io::Printer* printer) {
+ printer->Print(
+ variables_,
+ "if ($has_not_property_check$) {\n"
+ " $property_name$ = new $type_name$();\n"
+ "}\n");
+ if (descriptor_->type() == FieldDescriptor::Type::TYPE_MESSAGE) {
+ printer->Print(variables_, "input.ReadMessage($property_name$);\n");
+ } else {
+ printer->Print(variables_, "input.ReadGroup($property_name$);\n");
+ }
+}
+
+void MessageFieldGenerator::GenerateSerializationCode(io::Printer* printer) {
+ if (descriptor_->type() == FieldDescriptor::Type::TYPE_MESSAGE) {
+ printer->Print(
+ variables_,
+ "if ($has_property_check$) {\n"
+ " output.WriteRawTag($tag_bytes$);\n"
+ " output.WriteMessage($property_name$);\n"
+ "}\n");
+ } else {
+ printer->Print(
+ variables_,
+ "if ($has_property_check$) {\n"
+ " output.WriteRawTag($tag_bytes$);\n"
+ " output.WriteGroup($property_name$);\n"
+ " output.WriteRawTag($end_tag_bytes$);\n"
+ "}\n");
+ }
+}
+
+void MessageFieldGenerator::GenerateSerializedSizeCode(io::Printer* printer) {
+ if (descriptor_->type() == FieldDescriptor::Type::TYPE_MESSAGE) {
+ printer->Print(
+ variables_,
+ "if ($has_property_check$) {\n"
+ " size += $tag_size$ + pb::CodedOutputStream.ComputeMessageSize($property_name$);\n"
+ "}\n");
+ } else {
+ printer->Print(
+ variables_,
+ "if ($has_property_check$) {\n"
+ " size += $tag_size$ + pb::CodedOutputStream.ComputeGroupSize($property_name$);\n"
+ "}\n");
+ }
+}
+
+void MessageFieldGenerator::WriteHash(io::Printer* printer) {
+ printer->Print(
+ variables_,
+ "if ($has_property_check$) hash ^= $property_name$.GetHashCode();\n");
+}
+void MessageFieldGenerator::WriteEquals(io::Printer* printer) {
+ printer->Print(
+ variables_,
+ "if (!object.Equals($property_name$, other.$property_name$)) return false;\n");
+}
+void MessageFieldGenerator::WriteToString(io::Printer* printer) {
+ variables_["field_name"] = GetFieldName(descriptor_);
+ printer->Print(
+ variables_,
+ "PrintField(\"$field_name$\", has$property_name$, $name$_, writer);\n");
+}
+void MessageFieldGenerator::GenerateExtensionCode(io::Printer* printer) {
+ WritePropertyDocComment(printer, descriptor_);
+ AddDeprecatedFlag(printer);
+ printer->Print(
+ variables_,
+ "$access_level$ static readonly pb::Extension<$extended_type$, $type_name$> $property_name$ =\n"
+ " new pb::Extension<$extended_type$, $type_name$>($number$, ");
+ GenerateCodecCode(printer);
+ printer->Print(");\n");
+}
+void MessageFieldGenerator::GenerateCloningCode(io::Printer* printer) {
+ printer->Print(variables_,
+ "$name$_ = other.$has_property_check$ ? other.$name$_.Clone() : null;\n");
+}
+
+void MessageFieldGenerator::GenerateFreezingCode(io::Printer* printer) {
+}
+
+void MessageFieldGenerator::GenerateCodecCode(io::Printer* printer) {
+ if (descriptor_->type() == FieldDescriptor::Type::TYPE_MESSAGE) {
+ printer->Print(
+ variables_,
+ "pb::FieldCodec.ForMessage($tag$, $type_name$.Parser)");
+ } else {
+ printer->Print(
+ variables_,
+ "pb::FieldCodec.ForGroup($tag$, $end_tag$, $type_name$.Parser)");
+ }
+}
+
+MessageOneofFieldGenerator::MessageOneofFieldGenerator(
+ const FieldDescriptor* descriptor,
+ int presenceIndex,
+ const Options *options)
+ : MessageFieldGenerator(descriptor, presenceIndex, options) {
+ SetCommonOneofFieldVariables(&variables_);
+}
+
+MessageOneofFieldGenerator::~MessageOneofFieldGenerator() {
+
+}
+
+void MessageOneofFieldGenerator::GenerateMembers(io::Printer* printer) {
+ WritePropertyDocComment(printer, descriptor_);
+ AddPublicMemberAttributes(printer);
+ printer->Print(
+ variables_,
+ "$access_level$ $type_name$ $property_name$ {\n"
+ " get { return $has_property_check$ ? ($type_name$) $oneof_name$_ : null; }\n"
+ " set {\n"
+ " $oneof_name$_ = value;\n"
+ " $oneof_name$Case_ = value == null ? $oneof_property_name$OneofCase.None : $oneof_property_name$OneofCase.$property_name$;\n"
+ " }\n"
+ "}\n");
+ if (SupportsPresenceApi(descriptor_)) {
+ printer->Print(
+ variables_,
+ "/// <summary>Gets whether the \"$descriptor_name$\" field is set</summary>\n");
+ AddPublicMemberAttributes(printer);
+ printer->Print(
+ variables_,
+ "$access_level$ bool Has$property_name$ {\n"
+ " get { return $oneof_name$Case_ == $oneof_property_name$OneofCase.$property_name$; }\n"
+ "}\n");
+ printer->Print(
+ variables_,
+ "/// <summary> Clears the value of the oneof if it's currently set to \"$descriptor_name$\" </summary>\n");
+ AddPublicMemberAttributes(printer);
+ printer->Print(
+ variables_,
+ "$access_level$ void Clear$property_name$() {\n"
+ " if ($has_property_check$) {\n"
+ " Clear$oneof_property_name$();\n"
+ " }\n"
+ "}\n");
+ }
+}
+
+void MessageOneofFieldGenerator::GenerateMergingCode(io::Printer* printer) {
+ printer->Print(variables_,
+ "if ($property_name$ == null) {\n"
+ " $property_name$ = new $type_name$();\n"
+ "}\n"
+ "$property_name$.MergeFrom(other.$property_name$);\n");
+}
+
+void MessageOneofFieldGenerator::GenerateParsingCode(io::Printer* printer) {
+ // TODO(jonskeet): We may be able to do better than this
+ printer->Print(
+ variables_,
+ "$type_name$ subBuilder = new $type_name$();\n"
+ "if ($has_property_check$) {\n"
+ " subBuilder.MergeFrom($property_name$);\n"
+ "}\n");
+ if (descriptor_->type() == FieldDescriptor::Type::TYPE_MESSAGE) {
+ printer->Print("input.ReadMessage(subBuilder);\n");
+ } else {
+ printer->Print("input.ReadGroup(subBuilder);\n");
+ }
+ printer->Print(variables_, "$property_name$ = subBuilder;\n");
+}
+
+void MessageOneofFieldGenerator::WriteToString(io::Printer* printer) {
+ printer->Print(
+ variables_,
+ "PrintField(\"$descriptor_name$\", $has_property_check$, $oneof_name$_, writer);\n");
+}
+
+void MessageOneofFieldGenerator::GenerateCloningCode(io::Printer* printer) {
+ printer->Print(variables_,
+ "$property_name$ = other.$property_name$.Clone();\n");
+}
+
+} // namespace csharp
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_message_field.h b/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_message_field.h
new file mode 100644
index 00000000..4cea5197
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_message_field.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_COMPILER_CSHARP_MESSAGE_FIELD_H__
+#define GOOGLE_PROTOBUF_COMPILER_CSHARP_MESSAGE_FIELD_H__
+
+#include <string>
+
+#include <compiler/code_generator.h>
+#include <compiler/csharp/csharp_field_base.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace csharp {
+
+class MessageFieldGenerator : public FieldGeneratorBase {
+ public:
+ MessageFieldGenerator(const FieldDescriptor* descriptor,
+ int presenceIndex,
+ const Options *options);
+ ~MessageFieldGenerator();
+
+ MessageFieldGenerator(const MessageFieldGenerator&) = delete;
+ MessageFieldGenerator& operator=(const MessageFieldGenerator&) = delete;
+
+ virtual void GenerateCodecCode(io::Printer* printer) override;
+ virtual void GenerateCloningCode(io::Printer* printer) override;
+ virtual void GenerateFreezingCode(io::Printer* printer) override;
+ virtual void GenerateMembers(io::Printer* printer) override;
+ virtual void GenerateMergingCode(io::Printer* printer) override;
+ virtual void GenerateParsingCode(io::Printer* printer) override;
+ virtual void GenerateSerializationCode(io::Printer* printer) override;
+ virtual void GenerateSerializedSizeCode(io::Printer* printer) override;
+ virtual void GenerateExtensionCode(io::Printer* printer) override;
+
+ virtual void WriteHash(io::Printer* printer) override;
+ virtual void WriteEquals(io::Printer* printer) override;
+ virtual void WriteToString(io::Printer* printer) override;
+};
+
+class MessageOneofFieldGenerator : public MessageFieldGenerator {
+ public:
+ MessageOneofFieldGenerator(const FieldDescriptor* descriptor,
+ int presenceIndex,
+ const Options *options);
+ ~MessageOneofFieldGenerator();
+
+ MessageOneofFieldGenerator(const MessageOneofFieldGenerator&) = delete;
+ MessageOneofFieldGenerator& operator=(const MessageOneofFieldGenerator&) =
+ delete;
+
+ virtual void GenerateCloningCode(io::Printer* printer) override;
+ virtual void GenerateMembers(io::Printer* printer) override;
+ virtual void GenerateMergingCode(io::Printer* printer) override;
+ virtual void WriteToString(io::Printer* printer) override;
+ virtual void GenerateParsingCode(io::Printer* printer) override;
+};
+
+} // namespace csharp
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_COMPILER_CSHARP_MESSAGE_FIELD_H__
+
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_names.h b/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_names.h
new file mode 100644
index 00000000..247951ef
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_names.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.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// Provides a mechanism for mapping a descriptor to the
+// fully-qualified name of the corresponding C# class.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_CSHARP_NAMES_H__
+#define GOOGLE_PROTOBUF_COMPILER_CSHARP_NAMES_H__
+
+#include <string>
+#include <port.h>
+#include <stubs/common.h>
+
+#include <port_def.inc>
+
+namespace google {
+namespace protobuf {
+
+class Descriptor;
+class EnumDescriptor;
+class FileDescriptor;
+class ServiceDescriptor;
+
+namespace compiler {
+namespace csharp {
+
+// Requires:
+// descriptor != NULL
+//
+// Returns:
+// The namespace to use for given file descriptor.
+std::string PROTOC_EXPORT GetFileNamespace(const FileDescriptor* descriptor);
+
+// Requires:
+// descriptor != NULL
+//
+// Returns:
+// The fully-qualified C# class name.
+std::string PROTOC_EXPORT GetClassName(const Descriptor* descriptor);
+
+// Requires:
+// descriptor != NULL
+//
+// Returns:
+// The fully-qualified name of the C# class that provides
+// access to the file descriptor. Proto compiler generates
+// such class for each .proto file processed.
+std::string PROTOC_EXPORT
+GetReflectionClassName(const FileDescriptor* descriptor);
+
+// Generates output file name for given file descriptor. If generate_directories
+// is true, the output file will be put under directory corresponding to file's
+// namespace. base_namespace can be used to strip some of the top level
+// directories. E.g. for file with namespace "Bar.Foo" and base_namespace="Bar",
+// the resulting file will be put under directory "Foo" (and not "Bar/Foo").
+//
+// Requires:
+// descriptor != NULL
+// error != NULL
+//
+// Returns:
+// The file name to use as output file for given file descriptor. In case
+// of failure, this function will return empty string and error parameter
+// will contain the error message.
+std::string PROTOC_EXPORT GetOutputFile(const FileDescriptor* descriptor,
+ const std::string file_extension,
+ const bool generate_directories,
+ const std::string base_namespace,
+ std::string* error);
+
+} // namespace csharp
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#include <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_COMPILER_CSHARP_NAMES_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_options.h b/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_options.h
new file mode 100644
index 00000000..42ff6d86
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_options.h
@@ -0,0 +1,81 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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_COMPILER_CSHARP_OPTIONS_H__
+#define GOOGLE_PROTOBUF_COMPILER_CSHARP_OPTIONS_H__
+
+#include <string>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace csharp {
+
+// Generator options (used by csharp_generator.cc):
+struct Options {
+ Options() :
+ file_extension(".cs"),
+ base_namespace(""),
+ base_namespace_specified(false),
+ internal_access(false),
+ serializable(false) {
+ }
+ // Extension of the generated file. Defaults to ".cs"
+ std::string file_extension;
+ // Base namespace to use to create directory hierarchy. Defaults to "".
+ // This option allows the simple creation of a conventional C# file layout,
+ // where directories are created relative to a project-specific base
+ // namespace. For example, in a project with a base namespace of PetShop, a
+ // proto of user.proto with a C# namespace of PetShop.Model.Shared would
+ // generate Model/Shared/User.cs underneath the specified --csharp_out
+ // directory.
+ //
+ // If no base namespace is specified, all files are generated in the
+ // --csharp_out directory, with no subdirectories created automatically.
+ std::string base_namespace;
+ // Whether the base namespace has been explicitly specified by the user.
+ // This is required as the base namespace can be explicitly set to the empty
+ // string, meaning "create a full directory hierarchy, starting from the first
+ // segment of the namespace."
+ bool base_namespace_specified;
+ // Whether the generated classes should have accessibility level of "internal".
+ // Defaults to false that generates "public" classes.
+ bool internal_access;
+ // Whether the generated classes should have a global::System.Serializable attribute added
+ // Defaults to false
+ bool serializable;
+};
+
+} // namespace csharp
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_COMPILER_CSHARP_OPTIONS_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_primitive_field.cc b/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_primitive_field.cc
new file mode 100644
index 00000000..6f695aa8
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_primitive_field.cc
@@ -0,0 +1,349 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <sstream>
+
+#include <compiler/code_generator.h>
+#include <descriptor.h>
+#include <descriptor.pb.h>
+#include <io/printer.h>
+#include <io/zero_copy_stream.h>
+#include <stubs/strutil.h>
+
+#include <compiler/csharp/csharp_doc_comment.h>
+#include <compiler/csharp/csharp_helpers.h>
+#include <compiler/csharp/csharp_options.h>
+#include <compiler/csharp/csharp_primitive_field.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace csharp {
+
+PrimitiveFieldGenerator::PrimitiveFieldGenerator(
+ const FieldDescriptor* descriptor, int presenceIndex, const Options *options)
+ : FieldGeneratorBase(descriptor, presenceIndex, options) {
+ // TODO(jonskeet): Make this cleaner...
+ is_value_type = descriptor->type() != FieldDescriptor::TYPE_STRING
+ && descriptor->type() != FieldDescriptor::TYPE_BYTES;
+ if (!is_value_type && !SupportsPresenceApi(descriptor_)) {
+ variables_["has_property_check"] = variables_["property_name"] + ".Length != 0";
+ variables_["other_has_property_check"] = "other." + variables_["property_name"] + ".Length != 0";
+ }
+}
+
+PrimitiveFieldGenerator::~PrimitiveFieldGenerator() {
+}
+
+void PrimitiveFieldGenerator::GenerateMembers(io::Printer* printer) {
+
+ // Note: in multiple places, this code assumes that all fields
+ // that support presence are either nullable, or use a presence field bit.
+ // Fields which are oneof members are not generated here; they're generated in PrimitiveOneofFieldGenerator below.
+ // Extensions are not generated here either.
+
+
+ // Proto2 allows different default values to be specified. These are retained
+ // via static fields. They don't particularly need to be, but we don't need
+ // to change that. In Proto3 the default value we don't generate these
+ // fields, just using the literal instead.
+ if (IsProto2(descriptor_->file())) {
+ // Note: "private readonly static" isn't as idiomatic as
+ // "private static readonly", but changing this now would create a lot of
+ // churn in generated code with near-to-zero benefit.
+ printer->Print(
+ variables_,
+ "private readonly static $type_name$ $property_name$DefaultValue = $default_value$;\n\n");
+ variables_["default_value_access"] =
+ variables_["property_name"] + "DefaultValue";
+ } else {
+ variables_["default_value_access"] = variables_["default_value"];
+ }
+
+ // Declare the field itself.
+ printer->Print(
+ variables_,
+ "private $type_name$ $name_def_message$;\n");
+
+ WritePropertyDocComment(printer, descriptor_);
+ AddPublicMemberAttributes(printer);
+
+ // Most of the work is done in the property:
+ // Declare the property itself (the same for all options)
+ printer->Print(variables_, "$access_level$ $type_name$ $property_name$ {\n");
+
+ // Specify the "getter", which may need to check for a presence field.
+ if (SupportsPresenceApi(descriptor_)) {
+ if (IsNullable(descriptor_)) {
+ printer->Print(
+ variables_,
+ " get { return $name$_ ?? $default_value_access$; }\n");
+ } else {
+ printer->Print(
+ variables_,
+ // Note: it's possible that this could be rewritten as a
+ // conditional ?: expression, but there's no significant benefit
+ // to changing it.
+ " get { if ($has_field_check$) { return $name$_; } else { return $default_value_access$; } }\n");
+ }
+ } else {
+ printer->Print(
+ variables_,
+ " get { return $name$_; }\n");
+ }
+
+ // Specify the "setter", which may need to set a field bit as well as the
+ // value.
+ printer->Print(" set {\n");
+ if (presenceIndex_ != -1) {
+ printer->Print(
+ variables_,
+ " $set_has_field$;\n");
+ }
+ if (is_value_type) {
+ printer->Print(
+ variables_,
+ " $name$_ = value;\n");
+ } else {
+ printer->Print(
+ variables_,
+ " $name$_ = pb::ProtoPreconditions.CheckNotNull(value, \"value\");\n");
+ }
+ printer->Print(
+ " }\n"
+ "}\n");
+
+ // The "HasFoo" property, where required.
+ if (SupportsPresenceApi(descriptor_)) {
+ printer->Print(variables_,
+ "/// <summary>Gets whether the \"$descriptor_name$\" field is set</summary>\n");
+ AddPublicMemberAttributes(printer);
+ printer->Print(
+ variables_,
+ "$access_level$ bool Has$property_name$ {\n"
+ " get { return ");
+ if (IsNullable(descriptor_)) {
+ printer->Print(
+ variables_,
+ "$name$_ != null; }\n}\n");
+ } else {
+ printer->Print(
+ variables_,
+ "$has_field_check$; }\n}\n");
+ }
+ }
+
+ // The "ClearFoo" method, where required.
+ if (SupportsPresenceApi(descriptor_)) {
+ printer->Print(variables_,
+ "/// <summary>Clears the value of the \"$descriptor_name$\" field</summary>\n");
+ AddPublicMemberAttributes(printer);
+ printer->Print(
+ variables_,
+ "$access_level$ void Clear$property_name$() {\n");
+ if (IsNullable(descriptor_)) {
+ printer->Print(variables_, " $name$_ = null;\n");
+ } else {
+ printer->Print(variables_, " $clear_has_field$;\n");
+ }
+ printer->Print("}\n");
+ }
+}
+
+void PrimitiveFieldGenerator::GenerateMergingCode(io::Printer* printer) {
+ printer->Print(
+ variables_,
+ "if ($other_has_property_check$) {\n"
+ " $property_name$ = other.$property_name$;\n"
+ "}\n");
+}
+
+void PrimitiveFieldGenerator::GenerateParsingCode(io::Printer* printer) {
+ // Note: invoke the property setter rather than writing straight to the field,
+ // so that we can normalize "null to empty" for strings and bytes.
+ printer->Print(
+ variables_,
+ "$property_name$ = input.Read$capitalized_type_name$();\n");
+}
+
+void PrimitiveFieldGenerator::GenerateSerializationCode(io::Printer* printer) {
+ printer->Print(
+ variables_,
+ "if ($has_property_check$) {\n"
+ " output.WriteRawTag($tag_bytes$);\n"
+ " output.Write$capitalized_type_name$($property_name$);\n"
+ "}\n");
+}
+
+void PrimitiveFieldGenerator::GenerateSerializedSizeCode(io::Printer* printer) {
+ printer->Print(
+ variables_,
+ "if ($has_property_check$) {\n");
+ printer->Indent();
+ int fixedSize = GetFixedSize(descriptor_->type());
+ if (fixedSize == -1) {
+ printer->Print(
+ variables_,
+ "size += $tag_size$ + pb::CodedOutputStream.Compute$capitalized_type_name$Size($property_name$);\n");
+ } else {
+ printer->Print(
+ "size += $tag_size$ + $fixed_size$;\n",
+ "fixed_size", StrCat(fixedSize),
+ "tag_size", variables_["tag_size"]);
+ }
+ printer->Outdent();
+ printer->Print("}\n");
+}
+
+void PrimitiveFieldGenerator::WriteHash(io::Printer* printer) {
+ const char *text = "if ($has_property_check$) hash ^= $property_name$.GetHashCode();\n";
+ if (descriptor_->type() == FieldDescriptor::TYPE_FLOAT) {
+ text = "if ($has_property_check$) hash ^= pbc::ProtobufEqualityComparers.BitwiseSingleEqualityComparer.GetHashCode($property_name$);\n";
+ } else if (descriptor_->type() == FieldDescriptor::TYPE_DOUBLE) {
+ text = "if ($has_property_check$) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode($property_name$);\n";
+ }
+ printer->Print(variables_, text);
+}
+void PrimitiveFieldGenerator::WriteEquals(io::Printer* printer) {
+ const char *text = "if ($property_name$ != other.$property_name$) return false;\n";
+ if (descriptor_->type() == FieldDescriptor::TYPE_FLOAT) {
+ text = "if (!pbc::ProtobufEqualityComparers.BitwiseSingleEqualityComparer.Equals($property_name$, other.$property_name$)) return false;\n";
+ } else if (descriptor_->type() == FieldDescriptor::TYPE_DOUBLE) {
+ text = "if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals($property_name$, other.$property_name$)) return false;\n";
+ }
+ printer->Print(variables_, text);
+}
+void PrimitiveFieldGenerator::WriteToString(io::Printer* printer) {
+ printer->Print(
+ variables_,
+ "PrintField(\"$descriptor_name$\", $has_property_check$, $property_name$, writer);\n");
+}
+
+void PrimitiveFieldGenerator::GenerateCloningCode(io::Printer* printer) {
+ printer->Print(variables_,
+ "$name$_ = other.$name$_;\n");
+}
+
+void PrimitiveFieldGenerator::GenerateCodecCode(io::Printer* printer) {
+ printer->Print(
+ variables_,
+ "pb::FieldCodec.For$capitalized_type_name$($tag$, $default_value$)");
+}
+
+void PrimitiveFieldGenerator::GenerateExtensionCode(io::Printer* printer) {
+ WritePropertyDocComment(printer, descriptor_);
+ AddDeprecatedFlag(printer);
+ printer->Print(
+ variables_,
+ "$access_level$ static readonly pb::Extension<$extended_type$, $type_name$> $property_name$ =\n"
+ " new pb::Extension<$extended_type$, $type_name$>($number$, ");
+ GenerateCodecCode(printer);
+ printer->Print(");\n");
+}
+
+PrimitiveOneofFieldGenerator::PrimitiveOneofFieldGenerator(
+ const FieldDescriptor* descriptor, int presenceIndex, const Options *options)
+ : PrimitiveFieldGenerator(descriptor, presenceIndex, options) {
+ SetCommonOneofFieldVariables(&variables_);
+}
+
+PrimitiveOneofFieldGenerator::~PrimitiveOneofFieldGenerator() {
+}
+
+void PrimitiveOneofFieldGenerator::GenerateMembers(io::Printer* printer) {
+ WritePropertyDocComment(printer, descriptor_);
+ AddPublicMemberAttributes(printer);
+ printer->Print(
+ variables_,
+ "$access_level$ $type_name$ $property_name$ {\n"
+ " get { return $has_property_check$ ? ($type_name$) $oneof_name$_ : $default_value$; }\n"
+ " set {\n");
+ if (is_value_type) {
+ printer->Print(
+ variables_,
+ " $oneof_name$_ = value;\n");
+ } else {
+ printer->Print(
+ variables_,
+ " $oneof_name$_ = pb::ProtoPreconditions.CheckNotNull(value, \"value\");\n");
+ }
+ printer->Print(
+ variables_,
+ " $oneof_name$Case_ = $oneof_property_name$OneofCase.$property_name$;\n"
+ " }\n"
+ "}\n");
+ if (SupportsPresenceApi(descriptor_)) {
+ printer->Print(
+ variables_,
+ "/// <summary>Gets whether the \"$descriptor_name$\" field is set</summary>\n");
+ AddPublicMemberAttributes(printer);
+ printer->Print(
+ variables_,
+ "$access_level$ bool Has$property_name$ {\n"
+ " get { return $oneof_name$Case_ == $oneof_property_name$OneofCase.$property_name$; }\n"
+ "}\n");
+ printer->Print(
+ variables_,
+ "/// <summary> Clears the value of the oneof if it's currently set to \"$descriptor_name$\" </summary>\n");
+ AddPublicMemberAttributes(printer);
+ printer->Print(
+ variables_,
+ "$access_level$ void Clear$property_name$() {\n"
+ " if ($has_property_check$) {\n"
+ " Clear$oneof_property_name$();\n"
+ " }\n"
+ "}\n");
+ }
+}
+
+void PrimitiveOneofFieldGenerator::GenerateMergingCode(io::Printer* printer) {
+ printer->Print(variables_, "$property_name$ = other.$property_name$;\n");
+}
+
+void PrimitiveOneofFieldGenerator::WriteToString(io::Printer* printer) {
+ printer->Print(variables_,
+ "PrintField(\"$descriptor_name$\", $has_property_check$, $oneof_name$_, writer);\n");
+}
+
+void PrimitiveOneofFieldGenerator::GenerateParsingCode(io::Printer* printer) {
+ printer->Print(
+ variables_,
+ "$property_name$ = input.Read$capitalized_type_name$();\n");
+}
+
+void PrimitiveOneofFieldGenerator::GenerateCloningCode(io::Printer* printer) {
+ printer->Print(variables_,
+ "$property_name$ = other.$property_name$;\n");
+}
+
+} // namespace csharp
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_primitive_field.h b/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_primitive_field.h
new file mode 100644
index 00000000..2386331e
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_primitive_field.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_COMPILER_CSHARP_PRIMITIVE_FIELD_H__
+#define GOOGLE_PROTOBUF_COMPILER_CSHARP_PRIMITIVE_FIELD_H__
+
+#include <string>
+
+#include <compiler/code_generator.h>
+#include <compiler/csharp/csharp_field_base.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace csharp {
+
+struct Options;
+
+class PrimitiveFieldGenerator : public FieldGeneratorBase {
+ public:
+ PrimitiveFieldGenerator(const FieldDescriptor* descriptor,
+ int presenceIndex,
+ const Options *options);
+ ~PrimitiveFieldGenerator();
+
+ PrimitiveFieldGenerator(const PrimitiveFieldGenerator&) = delete;
+ PrimitiveFieldGenerator& operator=(const PrimitiveFieldGenerator&) = delete;
+
+ virtual void GenerateCodecCode(io::Printer* printer) override;
+ virtual void GenerateCloningCode(io::Printer* printer) override;
+ virtual void GenerateMembers(io::Printer* printer) override;
+ virtual void GenerateMergingCode(io::Printer* printer) override;
+ virtual void GenerateParsingCode(io::Printer* printer) override;
+ virtual void GenerateSerializationCode(io::Printer* printer) override;
+ virtual void GenerateSerializedSizeCode(io::Printer* printer) override;
+ virtual void GenerateExtensionCode(io::Printer* printer) override;
+
+ virtual void WriteHash(io::Printer* printer) override;
+ virtual void WriteEquals(io::Printer* printer) override;
+ virtual void WriteToString(io::Printer* printer) override;
+
+ protected:
+ bool is_value_type;
+};
+
+class PrimitiveOneofFieldGenerator : public PrimitiveFieldGenerator {
+ public:
+ PrimitiveOneofFieldGenerator(const FieldDescriptor* descriptor,
+ int presenceIndex,
+ const Options *options);
+ ~PrimitiveOneofFieldGenerator();
+
+ PrimitiveOneofFieldGenerator(const PrimitiveOneofFieldGenerator&) = delete;
+ PrimitiveOneofFieldGenerator& operator=(const PrimitiveOneofFieldGenerator&) =
+ delete;
+
+ virtual void GenerateCloningCode(io::Printer* printer) override;
+ virtual void GenerateMembers(io::Printer* printer) override;
+ virtual void GenerateMergingCode(io::Printer* printer) override;
+ virtual void WriteToString(io::Printer* printer) override;
+ virtual void GenerateParsingCode(io::Printer* printer) override;
+};
+
+} // namespace csharp
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_COMPILER_CSHARP_PRIMITIVE_FIELD_H__
+
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_reflection_class.cc b/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_reflection_class.cc
new file mode 100644
index 00000000..5975f313
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_reflection_class.cc
@@ -0,0 +1,330 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 <sstream>
+
+#include <compiler/code_generator.h>
+#include <descriptor.h>
+#include <descriptor.pb.h>
+#include <io/printer.h>
+#include <io/zero_copy_stream.h>
+#include <stubs/strutil.h>
+
+
+#include <compiler/csharp/csharp_enum.h>
+#include <compiler/csharp/csharp_helpers.h>
+#include <compiler/csharp/csharp_field_base.h>
+#include <compiler/csharp/csharp_message.h>
+#include <compiler/csharp/csharp_names.h>
+#include <compiler/csharp/csharp_options.h>
+#include <compiler/csharp/csharp_reflection_class.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace csharp {
+
+ReflectionClassGenerator::ReflectionClassGenerator(const FileDescriptor* file,
+ const Options* options)
+ : SourceGeneratorBase(options),
+ file_(file) {
+ namespace_ = GetFileNamespace(file);
+ reflectionClassname_ = GetReflectionClassUnqualifiedName(file);
+ extensionClassname_ = GetExtensionClassUnqualifiedName(file);
+}
+
+ReflectionClassGenerator::~ReflectionClassGenerator() {
+}
+
+void ReflectionClassGenerator::Generate(io::Printer* printer) {
+ WriteIntroduction(printer);
+
+ WriteDescriptor(printer);
+ // Close the class declaration.
+ printer->Outdent();
+ printer->Print("}\n");
+
+ if (file_->extension_count() > 0) {
+ printer->Print(
+ "/// <summary>Holder for extension identifiers generated from the top "
+ "level of $file_name$</summary>\n"
+ "$access_level$ static partial class $class_name$ {\n",
+ "access_level", class_access_level(), "class_name", extensionClassname_,
+ "file_name", file_->name());
+ printer->Indent();
+ for (int i = 0; i < file_->extension_count(); i++) {
+ std::unique_ptr<FieldGeneratorBase> generator(
+ CreateFieldGenerator(file_->extension(i), -1, this->options()));
+ generator->GenerateExtensionCode(printer);
+ }
+ printer->Outdent();
+ printer->Print(
+ "}\n"
+ "\n");
+ }
+
+ // write children: Enums
+ if (file_->enum_type_count() > 0) {
+ printer->Print("#region Enums\n");
+ for (int i = 0; i < file_->enum_type_count(); i++) {
+ EnumGenerator enumGenerator(file_->enum_type(i), this->options());
+ enumGenerator.Generate(printer);
+ }
+ printer->Print("#endregion\n");
+ printer->Print("\n");
+ }
+
+ // write children: Messages
+ if (file_->message_type_count() > 0) {
+ printer->Print("#region Messages\n");
+ for (int i = 0; i < file_->message_type_count(); i++) {
+ MessageGenerator messageGenerator(file_->message_type(i), this->options());
+ messageGenerator.Generate(printer);
+ }
+ printer->Print("#endregion\n");
+ printer->Print("\n");
+ }
+
+ // TODO(jtattermusch): add insertion point for services.
+
+ if (!namespace_.empty()) {
+ printer->Outdent();
+ printer->Print("}\n");
+ }
+ printer->Print("\n");
+ printer->Print("#endregion Designer generated code\n");
+}
+
+void ReflectionClassGenerator::WriteIntroduction(io::Printer* printer) {
+ printer->Print(
+ "// <auto-generated>\n"
+ "// Generated by the protocol buffer compiler. DO NOT EDIT!\n"
+ "// source: $file_name$\n"
+ "// </auto-generated>\n"
+ "#pragma warning disable 1591, 0612, 3021\n"
+ "#region Designer generated code\n"
+ "\n"
+ "using pb = global::Google.Protobuf;\n"
+ "using pbc = global::Google.Protobuf.Collections;\n"
+ "using pbr = global::Google.Protobuf.Reflection;\n"
+ "using scg = global::System.Collections.Generic;\n",
+ "file_name", file_->name());
+
+ if (!namespace_.empty()) {
+ printer->Print("namespace $namespace$ {\n", "namespace", namespace_);
+ printer->Indent();
+ printer->Print("\n");
+ }
+
+ printer->Print(
+ "/// <summary>Holder for reflection information generated from $file_name$</summary>\n"
+ "$access_level$ static partial class $reflection_class_name$ {\n"
+ "\n",
+ "file_name", file_->name(),
+ "access_level", class_access_level(),
+ "reflection_class_name", reflectionClassname_);
+ printer->Indent();
+}
+
+void ReflectionClassGenerator::WriteDescriptor(io::Printer* printer) {
+ printer->Print(
+ "#region Descriptor\n"
+ "/// <summary>File descriptor for $file_name$</summary>\n"
+ "public static pbr::FileDescriptor Descriptor {\n"
+ " get { return descriptor; }\n"
+ "}\n"
+ "private static pbr::FileDescriptor descriptor;\n"
+ "\n"
+ "static $reflection_class_name$() {\n",
+ "file_name", file_->name(),
+ "reflection_class_name", reflectionClassname_);
+ printer->Indent();
+ printer->Print(
+ "byte[] descriptorData = global::System.Convert.FromBase64String(\n");
+ printer->Indent();
+ printer->Indent();
+ printer->Print("string.Concat(\n");
+ printer->Indent();
+
+ // TODO(jonskeet): Consider a C#-escaping format here instead of just Base64.
+ std::string base64 = FileDescriptorToBase64(file_);
+ while (base64.size() > 60) {
+ printer->Print("\"$base64$\",\n", "base64", base64.substr(0, 60));
+ base64 = base64.substr(60);
+ }
+ printer->Print("\"$base64$\"));\n", "base64", base64);
+ printer->Outdent();
+ printer->Outdent();
+ printer->Outdent();
+
+ // -----------------------------------------------------------------
+ // Invoke InternalBuildGeneratedFileFrom() to build the file.
+ printer->Print(
+ "descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,\n");
+ printer->Print(" new pbr::FileDescriptor[] { ");
+ for (int i = 0; i < file_->dependency_count(); i++) {
+ printer->Print(
+ "$full_reflection_class_name$.Descriptor, ",
+ "full_reflection_class_name",
+ GetReflectionClassName(file_->dependency(i)));
+ }
+ printer->Print("},\n"
+ " new pbr::GeneratedClrTypeInfo(");
+ // Specify all the generated code information, recursively.
+ if (file_->enum_type_count() > 0) {
+ printer->Print("new[] {");
+ for (int i = 0; i < file_->enum_type_count(); i++) {
+ printer->Print("typeof($type_name$), ", "type_name", GetClassName(file_->enum_type(i)));
+ }
+ printer->Print("}, ");
+ }
+ else {
+ printer->Print("null, ");
+ }
+ if (file_->extension_count() > 0) {
+ std::vector<std::string> extensions;
+ for (int i = 0; i < file_->extension_count(); i++) {
+ extensions.push_back(GetFullExtensionName(file_->extension(i)));
+ }
+ printer->Print("new pb::Extension[] { $extensions$ }, ", "extensions", Join(extensions, ", "));
+ }
+ else {
+ printer->Print("null, ");
+ }
+ if (file_->message_type_count() > 0) {
+ printer->Print("new pbr::GeneratedClrTypeInfo[] {\n");
+ printer->Indent();
+ printer->Indent();
+ printer->Indent();
+ for (int i = 0; i < file_->message_type_count(); i++) {
+ WriteGeneratedCodeInfo(file_->message_type(i), printer, i == file_->message_type_count() - 1);
+ }
+ printer->Outdent();
+ printer->Print("\n}));\n");
+ printer->Outdent();
+ printer->Outdent();
+ }
+ else {
+ printer->Print("null));\n");
+ }
+
+ printer->Outdent();
+ printer->Print("}\n");
+ printer->Print("#endregion\n\n");
+}
+
+// Write out the generated code for a particular message. This consists of the CLR type, property names
+// corresponding to fields, names corresponding to oneofs, nested enums, and nested types. Each array part
+// can be specified as null if it would be empty, to make the generated code somewhat simpler to read.
+// We write a line break at the end of each generated code info, so that in the final file we'll see all
+// the types, pre-ordered depth first, one per line. The indentation will be slightly unusual,
+// in that it will look like a single array when it's actually constructing a tree, but it'll be easy to
+// read even with multiple levels of nesting.
+// The "last" parameter indicates whether this message descriptor is the last one being printed in this immediate
+// context. It governs whether or not a trailing comma and newline is written after the constructor, effectively
+// just controlling the formatting in the generated code.
+void ReflectionClassGenerator::WriteGeneratedCodeInfo(const Descriptor* descriptor, io::Printer* printer, bool last) {
+ if (IsMapEntryMessage(descriptor)) {
+ printer->Print("null, ");
+ return;
+ }
+ // Generated message type
+ printer->Print("new pbr::GeneratedClrTypeInfo(typeof($type_name$), $type_name$.Parser, ", "type_name", GetClassName(descriptor));
+
+ // Fields
+ if (descriptor->field_count() > 0) {
+ std::vector<std::string> fields;
+ fields.reserve(descriptor->field_count());
+ for (int i = 0; i < descriptor->field_count(); i++) {
+ fields.push_back(GetPropertyName(descriptor->field(i)));
+ }
+ printer->Print("new[]{ \"$fields$\" }, ", "fields", Join(fields, "\", \""));
+ }
+ else {
+ printer->Print("null, ");
+ }
+
+ // Oneofs
+ if (descriptor->oneof_decl_count() > 0) {
+ std::vector<std::string> oneofs;
+ oneofs.reserve(descriptor->oneof_decl_count());
+ for (int i = 0; i < descriptor->oneof_decl_count(); i++) {
+ oneofs.push_back(UnderscoresToCamelCase(descriptor->oneof_decl(i)->name(), true));
+ }
+ printer->Print("new[]{ \"$oneofs$\" }, ", "oneofs", Join(oneofs, "\", \""));
+ }
+ else {
+ printer->Print("null, ");
+ }
+
+ // Nested enums
+ if (descriptor->enum_type_count() > 0) {
+ std::vector<std::string> enums;
+ enums.reserve(descriptor->enum_type_count());
+ for (int i = 0; i < descriptor->enum_type_count(); i++) {
+ enums.push_back(GetClassName(descriptor->enum_type(i)));
+ }
+ printer->Print("new[]{ typeof($enums$) }, ", "enums", Join(enums, "), typeof("));
+ }
+ else {
+ printer->Print("null, ");
+ }
+
+ // Extensions
+ if (descriptor->extension_count() > 0) {
+ std::vector<std::string> extensions;
+ for (int i = 0; i < descriptor->extension_count(); i++) {
+ extensions.push_back(GetFullExtensionName(descriptor->extension(i)));
+ }
+ printer->Print("new pb::Extension[] { $extensions$ }, ", "extensions", Join(extensions, ", "));
+ }
+ else {
+ printer->Print("null, ");
+ }
+
+ // Nested types
+ if (descriptor->nested_type_count() > 0) {
+ // Need to specify array type explicitly here, as all elements may be null.
+ printer->Print("new pbr::GeneratedClrTypeInfo[] { ");
+ for (int i = 0; i < descriptor->nested_type_count(); i++) {
+ WriteGeneratedCodeInfo(descriptor->nested_type(i), printer, i == descriptor->nested_type_count() - 1);
+ }
+ printer->Print("}");
+ }
+ else {
+ printer->Print("null");
+ }
+ printer->Print(last ? ")" : "),\n");
+}
+
+} // namespace csharp
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_reflection_class.h b/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_reflection_class.h
new file mode 100644
index 00000000..4834708b
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_reflection_class.h
@@ -0,0 +1,75 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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_COMPILER_CSHARP_REFLECTION_CLASS_H__
+#define GOOGLE_PROTOBUF_COMPILER_CSHARP_REFLECTION_CLASS_H__
+
+#include <string>
+
+#include <compiler/code_generator.h>
+#include <compiler/csharp/csharp_source_generator_base.h>
+#include <descriptor.h>
+#include <io/printer.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace csharp {
+
+class ReflectionClassGenerator : public SourceGeneratorBase {
+ public:
+ ReflectionClassGenerator(const FileDescriptor* file, const Options* options);
+ ~ReflectionClassGenerator();
+
+ ReflectionClassGenerator(const ReflectionClassGenerator&) = delete;
+ ReflectionClassGenerator& operator=(const ReflectionClassGenerator&) = delete;
+
+ void Generate(io::Printer* printer);
+
+ private:
+ const FileDescriptor* file_;
+
+ std::string namespace_;
+ std::string reflectionClassname_;
+ std::string extensionClassname_;
+
+ void WriteIntroduction(io::Printer* printer);
+ void WriteDescriptor(io::Printer* printer);
+ void WriteGeneratedCodeInfo(const Descriptor* descriptor,
+ io::Printer* printer,
+ bool last);
+};
+
+} // namespace csharp
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_COMPILER_CSHARP_REFLECTION_CLASS_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_repeated_enum_field.cc b/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_repeated_enum_field.cc
new file mode 100644
index 00000000..57e83266
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_repeated_enum_field.cc
@@ -0,0 +1,148 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <sstream>
+
+#include <compiler/code_generator.h>
+#include <descriptor.h>
+#include <descriptor.pb.h>
+#include <io/printer.h>
+#include <io/zero_copy_stream.h>
+#include <wire_format.h>
+
+#include <compiler/csharp/csharp_doc_comment.h>
+#include <compiler/csharp/csharp_helpers.h>
+#include <compiler/csharp/csharp_repeated_enum_field.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace csharp {
+
+RepeatedEnumFieldGenerator::RepeatedEnumFieldGenerator(
+ const FieldDescriptor* descriptor, int presenceIndex, const Options *options)
+ : FieldGeneratorBase(descriptor, presenceIndex, options) {
+}
+
+RepeatedEnumFieldGenerator::~RepeatedEnumFieldGenerator() {
+
+}
+
+void RepeatedEnumFieldGenerator::GenerateMembers(io::Printer* printer) {
+ printer->Print(
+ variables_,
+ "private static readonly pb::FieldCodec<$type_name$> _repeated_$name$_codec\n"
+ " = pb::FieldCodec.ForEnum($tag$, x => (int) x, x => ($type_name$) x);\n");
+ printer->Print(variables_,
+ "private readonly pbc::RepeatedField<$type_name$> $name$_ = new pbc::RepeatedField<$type_name$>();\n");
+ WritePropertyDocComment(printer, descriptor_);
+ AddPublicMemberAttributes(printer);
+ printer->Print(
+ variables_,
+ "$access_level$ pbc::RepeatedField<$type_name$> $property_name$ {\n"
+ " get { return $name$_; }\n"
+ "}\n");
+}
+
+void RepeatedEnumFieldGenerator::GenerateMergingCode(io::Printer* printer) {
+ printer->Print(
+ variables_,
+ "$name$_.Add(other.$name$_);\n");
+}
+
+void RepeatedEnumFieldGenerator::GenerateParsingCode(io::Printer* printer) {
+ GenerateParsingCode(printer, true);
+}
+
+void RepeatedEnumFieldGenerator::GenerateParsingCode(io::Printer* printer, bool use_parse_context) {
+ printer->Print(
+ variables_,
+ use_parse_context
+ ? "$name$_.AddEntriesFrom(ref input, _repeated_$name$_codec);\n"
+ : "$name$_.AddEntriesFrom(input, _repeated_$name$_codec);\n");
+}
+
+void RepeatedEnumFieldGenerator::GenerateSerializationCode(io::Printer* printer) {
+ GenerateSerializationCode(printer, true);
+}
+
+void RepeatedEnumFieldGenerator::GenerateSerializationCode(io::Printer* printer, bool use_write_context) {
+ printer->Print(
+ variables_,
+ use_write_context
+ ? "$name$_.WriteTo(ref output, _repeated_$name$_codec);\n"
+ : "$name$_.WriteTo(output, _repeated_$name$_codec);\n");
+}
+
+void RepeatedEnumFieldGenerator::GenerateSerializedSizeCode(io::Printer* printer) {
+ printer->Print(
+ variables_,
+ "size += $name$_.CalculateSize(_repeated_$name$_codec);\n");
+}
+
+void RepeatedEnumFieldGenerator::WriteHash(io::Printer* printer) {
+ printer->Print(
+ variables_,
+ "hash ^= $name$_.GetHashCode();\n");
+}
+
+void RepeatedEnumFieldGenerator::WriteEquals(io::Printer* printer) {
+ printer->Print(
+ variables_,
+ "if(!$name$_.Equals(other.$name$_)) return false;\n");
+}
+
+void RepeatedEnumFieldGenerator::WriteToString(io::Printer* printer) {
+ printer->Print(variables_,
+ "PrintField(\"$descriptor_name$\", $name$_, writer);\n");
+}
+
+void RepeatedEnumFieldGenerator::GenerateCloningCode(io::Printer* printer) {
+ printer->Print(variables_,
+ "$name$_ = other.$name$_.Clone();\n");
+}
+
+void RepeatedEnumFieldGenerator::GenerateExtensionCode(io::Printer* printer) {
+ WritePropertyDocComment(printer, descriptor_);
+ AddDeprecatedFlag(printer);
+ printer->Print(
+ variables_,
+ "$access_level$ static readonly pb::RepeatedExtension<$extended_type$, $type_name$> $property_name$ =\n"
+ " new pb::RepeatedExtension<$extended_type$, $type_name$>($number$, "
+ "pb::FieldCodec.ForEnum($tag$, x => (int) x, x => ($type_name$) x));\n");
+}
+
+void RepeatedEnumFieldGenerator::GenerateFreezingCode(io::Printer* printer) {
+}
+
+} // namespace csharp
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_repeated_enum_field.h b/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_repeated_enum_field.h
new file mode 100644
index 00000000..cce82868
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_repeated_enum_field.h
@@ -0,0 +1,79 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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_COMPILER_CSHARP_REPEATED_ENUM_FIELD_H__
+#define GOOGLE_PROTOBUF_COMPILER_CSHARP_REPEATED_ENUM_FIELD_H__
+
+#include <string>
+
+#include <compiler/code_generator.h>
+#include <compiler/csharp/csharp_field_base.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace csharp {
+
+// TODO(jonskeet): Refactor repeated field support; all the implementations are
+// *really* similar. We should probably have a RepeatedFieldGeneratorBase.
+class RepeatedEnumFieldGenerator : public FieldGeneratorBase {
+ public:
+ RepeatedEnumFieldGenerator(const FieldDescriptor* descriptor,
+ int presenceIndex,
+ const Options *options);
+ ~RepeatedEnumFieldGenerator();
+
+ RepeatedEnumFieldGenerator(const RepeatedEnumFieldGenerator&) = delete;
+ RepeatedEnumFieldGenerator& operator=(const RepeatedEnumFieldGenerator&) =
+ delete;
+
+ virtual void GenerateCloningCode(io::Printer* printer) override;
+ virtual void GenerateFreezingCode(io::Printer* printer) override;
+ virtual void GenerateMembers(io::Printer* printer) override;
+ virtual void GenerateMergingCode(io::Printer* printer) override;
+ virtual void GenerateParsingCode(io::Printer* printer) override;
+ virtual void GenerateParsingCode(io::Printer* printer, bool use_parse_context) override;
+ virtual void GenerateSerializationCode(io::Printer* printer) override;
+ virtual void GenerateSerializationCode(io::Printer* printer, bool use_write_context) override;
+ virtual void GenerateSerializedSizeCode(io::Printer* printer) override;
+ virtual void GenerateExtensionCode(io::Printer* printer) override;
+
+ virtual void WriteHash(io::Printer* printer) override;
+ virtual void WriteEquals(io::Printer* printer) override;
+ virtual void WriteToString(io::Printer* printer) override;
+};
+
+} // namespace csharp
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_COMPILER_CSHARP_REPEATED_ENUM_FIELD_H__
+
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_repeated_message_field.cc b/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_repeated_message_field.cc
new file mode 100644
index 00000000..bd2c22a3
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_repeated_message_field.cc
@@ -0,0 +1,174 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 <sstream>
+
+#include <compiler/code_generator.h>
+#include <descriptor.h>
+#include <descriptor.pb.h>
+#include <io/printer.h>
+#include <io/zero_copy_stream.h>
+
+#include <compiler/csharp/csharp_doc_comment.h>
+#include <compiler/csharp/csharp_helpers.h>
+#include <compiler/csharp/csharp_repeated_message_field.h>
+#include <compiler/csharp/csharp_message_field.h>
+#include <compiler/csharp/csharp_wrapper_field.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace csharp {
+
+RepeatedMessageFieldGenerator::RepeatedMessageFieldGenerator(
+ const FieldDescriptor* descriptor, int presenceIndex, const Options *options)
+ : FieldGeneratorBase(descriptor, presenceIndex, options) {
+}
+
+RepeatedMessageFieldGenerator::~RepeatedMessageFieldGenerator() {
+
+}
+
+void RepeatedMessageFieldGenerator::GenerateMembers(io::Printer* printer) {
+ printer->Print(
+ variables_,
+ "private static readonly pb::FieldCodec<$type_name$> _repeated_$name$_codec\n"
+ " = ");
+ // Don't want to duplicate the codec code here... maybe we should have a
+ // "create single field generator for this repeated field"
+ // function, but it doesn't seem worth it for just this.
+ if (IsWrapperType(descriptor_)) {
+ std::unique_ptr<FieldGeneratorBase> single_generator(
+ new WrapperFieldGenerator(descriptor_, presenceIndex_, this->options()));
+ single_generator->GenerateCodecCode(printer);
+ } else {
+ std::unique_ptr<FieldGeneratorBase> single_generator(
+ new MessageFieldGenerator(descriptor_, presenceIndex_, this->options()));
+ single_generator->GenerateCodecCode(printer);
+ }
+ printer->Print(";\n");
+ printer->Print(
+ variables_,
+ "private readonly pbc::RepeatedField<$type_name$> $name$_ = new pbc::RepeatedField<$type_name$>();\n");
+ WritePropertyDocComment(printer, descriptor_);
+ AddPublicMemberAttributes(printer);
+ printer->Print(
+ variables_,
+ "$access_level$ pbc::RepeatedField<$type_name$> $property_name$ {\n"
+ " get { return $name$_; }\n"
+ "}\n");
+}
+
+void RepeatedMessageFieldGenerator::GenerateMergingCode(io::Printer* printer) {
+ printer->Print(
+ variables_,
+ "$name$_.Add(other.$name$_);\n");
+}
+
+void RepeatedMessageFieldGenerator::GenerateParsingCode(io::Printer* printer) {
+ GenerateParsingCode(printer, true);
+}
+
+void RepeatedMessageFieldGenerator::GenerateParsingCode(io::Printer* printer, bool use_parse_context) {
+ printer->Print(
+ variables_,
+ use_parse_context
+ ? "$name$_.AddEntriesFrom(ref input, _repeated_$name$_codec);\n"
+ : "$name$_.AddEntriesFrom(input, _repeated_$name$_codec);\n");
+}
+
+void RepeatedMessageFieldGenerator::GenerateSerializationCode(io::Printer* printer) {
+ GenerateSerializationCode(printer, true);
+}
+
+void RepeatedMessageFieldGenerator::GenerateSerializationCode(io::Printer* printer, bool use_write_context) {
+ printer->Print(
+ variables_,
+ use_write_context
+ ? "$name$_.WriteTo(ref output, _repeated_$name$_codec);\n"
+ : "$name$_.WriteTo(output, _repeated_$name$_codec);\n");
+}
+
+void RepeatedMessageFieldGenerator::GenerateSerializedSizeCode(io::Printer* printer) {
+ printer->Print(
+ variables_,
+ "size += $name$_.CalculateSize(_repeated_$name$_codec);\n");
+}
+
+void RepeatedMessageFieldGenerator::WriteHash(io::Printer* printer) {
+ printer->Print(
+ variables_,
+ "hash ^= $name$_.GetHashCode();\n");
+}
+
+void RepeatedMessageFieldGenerator::WriteEquals(io::Printer* printer) {
+ printer->Print(
+ variables_,
+ "if(!$name$_.Equals(other.$name$_)) return false;\n");
+}
+
+void RepeatedMessageFieldGenerator::WriteToString(io::Printer* printer) {
+ variables_["field_name"] = GetFieldName(descriptor_);
+ printer->Print(
+ variables_,
+ "PrintField(\"$field_name$\", $name$_, writer);\n");
+}
+
+void RepeatedMessageFieldGenerator::GenerateCloningCode(io::Printer* printer) {
+ printer->Print(variables_,
+ "$name$_ = other.$name$_.Clone();\n");
+}
+
+void RepeatedMessageFieldGenerator::GenerateFreezingCode(io::Printer* printer) {
+}
+
+void RepeatedMessageFieldGenerator::GenerateExtensionCode(io::Printer* printer) {
+ WritePropertyDocComment(printer, descriptor_);
+ AddDeprecatedFlag(printer);
+ printer->Print(
+ variables_,
+ "$access_level$ static readonly pb::RepeatedExtension<$extended_type$, $type_name$> $property_name$ =\n"
+ " new pb::RepeatedExtension<$extended_type$, $type_name$>($number$, ");
+ if (IsWrapperType(descriptor_)) {
+ std::unique_ptr<FieldGeneratorBase> single_generator(
+ new WrapperFieldGenerator(descriptor_, -1, this->options()));
+ single_generator->GenerateCodecCode(printer);
+ } else {
+ std::unique_ptr<FieldGeneratorBase> single_generator(
+ new MessageFieldGenerator(descriptor_, -1, this->options()));
+ single_generator->GenerateCodecCode(printer);
+ }
+ printer->Print(");\n");
+}
+
+} // namespace csharp
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_repeated_message_field.h b/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_repeated_message_field.h
new file mode 100644
index 00000000..dc975888
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_repeated_message_field.h
@@ -0,0 +1,79 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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_COMPILER_CSHARP_REPEATED_MESSAGE_FIELD_H__
+#define GOOGLE_PROTOBUF_COMPILER_CSHARP_REPEATED_MESSAGE_FIELD_H__
+
+#include <string>
+
+#include <compiler/code_generator.h>
+#include <compiler/csharp/csharp_field_base.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace csharp {
+
+struct Options;
+
+class RepeatedMessageFieldGenerator : public FieldGeneratorBase {
+ public:
+ RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor,
+ int presenceIndex,
+ const Options *options);
+ ~RepeatedMessageFieldGenerator();
+
+ RepeatedMessageFieldGenerator(const RepeatedMessageFieldGenerator&) = delete;
+ RepeatedMessageFieldGenerator& operator=(
+ const RepeatedMessageFieldGenerator&) = delete;
+
+ virtual void GenerateCloningCode(io::Printer* printer) override;
+ virtual void GenerateFreezingCode(io::Printer* printer) override;
+ virtual void GenerateMembers(io::Printer* printer) override;
+ virtual void GenerateMergingCode(io::Printer* printer) override;
+ virtual void GenerateParsingCode(io::Printer* printer) override;
+ virtual void GenerateParsingCode(io::Printer* printer, bool use_parse_context) override;
+ virtual void GenerateSerializationCode(io::Printer* printer) override;
+ virtual void GenerateSerializationCode(io::Printer* printer, bool use_write_context) override;
+ virtual void GenerateSerializedSizeCode(io::Printer* printer) override;
+ virtual void GenerateExtensionCode(io::Printer* printer) override;
+
+ virtual void WriteHash(io::Printer* printer) override;
+ virtual void WriteEquals(io::Printer* printer) override;
+ virtual void WriteToString(io::Printer* printer) override;
+};
+
+} // namespace csharp
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_COMPILER_CSHARP_REPEATED_MESSAGE_FIELD_H__
+
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_repeated_primitive_field.cc b/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_repeated_primitive_field.cc
new file mode 100644
index 00000000..6df3edc5
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_repeated_primitive_field.cc
@@ -0,0 +1,145 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 <sstream>
+
+#include <compiler/code_generator.h>
+#include <descriptor.h>
+#include <descriptor.pb.h>
+#include <io/printer.h>
+#include <io/zero_copy_stream.h>
+#include <wire_format.h>
+
+#include <compiler/csharp/csharp_doc_comment.h>
+#include <compiler/csharp/csharp_helpers.h>
+#include <compiler/csharp/csharp_repeated_primitive_field.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace csharp {
+
+RepeatedPrimitiveFieldGenerator::RepeatedPrimitiveFieldGenerator(
+ const FieldDescriptor* descriptor, int presenceIndex, const Options *options)
+ : FieldGeneratorBase(descriptor, presenceIndex, options) {
+}
+
+RepeatedPrimitiveFieldGenerator::~RepeatedPrimitiveFieldGenerator() {
+
+}
+
+void RepeatedPrimitiveFieldGenerator::GenerateMembers(io::Printer* printer) {
+ printer->Print(
+ variables_,
+ "private static readonly pb::FieldCodec<$type_name$> _repeated_$name$_codec\n"
+ " = pb::FieldCodec.For$capitalized_type_name$($tag$);\n");
+ printer->Print(variables_,
+ "private readonly pbc::RepeatedField<$type_name$> $name$_ = new pbc::RepeatedField<$type_name$>();\n");
+ WritePropertyDocComment(printer, descriptor_);
+ AddPublicMemberAttributes(printer);
+ printer->Print(
+ variables_,
+ "$access_level$ pbc::RepeatedField<$type_name$> $property_name$ {\n"
+ " get { return $name$_; }\n"
+ "}\n");
+}
+
+void RepeatedPrimitiveFieldGenerator::GenerateMergingCode(io::Printer* printer) {
+ printer->Print(
+ variables_,
+ "$name$_.Add(other.$name$_);\n");
+}
+
+void RepeatedPrimitiveFieldGenerator::GenerateParsingCode(io::Printer* printer) {
+ GenerateParsingCode(printer, true);
+}
+
+void RepeatedPrimitiveFieldGenerator::GenerateParsingCode(io::Printer* printer, bool use_parse_context) {
+ printer->Print(
+ variables_,
+ use_parse_context
+ ? "$name$_.AddEntriesFrom(ref input, _repeated_$name$_codec);\n"
+ : "$name$_.AddEntriesFrom(input, _repeated_$name$_codec);\n");
+}
+
+void RepeatedPrimitiveFieldGenerator::GenerateSerializationCode(io::Printer* printer) {
+ GenerateSerializationCode(printer, true);
+}
+
+void RepeatedPrimitiveFieldGenerator::GenerateSerializationCode(io::Printer* printer, bool use_write_context) {
+ printer->Print(
+ variables_,
+ use_write_context
+ ? "$name$_.WriteTo(ref output, _repeated_$name$_codec);\n"
+ : "$name$_.WriteTo(output, _repeated_$name$_codec);\n");
+}
+
+void RepeatedPrimitiveFieldGenerator::GenerateSerializedSizeCode(io::Printer* printer) {
+ printer->Print(
+ variables_,
+ "size += $name$_.CalculateSize(_repeated_$name$_codec);\n");
+}
+
+void RepeatedPrimitiveFieldGenerator::WriteHash(io::Printer* printer) {
+ printer->Print(
+ variables_,
+ "hash ^= $name$_.GetHashCode();\n");
+}
+void RepeatedPrimitiveFieldGenerator::WriteEquals(io::Printer* printer) {
+ printer->Print(
+ variables_,
+ "if(!$name$_.Equals(other.$name$_)) return false;\n");
+}
+void RepeatedPrimitiveFieldGenerator::WriteToString(io::Printer* printer) {
+ printer->Print(variables_,
+ "PrintField(\"$descriptor_name$\", $name$_, writer);\n");
+}
+
+void RepeatedPrimitiveFieldGenerator::GenerateCloningCode(io::Printer* printer) {
+ printer->Print(variables_,
+ "$name$_ = other.$name$_.Clone();\n");
+}
+
+void RepeatedPrimitiveFieldGenerator::GenerateFreezingCode(io::Printer* printer) {
+}
+
+void RepeatedPrimitiveFieldGenerator::GenerateExtensionCode(io::Printer* printer) {
+ WritePropertyDocComment(printer, descriptor_);
+ AddDeprecatedFlag(printer);
+ printer->Print(
+ variables_,
+ "$access_level$ static readonly pb::RepeatedExtension<$extended_type$, $type_name$> $property_name$ =\n"
+ " new pb::RepeatedExtension<$extended_type$, $type_name$>($number$, pb::FieldCodec.For$capitalized_type_name$($tag$));\n");
+}
+
+} // namespace csharp
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_repeated_primitive_field.h b/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_repeated_primitive_field.h
new file mode 100644
index 00000000..83bb41f2
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_repeated_primitive_field.h
@@ -0,0 +1,75 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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_COMPILER_CSHARP_REPEATED_PRIMITIVE_FIELD_H__
+#define GOOGLE_PROTOBUF_COMPILER_CSHARP_REPEATED_PRIMITIVE_FIELD_H__
+
+#include <string>
+
+#include <compiler/code_generator.h>
+#include <compiler/csharp/csharp_field_base.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace csharp {
+
+class RepeatedPrimitiveFieldGenerator : public FieldGeneratorBase {
+ public:
+ RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor,
+ int presenceIndex, const Options* options);
+ ~RepeatedPrimitiveFieldGenerator();
+
+ RepeatedPrimitiveFieldGenerator(const RepeatedPrimitiveFieldGenerator&) = delete;
+ RepeatedPrimitiveFieldGenerator& operator=(const RepeatedPrimitiveFieldGenerator&) = delete;
+
+ virtual void GenerateCloningCode(io::Printer* printer) override;
+ virtual void GenerateFreezingCode(io::Printer* printer) override;
+ virtual void GenerateMembers(io::Printer* printer) override;
+ virtual void GenerateMergingCode(io::Printer* printer) override;
+ virtual void GenerateParsingCode(io::Printer* printer) override;
+ virtual void GenerateParsingCode(io::Printer* printer, bool use_parse_context) override;
+ virtual void GenerateSerializationCode(io::Printer* printer) override;
+ virtual void GenerateSerializationCode(io::Printer* printer, bool use_write_context) override;
+ virtual void GenerateSerializedSizeCode(io::Printer* printer) override;
+ virtual void GenerateExtensionCode(io::Printer* printer) override;
+
+ virtual void WriteHash(io::Printer* printer) override;
+ virtual void WriteEquals(io::Printer* printer) override;
+ virtual void WriteToString(io::Printer* printer) override;
+};
+
+} // namespace csharp
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_COMPILER_CSHARP_REPEATED_PRIMITIVE_FIELD_H__
+
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_source_generator_base.cc b/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_source_generator_base.cc
new file mode 100644
index 00000000..213422ad
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_source_generator_base.cc
@@ -0,0 +1,75 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 <sstream>
+
+#include <compiler/code_generator.h>
+#include <descriptor.h>
+#include <descriptor.pb.h>
+#include <io/printer.h>
+#include <io/zero_copy_stream.h>
+
+#include <compiler/csharp/csharp_source_generator_base.h>
+#include <compiler/csharp/csharp_helpers.h>
+#include <compiler/csharp/csharp_names.h>
+#include <compiler/csharp/csharp_options.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace csharp {
+
+SourceGeneratorBase::SourceGeneratorBase(
+ const Options *options) : options_(options) {
+}
+
+SourceGeneratorBase::~SourceGeneratorBase() {
+}
+
+void SourceGeneratorBase::WriteGeneratedCodeAttributes(io::Printer* printer) {
+ printer->Print("[global::System.Diagnostics.DebuggerNonUserCodeAttribute]\n");
+ // The second argument of the [GeneratedCode] attribute could be set to current protoc
+ // version, but that would cause excessive code churn in the pre-generated
+ // code in the repository every time the protobuf version number is updated.
+ printer->Print("[global::System.CodeDom.Compiler.GeneratedCode(\"protoc\", null)]\n");
+}
+
+std::string SourceGeneratorBase::class_access_level() {
+ return this->options()->internal_access ? "internal" : "public";
+}
+
+const Options* SourceGeneratorBase::options() {
+ return this->options_;
+}
+
+} // namespace csharp
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_source_generator_base.h b/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_source_generator_base.h
new file mode 100644
index 00000000..b09c92b6
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_source_generator_base.h
@@ -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.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_CSHARP_SOURCE_GENERATOR_BASE_H__
+#define GOOGLE_PROTOBUF_COMPILER_CSHARP_SOURCE_GENERATOR_BASE_H__
+
+#include <string>
+
+#include <compiler/code_generator.h>
+#include <io/printer.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace csharp {
+
+struct Options;
+
+class SourceGeneratorBase {
+ protected:
+ SourceGeneratorBase(const Options* options);
+ virtual ~SourceGeneratorBase();
+
+ SourceGeneratorBase(const SourceGeneratorBase&) = delete;
+ SourceGeneratorBase& operator=(const SourceGeneratorBase&) = delete;
+
+ std::string class_access_level();
+ const Options* options();
+
+ // Write any attributes used to decorate generated function members (methods and properties).
+ // Should not be used to decorate types.
+ void WriteGeneratedCodeAttributes(io::Printer* printer);
+
+ private:
+ const Options *options_;
+};
+
+} // namespace csharp
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_COMPILER_CSHARP_SOURCE_GENERATOR_BASE_H__
+
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_wrapper_field.cc b/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_wrapper_field.cc
new file mode 100644
index 00000000..4a45017e
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_wrapper_field.cc
@@ -0,0 +1,308 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 <sstream>
+
+#include <compiler/code_generator.h>
+#include <descriptor.h>
+#include <descriptor.pb.h>
+#include <io/printer.h>
+#include <io/zero_copy_stream.h>
+
+#include <compiler/csharp/csharp_doc_comment.h>
+#include <compiler/csharp/csharp_helpers.h>
+#include <compiler/csharp/csharp_options.h>
+#include <compiler/csharp/csharp_wrapper_field.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace csharp {
+
+WrapperFieldGenerator::WrapperFieldGenerator(const FieldDescriptor* descriptor,
+ int presenceIndex, const Options *options)
+ : FieldGeneratorBase(descriptor, presenceIndex, options) {
+ variables_["has_property_check"] = name() + "_ != null";
+ variables_["has_not_property_check"] = name() + "_ == null";
+ const FieldDescriptor* wrapped_field = descriptor->message_type()->field(0);
+ is_value_type = wrapped_field->type() != FieldDescriptor::TYPE_STRING &&
+ wrapped_field->type() != FieldDescriptor::TYPE_BYTES;
+ if (is_value_type) {
+ variables_["nonnullable_type_name"] = type_name(wrapped_field);
+ }
+}
+
+WrapperFieldGenerator::~WrapperFieldGenerator() {
+}
+
+void WrapperFieldGenerator::GenerateMembers(io::Printer* printer) {
+ printer->Print(
+ variables_,
+ "private static readonly pb::FieldCodec<$type_name$> _single_$name$_codec = ");
+ GenerateCodecCode(printer);
+ printer->Print(
+ variables_,
+ ";\n"
+ "private $type_name$ $name$_;\n");
+ WritePropertyDocComment(printer, descriptor_);
+ AddPublicMemberAttributes(printer);
+ printer->Print(
+ variables_,
+ "$access_level$ $type_name$ $property_name$ {\n"
+ " get { return $name$_; }\n"
+ " set {\n"
+ " $name$_ = value;\n"
+ " }\n"
+ "}\n\n");
+ if (SupportsPresenceApi(descriptor_)) {
+ printer->Print(
+ variables_,
+ "/// <summary>Gets whether the $descriptor_name$ field is set</summary>\n");
+ AddPublicMemberAttributes(printer);
+ printer->Print(
+ variables_,
+ "$access_level$ bool Has$property_name$ {\n"
+ " get { return $name$_ != null; }\n"
+ "}\n\n");
+ printer->Print(
+ variables_,
+ "/// <summary>Clears the value of the $descriptor_name$ field</summary>\n");
+ AddPublicMemberAttributes(printer);
+ printer->Print(
+ variables_,
+ "$access_level$ void Clear$property_name$() {\n"
+ " $name$_ = null;\n"
+ "}\n");
+ }
+}
+
+void WrapperFieldGenerator::GenerateMergingCode(io::Printer* printer) {
+ printer->Print(
+ variables_,
+ "if (other.$has_property_check$) {\n"
+ " if ($has_not_property_check$ || other.$property_name$ != $default_value$) {\n"
+ " $property_name$ = other.$property_name$;\n"
+ " }\n"
+ "}\n");
+}
+
+void WrapperFieldGenerator::GenerateParsingCode(io::Printer* printer) {
+ GenerateParsingCode(printer, true);
+}
+
+void WrapperFieldGenerator::GenerateParsingCode(io::Printer* printer, bool use_parse_context) {
+ printer->Print(
+ variables_,
+ use_parse_context
+ ? "$type_name$ value = _single_$name$_codec.Read(ref input);\n"
+ "if ($has_not_property_check$ || value != $default_value$) {\n"
+ " $property_name$ = value;\n"
+ "}\n"
+ : "$type_name$ value = _single_$name$_codec.Read(input);\n"
+ "if ($has_not_property_check$ || value != $default_value$) {\n"
+ " $property_name$ = value;\n"
+ "}\n");
+}
+
+void WrapperFieldGenerator::GenerateSerializationCode(io::Printer* printer) {
+ GenerateSerializationCode(printer, true);
+}
+
+void WrapperFieldGenerator::GenerateSerializationCode(io::Printer* printer, bool use_write_context) {
+ printer->Print(
+ variables_,
+ use_write_context
+ ? "if ($has_property_check$) {\n"
+ " _single_$name$_codec.WriteTagAndValue(ref output, $property_name$);\n"
+ "}\n"
+ : "if ($has_property_check$) {\n"
+ " _single_$name$_codec.WriteTagAndValue(output, $property_name$);\n"
+ "}\n");
+}
+
+void WrapperFieldGenerator::GenerateSerializedSizeCode(io::Printer* printer) {
+ printer->Print(
+ variables_,
+ "if ($has_property_check$) {\n"
+ " size += _single_$name$_codec.CalculateSizeWithTag($property_name$);\n"
+ "}\n");
+}
+
+void WrapperFieldGenerator::WriteHash(io::Printer* printer) {
+ const char *text = "if ($has_property_check$) hash ^= $property_name$.GetHashCode();\n";
+ if (descriptor_->message_type()->field(0)->type() == FieldDescriptor::TYPE_FLOAT) {
+ text = "if ($has_property_check$) hash ^= pbc::ProtobufEqualityComparers.BitwiseNullableSingleEqualityComparer.GetHashCode($property_name$);\n";
+ }
+ else if (descriptor_->message_type()->field(0)->type() == FieldDescriptor::TYPE_DOUBLE) {
+ text = "if ($has_property_check$) hash ^= pbc::ProtobufEqualityComparers.BitwiseNullableDoubleEqualityComparer.GetHashCode($property_name$);\n";
+ }
+ printer->Print(variables_, text);
+}
+
+void WrapperFieldGenerator::WriteEquals(io::Printer* printer) {
+ const char *text = "if ($property_name$ != other.$property_name$) return false;\n";
+ if (descriptor_->message_type()->field(0)->type() == FieldDescriptor::TYPE_FLOAT) {
+ text = "if (!pbc::ProtobufEqualityComparers.BitwiseNullableSingleEqualityComparer.Equals($property_name$, other.$property_name$)) return false;\n";
+ }
+ else if (descriptor_->message_type()->field(0)->type() == FieldDescriptor::TYPE_DOUBLE) {
+ text = "if (!pbc::ProtobufEqualityComparers.BitwiseNullableDoubleEqualityComparer.Equals($property_name$, other.$property_name$)) return false;\n";
+ }
+ printer->Print(variables_, text);
+}
+
+void WrapperFieldGenerator::WriteToString(io::Printer* printer) {
+ // TODO: Implement if we ever actually need it...
+}
+
+void WrapperFieldGenerator::GenerateCloningCode(io::Printer* printer) {
+ printer->Print(variables_,
+ "$property_name$ = other.$property_name$;\n");
+}
+
+void WrapperFieldGenerator::GenerateCodecCode(io::Printer* printer) {
+ if (is_value_type) {
+ printer->Print(
+ variables_,
+ "pb::FieldCodec.ForStructWrapper<$nonnullable_type_name$>($tag$)");
+ } else {
+ printer->Print(
+ variables_,
+ "pb::FieldCodec.ForClassWrapper<$type_name$>($tag$)");
+ }
+}
+
+void WrapperFieldGenerator::GenerateExtensionCode(io::Printer* printer) {
+ WritePropertyDocComment(printer, descriptor_);
+ AddDeprecatedFlag(printer);
+ printer->Print(
+ variables_,
+ "$access_level$ static readonly pb::Extension<$extended_type$, $type_name$> $property_name$ =\n"
+ " new pb::Extension<$extended_type$, $type_name$>($number$, ");
+ GenerateCodecCode(printer);
+ printer->Print(");\n");
+}
+
+WrapperOneofFieldGenerator::WrapperOneofFieldGenerator(
+ const FieldDescriptor* descriptor, int presenceIndex, const Options *options)
+ : WrapperFieldGenerator(descriptor, presenceIndex, options) {
+ SetCommonOneofFieldVariables(&variables_);
+}
+
+WrapperOneofFieldGenerator::~WrapperOneofFieldGenerator() {
+}
+
+void WrapperOneofFieldGenerator::GenerateMembers(io::Printer* printer) {
+ // Note: deliberately _oneof_$name$_codec, not _$oneof_name$_codec... we have one codec per field.
+ printer->Print(
+ variables_,
+ "private static readonly pb::FieldCodec<$type_name$> _oneof_$name$_codec = ");
+ GenerateCodecCode(printer);
+ printer->Print(";\n");
+ WritePropertyDocComment(printer, descriptor_);
+ AddPublicMemberAttributes(printer);
+ printer->Print(
+ variables_,
+ "$access_level$ $type_name$ $property_name$ {\n"
+ " get { return $has_property_check$ ? ($type_name$) $oneof_name$_ : ($type_name$) null; }\n"
+ " set {\n"
+ " $oneof_name$_ = value;\n"
+ " $oneof_name$Case_ = value == null ? $oneof_property_name$OneofCase.None : $oneof_property_name$OneofCase.$property_name$;\n"
+ " }\n"
+ "}\n");
+ if (SupportsPresenceApi(descriptor_)) {
+ printer->Print(
+ variables_,
+ "/// <summary>Gets whether the \"$descriptor_name$\" field is set</summary>\n");
+ AddPublicMemberAttributes(printer);
+ printer->Print(
+ variables_,
+ "$access_level$ bool Has$property_name$ {\n"
+ " get { return $oneof_name$Case_ == $oneof_property_name$OneofCase.$property_name$; }\n"
+ "}\n");
+ printer->Print(
+ variables_,
+ "/// <summary> Clears the value of the oneof if it's currently set to \"$descriptor_name$\" </summary>\n");
+ AddPublicMemberAttributes(printer);
+ printer->Print(
+ variables_,
+ "$access_level$ void Clear$property_name$() {\n"
+ " if ($has_property_check$) {\n"
+ " Clear$oneof_property_name$();\n"
+ " }\n"
+ "}\n");
+ }
+}
+
+void WrapperOneofFieldGenerator::GenerateMergingCode(io::Printer* printer) {
+ printer->Print(variables_, "$property_name$ = other.$property_name$;\n");
+}
+
+void WrapperOneofFieldGenerator::GenerateParsingCode(io::Printer* printer) {
+ GenerateParsingCode(printer, true);
+}
+
+void WrapperOneofFieldGenerator::GenerateParsingCode(io::Printer* printer, bool use_parse_context) {
+ printer->Print(
+ variables_,
+ use_parse_context
+ ? "$property_name$ = _oneof_$name$_codec.Read(ref input);\n"
+ : "$property_name$ = _oneof_$name$_codec.Read(input);\n");
+}
+
+void WrapperOneofFieldGenerator::GenerateSerializationCode(io::Printer* printer) {
+ GenerateSerializationCode(printer, true);
+}
+
+void WrapperOneofFieldGenerator::GenerateSerializationCode(io::Printer* printer, bool use_write_context) {
+ // TODO: I suspect this is wrong...
+ printer->Print(
+ variables_,
+ use_write_context
+ ? "if ($has_property_check$) {\n"
+ " _oneof_$name$_codec.WriteTagAndValue(ref output, ($type_name$) $oneof_name$_);\n"
+ "}\n"
+ : "if ($has_property_check$) {\n"
+ " _oneof_$name$_codec.WriteTagAndValue(output, ($type_name$) $oneof_name$_);\n"
+ "}\n");
+}
+
+void WrapperOneofFieldGenerator::GenerateSerializedSizeCode(io::Printer* printer) {
+ // TODO: I suspect this is wrong...
+ printer->Print(
+ variables_,
+ "if ($has_property_check$) {\n"
+ " size += _oneof_$name$_codec.CalculateSizeWithTag($property_name$);\n"
+ "}\n");
+}
+
+} // namespace csharp
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_wrapper_field.h b/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_wrapper_field.h
new file mode 100644
index 00000000..86d5b7fc
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/csharp/csharp_wrapper_field.h
@@ -0,0 +1,99 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_CSHARP_WRAPPER_FIELD_H__
+#define GOOGLE_PROTOBUF_COMPILER_CSHARP_WRAPPER_FIELD_H__
+
+#include <string>
+
+#include <compiler/code_generator.h>
+#include <compiler/csharp/csharp_field_base.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace csharp {
+
+struct Options;
+
+class WrapperFieldGenerator : public FieldGeneratorBase {
+ public:
+ WrapperFieldGenerator(const FieldDescriptor* descriptor,
+ int presenceIndex,
+ const Options *options);
+ ~WrapperFieldGenerator();
+
+ WrapperFieldGenerator(const WrapperFieldGenerator&) = delete;
+ WrapperFieldGenerator& operator=(const WrapperFieldGenerator&) = delete;
+
+ virtual void GenerateCodecCode(io::Printer* printer) override;
+ virtual void GenerateCloningCode(io::Printer* printer) override;
+ virtual void GenerateMembers(io::Printer* printer) override;
+ virtual void GenerateMergingCode(io::Printer* printer) override;
+ virtual void GenerateParsingCode(io::Printer* printer) override;
+ virtual void GenerateParsingCode(io::Printer* printer, bool use_parse_context) override;
+ virtual void GenerateSerializationCode(io::Printer* printer) override;
+ virtual void GenerateSerializationCode(io::Printer* printer, bool use_write_context) override;
+ virtual void GenerateSerializedSizeCode(io::Printer* printer) override;
+ virtual void GenerateExtensionCode(io::Printer* printer) override;
+
+ virtual void WriteHash(io::Printer* printer) override;
+ virtual void WriteEquals(io::Printer* printer) override;
+ virtual void WriteToString(io::Printer* printer) override;
+
+ private:
+ bool is_value_type; // True for int32 etc; false for bytes and string
+};
+
+class WrapperOneofFieldGenerator : public WrapperFieldGenerator {
+ public:
+ WrapperOneofFieldGenerator(const FieldDescriptor* descriptor,
+ int presenceIndex,
+ const Options *options);
+ ~WrapperOneofFieldGenerator();
+
+ WrapperOneofFieldGenerator(const WrapperOneofFieldGenerator&) = delete;
+ WrapperOneofFieldGenerator& operator=(const WrapperOneofFieldGenerator&) = delete;
+
+ virtual void GenerateMembers(io::Printer* printer) override;
+ virtual void GenerateMergingCode(io::Printer* printer) override;
+ virtual void GenerateParsingCode(io::Printer* printer) override;
+ virtual void GenerateParsingCode(io::Printer* printer, bool use_parse_context) override;
+ virtual void GenerateSerializationCode(io::Printer* printer) override;
+ virtual void GenerateSerializationCode(io::Printer* printer, bool use_write_context) override;
+ virtual void GenerateSerializedSizeCode(io::Printer* printer) override;
+};
+
+} // namespace csharp
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_COMPILER_CSHARP_WRAPPER_FIELD_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/importer.cc b/NorthstarDedicatedTest/include/protobuf/compiler/importer.cc
new file mode 100644
index 00000000..e2e6cd32
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/importer.cc
@@ -0,0 +1,524 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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.
+
+#ifdef _MSC_VER
+#include <direct.h>
+#else
+#include <unistd.h>
+#endif
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include <algorithm>
+#include <memory>
+
+#include <compiler/importer.h>
+#include <compiler/parser.h>
+#include <io/tokenizer.h>
+#include <io/zero_copy_stream_impl.h>
+#include <stubs/strutil.h>
+#include <io/io_win32.h>
+
+#ifdef _WIN32
+#include <ctype.h>
+#endif
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+
+#ifdef _WIN32
+// 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::open;
+#endif
+
+// Returns true if the text looks like a Windows-style absolute path, starting
+// with a drive letter. Example: "C:\foo". TODO(kenton): Share this with
+// copy in command_line_interface.cc?
+static bool IsWindowsAbsolutePath(const std::string& text) {
+#if defined(_WIN32) || defined(__CYGWIN__)
+ return text.size() >= 3 && text[1] == ':' && isalpha(text[0]) &&
+ (text[2] == '/' || text[2] == '\\') && text.find_last_of(':') == 1;
+#else
+ return false;
+#endif
+}
+
+MultiFileErrorCollector::~MultiFileErrorCollector() {}
+
+// This class serves two purposes:
+// - It implements the ErrorCollector interface (used by Tokenizer and Parser)
+// in terms of MultiFileErrorCollector, using a particular filename.
+// - It lets us check if any errors have occurred.
+class SourceTreeDescriptorDatabase::SingleFileErrorCollector
+ : public io::ErrorCollector {
+ public:
+ SingleFileErrorCollector(const std::string& filename,
+ MultiFileErrorCollector* multi_file_error_collector)
+ : filename_(filename),
+ multi_file_error_collector_(multi_file_error_collector),
+ had_errors_(false) {}
+ ~SingleFileErrorCollector() {}
+
+ bool had_errors() { return had_errors_; }
+
+ // implements ErrorCollector ---------------------------------------
+ void AddError(int line, int column, const std::string& message) override {
+ if (multi_file_error_collector_ != NULL) {
+ multi_file_error_collector_->AddError(filename_, line, column, message);
+ }
+ had_errors_ = true;
+ }
+
+ private:
+ std::string filename_;
+ MultiFileErrorCollector* multi_file_error_collector_;
+ bool had_errors_;
+};
+
+// ===================================================================
+
+SourceTreeDescriptorDatabase::SourceTreeDescriptorDatabase(
+ SourceTree* source_tree)
+ : source_tree_(source_tree),
+ fallback_database_(nullptr),
+ error_collector_(nullptr),
+ using_validation_error_collector_(false),
+ validation_error_collector_(this) {}
+
+SourceTreeDescriptorDatabase::SourceTreeDescriptorDatabase(
+ SourceTree* source_tree, DescriptorDatabase* fallback_database)
+ : source_tree_(source_tree),
+ fallback_database_(fallback_database),
+ error_collector_(nullptr),
+ using_validation_error_collector_(false),
+ validation_error_collector_(this) {}
+
+SourceTreeDescriptorDatabase::~SourceTreeDescriptorDatabase() {}
+
+bool SourceTreeDescriptorDatabase::FindFileByName(const std::string& filename,
+ FileDescriptorProto* output) {
+ std::unique_ptr<io::ZeroCopyInputStream> input(source_tree_->Open(filename));
+ if (input == NULL) {
+ if (fallback_database_ != nullptr &&
+ fallback_database_->FindFileByName(filename, output)) {
+ return true;
+ }
+ if (error_collector_ != NULL) {
+ error_collector_->AddError(filename, -1, 0,
+ source_tree_->GetLastErrorMessage());
+ }
+ return false;
+ }
+
+ // Set up the tokenizer and parser.
+ SingleFileErrorCollector file_error_collector(filename, error_collector_);
+ io::Tokenizer tokenizer(input.get(), &file_error_collector);
+
+ Parser parser;
+ if (error_collector_ != NULL) {
+ parser.RecordErrorsTo(&file_error_collector);
+ }
+ if (using_validation_error_collector_) {
+ parser.RecordSourceLocationsTo(&source_locations_);
+ }
+
+ // Parse it.
+ output->set_name(filename);
+ return parser.Parse(&tokenizer, output) && !file_error_collector.had_errors();
+}
+
+bool SourceTreeDescriptorDatabase::FindFileContainingSymbol(
+ const std::string& symbol_name, FileDescriptorProto* output) {
+ return false;
+}
+
+bool SourceTreeDescriptorDatabase::FindFileContainingExtension(
+ const std::string& containing_type, int field_number,
+ FileDescriptorProto* output) {
+ return false;
+}
+
+// -------------------------------------------------------------------
+
+SourceTreeDescriptorDatabase::ValidationErrorCollector::
+ ValidationErrorCollector(SourceTreeDescriptorDatabase* owner)
+ : owner_(owner) {}
+
+SourceTreeDescriptorDatabase::ValidationErrorCollector::
+ ~ValidationErrorCollector() {}
+
+void SourceTreeDescriptorDatabase::ValidationErrorCollector::AddError(
+ const std::string& filename, const std::string& element_name,
+ const Message* descriptor, ErrorLocation location,
+ const std::string& message) {
+ if (owner_->error_collector_ == NULL) return;
+
+ int line, column;
+ if (location == DescriptorPool::ErrorCollector::IMPORT) {
+ owner_->source_locations_.FindImport(descriptor, element_name, &line,
+ &column);
+ } else {
+ owner_->source_locations_.Find(descriptor, location, &line, &column);
+ }
+ owner_->error_collector_->AddError(filename, line, column, message);
+}
+
+void SourceTreeDescriptorDatabase::ValidationErrorCollector::AddWarning(
+ const std::string& filename, const std::string& element_name,
+ const Message* descriptor, ErrorLocation location,
+ const std::string& message) {
+ if (owner_->error_collector_ == NULL) return;
+
+ int line, column;
+ if (location == DescriptorPool::ErrorCollector::IMPORT) {
+ owner_->source_locations_.FindImport(descriptor, element_name, &line,
+ &column);
+ } else {
+ owner_->source_locations_.Find(descriptor, location, &line, &column);
+ }
+ owner_->error_collector_->AddWarning(filename, line, column, message);
+}
+
+// ===================================================================
+
+Importer::Importer(SourceTree* source_tree,
+ MultiFileErrorCollector* error_collector)
+ : database_(source_tree),
+ pool_(&database_, database_.GetValidationErrorCollector()) {
+ pool_.EnforceWeakDependencies(true);
+ database_.RecordErrorsTo(error_collector);
+}
+
+Importer::~Importer() {}
+
+const FileDescriptor* Importer::Import(const std::string& filename) {
+ return pool_.FindFileByName(filename);
+}
+
+void Importer::AddUnusedImportTrackFile(const std::string& file_name,
+ bool is_error) {
+ pool_.AddUnusedImportTrackFile(file_name, is_error);
+}
+
+void Importer::ClearUnusedImportTrackFiles() {
+ pool_.ClearUnusedImportTrackFiles();
+}
+
+
+// ===================================================================
+
+SourceTree::~SourceTree() {}
+
+std::string SourceTree::GetLastErrorMessage() { return "File not found."; }
+
+DiskSourceTree::DiskSourceTree() {}
+
+DiskSourceTree::~DiskSourceTree() {}
+
+static inline char LastChar(const std::string& str) {
+ return str[str.size() - 1];
+}
+
+// Given a path, returns an equivalent path with these changes:
+// - On Windows, any backslashes are replaced with forward slashes.
+// - Any instances of the directory "." are removed.
+// - Any consecutive '/'s are collapsed into a single slash.
+// Note that the resulting string may be empty.
+//
+// TODO(kenton): It would be nice to handle "..", e.g. so that we can figure
+// out that "foo/bar.proto" is inside "baz/../foo". However, if baz is a
+// symlink or doesn't exist, then things get complicated, and we can't
+// actually determine this without investigating the filesystem, probably
+// in non-portable ways. So, we punt.
+//
+// TODO(kenton): It would be nice to use realpath() here except that it
+// resolves symbolic links. This could cause problems if people place
+// symbolic links in their source tree. For example, if you executed:
+// protoc --proto_path=foo foo/bar/baz.proto
+// then if foo/bar is a symbolic link, foo/bar/baz.proto will canonicalize
+// to a path which does not appear to be under foo, and thus the compiler
+// will complain that baz.proto is not inside the --proto_path.
+static std::string CanonicalizePath(std::string path) {
+#ifdef _WIN32
+ // The Win32 API accepts forward slashes as a path delimiter even though
+ // backslashes are standard. Let's avoid confusion and use only forward
+ // slashes.
+ if (HasPrefixString(path, "\\\\")) {
+ // Avoid converting two leading backslashes.
+ path = "\\\\" + StringReplace(path.substr(2), "\\", "/", true);
+ } else {
+ path = StringReplace(path, "\\", "/", true);
+ }
+#endif
+
+ std::vector<std::string> canonical_parts;
+ std::vector<std::string> parts = Split(
+ path, "/", true); // Note: Removes empty parts.
+ for (const std::string& part : parts) {
+ if (part == ".") {
+ // Ignore.
+ } else {
+ canonical_parts.push_back(part);
+ }
+ }
+ std::string result = Join(canonical_parts, "/");
+ if (!path.empty() && path[0] == '/') {
+ // Restore leading slash.
+ result = '/' + result;
+ }
+ if (!path.empty() && LastChar(path) == '/' && !result.empty() &&
+ LastChar(result) != '/') {
+ // Restore trailing slash.
+ result += '/';
+ }
+ return result;
+}
+
+static inline bool ContainsParentReference(const std::string& path) {
+ return path == ".." || HasPrefixString(path, "../") ||
+ HasSuffixString(path, "/..") || path.find("/../") != std::string::npos;
+}
+
+// Maps a file from an old location to a new one. Typically, old_prefix is
+// a virtual path and new_prefix is its corresponding disk path. Returns
+// false if the filename did not start with old_prefix, otherwise replaces
+// old_prefix with new_prefix and stores the result in *result. Examples:
+// string result;
+// assert(ApplyMapping("foo/bar", "", "baz", &result));
+// assert(result == "baz/foo/bar");
+//
+// assert(ApplyMapping("foo/bar", "foo", "baz", &result));
+// assert(result == "baz/bar");
+//
+// assert(ApplyMapping("foo", "foo", "bar", &result));
+// assert(result == "bar");
+//
+// assert(!ApplyMapping("foo/bar", "baz", "qux", &result));
+// assert(!ApplyMapping("foo/bar", "baz", "qux", &result));
+// assert(!ApplyMapping("foobar", "foo", "baz", &result));
+static bool ApplyMapping(const std::string& filename,
+ const std::string& old_prefix,
+ const std::string& new_prefix, std::string* result) {
+ if (old_prefix.empty()) {
+ // old_prefix matches any relative path.
+ if (ContainsParentReference(filename)) {
+ // We do not allow the file name to use "..".
+ return false;
+ }
+ if (HasPrefixString(filename, "/") || IsWindowsAbsolutePath(filename)) {
+ // This is an absolute path, so it isn't matched by the empty string.
+ return false;
+ }
+ result->assign(new_prefix);
+ if (!result->empty()) result->push_back('/');
+ result->append(filename);
+ return true;
+ } else if (HasPrefixString(filename, old_prefix)) {
+ // old_prefix is a prefix of the filename. Is it the whole filename?
+ if (filename.size() == old_prefix.size()) {
+ // Yep, it's an exact match.
+ *result = new_prefix;
+ return true;
+ } else {
+ // Not an exact match. Is the next character a '/'? Otherwise,
+ // this isn't actually a match at all. E.g. the prefix "foo/bar"
+ // does not match the filename "foo/barbaz".
+ int after_prefix_start = -1;
+ if (filename[old_prefix.size()] == '/') {
+ after_prefix_start = old_prefix.size() + 1;
+ } else if (filename[old_prefix.size() - 1] == '/') {
+ // old_prefix is never empty, and canonicalized paths never have
+ // consecutive '/' characters.
+ after_prefix_start = old_prefix.size();
+ }
+ if (after_prefix_start != -1) {
+ // Yep. So the prefixes are directories and the filename is a file
+ // inside them.
+ std::string after_prefix = filename.substr(after_prefix_start);
+ if (ContainsParentReference(after_prefix)) {
+ // We do not allow the file name to use "..".
+ return false;
+ }
+ result->assign(new_prefix);
+ if (!result->empty()) result->push_back('/');
+ result->append(after_prefix);
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+void DiskSourceTree::MapPath(const std::string& virtual_path,
+ const std::string& disk_path) {
+ mappings_.push_back(Mapping(virtual_path, CanonicalizePath(disk_path)));
+}
+
+DiskSourceTree::DiskFileToVirtualFileResult
+DiskSourceTree::DiskFileToVirtualFile(const std::string& disk_file,
+ std::string* virtual_file,
+ std::string* shadowing_disk_file) {
+ int mapping_index = -1;
+ std::string canonical_disk_file = CanonicalizePath(disk_file);
+
+ for (int i = 0; i < mappings_.size(); i++) {
+ // Apply the mapping in reverse.
+ if (ApplyMapping(canonical_disk_file, mappings_[i].disk_path,
+ mappings_[i].virtual_path, virtual_file)) {
+ // Success.
+ mapping_index = i;
+ break;
+ }
+ }
+
+ if (mapping_index == -1) {
+ return NO_MAPPING;
+ }
+
+ // Iterate through all mappings with higher precedence and verify that none
+ // of them map this file to some other existing file.
+ for (int i = 0; i < mapping_index; i++) {
+ if (ApplyMapping(*virtual_file, mappings_[i].virtual_path,
+ mappings_[i].disk_path, shadowing_disk_file)) {
+ if (access(shadowing_disk_file->c_str(), F_OK) >= 0) {
+ // File exists.
+ return SHADOWED;
+ }
+ }
+ }
+ shadowing_disk_file->clear();
+
+ // Verify that we can open the file. Note that this also has the side-effect
+ // of verifying that we are not canonicalizing away any non-existent
+ // directories.
+ std::unique_ptr<io::ZeroCopyInputStream> stream(OpenDiskFile(disk_file));
+ if (stream == NULL) {
+ return CANNOT_OPEN;
+ }
+
+ return SUCCESS;
+}
+
+bool DiskSourceTree::VirtualFileToDiskFile(const std::string& virtual_file,
+ std::string* disk_file) {
+ std::unique_ptr<io::ZeroCopyInputStream> stream(
+ OpenVirtualFile(virtual_file, disk_file));
+ return stream != NULL;
+}
+
+io::ZeroCopyInputStream* DiskSourceTree::Open(const std::string& filename) {
+ return OpenVirtualFile(filename, NULL);
+}
+
+std::string DiskSourceTree::GetLastErrorMessage() {
+ return last_error_message_;
+}
+
+io::ZeroCopyInputStream* DiskSourceTree::OpenVirtualFile(
+ const std::string& virtual_file, std::string* disk_file) {
+ if (virtual_file != CanonicalizePath(virtual_file) ||
+ ContainsParentReference(virtual_file)) {
+ // We do not allow importing of paths containing things like ".." or
+ // consecutive slashes since the compiler expects files to be uniquely
+ // identified by file name.
+ last_error_message_ =
+ "Backslashes, consecutive slashes, \".\", or \"..\" "
+ "are not allowed in the virtual path";
+ return NULL;
+ }
+
+ for (const auto& mapping : mappings_) {
+ std::string temp_disk_file;
+ if (ApplyMapping(virtual_file, mapping.virtual_path, mapping.disk_path,
+ &temp_disk_file)) {
+ io::ZeroCopyInputStream* stream = OpenDiskFile(temp_disk_file);
+ if (stream != NULL) {
+ if (disk_file != NULL) {
+ *disk_file = temp_disk_file;
+ }
+ return stream;
+ }
+
+ if (errno == EACCES) {
+ // The file exists but is not readable.
+ last_error_message_ =
+ "Read access is denied for file: " + temp_disk_file;
+ return NULL;
+ }
+ }
+ }
+ last_error_message_ = "File not found.";
+ return NULL;
+}
+
+io::ZeroCopyInputStream* DiskSourceTree::OpenDiskFile(
+ const std::string& filename) {
+ struct stat sb;
+ int ret = 0;
+ do {
+ ret = stat(filename.c_str(), &sb);
+ } while (ret != 0 && errno == EINTR);
+#if defined(_WIN32)
+ if (ret == 0 && sb.st_mode & S_IFDIR) {
+ last_error_message_ = "Input file is a directory.";
+ return NULL;
+ }
+#else
+ if (ret == 0 && S_ISDIR(sb.st_mode)) {
+ last_error_message_ = "Input file is a directory.";
+ return NULL;
+ }
+#endif
+ int file_descriptor;
+ do {
+ file_descriptor = open(filename.c_str(), O_RDONLY);
+ } while (file_descriptor < 0 && errno == EINTR);
+ if (file_descriptor >= 0) {
+ io::FileInputStream* result = new io::FileInputStream(file_descriptor);
+ result->SetCloseOnDelete(true);
+ return result;
+ } else {
+ return NULL;
+ }
+}
+
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/importer.h b/NorthstarDedicatedTest/include/protobuf/compiler/importer.h
new file mode 100644
index 00000000..10c7feb3
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/importer.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 is the public interface to the .proto file parser.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_IMPORTER_H__
+#define GOOGLE_PROTOBUF_COMPILER_IMPORTER_H__
+
+#include <set>
+#include <string>
+#include <utility>
+#include <vector>
+#include <compiler/parser.h>
+#include <descriptor.h>
+#include <descriptor_database.h>
+
+#include <port_def.inc>
+
+namespace google {
+namespace protobuf {
+
+namespace io {
+class ZeroCopyInputStream;
+}
+
+namespace compiler {
+
+// Defined in this file.
+class Importer;
+class MultiFileErrorCollector;
+class SourceTree;
+class DiskSourceTree;
+
+// TODO(kenton): Move all SourceTree stuff to a separate file?
+
+// An implementation of DescriptorDatabase which loads files from a SourceTree
+// and parses them.
+//
+// Note: This class is not thread-safe since it maintains a table of source
+// code locations for error reporting. However, when a DescriptorPool wraps
+// a DescriptorDatabase, it uses mutex locking to make sure only one method
+// of the database is called at a time, even if the DescriptorPool is used
+// from multiple threads. Therefore, there is only a problem if you create
+// multiple DescriptorPools wrapping the same SourceTreeDescriptorDatabase
+// and use them from multiple threads.
+//
+// Note: This class does not implement FindFileContainingSymbol() or
+// FindFileContainingExtension(); these will always return false.
+class PROTOBUF_EXPORT SourceTreeDescriptorDatabase : public DescriptorDatabase {
+ public:
+ SourceTreeDescriptorDatabase(SourceTree* source_tree);
+
+ // If non-NULL, fallback_database will be checked if a file doesn't exist in
+ // the specified source_tree.
+ SourceTreeDescriptorDatabase(SourceTree* source_tree,
+ DescriptorDatabase* fallback_database);
+ ~SourceTreeDescriptorDatabase();
+
+ // Instructs the SourceTreeDescriptorDatabase to report any parse errors
+ // to the given MultiFileErrorCollector. This should be called before
+ // parsing. error_collector must remain valid until either this method
+ // is called again or the SourceTreeDescriptorDatabase is destroyed.
+ void RecordErrorsTo(MultiFileErrorCollector* error_collector) {
+ error_collector_ = error_collector;
+ }
+
+ // Gets a DescriptorPool::ErrorCollector which records errors to the
+ // MultiFileErrorCollector specified with RecordErrorsTo(). This collector
+ // has the ability to determine exact line and column numbers of errors
+ // from the information given to it by the DescriptorPool.
+ DescriptorPool::ErrorCollector* GetValidationErrorCollector() {
+ using_validation_error_collector_ = true;
+ return &validation_error_collector_;
+ }
+
+ // 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;
+
+ private:
+ class SingleFileErrorCollector;
+
+ SourceTree* source_tree_;
+ DescriptorDatabase* fallback_database_;
+ MultiFileErrorCollector* error_collector_;
+
+ class PROTOBUF_EXPORT ValidationErrorCollector
+ : public DescriptorPool::ErrorCollector {
+ public:
+ ValidationErrorCollector(SourceTreeDescriptorDatabase* owner);
+ ~ValidationErrorCollector();
+
+ // implements ErrorCollector ---------------------------------------
+ void AddError(const std::string& filename, const std::string& element_name,
+ const Message* descriptor, ErrorLocation location,
+ const std::string& message) override;
+
+ void AddWarning(const std::string& filename,
+ const std::string& element_name, const Message* descriptor,
+ ErrorLocation location,
+ const std::string& message) override;
+
+ private:
+ SourceTreeDescriptorDatabase* owner_;
+ };
+ friend class ValidationErrorCollector;
+
+ bool using_validation_error_collector_;
+ SourceLocationTable source_locations_;
+ ValidationErrorCollector validation_error_collector_;
+};
+
+// Simple interface for parsing .proto files. This wraps the process
+// of opening the file, parsing it with a Parser, recursively parsing all its
+// imports, and then cross-linking the results to produce a FileDescriptor.
+//
+// This is really just a thin wrapper around SourceTreeDescriptorDatabase.
+// You may find that SourceTreeDescriptorDatabase is more flexible.
+//
+// TODO(kenton): I feel like this class is not well-named.
+class PROTOBUF_EXPORT Importer {
+ public:
+ Importer(SourceTree* source_tree, MultiFileErrorCollector* error_collector);
+ ~Importer();
+
+ // Import the given file and build a FileDescriptor representing it. If
+ // the file is already in the DescriptorPool, the existing FileDescriptor
+ // will be returned. The FileDescriptor is property of the DescriptorPool,
+ // and will remain valid until it is destroyed. If any errors occur, they
+ // will be reported using the error collector and Import() will return NULL.
+ //
+ // A particular Importer object will only report errors for a particular
+ // file once. All future attempts to import the same file will return NULL
+ // without reporting any errors. The idea is that you might want to import
+ // a lot of files without seeing the same errors over and over again. If
+ // you want to see errors for the same files repeatedly, you can use a
+ // separate Importer object to import each one (but use the same
+ // DescriptorPool so that they can be cross-linked).
+ const FileDescriptor* Import(const std::string& filename);
+
+ // The DescriptorPool in which all imported FileDescriptors and their
+ // contents are stored.
+ inline const DescriptorPool* pool() const { return &pool_; }
+
+ void AddUnusedImportTrackFile(const std::string& file_name,
+ bool is_error = false);
+ void ClearUnusedImportTrackFiles();
+
+
+ private:
+ SourceTreeDescriptorDatabase database_;
+ DescriptorPool pool_;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Importer);
+};
+
+// If the importer encounters problems while trying to import the proto files,
+// it reports them to a MultiFileErrorCollector.
+class PROTOBUF_EXPORT MultiFileErrorCollector {
+ public:
+ inline MultiFileErrorCollector() {}
+ virtual ~MultiFileErrorCollector();
+
+ // Line and column numbers are zero-based. A line number of -1 indicates
+ // an error with the entire file (e.g. "not found").
+ virtual void AddError(const std::string& filename, int line, int column,
+ const std::string& message) = 0;
+
+ virtual void AddWarning(const std::string& /* filename */, int /* line */,
+ int /* column */, const std::string& /* message */) {}
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MultiFileErrorCollector);
+};
+
+// Abstract interface which represents a directory tree containing proto files.
+// Used by the default implementation of Importer to resolve import statements
+// Most users will probably want to use the DiskSourceTree implementation,
+// below.
+class PROTOBUF_EXPORT SourceTree {
+ public:
+ inline SourceTree() {}
+ virtual ~SourceTree();
+
+ // Open the given file and return a stream that reads it, or NULL if not
+ // found. The caller takes ownership of the returned object. The filename
+ // must be a path relative to the root of the source tree and must not
+ // contain "." or ".." components.
+ virtual io::ZeroCopyInputStream* Open(const std::string& filename) = 0;
+
+ // If Open() returns NULL, calling this method immediately will return an
+ // description of the error.
+ // Subclasses should implement this method and return a meaningful value for
+ // better error reporting.
+ // TODO(xiaofeng): change this to a pure virtual function.
+ virtual std::string GetLastErrorMessage();
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(SourceTree);
+};
+
+// An implementation of SourceTree which loads files from locations on disk.
+// Multiple mappings can be set up to map locations in the DiskSourceTree to
+// locations in the physical filesystem.
+class PROTOBUF_EXPORT DiskSourceTree : public SourceTree {
+ public:
+ DiskSourceTree();
+ ~DiskSourceTree();
+
+ // Map a path on disk to a location in the SourceTree. The path may be
+ // either a file or a directory. If it is a directory, the entire tree
+ // under it will be mapped to the given virtual location. To map a directory
+ // to the root of the source tree, pass an empty string for virtual_path.
+ //
+ // If multiple mapped paths apply when opening a file, they will be searched
+ // in order. For example, if you do:
+ // MapPath("bar", "foo/bar");
+ // MapPath("", "baz");
+ // and then you do:
+ // Open("bar/qux");
+ // the DiskSourceTree will first try to open foo/bar/qux, then baz/bar/qux,
+ // returning the first one that opens successfully.
+ //
+ // disk_path may be an absolute path or relative to the current directory,
+ // just like a path you'd pass to open().
+ void MapPath(const std::string& virtual_path, const std::string& disk_path);
+
+ // Return type for DiskFileToVirtualFile().
+ enum DiskFileToVirtualFileResult {
+ SUCCESS,
+ SHADOWED,
+ CANNOT_OPEN,
+ NO_MAPPING
+ };
+
+ // Given a path to a file on disk, find a virtual path mapping to that
+ // file. The first mapping created with MapPath() whose disk_path contains
+ // the filename is used. However, that virtual path may not actually be
+ // usable to open the given file. Possible return values are:
+ // * SUCCESS: The mapping was found. *virtual_file is filled in so that
+ // calling Open(*virtual_file) will open the file named by disk_file.
+ // * SHADOWED: A mapping was found, but using Open() to open this virtual
+ // path will end up returning some different file. This is because some
+ // other mapping with a higher precedence also matches this virtual path
+ // and maps it to a different file that exists on disk. *virtual_file
+ // is filled in as it would be in the SUCCESS case. *shadowing_disk_file
+ // is filled in with the disk path of the file which would be opened if
+ // you were to call Open(*virtual_file).
+ // * CANNOT_OPEN: The mapping was found and was not shadowed, but the
+ // file specified cannot be opened. When this value is returned,
+ // errno will indicate the reason the file cannot be opened. *virtual_file
+ // will be set to the virtual path as in the SUCCESS case, even though
+ // it is not useful.
+ // * NO_MAPPING: Indicates that no mapping was found which contains this
+ // file.
+ DiskFileToVirtualFileResult DiskFileToVirtualFile(
+ const std::string& disk_file, std::string* virtual_file,
+ std::string* shadowing_disk_file);
+
+ // Given a virtual path, find the path to the file on disk.
+ // Return true and update disk_file with the on-disk path if the file exists.
+ // Return false and leave disk_file untouched if the file doesn't exist.
+ bool VirtualFileToDiskFile(const std::string& virtual_file,
+ std::string* disk_file);
+
+ // implements SourceTree -------------------------------------------
+ io::ZeroCopyInputStream* Open(const std::string& filename) override;
+
+ std::string GetLastErrorMessage() override;
+
+ private:
+ struct Mapping {
+ std::string virtual_path;
+ std::string disk_path;
+
+ inline Mapping(const std::string& virtual_path_param,
+ const std::string& disk_path_param)
+ : virtual_path(virtual_path_param), disk_path(disk_path_param) {}
+ };
+ std::vector<Mapping> mappings_;
+ std::string last_error_message_;
+
+ // Like Open(), but returns the on-disk path in disk_file if disk_file is
+ // non-NULL and the file could be successfully opened.
+ io::ZeroCopyInputStream* OpenVirtualFile(const std::string& virtual_file,
+ std::string* disk_file);
+
+ // Like Open() but given the actual on-disk path.
+ io::ZeroCopyInputStream* OpenDiskFile(const std::string& filename);
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(DiskSourceTree);
+};
+
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#include <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_COMPILER_IMPORTER_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/importer_unittest.cc b/NorthstarDedicatedTest/include/protobuf/compiler/importer_unittest.cc
new file mode 100644
index 00000000..16ff90f2
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/importer_unittest.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.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <compiler/importer.h>
+
+#include <memory>
+#include <unordered_map>
+
+#include <stubs/logging.h>
+#include <stubs/common.h>
+#include <testing/file.h>
+#include <testing/file.h>
+#include <testing/file.h>
+#include <io/zero_copy_stream_impl.h>
+#include <descriptor.h>
+#include <testing/googletest.h>
+#include <gtest/gtest.h>
+#include <stubs/substitute.h>
+#include <stubs/map_util.h>
+#include <stubs/strutil.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+
+namespace {
+
+bool FileExists(const std::string& path) {
+ return File::Exists(path);
+}
+
+#define EXPECT_SUBSTRING(needle, haystack) \
+ EXPECT_PRED_FORMAT2(testing::IsSubstring, (needle), (haystack))
+
+class MockErrorCollector : public MultiFileErrorCollector {
+ public:
+ MockErrorCollector() {}
+ ~MockErrorCollector() {}
+
+ std::string text_;
+ std::string warning_text_;
+
+ // implements ErrorCollector ---------------------------------------
+ void AddError(const std::string& filename, int line, int column,
+ const std::string& message) {
+ strings::SubstituteAndAppend(&text_, "$0:$1:$2: $3\n", filename, line, column,
+ message);
+ }
+
+ void AddWarning(const std::string& filename, int line, int column,
+ const std::string& message) {
+ strings::SubstituteAndAppend(&warning_text_, "$0:$1:$2: $3\n", filename, line,
+ column, message);
+ }
+};
+
+// -------------------------------------------------------------------
+
+// A dummy implementation of SourceTree backed by a simple map.
+class MockSourceTree : public SourceTree {
+ public:
+ MockSourceTree() {}
+ ~MockSourceTree() {}
+
+ void AddFile(const std::string& name, const char* contents) {
+ files_[name] = contents;
+ }
+
+ // implements SourceTree -------------------------------------------
+ io::ZeroCopyInputStream* Open(const std::string& filename) {
+ const char* contents = FindPtrOrNull(files_, filename);
+ if (contents == NULL) {
+ return NULL;
+ } else {
+ return new io::ArrayInputStream(contents, strlen(contents));
+ }
+ }
+
+ std::string GetLastErrorMessage() { return "File not found."; }
+
+ private:
+ std::unordered_map<std::string, const char*> files_;
+};
+
+// ===================================================================
+
+class ImporterTest : public testing::Test {
+ protected:
+ ImporterTest() : importer_(&source_tree_, &error_collector_) {}
+
+ void AddFile(const std::string& filename, const char* text) {
+ source_tree_.AddFile(filename, text);
+ }
+
+ // Return the collected error text
+ std::string warning() const { return error_collector_.warning_text_; }
+
+ MockErrorCollector error_collector_;
+ MockSourceTree source_tree_;
+ Importer importer_;
+};
+
+TEST_F(ImporterTest, Import) {
+ // Test normal importing.
+ AddFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "message Foo {}\n");
+
+ const FileDescriptor* file = importer_.Import("foo.proto");
+ EXPECT_EQ("", error_collector_.text_);
+ ASSERT_TRUE(file != NULL);
+
+ ASSERT_EQ(1, file->message_type_count());
+ EXPECT_EQ("Foo", file->message_type(0)->name());
+
+ // Importing again should return same object.
+ EXPECT_EQ(file, importer_.Import("foo.proto"));
+}
+
+TEST_F(ImporterTest, ImportNested) {
+ // Test that importing a file which imports another file works.
+ AddFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "import \"bar.proto\";\n"
+ "message Foo {\n"
+ " optional Bar bar = 1;\n"
+ "}\n");
+ AddFile("bar.proto",
+ "syntax = \"proto2\";\n"
+ "message Bar {}\n");
+
+ // Note that both files are actually parsed by the first call to Import()
+ // here, since foo.proto imports bar.proto. The second call just returns
+ // the same ProtoFile for bar.proto which was constructed while importing
+ // foo.proto. We test that this is the case below by checking that bar
+ // is among foo's dependencies (by pointer).
+ const FileDescriptor* foo = importer_.Import("foo.proto");
+ const FileDescriptor* bar = importer_.Import("bar.proto");
+ EXPECT_EQ("", error_collector_.text_);
+ ASSERT_TRUE(foo != NULL);
+ ASSERT_TRUE(bar != NULL);
+
+ // Check that foo's dependency is the same object as bar.
+ ASSERT_EQ(1, foo->dependency_count());
+ EXPECT_EQ(bar, foo->dependency(0));
+
+ // Check that foo properly cross-links bar.
+ ASSERT_EQ(1, foo->message_type_count());
+ ASSERT_EQ(1, bar->message_type_count());
+ ASSERT_EQ(1, foo->message_type(0)->field_count());
+ ASSERT_EQ(FieldDescriptor::TYPE_MESSAGE,
+ foo->message_type(0)->field(0)->type());
+ EXPECT_EQ(bar->message_type(0),
+ foo->message_type(0)->field(0)->message_type());
+}
+
+TEST_F(ImporterTest, FileNotFound) {
+ // Error: Parsing a file that doesn't exist.
+ EXPECT_TRUE(importer_.Import("foo.proto") == NULL);
+ EXPECT_EQ("foo.proto:-1:0: File not found.\n", error_collector_.text_);
+}
+
+TEST_F(ImporterTest, ImportNotFound) {
+ // Error: Importing a file that doesn't exist.
+ AddFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "import \"bar.proto\";\n");
+
+ EXPECT_TRUE(importer_.Import("foo.proto") == NULL);
+ EXPECT_EQ(
+ "bar.proto:-1:0: File not found.\n"
+ "foo.proto:1:0: Import \"bar.proto\" was not found or had errors.\n",
+ error_collector_.text_);
+}
+
+TEST_F(ImporterTest, RecursiveImport) {
+ // Error: Recursive import.
+ AddFile("recursive1.proto",
+ "syntax = \"proto2\";\n"
+ "\n"
+ "import \"recursive2.proto\";\n");
+ AddFile("recursive2.proto",
+ "syntax = \"proto2\";\n"
+ "import \"recursive1.proto\";\n");
+
+ EXPECT_TRUE(importer_.Import("recursive1.proto") == NULL);
+ EXPECT_EQ(
+ "recursive1.proto:2:0: File recursively imports itself: "
+ "recursive1.proto "
+ "-> recursive2.proto -> recursive1.proto\n"
+ "recursive2.proto:1:0: Import \"recursive1.proto\" was not found "
+ "or had errors.\n"
+ "recursive1.proto:2:0: Import \"recursive2.proto\" was not found "
+ "or had errors.\n",
+ error_collector_.text_);
+}
+
+TEST_F(ImporterTest, RecursiveImportSelf) {
+ // Error: Recursive import.
+ AddFile("recursive.proto",
+ "syntax = \"proto2\";\n"
+ "\n"
+ "import \"recursive.proto\";\n");
+
+ EXPECT_TRUE(importer_.Import("recursive.proto") == nullptr);
+ EXPECT_EQ(
+ "recursive.proto:2:0: File recursively imports itself: "
+ "recursive.proto -> recursive.proto\n",
+ error_collector_.text_);
+}
+
+TEST_F(ImporterTest, LiteRuntimeImport) {
+ // Error: Recursive import.
+ AddFile("bar.proto",
+ "syntax = \"proto2\";\n"
+ "option optimize_for = LITE_RUNTIME;\n");
+ AddFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "import \"bar.proto\";\n");
+
+ EXPECT_TRUE(importer_.Import("foo.proto") == nullptr);
+ EXPECT_EQ(
+ "foo.proto:1:0: 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 \"bar.proto\" which is.\n",
+ error_collector_.text_);
+}
+
+
+// ===================================================================
+
+class DiskSourceTreeTest : public testing::Test {
+ protected:
+ virtual void SetUp() {
+ dirnames_.push_back(TestTempDir() + "/test_proto2_import_path_1");
+ dirnames_.push_back(TestTempDir() + "/test_proto2_import_path_2");
+
+ for (int i = 0; i < dirnames_.size(); i++) {
+ if (FileExists(dirnames_[i])) {
+ File::DeleteRecursively(dirnames_[i], NULL, NULL);
+ }
+ GOOGLE_CHECK_OK(File::CreateDir(dirnames_[i], 0777));
+ }
+ }
+
+ virtual void TearDown() {
+ for (int i = 0; i < dirnames_.size(); i++) {
+ if (FileExists(dirnames_[i])) {
+ File::DeleteRecursively(dirnames_[i], NULL, NULL);
+ }
+ }
+ }
+
+ void AddFile(const std::string& filename, const char* contents) {
+ GOOGLE_CHECK_OK(File::SetContents(filename, contents, true));
+ }
+
+ void AddSubdir(const std::string& dirname) {
+ GOOGLE_CHECK_OK(File::CreateDir(dirname, 0777));
+ }
+
+ void ExpectFileContents(const std::string& filename,
+ const char* expected_contents) {
+ std::unique_ptr<io::ZeroCopyInputStream> input(source_tree_.Open(filename));
+
+ ASSERT_FALSE(input == NULL);
+
+ // Read all the data from the file.
+ std::string file_contents;
+ const void* data;
+ int size;
+ while (input->Next(&data, &size)) {
+ file_contents.append(reinterpret_cast<const char*>(data), size);
+ }
+
+ EXPECT_EQ(expected_contents, file_contents);
+ }
+
+ void ExpectCannotOpenFile(const std::string& filename,
+ const std::string& error_message) {
+ std::unique_ptr<io::ZeroCopyInputStream> input(source_tree_.Open(filename));
+ EXPECT_TRUE(input == NULL);
+ EXPECT_EQ(error_message, source_tree_.GetLastErrorMessage());
+ }
+
+ DiskSourceTree source_tree_;
+
+ // Paths of two on-disk directories to use during the test.
+ std::vector<std::string> dirnames_;
+};
+
+TEST_F(DiskSourceTreeTest, MapRoot) {
+ // Test opening a file in a directory that is mapped to the root of the
+ // source tree.
+ AddFile(dirnames_[0] + "/foo", "Hello World!");
+ source_tree_.MapPath("", dirnames_[0]);
+
+ ExpectFileContents("foo", "Hello World!");
+ ExpectCannotOpenFile("bar", "File not found.");
+}
+
+TEST_F(DiskSourceTreeTest, MapDirectory) {
+ // Test opening a file in a directory that is mapped to somewhere other
+ // than the root of the source tree.
+
+ AddFile(dirnames_[0] + "/foo", "Hello World!");
+ source_tree_.MapPath("baz", dirnames_[0]);
+
+ ExpectFileContents("baz/foo", "Hello World!");
+ ExpectCannotOpenFile("baz/bar", "File not found.");
+ ExpectCannotOpenFile("foo", "File not found.");
+ ExpectCannotOpenFile("bar", "File not found.");
+
+ // Non-canonical file names should not work.
+ ExpectCannotOpenFile("baz//foo",
+ "Backslashes, consecutive slashes, \".\", or \"..\" are "
+ "not allowed in the virtual path");
+ ExpectCannotOpenFile("baz/../baz/foo",
+ "Backslashes, consecutive slashes, \".\", or \"..\" are "
+ "not allowed in the virtual path");
+ ExpectCannotOpenFile("baz/./foo",
+ "Backslashes, consecutive slashes, \".\", or \"..\" are "
+ "not allowed in the virtual path");
+ ExpectCannotOpenFile("baz/foo/", "File not found.");
+}
+
+TEST_F(DiskSourceTreeTest, NoParent) {
+ // Test that we cannot open files in a parent of a mapped directory.
+
+ AddFile(dirnames_[0] + "/foo", "Hello World!");
+ AddSubdir(dirnames_[0] + "/bar");
+ AddFile(dirnames_[0] + "/bar/baz", "Blah.");
+ source_tree_.MapPath("", dirnames_[0] + "/bar");
+
+ ExpectFileContents("baz", "Blah.");
+ ExpectCannotOpenFile("../foo",
+ "Backslashes, consecutive slashes, \".\", or \"..\" are "
+ "not allowed in the virtual path");
+ ExpectCannotOpenFile("../bar/baz",
+ "Backslashes, consecutive slashes, \".\", or \"..\" are "
+ "not allowed in the virtual path");
+}
+
+TEST_F(DiskSourceTreeTest, MapFile) {
+ // Test opening a file that is mapped directly into the source tree.
+
+ AddFile(dirnames_[0] + "/foo", "Hello World!");
+ source_tree_.MapPath("foo", dirnames_[0] + "/foo");
+
+ ExpectFileContents("foo", "Hello World!");
+ ExpectCannotOpenFile("bar", "File not found.");
+}
+
+TEST_F(DiskSourceTreeTest, SearchMultipleDirectories) {
+ // Test mapping and searching multiple directories.
+
+ AddFile(dirnames_[0] + "/foo", "Hello World!");
+ AddFile(dirnames_[1] + "/foo", "This file should be hidden.");
+ AddFile(dirnames_[1] + "/bar", "Goodbye World!");
+ source_tree_.MapPath("", dirnames_[0]);
+ source_tree_.MapPath("", dirnames_[1]);
+
+ ExpectFileContents("foo", "Hello World!");
+ ExpectFileContents("bar", "Goodbye World!");
+ ExpectCannotOpenFile("baz", "File not found.");
+}
+
+TEST_F(DiskSourceTreeTest, OrderingTrumpsSpecificity) {
+ // Test that directories are always searched in order, even when a latter
+ // directory is more-specific than a former one.
+
+ // Create the "bar" directory so we can put a file in it.
+ GOOGLE_CHECK_OK(File::CreateDir(dirnames_[0] + "/bar", 0777));
+
+ // Add files and map paths.
+ AddFile(dirnames_[0] + "/bar/foo", "Hello World!");
+ AddFile(dirnames_[1] + "/foo", "This file should be hidden.");
+ source_tree_.MapPath("", dirnames_[0]);
+ source_tree_.MapPath("bar", dirnames_[1]);
+
+ // Check.
+ ExpectFileContents("bar/foo", "Hello World!");
+}
+
+TEST_F(DiskSourceTreeTest, DiskFileToVirtualFile) {
+ // Test DiskFileToVirtualFile.
+
+ AddFile(dirnames_[0] + "/foo", "Hello World!");
+ AddFile(dirnames_[1] + "/foo", "This file should be hidden.");
+ source_tree_.MapPath("bar", dirnames_[0]);
+ source_tree_.MapPath("bar", dirnames_[1]);
+
+ std::string virtual_file;
+ std::string shadowing_disk_file;
+
+ EXPECT_EQ(DiskSourceTree::NO_MAPPING,
+ source_tree_.DiskFileToVirtualFile("/foo", &virtual_file,
+ &shadowing_disk_file));
+
+ EXPECT_EQ(DiskSourceTree::SHADOWED,
+ source_tree_.DiskFileToVirtualFile(
+ dirnames_[1] + "/foo", &virtual_file, &shadowing_disk_file));
+ EXPECT_EQ("bar/foo", virtual_file);
+ EXPECT_EQ(dirnames_[0] + "/foo", shadowing_disk_file);
+
+ EXPECT_EQ(DiskSourceTree::CANNOT_OPEN,
+ source_tree_.DiskFileToVirtualFile(
+ dirnames_[1] + "/baz", &virtual_file, &shadowing_disk_file));
+ EXPECT_EQ("bar/baz", virtual_file);
+
+ EXPECT_EQ(DiskSourceTree::SUCCESS,
+ source_tree_.DiskFileToVirtualFile(
+ dirnames_[0] + "/foo", &virtual_file, &shadowing_disk_file));
+ EXPECT_EQ("bar/foo", virtual_file);
+}
+
+TEST_F(DiskSourceTreeTest, DiskFileToVirtualFileCanonicalization) {
+ // Test handling of "..", ".", etc. in DiskFileToVirtualFile().
+
+ source_tree_.MapPath("dir1", "..");
+ source_tree_.MapPath("dir2", "../../foo");
+ source_tree_.MapPath("dir3", "./foo/bar/.");
+ source_tree_.MapPath("dir4", ".");
+ source_tree_.MapPath("", "/qux");
+ source_tree_.MapPath("dir5", "/quux/");
+
+ std::string virtual_file;
+ std::string shadowing_disk_file;
+
+ // "../.." should not be considered to be under "..".
+ EXPECT_EQ(DiskSourceTree::NO_MAPPING,
+ source_tree_.DiskFileToVirtualFile("../../baz", &virtual_file,
+ &shadowing_disk_file));
+
+ // "/foo" is not mapped (it should not be misinterpreted as being under ".").
+ EXPECT_EQ(DiskSourceTree::NO_MAPPING,
+ source_tree_.DiskFileToVirtualFile("/foo", &virtual_file,
+ &shadowing_disk_file));
+
+#ifdef WIN32
+ // "C:\foo" is not mapped (it should not be misinterpreted as being under
+ // ".").
+ EXPECT_EQ(DiskSourceTree::NO_MAPPING,
+ source_tree_.DiskFileToVirtualFile("C:\\foo", &virtual_file,
+ &shadowing_disk_file));
+#endif // WIN32
+
+ // But "../baz" should be.
+ EXPECT_EQ(DiskSourceTree::CANNOT_OPEN,
+ source_tree_.DiskFileToVirtualFile("../baz", &virtual_file,
+ &shadowing_disk_file));
+ EXPECT_EQ("dir1/baz", virtual_file);
+
+ // "../../foo/baz" is under "../../foo".
+ EXPECT_EQ(DiskSourceTree::CANNOT_OPEN,
+ source_tree_.DiskFileToVirtualFile("../../foo/baz", &virtual_file,
+ &shadowing_disk_file));
+ EXPECT_EQ("dir2/baz", virtual_file);
+
+ // "foo/./bar/baz" is under "./foo/bar/.".
+ EXPECT_EQ(DiskSourceTree::CANNOT_OPEN,
+ source_tree_.DiskFileToVirtualFile("foo/bar/baz", &virtual_file,
+ &shadowing_disk_file));
+ EXPECT_EQ("dir3/baz", virtual_file);
+
+ // "bar" is under ".".
+ EXPECT_EQ(DiskSourceTree::CANNOT_OPEN,
+ source_tree_.DiskFileToVirtualFile("bar", &virtual_file,
+ &shadowing_disk_file));
+ EXPECT_EQ("dir4/bar", virtual_file);
+
+ // "/qux/baz" is under "/qux".
+ EXPECT_EQ(DiskSourceTree::CANNOT_OPEN,
+ source_tree_.DiskFileToVirtualFile("/qux/baz", &virtual_file,
+ &shadowing_disk_file));
+ EXPECT_EQ("baz", virtual_file);
+
+ // "/quux/bar" is under "/quux".
+ EXPECT_EQ(DiskSourceTree::CANNOT_OPEN,
+ source_tree_.DiskFileToVirtualFile("/quux/bar", &virtual_file,
+ &shadowing_disk_file));
+ EXPECT_EQ("dir5/bar", virtual_file);
+}
+
+TEST_F(DiskSourceTreeTest, VirtualFileToDiskFile) {
+ // Test VirtualFileToDiskFile.
+
+ AddFile(dirnames_[0] + "/foo", "Hello World!");
+ AddFile(dirnames_[1] + "/foo", "This file should be hidden.");
+ AddFile(dirnames_[1] + "/quux", "This file should not be hidden.");
+ source_tree_.MapPath("bar", dirnames_[0]);
+ source_tree_.MapPath("bar", dirnames_[1]);
+
+ // Existent files, shadowed and non-shadowed case.
+ std::string disk_file;
+ EXPECT_TRUE(source_tree_.VirtualFileToDiskFile("bar/foo", &disk_file));
+ EXPECT_EQ(dirnames_[0] + "/foo", disk_file);
+ EXPECT_TRUE(source_tree_.VirtualFileToDiskFile("bar/quux", &disk_file));
+ EXPECT_EQ(dirnames_[1] + "/quux", disk_file);
+
+ // Nonexistent file in existent directory and vice versa.
+ std::string not_touched = "not touched";
+ EXPECT_FALSE(source_tree_.VirtualFileToDiskFile("bar/baz", &not_touched));
+ EXPECT_EQ("not touched", not_touched);
+ EXPECT_FALSE(source_tree_.VirtualFileToDiskFile("baz/foo", &not_touched));
+ EXPECT_EQ("not touched", not_touched);
+
+ // Accept NULL as output parameter.
+ EXPECT_TRUE(source_tree_.VirtualFileToDiskFile("bar/foo", NULL));
+ EXPECT_FALSE(source_tree_.VirtualFileToDiskFile("baz/foo", NULL));
+}
+
+} // namespace
+
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_context.cc b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_context.cc
new file mode 100644
index 00000000..00ffc946
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_context.cc
@@ -0,0 +1,202 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <compiler/java/java_context.h>
+
+#include <compiler/java/java_field.h>
+#include <compiler/java/java_helpers.h>
+#include <compiler/java/java_name_resolver.h>
+#include <descriptor.h>
+#include <stubs/strutil.h>
+#include <stubs/map_util.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+Context::Context(const FileDescriptor* file, const Options& options)
+ : name_resolver_(new ClassNameResolver), options_(options) {
+ InitializeFieldGeneratorInfo(file);
+}
+
+Context::~Context() {}
+
+ClassNameResolver* Context::GetNameResolver() const {
+ return name_resolver_.get();
+}
+
+namespace {
+// Whether two fields have conflicting accessors (assuming name1 and name2
+// are different). name1 and name2 are field1 and field2's camel-case name
+// respectively.
+bool IsConflicting(const FieldDescriptor* field1, const std::string& name1,
+ const FieldDescriptor* field2, const std::string& name2,
+ std::string* info) {
+ if (field1->is_repeated()) {
+ if (field2->is_repeated()) {
+ // Both fields are repeated.
+ return false;
+ } else {
+ // field1 is repeated, and field2 is not.
+ if (name1 + "Count" == name2) {
+ *info = "both repeated field \"" + field1->name() + "\" and singular " +
+ "field \"" + field2->name() + "\" generate the method \"" +
+ "get" + name1 + "Count()\"";
+ return true;
+ }
+ if (name1 + "List" == name2) {
+ *info = "both repeated field \"" + field1->name() + "\" and singular " +
+ "field \"" + field2->name() + "\" generate the method \"" +
+ "get" + name1 + "List()\"";
+ return true;
+ }
+ // Well, there are obviously many more conflicting cases, but it probably
+ // doesn't worth the effort to exhaust all of them because they rarely
+ // happen and as we are continuing adding new methods/changing existing
+ // methods the number of different conflicting cases will keep growing.
+ // We can just add more cases here when they are found in the real world.
+ return false;
+ }
+ } else {
+ if (field2->is_repeated()) {
+ return IsConflicting(field2, name2, field1, name1, info);
+ } else {
+ // None of the two fields are repeated.
+ return false;
+ }
+ }
+}
+} // namespace
+
+void Context::InitializeFieldGeneratorInfo(const FileDescriptor* file) {
+ for (int i = 0; i < file->message_type_count(); ++i) {
+ InitializeFieldGeneratorInfoForMessage(file->message_type(i));
+ }
+}
+
+void Context::InitializeFieldGeneratorInfoForMessage(
+ const Descriptor* message) {
+ for (int i = 0; i < message->nested_type_count(); ++i) {
+ InitializeFieldGeneratorInfoForMessage(message->nested_type(i));
+ }
+ std::vector<const FieldDescriptor*> fields;
+ fields.reserve(message->field_count());
+ for (int i = 0; i < message->field_count(); ++i) {
+ fields.push_back(message->field(i));
+ }
+ InitializeFieldGeneratorInfoForFields(fields);
+
+ for (int i = 0; i < message->oneof_decl_count(); ++i) {
+ const OneofDescriptor* oneof = message->oneof_decl(i);
+ OneofGeneratorInfo info;
+ info.name = UnderscoresToCamelCase(oneof->name(), false);
+ info.capitalized_name = UnderscoresToCamelCase(oneof->name(), true);
+ oneof_generator_info_map_[oneof] = info;
+ }
+}
+
+void Context::InitializeFieldGeneratorInfoForFields(
+ const std::vector<const FieldDescriptor*>& fields) {
+ // Find out all fields that conflict with some other field in the same
+ // message.
+ std::vector<bool> is_conflict(fields.size());
+ std::vector<std::string> conflict_reason(fields.size());
+ for (int i = 0; i < fields.size(); ++i) {
+ const FieldDescriptor* field = fields[i];
+ const std::string& name = UnderscoresToCapitalizedCamelCase(field);
+ for (int j = i + 1; j < fields.size(); ++j) {
+ const FieldDescriptor* other = fields[j];
+ const std::string& other_name = UnderscoresToCapitalizedCamelCase(other);
+ if (name == other_name) {
+ is_conflict[i] = is_conflict[j] = true;
+ conflict_reason[i] = conflict_reason[j] =
+ "capitalized name of field \"" + field->name() +
+ "\" conflicts with field \"" + other->name() + "\"";
+ } else if (IsConflicting(field, name, other, other_name,
+ &conflict_reason[j])) {
+ is_conflict[i] = is_conflict[j] = true;
+ conflict_reason[i] = conflict_reason[j];
+ }
+ }
+ if (is_conflict[i]) {
+ GOOGLE_LOG(WARNING) << "field \"" << field->full_name() << "\" is conflicting "
+ << "with another field: " << conflict_reason[i];
+ }
+ }
+ for (int i = 0; i < fields.size(); ++i) {
+ const FieldDescriptor* field = fields[i];
+ FieldGeneratorInfo info;
+ info.name = CamelCaseFieldName(field);
+ info.capitalized_name = UnderscoresToCapitalizedCamelCase(field);
+ // For fields conflicting with some other fields, we append the field
+ // number to their field names in generated code to avoid conflicts.
+ if (is_conflict[i]) {
+ info.name += StrCat(field->number());
+ info.capitalized_name += StrCat(field->number());
+ info.disambiguated_reason = conflict_reason[i];
+ }
+ field_generator_info_map_[field] = info;
+ }
+}
+
+const FieldGeneratorInfo* Context::GetFieldGeneratorInfo(
+ const FieldDescriptor* field) const {
+ const FieldGeneratorInfo* result =
+ FindOrNull(field_generator_info_map_, field);
+ if (result == NULL) {
+ GOOGLE_LOG(FATAL) << "Can not find FieldGeneratorInfo for field: "
+ << field->full_name();
+ }
+ return result;
+}
+
+const OneofGeneratorInfo* Context::GetOneofGeneratorInfo(
+ const OneofDescriptor* oneof) const {
+ const OneofGeneratorInfo* result =
+ FindOrNull(oneof_generator_info_map_, oneof);
+ if (result == NULL) {
+ GOOGLE_LOG(FATAL) << "Can not find OneofGeneratorInfo for oneof: "
+ << oneof->name();
+ }
+ return result;
+}
+
+// Does this message class have generated parsing, serialization, and other
+// standard methods for which reflection-based fallback implementations exist?
+bool Context::HasGeneratedMethods(const Descriptor* descriptor) const {
+ return options_.enforce_lite ||
+ descriptor->file()->options().optimize_for() != FileOptions::CODE_SIZE;
+}
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_context.h b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_context.h
new file mode 100644
index 00000000..ed6e9e9c
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_context.h
@@ -0,0 +1,113 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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_COMPILER_JAVA_CONTEXT_H__
+#define GOOGLE_PROTOBUF_COMPILER_JAVA_CONTEXT_H__
+
+#include <map>
+#include <memory>
+#include <vector>
+
+#include <stubs/common.h>
+#include <compiler/java/java_options.h>
+
+namespace google {
+namespace protobuf {
+class FileDescriptor;
+class FieldDescriptor;
+class OneofDescriptor;
+class Descriptor;
+class EnumDescriptor;
+namespace compiler {
+namespace java {
+class ClassNameResolver; // name_resolver.h
+}
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+struct FieldGeneratorInfo;
+struct OneofGeneratorInfo;
+// A context object holds the information that is shared among all code
+// generators.
+class Context {
+ public:
+ Context(const FileDescriptor* file, const Options& options);
+ ~Context();
+
+ // Get the name resolver associated with this context. The resolver
+ // can be used to map descriptors to Java class names.
+ ClassNameResolver* GetNameResolver() const;
+
+ // Get the FieldGeneratorInfo for a given field.
+ const FieldGeneratorInfo* GetFieldGeneratorInfo(
+ const FieldDescriptor* field) const;
+
+ // Get the OneofGeneratorInfo for a given oneof.
+ const OneofGeneratorInfo* GetOneofGeneratorInfo(
+ const OneofDescriptor* oneof) const;
+
+ const Options& options() const { return options_; }
+
+ // Enforces all the files (including transitive dependencies) to use
+ // LiteRuntime.
+
+ bool EnforceLite() const { return options_.enforce_lite; }
+
+ // Does this message class have generated parsing, serialization, and other
+ // standard methods for which reflection-based fallback implementations exist?
+ bool HasGeneratedMethods(const Descriptor* descriptor) const;
+
+ private:
+ void InitializeFieldGeneratorInfo(const FileDescriptor* file);
+ void InitializeFieldGeneratorInfoForMessage(const Descriptor* message);
+ void InitializeFieldGeneratorInfoForFields(
+ const std::vector<const FieldDescriptor*>& fields);
+
+ std::unique_ptr<ClassNameResolver> name_resolver_;
+ std::map<const FieldDescriptor*, FieldGeneratorInfo>
+ field_generator_info_map_;
+ std::map<const OneofDescriptor*, OneofGeneratorInfo>
+ oneof_generator_info_map_;
+ Options options_;
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Context);
+};
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_CONTEXT_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_doc_comment.cc b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_doc_comment.cc
new file mode 100644
index 00000000..ed9f0d27
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_doc_comment.cc
@@ -0,0 +1,435 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 <compiler/java/java_doc_comment.h>
+
+#include <vector>
+
+#include <descriptor.pb.h>
+#include <io/printer.h>
+#include <stubs/strutil.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+std::string EscapeJavadoc(const std::string& input) {
+ std::string result;
+ result.reserve(input.size() * 2);
+
+ char prev = '*';
+
+ for (std::string::size_type i = 0; i < input.size(); i++) {
+ char c = input[i];
+ switch (c) {
+ case '*':
+ // Avoid "/*".
+ if (prev == '/') {
+ result.append("&#42;");
+ } else {
+ result.push_back(c);
+ }
+ break;
+ case '/':
+ // Avoid "*/".
+ if (prev == '*') {
+ result.append("&#47;");
+ } else {
+ result.push_back(c);
+ }
+ break;
+ case '@':
+ // '@' starts javadoc tags including the @deprecated tag, which will
+ // cause a compile-time error if inserted before a declaration that
+ // does not have a corresponding @Deprecated annotation.
+ result.append("&#64;");
+ break;
+ case '<':
+ // Avoid interpretation as HTML.
+ result.append("&lt;");
+ break;
+ case '>':
+ // Avoid interpretation as HTML.
+ result.append("&gt;");
+ break;
+ case '&':
+ // Avoid interpretation as HTML.
+ result.append("&amp;");
+ break;
+ case '\\':
+ // Java interprets Unicode escape sequences anywhere!
+ result.append("&#92;");
+ break;
+ default:
+ result.push_back(c);
+ break;
+ }
+
+ prev = c;
+ }
+
+ return result;
+}
+
+static void WriteDocCommentBodyForLocation(io::Printer* printer,
+ const SourceLocation& location) {
+ std::string comments = location.leading_comments.empty()
+ ? location.trailing_comments
+ : location.leading_comments;
+ if (!comments.empty()) {
+ // TODO(kenton): Ideally we should parse the comment text as Markdown and
+ // write it back as HTML, but this requires a Markdown parser. For now
+ // we just use <pre> to get fixed-width text formatting.
+
+ // If the comment itself contains block comment start or end markers,
+ // HTML-escape them so that they don't accidentally close the doc comment.
+ comments = EscapeJavadoc(comments);
+
+ std::vector<std::string> lines = Split(comments, "\n");
+ while (!lines.empty() && lines.back().empty()) {
+ lines.pop_back();
+ }
+
+ printer->Print(" * <pre>\n");
+ for (int i = 0; i < lines.size(); i++) {
+ // Most lines should start with a space. Watch out for lines that start
+ // with a /, since putting that right after the leading asterisk will
+ // close the comment.
+ if (!lines[i].empty() && lines[i][0] == '/') {
+ printer->Print(" * $line$\n", "line", lines[i]);
+ } else {
+ printer->Print(" *$line$\n", "line", lines[i]);
+ }
+ }
+ printer->Print(
+ " * </pre>\n"
+ " *\n");
+ }
+}
+
+template <typename DescriptorType>
+static void WriteDocCommentBody(io::Printer* printer,
+ const DescriptorType* descriptor) {
+ SourceLocation location;
+ if (descriptor->GetSourceLocation(&location)) {
+ WriteDocCommentBodyForLocation(printer, location);
+ }
+}
+
+static std::string FirstLineOf(const std::string& value) {
+ std::string result = value;
+
+ std::string::size_type pos = result.find_first_of('\n');
+ if (pos != std::string::npos) {
+ result.erase(pos);
+ }
+
+ // If line ends in an opening brace, make it "{ ... }" so it looks nice.
+ if (!result.empty() && result[result.size() - 1] == '{') {
+ result.append(" ... }");
+ }
+
+ return result;
+}
+
+void WriteMessageDocComment(io::Printer* printer, const Descriptor* message) {
+ printer->Print("/**\n");
+ WriteDocCommentBody(printer, message);
+ printer->Print(
+ " * Protobuf type {@code $fullname$}\n"
+ " */\n",
+ "fullname", EscapeJavadoc(message->full_name()));
+}
+
+void WriteFieldDocComment(io::Printer* printer, const FieldDescriptor* field) {
+ // We start the comment with the main body based on the comments from the
+ // .proto file (if present). We then continue with the field declaration,
+ // e.g.:
+ // optional string foo = 5;
+ // And then we end with the javadoc tags if applicable.
+ // If the field is a group, the debug string might end with {.
+ printer->Print("/**\n");
+ WriteDocCommentBody(printer, field);
+ printer->Print(" * <code>$def$</code>\n", "def",
+ EscapeJavadoc(FirstLineOf(field->DebugString())));
+ printer->Print(" */\n");
+}
+
+void WriteDeprecatedJavadoc(io::Printer* printer, const FieldDescriptor* field,
+ const FieldAccessorType type) {
+ if (!field->options().deprecated()) {
+ return;
+ }
+
+ // Lite codegen does not annotate set & clear methods with @Deprecated.
+ if (field->file()->options().optimize_for() == FileOptions::LITE_RUNTIME &&
+ (type == SETTER || type == CLEARER)) {
+ return;
+ }
+
+ printer->Print(" * @deprecated\n");
+}
+
+void WriteFieldAccessorDocComment(io::Printer* printer,
+ const FieldDescriptor* field,
+ const FieldAccessorType type,
+ const bool builder) {
+ printer->Print("/**\n");
+ WriteDocCommentBody(printer, field);
+ printer->Print(" * <code>$def$</code>\n", "def",
+ EscapeJavadoc(FirstLineOf(field->DebugString())));
+ WriteDeprecatedJavadoc(printer, field, type);
+ switch (type) {
+ case HAZZER:
+ printer->Print(" * @return Whether the $name$ field is set.\n", "name",
+ field->camelcase_name());
+ break;
+ case GETTER:
+ printer->Print(" * @return The $name$.\n", "name",
+ field->camelcase_name());
+ break;
+ case SETTER:
+ printer->Print(" * @param value The $name$ to set.\n", "name",
+ field->camelcase_name());
+ break;
+ case CLEARER:
+ // Print nothing
+ break;
+ // Repeated
+ case LIST_COUNT:
+ printer->Print(" * @return The count of $name$.\n", "name",
+ field->camelcase_name());
+ break;
+ case LIST_GETTER:
+ printer->Print(" * @return A list containing the $name$.\n", "name",
+ field->camelcase_name());
+ break;
+ case LIST_INDEXED_GETTER:
+ printer->Print(" * @param index The index of the element to return.\n");
+ printer->Print(" * @return The $name$ at the given index.\n", "name",
+ field->camelcase_name());
+ break;
+ case LIST_INDEXED_SETTER:
+ printer->Print(" * @param index The index to set the value at.\n");
+ printer->Print(" * @param value The $name$ to set.\n", "name",
+ field->camelcase_name());
+ break;
+ case LIST_ADDER:
+ printer->Print(" * @param value The $name$ to add.\n", "name",
+ field->camelcase_name());
+ break;
+ case LIST_MULTI_ADDER:
+ printer->Print(" * @param values The $name$ to add.\n", "name",
+ field->camelcase_name());
+ break;
+ }
+ if (builder) {
+ printer->Print(" * @return This builder for chaining.\n");
+ }
+ printer->Print(" */\n");
+}
+
+void WriteFieldEnumValueAccessorDocComment(io::Printer* printer,
+ const FieldDescriptor* field,
+ const FieldAccessorType type,
+ const bool builder) {
+ printer->Print("/**\n");
+ WriteDocCommentBody(printer, field);
+ printer->Print(" * <code>$def$</code>\n", "def",
+ EscapeJavadoc(FirstLineOf(field->DebugString())));
+ WriteDeprecatedJavadoc(printer, field, type);
+ switch (type) {
+ case HAZZER:
+ // Should never happen
+ break;
+ case GETTER:
+ printer->Print(
+ " * @return The enum numeric value on the wire for $name$.\n", "name",
+ field->camelcase_name());
+ break;
+ case SETTER:
+ printer->Print(
+ " * @param value The enum numeric value on the wire for $name$ to "
+ "set.\n",
+ "name", field->camelcase_name());
+ break;
+ case CLEARER:
+ // Print nothing
+ break;
+ // Repeated
+ case LIST_COUNT:
+ // Should never happen
+ break;
+ case LIST_GETTER:
+ printer->Print(
+ " * @return A list containing the enum numeric values on the wire "
+ "for $name$.\n",
+ "name", field->camelcase_name());
+ break;
+ case LIST_INDEXED_GETTER:
+ printer->Print(" * @param index The index of the value to return.\n");
+ printer->Print(
+ " * @return The enum numeric value on the wire of $name$ at the "
+ "given index.\n",
+ "name", field->camelcase_name());
+ break;
+ case LIST_INDEXED_SETTER:
+ printer->Print(" * @param index The index to set the value at.\n");
+ printer->Print(
+ " * @param value The enum numeric value on the wire for $name$ to "
+ "set.\n",
+ "name", field->camelcase_name());
+ break;
+ case LIST_ADDER:
+ printer->Print(
+ " * @param value The enum numeric value on the wire for $name$ to "
+ "add.\n",
+ "name", field->camelcase_name());
+ break;
+ case LIST_MULTI_ADDER:
+ printer->Print(
+ " * @param values The enum numeric values on the wire for $name$ to "
+ "add.\n",
+ "name", field->camelcase_name());
+ break;
+ }
+ if (builder) {
+ printer->Print(" * @return This builder for chaining.\n");
+ }
+ printer->Print(" */\n");
+}
+
+void WriteFieldStringBytesAccessorDocComment(io::Printer* printer,
+ const FieldDescriptor* field,
+ const FieldAccessorType type,
+ const bool builder) {
+ printer->Print("/**\n");
+ WriteDocCommentBody(printer, field);
+ printer->Print(" * <code>$def$</code>\n", "def",
+ EscapeJavadoc(FirstLineOf(field->DebugString())));
+ WriteDeprecatedJavadoc(printer, field, type);
+ switch (type) {
+ case HAZZER:
+ // Should never happen
+ break;
+ case GETTER:
+ printer->Print(" * @return The bytes for $name$.\n", "name",
+ field->camelcase_name());
+ break;
+ case SETTER:
+ printer->Print(" * @param value The bytes for $name$ to set.\n", "name",
+ field->camelcase_name());
+ break;
+ case CLEARER:
+ // Print nothing
+ break;
+ // Repeated
+ case LIST_COUNT:
+ // Should never happen
+ break;
+ case LIST_GETTER:
+ printer->Print(" * @return A list containing the bytes for $name$.\n",
+ "name", field->camelcase_name());
+ break;
+ case LIST_INDEXED_GETTER:
+ printer->Print(" * @param index The index of the value to return.\n");
+ printer->Print(" * @return The bytes of the $name$ at the given index.\n",
+ "name", field->camelcase_name());
+ break;
+ case LIST_INDEXED_SETTER:
+ printer->Print(" * @param index The index to set the value at.\n");
+ printer->Print(" * @param value The bytes of the $name$ to set.\n",
+ "name", field->camelcase_name());
+ break;
+ case LIST_ADDER:
+ printer->Print(" * @param value The bytes of the $name$ to add.\n",
+ "name", field->camelcase_name());
+ break;
+ case LIST_MULTI_ADDER:
+ printer->Print(" * @param values The bytes of the $name$ to add.\n",
+ "name", field->camelcase_name());
+ break;
+ }
+ if (builder) {
+ printer->Print(" * @return This builder for chaining.\n");
+ }
+ printer->Print(" */\n");
+}
+
+// Enum
+
+void WriteEnumDocComment(io::Printer* printer, const EnumDescriptor* enum_) {
+ printer->Print("/**\n");
+ WriteDocCommentBody(printer, enum_);
+ printer->Print(
+ " * Protobuf enum {@code $fullname$}\n"
+ " */\n",
+ "fullname", EscapeJavadoc(enum_->full_name()));
+}
+
+void WriteEnumValueDocComment(io::Printer* printer,
+ const EnumValueDescriptor* value) {
+ printer->Print("/**\n");
+ WriteDocCommentBody(printer, value);
+ printer->Print(
+ " * <code>$def$</code>\n"
+ " */\n",
+ "def", EscapeJavadoc(FirstLineOf(value->DebugString())));
+}
+
+void WriteServiceDocComment(io::Printer* printer,
+ const ServiceDescriptor* service) {
+ printer->Print("/**\n");
+ WriteDocCommentBody(printer, service);
+ printer->Print(
+ " * Protobuf service {@code $fullname$}\n"
+ " */\n",
+ "fullname", EscapeJavadoc(service->full_name()));
+}
+
+void WriteMethodDocComment(io::Printer* printer,
+ const MethodDescriptor* method) {
+ printer->Print("/**\n");
+ WriteDocCommentBody(printer, method);
+ printer->Print(
+ " * <code>$def$</code>\n"
+ " */\n",
+ "def", EscapeJavadoc(FirstLineOf(method->DebugString())));
+}
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_doc_comment.h b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_doc_comment.h
new file mode 100644
index 00000000..2706effb
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_doc_comment.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.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_DOC_COMMENT_H__
+#define GOOGLE_PROTOBUF_COMPILER_JAVA_DOC_COMMENT_H__
+
+#include <descriptor.h>
+
+#include <port_def.inc>
+
+namespace google {
+namespace protobuf {
+namespace io {
+class Printer; // printer.h
+}
+} // namespace protobuf
+} // namespace google
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+enum FieldAccessorType {
+ HAZZER,
+ GETTER,
+ SETTER,
+ CLEARER,
+ // Repeated
+ LIST_COUNT,
+ LIST_GETTER,
+ LIST_INDEXED_GETTER,
+ LIST_INDEXED_SETTER,
+ LIST_ADDER,
+ LIST_MULTI_ADDER
+};
+
+void WriteMessageDocComment(io::Printer* printer, const Descriptor* message);
+void WriteFieldDocComment(io::Printer* printer, const FieldDescriptor* field);
+void WriteFieldAccessorDocComment(io::Printer* printer,
+ const FieldDescriptor* field,
+ const FieldAccessorType type,
+ const bool builder = false);
+void WriteFieldEnumValueAccessorDocComment(io::Printer* printer,
+ const FieldDescriptor* field,
+ const FieldAccessorType type,
+ const bool builder = false);
+void WriteFieldStringBytesAccessorDocComment(io::Printer* printer,
+ const FieldDescriptor* field,
+ const FieldAccessorType type,
+ const bool builder = false);
+void WriteEnumDocComment(io::Printer* printer, const EnumDescriptor* enum_);
+void WriteEnumValueDocComment(io::Printer* printer,
+ const EnumValueDescriptor* value);
+void WriteServiceDocComment(io::Printer* printer,
+ const ServiceDescriptor* service);
+void WriteMethodDocComment(io::Printer* printer,
+ const MethodDescriptor* method);
+
+// Exposed for testing only.
+PROTOC_EXPORT std::string EscapeJavadoc(const std::string& input);
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#include <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_DOC_COMMENT_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_doc_comment_unittest.cc b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_doc_comment_unittest.cc
new file mode 100644
index 00000000..cbeadd0e
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_doc_comment_unittest.cc
@@ -0,0 +1,67 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+
+#include <compiler/java/java_doc_comment.h>
+
+#include <gtest/gtest.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+namespace {
+
+TEST(JavaDocCommentTest, Escaping) {
+ EXPECT_EQ("foo /&#42; bar *&#47; baz", EscapeJavadoc("foo /* bar */ baz"));
+ EXPECT_EQ("foo /&#42;&#47; baz", EscapeJavadoc("foo /*/ baz"));
+ EXPECT_EQ("{&#64;foo}", EscapeJavadoc("{@foo}"));
+ EXPECT_EQ("&lt;i&gt;&amp;&lt;/i&gt;", EscapeJavadoc("<i>&</i>"));
+ EXPECT_EQ("foo&#92;u1234bar", EscapeJavadoc("foo\\u1234bar"));
+ EXPECT_EQ("&#64;deprecated", EscapeJavadoc("@deprecated"));
+}
+
+// TODO(kenton): It's hard to write a robust test of the doc comments -- we
+// can only really compare the output against a golden value, which is a
+// fairly tedious and fragile testing strategy. If we want to go that route,
+// it probably makes sense to bite the bullet and write a test that compares
+// the whole generated output for unittest.proto against a golden value, with
+// a very simple script that can be run to regenerate it with the latest code.
+// This would mean that updates to the golden file would have to be included
+// in any change to the code generator, which would actually be fairly useful
+// as it allows the reviewer to see clearly how the generated code is
+// changing.
+
+} // namespace
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_enum.cc b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_enum.cc
new file mode 100644
index 00000000..f3eb4bc2
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_enum.cc
@@ -0,0 +1,391 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <map>
+#include <string>
+
+#include <compiler/java/java_context.h>
+#include <compiler/java/java_doc_comment.h>
+#include <compiler/java/java_enum.h>
+#include <compiler/java/java_helpers.h>
+#include <compiler/java/java_name_resolver.h>
+#include <descriptor.pb.h>
+#include <io/printer.h>
+#include <stubs/strutil.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+EnumGenerator::EnumGenerator(const EnumDescriptor* descriptor,
+ bool immutable_api, Context* context)
+ : descriptor_(descriptor),
+ immutable_api_(immutable_api),
+ context_(context),
+ name_resolver_(context->GetNameResolver()) {
+ for (int i = 0; i < descriptor_->value_count(); i++) {
+ const EnumValueDescriptor* value = descriptor_->value(i);
+ const EnumValueDescriptor* canonical_value =
+ descriptor_->FindValueByNumber(value->number());
+
+ if (value == canonical_value) {
+ canonical_values_.push_back(value);
+ } else {
+ Alias alias;
+ alias.value = value;
+ alias.canonical_value = canonical_value;
+ aliases_.push_back(alias);
+ }
+ }
+}
+
+EnumGenerator::~EnumGenerator() {}
+
+void EnumGenerator::Generate(io::Printer* printer) {
+ WriteEnumDocComment(printer, descriptor_);
+ MaybePrintGeneratedAnnotation(context_, printer, descriptor_, immutable_api_);
+ printer->Print(
+ "$deprecation$public enum $classname$\n"
+ " implements com.google.protobuf.ProtocolMessageEnum {\n",
+ "classname", descriptor_->name(), "deprecation",
+ descriptor_->options().deprecated() ? "@java.lang.Deprecated " : "");
+ printer->Annotate("classname", descriptor_);
+ printer->Indent();
+
+ bool ordinal_is_index = true;
+ std::string index_text = "ordinal()";
+ for (int i = 0; i < canonical_values_.size(); i++) {
+ if (canonical_values_[i]->index() != i) {
+ ordinal_is_index = false;
+ index_text = "index";
+ break;
+ }
+ }
+
+ for (int i = 0; i < canonical_values_.size(); i++) {
+ std::map<std::string, std::string> vars;
+ vars["name"] = canonical_values_[i]->name();
+ vars["index"] = StrCat(canonical_values_[i]->index());
+ vars["number"] = StrCat(canonical_values_[i]->number());
+ WriteEnumValueDocComment(printer, canonical_values_[i]);
+ if (canonical_values_[i]->options().deprecated()) {
+ printer->Print("@java.lang.Deprecated\n");
+ }
+ if (ordinal_is_index) {
+ printer->Print(vars, "$name$($number$),\n");
+ } else {
+ printer->Print(vars, "$name$($index$, $number$),\n");
+ }
+ printer->Annotate("name", canonical_values_[i]);
+ }
+
+ if (SupportUnknownEnumValue(descriptor_->file())) {
+ if (ordinal_is_index) {
+ printer->Print("${$UNRECOGNIZED$}$(-1),\n", "{", "", "}", "");
+ } else {
+ printer->Print("${$UNRECOGNIZED$}$(-1, -1),\n", "{", "", "}", "");
+ }
+ printer->Annotate("{", "}", descriptor_);
+ }
+
+ printer->Print(
+ ";\n"
+ "\n");
+
+ // -----------------------------------------------------------------
+
+ for (int i = 0; i < aliases_.size(); i++) {
+ std::map<std::string, std::string> vars;
+ vars["classname"] = descriptor_->name();
+ vars["name"] = aliases_[i].value->name();
+ vars["canonical_name"] = aliases_[i].canonical_value->name();
+ WriteEnumValueDocComment(printer, aliases_[i].value);
+ printer->Print(
+ vars, "public static final $classname$ $name$ = $canonical_name$;\n");
+ printer->Annotate("name", aliases_[i].value);
+ }
+
+ for (int i = 0; i < descriptor_->value_count(); i++) {
+ std::map<std::string, std::string> vars;
+ vars["name"] = descriptor_->value(i)->name();
+ vars["number"] = StrCat(descriptor_->value(i)->number());
+ vars["{"] = "";
+ vars["}"] = "";
+ vars["deprecation"] = descriptor_->value(i)->options().deprecated()
+ ? "@java.lang.Deprecated "
+ : "";
+ WriteEnumValueDocComment(printer, descriptor_->value(i));
+ printer->Print(vars,
+ "$deprecation$public static final int ${$$name$_VALUE$}$ = "
+ "$number$;\n");
+ printer->Annotate("{", "}", descriptor_->value(i));
+ }
+ printer->Print("\n");
+
+ // -----------------------------------------------------------------
+
+ printer->Print(
+ "\n"
+ "public final int getNumber() {\n");
+ if (SupportUnknownEnumValue(descriptor_->file())) {
+ if (ordinal_is_index) {
+ printer->Print(
+ " if (this == UNRECOGNIZED) {\n"
+ " throw new java.lang.IllegalArgumentException(\n"
+ " \"Can't get the number of an unknown enum value.\");\n"
+ " }\n");
+ } else {
+ printer->Print(
+ " if (index == -1) {\n"
+ " throw new java.lang.IllegalArgumentException(\n"
+ " \"Can't get the number of an unknown enum value.\");\n"
+ " }\n");
+ }
+ }
+ printer->Print(
+ " return value;\n"
+ "}\n"
+ "\n"
+ "/**\n"
+ " * @param value The numeric wire value of the corresponding enum "
+ "entry.\n"
+ " * @return The enum associated with the given numeric wire value.\n"
+ " * @deprecated Use {@link #forNumber(int)} instead.\n"
+ " */\n"
+ "@java.lang.Deprecated\n"
+ "public static $classname$ valueOf(int value) {\n"
+ " return forNumber(value);\n"
+ "}\n"
+ "\n"
+ "/**\n"
+ " * @param value The numeric wire value of the corresponding enum "
+ "entry.\n"
+ " * @return The enum associated with the given numeric wire value.\n"
+ " */\n"
+ "public static $classname$ forNumber(int value) {\n"
+ " switch (value) {\n",
+ "classname", descriptor_->name());
+ printer->Indent();
+ printer->Indent();
+
+ for (int i = 0; i < canonical_values_.size(); i++) {
+ printer->Print("case $number$: return $name$;\n", "name",
+ canonical_values_[i]->name(), "number",
+ StrCat(canonical_values_[i]->number()));
+ }
+
+ printer->Outdent();
+ printer->Outdent();
+ printer->Print(
+ " default: return null;\n"
+ " }\n"
+ "}\n"
+ "\n"
+ "public static com.google.protobuf.Internal.EnumLiteMap<$classname$>\n"
+ " internalGetValueMap() {\n"
+ " return internalValueMap;\n"
+ "}\n"
+ "private static final com.google.protobuf.Internal.EnumLiteMap<\n"
+ " $classname$> internalValueMap =\n"
+ " new com.google.protobuf.Internal.EnumLiteMap<$classname$>() {\n"
+ " public $classname$ findValueByNumber(int number) {\n"
+ " return $classname$.forNumber(number);\n"
+ " }\n"
+ " };\n"
+ "\n",
+ "classname", descriptor_->name());
+
+ // -----------------------------------------------------------------
+ // Reflection
+
+ if (HasDescriptorMethods(descriptor_, context_->EnforceLite())) {
+ printer->Print(
+ "public final com.google.protobuf.Descriptors.EnumValueDescriptor\n"
+ " getValueDescriptor() {\n");
+ if (SupportUnknownEnumValue(descriptor_->file())) {
+ if (ordinal_is_index) {
+ printer->Print(
+ " if (this == UNRECOGNIZED) {\n"
+ " throw new java.lang.IllegalStateException(\n"
+ " \"Can't get the descriptor of an unrecognized enum "
+ "value.\");\n"
+ " }\n");
+ } else {
+ printer->Print(
+ " if (index == -1) {\n"
+ " throw new java.lang.IllegalStateException(\n"
+ " \"Can't get the descriptor of an unrecognized enum "
+ "value.\");\n"
+ " }\n");
+ }
+ }
+ printer->Print(
+ " return getDescriptor().getValues().get($index_text$);\n"
+ "}\n"
+ "public final com.google.protobuf.Descriptors.EnumDescriptor\n"
+ " getDescriptorForType() {\n"
+ " return getDescriptor();\n"
+ "}\n"
+ "public static final com.google.protobuf.Descriptors.EnumDescriptor\n"
+ " getDescriptor() {\n",
+ "index_text", index_text);
+
+ // TODO(kenton): Cache statically? Note that we can't access descriptors
+ // at module init time because it wouldn't work with descriptor.proto, but
+ // we can cache the value the first time getDescriptor() is called.
+ if (descriptor_->containing_type() == NULL) {
+ // The class generated for the File fully populates the descriptor with
+ // extensions in both the mutable and immutable cases. (In the mutable api
+ // this is accomplished by attempting to load the immutable outer class).
+ printer->Print(
+ " return $file$.getDescriptor().getEnumTypes().get($index$);\n",
+ "file",
+ name_resolver_->GetClassName(descriptor_->file(), immutable_api_),
+ "index", StrCat(descriptor_->index()));
+ } else {
+ printer->Print(
+ " return $parent$.$descriptor$.getEnumTypes().get($index$);\n",
+ "parent",
+ name_resolver_->GetClassName(descriptor_->containing_type(),
+ immutable_api_),
+ "descriptor",
+ descriptor_->containing_type()
+ ->options()
+ .no_standard_descriptor_accessor()
+ ? "getDefaultInstance().getDescriptorForType()"
+ : "getDescriptor()",
+ "index", StrCat(descriptor_->index()));
+ }
+
+ printer->Print(
+ "}\n"
+ "\n"
+ "private static final $classname$[] VALUES = ",
+ "classname", descriptor_->name());
+
+ if (CanUseEnumValues()) {
+ // If the constants we are going to output are exactly the ones we
+ // have declared in the Java enum in the same order, then we can use
+ // the values() method that the Java compiler automatically generates
+ // for every enum.
+ printer->Print("values();\n");
+ } else {
+ printer->Print("getStaticValuesArray();\n");
+ printer->Print("private static $classname$[] getStaticValuesArray() {\n",
+ "classname", descriptor_->name());
+ printer->Indent();
+ printer->Print(
+ "return new $classname$[] {\n"
+ " ",
+ "classname", descriptor_->name());
+ for (int i = 0; i < descriptor_->value_count(); i++) {
+ printer->Print("$name$, ", "name", descriptor_->value(i)->name());
+ }
+ printer->Print(
+ "\n"
+ "};\n");
+ printer->Outdent();
+ printer->Print("}");
+ }
+
+ printer->Print(
+ "\n"
+ "public static $classname$ valueOf(\n"
+ " com.google.protobuf.Descriptors.EnumValueDescriptor desc) {\n"
+ " if (desc.getType() != getDescriptor()) {\n"
+ " throw new java.lang.IllegalArgumentException(\n"
+ " \"EnumValueDescriptor is not for this type.\");\n"
+ " }\n",
+ "classname", descriptor_->name());
+ if (SupportUnknownEnumValue(descriptor_->file())) {
+ printer->Print(
+ " if (desc.getIndex() == -1) {\n"
+ " return UNRECOGNIZED;\n"
+ " }\n");
+ }
+ printer->Print(
+ " return VALUES[desc.getIndex()];\n"
+ "}\n"
+ "\n");
+
+ if (!ordinal_is_index) {
+ printer->Print("private final int index;\n");
+ }
+ }
+
+ // -----------------------------------------------------------------
+
+ printer->Print("private final int value;\n\n");
+
+ if (ordinal_is_index) {
+ printer->Print("private $classname$(int value) {\n", "classname",
+ descriptor_->name());
+ } else {
+ printer->Print("private $classname$(int index, int value) {\n", "classname",
+ descriptor_->name());
+ }
+ if (HasDescriptorMethods(descriptor_, context_->EnforceLite()) &&
+ !ordinal_is_index) {
+ printer->Print(" this.index = index;\n");
+ }
+ printer->Print(
+ " this.value = value;\n"
+ "}\n");
+
+ printer->Print(
+ "\n"
+ "// @@protoc_insertion_point(enum_scope:$full_name$)\n",
+ "full_name", descriptor_->full_name());
+
+ printer->Outdent();
+ printer->Print("}\n\n");
+}
+
+bool EnumGenerator::CanUseEnumValues() {
+ if (canonical_values_.size() != descriptor_->value_count()) {
+ return false;
+ }
+ for (int i = 0; i < descriptor_->value_count(); i++) {
+ if (descriptor_->value(i)->name() != canonical_values_[i]->name()) {
+ return false;
+ }
+ }
+ return true;
+}
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_enum.h b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_enum.h
new file mode 100644
index 00000000..cae2ffea
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_enum.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: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_ENUM_H__
+#define GOOGLE_PROTOBUF_COMPILER_JAVA_ENUM_H__
+
+#include <string>
+#include <vector>
+#include <descriptor.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+class Context; // context.h
+class ClassNameResolver; // name_resolver.h
+} // namespace java
+} // namespace compiler
+namespace io {
+class Printer; // printer.h
+}
+} // namespace protobuf
+} // namespace google
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+class EnumGenerator {
+ public:
+ EnumGenerator(const EnumDescriptor* descriptor, bool immutable_api,
+ Context* context);
+ ~EnumGenerator();
+
+ void Generate(io::Printer* printer);
+
+ private:
+ const EnumDescriptor* descriptor_;
+
+ // The proto language allows multiple enum constants to have the same
+ // numeric value. Java, however, does not allow multiple enum constants to
+ // be considered equivalent. We treat the first defined constant for any
+ // given numeric value as "canonical" and the rest as aliases of that
+ // canonical value.
+ std::vector<const EnumValueDescriptor*> canonical_values_;
+
+ struct Alias {
+ const EnumValueDescriptor* value;
+ const EnumValueDescriptor* canonical_value;
+ };
+ std::vector<Alias> aliases_;
+
+ bool immutable_api_;
+
+ Context* context_;
+ ClassNameResolver* name_resolver_;
+
+ bool CanUseEnumValues();
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumGenerator);
+};
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_ENUM_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_enum_field.cc b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_enum_field.cc
new file mode 100644
index 00000000..51e944df
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_enum_field.cc
@@ -0,0 +1,1176 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 <compiler/java/java_enum_field.h>
+
+#include <cstdint>
+#include <map>
+#include <string>
+
+#include <stubs/logging.h>
+#include <stubs/common.h>
+#include <compiler/java/java_context.h>
+#include <compiler/java/java_doc_comment.h>
+#include <compiler/java/java_helpers.h>
+#include <compiler/java/java_name_resolver.h>
+#include <io/printer.h>
+#include <wire_format.h>
+#include <stubs/strutil.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+namespace {
+
+void SetEnumVariables(const FieldDescriptor* descriptor, int messageBitIndex,
+ int builderBitIndex, const FieldGeneratorInfo* info,
+ ClassNameResolver* name_resolver,
+ std::map<std::string, std::string>* variables) {
+ SetCommonFieldVariables(descriptor, info, variables);
+
+ (*variables)["type"] =
+ name_resolver->GetImmutableClassName(descriptor->enum_type());
+ (*variables)["kt_type"] = (*variables)["type"];
+ (*variables)["mutable_type"] =
+ name_resolver->GetMutableClassName(descriptor->enum_type());
+ (*variables)["default"] = ImmutableDefaultValue(descriptor, name_resolver);
+ (*variables)["default_number"] =
+ StrCat(descriptor->default_value_enum()->number());
+ (*variables)["tag"] = StrCat(
+ static_cast<int32_t>(internal::WireFormat::MakeTag(descriptor)));
+ (*variables)["tag_size"] = StrCat(
+ internal::WireFormat::TagSize(descriptor->number(), GetType(descriptor)));
+ // TODO(birdo): Add @deprecated javadoc when generating javadoc is supported
+ // by the proto compiler
+ (*variables)["deprecation"] =
+ descriptor->options().deprecated() ? "@java.lang.Deprecated " : "";
+ (*variables)["kt_deprecation"] =
+ descriptor->options().deprecated()
+ ? "@kotlin.Deprecated(message = \"Field " + (*variables)["name"] +
+ " is deprecated\") "
+ : "";
+ (*variables)["on_changed"] = "onChanged();";
+ // Use deprecated valueOf() method to be compatible with old generated code
+ // for v2.5.0/v2.6.1.
+ // TODO(xiaofeng): Use "forNumber" when we no longer support compatibility
+ // with v2.5.0/v2.6.1, and remove the @SuppressWarnings annotations.
+ (*variables)["for_number"] = "valueOf";
+
+ if (HasHasbit(descriptor)) {
+ // For singular messages and builders, one bit is used for the hasField bit.
+ (*variables)["get_has_field_bit_message"] = GenerateGetBit(messageBitIndex);
+ (*variables)["get_has_field_bit_builder"] = GenerateGetBit(builderBitIndex);
+
+ // Note that these have a trailing ";".
+ (*variables)["set_has_field_bit_message"] =
+ GenerateSetBit(messageBitIndex) + ";";
+ (*variables)["set_has_field_bit_builder"] =
+ GenerateSetBit(builderBitIndex) + ";";
+ (*variables)["clear_has_field_bit_builder"] =
+ GenerateClearBit(builderBitIndex) + ";";
+
+ (*variables)["is_field_present_message"] = GenerateGetBit(messageBitIndex);
+ } else {
+ (*variables)["set_has_field_bit_message"] = "";
+ (*variables)["set_has_field_bit_builder"] = "";
+ (*variables)["clear_has_field_bit_builder"] = "";
+
+ (*variables)["is_field_present_message"] =
+ (*variables)["name"] + "_ != " + (*variables)["default"] +
+ ".getNumber()";
+ }
+
+ // For repeated builders, one bit is used for whether the array is immutable.
+ (*variables)["get_mutable_bit_builder"] = GenerateGetBit(builderBitIndex);
+ (*variables)["set_mutable_bit_builder"] = GenerateSetBit(builderBitIndex);
+ (*variables)["clear_mutable_bit_builder"] = GenerateClearBit(builderBitIndex);
+
+ // For repeated fields, one bit is used for whether the array is immutable
+ // in the parsing constructor.
+ (*variables)["get_mutable_bit_parser"] =
+ GenerateGetBitMutableLocal(builderBitIndex);
+ (*variables)["set_mutable_bit_parser"] =
+ GenerateSetBitMutableLocal(builderBitIndex);
+
+ (*variables)["get_has_field_bit_from_local"] =
+ GenerateGetBitFromLocal(builderBitIndex);
+ (*variables)["set_has_field_bit_to_local"] =
+ GenerateSetBitToLocal(messageBitIndex);
+
+ if (SupportUnknownEnumValue(descriptor->file())) {
+ (*variables)["unknown"] = (*variables)["type"] + ".UNRECOGNIZED";
+ } else {
+ (*variables)["unknown"] = (*variables)["default"];
+ }
+}
+
+} // namespace
+
+// ===================================================================
+
+ImmutableEnumFieldGenerator::ImmutableEnumFieldGenerator(
+ const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex,
+ Context* context)
+ : descriptor_(descriptor), name_resolver_(context->GetNameResolver()) {
+ SetEnumVariables(descriptor, messageBitIndex, builderBitIndex,
+ context->GetFieldGeneratorInfo(descriptor), name_resolver_,
+ &variables_);
+}
+
+ImmutableEnumFieldGenerator::~ImmutableEnumFieldGenerator() {}
+
+int ImmutableEnumFieldGenerator::GetNumBitsForMessage() const {
+ return HasHasbit(descriptor_) ? 1 : 0;
+}
+
+int ImmutableEnumFieldGenerator::GetNumBitsForBuilder() const {
+ return GetNumBitsForMessage();
+}
+
+void ImmutableEnumFieldGenerator::GenerateInterfaceMembers(
+ io::Printer* printer) const {
+ if (HasHazzer(descriptor_)) {
+ WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
+ printer->Print(variables_,
+ "$deprecation$boolean has$capitalized_name$();\n");
+ }
+ if (SupportUnknownEnumValue(descriptor_->file())) {
+ WriteFieldEnumValueAccessorDocComment(printer, descriptor_, GETTER);
+ printer->Print(variables_,
+ "$deprecation$int get$capitalized_name$Value();\n");
+ }
+ WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
+ printer->Print(variables_, "$deprecation$$type$ get$capitalized_name$();\n");
+}
+
+void ImmutableEnumFieldGenerator::GenerateMembers(io::Printer* printer) const {
+ printer->Print(variables_, "private int $name$_;\n");
+ PrintExtraFieldInfo(variables_, printer);
+ if (HasHazzer(descriptor_)) {
+ WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
+ printer->Print(variables_,
+ "@java.lang.Override $deprecation$public boolean "
+ "${$has$capitalized_name$$}$() {\n"
+ " return $get_has_field_bit_message$;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ }
+ if (SupportUnknownEnumValue(descriptor_->file())) {
+ WriteFieldEnumValueAccessorDocComment(printer, descriptor_, GETTER);
+ printer->Print(variables_,
+ "@java.lang.Override $deprecation$public int "
+ "${$get$capitalized_name$Value$}$() {\n"
+ " return $name$_;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ }
+ WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
+ printer->Print(variables_,
+ "@java.lang.Override $deprecation$public $type$ "
+ "${$get$capitalized_name$$}$() {\n"
+ " @SuppressWarnings(\"deprecation\")\n"
+ " $type$ result = $type$.$for_number$($name$_);\n"
+ " return result == null ? $unknown$ : result;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+}
+
+void ImmutableEnumFieldGenerator::GenerateBuilderMembers(
+ io::Printer* printer) const {
+ printer->Print(variables_, "private int $name$_ = $default_number$;\n");
+ if (HasHazzer(descriptor_)) {
+ WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
+ printer->Print(variables_,
+ "@java.lang.Override $deprecation$public boolean "
+ "${$has$capitalized_name$$}$() {\n"
+ " return $get_has_field_bit_builder$;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ }
+ if (SupportUnknownEnumValue(descriptor_->file())) {
+ WriteFieldEnumValueAccessorDocComment(printer, descriptor_, GETTER);
+ printer->Print(variables_,
+ "@java.lang.Override $deprecation$public int "
+ "${$get$capitalized_name$Value$}$() {\n"
+ " return $name$_;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldEnumValueAccessorDocComment(printer, descriptor_, SETTER,
+ /* builder */ true);
+ printer->Print(variables_,
+ "$deprecation$public Builder "
+ "${$set$capitalized_name$Value$}$(int value) {\n"
+ " $set_has_field_bit_builder$\n"
+ " $name$_ = value;\n"
+ " $on_changed$\n"
+ " return this;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ }
+ WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
+ printer->Print(variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
+ " @SuppressWarnings(\"deprecation\")\n"
+ " $type$ result = $type$.$for_number$($name$_);\n"
+ " return result == null ? $unknown$ : result;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldAccessorDocComment(printer, descriptor_, SETTER,
+ /* builder */ true);
+ printer->Print(variables_,
+ "$deprecation$public Builder "
+ "${$set$capitalized_name$$}$($type$ value) {\n"
+ " if (value == null) {\n"
+ " throw new NullPointerException();\n"
+ " }\n"
+ " $set_has_field_bit_builder$\n"
+ " $name$_ = value.getNumber();\n"
+ " $on_changed$\n"
+ " return this;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldAccessorDocComment(printer, descriptor_, CLEARER,
+ /* builder */ true);
+ printer->Print(
+ variables_,
+ "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n"
+ " $clear_has_field_bit_builder$\n"
+ " $name$_ = $default_number$;\n"
+ " $on_changed$\n"
+ " return this;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+}
+
+void ImmutableEnumFieldGenerator::GenerateKotlinDslMembers(
+ io::Printer* printer) const {
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$kt_deprecation$public var $kt_name$: $kt_type$\n"
+ " @JvmName(\"${$get$kt_capitalized_name$$}$\")\n"
+ " get() = $kt_dsl_builder$.${$get$capitalized_name$$}$()\n"
+ " @JvmName(\"${$set$kt_capitalized_name$$}$\")\n"
+ " set(value) {\n"
+ " $kt_dsl_builder$.${$set$capitalized_name$$}$(value)\n"
+ " }\n");
+
+ WriteFieldAccessorDocComment(printer, descriptor_, CLEARER,
+ /* builder */ false);
+ printer->Print(variables_,
+ "public fun ${$clear$kt_capitalized_name$$}$() {\n"
+ " $kt_dsl_builder$.${$clear$capitalized_name$$}$()\n"
+ "}\n");
+
+ if (HasHazzer(descriptor_)) {
+ WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
+ printer->Print(
+ variables_,
+ "public fun ${$has$kt_capitalized_name$$}$(): kotlin.Boolean {\n"
+ " return $kt_dsl_builder$.${$has$capitalized_name$$}$()\n"
+ "}\n");
+ }
+}
+
+void ImmutableEnumFieldGenerator::GenerateFieldBuilderInitializationCode(
+ io::Printer* printer) const {
+ // noop for enums
+}
+
+void ImmutableEnumFieldGenerator::GenerateInitializationCode(
+ io::Printer* printer) const {
+ printer->Print(variables_, "$name$_ = $default_number$;\n");
+}
+
+void ImmutableEnumFieldGenerator::GenerateBuilderClearCode(
+ io::Printer* printer) const {
+ printer->Print(variables_,
+ "$name$_ = $default_number$;\n"
+ "$clear_has_field_bit_builder$\n");
+}
+
+void ImmutableEnumFieldGenerator::GenerateMergingCode(
+ io::Printer* printer) const {
+ if (HasHazzer(descriptor_)) {
+ printer->Print(variables_,
+ "if (other.has$capitalized_name$()) {\n"
+ " set$capitalized_name$(other.get$capitalized_name$());\n"
+ "}\n");
+ } else if (SupportUnknownEnumValue(descriptor_->file())) {
+ printer->Print(
+ variables_,
+ "if (other.$name$_ != $default_number$) {\n"
+ " set$capitalized_name$Value(other.get$capitalized_name$Value());\n"
+ "}\n");
+ } else {
+ GOOGLE_LOG(FATAL) << "Can't reach here.";
+ }
+}
+
+void ImmutableEnumFieldGenerator::GenerateBuildingCode(
+ io::Printer* printer) const {
+ if (HasHazzer(descriptor_)) {
+ printer->Print(variables_,
+ "if ($get_has_field_bit_from_local$) {\n"
+ " $set_has_field_bit_to_local$;\n"
+ "}\n");
+ }
+ printer->Print(variables_, "result.$name$_ = $name$_;\n");
+}
+
+void ImmutableEnumFieldGenerator::GenerateParsingCode(
+ io::Printer* printer) const {
+ if (SupportUnknownEnumValue(descriptor_->file())) {
+ printer->Print(variables_,
+ "int rawValue = input.readEnum();\n"
+ "$set_has_field_bit_message$\n"
+ "$name$_ = rawValue;\n");
+ } else {
+ printer->Print(variables_,
+ "int rawValue = input.readEnum();\n"
+ " @SuppressWarnings(\"deprecation\")\n"
+ "$type$ value = $type$.$for_number$(rawValue);\n"
+ "if (value == null) {\n"
+ " unknownFields.mergeVarintField($number$, rawValue);\n"
+ "} else {\n"
+ " $set_has_field_bit_message$\n"
+ " $name$_ = rawValue;\n"
+ "}\n");
+ }
+}
+
+void ImmutableEnumFieldGenerator::GenerateParsingDoneCode(
+ io::Printer* printer) const {
+ // noop for enums
+}
+
+void ImmutableEnumFieldGenerator::GenerateSerializationCode(
+ io::Printer* printer) const {
+ printer->Print(variables_,
+ "if ($is_field_present_message$) {\n"
+ " output.writeEnum($number$, $name$_);\n"
+ "}\n");
+}
+
+void ImmutableEnumFieldGenerator::GenerateSerializedSizeCode(
+ io::Printer* printer) const {
+ printer->Print(variables_,
+ "if ($is_field_present_message$) {\n"
+ " size += com.google.protobuf.CodedOutputStream\n"
+ " .computeEnumSize($number$, $name$_);\n"
+ "}\n");
+}
+
+void ImmutableEnumFieldGenerator::GenerateEqualsCode(
+ io::Printer* printer) const {
+ printer->Print(variables_, "if ($name$_ != other.$name$_) return false;\n");
+}
+
+void ImmutableEnumFieldGenerator::GenerateHashCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "hash = (37 * hash) + $constant_name$;\n"
+ "hash = (53 * hash) + $name$_;\n");
+}
+
+std::string ImmutableEnumFieldGenerator::GetBoxedType() const {
+ return name_resolver_->GetImmutableClassName(descriptor_->enum_type());
+}
+
+// ===================================================================
+
+ImmutableEnumOneofFieldGenerator::ImmutableEnumOneofFieldGenerator(
+ const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex,
+ Context* context)
+ : ImmutableEnumFieldGenerator(descriptor, messageBitIndex, builderBitIndex,
+ context) {
+ const OneofGeneratorInfo* info =
+ context->GetOneofGeneratorInfo(descriptor->containing_oneof());
+ SetCommonOneofVariables(descriptor, info, &variables_);
+}
+
+ImmutableEnumOneofFieldGenerator::~ImmutableEnumOneofFieldGenerator() {}
+
+void ImmutableEnumOneofFieldGenerator::GenerateMembers(
+ io::Printer* printer) const {
+ PrintExtraFieldInfo(variables_, printer);
+ GOOGLE_DCHECK(HasHazzer(descriptor_));
+ WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
+ printer->Print(variables_,
+ "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
+ " return $has_oneof_case_message$;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+
+ if (SupportUnknownEnumValue(descriptor_->file())) {
+ WriteFieldEnumValueAccessorDocComment(printer, descriptor_, GETTER);
+ printer->Print(
+ variables_,
+ "$deprecation$public int ${$get$capitalized_name$Value$}$() {\n"
+ " if ($has_oneof_case_message$) {\n"
+ " return (java.lang.Integer) $oneof_name$_;\n"
+ " }\n"
+ " return $default_number$;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ }
+ WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
+ printer->Print(variables_,
+ "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
+ " if ($has_oneof_case_message$) {\n"
+ " @SuppressWarnings(\"deprecation\")\n"
+ " $type$ result = $type$.$for_number$(\n"
+ " (java.lang.Integer) $oneof_name$_);\n"
+ " return result == null ? $unknown$ : result;\n"
+ " }\n"
+ " return $default$;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+}
+
+void ImmutableEnumOneofFieldGenerator::GenerateBuilderMembers(
+ io::Printer* printer) const {
+ GOOGLE_DCHECK(HasHazzer(descriptor_));
+ WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
+ printer->Print(variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
+ " return $has_oneof_case_message$;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+
+ if (SupportUnknownEnumValue(descriptor_->file())) {
+ WriteFieldEnumValueAccessorDocComment(printer, descriptor_, GETTER);
+ printer->Print(
+ variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public int ${$get$capitalized_name$Value$}$() {\n"
+ " if ($has_oneof_case_message$) {\n"
+ " return ((java.lang.Integer) $oneof_name$_).intValue();\n"
+ " }\n"
+ " return $default_number$;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldEnumValueAccessorDocComment(printer, descriptor_, SETTER,
+ /* builder */ true);
+ printer->Print(variables_,
+ "$deprecation$public Builder "
+ "${$set$capitalized_name$Value$}$(int value) {\n"
+ " $set_oneof_case_message$;\n"
+ " $oneof_name$_ = value;\n"
+ " $on_changed$\n"
+ " return this;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ }
+ WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
+ printer->Print(variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
+ " if ($has_oneof_case_message$) {\n"
+ " @SuppressWarnings(\"deprecation\")\n"
+ " $type$ result = $type$.$for_number$(\n"
+ " (java.lang.Integer) $oneof_name$_);\n"
+ " return result == null ? $unknown$ : result;\n"
+ " }\n"
+ " return $default$;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldAccessorDocComment(printer, descriptor_, SETTER,
+ /* builder */ true);
+ printer->Print(variables_,
+ "$deprecation$public Builder "
+ "${$set$capitalized_name$$}$($type$ value) {\n"
+ " if (value == null) {\n"
+ " throw new NullPointerException();\n"
+ " }\n"
+ " $set_oneof_case_message$;\n"
+ " $oneof_name$_ = value.getNumber();\n"
+ " $on_changed$\n"
+ " return this;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldAccessorDocComment(printer, descriptor_, CLEARER,
+ /* builder */ true);
+ printer->Print(
+ variables_,
+ "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n"
+ " if ($has_oneof_case_message$) {\n"
+ " $clear_oneof_case_message$;\n"
+ " $oneof_name$_ = null;\n"
+ " $on_changed$\n"
+ " }\n"
+ " return this;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+}
+
+void ImmutableEnumOneofFieldGenerator::GenerateBuildingCode(
+ io::Printer* printer) const {
+ printer->Print(variables_,
+ "if ($has_oneof_case_message$) {\n"
+ " result.$oneof_name$_ = $oneof_name$_;\n"
+ "}\n");
+}
+
+void ImmutableEnumOneofFieldGenerator::GenerateMergingCode(
+ io::Printer* printer) const {
+ if (SupportUnknownEnumValue(descriptor_->file())) {
+ printer->Print(
+ variables_,
+ "set$capitalized_name$Value(other.get$capitalized_name$Value());\n");
+ } else {
+ printer->Print(variables_,
+ "set$capitalized_name$(other.get$capitalized_name$());\n");
+ }
+}
+
+void ImmutableEnumOneofFieldGenerator::GenerateParsingCode(
+ io::Printer* printer) const {
+ if (SupportUnknownEnumValue(descriptor_->file())) {
+ printer->Print(variables_,
+ "int rawValue = input.readEnum();\n"
+ "$set_oneof_case_message$;\n"
+ "$oneof_name$_ = rawValue;\n");
+ } else {
+ printer->Print(variables_,
+ "int rawValue = input.readEnum();\n"
+ "@SuppressWarnings(\"deprecation\")\n"
+ "$type$ value = $type$.$for_number$(rawValue);\n"
+ "if (value == null) {\n"
+ " unknownFields.mergeVarintField($number$, rawValue);\n"
+ "} else {\n"
+ " $set_oneof_case_message$;\n"
+ " $oneof_name$_ = rawValue;\n"
+ "}\n");
+ }
+}
+
+void ImmutableEnumOneofFieldGenerator::GenerateSerializationCode(
+ io::Printer* printer) const {
+ printer->Print(
+ variables_,
+ "if ($has_oneof_case_message$) {\n"
+ " output.writeEnum($number$, ((java.lang.Integer) $oneof_name$_));\n"
+ "}\n");
+}
+
+void ImmutableEnumOneofFieldGenerator::GenerateSerializedSizeCode(
+ io::Printer* printer) const {
+ printer->Print(
+ variables_,
+ "if ($has_oneof_case_message$) {\n"
+ " size += com.google.protobuf.CodedOutputStream\n"
+ " .computeEnumSize($number$, ((java.lang.Integer) $oneof_name$_));\n"
+ "}\n");
+}
+
+void ImmutableEnumOneofFieldGenerator::GenerateEqualsCode(
+ io::Printer* printer) const {
+ if (SupportUnknownEnumValue(descriptor_->file())) {
+ printer->Print(
+ variables_,
+ "if (get$capitalized_name$Value()\n"
+ " != other.get$capitalized_name$Value()) return false;\n");
+ } else {
+ printer->Print(
+ variables_,
+ "if (!get$capitalized_name$()\n"
+ " .equals(other.get$capitalized_name$())) return false;\n");
+ }
+}
+
+void ImmutableEnumOneofFieldGenerator::GenerateHashCode(
+ io::Printer* printer) const {
+ if (SupportUnknownEnumValue(descriptor_->file())) {
+ printer->Print(variables_,
+ "hash = (37 * hash) + $constant_name$;\n"
+ "hash = (53 * hash) + get$capitalized_name$Value();\n");
+ } else {
+ printer->Print(
+ variables_,
+ "hash = (37 * hash) + $constant_name$;\n"
+ "hash = (53 * hash) + get$capitalized_name$().getNumber();\n");
+ }
+}
+
+// ===================================================================
+
+RepeatedImmutableEnumFieldGenerator::RepeatedImmutableEnumFieldGenerator(
+ const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex,
+ Context* context)
+ : descriptor_(descriptor), name_resolver_(context->GetNameResolver()) {
+ SetEnumVariables(descriptor, messageBitIndex, builderBitIndex,
+ context->GetFieldGeneratorInfo(descriptor), name_resolver_,
+ &variables_);
+}
+
+RepeatedImmutableEnumFieldGenerator::~RepeatedImmutableEnumFieldGenerator() {}
+
+int RepeatedImmutableEnumFieldGenerator::GetNumBitsForMessage() const {
+ return 0;
+}
+
+int RepeatedImmutableEnumFieldGenerator::GetNumBitsForBuilder() const {
+ return 1;
+}
+
+void RepeatedImmutableEnumFieldGenerator::GenerateInterfaceMembers(
+ io::Printer* printer) const {
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_GETTER);
+ printer->Print(
+ variables_,
+ "$deprecation$java.util.List<$type$> get$capitalized_name$List();\n");
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_COUNT);
+ printer->Print(variables_,
+ "$deprecation$int get$capitalized_name$Count();\n");
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_GETTER);
+ printer->Print(variables_,
+ "$deprecation$$type$ get$capitalized_name$(int index);\n");
+ if (SupportUnknownEnumValue(descriptor_->file())) {
+ WriteFieldEnumValueAccessorDocComment(printer, descriptor_, LIST_GETTER);
+ printer->Print(variables_,
+ "$deprecation$java.util.List<java.lang.Integer>\n"
+ "get$capitalized_name$ValueList();\n");
+ WriteFieldEnumValueAccessorDocComment(printer, descriptor_,
+ LIST_INDEXED_GETTER);
+ printer->Print(variables_,
+ "$deprecation$int get$capitalized_name$Value(int index);\n");
+ }
+}
+
+void RepeatedImmutableEnumFieldGenerator::GenerateMembers(
+ io::Printer* printer) const {
+ printer->Print(
+ variables_,
+ "private java.util.List<java.lang.Integer> $name$_;\n"
+ "private static final "
+ "com.google.protobuf.Internal.ListAdapter.Converter<\n"
+ " java.lang.Integer, $type$> $name$_converter_ =\n"
+ " new com.google.protobuf.Internal.ListAdapter.Converter<\n"
+ " java.lang.Integer, $type$>() {\n"
+ " public $type$ convert(java.lang.Integer from) {\n"
+ " @SuppressWarnings(\"deprecation\")\n"
+ " $type$ result = $type$.$for_number$(from);\n"
+ " return result == null ? $unknown$ : result;\n"
+ " }\n"
+ " };\n");
+ PrintExtraFieldInfo(variables_, printer);
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_GETTER);
+ printer->Print(
+ variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public java.util.List<$type$> "
+ "${$get$capitalized_name$List$}$() {\n"
+ " return new com.google.protobuf.Internal.ListAdapter<\n"
+ " java.lang.Integer, $type$>($name$_, $name$_converter_);\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_COUNT);
+ printer->Print(
+ variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n"
+ " return $name$_.size();\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_GETTER);
+ printer->Print(
+ variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n"
+ " return $name$_converter_.convert($name$_.get(index));\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ if (SupportUnknownEnumValue(descriptor_->file())) {
+ WriteFieldEnumValueAccessorDocComment(printer, descriptor_, LIST_GETTER);
+ printer->Print(variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public java.util.List<java.lang.Integer>\n"
+ "${$get$capitalized_name$ValueList$}$() {\n"
+ " return $name$_;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldEnumValueAccessorDocComment(printer, descriptor_,
+ LIST_INDEXED_GETTER);
+ printer->Print(variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public int "
+ "${$get$capitalized_name$Value$}$(int index) {\n"
+ " return $name$_.get(index);\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ }
+
+ if (descriptor_->is_packed()) {
+ printer->Print(variables_, "private int $name$MemoizedSerializedSize;\n");
+ }
+}
+
+void RepeatedImmutableEnumFieldGenerator::GenerateBuilderMembers(
+ io::Printer* printer) const {
+ printer->Print(
+ variables_,
+ // One field is the list and the other field keeps track of whether the
+ // list is immutable. If it's immutable, the invariant is that it must
+ // either an instance of Collections.emptyList() or it's an ArrayList
+ // wrapped in a Collections.unmodifiableList() wrapper and nobody else has
+ // a reference to the underlying ArrayList. This invariant allows us to
+ // share instances of lists between protocol buffers avoiding expensive
+ // memory allocations. Note, immutable is a strong guarantee here -- not
+ // just that the list cannot be modified via the reference but that the
+ // list can never be modified.
+ "private java.util.List<java.lang.Integer> $name$_ =\n"
+ " java.util.Collections.emptyList();\n"
+
+ "private void ensure$capitalized_name$IsMutable() {\n"
+ " if (!$get_mutable_bit_builder$) {\n"
+ " $name$_ = new java.util.ArrayList<java.lang.Integer>($name$_);\n"
+ " $set_mutable_bit_builder$;\n"
+ " }\n"
+ "}\n");
+
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_GETTER);
+ printer->Print(
+ variables_,
+ // Note: We return an unmodifiable list because otherwise the caller
+ // could hold on to the returned list and modify it after the message
+ // has been built, thus mutating the message which is supposed to be
+ // immutable.
+ "$deprecation$public java.util.List<$type$> "
+ "${$get$capitalized_name$List$}$() {\n"
+ " return new com.google.protobuf.Internal.ListAdapter<\n"
+ " java.lang.Integer, $type$>($name$_, $name$_converter_);\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_COUNT);
+ printer->Print(
+ variables_,
+ "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n"
+ " return $name$_.size();\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_GETTER);
+ printer->Print(
+ variables_,
+ "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n"
+ " return $name$_converter_.convert($name$_.get(index));\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_SETTER,
+ /* builder */ true);
+ printer->Print(variables_,
+ "$deprecation$public Builder ${$set$capitalized_name$$}$(\n"
+ " int index, $type$ value) {\n"
+ " if (value == null) {\n"
+ " throw new NullPointerException();\n"
+ " }\n"
+ " ensure$capitalized_name$IsMutable();\n"
+ " $name$_.set(index, value.getNumber());\n"
+ " $on_changed$\n"
+ " return this;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_ADDER,
+ /* builder */ true);
+ printer->Print(variables_,
+ "$deprecation$public Builder "
+ "${$add$capitalized_name$$}$($type$ value) {\n"
+ " if (value == null) {\n"
+ " throw new NullPointerException();\n"
+ " }\n"
+ " ensure$capitalized_name$IsMutable();\n"
+ " $name$_.add(value.getNumber());\n"
+ " $on_changed$\n"
+ " return this;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_MULTI_ADDER,
+ /* builder */ true);
+ printer->Print(variables_,
+ "$deprecation$public Builder ${$addAll$capitalized_name$$}$(\n"
+ " java.lang.Iterable<? extends $type$> values) {\n"
+ " ensure$capitalized_name$IsMutable();\n"
+ " for ($type$ value : values) {\n"
+ " $name$_.add(value.getNumber());\n"
+ " }\n"
+ " $on_changed$\n"
+ " return this;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldAccessorDocComment(printer, descriptor_, CLEARER,
+ /* builder */ true);
+ printer->Print(
+ variables_,
+ "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n"
+ " $name$_ = java.util.Collections.emptyList();\n"
+ " $clear_mutable_bit_builder$;\n"
+ " $on_changed$\n"
+ " return this;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+
+ if (SupportUnknownEnumValue(descriptor_->file())) {
+ WriteFieldEnumValueAccessorDocComment(printer, descriptor_, LIST_GETTER);
+ printer->Print(variables_,
+ "$deprecation$public java.util.List<java.lang.Integer>\n"
+ "${$get$capitalized_name$ValueList$}$() {\n"
+ " return java.util.Collections.unmodifiableList($name$_);\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldEnumValueAccessorDocComment(printer, descriptor_,
+ LIST_INDEXED_GETTER);
+ printer->Print(variables_,
+ "$deprecation$public int "
+ "${$get$capitalized_name$Value$}$(int index) {\n"
+ " return $name$_.get(index);\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldEnumValueAccessorDocComment(printer, descriptor_,
+ LIST_INDEXED_GETTER,
+ /* builder */ true);
+ printer->Print(
+ variables_,
+ "$deprecation$public Builder ${$set$capitalized_name$Value$}$(\n"
+ " int index, int value) {\n"
+ " ensure$capitalized_name$IsMutable();\n"
+ " $name$_.set(index, value);\n"
+ " $on_changed$\n"
+ " return this;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldEnumValueAccessorDocComment(printer, descriptor_, LIST_ADDER,
+ /* builder */ true);
+ printer->Print(variables_,
+ "$deprecation$public Builder "
+ "${$add$capitalized_name$Value$}$(int value) {\n"
+ " ensure$capitalized_name$IsMutable();\n"
+ " $name$_.add(value);\n"
+ " $on_changed$\n"
+ " return this;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldEnumValueAccessorDocComment(printer, descriptor_,
+ LIST_MULTI_ADDER, /* builder */ true);
+ printer->Print(
+ variables_,
+ "$deprecation$public Builder ${$addAll$capitalized_name$Value$}$(\n"
+ " java.lang.Iterable<java.lang.Integer> values) {\n"
+ " ensure$capitalized_name$IsMutable();\n"
+ " for (int value : values) {\n"
+ " $name$_.add(value);\n"
+ " }\n"
+ " $on_changed$\n"
+ " return this;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ }
+}
+
+void RepeatedImmutableEnumFieldGenerator::
+ GenerateFieldBuilderInitializationCode(io::Printer* printer) const {
+ // noop for enums
+}
+
+void RepeatedImmutableEnumFieldGenerator::GenerateInitializationCode(
+ io::Printer* printer) const {
+ printer->Print(variables_, "$name$_ = java.util.Collections.emptyList();\n");
+}
+
+void RepeatedImmutableEnumFieldGenerator::GenerateBuilderClearCode(
+ io::Printer* printer) const {
+ printer->Print(variables_,
+ "$name$_ = java.util.Collections.emptyList();\n"
+ "$clear_mutable_bit_builder$;\n");
+}
+
+void RepeatedImmutableEnumFieldGenerator::GenerateMergingCode(
+ io::Printer* printer) const {
+ // The code below does two optimizations:
+ // 1. If the other list is empty, there's nothing to do. This ensures we
+ // don't allocate a new array if we already have an immutable one.
+ // 2. If the other list is non-empty and our current list is empty, we can
+ // reuse the other list which is guaranteed to be immutable.
+ printer->Print(variables_,
+ "if (!other.$name$_.isEmpty()) {\n"
+ " if ($name$_.isEmpty()) {\n"
+ " $name$_ = other.$name$_;\n"
+ " $clear_mutable_bit_builder$;\n"
+ " } else {\n"
+ " ensure$capitalized_name$IsMutable();\n"
+ " $name$_.addAll(other.$name$_);\n"
+ " }\n"
+ " $on_changed$\n"
+ "}\n");
+}
+
+void RepeatedImmutableEnumFieldGenerator::GenerateBuildingCode(
+ io::Printer* printer) const {
+ // The code below ensures that the result has an immutable list. If our
+ // list is immutable, we can just reuse it. If not, we make it immutable.
+ printer->Print(
+ variables_,
+ "if ($get_mutable_bit_builder$) {\n"
+ " $name$_ = java.util.Collections.unmodifiableList($name$_);\n"
+ " $clear_mutable_bit_builder$;\n"
+ "}\n"
+ "result.$name$_ = $name$_;\n");
+}
+
+void RepeatedImmutableEnumFieldGenerator::GenerateParsingCode(
+ io::Printer* printer) const {
+ // Read and store the enum
+ if (SupportUnknownEnumValue(descriptor_->file())) {
+ printer->Print(variables_,
+ "int rawValue = input.readEnum();\n"
+ "if (!$get_mutable_bit_parser$) {\n"
+ " $name$_ = new java.util.ArrayList<java.lang.Integer>();\n"
+ " $set_mutable_bit_parser$;\n"
+ "}\n"
+ "$name$_.add(rawValue);\n");
+ } else {
+ printer->Print(
+ variables_,
+ "int rawValue = input.readEnum();\n"
+ "@SuppressWarnings(\"deprecation\")\n"
+ "$type$ value = $type$.$for_number$(rawValue);\n"
+ "if (value == null) {\n"
+ " unknownFields.mergeVarintField($number$, rawValue);\n"
+ "} else {\n"
+ " if (!$get_mutable_bit_parser$) {\n"
+ " $name$_ = new java.util.ArrayList<java.lang.Integer>();\n"
+ " $set_mutable_bit_parser$;\n"
+ " }\n"
+ " $name$_.add(rawValue);\n"
+ "}\n");
+ }
+}
+
+void RepeatedImmutableEnumFieldGenerator::GenerateParsingCodeFromPacked(
+ io::Printer* printer) const {
+ // Wrap GenerateParsingCode's contents with a while loop.
+
+ printer->Print(variables_,
+ "int length = input.readRawVarint32();\n"
+ "int oldLimit = input.pushLimit(length);\n"
+ "while(input.getBytesUntilLimit() > 0) {\n");
+ printer->Indent();
+
+ GenerateParsingCode(printer);
+
+ printer->Outdent();
+ printer->Print(variables_,
+ "}\n"
+ "input.popLimit(oldLimit);\n");
+}
+
+void RepeatedImmutableEnumFieldGenerator::GenerateParsingDoneCode(
+ io::Printer* printer) const {
+ printer->Print(
+ variables_,
+ "if ($get_mutable_bit_parser$) {\n"
+ " $name$_ = java.util.Collections.unmodifiableList($name$_);\n"
+ "}\n");
+}
+
+void RepeatedImmutableEnumFieldGenerator::GenerateSerializationCode(
+ io::Printer* printer) const {
+ if (descriptor_->is_packed()) {
+ printer->Print(variables_,
+ "if (get$capitalized_name$List().size() > 0) {\n"
+ " output.writeUInt32NoTag($tag$);\n"
+ " output.writeUInt32NoTag($name$MemoizedSerializedSize);\n"
+ "}\n"
+ "for (int i = 0; i < $name$_.size(); i++) {\n"
+ " output.writeEnumNoTag($name$_.get(i));\n"
+ "}\n");
+ } else {
+ printer->Print(variables_,
+ "for (int i = 0; i < $name$_.size(); i++) {\n"
+ " output.writeEnum($number$, $name$_.get(i));\n"
+ "}\n");
+ }
+}
+
+void RepeatedImmutableEnumFieldGenerator::GenerateSerializedSizeCode(
+ io::Printer* printer) const {
+ printer->Print(variables_,
+ "{\n"
+ " int dataSize = 0;\n");
+ printer->Indent();
+
+ printer->Print(variables_,
+ "for (int i = 0; i < $name$_.size(); i++) {\n"
+ " dataSize += com.google.protobuf.CodedOutputStream\n"
+ " .computeEnumSizeNoTag($name$_.get(i));\n"
+ "}\n");
+ printer->Print("size += dataSize;\n");
+ if (descriptor_->is_packed()) {
+ printer->Print(variables_,
+ "if (!get$capitalized_name$List().isEmpty()) {"
+ " size += $tag_size$;\n"
+ " size += com.google.protobuf.CodedOutputStream\n"
+ " .computeUInt32SizeNoTag(dataSize);\n"
+ "}");
+ } else {
+ printer->Print(variables_, "size += $tag_size$ * $name$_.size();\n");
+ }
+
+ // cache the data size for packed fields.
+ if (descriptor_->is_packed()) {
+ printer->Print(variables_, "$name$MemoizedSerializedSize = dataSize;\n");
+ }
+
+ printer->Outdent();
+ printer->Print("}\n");
+}
+
+void RepeatedImmutableEnumFieldGenerator::GenerateEqualsCode(
+ io::Printer* printer) const {
+ printer->Print(variables_,
+ "if (!$name$_.equals(other.$name$_)) return false;\n");
+}
+
+void RepeatedImmutableEnumFieldGenerator::GenerateHashCode(
+ io::Printer* printer) const {
+ printer->Print(variables_,
+ "if (get$capitalized_name$Count() > 0) {\n"
+ " hash = (37 * hash) + $constant_name$;\n"
+ " hash = (53 * hash) + $name$_.hashCode();\n"
+ "}\n");
+}
+
+void RepeatedImmutableEnumFieldGenerator::GenerateKotlinDslMembers(
+ io::Printer* printer) const {
+ printer->Print(
+ variables_,
+ "/**\n"
+ " * An uninstantiable, behaviorless type to represent the field in\n"
+ " * generics.\n"
+ " */\n"
+ "@kotlin.OptIn"
+ "(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)\n"
+ "public class ${$$kt_capitalized_name$Proxy$}$ private constructor()"
+ " : com.google.protobuf.kotlin.DslProxy()\n");
+
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$kt_deprecation$ public val $kt_name$: "
+ "com.google.protobuf.kotlin.DslList"
+ "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>\n"
+ " @kotlin.jvm.JvmSynthetic\n"
+ " get() = com.google.protobuf.kotlin.DslList(\n"
+ " $kt_dsl_builder$.${$get$capitalized_name$List$}$()\n"
+ " )\n");
+
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_ADDER,
+ /* builder */ false);
+ printer->Print(variables_,
+ "@kotlin.jvm.JvmSynthetic\n"
+ "@kotlin.jvm.JvmName(\"add$kt_capitalized_name$\")\n"
+ "public fun com.google.protobuf.kotlin.DslList"
+ "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>."
+ "add(value: $kt_type$) {\n"
+ " $kt_dsl_builder$.${$add$capitalized_name$$}$(value)\n"
+ "}");
+
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_ADDER,
+ /* builder */ false);
+ printer->Print(variables_,
+ "@kotlin.jvm.JvmSynthetic\n"
+ "@kotlin.jvm.JvmName(\"plusAssign$kt_capitalized_name$\")\n"
+ "@Suppress(\"NOTHING_TO_INLINE\")\n"
+ "public inline operator fun com.google.protobuf.kotlin.DslList"
+ "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>."
+ "plusAssign(value: $kt_type$) {\n"
+ " add(value)\n"
+ "}");
+
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_MULTI_ADDER,
+ /* builder */ false);
+ printer->Print(variables_,
+ "@kotlin.jvm.JvmSynthetic\n"
+ "@kotlin.jvm.JvmName(\"addAll$kt_capitalized_name$\")\n"
+ "public fun com.google.protobuf.kotlin.DslList"
+ "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>."
+ "addAll(values: kotlin.collections.Iterable<$kt_type$>) {\n"
+ " $kt_dsl_builder$.${$addAll$capitalized_name$$}$(values)\n"
+ "}");
+
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_MULTI_ADDER,
+ /* builder */ false);
+ printer->Print(
+ variables_,
+ "@kotlin.jvm.JvmSynthetic\n"
+ "@kotlin.jvm.JvmName(\"plusAssignAll$kt_capitalized_name$\")\n"
+ "@Suppress(\"NOTHING_TO_INLINE\")\n"
+ "public inline operator fun com.google.protobuf.kotlin.DslList"
+ "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>."
+ "plusAssign(values: kotlin.collections.Iterable<$kt_type$>) {\n"
+ " addAll(values)\n"
+ "}");
+
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_SETTER,
+ /* builder */ false);
+ printer->Print(
+ variables_,
+ "@kotlin.jvm.JvmSynthetic\n"
+ "@kotlin.jvm.JvmName(\"set$kt_capitalized_name$\")\n"
+ "public operator fun com.google.protobuf.kotlin.DslList"
+ "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>."
+ "set(index: kotlin.Int, value: $kt_type$) {\n"
+ " $kt_dsl_builder$.${$set$capitalized_name$$}$(index, value)\n"
+ "}");
+
+ WriteFieldAccessorDocComment(printer, descriptor_, CLEARER,
+ /* builder */ false);
+ printer->Print(variables_,
+ "@kotlin.jvm.JvmSynthetic\n"
+ "@kotlin.jvm.JvmName(\"clear$kt_capitalized_name$\")\n"
+ "public fun com.google.protobuf.kotlin.DslList"
+ "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>."
+ "clear() {\n"
+ " $kt_dsl_builder$.${$clear$capitalized_name$$}$()\n"
+ "}");
+}
+
+std::string RepeatedImmutableEnumFieldGenerator::GetBoxedType() const {
+ return name_resolver_->GetImmutableClassName(descriptor_->enum_type());
+}
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_enum_field.h b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_enum_field.h
new file mode 100644
index 00000000..1e88bbf3
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_enum_field.h
@@ -0,0 +1,161 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 GOOGLE_PROTOBUF_COMPILER_JAVA_ENUM_FIELD_H__
+#define GOOGLE_PROTOBUF_COMPILER_JAVA_ENUM_FIELD_H__
+
+#include <map>
+#include <string>
+#include <compiler/java/java_field.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+class Context; // context.h
+class ClassNameResolver; // name_resolver.h
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+class ImmutableEnumFieldGenerator : public ImmutableFieldGenerator {
+ public:
+ explicit ImmutableEnumFieldGenerator(const FieldDescriptor* descriptor,
+ int messageBitIndex, int builderBitIndex,
+ Context* context);
+ ~ImmutableEnumFieldGenerator() override;
+
+ // implements ImmutableFieldGenerator
+ // ---------------------------------------
+ int GetNumBitsForMessage() const override;
+ int GetNumBitsForBuilder() const override;
+ void GenerateInterfaceMembers(io::Printer* printer) const override;
+ void GenerateMembers(io::Printer* printer) const override;
+ void GenerateBuilderMembers(io::Printer* printer) const override;
+ void GenerateInitializationCode(io::Printer* printer) const override;
+ void GenerateBuilderClearCode(io::Printer* printer) const override;
+ void GenerateMergingCode(io::Printer* printer) const override;
+ void GenerateBuildingCode(io::Printer* printer) const override;
+ void GenerateParsingCode(io::Printer* printer) const override;
+ void GenerateParsingDoneCode(io::Printer* printer) const override;
+ void GenerateSerializationCode(io::Printer* printer) const override;
+ void GenerateSerializedSizeCode(io::Printer* printer) const override;
+ void GenerateFieldBuilderInitializationCode(
+ io::Printer* printer) const override;
+ void GenerateEqualsCode(io::Printer* printer) const override;
+ void GenerateHashCode(io::Printer* printer) const override;
+ void GenerateKotlinDslMembers(io::Printer* printer) const override;
+
+ std::string GetBoxedType() const override;
+
+ protected:
+ const FieldDescriptor* descriptor_;
+ std::map<std::string, std::string> variables_;
+ ClassNameResolver* name_resolver_;
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableEnumFieldGenerator);
+};
+
+class ImmutableEnumOneofFieldGenerator : public ImmutableEnumFieldGenerator {
+ public:
+ ImmutableEnumOneofFieldGenerator(const FieldDescriptor* descriptor,
+ int messageBitIndex, int builderBitIndex,
+ Context* context);
+ ~ImmutableEnumOneofFieldGenerator();
+
+ void GenerateMembers(io::Printer* printer) const override;
+ void GenerateBuilderMembers(io::Printer* printer) const override;
+ void GenerateMergingCode(io::Printer* printer) const override;
+ void GenerateBuildingCode(io::Printer* printer) const override;
+ void GenerateParsingCode(io::Printer* printer) const override;
+ void GenerateSerializationCode(io::Printer* printer) const override;
+ void GenerateSerializedSizeCode(io::Printer* printer) const override;
+ void GenerateEqualsCode(io::Printer* printer) const override;
+ void GenerateHashCode(io::Printer* printer) const override;
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableEnumOneofFieldGenerator);
+};
+
+class RepeatedImmutableEnumFieldGenerator : public ImmutableFieldGenerator {
+ public:
+ explicit RepeatedImmutableEnumFieldGenerator(
+ const FieldDescriptor* descriptor, int messageBitIndex,
+ int builderBitIndex, Context* context);
+ ~RepeatedImmutableEnumFieldGenerator() override;
+
+ // implements ImmutableFieldGenerator ---------------------------------------
+ int GetNumBitsForMessage() const override;
+ int GetNumBitsForBuilder() const override;
+ void GenerateInterfaceMembers(io::Printer* printer) const override;
+ void GenerateMembers(io::Printer* printer) const override;
+ void GenerateBuilderMembers(io::Printer* printer) const override;
+ void GenerateInitializationCode(io::Printer* printer) const override;
+ void GenerateBuilderClearCode(io::Printer* printer) const override;
+ void GenerateMergingCode(io::Printer* printer) const override;
+ void GenerateBuildingCode(io::Printer* printer) const override;
+ void GenerateParsingCode(io::Printer* printer) const override;
+ void GenerateParsingCodeFromPacked(io::Printer* printer) const override;
+ void GenerateParsingDoneCode(io::Printer* printer) const override;
+ void GenerateSerializationCode(io::Printer* printer) const override;
+ void GenerateSerializedSizeCode(io::Printer* printer) const override;
+ void GenerateFieldBuilderInitializationCode(
+ io::Printer* printer) const override;
+ void GenerateEqualsCode(io::Printer* printer) const override;
+ void GenerateHashCode(io::Printer* printer) const override;
+ void GenerateKotlinDslMembers(io::Printer* printer) const override;
+
+ std::string GetBoxedType() const override;
+
+ private:
+ const FieldDescriptor* descriptor_;
+ std::map<std::string, std::string> variables_;
+ ClassNameResolver* name_resolver_;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedImmutableEnumFieldGenerator);
+};
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_ENUM_FIELD_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_enum_field_lite.cc b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_enum_field_lite.cc
new file mode 100644
index 00000000..ffc28ef0
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_enum_field_lite.cc
@@ -0,0 +1,918 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 <compiler/java/java_enum_field_lite.h>
+
+#include <cstdint>
+#include <map>
+#include <string>
+
+#include <stubs/logging.h>
+#include <stubs/common.h>
+#include <compiler/java/java_context.h>
+#include <compiler/java/java_doc_comment.h>
+#include <compiler/java/java_helpers.h>
+#include <compiler/java/java_name_resolver.h>
+#include <io/printer.h>
+#include <wire_format.h>
+#include <stubs/strutil.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+namespace {
+bool EnableExperimentalRuntimeForLite() {
+#ifdef PROTOBUF_EXPERIMENT
+ return PROTOBUF_EXPERIMENT;
+#else // PROTOBUF_EXPERIMENT
+ return false;
+#endif // !PROTOBUF_EXPERIMENT
+}
+
+void SetEnumVariables(const FieldDescriptor* descriptor, int messageBitIndex,
+ int builderBitIndex, const FieldGeneratorInfo* info,
+ ClassNameResolver* name_resolver,
+ std::map<std::string, std::string>* variables) {
+ SetCommonFieldVariables(descriptor, info, variables);
+
+ (*variables)["type"] =
+ name_resolver->GetImmutableClassName(descriptor->enum_type());
+ (*variables)["kt_type"] = (*variables)["type"];
+ (*variables)["mutable_type"] =
+ name_resolver->GetMutableClassName(descriptor->enum_type());
+ (*variables)["default"] = ImmutableDefaultValue(descriptor, name_resolver);
+ (*variables)["default_number"] =
+ StrCat(descriptor->default_value_enum()->number());
+ (*variables)["tag"] = StrCat(
+ static_cast<int32_t>(internal::WireFormat::MakeTag(descriptor)));
+ (*variables)["tag_size"] = StrCat(
+ internal::WireFormat::TagSize(descriptor->number(), GetType(descriptor)));
+ // TODO(birdo): Add @deprecated javadoc when generating javadoc is supported
+ // by the proto compiler
+ (*variables)["deprecation"] =
+ descriptor->options().deprecated() ? "@java.lang.Deprecated " : "";
+ (*variables)["kt_deprecation"] =
+ descriptor->options().deprecated()
+ ? "@kotlin.Deprecated(message = \"Field " + (*variables)["name"] +
+ " is deprecated\") "
+ : "";
+ (*variables)["required"] = descriptor->is_required() ? "true" : "false";
+
+ if (HasHasbit(descriptor)) {
+ // For singular messages and builders, one bit is used for the hasField bit.
+ (*variables)["get_has_field_bit_message"] = GenerateGetBit(messageBitIndex);
+
+ // Note that these have a trailing ";".
+ (*variables)["set_has_field_bit_message"] =
+ GenerateSetBit(messageBitIndex) + ";";
+ (*variables)["clear_has_field_bit_message"] =
+ GenerateClearBit(messageBitIndex) + ";";
+
+ (*variables)["is_field_present_message"] = GenerateGetBit(messageBitIndex);
+ } else {
+ (*variables)["set_has_field_bit_message"] = "";
+ (*variables)["clear_has_field_bit_message"] = "";
+
+ (*variables)["is_field_present_message"] =
+ (*variables)["name"] + "_ != " + (*variables)["default"] +
+ ".getNumber()";
+ }
+
+ (*variables)["get_has_field_bit_from_local"] =
+ GenerateGetBitFromLocal(builderBitIndex);
+ (*variables)["set_has_field_bit_to_local"] =
+ GenerateSetBitToLocal(messageBitIndex);
+
+ if (SupportUnknownEnumValue(descriptor->file())) {
+ (*variables)["unknown"] = (*variables)["type"] + ".UNRECOGNIZED";
+ } else {
+ (*variables)["unknown"] = (*variables)["default"];
+ }
+
+ // We use `x.getClass()` as a null check because it generates less bytecode
+ // than an `if (x == null) { throw ... }` statement.
+ (*variables)["null_check"] = "value.getClass();\n";
+}
+
+} // namespace
+
+// ===================================================================
+
+ImmutableEnumFieldLiteGenerator::ImmutableEnumFieldLiteGenerator(
+ const FieldDescriptor* descriptor, int messageBitIndex, Context* context)
+ : descriptor_(descriptor),
+ messageBitIndex_(messageBitIndex),
+ context_(context),
+ name_resolver_(context->GetNameResolver()) {
+ SetEnumVariables(descriptor, messageBitIndex, 0,
+ context->GetFieldGeneratorInfo(descriptor), name_resolver_,
+ &variables_);
+}
+
+ImmutableEnumFieldLiteGenerator::~ImmutableEnumFieldLiteGenerator() {}
+
+int ImmutableEnumFieldLiteGenerator::GetNumBitsForMessage() const {
+ return HasHasbit(descriptor_) ? 1 : 0;
+}
+
+void ImmutableEnumFieldLiteGenerator::GenerateInterfaceMembers(
+ io::Printer* printer) const {
+ if (HasHazzer(descriptor_)) {
+ WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
+ printer->Print(variables_,
+ "$deprecation$boolean has$capitalized_name$();\n");
+ }
+ if (SupportUnknownEnumValue(descriptor_->file())) {
+ WriteFieldEnumValueAccessorDocComment(printer, descriptor_, GETTER);
+ printer->Print(variables_,
+ "$deprecation$int get$capitalized_name$Value();\n");
+ }
+ WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
+ printer->Print(variables_, "$deprecation$$type$ get$capitalized_name$();\n");
+}
+
+void ImmutableEnumFieldLiteGenerator::GenerateMembers(
+ io::Printer* printer) const {
+ printer->Print(variables_, "private int $name$_;\n");
+ PrintExtraFieldInfo(variables_, printer);
+ if (HasHazzer(descriptor_)) {
+ WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
+ printer->Print(
+ variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
+ " return $get_has_field_bit_message$;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ }
+ if (SupportUnknownEnumValue(descriptor_->file())) {
+ WriteFieldEnumValueAccessorDocComment(printer, descriptor_, GETTER);
+ printer->Print(
+ variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public int ${$get$capitalized_name$Value$}$() {\n"
+ " return $name$_;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ }
+ WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
+ printer->Print(variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
+ " $type$ result = $type$.forNumber($name$_);\n"
+ " return result == null ? $unknown$ : result;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+
+ // Generate private setters for the builder to proxy into.
+ if (SupportUnknownEnumValue(descriptor_->file())) {
+ WriteFieldEnumValueAccessorDocComment(printer, descriptor_, SETTER);
+ printer->Print(variables_,
+ "private void set$capitalized_name$Value(int value) {\n"
+ " $set_has_field_bit_message$"
+ " $name$_ = value;\n"
+ "}\n");
+ }
+ WriteFieldAccessorDocComment(printer, descriptor_, SETTER);
+ printer->Print(variables_,
+ "private void set$capitalized_name$($type$ value) {\n"
+ " $name$_ = value.getNumber();\n"
+ " $set_has_field_bit_message$\n"
+ "}\n");
+ WriteFieldAccessorDocComment(printer, descriptor_, CLEARER);
+ printer->Print(variables_,
+ "private void clear$capitalized_name$() {\n"
+ " $clear_has_field_bit_message$\n"
+ " $name$_ = $default_number$;\n"
+ "}\n");
+}
+
+void ImmutableEnumFieldLiteGenerator::GenerateBuilderMembers(
+ io::Printer* printer) const {
+ if (HasHazzer(descriptor_)) {
+ WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
+ printer->Print(
+ variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
+ " return instance.has$capitalized_name$();\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ }
+ if (SupportUnknownEnumValue(descriptor_->file())) {
+ WriteFieldEnumValueAccessorDocComment(printer, descriptor_, GETTER);
+ printer->Print(
+ variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public int ${$get$capitalized_name$Value$}$() {\n"
+ " return instance.get$capitalized_name$Value();\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldAccessorDocComment(printer, descriptor_, SETTER,
+ /* builder */ true);
+ printer->Print(variables_,
+ "$deprecation$public Builder "
+ "${$set$capitalized_name$Value$}$(int value) {\n"
+ " copyOnWrite();\n"
+ " instance.set$capitalized_name$Value(value);\n"
+ " return this;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ }
+ WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
+ printer->Print(variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
+ " return instance.get$capitalized_name$();\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldEnumValueAccessorDocComment(printer, descriptor_, SETTER,
+ /* builder */ true);
+ printer->Print(variables_,
+ "$deprecation$public Builder "
+ "${$set$capitalized_name$$}$($type$ value) {\n"
+ " copyOnWrite();\n"
+ " instance.set$capitalized_name$(value);\n"
+ " return this;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldAccessorDocComment(printer, descriptor_, CLEARER,
+ /* builder */ true);
+ printer->Print(
+ variables_,
+ "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n"
+ " copyOnWrite();\n"
+ " instance.clear$capitalized_name$();\n"
+ " return this;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+}
+
+void ImmutableEnumFieldLiteGenerator::GenerateKotlinDslMembers(
+ io::Printer* printer) const {
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$kt_deprecation$public var $kt_name$: $kt_type$\n"
+ " @JvmName(\"${$get$kt_capitalized_name$$}$\")\n"
+ " get() = $kt_dsl_builder$.${$get$capitalized_name$$}$()\n"
+ " @JvmName(\"${$set$kt_capitalized_name$$}$\")\n"
+ " set(value) {\n"
+ " $kt_dsl_builder$.${$set$capitalized_name$$}$(value)\n"
+ " }\n");
+
+ WriteFieldAccessorDocComment(printer, descriptor_, CLEARER,
+ /* builder */ false);
+ printer->Print(variables_,
+ "public fun ${$clear$kt_capitalized_name$$}$() {\n"
+ " $kt_dsl_builder$.${$clear$capitalized_name$$}$()\n"
+ "}\n");
+
+ if (HasHazzer(descriptor_)) {
+ WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
+ printer->Print(
+ variables_,
+ "public fun ${$has$kt_capitalized_name$$}$(): kotlin.Boolean {\n"
+ " return $kt_dsl_builder$.${$has$capitalized_name$$}$()\n"
+ "}\n");
+ }
+}
+
+void ImmutableEnumFieldLiteGenerator::GenerateInitializationCode(
+ io::Printer* printer) const {
+ if (!IsDefaultValueJavaDefault(descriptor_)) {
+ printer->Print(variables_, "$name$_ = $default_number$;\n");
+ }
+}
+
+void ImmutableEnumFieldLiteGenerator::GenerateFieldInfo(
+ io::Printer* printer, std::vector<uint16_t>* output) const {
+ WriteIntToUtf16CharSequence(descriptor_->number(), output);
+ WriteIntToUtf16CharSequence(GetExperimentalJavaFieldType(descriptor_),
+ output);
+ if (HasHasbit(descriptor_)) {
+ WriteIntToUtf16CharSequence(messageBitIndex_, output);
+ }
+ printer->Print(variables_, "\"$name$_\",\n");
+ if (!SupportUnknownEnumValue((descriptor_))) {
+ PrintEnumVerifierLogic(printer, descriptor_, variables_,
+ /*var_name=*/"$type$",
+ /*terminating_string=*/",\n",
+ /*enforce_lite=*/context_->EnforceLite());
+ }
+}
+
+std::string ImmutableEnumFieldLiteGenerator::GetBoxedType() const {
+ return name_resolver_->GetImmutableClassName(descriptor_->enum_type());
+}
+
+// ===================================================================
+
+ImmutableEnumOneofFieldLiteGenerator::ImmutableEnumOneofFieldLiteGenerator(
+ const FieldDescriptor* descriptor, int messageBitIndex, Context* context)
+ : ImmutableEnumFieldLiteGenerator(descriptor, messageBitIndex, context) {
+ const OneofGeneratorInfo* info =
+ context->GetOneofGeneratorInfo(descriptor->containing_oneof());
+ SetCommonOneofVariables(descriptor, info, &variables_);
+}
+
+ImmutableEnumOneofFieldLiteGenerator::~ImmutableEnumOneofFieldLiteGenerator() {}
+
+void ImmutableEnumOneofFieldLiteGenerator::GenerateMembers(
+ io::Printer* printer) const {
+ PrintExtraFieldInfo(variables_, printer);
+ GOOGLE_DCHECK(HasHazzer(descriptor_));
+ WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
+ printer->Print(variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
+ " return $has_oneof_case_message$;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+
+ if (SupportUnknownEnumValue(descriptor_->file())) {
+ WriteFieldEnumValueAccessorDocComment(printer, descriptor_, GETTER);
+ printer->Print(
+ variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public int ${$get$capitalized_name$Value$}$() {\n"
+ " if ($has_oneof_case_message$) {\n"
+ " return (java.lang.Integer) $oneof_name$_;\n"
+ " }\n"
+ " return $default_number$;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ }
+ WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
+ printer->Print(variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
+ " if ($has_oneof_case_message$) {\n"
+ " $type$ result = $type$.forNumber((java.lang.Integer) "
+ "$oneof_name$_);\n"
+ " return result == null ? $unknown$ : result;\n"
+ " }\n"
+ " return $default$;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+
+ // Generate private setters for the builder to proxy into.
+ if (SupportUnknownEnumValue(descriptor_->file())) {
+ WriteFieldEnumValueAccessorDocComment(printer, descriptor_, SETTER);
+ printer->Print(variables_,
+ "private void set$capitalized_name$Value(int value) {\n"
+ " $set_oneof_case_message$;\n"
+ " $oneof_name$_ = value;\n"
+ "}\n");
+ }
+ WriteFieldAccessorDocComment(printer, descriptor_, SETTER);
+ printer->Print(variables_,
+ "private void set$capitalized_name$($type$ value) {\n"
+ " $oneof_name$_ = value.getNumber();\n"
+ " $set_oneof_case_message$;\n"
+ "}\n");
+ WriteFieldAccessorDocComment(printer, descriptor_, CLEARER);
+ printer->Print(variables_,
+ "private void clear$capitalized_name$() {\n"
+ " if ($has_oneof_case_message$) {\n"
+ " $clear_oneof_case_message$;\n"
+ " $oneof_name$_ = null;\n"
+ " }\n"
+ "}\n");
+}
+
+void ImmutableEnumOneofFieldLiteGenerator::GenerateFieldInfo(
+ io::Printer* printer, std::vector<uint16_t>* output) const {
+ WriteIntToUtf16CharSequence(descriptor_->number(), output);
+ WriteIntToUtf16CharSequence(GetExperimentalJavaFieldType(descriptor_),
+ output);
+ WriteIntToUtf16CharSequence(descriptor_->containing_oneof()->index(), output);
+ if (!SupportUnknownEnumValue(descriptor_)) {
+ PrintEnumVerifierLogic(printer, descriptor_, variables_,
+ /*var_name=*/"$type$",
+ /*terminating_string=*/",\n",
+ /*enforce_lite=*/context_->EnforceLite());
+ }
+}
+
+void ImmutableEnumOneofFieldLiteGenerator::GenerateBuilderMembers(
+ io::Printer* printer) const {
+ GOOGLE_DCHECK(HasHazzer(descriptor_));
+ WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
+ printer->Print(variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
+ " return instance.has$capitalized_name$();\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+
+ if (SupportUnknownEnumValue(descriptor_->file())) {
+ WriteFieldEnumValueAccessorDocComment(printer, descriptor_, GETTER);
+ printer->Print(
+ variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public int ${$get$capitalized_name$Value$}$() {\n"
+ " return instance.get$capitalized_name$Value();\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldEnumValueAccessorDocComment(printer, descriptor_, SETTER,
+ /* builder */ true);
+ printer->Print(variables_,
+ "$deprecation$public Builder "
+ "${$set$capitalized_name$Value$}$(int value) {\n"
+ " copyOnWrite();\n"
+ " instance.set$capitalized_name$Value(value);\n"
+ " return this;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ }
+ WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
+ printer->Print(variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
+ " return instance.get$capitalized_name$();\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldAccessorDocComment(printer, descriptor_, SETTER,
+ /* builder */ true);
+ printer->Print(variables_,
+ "$deprecation$public Builder "
+ "${$set$capitalized_name$$}$($type$ value) {\n"
+ " copyOnWrite();\n"
+ " instance.set$capitalized_name$(value);\n"
+ " return this;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldAccessorDocComment(printer, descriptor_, CLEARER,
+ /* builder */ true);
+ printer->Print(
+ variables_,
+ "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n"
+ " copyOnWrite();\n"
+ " instance.clear$capitalized_name$();\n"
+ " return this;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+}
+
+// ===================================================================
+
+RepeatedImmutableEnumFieldLiteGenerator::
+ RepeatedImmutableEnumFieldLiteGenerator(const FieldDescriptor* descriptor,
+ int messageBitIndex,
+ Context* context)
+ : descriptor_(descriptor),
+ context_(context),
+ name_resolver_(context->GetNameResolver()) {
+ SetEnumVariables(descriptor, messageBitIndex, 0,
+ context->GetFieldGeneratorInfo(descriptor), name_resolver_,
+ &variables_);
+}
+
+RepeatedImmutableEnumFieldLiteGenerator::
+ ~RepeatedImmutableEnumFieldLiteGenerator() {}
+
+int RepeatedImmutableEnumFieldLiteGenerator::GetNumBitsForMessage() const {
+ return 0;
+}
+
+void RepeatedImmutableEnumFieldLiteGenerator::GenerateInterfaceMembers(
+ io::Printer* printer) const {
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_GETTER);
+ printer->Print(
+ variables_,
+ "$deprecation$java.util.List<$type$> get$capitalized_name$List();\n");
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_COUNT);
+ printer->Print(variables_,
+ "$deprecation$int get$capitalized_name$Count();\n");
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_GETTER);
+ printer->Print(variables_,
+ "$deprecation$$type$ get$capitalized_name$(int index);\n");
+ if (SupportUnknownEnumValue(descriptor_->file())) {
+ WriteFieldEnumValueAccessorDocComment(printer, descriptor_, LIST_GETTER);
+ printer->Print(variables_,
+ "$deprecation$java.util.List<java.lang.Integer>\n"
+ "get$capitalized_name$ValueList();\n");
+ WriteFieldEnumValueAccessorDocComment(printer, descriptor_,
+ LIST_INDEXED_GETTER);
+ printer->Print(variables_,
+ "$deprecation$int get$capitalized_name$Value(int index);\n");
+ }
+}
+
+void RepeatedImmutableEnumFieldLiteGenerator::GenerateMembers(
+ io::Printer* printer) const {
+ printer->Print(
+ variables_,
+ "private com.google.protobuf.Internal.IntList $name$_;\n"
+ "private static final "
+ "com.google.protobuf.Internal.ListAdapter.Converter<\n"
+ " java.lang.Integer, $type$> $name$_converter_ =\n"
+ " new com.google.protobuf.Internal.ListAdapter.Converter<\n"
+ " java.lang.Integer, $type$>() {\n"
+ " @java.lang.Override\n"
+ " public $type$ convert(java.lang.Integer from) {\n"
+ " $type$ result = $type$.forNumber(from);\n"
+ " return result == null ? $unknown$ : result;\n"
+ " }\n"
+ " };\n");
+ PrintExtraFieldInfo(variables_, printer);
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_GETTER);
+ printer->Print(
+ variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public java.util.List<$type$> "
+ "${$get$capitalized_name$List$}$() {\n"
+ " return new com.google.protobuf.Internal.ListAdapter<\n"
+ " java.lang.Integer, $type$>($name$_, $name$_converter_);\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_COUNT);
+ printer->Print(
+ variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n"
+ " return $name$_.size();\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_GETTER);
+ printer->Print(
+ variables_,
+ // NB: Do not use the "$name$_converter_" field; the usage of generics
+ // (and requisite upcasts to Object) prevent optimizations. Even
+ // without any optimizations, the below code is cheaper because it
+ // avoids boxing an int and a checkcast from the generics.
+ "@java.lang.Override\n"
+ "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n"
+ " $type$ result = $type$.forNumber($name$_.getInt(index));\n"
+ " return result == null ? $unknown$ : result;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ if (SupportUnknownEnumValue(descriptor_->file())) {
+ WriteFieldEnumValueAccessorDocComment(printer, descriptor_, LIST_GETTER);
+ printer->Print(variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public java.util.List<java.lang.Integer>\n"
+ "${$get$capitalized_name$ValueList$}$() {\n"
+ " return $name$_;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldEnumValueAccessorDocComment(printer, descriptor_,
+ LIST_INDEXED_GETTER);
+ printer->Print(variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public int "
+ "${$get$capitalized_name$Value$}$(int index) {\n"
+ " return $name$_.getInt(index);\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ }
+
+ if (!EnableExperimentalRuntimeForLite() && descriptor_->is_packed() &&
+ context_->HasGeneratedMethods(descriptor_->containing_type())) {
+ printer->Print(variables_, "private int $name$MemoizedSerializedSize;\n");
+ }
+
+ // Generate private setters for the builder to proxy into.
+ printer->Print(
+ variables_,
+ "private void ensure$capitalized_name$IsMutable() {\n"
+ // Use a temporary to avoid a redundant iget-object.
+ " com.google.protobuf.Internal.IntList tmp = $name$_;\n"
+ " if (!tmp.isModifiable()) {\n"
+ " $name$_ =\n"
+ " com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);\n"
+ " }\n"
+ "}\n");
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_SETTER);
+ printer->Print(variables_,
+ "private void set$capitalized_name$(\n"
+ " int index, $type$ value) {\n"
+ " $null_check$"
+ " ensure$capitalized_name$IsMutable();\n"
+ " $name$_.setInt(index, value.getNumber());\n"
+ "}\n");
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_ADDER);
+ printer->Print(variables_,
+ "private void add$capitalized_name$($type$ value) {\n"
+ " $null_check$"
+ " ensure$capitalized_name$IsMutable();\n"
+ " $name$_.addInt(value.getNumber());\n"
+ "}\n");
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_MULTI_ADDER);
+ printer->Print(variables_,
+ "private void addAll$capitalized_name$(\n"
+ " java.lang.Iterable<? extends $type$> values) {\n"
+ " ensure$capitalized_name$IsMutable();\n"
+ " for ($type$ value : values) {\n"
+ " $name$_.addInt(value.getNumber());\n"
+ " }\n"
+ "}\n");
+ WriteFieldAccessorDocComment(printer, descriptor_, CLEARER);
+ printer->Print(variables_,
+ "private void clear$capitalized_name$() {\n"
+ " $name$_ = emptyIntList();\n"
+ "}\n");
+
+ if (SupportUnknownEnumValue(descriptor_->file())) {
+ WriteFieldEnumValueAccessorDocComment(printer, descriptor_, SETTER);
+ printer->Print(variables_,
+ "private void set$capitalized_name$Value(\n"
+ " int index, int value) {\n"
+ " ensure$capitalized_name$IsMutable();\n"
+ " $name$_.setInt(index, value);\n"
+ "}\n");
+ WriteFieldEnumValueAccessorDocComment(printer, descriptor_, LIST_ADDER);
+ printer->Print(variables_,
+ "private void add$capitalized_name$Value(int value) {\n"
+ " ensure$capitalized_name$IsMutable();\n"
+ " $name$_.addInt(value);\n"
+ "}\n");
+ WriteFieldEnumValueAccessorDocComment(printer, descriptor_,
+ LIST_MULTI_ADDER);
+ printer->Print(variables_,
+ "private void addAll$capitalized_name$Value(\n"
+ " java.lang.Iterable<java.lang.Integer> values) {\n"
+ " ensure$capitalized_name$IsMutable();\n"
+ " for (int value : values) {\n"
+ " $name$_.addInt(value);\n"
+ " }\n"
+ "}\n");
+ }
+}
+
+void RepeatedImmutableEnumFieldLiteGenerator::GenerateFieldInfo(
+ io::Printer* printer, std::vector<uint16_t>* output) const {
+ WriteIntToUtf16CharSequence(descriptor_->number(), output);
+ WriteIntToUtf16CharSequence(GetExperimentalJavaFieldType(descriptor_),
+ output);
+ printer->Print(variables_, "\"$name$_\",\n");
+ if (!SupportUnknownEnumValue(descriptor_->file())) {
+ PrintEnumVerifierLogic(printer, descriptor_, variables_,
+ /*var_name=*/"$type$",
+ /*terminating_string=*/",\n",
+ /*enforce_lite=*/context_->EnforceLite());
+ }
+}
+
+void RepeatedImmutableEnumFieldLiteGenerator::GenerateBuilderMembers(
+ io::Printer* printer) const {
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_GETTER);
+ printer->Print(variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public java.util.List<$type$> "
+ "${$get$capitalized_name$List$}$() {\n"
+ " return instance.get$capitalized_name$List();\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_COUNT);
+ printer->Print(
+ variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n"
+ " return instance.get$capitalized_name$Count();\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_GETTER);
+ printer->Print(
+ variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n"
+ " return instance.get$capitalized_name$(index);\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_SETTER,
+ /* builder */ true);
+ printer->Print(variables_,
+ "$deprecation$public Builder ${$set$capitalized_name$$}$(\n"
+ " int index, $type$ value) {\n"
+ " copyOnWrite();\n"
+ " instance.set$capitalized_name$(index, value);\n"
+ " return this;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_ADDER,
+ /* builder */ true);
+ printer->Print(variables_,
+ "$deprecation$public Builder "
+ "${$add$capitalized_name$$}$($type$ value) {\n"
+ " copyOnWrite();\n"
+ " instance.add$capitalized_name$(value);\n"
+ " return this;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_MULTI_ADDER,
+ /* builder */ true);
+ printer->Print(variables_,
+ "$deprecation$public Builder ${$addAll$capitalized_name$$}$(\n"
+ " java.lang.Iterable<? extends $type$> values) {\n"
+ " copyOnWrite();\n"
+ " instance.addAll$capitalized_name$(values);"
+ " return this;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldAccessorDocComment(printer, descriptor_, CLEARER,
+ /* builder */ true);
+ printer->Print(
+ variables_,
+ "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n"
+ " copyOnWrite();\n"
+ " instance.clear$capitalized_name$();\n"
+ " return this;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+
+ if (SupportUnknownEnumValue(descriptor_->file())) {
+ WriteFieldEnumValueAccessorDocComment(printer, descriptor_, LIST_GETTER);
+ printer->Print(variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public java.util.List<java.lang.Integer>\n"
+ "${$get$capitalized_name$ValueList$}$() {\n"
+ " return java.util.Collections.unmodifiableList(\n"
+ " instance.get$capitalized_name$ValueList());\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldEnumValueAccessorDocComment(printer, descriptor_,
+ LIST_INDEXED_GETTER);
+ printer->Print(variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public int "
+ "${$get$capitalized_name$Value$}$(int index) {\n"
+ " return instance.get$capitalized_name$Value(index);\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldEnumValueAccessorDocComment(printer, descriptor_,
+ LIST_INDEXED_SETTER,
+ /* builder */ true);
+ printer->Print(
+ variables_,
+ "$deprecation$public Builder ${$set$capitalized_name$Value$}$(\n"
+ " int index, int value) {\n"
+ " copyOnWrite();\n"
+ " instance.set$capitalized_name$Value(index, value);\n"
+ " return this;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldEnumValueAccessorDocComment(printer, descriptor_, LIST_ADDER,
+ /* builder */ true);
+ printer->Print(variables_,
+ "$deprecation$public Builder "
+ "${$add$capitalized_name$Value$}$(int value) {\n"
+ " instance.add$capitalized_name$Value(value);\n"
+ " return this;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldEnumValueAccessorDocComment(printer, descriptor_,
+ LIST_MULTI_ADDER,
+ /* builder */ true);
+ printer->Print(
+ variables_,
+ "$deprecation$public Builder ${$addAll$capitalized_name$Value$}$(\n"
+ " java.lang.Iterable<java.lang.Integer> values) {\n"
+ " copyOnWrite();\n"
+ " instance.addAll$capitalized_name$Value(values);\n"
+ " return this;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ }
+}
+
+void RepeatedImmutableEnumFieldLiteGenerator::GenerateInitializationCode(
+ io::Printer* printer) const {
+ printer->Print(variables_, "$name$_ = emptyIntList();\n");
+}
+
+void RepeatedImmutableEnumFieldLiteGenerator::GenerateKotlinDslMembers(
+ io::Printer* printer) const {
+ printer->Print(
+ variables_,
+ "/**\n"
+ " * An uninstantiable, behaviorless type to represent the field in\n"
+ " * generics.\n"
+ " */\n"
+ "@kotlin.OptIn"
+ "(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)\n"
+ "public class ${$$kt_capitalized_name$Proxy$}$ private constructor()"
+ " : com.google.protobuf.kotlin.DslProxy()\n");
+
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$kt_deprecation$ public val $kt_name$: "
+ "com.google.protobuf.kotlin.DslList"
+ "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>\n"
+ " @kotlin.jvm.JvmSynthetic\n"
+ " get() = com.google.protobuf.kotlin.DslList(\n"
+ " $kt_dsl_builder$.${$get$capitalized_name$List$}$()\n"
+ " )\n");
+
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_ADDER,
+ /* builder */ false);
+ printer->Print(variables_,
+ "@kotlin.jvm.JvmSynthetic\n"
+ "@kotlin.jvm.JvmName(\"add$kt_capitalized_name$\")\n"
+ "public fun com.google.protobuf.kotlin.DslList"
+ "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>."
+ "add(value: $kt_type$) {\n"
+ " $kt_dsl_builder$.${$add$capitalized_name$$}$(value)\n"
+ "}");
+
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_ADDER,
+ /* builder */ false);
+ printer->Print(variables_,
+ "@kotlin.jvm.JvmSynthetic\n"
+ "@kotlin.jvm.JvmName(\"plusAssign$kt_capitalized_name$\")\n"
+ "@Suppress(\"NOTHING_TO_INLINE\")\n"
+ "public inline operator fun com.google.protobuf.kotlin.DslList"
+ "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>."
+ "plusAssign(value: $kt_type$) {\n"
+ " add(value)\n"
+ "}");
+
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_MULTI_ADDER,
+ /* builder */ false);
+ printer->Print(variables_,
+ "@kotlin.jvm.JvmSynthetic\n"
+ "@kotlin.jvm.JvmName(\"addAll$kt_capitalized_name$\")\n"
+ "public fun com.google.protobuf.kotlin.DslList"
+ "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>."
+ "addAll(values: kotlin.collections.Iterable<$kt_type$>) {\n"
+ " $kt_dsl_builder$.${$addAll$capitalized_name$$}$(values)\n"
+ "}");
+
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_MULTI_ADDER,
+ /* builder */ false);
+ printer->Print(
+ variables_,
+ "@kotlin.jvm.JvmSynthetic\n"
+ "@kotlin.jvm.JvmName(\"plusAssignAll$kt_capitalized_name$\")\n"
+ "@Suppress(\"NOTHING_TO_INLINE\")\n"
+ "public inline operator fun com.google.protobuf.kotlin.DslList"
+ "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>."
+ "plusAssign(values: kotlin.collections.Iterable<$kt_type$>) {\n"
+ " addAll(values)\n"
+ "}");
+
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_SETTER,
+ /* builder */ false);
+ printer->Print(
+ variables_,
+ "@kotlin.jvm.JvmSynthetic\n"
+ "@kotlin.jvm.JvmName(\"set$kt_capitalized_name$\")\n"
+ "public operator fun com.google.protobuf.kotlin.DslList"
+ "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>."
+ "set(index: kotlin.Int, value: $kt_type$) {\n"
+ " $kt_dsl_builder$.${$set$capitalized_name$$}$(index, value)\n"
+ "}");
+
+ WriteFieldAccessorDocComment(printer, descriptor_, CLEARER,
+ /* builder */ false);
+ printer->Print(variables_,
+ "@kotlin.jvm.JvmSynthetic\n"
+ "@kotlin.jvm.JvmName(\"clear$kt_capitalized_name$\")\n"
+ "public fun com.google.protobuf.kotlin.DslList"
+ "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>."
+ "clear() {\n"
+ " $kt_dsl_builder$.${$clear$capitalized_name$$}$()\n"
+ "}");
+}
+
+std::string RepeatedImmutableEnumFieldLiteGenerator::GetBoxedType() const {
+ return name_resolver_->GetImmutableClassName(descriptor_->enum_type());
+}
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_enum_field_lite.h b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_enum_field_lite.h
new file mode 100644
index 00000000..8073f393
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_enum_field_lite.h
@@ -0,0 +1,140 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_ENUM_FIELD_LITE_H__
+#define GOOGLE_PROTOBUF_COMPILER_JAVA_ENUM_FIELD_LITE_H__
+
+#include <cstdint>
+#include <map>
+#include <string>
+
+#include <compiler/java/java_field.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+class Context; // context.h
+class ClassNameResolver; // name_resolver.h
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+class ImmutableEnumFieldLiteGenerator : public ImmutableFieldLiteGenerator {
+ public:
+ explicit ImmutableEnumFieldLiteGenerator(const FieldDescriptor* descriptor,
+ int messageBitIndex,
+ Context* context);
+ ~ImmutableEnumFieldLiteGenerator() override;
+
+ // implements ImmutableFieldLiteGenerator
+ // ------------------------------------
+ int GetNumBitsForMessage() const override;
+ void GenerateInterfaceMembers(io::Printer* printer) const override;
+ void GenerateMembers(io::Printer* printer) const override;
+ void GenerateBuilderMembers(io::Printer* printer) const override;
+ void GenerateInitializationCode(io::Printer* printer) const override;
+ void GenerateFieldInfo(io::Printer* printer,
+ std::vector<uint16_t>* output) const override;
+ void GenerateKotlinDslMembers(io::Printer* printer) const override;
+
+ std::string GetBoxedType() const override;
+
+ protected:
+ const FieldDescriptor* descriptor_;
+ std::map<std::string, std::string> variables_;
+ const int messageBitIndex_;
+ Context* context_;
+ ClassNameResolver* name_resolver_;
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableEnumFieldLiteGenerator);
+};
+
+class ImmutableEnumOneofFieldLiteGenerator
+ : public ImmutableEnumFieldLiteGenerator {
+ public:
+ ImmutableEnumOneofFieldLiteGenerator(const FieldDescriptor* descriptor,
+ int messageBitIndex, Context* context);
+ ~ImmutableEnumOneofFieldLiteGenerator() override;
+
+ void GenerateMembers(io::Printer* printer) const override;
+ void GenerateBuilderMembers(io::Printer* printer) const override;
+ void GenerateFieldInfo(io::Printer* printer,
+ std::vector<uint16_t>* output) const override;
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableEnumOneofFieldLiteGenerator);
+};
+
+class RepeatedImmutableEnumFieldLiteGenerator
+ : public ImmutableFieldLiteGenerator {
+ public:
+ explicit RepeatedImmutableEnumFieldLiteGenerator(
+ const FieldDescriptor* descriptor, int messageBitIndex, Context* context);
+ ~RepeatedImmutableEnumFieldLiteGenerator() override;
+
+ // implements ImmutableFieldLiteGenerator ------------------------------------
+ int GetNumBitsForMessage() const override;
+ void GenerateInterfaceMembers(io::Printer* printer) const override;
+ void GenerateMembers(io::Printer* printer) const override;
+ void GenerateBuilderMembers(io::Printer* printer) const override;
+ void GenerateInitializationCode(io::Printer* printer) const override;
+ void GenerateFieldInfo(io::Printer* printer,
+ std::vector<uint16_t>* output) const override;
+ void GenerateKotlinDslMembers(io::Printer* printer) const override;
+
+ std::string GetBoxedType() const override;
+
+ private:
+ const FieldDescriptor* descriptor_;
+ std::map<std::string, std::string> variables_;
+ Context* context_;
+ ClassNameResolver* name_resolver_;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedImmutableEnumFieldLiteGenerator);
+};
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_ENUM_FIELD_LITE_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_enum_lite.cc b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_enum_lite.cc
new file mode 100644
index 00000000..7cfad624
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_enum_lite.cc
@@ -0,0 +1,235 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 <map>
+#include <string>
+
+#include <compiler/java/java_context.h>
+#include <compiler/java/java_doc_comment.h>
+#include <compiler/java/java_enum_lite.h>
+#include <compiler/java/java_helpers.h>
+#include <compiler/java/java_name_resolver.h>
+#include <descriptor.pb.h>
+#include <io/printer.h>
+#include <stubs/strutil.h>
+#include <stubs/map_util.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+EnumLiteGenerator::EnumLiteGenerator(const EnumDescriptor* descriptor,
+ bool immutable_api, Context* context)
+ : descriptor_(descriptor),
+ immutable_api_(immutable_api),
+ context_(context),
+ name_resolver_(context->GetNameResolver()) {
+ for (int i = 0; i < descriptor_->value_count(); i++) {
+ const EnumValueDescriptor* value = descriptor_->value(i);
+ const EnumValueDescriptor* canonical_value =
+ descriptor_->FindValueByNumber(value->number());
+
+ if (value == canonical_value) {
+ canonical_values_.push_back(value);
+ } else {
+ Alias alias;
+ alias.value = value;
+ alias.canonical_value = canonical_value;
+ aliases_.push_back(alias);
+ }
+ }
+}
+
+EnumLiteGenerator::~EnumLiteGenerator() {}
+
+void EnumLiteGenerator::Generate(io::Printer* printer) {
+ WriteEnumDocComment(printer, descriptor_);
+ MaybePrintGeneratedAnnotation(context_, printer, descriptor_, immutable_api_);
+ printer->Print(
+ "$deprecation$public enum $classname$\n"
+ " implements com.google.protobuf.Internal.EnumLite {\n",
+ "classname", descriptor_->name(), "deprecation",
+ descriptor_->options().deprecated() ? "@java.lang.Deprecated " : "");
+ printer->Annotate("classname", descriptor_);
+ printer->Indent();
+
+ for (int i = 0; i < canonical_values_.size(); i++) {
+ std::map<std::string, std::string> vars;
+ vars["name"] = canonical_values_[i]->name();
+ vars["number"] = StrCat(canonical_values_[i]->number());
+ WriteEnumValueDocComment(printer, canonical_values_[i]);
+ if (canonical_values_[i]->options().deprecated()) {
+ printer->Print("@java.lang.Deprecated\n");
+ }
+ printer->Print(vars, "$name$($number$),\n");
+ printer->Annotate("name", canonical_values_[i]);
+ }
+
+ if (SupportUnknownEnumValue(descriptor_->file())) {
+ printer->Print("${$UNRECOGNIZED$}$(-1),\n", "{", "", "}", "");
+ printer->Annotate("{", "}", descriptor_);
+ }
+
+ printer->Print(
+ ";\n"
+ "\n");
+
+ // -----------------------------------------------------------------
+
+ for (int i = 0; i < aliases_.size(); i++) {
+ std::map<std::string, std::string> vars;
+ vars["classname"] = descriptor_->name();
+ vars["name"] = aliases_[i].value->name();
+ vars["canonical_name"] = aliases_[i].canonical_value->name();
+ WriteEnumValueDocComment(printer, aliases_[i].value);
+ printer->Print(
+ vars, "public static final $classname$ $name$ = $canonical_name$;\n");
+ printer->Annotate("name", aliases_[i].value);
+ }
+
+ for (int i = 0; i < descriptor_->value_count(); i++) {
+ std::map<std::string, std::string> vars;
+ vars["name"] = descriptor_->value(i)->name();
+ vars["number"] = StrCat(descriptor_->value(i)->number());
+ vars["{"] = "";
+ vars["}"] = "";
+ vars["deprecation"] = descriptor_->value(i)->options().deprecated()
+ ? "@java.lang.Deprecated "
+ : "";
+ WriteEnumValueDocComment(printer, descriptor_->value(i));
+ printer->Print(vars,
+ "$deprecation$public static final int ${$$name$_VALUE$}$ = "
+ "$number$;\n");
+ printer->Annotate("{", "}", descriptor_->value(i));
+ }
+ printer->Print("\n");
+
+ // -----------------------------------------------------------------
+
+ printer->Print(
+ "\n"
+ "@java.lang.Override\n"
+ "public final int getNumber() {\n");
+ if (SupportUnknownEnumValue(descriptor_->file())) {
+ printer->Print(
+ " if (this == UNRECOGNIZED) {\n"
+ " throw new java.lang.IllegalArgumentException(\n"
+ " \"Can't get the number of an unknown enum value.\");\n"
+ " }\n");
+ }
+ printer->Print(
+ " return value;\n"
+ "}\n"
+ "\n"
+ "/**\n"
+ " * @param value The number of the enum to look for.\n"
+ " * @return The enum associated with the given number.\n"
+ " * @deprecated Use {@link #forNumber(int)} instead.\n"
+ " */\n"
+ "@java.lang.Deprecated\n"
+ "public static $classname$ valueOf(int value) {\n"
+ " return forNumber(value);\n"
+ "}\n"
+ "\n"
+ "public static $classname$ forNumber(int value) {\n"
+ " switch (value) {\n",
+ "classname", descriptor_->name());
+ printer->Indent();
+ printer->Indent();
+
+ for (int i = 0; i < canonical_values_.size(); i++) {
+ printer->Print("case $number$: return $name$;\n", "name",
+ canonical_values_[i]->name(), "number",
+ StrCat(canonical_values_[i]->number()));
+ }
+
+ printer->Outdent();
+ printer->Outdent();
+ printer->Print(
+ " default: return null;\n"
+ " }\n"
+ "}\n"
+ "\n"
+ "public static com.google.protobuf.Internal.EnumLiteMap<$classname$>\n"
+ " internalGetValueMap() {\n"
+ " return internalValueMap;\n"
+ "}\n"
+ "private static final com.google.protobuf.Internal.EnumLiteMap<\n"
+ " $classname$> internalValueMap =\n"
+ " new com.google.protobuf.Internal.EnumLiteMap<$classname$>() {\n"
+ " @java.lang.Override\n"
+ " public $classname$ findValueByNumber(int number) {\n"
+ " return $classname$.forNumber(number);\n"
+ " }\n"
+ " };\n"
+ "\n"
+ "public static com.google.protobuf.Internal.EnumVerifier \n"
+ " internalGetVerifier() {\n"
+ " return $classname$Verifier.INSTANCE;\n"
+ "}\n"
+ "\n"
+ "private static final class $classname$Verifier implements \n"
+ " com.google.protobuf.Internal.EnumVerifier { \n"
+ " static final com.google.protobuf.Internal.EnumVerifier "
+ " INSTANCE = new $classname$Verifier();\n"
+ " @java.lang.Override\n"
+ " public boolean isInRange(int number) {\n"
+ " return $classname$.forNumber(number) != null;\n"
+ " }\n"
+ " };\n"
+ "\n",
+ "classname", descriptor_->name());
+
+ printer->Print(
+ "private final int value;\n\n"
+ "private $classname$(int value) {\n",
+ "classname", descriptor_->name());
+ printer->Print(
+ " this.value = value;\n"
+ "}\n");
+
+ printer->Print(
+ "\n"
+ "// @@protoc_insertion_point(enum_scope:$full_name$)\n",
+ "full_name", descriptor_->full_name());
+
+ printer->Outdent();
+ printer->Print("}\n\n");
+}
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_enum_lite.h b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_enum_lite.h
new file mode 100644
index 00000000..0b706d8e
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_enum_lite.h
@@ -0,0 +1,98 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_ENUM_LITE_H__
+#define GOOGLE_PROTOBUF_COMPILER_JAVA_ENUM_LITE_H__
+
+#include <string>
+#include <vector>
+#include <descriptor.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+class Context; // context.h
+class ClassNameResolver; // name_resolver.h
+} // namespace java
+} // namespace compiler
+namespace io {
+class Printer; // printer.h
+}
+} // namespace protobuf
+} // namespace google
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+class EnumLiteGenerator {
+ public:
+ EnumLiteGenerator(const EnumDescriptor* descriptor, bool immutable_api,
+ Context* context);
+ ~EnumLiteGenerator();
+
+ void Generate(io::Printer* printer);
+
+ private:
+ const EnumDescriptor* descriptor_;
+
+ // The proto language allows multiple enum constants to have the same
+ // numeric value. Java, however, does not allow multiple enum constants to
+ // be considered equivalent. We treat the first defined constant for any
+ // given numeric value as "canonical" and the rest as aliases of that
+ // canonical value.
+ std::vector<const EnumValueDescriptor*> canonical_values_;
+
+ struct Alias {
+ const EnumValueDescriptor* value;
+ const EnumValueDescriptor* canonical_value;
+ };
+ std::vector<Alias> aliases_;
+
+ bool immutable_api_;
+
+ Context* context_;
+ ClassNameResolver* name_resolver_;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumLiteGenerator);
+};
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_ENUM_LITE_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_extension.cc b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_extension.cc
new file mode 100644
index 00000000..d45fd9c1
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_extension.cc
@@ -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.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <compiler/java/java_extension.h>
+
+#include <compiler/java/java_context.h>
+#include <compiler/java/java_doc_comment.h>
+#include <compiler/java/java_helpers.h>
+#include <compiler/java/java_name_resolver.h>
+#include <io/printer.h>
+#include <stubs/strutil.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+ImmutableExtensionGenerator::ImmutableExtensionGenerator(
+ const FieldDescriptor* descriptor, Context* context)
+ : descriptor_(descriptor), name_resolver_(context->GetNameResolver()) {
+ if (descriptor_->extension_scope() != NULL) {
+ scope_ =
+ name_resolver_->GetImmutableClassName(descriptor_->extension_scope());
+ } else {
+ scope_ = name_resolver_->GetImmutableClassName(descriptor_->file());
+ }
+}
+
+ImmutableExtensionGenerator::~ImmutableExtensionGenerator() {}
+
+// Initializes the vars referenced in the generated code templates.
+void ExtensionGenerator::InitTemplateVars(
+ const FieldDescriptor* descriptor, const std::string& scope, bool immutable,
+ ClassNameResolver* name_resolver,
+ std::map<std::string, std::string>* vars_pointer) {
+ std::map<std::string, std::string>& vars = *vars_pointer;
+ vars["scope"] = scope;
+ vars["name"] = UnderscoresToCamelCaseCheckReserved(descriptor);
+ vars["containing_type"] =
+ name_resolver->GetClassName(descriptor->containing_type(), immutable);
+ vars["number"] = StrCat(descriptor->number());
+ vars["constant_name"] = FieldConstantName(descriptor);
+ vars["index"] = StrCat(descriptor->index());
+ vars["default"] = descriptor->is_repeated()
+ ? ""
+ : DefaultValue(descriptor, immutable, name_resolver);
+ vars["type_constant"] = FieldTypeName(GetType(descriptor));
+ vars["packed"] = descriptor->is_packed() ? "true" : "false";
+ vars["enum_map"] = "null";
+ vars["prototype"] = "null";
+
+ JavaType java_type = GetJavaType(descriptor);
+ std::string singular_type;
+ switch (java_type) {
+ case JAVATYPE_MESSAGE:
+ singular_type =
+ name_resolver->GetClassName(descriptor->message_type(), immutable);
+ vars["prototype"] = singular_type + ".getDefaultInstance()";
+ break;
+ case JAVATYPE_ENUM:
+ singular_type =
+ name_resolver->GetClassName(descriptor->enum_type(), immutable);
+ vars["enum_map"] = singular_type + ".internalGetValueMap()";
+ break;
+ case JAVATYPE_STRING:
+ singular_type = "java.lang.String";
+ break;
+ case JAVATYPE_BYTES:
+ singular_type = immutable ? "com.google.protobuf.ByteString" : "byte[]";
+ break;
+ default:
+ singular_type = BoxedPrimitiveTypeName(java_type);
+ break;
+ }
+ vars["type"] = descriptor->is_repeated()
+ ? "java.util.List<" + singular_type + ">"
+ : singular_type;
+ vars["singular_type"] = singular_type;
+}
+
+void ImmutableExtensionGenerator::Generate(io::Printer* printer) {
+ std::map<std::string, std::string> vars;
+ const bool kUseImmutableNames = true;
+ InitTemplateVars(descriptor_, scope_, kUseImmutableNames, name_resolver_,
+ &vars);
+ printer->Print(vars, "public static final int $constant_name$ = $number$;\n");
+
+ WriteFieldDocComment(printer, descriptor_);
+ if (descriptor_->extension_scope() == NULL) {
+ // Non-nested
+ printer->Print(
+ vars,
+ "public static final\n"
+ " com.google.protobuf.GeneratedMessage.GeneratedExtension<\n"
+ " $containing_type$,\n"
+ " $type$> $name$ = com.google.protobuf.GeneratedMessage\n"
+ " .newFileScopedGeneratedExtension(\n"
+ " $singular_type$.class,\n"
+ " $prototype$);\n");
+ } else {
+ // Nested
+ printer->Print(
+ vars,
+ "public static final\n"
+ " com.google.protobuf.GeneratedMessage.GeneratedExtension<\n"
+ " $containing_type$,\n"
+ " $type$> $name$ = com.google.protobuf.GeneratedMessage\n"
+ " .newMessageScopedGeneratedExtension(\n"
+ " $scope$.getDefaultInstance(),\n"
+ " $index$,\n"
+ " $singular_type$.class,\n"
+ " $prototype$);\n");
+ }
+ printer->Annotate("name", descriptor_);
+}
+
+int ImmutableExtensionGenerator::GenerateNonNestedInitializationCode(
+ io::Printer* printer) {
+ int bytecode_estimate = 0;
+ if (descriptor_->extension_scope() == NULL) {
+ // Only applies to non-nested extensions.
+ printer->Print(
+ "$name$.internalInit(descriptor.getExtensions().get($index$));\n",
+ "name", UnderscoresToCamelCaseCheckReserved(descriptor_), "index",
+ StrCat(descriptor_->index()));
+ bytecode_estimate += 21;
+ }
+ return bytecode_estimate;
+}
+
+int ImmutableExtensionGenerator::GenerateRegistrationCode(
+ io::Printer* printer) {
+ printer->Print("registry.add($scope$.$name$);\n", "scope", scope_, "name",
+ UnderscoresToCamelCaseCheckReserved(descriptor_));
+ return 7;
+}
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_extension.h b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_extension.h
new file mode 100644
index 00000000..823190d7
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_extension.h
@@ -0,0 +1,115 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 GOOGLE_PROTOBUF_COMPILER_JAVA_EXTENSION_H__
+#define GOOGLE_PROTOBUF_COMPILER_JAVA_EXTENSION_H__
+
+#include <map>
+#include <string>
+
+#include <stubs/common.h>
+
+namespace google {
+namespace protobuf {
+class FieldDescriptor; // descriptor.h
+namespace compiler {
+namespace java {
+class Context; // context.h
+class ClassNameResolver; // name_resolver.h
+} // namespace java
+} // namespace compiler
+namespace io {
+class Printer; // printer.h
+}
+} // namespace protobuf
+} // namespace google
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+// Generates code for an extension, which may be within the scope of some
+// message or may be at file scope. This is much simpler than FieldGenerator
+// since extensions are just simple identifiers with interesting types.
+class ExtensionGenerator {
+ public:
+ explicit ExtensionGenerator() {}
+ virtual ~ExtensionGenerator() {}
+
+ virtual void Generate(io::Printer* printer) = 0;
+
+ // Returns an estimate of the number of bytes the printed code will compile
+ // to
+ virtual int GenerateNonNestedInitializationCode(io::Printer* printer) = 0;
+
+ // Returns an estimate of the number of bytes the printed code will compile
+ // to
+ virtual int GenerateRegistrationCode(io::Printer* printer) = 0;
+
+ protected:
+ static void InitTemplateVars(
+ const FieldDescriptor* descriptor, const std::string& scope,
+ bool immutable, ClassNameResolver* name_resolver,
+ std::map<std::string, std::string>* vars_pointer);
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ExtensionGenerator);
+};
+
+class ImmutableExtensionGenerator : public ExtensionGenerator {
+ public:
+ explicit ImmutableExtensionGenerator(const FieldDescriptor* descriptor,
+ Context* context);
+ virtual ~ImmutableExtensionGenerator();
+
+ void Generate(io::Printer* printer) override;
+ int GenerateNonNestedInitializationCode(io::Printer* printer) override;
+ int GenerateRegistrationCode(io::Printer* printer) override;
+
+ protected:
+ const FieldDescriptor* descriptor_;
+ ClassNameResolver* name_resolver_;
+ std::string scope_;
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableExtensionGenerator);
+};
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_EXTENSION_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_extension_lite.cc b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_extension_lite.cc
new file mode 100644
index 00000000..cf1975a0
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_extension_lite.cc
@@ -0,0 +1,115 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 <compiler/java/java_extension_lite.h>
+
+#include <compiler/java/java_context.h>
+#include <compiler/java/java_doc_comment.h>
+#include <compiler/java/java_helpers.h>
+#include <compiler/java/java_name_resolver.h>
+#include <io/printer.h>
+#include <stubs/strutil.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+ImmutableExtensionLiteGenerator::ImmutableExtensionLiteGenerator(
+ const FieldDescriptor* descriptor, Context* context)
+ : descriptor_(descriptor), name_resolver_(context->GetNameResolver()) {
+ if (descriptor_->extension_scope() != NULL) {
+ scope_ =
+ name_resolver_->GetImmutableClassName(descriptor_->extension_scope());
+ } else {
+ scope_ = name_resolver_->GetImmutableClassName(descriptor_->file());
+ }
+}
+
+ImmutableExtensionLiteGenerator::~ImmutableExtensionLiteGenerator() {}
+
+void ImmutableExtensionLiteGenerator::Generate(io::Printer* printer) {
+ std::map<std::string, std::string> vars;
+ const bool kUseImmutableNames = true;
+ InitTemplateVars(descriptor_, scope_, kUseImmutableNames, name_resolver_,
+ &vars);
+ printer->Print(vars, "public static final int $constant_name$ = $number$;\n");
+
+ WriteFieldDocComment(printer, descriptor_);
+ if (descriptor_->is_repeated()) {
+ printer->Print(
+ vars,
+ "public static final\n"
+ " com.google.protobuf.GeneratedMessageLite.GeneratedExtension<\n"
+ " $containing_type$,\n"
+ " $type$> $name$ = com.google.protobuf.GeneratedMessageLite\n"
+ " .newRepeatedGeneratedExtension(\n"
+ " $containing_type$.getDefaultInstance(),\n"
+ " $prototype$,\n"
+ " $enum_map$,\n"
+ " $number$,\n"
+ " com.google.protobuf.WireFormat.FieldType.$type_constant$,\n"
+ " $packed$,\n"
+ " $singular_type$.class);\n");
+ } else {
+ printer->Print(
+ vars,
+ "public static final\n"
+ " com.google.protobuf.GeneratedMessageLite.GeneratedExtension<\n"
+ " $containing_type$,\n"
+ " $type$> $name$ = com.google.protobuf.GeneratedMessageLite\n"
+ " .newSingularGeneratedExtension(\n"
+ " $containing_type$.getDefaultInstance(),\n"
+ " $default$,\n"
+ " $prototype$,\n"
+ " $enum_map$,\n"
+ " $number$,\n"
+ " com.google.protobuf.WireFormat.FieldType.$type_constant$,\n"
+ " $singular_type$.class);\n");
+ }
+ printer->Annotate("name", descriptor_);
+}
+
+int ImmutableExtensionLiteGenerator::GenerateNonNestedInitializationCode(
+ io::Printer* printer) {
+ return 0;
+}
+
+int ImmutableExtensionLiteGenerator::GenerateRegistrationCode(
+ io::Printer* printer) {
+ printer->Print("registry.add($scope$.$name$);\n", "scope", scope_, "name",
+ UnderscoresToCamelCaseCheckReserved(descriptor_));
+ return 7;
+}
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_extension_lite.h b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_extension_lite.h
new file mode 100644
index 00000000..0e38079f
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_extension_lite.h
@@ -0,0 +1,75 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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_COMPILER_JAVA_EXTENSION_LITE_H__
+#define GOOGLE_PROTOBUF_COMPILER_JAVA_EXTENSION_LITE_H__
+
+#include <map>
+#include <string>
+
+#include <stubs/common.h>
+#include <compiler/java/java_extension.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+// Generates code for a lite extension, which may be within the scope of some
+// message or may be at file scope. This is much simpler than FieldGenerator
+// since extensions are just simple identifiers with interesting types.
+class ImmutableExtensionLiteGenerator : public ExtensionGenerator {
+ public:
+ explicit ImmutableExtensionLiteGenerator(const FieldDescriptor* descriptor,
+ Context* context);
+ virtual ~ImmutableExtensionLiteGenerator();
+
+ void Generate(io::Printer* printer) override;
+
+ // Returns an estimate of the number of bytes the printed code will compile to
+ int GenerateNonNestedInitializationCode(io::Printer* printer) override;
+
+ // Returns an estimate of the number of bytes the printed code will compile to
+ int GenerateRegistrationCode(io::Printer* printer) override;
+
+ private:
+ const FieldDescriptor* descriptor_;
+ ClassNameResolver* name_resolver_;
+ std::string scope_;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableExtensionLiteGenerator);
+};
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_EXTENSION_LITE_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_field.cc b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_field.cc
new file mode 100644
index 00000000..5da51b22
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_field.cc
@@ -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.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <compiler/java/java_field.h>
+
+#include <memory>
+
+#include <stubs/logging.h>
+#include <stubs/common.h>
+#include <compiler/java/java_context.h>
+#include <compiler/java/java_enum_field.h>
+#include <compiler/java/java_enum_field_lite.h>
+#include <compiler/java/java_helpers.h>
+#include <compiler/java/java_map_field.h>
+#include <compiler/java/java_map_field_lite.h>
+#include <compiler/java/java_message_field.h>
+#include <compiler/java/java_message_field_lite.h>
+#include <compiler/java/java_primitive_field.h>
+#include <compiler/java/java_primitive_field_lite.h>
+#include <compiler/java/java_string_field.h>
+#include <compiler/java/java_string_field_lite.h>
+#include <io/printer.h>
+#include <stubs/strutil.h>
+#include <stubs/substitute.h>
+
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+namespace {
+
+ImmutableFieldGenerator* MakeImmutableGenerator(const FieldDescriptor* field,
+ int messageBitIndex,
+ int builderBitIndex,
+ Context* context) {
+ if (field->is_repeated()) {
+ switch (GetJavaType(field)) {
+ case JAVATYPE_MESSAGE:
+ if (IsMapEntry(field->message_type())) {
+ return new ImmutableMapFieldGenerator(field, messageBitIndex,
+ builderBitIndex, context);
+ } else {
+ return new RepeatedImmutableMessageFieldGenerator(
+ field, messageBitIndex, builderBitIndex, context);
+ }
+ case JAVATYPE_ENUM:
+ return new RepeatedImmutableEnumFieldGenerator(
+ field, messageBitIndex, builderBitIndex, context);
+ case JAVATYPE_STRING:
+ return new RepeatedImmutableStringFieldGenerator(
+ field, messageBitIndex, builderBitIndex, context);
+ default:
+ return new RepeatedImmutablePrimitiveFieldGenerator(
+ field, messageBitIndex, builderBitIndex, context);
+ }
+ } else {
+ if (IsRealOneof(field)) {
+ switch (GetJavaType(field)) {
+ case JAVATYPE_MESSAGE:
+ return new ImmutableMessageOneofFieldGenerator(
+ field, messageBitIndex, builderBitIndex, context);
+ case JAVATYPE_ENUM:
+ return new ImmutableEnumOneofFieldGenerator(field, messageBitIndex,
+ builderBitIndex, context);
+ case JAVATYPE_STRING:
+ return new ImmutableStringOneofFieldGenerator(
+ field, messageBitIndex, builderBitIndex, context);
+ default:
+ return new ImmutablePrimitiveOneofFieldGenerator(
+ field, messageBitIndex, builderBitIndex, context);
+ }
+ } else {
+ switch (GetJavaType(field)) {
+ case JAVATYPE_MESSAGE:
+ return new ImmutableMessageFieldGenerator(field, messageBitIndex,
+ builderBitIndex, context);
+ case JAVATYPE_ENUM:
+ return new ImmutableEnumFieldGenerator(field, messageBitIndex,
+ builderBitIndex, context);
+ case JAVATYPE_STRING:
+ return new ImmutableStringFieldGenerator(field, messageBitIndex,
+ builderBitIndex, context);
+ default:
+ return new ImmutablePrimitiveFieldGenerator(field, messageBitIndex,
+ builderBitIndex, context);
+ }
+ }
+ }
+}
+
+ImmutableFieldLiteGenerator* MakeImmutableLiteGenerator(
+ const FieldDescriptor* field, int messageBitIndex, Context* context) {
+ if (field->is_repeated()) {
+ switch (GetJavaType(field)) {
+ case JAVATYPE_MESSAGE:
+ if (IsMapEntry(field->message_type())) {
+ return new ImmutableMapFieldLiteGenerator(field, messageBitIndex,
+ context);
+ } else {
+ return new RepeatedImmutableMessageFieldLiteGenerator(
+ field, messageBitIndex, context);
+ }
+ case JAVATYPE_ENUM:
+ return new RepeatedImmutableEnumFieldLiteGenerator(
+ field, messageBitIndex, context);
+ case JAVATYPE_STRING:
+ return new RepeatedImmutableStringFieldLiteGenerator(
+ field, messageBitIndex, context);
+ default:
+ return new RepeatedImmutablePrimitiveFieldLiteGenerator(
+ field, messageBitIndex, context);
+ }
+ } else {
+ if (IsRealOneof(field)) {
+ switch (GetJavaType(field)) {
+ case JAVATYPE_MESSAGE:
+ return new ImmutableMessageOneofFieldLiteGenerator(
+ field, messageBitIndex, context);
+ case JAVATYPE_ENUM:
+ return new ImmutableEnumOneofFieldLiteGenerator(
+ field, messageBitIndex, context);
+ case JAVATYPE_STRING:
+ return new ImmutableStringOneofFieldLiteGenerator(
+ field, messageBitIndex, context);
+ default:
+ return new ImmutablePrimitiveOneofFieldLiteGenerator(
+ field, messageBitIndex, context);
+ }
+ } else {
+ switch (GetJavaType(field)) {
+ case JAVATYPE_MESSAGE:
+ return new ImmutableMessageFieldLiteGenerator(field, messageBitIndex,
+ context);
+ case JAVATYPE_ENUM:
+ return new ImmutableEnumFieldLiteGenerator(field, messageBitIndex,
+ context);
+ case JAVATYPE_STRING:
+ return new ImmutableStringFieldLiteGenerator(field, messageBitIndex,
+ context);
+ default:
+ return new ImmutablePrimitiveFieldLiteGenerator(
+ field, messageBitIndex, context);
+ }
+ }
+ }
+}
+
+
+static inline void ReportUnexpectedPackedFieldsCall(io::Printer* printer) {
+ // Reaching here indicates a bug. Cases are:
+ // - This FieldGenerator should support packing,
+ // but this method should be overridden.
+ // - This FieldGenerator doesn't support packing, and this method
+ // should never have been called.
+ GOOGLE_LOG(FATAL) << "GenerateParsingCodeFromPacked() "
+ << "called on field generator that does not support packing.";
+}
+
+} // namespace
+
+ImmutableFieldGenerator::~ImmutableFieldGenerator() {}
+
+void ImmutableFieldGenerator::GenerateParsingCodeFromPacked(
+ io::Printer* printer) const {
+ ReportUnexpectedPackedFieldsCall(printer);
+}
+
+ImmutableFieldLiteGenerator::~ImmutableFieldLiteGenerator() {}
+
+// ===================================================================
+
+template <>
+FieldGeneratorMap<ImmutableFieldGenerator>::FieldGeneratorMap(
+ const Descriptor* descriptor, Context* context)
+ : descriptor_(descriptor), field_generators_(descriptor->field_count()) {
+ // Construct all the FieldGenerators and assign them bit indices for their
+ // bit fields.
+ int messageBitIndex = 0;
+ int builderBitIndex = 0;
+ for (int i = 0; i < descriptor->field_count(); i++) {
+ ImmutableFieldGenerator* generator = MakeImmutableGenerator(
+ descriptor->field(i), messageBitIndex, builderBitIndex, context);
+ field_generators_[i].reset(generator);
+ messageBitIndex += generator->GetNumBitsForMessage();
+ builderBitIndex += generator->GetNumBitsForBuilder();
+ }
+}
+
+template <>
+FieldGeneratorMap<ImmutableFieldGenerator>::~FieldGeneratorMap() {}
+
+template <>
+FieldGeneratorMap<ImmutableFieldLiteGenerator>::FieldGeneratorMap(
+ const Descriptor* descriptor, Context* context)
+ : descriptor_(descriptor), field_generators_(descriptor->field_count()) {
+ // Construct all the FieldGenerators and assign them bit indices for their
+ // bit fields.
+ int messageBitIndex = 0;
+ for (int i = 0; i < descriptor->field_count(); i++) {
+ ImmutableFieldLiteGenerator* generator = MakeImmutableLiteGenerator(
+ descriptor->field(i), messageBitIndex, context);
+ field_generators_[i].reset(generator);
+ messageBitIndex += generator->GetNumBitsForMessage();
+ }
+}
+
+template <>
+FieldGeneratorMap<ImmutableFieldLiteGenerator>::~FieldGeneratorMap() {}
+
+
+void SetCommonFieldVariables(const FieldDescriptor* descriptor,
+ const FieldGeneratorInfo* info,
+ std::map<std::string, std::string>* variables) {
+ (*variables)["field_name"] = descriptor->name();
+ (*variables)["name"] = info->name;
+ (*variables)["classname"] = descriptor->containing_type()->name();
+ (*variables)["capitalized_name"] = info->capitalized_name;
+ (*variables)["disambiguated_reason"] = info->disambiguated_reason;
+ (*variables)["constant_name"] = FieldConstantName(descriptor);
+ (*variables)["number"] = StrCat(descriptor->number());
+ (*variables)["kt_dsl_builder"] = "_builder";
+ // These variables are placeholders to pick out the beginning and ends of
+ // identifiers for annotations (when doing so with existing variables would
+ // be ambiguous or impossible). They should never be set to anything but the
+ // empty string.
+ (*variables)["{"] = "";
+ (*variables)["}"] = "";
+ (*variables)["kt_name"] =
+ IsForbiddenKotlin(info->name) ? info->name + "_" : info->name;
+ (*variables)["kt_capitalized_name"] = IsForbiddenKotlin(info->name)
+ ? info->capitalized_name + "_"
+ : info->capitalized_name;
+ if (!descriptor->is_repeated()) {
+ (*variables)["annotation_field_type"] = FieldTypeName(descriptor->type());
+ } else if (GetJavaType(descriptor) == JAVATYPE_MESSAGE &&
+ IsMapEntry(descriptor->message_type())) {
+ (*variables)["annotation_field_type"] =
+ std::string(FieldTypeName(descriptor->type())) + "MAP";
+ } else {
+ (*variables)["annotation_field_type"] =
+ std::string(FieldTypeName(descriptor->type())) + "_LIST";
+ if (descriptor->is_packed()) {
+ (*variables)["annotation_field_type"] =
+ (*variables)["annotation_field_type"] + "_PACKED";
+ }
+ }
+}
+
+void SetCommonOneofVariables(const FieldDescriptor* descriptor,
+ const OneofGeneratorInfo* info,
+ std::map<std::string, std::string>* variables) {
+ (*variables)["oneof_name"] = info->name;
+ (*variables)["oneof_capitalized_name"] = info->capitalized_name;
+ (*variables)["oneof_index"] =
+ StrCat(descriptor->containing_oneof()->index());
+ (*variables)["oneof_stored_type"] = GetOneofStoredType(descriptor);
+ (*variables)["set_oneof_case_message"] =
+ info->name + "Case_ = " + StrCat(descriptor->number());
+ (*variables)["clear_oneof_case_message"] = info->name + "Case_ = 0";
+ (*variables)["has_oneof_case_message"] =
+ info->name + "Case_ == " + StrCat(descriptor->number());
+}
+
+void PrintExtraFieldInfo(const std::map<std::string, std::string>& variables,
+ io::Printer* printer) {
+ const std::map<std::string, std::string>::const_iterator it =
+ variables.find("disambiguated_reason");
+ if (it != variables.end() && !it->second.empty()) {
+ printer->Print(
+ variables,
+ "// An alternative name is used for field \"$field_name$\" because:\n"
+ "// $disambiguated_reason$\n");
+ }
+}
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_field.h b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_field.h
new file mode 100644
index 00000000..d010faac
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_field.h
@@ -0,0 +1,191 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 GOOGLE_PROTOBUF_COMPILER_JAVA_FIELD_H__
+#define GOOGLE_PROTOBUF_COMPILER_JAVA_FIELD_H__
+
+#include <cstdint>
+#include <map>
+#include <memory>
+#include <string>
+
+#include <stubs/logging.h>
+#include <stubs/common.h>
+#include <descriptor.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+class Context; // context.h
+class ClassNameResolver; // name_resolver.h
+} // namespace java
+} // namespace compiler
+namespace io {
+class Printer; // printer.h
+}
+} // namespace protobuf
+} // namespace google
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+class ImmutableFieldGenerator {
+ public:
+ ImmutableFieldGenerator() {}
+ virtual ~ImmutableFieldGenerator();
+
+ virtual int GetNumBitsForMessage() const = 0;
+ virtual int GetNumBitsForBuilder() const = 0;
+ virtual void GenerateInterfaceMembers(io::Printer* printer) const = 0;
+ virtual void GenerateMembers(io::Printer* printer) const = 0;
+ virtual void GenerateBuilderMembers(io::Printer* printer) const = 0;
+ virtual void GenerateInitializationCode(io::Printer* printer) const = 0;
+ virtual void GenerateBuilderClearCode(io::Printer* printer) const = 0;
+ virtual void GenerateMergingCode(io::Printer* printer) const = 0;
+ virtual void GenerateBuildingCode(io::Printer* printer) const = 0;
+ virtual void GenerateParsingCode(io::Printer* printer) const = 0;
+ virtual void GenerateParsingCodeFromPacked(io::Printer* printer) const;
+ virtual void GenerateParsingDoneCode(io::Printer* printer) const = 0;
+ virtual void GenerateSerializationCode(io::Printer* printer) const = 0;
+ virtual void GenerateSerializedSizeCode(io::Printer* printer) const = 0;
+ virtual void GenerateFieldBuilderInitializationCode(
+ io::Printer* printer) const = 0;
+ virtual void GenerateKotlinDslMembers(io::Printer* printer) const = 0;
+
+ virtual void GenerateEqualsCode(io::Printer* printer) const = 0;
+ virtual void GenerateHashCode(io::Printer* printer) const = 0;
+
+ virtual std::string GetBoxedType() const = 0;
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableFieldGenerator);
+};
+
+class ImmutableFieldLiteGenerator {
+ public:
+ ImmutableFieldLiteGenerator() {}
+ virtual ~ImmutableFieldLiteGenerator();
+
+ virtual int GetNumBitsForMessage() const = 0;
+ virtual void GenerateInterfaceMembers(io::Printer* printer) const = 0;
+ virtual void GenerateMembers(io::Printer* printer) const = 0;
+ virtual void GenerateBuilderMembers(io::Printer* printer) const = 0;
+ virtual void GenerateInitializationCode(io::Printer* printer) const = 0;
+ virtual void GenerateFieldInfo(io::Printer* printer,
+ std::vector<uint16_t>* output) const = 0;
+ virtual void GenerateKotlinDslMembers(io::Printer* printer) const = 0;
+
+ virtual std::string GetBoxedType() const = 0;
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableFieldLiteGenerator);
+};
+
+
+// Convenience class which constructs FieldGenerators for a Descriptor.
+template <typename FieldGeneratorType>
+class FieldGeneratorMap {
+ public:
+ explicit FieldGeneratorMap(const Descriptor* descriptor, Context* context);
+ ~FieldGeneratorMap();
+
+ const FieldGeneratorType& get(const FieldDescriptor* field) const;
+
+ private:
+ const Descriptor* descriptor_;
+ std::vector<std::unique_ptr<FieldGeneratorType>> field_generators_;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldGeneratorMap);
+};
+
+template <typename FieldGeneratorType>
+inline const FieldGeneratorType& FieldGeneratorMap<FieldGeneratorType>::get(
+ const FieldDescriptor* field) const {
+ GOOGLE_CHECK_EQ(field->containing_type(), descriptor_);
+ return *field_generators_[field->index()];
+}
+
+// Instantiate template for mutable and immutable maps.
+template <>
+FieldGeneratorMap<ImmutableFieldGenerator>::FieldGeneratorMap(
+ const Descriptor* descriptor, Context* context);
+
+template <>
+FieldGeneratorMap<ImmutableFieldGenerator>::~FieldGeneratorMap();
+
+
+template <>
+FieldGeneratorMap<ImmutableFieldLiteGenerator>::FieldGeneratorMap(
+ const Descriptor* descriptor, Context* context);
+
+template <>
+FieldGeneratorMap<ImmutableFieldLiteGenerator>::~FieldGeneratorMap();
+
+
+// Field information used in FieldGeneartors.
+struct FieldGeneratorInfo {
+ std::string name;
+ std::string capitalized_name;
+ std::string disambiguated_reason;
+};
+
+// Oneof information used in OneofFieldGenerators.
+struct OneofGeneratorInfo {
+ std::string name;
+ std::string capitalized_name;
+};
+
+// Set some common variables used in variable FieldGenerators.
+void SetCommonFieldVariables(const FieldDescriptor* descriptor,
+ const FieldGeneratorInfo* info,
+ std::map<std::string, std::string>* variables);
+
+// Set some common oneof variables used in OneofFieldGenerators.
+void SetCommonOneofVariables(const FieldDescriptor* descriptor,
+ const OneofGeneratorInfo* info,
+ std::map<std::string, std::string>* variables);
+
+// Print useful comments before a field's accessors.
+void PrintExtraFieldInfo(const std::map<std::string, std::string>& variables,
+ io::Printer* printer);
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_FIELD_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_file.cc b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_file.cc
new file mode 100644
index 00000000..71a49ed4
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_file.cc
@@ -0,0 +1,734 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 <compiler/java/java_file.h>
+
+#include <memory>
+#include <set>
+
+#include <compiler/java/java_context.h>
+#include <compiler/java/java_enum.h>
+#include <compiler/java/java_enum_lite.h>
+#include <compiler/java/java_extension.h>
+#include <compiler/java/java_generator_factory.h>
+#include <compiler/java/java_helpers.h>
+#include <compiler/java/java_message.h>
+#include <compiler/java/java_name_resolver.h>
+#include <compiler/java/java_service.h>
+#include <compiler/java/java_shared_code_generator.h>
+#include <compiler/code_generator.h>
+#include <descriptor.pb.h>
+#include <io/printer.h>
+#include <io/zero_copy_stream.h>
+#include <dynamic_message.h>
+#include <stubs/strutil.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+namespace {
+
+struct FieldDescriptorCompare {
+ bool operator()(const FieldDescriptor* f1, const FieldDescriptor* f2) const {
+ if (f1 == NULL) {
+ return false;
+ }
+ if (f2 == NULL) {
+ return true;
+ }
+ return f1->full_name() < f2->full_name();
+ }
+};
+
+typedef std::set<const FieldDescriptor*, FieldDescriptorCompare>
+ FieldDescriptorSet;
+
+// Recursively searches the given message to collect extensions.
+// Returns true if all the extensions can be recognized. The extensions will be
+// appended in to the extensions parameter.
+// Returns false when there are unknown fields, in which case the data in the
+// extensions output parameter is not reliable and should be discarded.
+bool CollectExtensions(const Message& message, FieldDescriptorSet* extensions) {
+ const Reflection* reflection = message.GetReflection();
+
+ // There are unknown fields that could be extensions, thus this call fails.
+ if (reflection->GetUnknownFields(message).field_count() > 0) return false;
+
+ std::vector<const FieldDescriptor*> fields;
+ reflection->ListFields(message, &fields);
+
+ for (int i = 0; i < fields.size(); i++) {
+ if (fields[i]->is_extension()) {
+ extensions->insert(fields[i]);
+ }
+
+ if (GetJavaType(fields[i]) == JAVATYPE_MESSAGE) {
+ if (fields[i]->is_repeated()) {
+ int size = reflection->FieldSize(message, fields[i]);
+ for (int j = 0; j < size; j++) {
+ const Message& sub_message =
+ reflection->GetRepeatedMessage(message, fields[i], j);
+ if (!CollectExtensions(sub_message, extensions)) return false;
+ }
+ } else {
+ const Message& sub_message = reflection->GetMessage(message, fields[i]);
+ if (!CollectExtensions(sub_message, extensions)) return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+// Finds all extensions in the given message and its sub-messages. If the
+// message contains unknown fields (which could be extensions), then those
+// extensions are defined in alternate_pool.
+// The message will be converted to a DynamicMessage backed by alternate_pool
+// in order to handle this case.
+void CollectExtensions(const FileDescriptorProto& file_proto,
+ const DescriptorPool& alternate_pool,
+ FieldDescriptorSet* extensions,
+ const std::string& file_data) {
+ if (!CollectExtensions(file_proto, extensions)) {
+ // There are unknown fields in the file_proto, which are probably
+ // extensions. We need to parse the data into a dynamic message based on the
+ // builder-pool to find out all extensions.
+ const Descriptor* file_proto_desc = alternate_pool.FindMessageTypeByName(
+ file_proto.GetDescriptor()->full_name());
+ GOOGLE_CHECK(file_proto_desc)
+ << "Find unknown fields in FileDescriptorProto when building "
+ << file_proto.name()
+ << ". It's likely that those fields are custom options, however, "
+ "descriptor.proto is not in the transitive dependencies. "
+ "This normally should not happen. Please report a bug.";
+ DynamicMessageFactory factory;
+ std::unique_ptr<Message> dynamic_file_proto(
+ factory.GetPrototype(file_proto_desc)->New());
+ GOOGLE_CHECK(dynamic_file_proto.get() != NULL);
+ GOOGLE_CHECK(dynamic_file_proto->ParseFromString(file_data));
+
+ // Collect the extensions again from the dynamic message. There should be no
+ // more unknown fields this time, i.e. all the custom options should be
+ // parsed as extensions now.
+ extensions->clear();
+ GOOGLE_CHECK(CollectExtensions(*dynamic_file_proto, extensions))
+ << "Find unknown fields in FileDescriptorProto when building "
+ << file_proto.name()
+ << ". It's likely that those fields are custom options, however, "
+ "those options cannot be recognized in the builder pool. "
+ "This normally should not happen. Please report a bug.";
+ }
+}
+
+// Our static initialization methods can become very, very large.
+// So large that if we aren't careful we end up blowing the JVM's
+// 64K bytes of bytecode/method. Fortunately, since these static
+// methods are executed only once near the beginning of a program,
+// there's usually plenty of stack space available and we can
+// extend our methods by simply chaining them to another method
+// with a tail call. This inserts the sequence call-next-method,
+// end this one, begin-next-method as needed.
+void MaybeRestartJavaMethod(io::Printer* printer, int* bytecode_estimate,
+ int* method_num, const char* chain_statement,
+ const char* method_decl) {
+ // The goal here is to stay under 64K bytes of jvm bytecode/method,
+ // since otherwise we hit a hardcoded limit in the jvm and javac will
+ // then fail with the error "code too large". This limit lets our
+ // estimates be off by a factor of two and still we're okay.
+ static const int bytesPerMethod = kMaxStaticSize;
+
+ if ((*bytecode_estimate) > bytesPerMethod) {
+ ++(*method_num);
+ printer->Print(chain_statement, "method_num", StrCat(*method_num));
+ printer->Outdent();
+ printer->Print("}\n");
+ printer->Print(method_decl, "method_num", StrCat(*method_num));
+ printer->Indent();
+ *bytecode_estimate = 0;
+ }
+}
+} // namespace
+
+FileGenerator::FileGenerator(const FileDescriptor* file, const Options& options,
+ bool immutable_api)
+ : file_(file),
+ java_package_(FileJavaPackage(file, immutable_api)),
+ message_generators_(file->message_type_count()),
+ extension_generators_(file->extension_count()),
+ context_(new Context(file, options)),
+ name_resolver_(context_->GetNameResolver()),
+ options_(options),
+ immutable_api_(immutable_api) {
+ classname_ = name_resolver_->GetFileClassName(file, immutable_api);
+ generator_factory_.reset(new ImmutableGeneratorFactory(context_.get()));
+ for (int i = 0; i < file_->message_type_count(); ++i) {
+ message_generators_[i].reset(
+ generator_factory_->NewMessageGenerator(file_->message_type(i)));
+ }
+ for (int i = 0; i < file_->extension_count(); ++i) {
+ extension_generators_[i].reset(
+ generator_factory_->NewExtensionGenerator(file_->extension(i)));
+ }
+}
+
+FileGenerator::~FileGenerator() {}
+
+bool FileGenerator::Validate(std::string* error) {
+ // Check that no class name matches the file's class name. This is a common
+ // problem that leads to Java compile errors that can be hard to understand.
+ // It's especially bad when using the java_multiple_files, since we would
+ // end up overwriting the outer class with one of the inner ones.
+ if (name_resolver_->HasConflictingClassName(file_, classname_,
+ NameEquality::EXACT_EQUAL)) {
+ error->assign(file_->name());
+ error->append(
+ ": Cannot generate Java output because the file's outer class name, "
+ "\"");
+ error->append(classname_);
+ error->append(
+ "\", matches the name of one of the types declared inside it. "
+ "Please either rename the type or use the java_outer_classname "
+ "option to specify a different outer class name for the .proto file.");
+ return false;
+ }
+ // Similar to the check above, but ignore the case this time. This is not a
+ // problem on Linux, but will lead to Java compile errors on Windows / Mac
+ // because filenames are case-insensitive on those platforms.
+ if (name_resolver_->HasConflictingClassName(
+ file_, classname_, NameEquality::EQUAL_IGNORE_CASE)) {
+ GOOGLE_LOG(WARNING)
+ << file_->name() << ": The file's outer class name, \"" << classname_
+ << "\", matches the name of one of the types declared inside it when "
+ << "case is ignored. This can cause compilation issues on Windows / "
+ << "MacOS. Please either rename the type or use the "
+ << "java_outer_classname option to specify a different outer class "
+ << "name for the .proto file to be safe.";
+ }
+
+ // Print a warning if optimize_for = LITE_RUNTIME is used.
+ if (file_->options().optimize_for() == FileOptions::LITE_RUNTIME &&
+ !options_.enforce_lite) {
+ GOOGLE_LOG(WARNING)
+ << "The optimize_for = LITE_RUNTIME option is no longer supported by "
+ << "protobuf Java code generator and is ignored--protoc will always "
+ << "generate full runtime code for Java. To use Java Lite runtime, "
+ << "users should use the Java Lite plugin instead. See:\n"
+ << " "
+ "https://github.com/protocolbuffers/protobuf/blob/master/java/"
+ "lite.md";
+ }
+ return true;
+}
+
+void FileGenerator::Generate(io::Printer* printer) {
+ // We don't import anything because we refer to all classes by their
+ // fully-qualified names in the generated source.
+ printer->Print(
+ "// Generated by the protocol buffer compiler. DO NOT EDIT!\n"
+ "// source: $filename$\n"
+ "\n",
+ "filename", file_->name());
+ if (!java_package_.empty()) {
+ printer->Print(
+ "package $package$;\n"
+ "\n",
+ "package", java_package_);
+ }
+ PrintGeneratedAnnotation(
+ printer, '$', options_.annotate_code ? classname_ + ".java.pb.meta" : "");
+
+ printer->Print(
+ "$deprecation$public final class $classname$ {\n"
+ " private $ctor$() {}\n",
+ "deprecation",
+ file_->options().deprecated() ? "@java.lang.Deprecated " : "",
+ "classname", classname_, "ctor", classname_);
+ printer->Annotate("classname", file_->name());
+ printer->Indent();
+
+ // -----------------------------------------------------------------
+
+ printer->Print(
+ "public static void registerAllExtensions(\n"
+ " com.google.protobuf.ExtensionRegistryLite registry) {\n");
+
+ printer->Indent();
+
+ for (int i = 0; i < file_->extension_count(); i++) {
+ extension_generators_[i]->GenerateRegistrationCode(printer);
+ }
+
+ for (int i = 0; i < file_->message_type_count(); i++) {
+ message_generators_[i]->GenerateExtensionRegistrationCode(printer);
+ }
+
+ printer->Outdent();
+ printer->Print("}\n");
+ if (HasDescriptorMethods(file_, context_->EnforceLite())) {
+ // Overload registerAllExtensions for the non-lite usage to
+ // redundantly maintain the original signature (this is
+ // redundant because ExtensionRegistryLite now invokes
+ // ExtensionRegistry in the non-lite usage). Intent is
+ // to remove this in the future.
+ printer->Print(
+ "\n"
+ "public static void registerAllExtensions(\n"
+ " com.google.protobuf.ExtensionRegistry registry) {\n"
+ " registerAllExtensions(\n"
+ " (com.google.protobuf.ExtensionRegistryLite) registry);\n"
+ "}\n");
+ }
+
+ // -----------------------------------------------------------------
+
+ if (!MultipleJavaFiles(file_, immutable_api_)) {
+ for (int i = 0; i < file_->enum_type_count(); i++) {
+ if (HasDescriptorMethods(file_, context_->EnforceLite())) {
+ EnumGenerator(file_->enum_type(i), immutable_api_, context_.get())
+ .Generate(printer);
+ } else {
+ EnumLiteGenerator(file_->enum_type(i), immutable_api_, context_.get())
+ .Generate(printer);
+ }
+ }
+ for (int i = 0; i < file_->message_type_count(); i++) {
+ message_generators_[i]->GenerateInterface(printer);
+ message_generators_[i]->Generate(printer);
+ }
+ if (HasGenericServices(file_, context_->EnforceLite())) {
+ for (int i = 0; i < file_->service_count(); i++) {
+ std::unique_ptr<ServiceGenerator> generator(
+ generator_factory_->NewServiceGenerator(file_->service(i)));
+ generator->Generate(printer);
+ }
+ }
+ }
+
+ // Extensions must be generated in the outer class since they are values,
+ // not classes.
+ for (int i = 0; i < file_->extension_count(); i++) {
+ extension_generators_[i]->Generate(printer);
+ }
+
+ // Static variables. We'd like them to be final if possible, but due to
+ // the JVM's 64k size limit on static blocks, we have to initialize some
+ // of them in methods; thus they cannot be final.
+ int static_block_bytecode_estimate = 0;
+ for (int i = 0; i < file_->message_type_count(); i++) {
+ message_generators_[i]->GenerateStaticVariables(
+ printer, &static_block_bytecode_estimate);
+ }
+
+ printer->Print("\n");
+
+ if (HasDescriptorMethods(file_, context_->EnforceLite())) {
+ if (immutable_api_) {
+ GenerateDescriptorInitializationCodeForImmutable(printer);
+ } else {
+ GenerateDescriptorInitializationCodeForMutable(printer);
+ }
+ } else {
+ printer->Print("static {\n");
+ printer->Indent();
+ int bytecode_estimate = 0;
+ int method_num = 0;
+
+ for (int i = 0; i < file_->message_type_count(); i++) {
+ bytecode_estimate +=
+ message_generators_[i]->GenerateStaticVariableInitializers(printer);
+ MaybeRestartJavaMethod(
+ printer, &bytecode_estimate, &method_num,
+ "_clinit_autosplit_$method_num$();\n",
+ "private static void _clinit_autosplit_$method_num$() {\n");
+ }
+
+ printer->Outdent();
+ printer->Print("}\n");
+ }
+
+ printer->Print(
+ "\n"
+ "// @@protoc_insertion_point(outer_class_scope)\n");
+
+ printer->Outdent();
+ printer->Print("}\n");
+}
+
+void FileGenerator::GenerateDescriptorInitializationCodeForImmutable(
+ io::Printer* printer) {
+ printer->Print(
+ "public static com.google.protobuf.Descriptors.FileDescriptor\n"
+ " getDescriptor() {\n"
+ " return descriptor;\n"
+ "}\n"
+ "private static $final$ com.google.protobuf.Descriptors.FileDescriptor\n"
+ " descriptor;\n"
+ "static {\n",
+ // TODO(dweis): Mark this as final.
+ "final", "");
+ printer->Indent();
+
+ SharedCodeGenerator shared_code_generator(file_, options_);
+ shared_code_generator.GenerateDescriptors(printer);
+
+ int bytecode_estimate = 0;
+ int method_num = 0;
+
+ for (int i = 0; i < file_->message_type_count(); i++) {
+ bytecode_estimate +=
+ message_generators_[i]->GenerateStaticVariableInitializers(printer);
+ MaybeRestartJavaMethod(
+ printer, &bytecode_estimate, &method_num,
+ "_clinit_autosplit_dinit_$method_num$();\n",
+ "private static void _clinit_autosplit_dinit_$method_num$() {\n");
+ }
+ for (int i = 0; i < file_->extension_count(); i++) {
+ bytecode_estimate +=
+ extension_generators_[i]->GenerateNonNestedInitializationCode(printer);
+ MaybeRestartJavaMethod(
+ printer, &bytecode_estimate, &method_num,
+ "_clinit_autosplit_dinit_$method_num$();\n",
+ "private static void _clinit_autosplit_dinit_$method_num$() {\n");
+ }
+
+ // Proto compiler builds a DescriptorPool, which holds all the descriptors to
+ // generate, when processing the ".proto" files. We call this DescriptorPool
+ // the parsed pool (a.k.a. file_->pool()).
+ //
+ // Note that when users try to extend the (.*)DescriptorProto in their
+ // ".proto" files, it does not affect the pre-built FileDescriptorProto class
+ // in proto compiler. When we put the descriptor data in the file_proto, those
+ // extensions become unknown fields.
+ //
+ // Now we need to find out all the extension value to the (.*)DescriptorProto
+ // in the file_proto message, and prepare an ExtensionRegistry to return.
+ //
+ // To find those extensions, we need to parse the data into a dynamic message
+ // of the FileDescriptor based on the builder-pool, then we can use
+ // reflections to find all extension fields
+ FileDescriptorProto file_proto;
+ file_->CopyTo(&file_proto);
+ std::string file_data;
+ file_proto.SerializeToString(&file_data);
+ FieldDescriptorSet extensions;
+ CollectExtensions(file_proto, *file_->pool(), &extensions, file_data);
+
+ if (extensions.size() > 0) {
+ // Must construct an ExtensionRegistry containing all existing extensions
+ // and use it to parse the descriptor data again to recognize extensions.
+ printer->Print(
+ "com.google.protobuf.ExtensionRegistry registry =\n"
+ " com.google.protobuf.ExtensionRegistry.newInstance();\n");
+ FieldDescriptorSet::iterator it;
+ for (it = extensions.begin(); it != extensions.end(); it++) {
+ std::unique_ptr<ExtensionGenerator> generator(
+ generator_factory_->NewExtensionGenerator(*it));
+ bytecode_estimate += generator->GenerateRegistrationCode(printer);
+ MaybeRestartJavaMethod(
+ printer, &bytecode_estimate, &method_num,
+ "_clinit_autosplit_dinit_$method_num$(registry);\n",
+ "private static void _clinit_autosplit_dinit_$method_num$(\n"
+ " com.google.protobuf.ExtensionRegistry registry) {\n");
+ }
+ printer->Print(
+ "com.google.protobuf.Descriptors.FileDescriptor\n"
+ " .internalUpdateFileDescriptor(descriptor, registry);\n");
+ }
+
+ // Force descriptor initialization of all dependencies.
+ for (int i = 0; i < file_->dependency_count(); i++) {
+ if (ShouldIncludeDependency(file_->dependency(i), true)) {
+ std::string dependency =
+ name_resolver_->GetImmutableClassName(file_->dependency(i));
+ printer->Print("$dependency$.getDescriptor();\n", "dependency",
+ dependency);
+ }
+ }
+
+ printer->Outdent();
+ printer->Print("}\n");
+}
+
+void FileGenerator::GenerateDescriptorInitializationCodeForMutable(
+ io::Printer* printer) {
+ printer->Print(
+ "public static com.google.protobuf.Descriptors.FileDescriptor\n"
+ " getDescriptor() {\n"
+ " return descriptor;\n"
+ "}\n"
+ "private static final com.google.protobuf.Descriptors.FileDescriptor\n"
+ " descriptor;\n"
+ "static {\n");
+ printer->Indent();
+
+ printer->Print(
+ "descriptor = $immutable_package$.$descriptor_classname$.descriptor;\n",
+ "immutable_package", FileJavaPackage(file_, true), "descriptor_classname",
+ name_resolver_->GetDescriptorClassName(file_));
+
+ for (int i = 0; i < file_->message_type_count(); i++) {
+ message_generators_[i]->GenerateStaticVariableInitializers(printer);
+ }
+ for (int i = 0; i < file_->extension_count(); i++) {
+ extension_generators_[i]->GenerateNonNestedInitializationCode(printer);
+ }
+
+ // Check if custom options exist. If any, try to load immutable classes since
+ // custom options are only represented with immutable messages.
+ FileDescriptorProto file_proto;
+ file_->CopyTo(&file_proto);
+ std::string file_data;
+ file_proto.SerializeToString(&file_data);
+ FieldDescriptorSet extensions;
+ CollectExtensions(file_proto, *file_->pool(), &extensions, file_data);
+
+ if (extensions.size() > 0) {
+ // Try to load immutable messages' outer class. Its initialization code
+ // will take care of interpreting custom options.
+ printer->Print(
+ "try {\n"
+ // Note that we have to load the immutable class dynamically here as
+ // we want the mutable code to be independent from the immutable code
+ // at compile time. It is required to implement dual-compile for
+ // mutable and immutable API in blaze.
+ " java.lang.Class<?> immutableClass = java.lang.Class.forName(\n"
+ " \"$immutable_classname$\");\n"
+ "} catch (java.lang.ClassNotFoundException e) {\n",
+ "immutable_classname", name_resolver_->GetImmutableClassName(file_));
+ printer->Indent();
+
+ // The immutable class can not be found. We try our best to collect all
+ // custom option extensions to interpret the custom options.
+ printer->Print(
+ "com.google.protobuf.ExtensionRegistry registry =\n"
+ " com.google.protobuf.ExtensionRegistry.newInstance();\n"
+ "com.google.protobuf.MessageLite defaultExtensionInstance = null;\n");
+ FieldDescriptorSet::iterator it;
+ for (it = extensions.begin(); it != extensions.end(); it++) {
+ const FieldDescriptor* field = *it;
+ std::string scope;
+ if (field->extension_scope() != NULL) {
+ scope = name_resolver_->GetMutableClassName(field->extension_scope()) +
+ ".getDescriptor()";
+ } else {
+ scope = FileJavaPackage(field->file(), true) + "." +
+ name_resolver_->GetDescriptorClassName(field->file()) +
+ ".descriptor";
+ }
+ if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+ printer->Print(
+ "defaultExtensionInstance = com.google.protobuf.Internal\n"
+ " .getDefaultInstance(\"$class$\");\n"
+ "if (defaultExtensionInstance != null) {\n"
+ " registry.add(\n"
+ " $scope$.getExtensions().get($index$),\n"
+ " (com.google.protobuf.Message) defaultExtensionInstance);\n"
+ "}\n",
+ "scope", scope, "index", StrCat(field->index()), "class",
+ name_resolver_->GetImmutableClassName(field->message_type()));
+ } else {
+ printer->Print("registry.add($scope$.getExtensions().get($index$));\n",
+ "scope", scope, "index", StrCat(field->index()));
+ }
+ }
+ printer->Print(
+ "com.google.protobuf.Descriptors.FileDescriptor\n"
+ " .internalUpdateFileDescriptor(descriptor, registry);\n");
+
+ printer->Outdent();
+ printer->Print("}\n");
+ }
+
+ // Force descriptor initialization of all dependencies.
+ for (int i = 0; i < file_->dependency_count(); i++) {
+ if (ShouldIncludeDependency(file_->dependency(i), false)) {
+ std::string dependency =
+ name_resolver_->GetMutableClassName(file_->dependency(i));
+ printer->Print("$dependency$.getDescriptor();\n", "dependency",
+ dependency);
+ }
+ }
+
+ printer->Outdent();
+ printer->Print("}\n");
+}
+
+template <typename GeneratorClass, typename DescriptorClass>
+static void GenerateSibling(
+ const std::string& package_dir, const std::string& java_package,
+ const DescriptorClass* descriptor, GeneratorContext* context,
+ std::vector<std::string>* file_list, bool annotate_code,
+ std::vector<std::string>* annotation_list, const std::string& name_suffix,
+ GeneratorClass* generator,
+ void (GeneratorClass::*pfn)(io::Printer* printer)) {
+ std::string filename =
+ package_dir + descriptor->name() + name_suffix + ".java";
+ file_list->push_back(filename);
+ std::string info_full_path = filename + ".pb.meta";
+ GeneratedCodeInfo annotations;
+ io::AnnotationProtoCollector<GeneratedCodeInfo> annotation_collector(
+ &annotations);
+
+ std::unique_ptr<io::ZeroCopyOutputStream> output(context->Open(filename));
+ io::Printer printer(output.get(), '$',
+ annotate_code ? &annotation_collector : NULL);
+
+ printer.Print(
+ "// Generated by the protocol buffer compiler. DO NOT EDIT!\n"
+ "// source: $filename$\n"
+ "\n",
+ "filename", descriptor->file()->name());
+ if (!java_package.empty()) {
+ printer.Print(
+ "package $package$;\n"
+ "\n",
+ "package", java_package);
+ }
+
+ (generator->*pfn)(&printer);
+
+ if (annotate_code) {
+ std::unique_ptr<io::ZeroCopyOutputStream> info_output(
+ context->Open(info_full_path));
+ annotations.SerializeToZeroCopyStream(info_output.get());
+ annotation_list->push_back(info_full_path);
+ }
+}
+
+void FileGenerator::GenerateSiblings(
+ const std::string& package_dir, GeneratorContext* context,
+ std::vector<std::string>* file_list,
+ std::vector<std::string>* annotation_list) {
+ if (MultipleJavaFiles(file_, immutable_api_)) {
+ for (int i = 0; i < file_->enum_type_count(); i++) {
+ if (HasDescriptorMethods(file_, context_->EnforceLite())) {
+ EnumGenerator generator(file_->enum_type(i), immutable_api_,
+ context_.get());
+ GenerateSibling<EnumGenerator>(
+ package_dir, java_package_, file_->enum_type(i), context, file_list,
+ options_.annotate_code, annotation_list, "", &generator,
+ &EnumGenerator::Generate);
+ } else {
+ EnumLiteGenerator generator(file_->enum_type(i), immutable_api_,
+ context_.get());
+ GenerateSibling<EnumLiteGenerator>(
+ package_dir, java_package_, file_->enum_type(i), context, file_list,
+ options_.annotate_code, annotation_list, "", &generator,
+ &EnumLiteGenerator::Generate);
+ }
+ }
+ for (int i = 0; i < file_->message_type_count(); i++) {
+ if (immutable_api_) {
+ GenerateSibling<MessageGenerator>(
+ package_dir, java_package_, file_->message_type(i), context,
+ file_list, options_.annotate_code, annotation_list, "OrBuilder",
+ message_generators_[i].get(), &MessageGenerator::GenerateInterface);
+ }
+ GenerateSibling<MessageGenerator>(
+ package_dir, java_package_, file_->message_type(i), context,
+ file_list, options_.annotate_code, annotation_list, "",
+ message_generators_[i].get(), &MessageGenerator::Generate);
+ }
+ if (HasGenericServices(file_, context_->EnforceLite())) {
+ for (int i = 0; i < file_->service_count(); i++) {
+ std::unique_ptr<ServiceGenerator> generator(
+ generator_factory_->NewServiceGenerator(file_->service(i)));
+ GenerateSibling<ServiceGenerator>(
+ package_dir, java_package_, file_->service(i), context, file_list,
+ options_.annotate_code, annotation_list, "", generator.get(),
+ &ServiceGenerator::Generate);
+ }
+ }
+ }
+}
+
+std::string FileGenerator::GetKotlinClassname() {
+ return name_resolver_->GetFileClassName(file_, immutable_api_, true);
+}
+
+void FileGenerator::GenerateKotlinSiblings(
+ const std::string& package_dir, GeneratorContext* context,
+ std::vector<std::string>* file_list,
+ std::vector<std::string>* annotation_list) {
+ for (int i = 0; i < file_->message_type_count(); i++) {
+ const Descriptor* descriptor = file_->message_type(i);
+ MessageGenerator* generator = message_generators_[i].get();
+ auto open_file = [context](const std::string& filename) {
+ return std::unique_ptr<io::ZeroCopyOutputStream>(context->Open(filename));
+ };
+ std::string filename = package_dir + descriptor->name() + "Kt.kt";
+ file_list->push_back(filename);
+ std::string info_full_path = filename + ".pb.meta";
+ GeneratedCodeInfo annotations;
+ io::AnnotationProtoCollector<GeneratedCodeInfo> annotation_collector(
+ &annotations);
+ auto output = open_file(filename);
+ io::Printer printer(
+ output.get(), '$',
+ options_.annotate_code ? &annotation_collector : nullptr);
+
+ printer.Print(
+ "//Generated by the protocol buffer compiler. DO NOT EDIT!\n"
+ "// source: $filename$\n"
+ "\n",
+ "filename", descriptor->file()->name());
+ if (!java_package_.empty()) {
+ printer.Print(
+ "package $package$;\n"
+ "\n",
+ "package", java_package_);
+ }
+
+ generator->GenerateKotlinMembers(&printer);
+ generator->GenerateTopLevelKotlinMembers(&printer);
+
+ if (options_.annotate_code) {
+ auto info_output = open_file(info_full_path);
+ annotations.SerializeToZeroCopyStream(info_output.get());
+ annotation_list->push_back(info_full_path);
+ }
+ }
+}
+
+bool FileGenerator::ShouldIncludeDependency(const FileDescriptor* descriptor,
+ bool immutable_api) {
+ return true;
+}
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_file.h b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_file.h
new file mode 100644
index 00000000..80fb6e5d
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_file.h
@@ -0,0 +1,125 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_FILE_H__
+#define GOOGLE_PROTOBUF_COMPILER_JAVA_FILE_H__
+
+#include <memory>
+#include <string>
+#include <vector>
+#include <stubs/common.h>
+#include <compiler/java/java_options.h>
+
+namespace google {
+namespace protobuf {
+class FileDescriptor; // descriptor.h
+namespace io {
+class Printer; // printer.h
+}
+namespace compiler {
+class GeneratorContext; // code_generator.h
+namespace java {
+class Context; // context.h
+class MessageGenerator; // message.h
+class GeneratorFactory; // generator_factory.h
+class ExtensionGenerator; // extension.h
+class ClassNameResolver; // name_resolver.h
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+class FileGenerator {
+ public:
+ FileGenerator(const FileDescriptor* file, const Options& options,
+ bool immutable_api = true);
+ ~FileGenerator();
+
+ // Checks for problems that would otherwise lead to cryptic compile errors.
+ // Returns true if there are no problems, or writes an error description to
+ // the given string and returns false otherwise.
+ bool Validate(std::string* error);
+
+ void Generate(io::Printer* printer);
+
+ std::string GetKotlinClassname();
+ void GenerateKotlinSiblings(const std::string& package_dir,
+ GeneratorContext* generator_context,
+ std::vector<std::string>* file_list,
+ std::vector<std::string>* annotation_list);
+
+ // If we aren't putting everything into one file, this will write all the
+ // files other than the outer file (i.e. one for each message, enum, and
+ // service type).
+ void GenerateSiblings(const std::string& package_dir,
+ GeneratorContext* generator_context,
+ std::vector<std::string>* file_list,
+ std::vector<std::string>* annotation_list);
+
+ const std::string& java_package() { return java_package_; }
+ const std::string& classname() { return classname_; }
+
+ private:
+ void GenerateDescriptorInitializationCodeForImmutable(io::Printer* printer);
+ void GenerateDescriptorInitializationCodeForMutable(io::Printer* printer);
+
+ bool ShouldIncludeDependency(const FileDescriptor* descriptor,
+ bool immutable_api_);
+
+ const FileDescriptor* file_;
+ std::string java_package_;
+ std::string classname_;
+
+ std::vector<std::unique_ptr<MessageGenerator>> message_generators_;
+ std::vector<std::unique_ptr<ExtensionGenerator>> extension_generators_;
+ std::unique_ptr<GeneratorFactory> generator_factory_;
+ std::unique_ptr<Context> context_;
+ ClassNameResolver* name_resolver_;
+ const Options options_;
+ bool immutable_api_;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FileGenerator);
+};
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_FILE_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_generator.cc b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_generator.cc
new file mode 100644
index 00000000..611a4d9c
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_generator.cc
@@ -0,0 +1,211 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 <compiler/java/java_generator.h>
+
+
+#include <memory>
+
+#include <compiler/java/java_file.h>
+#include <compiler/java/java_generator_factory.h>
+#include <compiler/java/java_helpers.h>
+#include <compiler/java/java_name_resolver.h>
+#include <compiler/java/java_options.h>
+#include <compiler/java/java_shared_code_generator.h>
+#include <descriptor.pb.h>
+#include <io/printer.h>
+#include <io/zero_copy_stream.h>
+
+#include <stubs/strutil.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+
+JavaGenerator::JavaGenerator() {}
+JavaGenerator::~JavaGenerator() {}
+
+uint64_t JavaGenerator::GetSupportedFeatures() const {
+ return CodeGenerator::Feature::FEATURE_PROTO3_OPTIONAL;
+}
+
+bool JavaGenerator::Generate(const FileDescriptor* file,
+ const std::string& parameter,
+ GeneratorContext* context,
+ std::string* error) const {
+ // -----------------------------------------------------------------
+ // parse generator options
+
+ std::vector<std::pair<std::string, std::string> > options;
+ ParseGeneratorParameter(parameter, &options);
+ Options file_options;
+
+ for (int i = 0; i < options.size(); i++) {
+ if (options[i].first == "output_list_file") {
+ file_options.output_list_file = options[i].second;
+ } else if (options[i].first == "immutable") {
+ file_options.generate_immutable_code = true;
+ } else if (options[i].first == "mutable") {
+ file_options.generate_mutable_code = true;
+ } else if (options[i].first == "shared") {
+ file_options.generate_shared_code = true;
+ } else if (options[i].first == "lite") {
+ // Note: Java Lite does not guarantee API/ABI stability. We may choose to
+ // break existing API in order to boost performance / reduce code size.
+ file_options.enforce_lite = true;
+ } else if (options[i].first == "annotate_code") {
+ file_options.annotate_code = true;
+ } else if (options[i].first == "annotation_list_file") {
+ file_options.annotation_list_file = options[i].second;
+ } else {
+ *error = "Unknown generator option: " + options[i].first;
+ return false;
+ }
+ }
+
+ if (file_options.enforce_lite && file_options.generate_mutable_code) {
+ *error = "lite runtime generator option cannot be used with mutable API.";
+ return false;
+ }
+
+ // By default we generate immutable code and shared code for immutable API.
+ if (!file_options.generate_immutable_code &&
+ !file_options.generate_mutable_code &&
+ !file_options.generate_shared_code) {
+ file_options.generate_immutable_code = true;
+ file_options.generate_shared_code = true;
+ }
+
+ // -----------------------------------------------------------------
+
+
+ std::vector<std::string> all_files;
+ std::vector<std::string> all_annotations;
+
+
+ std::vector<FileGenerator*> file_generators;
+ if (file_options.generate_immutable_code) {
+ file_generators.push_back(new FileGenerator(file, file_options,
+ /* immutable = */ true));
+ }
+ if (file_options.generate_mutable_code) {
+ file_generators.push_back(new FileGenerator(file, file_options,
+ /* mutable = */ false));
+ }
+
+ for (int i = 0; i < file_generators.size(); ++i) {
+ if (!file_generators[i]->Validate(error)) {
+ for (int j = 0; j < file_generators.size(); ++j) {
+ delete file_generators[j];
+ }
+ return false;
+ }
+ }
+
+ for (int i = 0; i < file_generators.size(); ++i) {
+ FileGenerator* file_generator = file_generators[i];
+
+ std::string package_dir = JavaPackageToDir(file_generator->java_package());
+
+ std::string java_filename = package_dir;
+ java_filename += file_generator->classname();
+ java_filename += ".java";
+ all_files.push_back(java_filename);
+ std::string info_full_path = java_filename + ".pb.meta";
+ if (file_options.annotate_code) {
+ all_annotations.push_back(info_full_path);
+ }
+
+ // Generate main java file.
+ std::unique_ptr<io::ZeroCopyOutputStream> output(
+ context->Open(java_filename));
+ GeneratedCodeInfo annotations;
+ io::AnnotationProtoCollector<GeneratedCodeInfo> annotation_collector(
+ &annotations);
+ io::Printer printer(
+ output.get(), '$',
+ file_options.annotate_code ? &annotation_collector : NULL);
+
+ file_generator->Generate(&printer);
+
+ // Generate sibling files.
+ file_generator->GenerateSiblings(package_dir, context, &all_files,
+ &all_annotations);
+
+ if (file_options.annotate_code) {
+ std::unique_ptr<io::ZeroCopyOutputStream> info_output(
+ context->Open(info_full_path));
+ annotations.SerializeToZeroCopyStream(info_output.get());
+ }
+ }
+
+
+ for (int i = 0; i < file_generators.size(); ++i) {
+ delete file_generators[i];
+ }
+ file_generators.clear();
+
+ // Generate output list if requested.
+ if (!file_options.output_list_file.empty()) {
+ // Generate output list. This is just a simple text file placed in a
+ // deterministic location which lists the .java files being generated.
+ std::unique_ptr<io::ZeroCopyOutputStream> srclist_raw_output(
+ context->Open(file_options.output_list_file));
+ io::Printer srclist_printer(srclist_raw_output.get(), '$');
+ for (int i = 0; i < all_files.size(); i++) {
+ srclist_printer.Print("$filename$\n", "filename", all_files[i]);
+ }
+ }
+
+ if (!file_options.annotation_list_file.empty()) {
+ // Generate output list. This is just a simple text file placed in a
+ // deterministic location which lists the .java files being generated.
+ std::unique_ptr<io::ZeroCopyOutputStream> annotation_list_raw_output(
+ context->Open(file_options.annotation_list_file));
+ io::Printer annotation_list_printer(annotation_list_raw_output.get(), '$');
+ for (int i = 0; i < all_annotations.size(); i++) {
+ annotation_list_printer.Print("$filename$\n", "filename",
+ all_annotations[i]);
+ }
+ }
+
+ return true;
+}
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_generator.h b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_generator.h
new file mode 100644
index 00000000..7910cc03
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_generator.h
@@ -0,0 +1,76 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// Generates Java code for a given .proto file.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_GENERATOR_H__
+#define GOOGLE_PROTOBUF_COMPILER_JAVA_GENERATOR_H__
+
+#include <string>
+#include <compiler/code_generator.h>
+
+#include <port_def.inc>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+// CodeGenerator implementation which generates Java code. If you create your
+// own protocol compiler binary and you want it to support Java output, you
+// can do so by registering an instance of this CodeGenerator with the
+// CommandLineInterface in your main() function.
+class PROTOC_EXPORT JavaGenerator : public CodeGenerator {
+ public:
+ JavaGenerator();
+ ~JavaGenerator();
+
+ // implements CodeGenerator ----------------------------------------
+ bool Generate(const FileDescriptor* file, const std::string& parameter,
+ GeneratorContext* context, std::string* error) const override;
+
+ uint64_t GetSupportedFeatures() const override;
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(JavaGenerator);
+};
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#include <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_GENERATOR_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_generator_factory.cc b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_generator_factory.cc
new file mode 100644
index 00000000..50fa50b0
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_generator_factory.cc
@@ -0,0 +1,86 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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: liujisi@google.com (Pherl Liu)
+
+#include <compiler/java/java_generator_factory.h>
+
+#include <compiler/java/java_context.h>
+#include <compiler/java/java_enum_field.h>
+#include <compiler/java/java_extension.h>
+#include <compiler/java/java_extension_lite.h>
+#include <compiler/java/java_field.h>
+#include <compiler/java/java_helpers.h>
+#include <compiler/java/java_message.h>
+#include <compiler/java/java_message_lite.h>
+#include <compiler/java/java_service.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+GeneratorFactory::GeneratorFactory() {}
+GeneratorFactory::~GeneratorFactory() {}
+
+// ===================================================================
+
+ImmutableGeneratorFactory::ImmutableGeneratorFactory(Context* context)
+ : context_(context) {}
+ImmutableGeneratorFactory::~ImmutableGeneratorFactory() {}
+
+MessageGenerator* ImmutableGeneratorFactory::NewMessageGenerator(
+ const Descriptor* descriptor) const {
+ if (HasDescriptorMethods(descriptor, context_->EnforceLite())) {
+ return new ImmutableMessageGenerator(descriptor, context_);
+ } else {
+ return new ImmutableMessageLiteGenerator(descriptor, context_);
+ }
+}
+
+ExtensionGenerator* ImmutableGeneratorFactory::NewExtensionGenerator(
+ const FieldDescriptor* descriptor) const {
+ if (HasDescriptorMethods(descriptor->file(), context_->EnforceLite())) {
+ return new ImmutableExtensionGenerator(descriptor, context_);
+ } else {
+ return new ImmutableExtensionLiteGenerator(descriptor, context_);
+ }
+}
+
+ServiceGenerator* ImmutableGeneratorFactory::NewServiceGenerator(
+ const ServiceDescriptor* descriptor) const {
+ return new ImmutableServiceGenerator(descriptor, context_);
+}
+
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_generator_factory.h b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_generator_factory.h
new file mode 100644
index 00000000..a0a827a5
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_generator_factory.h
@@ -0,0 +1,103 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: liujisi@google.com (Pherl Liu)
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_GENERATOR_FACTORY_H__
+#define GOOGLE_PROTOBUF_COMPILER_JAVA_GENERATOR_FACTORY_H__
+
+#include <stubs/common.h>
+
+namespace google {
+namespace protobuf {
+class FieldDescriptor; // descriptor.h
+class Descriptor; // descriptor.h
+class ServiceDescriptor; // descriptor.h
+namespace compiler {
+namespace java {
+class MessageGenerator; // message.h
+class ExtensionGenerator; // extension.h
+class ServiceGenerator; // service.h
+class Context; // context.h
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+class GeneratorFactory {
+ public:
+ GeneratorFactory();
+ virtual ~GeneratorFactory();
+
+ virtual MessageGenerator* NewMessageGenerator(
+ const Descriptor* descriptor) const = 0;
+
+ virtual ExtensionGenerator* NewExtensionGenerator(
+ const FieldDescriptor* descriptor) const = 0;
+
+ virtual ServiceGenerator* NewServiceGenerator(
+ const ServiceDescriptor* descriptor) const = 0;
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(GeneratorFactory);
+};
+
+// Factory that creates generators for immutable-default messages.
+class ImmutableGeneratorFactory : public GeneratorFactory {
+ public:
+ ImmutableGeneratorFactory(Context* context);
+ virtual ~ImmutableGeneratorFactory();
+
+ MessageGenerator* NewMessageGenerator(
+ const Descriptor* descriptor) const override;
+
+ ExtensionGenerator* NewExtensionGenerator(
+ const FieldDescriptor* descriptor) const override;
+
+ ServiceGenerator* NewServiceGenerator(
+ const ServiceDescriptor* descriptor) const override;
+
+ private:
+ Context* context_;
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableGeneratorFactory);
+};
+
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_GENERATOR_FACTORY_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_helpers.cc b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_helpers.cc
new file mode 100644
index 00000000..0ce86ba9
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_helpers.cc
@@ -0,0 +1,1100 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 <compiler/java/java_helpers.h>
+
+#include <algorithm>
+#include <cstdint>
+#include <limits>
+#include <unordered_set>
+#include <vector>
+
+#include <stubs/stringprintf.h>
+#include <compiler/java/java_name_resolver.h>
+#include <compiler/java/java_names.h>
+#include <descriptor.pb.h>
+#include <wire_format.h>
+#include <stubs/strutil.h>
+#include <stubs/substitute.h>
+#include <stubs/hash.h> // for hash<T *>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+using internal::WireFormat;
+using internal::WireFormatLite;
+
+const char kThickSeparator[] =
+ "// ===================================================================\n";
+const char kThinSeparator[] =
+ "// -------------------------------------------------------------------\n";
+
+namespace {
+
+const char* kDefaultPackage = "";
+
+// Names that should be avoided as field names.
+// Using them will cause the compiler to generate accessors whose names are
+// colliding with methods defined in base classes.
+const char* kForbiddenWordList[] = {
+ // message base class:
+ "cached_size",
+ "serialized_size",
+ // java.lang.Object:
+ "class",
+};
+
+const std::unordered_set<std::string>* kReservedNames =
+ new std::unordered_set<std::string>({
+ "abstract", "assert", "boolean", "break", "byte",
+ "case", "catch", "char", "class", "const",
+ "continue", "default", "do", "double", "else",
+ "enum", "extends", "final", "finally", "float",
+ "for", "goto", "if", "implements", "import",
+ "instanceof", "int", "interface", "long", "native",
+ "new", "package", "private", "protected", "public",
+ "return", "short", "static", "strictfp", "super",
+ "switch", "synchronized", "this", "throw", "throws",
+ "transient", "try", "void", "volatile", "while",
+ });
+
+bool IsForbidden(const std::string& field_name) {
+ for (int i = 0; i < GOOGLE_ARRAYSIZE(kForbiddenWordList); ++i) {
+ if (field_name == kForbiddenWordList[i]) {
+ return true;
+ }
+ }
+ return false;
+}
+
+std::string FieldName(const FieldDescriptor* field) {
+ std::string field_name;
+ // Groups are hacky: The name of the field is just the lower-cased name
+ // of the group type. In Java, though, we would like to retain the original
+ // capitalization of the type name.
+ if (GetType(field) == FieldDescriptor::TYPE_GROUP) {
+ field_name = field->message_type()->name();
+ } else {
+ field_name = field->name();
+ }
+ if (IsForbidden(field_name)) {
+ // Append a trailing "#" to indicate that the name should be decorated to
+ // avoid collision with other names.
+ field_name += "#";
+ }
+ return field_name;
+}
+
+
+} // namespace
+
+void PrintGeneratedAnnotation(io::Printer* printer, char delimiter,
+ const std::string& annotation_file) {
+ if (annotation_file.empty()) {
+ return;
+ }
+ std::string ptemplate =
+ "@javax.annotation.Generated(value=\"protoc\", comments=\"annotations:";
+ ptemplate.push_back(delimiter);
+ ptemplate.append("annotation_file");
+ ptemplate.push_back(delimiter);
+ ptemplate.append("\")\n");
+ printer->Print(ptemplate.c_str(), "annotation_file", annotation_file);
+}
+
+void PrintEnumVerifierLogic(io::Printer* printer,
+ const FieldDescriptor* descriptor,
+ const std::map<std::string, std::string>& variables,
+ const char* var_name,
+ const char* terminating_string, bool enforce_lite) {
+ std::string enum_verifier_string =
+ enforce_lite ? StrCat(var_name, ".internalGetVerifier()")
+ : StrCat(
+ "new com.google.protobuf.Internal.EnumVerifier() {\n"
+ " @java.lang.Override\n"
+ " public boolean isInRange(int number) {\n"
+ " return ",
+ var_name,
+ ".forNumber(number) != null;\n"
+ " }\n"
+ " }");
+ printer->Print(
+ variables,
+ StrCat(enum_verifier_string, terminating_string).c_str());
+}
+
+std::string UnderscoresToCamelCase(const std::string& input,
+ bool cap_next_letter) {
+ GOOGLE_CHECK(!input.empty());
+ std::string result;
+ // Note: I distrust ctype.h due to locales.
+ for (int i = 0; i < input.size(); i++) {
+ if ('a' <= input[i] && input[i] <= 'z') {
+ if (cap_next_letter) {
+ result += input[i] + ('A' - 'a');
+ } else {
+ result += input[i];
+ }
+ cap_next_letter = false;
+ } else if ('A' <= input[i] && input[i] <= 'Z') {
+ if (i == 0 && !cap_next_letter) {
+ // Force first letter to lower-case unless explicitly told to
+ // capitalize it.
+ result += input[i] + ('a' - 'A');
+ } else {
+ // Capital letters after the first are left as-is.
+ result += input[i];
+ }
+ cap_next_letter = false;
+ } else if ('0' <= input[i] && input[i] <= '9') {
+ result += input[i];
+ cap_next_letter = true;
+ } else {
+ cap_next_letter = true;
+ }
+ }
+ // Add a trailing "_" if the name should be altered.
+ if (input[input.size() - 1] == '#') {
+ result += '_';
+ }
+ return result;
+}
+
+std::string ToCamelCase(const std::string& input, bool lower_first) {
+ bool capitalize_next = !lower_first;
+ std::string result;
+ result.reserve(input.size());
+
+ for (char i : input) {
+ if (i == '_') {
+ capitalize_next = true;
+ } else if (capitalize_next) {
+ result.push_back(ToUpperCh(i));
+ capitalize_next = false;
+ } else {
+ result.push_back(i);
+ }
+ }
+
+ // Lower-case the first letter.
+ if (lower_first && !result.empty()) {
+ result[0] = ToLowerCh(result[0]);
+ }
+
+ return result;
+}
+
+char ToUpperCh(char ch) {
+ return (ch >= 'a' && ch <= 'z') ? (ch - 'a' + 'A') : ch;
+}
+
+char ToLowerCh(char ch) {
+ return (ch >= 'A' && ch <= 'Z') ? (ch - 'A' + 'a') : ch;
+}
+
+std::string UnderscoresToCamelCase(const FieldDescriptor* field) {
+ return UnderscoresToCamelCase(FieldName(field), false);
+}
+
+std::string UnderscoresToCapitalizedCamelCase(const FieldDescriptor* field) {
+ return UnderscoresToCamelCase(FieldName(field), true);
+}
+
+std::string CapitalizedFieldName(const FieldDescriptor* field) {
+ return UnderscoresToCapitalizedCamelCase(field);
+}
+
+std::string UnderscoresToCamelCase(const MethodDescriptor* method) {
+ return UnderscoresToCamelCase(method->name(), false);
+}
+
+std::string UnderscoresToCamelCaseCheckReserved(const FieldDescriptor* field) {
+ std::string name = UnderscoresToCamelCase(field);
+ if (kReservedNames->find(name) != kReservedNames->end()) {
+ return name + "_";
+ }
+ return name;
+}
+
+bool IsForbiddenKotlin(const std::string& field_name) {
+ // Names that should be avoided as field names in Kotlin.
+ // All Kotlin hard keywords are in this list.
+ const std::unordered_set<std::string>* kKotlinForbiddenNames =
+ new std::unordered_set<std::string>({
+ "as", "as?", "break", "class", "continue", "do",
+ "else", "false", "for", "fun", "if", "in",
+ "!in", "interface", "is", "!is", "null", "object",
+ "package", "return", "super", "this", "throw", "true",
+ "try", "typealias", "typeof", "val", "var", "when",
+ "while",
+ });
+ return kKotlinForbiddenNames->find(field_name) !=
+ kKotlinForbiddenNames->end();
+}
+
+std::string UniqueFileScopeIdentifier(const Descriptor* descriptor) {
+ return "static_" + StringReplace(descriptor->full_name(), ".", "_", true);
+}
+
+std::string CamelCaseFieldName(const FieldDescriptor* field) {
+ std::string fieldName = UnderscoresToCamelCase(field);
+ if ('0' <= fieldName[0] && fieldName[0] <= '9') {
+ return '_' + fieldName;
+ }
+ return fieldName;
+}
+
+std::string FileClassName(const FileDescriptor* file, bool immutable) {
+ ClassNameResolver name_resolver;
+ return name_resolver.GetFileClassName(file, immutable);
+}
+
+std::string FileJavaPackage(const FileDescriptor* file, bool immutable) {
+ std::string result;
+
+ if (file->options().has_java_package()) {
+ result = file->options().java_package();
+ } else {
+ result = kDefaultPackage;
+ if (!file->package().empty()) {
+ if (!result.empty()) result += '.';
+ result += file->package();
+ }
+ }
+
+ return result;
+}
+
+std::string FileJavaPackage(const FileDescriptor* file) {
+ return FileJavaPackage(file, true /* immutable */);
+}
+
+std::string JavaPackageToDir(std::string package_name) {
+ std::string package_dir = StringReplace(package_name, ".", "/", true);
+ if (!package_dir.empty()) package_dir += "/";
+ return package_dir;
+}
+
+std::string ClassName(const Descriptor* descriptor) {
+ ClassNameResolver name_resolver;
+ return name_resolver.GetClassName(descriptor, true);
+}
+
+std::string ClassName(const EnumDescriptor* descriptor) {
+ ClassNameResolver name_resolver;
+ return name_resolver.GetClassName(descriptor, true);
+}
+
+std::string ClassName(const ServiceDescriptor* descriptor) {
+ ClassNameResolver name_resolver;
+ return name_resolver.GetClassName(descriptor, true);
+}
+
+std::string ClassName(const FileDescriptor* descriptor) {
+ ClassNameResolver name_resolver;
+ return name_resolver.GetClassName(descriptor, true);
+}
+
+
+std::string ExtraMessageInterfaces(const Descriptor* descriptor) {
+ std::string interfaces = "// @@protoc_insertion_point(message_implements:" +
+ descriptor->full_name() + ")";
+ return interfaces;
+}
+
+
+std::string ExtraBuilderInterfaces(const Descriptor* descriptor) {
+ std::string interfaces = "// @@protoc_insertion_point(builder_implements:" +
+ descriptor->full_name() + ")";
+ return interfaces;
+}
+
+std::string ExtraMessageOrBuilderInterfaces(const Descriptor* descriptor) {
+ std::string interfaces = "// @@protoc_insertion_point(interface_extends:" +
+ descriptor->full_name() + ")";
+ return interfaces;
+}
+
+std::string FieldConstantName(const FieldDescriptor* field) {
+ std::string name = field->name() + "_FIELD_NUMBER";
+ ToUpper(&name);
+ return name;
+}
+
+FieldDescriptor::Type GetType(const FieldDescriptor* field) {
+ return field->type();
+}
+
+JavaType GetJavaType(const FieldDescriptor* field) {
+ switch (GetType(field)) {
+ case FieldDescriptor::TYPE_INT32:
+ case FieldDescriptor::TYPE_UINT32:
+ case FieldDescriptor::TYPE_SINT32:
+ case FieldDescriptor::TYPE_FIXED32:
+ case FieldDescriptor::TYPE_SFIXED32:
+ return JAVATYPE_INT;
+
+ case FieldDescriptor::TYPE_INT64:
+ case FieldDescriptor::TYPE_UINT64:
+ case FieldDescriptor::TYPE_SINT64:
+ case FieldDescriptor::TYPE_FIXED64:
+ case FieldDescriptor::TYPE_SFIXED64:
+ return JAVATYPE_LONG;
+
+ case FieldDescriptor::TYPE_FLOAT:
+ return JAVATYPE_FLOAT;
+
+ case FieldDescriptor::TYPE_DOUBLE:
+ return JAVATYPE_DOUBLE;
+
+ case FieldDescriptor::TYPE_BOOL:
+ return JAVATYPE_BOOLEAN;
+
+ case FieldDescriptor::TYPE_STRING:
+ return JAVATYPE_STRING;
+
+ case FieldDescriptor::TYPE_BYTES:
+ return JAVATYPE_BYTES;
+
+ case FieldDescriptor::TYPE_ENUM:
+ return JAVATYPE_ENUM;
+
+ case FieldDescriptor::TYPE_GROUP:
+ case FieldDescriptor::TYPE_MESSAGE:
+ return JAVATYPE_MESSAGE;
+
+ // No default because we want the compiler to complain if any new
+ // types are added.
+ }
+
+ GOOGLE_LOG(FATAL) << "Can't get here.";
+ return JAVATYPE_INT;
+}
+
+const char* PrimitiveTypeName(JavaType type) {
+ switch (type) {
+ case JAVATYPE_INT:
+ return "int";
+ case JAVATYPE_LONG:
+ return "long";
+ case JAVATYPE_FLOAT:
+ return "float";
+ case JAVATYPE_DOUBLE:
+ return "double";
+ case JAVATYPE_BOOLEAN:
+ return "boolean";
+ case JAVATYPE_STRING:
+ return "java.lang.String";
+ case JAVATYPE_BYTES:
+ return "com.google.protobuf.ByteString";
+ case JAVATYPE_ENUM:
+ return NULL;
+ case JAVATYPE_MESSAGE:
+ return NULL;
+
+ // No default because we want the compiler to complain if any new
+ // JavaTypes are added.
+ }
+
+ GOOGLE_LOG(FATAL) << "Can't get here.";
+ return NULL;
+}
+
+const char* PrimitiveTypeName(const FieldDescriptor* descriptor) {
+ return PrimitiveTypeName(GetJavaType(descriptor));
+}
+
+const char* BoxedPrimitiveTypeName(JavaType type) {
+ switch (type) {
+ case JAVATYPE_INT:
+ return "java.lang.Integer";
+ case JAVATYPE_LONG:
+ return "java.lang.Long";
+ case JAVATYPE_FLOAT:
+ return "java.lang.Float";
+ case JAVATYPE_DOUBLE:
+ return "java.lang.Double";
+ case JAVATYPE_BOOLEAN:
+ return "java.lang.Boolean";
+ case JAVATYPE_STRING:
+ return "java.lang.String";
+ case JAVATYPE_BYTES:
+ return "com.google.protobuf.ByteString";
+ case JAVATYPE_ENUM:
+ return NULL;
+ case JAVATYPE_MESSAGE:
+ return NULL;
+
+ // No default because we want the compiler to complain if any new
+ // JavaTypes are added.
+ }
+
+ GOOGLE_LOG(FATAL) << "Can't get here.";
+ return NULL;
+}
+
+const char* BoxedPrimitiveTypeName(const FieldDescriptor* descriptor) {
+ return BoxedPrimitiveTypeName(GetJavaType(descriptor));
+}
+
+const char* KotlinTypeName(JavaType type) {
+ switch (type) {
+ case JAVATYPE_INT:
+ return "kotlin.Int";
+ case JAVATYPE_LONG:
+ return "kotlin.Long";
+ case JAVATYPE_FLOAT:
+ return "kotlin.Float";
+ case JAVATYPE_DOUBLE:
+ return "kotlin.Double";
+ case JAVATYPE_BOOLEAN:
+ return "kotlin.Boolean";
+ case JAVATYPE_STRING:
+ return "kotlin.String";
+ case JAVATYPE_BYTES:
+ return "com.google.protobuf.ByteString";
+ case JAVATYPE_ENUM:
+ return NULL;
+ case JAVATYPE_MESSAGE:
+ return NULL;
+
+ // No default because we want the compiler to complain if any new
+ // JavaTypes are added.
+ }
+
+ GOOGLE_LOG(FATAL) << "Can't get here.";
+ return NULL;
+}
+
+std::string GetOneofStoredType(const FieldDescriptor* field) {
+ const JavaType javaType = GetJavaType(field);
+ switch (javaType) {
+ case JAVATYPE_ENUM:
+ return "java.lang.Integer";
+ case JAVATYPE_MESSAGE:
+ return ClassName(field->message_type());
+ default:
+ return BoxedPrimitiveTypeName(javaType);
+ }
+}
+
+const char* FieldTypeName(FieldDescriptor::Type field_type) {
+ switch (field_type) {
+ case FieldDescriptor::TYPE_INT32:
+ return "INT32";
+ case FieldDescriptor::TYPE_UINT32:
+ return "UINT32";
+ case FieldDescriptor::TYPE_SINT32:
+ return "SINT32";
+ case FieldDescriptor::TYPE_FIXED32:
+ return "FIXED32";
+ case FieldDescriptor::TYPE_SFIXED32:
+ return "SFIXED32";
+ case FieldDescriptor::TYPE_INT64:
+ return "INT64";
+ case FieldDescriptor::TYPE_UINT64:
+ return "UINT64";
+ case FieldDescriptor::TYPE_SINT64:
+ return "SINT64";
+ case FieldDescriptor::TYPE_FIXED64:
+ return "FIXED64";
+ case FieldDescriptor::TYPE_SFIXED64:
+ return "SFIXED64";
+ case FieldDescriptor::TYPE_FLOAT:
+ return "FLOAT";
+ case FieldDescriptor::TYPE_DOUBLE:
+ return "DOUBLE";
+ case FieldDescriptor::TYPE_BOOL:
+ return "BOOL";
+ case FieldDescriptor::TYPE_STRING:
+ return "STRING";
+ case FieldDescriptor::TYPE_BYTES:
+ return "BYTES";
+ case FieldDescriptor::TYPE_ENUM:
+ return "ENUM";
+ case FieldDescriptor::TYPE_GROUP:
+ return "GROUP";
+ case FieldDescriptor::TYPE_MESSAGE:
+ return "MESSAGE";
+
+ // No default because we want the compiler to complain if any new
+ // types are added.
+ }
+
+ GOOGLE_LOG(FATAL) << "Can't get here.";
+ return NULL;
+}
+
+bool AllAscii(const std::string& text) {
+ for (int i = 0; i < text.size(); i++) {
+ if ((text[i] & 0x80) != 0) {
+ return false;
+ }
+ }
+ return true;
+}
+
+std::string DefaultValue(const FieldDescriptor* field, bool immutable,
+ ClassNameResolver* name_resolver) {
+ // Switch on CppType since we need to know which default_value_* method
+ // of FieldDescriptor to call.
+ switch (field->cpp_type()) {
+ case FieldDescriptor::CPPTYPE_INT32:
+ return StrCat(field->default_value_int32());
+ case FieldDescriptor::CPPTYPE_UINT32:
+ // Need to print as a signed int since Java has no unsigned.
+ return StrCat(static_cast<int32_t>(field->default_value_uint32()));
+ case FieldDescriptor::CPPTYPE_INT64:
+ return StrCat(field->default_value_int64()) + "L";
+ case FieldDescriptor::CPPTYPE_UINT64:
+ return StrCat(static_cast<int64_t>(field->default_value_uint64())) +
+ "L";
+ case FieldDescriptor::CPPTYPE_DOUBLE: {
+ double value = field->default_value_double();
+ if (value == std::numeric_limits<double>::infinity()) {
+ return "Double.POSITIVE_INFINITY";
+ } else if (value == -std::numeric_limits<double>::infinity()) {
+ return "Double.NEGATIVE_INFINITY";
+ } else if (value != value) {
+ return "Double.NaN";
+ } else {
+ return SimpleDtoa(value) + "D";
+ }
+ }
+ case FieldDescriptor::CPPTYPE_FLOAT: {
+ float value = field->default_value_float();
+ if (value == std::numeric_limits<float>::infinity()) {
+ return "Float.POSITIVE_INFINITY";
+ } else if (value == -std::numeric_limits<float>::infinity()) {
+ return "Float.NEGATIVE_INFINITY";
+ } else if (value != value) {
+ return "Float.NaN";
+ } else {
+ return SimpleFtoa(value) + "F";
+ }
+ }
+ case FieldDescriptor::CPPTYPE_BOOL:
+ return field->default_value_bool() ? "true" : "false";
+ case FieldDescriptor::CPPTYPE_STRING:
+ if (GetType(field) == FieldDescriptor::TYPE_BYTES) {
+ if (field->has_default_value()) {
+ // See comments in Internal.java for gory details.
+ return strings::Substitute(
+ "com.google.protobuf.Internal.bytesDefaultValue(\"$0\")",
+ CEscape(field->default_value_string()));
+ } else {
+ return "com.google.protobuf.ByteString.EMPTY";
+ }
+ } else {
+ if (AllAscii(field->default_value_string())) {
+ // All chars are ASCII. In this case CEscape() works fine.
+ return "\"" + CEscape(field->default_value_string()) + "\"";
+ } else {
+ // See comments in Internal.java for gory details.
+ return strings::Substitute(
+ "com.google.protobuf.Internal.stringDefaultValue(\"$0\")",
+ CEscape(field->default_value_string()));
+ }
+ }
+
+ case FieldDescriptor::CPPTYPE_ENUM:
+ return name_resolver->GetClassName(field->enum_type(), immutable) + "." +
+ field->default_value_enum()->name();
+
+ case FieldDescriptor::CPPTYPE_MESSAGE:
+ return name_resolver->GetClassName(field->message_type(), immutable) +
+ ".getDefaultInstance()";
+
+ // No default because we want the compiler to complain if any new
+ // types are added.
+ }
+
+ GOOGLE_LOG(FATAL) << "Can't get here.";
+ return "";
+}
+
+bool IsDefaultValueJavaDefault(const FieldDescriptor* field) {
+ // Switch on CppType since we need to know which default_value_* method
+ // of FieldDescriptor to call.
+ switch (field->cpp_type()) {
+ case FieldDescriptor::CPPTYPE_INT32:
+ return field->default_value_int32() == 0;
+ case FieldDescriptor::CPPTYPE_UINT32:
+ return field->default_value_uint32() == 0;
+ case FieldDescriptor::CPPTYPE_INT64:
+ return field->default_value_int64() == 0L;
+ case FieldDescriptor::CPPTYPE_UINT64:
+ return field->default_value_uint64() == 0L;
+ case FieldDescriptor::CPPTYPE_DOUBLE:
+ return field->default_value_double() == 0.0;
+ case FieldDescriptor::CPPTYPE_FLOAT:
+ return field->default_value_float() == 0.0;
+ case FieldDescriptor::CPPTYPE_BOOL:
+ return field->default_value_bool() == false;
+ case FieldDescriptor::CPPTYPE_ENUM:
+ return field->default_value_enum()->number() == 0;
+ case FieldDescriptor::CPPTYPE_STRING:
+ case FieldDescriptor::CPPTYPE_MESSAGE:
+ return false;
+
+ // No default because we want the compiler to complain if any new
+ // types are added.
+ }
+
+ GOOGLE_LOG(FATAL) << "Can't get here.";
+ return false;
+}
+
+bool IsByteStringWithCustomDefaultValue(const FieldDescriptor* field) {
+ return GetJavaType(field) == JAVATYPE_BYTES &&
+ field->default_value_string() != "";
+}
+
+const char* bit_masks[] = {
+ "0x00000001", "0x00000002", "0x00000004", "0x00000008",
+ "0x00000010", "0x00000020", "0x00000040", "0x00000080",
+
+ "0x00000100", "0x00000200", "0x00000400", "0x00000800",
+ "0x00001000", "0x00002000", "0x00004000", "0x00008000",
+
+ "0x00010000", "0x00020000", "0x00040000", "0x00080000",
+ "0x00100000", "0x00200000", "0x00400000", "0x00800000",
+
+ "0x01000000", "0x02000000", "0x04000000", "0x08000000",
+ "0x10000000", "0x20000000", "0x40000000", "0x80000000",
+};
+
+std::string GetBitFieldName(int index) {
+ std::string varName = "bitField";
+ varName += StrCat(index);
+ varName += "_";
+ return varName;
+}
+
+std::string GetBitFieldNameForBit(int bitIndex) {
+ return GetBitFieldName(bitIndex / 32);
+}
+
+namespace {
+
+std::string GenerateGetBitInternal(const std::string& prefix, int bitIndex) {
+ std::string varName = prefix + GetBitFieldNameForBit(bitIndex);
+ int bitInVarIndex = bitIndex % 32;
+
+ std::string mask = bit_masks[bitInVarIndex];
+ std::string result = "((" + varName + " & " + mask + ") != 0)";
+ return result;
+}
+
+std::string GenerateSetBitInternal(const std::string& prefix, int bitIndex) {
+ std::string varName = prefix + GetBitFieldNameForBit(bitIndex);
+ int bitInVarIndex = bitIndex % 32;
+
+ std::string mask = bit_masks[bitInVarIndex];
+ std::string result = varName + " |= " + mask;
+ return result;
+}
+
+} // namespace
+
+std::string GenerateGetBit(int bitIndex) {
+ return GenerateGetBitInternal("", bitIndex);
+}
+
+std::string GenerateSetBit(int bitIndex) {
+ return GenerateSetBitInternal("", bitIndex);
+}
+
+std::string GenerateClearBit(int bitIndex) {
+ std::string varName = GetBitFieldNameForBit(bitIndex);
+ int bitInVarIndex = bitIndex % 32;
+
+ std::string mask = bit_masks[bitInVarIndex];
+ std::string result = varName + " = (" + varName + " & ~" + mask + ")";
+ return result;
+}
+
+std::string GenerateGetBitFromLocal(int bitIndex) {
+ return GenerateGetBitInternal("from_", bitIndex);
+}
+
+std::string GenerateSetBitToLocal(int bitIndex) {
+ return GenerateSetBitInternal("to_", bitIndex);
+}
+
+std::string GenerateGetBitMutableLocal(int bitIndex) {
+ return GenerateGetBitInternal("mutable_", bitIndex);
+}
+
+std::string GenerateSetBitMutableLocal(int bitIndex) {
+ return GenerateSetBitInternal("mutable_", bitIndex);
+}
+
+bool IsReferenceType(JavaType type) {
+ switch (type) {
+ case JAVATYPE_INT:
+ return false;
+ case JAVATYPE_LONG:
+ return false;
+ case JAVATYPE_FLOAT:
+ return false;
+ case JAVATYPE_DOUBLE:
+ return false;
+ case JAVATYPE_BOOLEAN:
+ return false;
+ case JAVATYPE_STRING:
+ return true;
+ case JAVATYPE_BYTES:
+ return true;
+ case JAVATYPE_ENUM:
+ return true;
+ case JAVATYPE_MESSAGE:
+ return true;
+
+ // No default because we want the compiler to complain if any new
+ // JavaTypes are added.
+ }
+
+ GOOGLE_LOG(FATAL) << "Can't get here.";
+ return false;
+}
+
+const char* GetCapitalizedType(const FieldDescriptor* field, bool immutable) {
+ switch (GetType(field)) {
+ case FieldDescriptor::TYPE_INT32:
+ return "Int32";
+ case FieldDescriptor::TYPE_UINT32:
+ return "UInt32";
+ case FieldDescriptor::TYPE_SINT32:
+ return "SInt32";
+ case FieldDescriptor::TYPE_FIXED32:
+ return "Fixed32";
+ case FieldDescriptor::TYPE_SFIXED32:
+ return "SFixed32";
+ case FieldDescriptor::TYPE_INT64:
+ return "Int64";
+ case FieldDescriptor::TYPE_UINT64:
+ return "UInt64";
+ case FieldDescriptor::TYPE_SINT64:
+ return "SInt64";
+ case FieldDescriptor::TYPE_FIXED64:
+ return "Fixed64";
+ case FieldDescriptor::TYPE_SFIXED64:
+ return "SFixed64";
+ case FieldDescriptor::TYPE_FLOAT:
+ return "Float";
+ case FieldDescriptor::TYPE_DOUBLE:
+ return "Double";
+ case FieldDescriptor::TYPE_BOOL:
+ return "Bool";
+ case FieldDescriptor::TYPE_STRING:
+ return "String";
+ case FieldDescriptor::TYPE_BYTES: {
+ return "Bytes";
+ }
+ case FieldDescriptor::TYPE_ENUM:
+ return "Enum";
+ case FieldDescriptor::TYPE_GROUP:
+ return "Group";
+ case FieldDescriptor::TYPE_MESSAGE:
+ return "Message";
+
+ // No default because we want the compiler to complain if any new
+ // types are added.
+ }
+
+ GOOGLE_LOG(FATAL) << "Can't get here.";
+ return NULL;
+}
+
+// For encodings with fixed sizes, returns that size in bytes. Otherwise
+// returns -1.
+int FixedSize(FieldDescriptor::Type type) {
+ switch (type) {
+ case FieldDescriptor::TYPE_INT32:
+ return -1;
+ case FieldDescriptor::TYPE_INT64:
+ return -1;
+ case FieldDescriptor::TYPE_UINT32:
+ return -1;
+ case FieldDescriptor::TYPE_UINT64:
+ return -1;
+ case FieldDescriptor::TYPE_SINT32:
+ return -1;
+ case FieldDescriptor::TYPE_SINT64:
+ return -1;
+ case FieldDescriptor::TYPE_FIXED32:
+ return WireFormatLite::kFixed32Size;
+ case FieldDescriptor::TYPE_FIXED64:
+ return WireFormatLite::kFixed64Size;
+ case FieldDescriptor::TYPE_SFIXED32:
+ return WireFormatLite::kSFixed32Size;
+ case FieldDescriptor::TYPE_SFIXED64:
+ return WireFormatLite::kSFixed64Size;
+ case FieldDescriptor::TYPE_FLOAT:
+ return WireFormatLite::kFloatSize;
+ case FieldDescriptor::TYPE_DOUBLE:
+ return WireFormatLite::kDoubleSize;
+
+ case FieldDescriptor::TYPE_BOOL:
+ return WireFormatLite::kBoolSize;
+ case FieldDescriptor::TYPE_ENUM:
+ return -1;
+
+ case FieldDescriptor::TYPE_STRING:
+ return -1;
+ case FieldDescriptor::TYPE_BYTES:
+ return -1;
+ case FieldDescriptor::TYPE_GROUP:
+ return -1;
+ case FieldDescriptor::TYPE_MESSAGE:
+ return -1;
+
+ // No default because we want the compiler to complain if any new
+ // types are added.
+ }
+ GOOGLE_LOG(FATAL) << "Can't get here.";
+ return -1;
+}
+
+// Sort the fields of the given Descriptor by number into a new[]'d array
+// and return it. The caller should delete the returned array.
+const FieldDescriptor** SortFieldsByNumber(const Descriptor* descriptor) {
+ const FieldDescriptor** fields =
+ new const FieldDescriptor*[descriptor->field_count()];
+ for (int i = 0; i < descriptor->field_count(); i++) {
+ fields[i] = descriptor->field(i);
+ }
+ std::sort(fields, fields + descriptor->field_count(),
+ FieldOrderingByNumber());
+ return fields;
+}
+
+// Returns true if the message type has any required fields. If it doesn't,
+// we can optimize out calls to its isInitialized() method.
+//
+// already_seen is used to avoid checking the same type multiple times
+// (and also to protect against recursion).
+bool HasRequiredFields(const Descriptor* type,
+ std::unordered_set<const Descriptor*>* already_seen) {
+ if (already_seen->count(type) > 0) {
+ // The type is already in cache. This means that either:
+ // a. The type has no required fields.
+ // b. We are in the midst of checking if the type has required fields,
+ // somewhere up the stack. In this case, we know that if the type
+ // has any required fields, they'll be found when we return to it,
+ // and the whole call to HasRequiredFields() will return true.
+ // Therefore, we don't have to check if this type has required fields
+ // here.
+ return false;
+ }
+ already_seen->insert(type);
+
+ // If the type has extensions, an extension with message type could contain
+ // required fields, so we have to be conservative and assume such an
+ // extension exists.
+ if (type->extension_range_count() > 0) return true;
+
+ for (int i = 0; i < type->field_count(); i++) {
+ const FieldDescriptor* field = type->field(i);
+ if (field->is_required()) {
+ return true;
+ }
+ if (GetJavaType(field) == JAVATYPE_MESSAGE) {
+ if (HasRequiredFields(field->message_type(), already_seen)) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+bool HasRequiredFields(const Descriptor* type) {
+ std::unordered_set<const Descriptor*> already_seen;
+ return HasRequiredFields(type, &already_seen);
+}
+
+bool HasRepeatedFields(const Descriptor* descriptor) {
+ for (int i = 0; i < descriptor->field_count(); ++i) {
+ const FieldDescriptor* field = descriptor->field(i);
+ if (field->is_repeated()) {
+ return true;
+ }
+ }
+ return false;
+}
+
+// Encode an unsigned 32-bit value into a sequence of UTF-16 characters.
+//
+// If the value is in [0x0000, 0xD7FF], we encode it with a single character
+// with the same numeric value.
+//
+// If the value is larger than 0xD7FF, we encode its lowest 13 bits into a
+// character in the range [0xE000, 0xFFFF] by combining these 13 bits with
+// 0xE000 using logic-or. Then we shift the value to the right by 13 bits, and
+// encode the remaining value by repeating this same process until we get to
+// a value in [0x0000, 0xD7FF] where we will encode it using a character with
+// the same numeric value.
+//
+// Note that we only use code points in [0x0000, 0xD7FF] and [0xE000, 0xFFFF].
+// There will be no surrogate pairs in the encoded character sequence.
+void WriteUInt32ToUtf16CharSequence(uint32_t number,
+ std::vector<uint16_t>* output) {
+ // For values in [0x0000, 0xD7FF], only use one char to encode it.
+ if (number < 0xD800) {
+ output->push_back(static_cast<uint16_t>(number));
+ return;
+ }
+ // Encode into multiple chars. All except the last char will be in the range
+ // [0xE000, 0xFFFF], and the last char will be in the range [0x0000, 0xD7FF].
+ // Note that we don't use any value in range [0xD800, 0xDFFF] because they
+ // have to come in pairs and the encoding is just more space-efficient w/o
+ // them.
+ while (number >= 0xD800) {
+ // [0xE000, 0xFFFF] can represent 13 bits of info.
+ output->push_back(static_cast<uint16_t>(0xE000 | (number & 0x1FFF)));
+ number >>= 13;
+ }
+ output->push_back(static_cast<uint16_t>(number));
+}
+
+int GetExperimentalJavaFieldTypeForSingular(const FieldDescriptor* field) {
+ // j/c/g/protobuf/FieldType.java lists field types in a slightly different
+ // order from FieldDescriptor::Type so we can't do a simple cast.
+ //
+ // TODO(xiaofeng): Make j/c/g/protobuf/FieldType.java follow the same order.
+ int result = field->type();
+ if (result == FieldDescriptor::TYPE_GROUP) {
+ return 17;
+ } else if (result < FieldDescriptor::TYPE_GROUP) {
+ return result - 1;
+ } else {
+ return result - 2;
+ }
+}
+
+int GetExperimentalJavaFieldTypeForRepeated(const FieldDescriptor* field) {
+ if (field->type() == FieldDescriptor::TYPE_GROUP) {
+ return 49;
+ } else {
+ return GetExperimentalJavaFieldTypeForSingular(field) + 18;
+ }
+}
+
+int GetExperimentalJavaFieldTypeForPacked(const FieldDescriptor* field) {
+ int result = field->type();
+ if (result < FieldDescriptor::TYPE_STRING) {
+ return result + 34;
+ } else if (result > FieldDescriptor::TYPE_BYTES) {
+ return result + 30;
+ } else {
+ GOOGLE_LOG(FATAL) << field->full_name() << " can't be packed.";
+ return 0;
+ }
+}
+
+int GetExperimentalJavaFieldType(const FieldDescriptor* field) {
+ static const int kMapFieldType = 50;
+ static const int kOneofFieldTypeOffset = 51;
+ static const int kRequiredBit = 0x100;
+ static const int kUtf8CheckBit = 0x200;
+ static const int kCheckInitialized = 0x400;
+ static const int kMapWithProto2EnumValue = 0x800;
+ static const int kHasHasBit = 0x1000;
+ int extra_bits = field->is_required() ? kRequiredBit : 0;
+ if (field->type() == FieldDescriptor::TYPE_STRING && CheckUtf8(field)) {
+ extra_bits |= kUtf8CheckBit;
+ }
+ if (field->is_required() || (GetJavaType(field) == JAVATYPE_MESSAGE &&
+ HasRequiredFields(field->message_type()))) {
+ extra_bits |= kCheckInitialized;
+ }
+ if (HasHasbit(field)) {
+ extra_bits |= kHasHasBit;
+ }
+
+ if (field->is_map()) {
+ if (!SupportUnknownEnumValue(field)) {
+ const FieldDescriptor* value =
+ field->message_type()->FindFieldByName("value");
+ if (GetJavaType(value) == JAVATYPE_ENUM) {
+ extra_bits |= kMapWithProto2EnumValue;
+ }
+ }
+ return kMapFieldType | extra_bits;
+ } else if (field->is_packed()) {
+ return GetExperimentalJavaFieldTypeForPacked(field);
+ } else if (field->is_repeated()) {
+ return GetExperimentalJavaFieldTypeForRepeated(field) | extra_bits;
+ } else if (IsRealOneof(field)) {
+ return (GetExperimentalJavaFieldTypeForSingular(field) +
+ kOneofFieldTypeOffset) |
+ extra_bits;
+ } else {
+ return GetExperimentalJavaFieldTypeForSingular(field) | extra_bits;
+ }
+}
+
+// Escape a UTF-16 character to be embedded in a Java string.
+void EscapeUtf16ToString(uint16_t code, std::string* output) {
+ if (code == '\t') {
+ output->append("\\t");
+ } else if (code == '\b') {
+ output->append("\\b");
+ } else if (code == '\n') {
+ output->append("\\n");
+ } else if (code == '\r') {
+ output->append("\\r");
+ } else if (code == '\f') {
+ output->append("\\f");
+ } else if (code == '\'') {
+ output->append("\\'");
+ } else if (code == '\"') {
+ output->append("\\\"");
+ } else if (code == '\\') {
+ output->append("\\\\");
+ } else if (code >= 0x20 && code <= 0x7f) {
+ output->push_back(static_cast<char>(code));
+ } else {
+ output->append(StringPrintf("\\u%04x", code));
+ }
+}
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_helpers.h b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_helpers.h
new file mode 100644
index 00000000..428aa254
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_helpers.h
@@ -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.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_HELPERS_H__
+#define GOOGLE_PROTOBUF_COMPILER_JAVA_HELPERS_H__
+
+#include <cstdint>
+#include <string>
+
+#include <compiler/java/java_context.h>
+#include <descriptor.pb.h>
+#include <io/printer.h>
+#include <descriptor.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+// Commonly-used separator comments. Thick is a line of '=', thin is a line
+// of '-'.
+extern const char kThickSeparator[];
+extern const char kThinSeparator[];
+
+bool IsForbiddenKotlin(const std::string& field_name);
+
+// If annotation_file is non-empty, prints a javax.annotation.Generated
+// annotation to the given Printer. annotation_file will be referenced in the
+// annotation's comments field. delimiter should be the Printer's delimiter
+// character. annotation_file will be included verbatim into a Java literal
+// string, so it should not contain quotes or invalid Java escape sequences;
+// however, these are unlikely to appear in practice, as the value of
+// annotation_file should be generated from the filename of the source file
+// being annotated (which in turn must be a Java identifier plus ".java").
+void PrintGeneratedAnnotation(io::Printer* printer, char delimiter = '$',
+ const std::string& annotation_file = "");
+
+// If a GeneratedMessageLite contains non-lite enums, then its verifier
+// must be instantiated inline, rather than retrieved from the enum class.
+void PrintEnumVerifierLogic(io::Printer* printer,
+ const FieldDescriptor* descriptor,
+ const std::map<std::string, std::string>& variables,
+ const char* var_name,
+ const char* terminating_string, bool enforce_lite);
+
+// Converts a name to camel-case. If cap_first_letter is true, capitalize the
+// first letter.
+std::string ToCamelCase(const std::string& input, bool lower_first);
+
+char ToUpperCh(char ch);
+char ToLowerCh(char ch);
+
+// Converts a name to camel-case. If cap_first_letter is true, capitalize the
+// first letter.
+std::string UnderscoresToCamelCase(const std::string& name,
+ bool cap_first_letter);
+// Converts the field's name to camel-case, e.g. "foo_bar_baz" becomes
+// "fooBarBaz" or "FooBarBaz", respectively.
+std::string UnderscoresToCamelCase(const FieldDescriptor* field);
+std::string UnderscoresToCapitalizedCamelCase(const FieldDescriptor* field);
+
+// Similar, but for method names. (Typically, this merely has the effect
+// of lower-casing the first letter of the name.)
+std::string UnderscoresToCamelCase(const MethodDescriptor* method);
+
+// Same as UnderscoresToCamelCase, but checks for reserved keywords
+std::string UnderscoresToCamelCaseCheckReserved(const FieldDescriptor* field);
+
+// Similar to UnderscoresToCamelCase, but guarantees that the result is a
+// complete Java identifier by adding a _ if needed.
+std::string CamelCaseFieldName(const FieldDescriptor* field);
+
+// Get an identifier that uniquely identifies this type within the file.
+// This is used to declare static variables related to this type at the
+// outermost file scope.
+std::string UniqueFileScopeIdentifier(const Descriptor* descriptor);
+
+// Gets the unqualified class name for the file. For each .proto file, there
+// will be one Java class containing all the immutable messages and another
+// Java class containing all the mutable messages.
+// TODO(xiaofeng): remove the default value after updating client code.
+std::string FileClassName(const FileDescriptor* file, bool immutable = true);
+
+// Returns the file's Java package name.
+std::string FileJavaPackage(const FileDescriptor* file, bool immutable);
+
+// Returns output directory for the given package name.
+std::string JavaPackageToDir(std::string package_name);
+
+// Comma-separate list of option-specified interfaces implemented by the
+// Message, to follow the "implements" declaration of the Message definition.
+std::string ExtraMessageInterfaces(const Descriptor* descriptor);
+// Comma-separate list of option-specified interfaces implemented by the
+// MutableMessage, to follow the "implements" declaration of the MutableMessage
+// definition.
+std::string ExtraMutableMessageInterfaces(const Descriptor* descriptor);
+// Comma-separate list of option-specified interfaces implemented by the
+// Builder, to follow the "implements" declaration of the Builder definition.
+std::string ExtraBuilderInterfaces(const Descriptor* descriptor);
+// Comma-separate list of option-specified interfaces extended by the
+// MessageOrBuilder, to follow the "extends" declaration of the
+// MessageOrBuilder definition.
+std::string ExtraMessageOrBuilderInterfaces(const Descriptor* descriptor);
+
+// Get the unqualified Java class name for mutable messages. i.e. without
+// package or outer classnames.
+inline std::string ShortMutableJavaClassName(const Descriptor* descriptor) {
+ return descriptor->name();
+}
+
+// Whether the given descriptor is for one of the core descriptor protos. We
+// cannot currently use the new runtime with core protos since there is a
+// bootstrapping problem with obtaining their descriptors.
+inline bool IsDescriptorProto(const Descriptor* descriptor) {
+ return descriptor->file()->name() == "net/proto2/proto/descriptor.proto" ||
+ descriptor->file()->name() == "google/protobuf/descriptor.proto";
+}
+
+// Returns the stored type string used by the experimental runtime for oneof
+// fields.
+std::string GetOneofStoredType(const FieldDescriptor* field);
+
+
+// Whether we should generate multiple java files for messages.
+inline bool MultipleJavaFiles(const FileDescriptor* descriptor,
+ bool immutable) {
+ (void)immutable;
+ return descriptor->options().java_multiple_files();
+}
+
+
+// Returns true if `descriptor` will be written to its own .java file.
+// `immutable` should be set to true if we're generating for the immutable API.
+template <typename Descriptor>
+bool IsOwnFile(const Descriptor* descriptor, bool immutable) {
+ return descriptor->containing_type() == NULL &&
+ MultipleJavaFiles(descriptor->file(), immutable);
+}
+
+template <>
+inline bool IsOwnFile(const ServiceDescriptor* descriptor, bool immutable) {
+ return MultipleJavaFiles(descriptor->file(), immutable);
+}
+
+// If `descriptor` describes an object with its own .java file,
+// returns the name (relative to that .java file) of the file that stores
+// annotation data for that descriptor. `suffix` is usually empty, but may
+// (e.g.) be "OrBuilder" for some generated interfaces.
+template <typename Descriptor>
+std::string AnnotationFileName(const Descriptor* descriptor,
+ const std::string& suffix) {
+ return descriptor->name() + suffix + ".java.pb.meta";
+}
+
+template <typename Descriptor>
+void MaybePrintGeneratedAnnotation(Context* context, io::Printer* printer,
+ Descriptor* descriptor, bool immutable,
+ const std::string& suffix = "") {
+ if (IsOwnFile(descriptor, immutable)) {
+ PrintGeneratedAnnotation(printer, '$',
+ context->options().annotate_code
+ ? AnnotationFileName(descriptor, suffix)
+ : "");
+ }
+}
+
+// Get the unqualified name that should be used for a field's field
+// number constant.
+std::string FieldConstantName(const FieldDescriptor* field);
+
+// Returns the type of the FieldDescriptor.
+// This does nothing interesting for the open source release, but is used for
+// hacks that improve compatibility with version 1 protocol buffers at Google.
+FieldDescriptor::Type GetType(const FieldDescriptor* field);
+
+enum JavaType {
+ JAVATYPE_INT,
+ JAVATYPE_LONG,
+ JAVATYPE_FLOAT,
+ JAVATYPE_DOUBLE,
+ JAVATYPE_BOOLEAN,
+ JAVATYPE_STRING,
+ JAVATYPE_BYTES,
+ JAVATYPE_ENUM,
+ JAVATYPE_MESSAGE
+};
+
+JavaType GetJavaType(const FieldDescriptor* field);
+
+const char* PrimitiveTypeName(JavaType type);
+
+// Get the fully-qualified class name for a boxed primitive type, e.g.
+// "java.lang.Integer" for JAVATYPE_INT. Returns NULL for enum and message
+// types.
+const char* BoxedPrimitiveTypeName(JavaType type);
+
+// Kotlin source does not distinguish between primitives and non-primitives,
+// but does use Kotlin-specific qualified types for them.
+const char* KotlinTypeName(JavaType type);
+
+// Get the name of the java enum constant representing this type. E.g.,
+// "INT32" for FieldDescriptor::TYPE_INT32. The enum constant's full
+// name is "com.google.protobuf.WireFormat.FieldType.INT32".
+const char* FieldTypeName(const FieldDescriptor::Type field_type);
+
+class ClassNameResolver;
+std::string DefaultValue(const FieldDescriptor* field, bool immutable,
+ ClassNameResolver* name_resolver);
+inline std::string ImmutableDefaultValue(const FieldDescriptor* field,
+ ClassNameResolver* name_resolver) {
+ return DefaultValue(field, true, name_resolver);
+}
+bool IsDefaultValueJavaDefault(const FieldDescriptor* field);
+bool IsByteStringWithCustomDefaultValue(const FieldDescriptor* field);
+
+// Does this message class have descriptor and reflection methods?
+inline bool HasDescriptorMethods(const Descriptor* /* descriptor */,
+ bool enforce_lite) {
+ return !enforce_lite;
+}
+inline bool HasDescriptorMethods(const EnumDescriptor* /* descriptor */,
+ bool enforce_lite) {
+ return !enforce_lite;
+}
+inline bool HasDescriptorMethods(const FileDescriptor* /* descriptor */,
+ bool enforce_lite) {
+ return !enforce_lite;
+}
+
+// Should we generate generic services for this file?
+inline bool HasGenericServices(const FileDescriptor* file, bool enforce_lite) {
+ return file->service_count() > 0 &&
+ HasDescriptorMethods(file, enforce_lite) &&
+ file->options().java_generic_services();
+}
+
+// Methods for shared bitfields.
+
+// Gets the name of the shared bitfield for the given index.
+std::string GetBitFieldName(int index);
+
+// Gets the name of the shared bitfield for the given bit index.
+// Effectively, GetBitFieldName(bitIndex / 32)
+std::string GetBitFieldNameForBit(int bitIndex);
+
+// Generates the java code for the expression that returns the boolean value
+// of the bit of the shared bitfields for the given bit index.
+// Example: "((bitField1_ & 0x04) == 0x04)"
+std::string GenerateGetBit(int bitIndex);
+
+// Generates the java code for the expression that sets the bit of the shared
+// bitfields for the given bit index.
+// Example: "bitField1_ = (bitField1_ | 0x04)"
+std::string GenerateSetBit(int bitIndex);
+
+// Generates the java code for the expression that clears the bit of the shared
+// bitfields for the given bit index.
+// Example: "bitField1_ = (bitField1_ & ~0x04)"
+std::string GenerateClearBit(int bitIndex);
+
+// Does the same as GenerateGetBit but operates on the bit field on a local
+// variable. This is used by the builder to copy the value in the builder to
+// the message.
+// Example: "((from_bitField1_ & 0x04) == 0x04)"
+std::string GenerateGetBitFromLocal(int bitIndex);
+
+// Does the same as GenerateSetBit but operates on the bit field on a local
+// variable. This is used by the builder to copy the value in the builder to
+// the message.
+// Example: "to_bitField1_ = (to_bitField1_ | 0x04)"
+std::string GenerateSetBitToLocal(int bitIndex);
+
+// Does the same as GenerateGetBit but operates on the bit field on a local
+// variable. This is used by the parsing constructor to record if a repeated
+// field is mutable.
+// Example: "((mutable_bitField1_ & 0x04) == 0x04)"
+std::string GenerateGetBitMutableLocal(int bitIndex);
+
+// Does the same as GenerateSetBit but operates on the bit field on a local
+// variable. This is used by the parsing constructor to record if a repeated
+// field is mutable.
+// Example: "mutable_bitField1_ = (mutable_bitField1_ | 0x04)"
+std::string GenerateSetBitMutableLocal(int bitIndex);
+
+// Returns whether the JavaType is a reference type.
+bool IsReferenceType(JavaType type);
+
+// Returns the capitalized name for calling relative functions in
+// CodedInputStream
+const char* GetCapitalizedType(const FieldDescriptor* field, bool immutable);
+
+// For encodings with fixed sizes, returns that size in bytes. Otherwise
+// returns -1.
+int FixedSize(FieldDescriptor::Type type);
+
+// Comparators used to sort fields in MessageGenerator
+struct FieldOrderingByNumber {
+ inline bool operator()(const FieldDescriptor* a,
+ const FieldDescriptor* b) const {
+ return a->number() < b->number();
+ }
+};
+
+struct ExtensionRangeOrdering {
+ bool operator()(const Descriptor::ExtensionRange* a,
+ const Descriptor::ExtensionRange* b) const {
+ return a->start < b->start;
+ }
+};
+
+// Sort the fields of the given Descriptor by number into a new[]'d array
+// and return it. The caller should delete the returned array.
+const FieldDescriptor** SortFieldsByNumber(const Descriptor* descriptor);
+
+// Does this message class have any packed fields?
+inline bool HasPackedFields(const Descriptor* descriptor) {
+ for (int i = 0; i < descriptor->field_count(); i++) {
+ if (descriptor->field(i)->is_packed()) {
+ return true;
+ }
+ }
+ return false;
+}
+
+// Check a message type and its sub-message types recursively to see if any of
+// them has a required field. Return true if a required field is found.
+bool HasRequiredFields(const Descriptor* descriptor);
+
+inline bool IsProto2(const FileDescriptor* descriptor) {
+ return descriptor->syntax() == FileDescriptor::SYNTAX_PROTO2;
+}
+
+inline bool IsRealOneof(const FieldDescriptor* descriptor) {
+ return descriptor->containing_oneof() &&
+ !descriptor->containing_oneof()->is_synthetic();
+}
+
+inline bool HasHazzer(const FieldDescriptor* descriptor) {
+ return !descriptor->is_repeated() &&
+ (descriptor->message_type() || descriptor->has_optional_keyword() ||
+ IsProto2(descriptor->file()) || IsRealOneof(descriptor));
+}
+
+inline bool HasHasbit(const FieldDescriptor* descriptor) {
+ // Note that currently message fields inside oneofs have hasbits. This is
+ // surprising, as the oneof case should avoid any need for a hasbit. But if
+ // you change this method to remove hasbits for oneofs, a few tests fail.
+ // TODO(b/124347790): remove hasbits for oneofs
+ return !descriptor->is_repeated() &&
+ (descriptor->has_optional_keyword() || IsProto2(descriptor->file()));
+}
+
+// Whether generate classes expose public PARSER instances.
+inline bool ExposePublicParser(const FileDescriptor* descriptor) {
+ // TODO(liujisi): Mark the PARSER private in 3.1.x releases.
+ return descriptor->syntax() == FileDescriptor::SYNTAX_PROTO2;
+}
+
+// Whether unknown enum values are kept (i.e., not stored in UnknownFieldSet
+// but in the message and can be queried using additional getters that return
+// ints.
+inline bool SupportUnknownEnumValue(const FileDescriptor* descriptor) {
+ return descriptor->syntax() == FileDescriptor::SYNTAX_PROTO3;
+}
+
+inline bool SupportUnknownEnumValue(const FieldDescriptor* field) {
+ return field->file()->syntax() == FileDescriptor::SYNTAX_PROTO3;
+}
+
+// Check whether a message has repeated fields.
+bool HasRepeatedFields(const Descriptor* descriptor);
+
+inline bool IsMapEntry(const Descriptor* descriptor) {
+ return descriptor->options().map_entry();
+}
+
+inline bool IsMapField(const FieldDescriptor* descriptor) {
+ return descriptor->is_map();
+}
+
+inline bool IsAnyMessage(const Descriptor* descriptor) {
+ return descriptor->full_name() == "google.protobuf.Any";
+}
+
+inline bool IsWrappersProtoFile(const FileDescriptor* descriptor) {
+ return descriptor->name() == "google/protobuf/wrappers.proto";
+}
+
+inline bool CheckUtf8(const FieldDescriptor* descriptor) {
+ return descriptor->file()->syntax() == FileDescriptor::SYNTAX_PROTO3 ||
+ descriptor->file()->options().java_string_check_utf8();
+}
+
+inline std::string GeneratedCodeVersionSuffix() {
+ return "V3";
+}
+
+void WriteUInt32ToUtf16CharSequence(uint32_t number,
+ std::vector<uint16_t>* output);
+
+inline void WriteIntToUtf16CharSequence(int value,
+ std::vector<uint16_t>* output) {
+ WriteUInt32ToUtf16CharSequence(static_cast<uint32_t>(value), output);
+}
+
+// Escape a UTF-16 character so it can be embedded in a Java string literal.
+void EscapeUtf16ToString(uint16_t code, std::string* output);
+
+// Only the lowest two bytes of the return value are used. The lowest byte
+// is the integer value of a j/c/g/protobuf/FieldType enum. For the other
+// byte:
+// bit 0: whether the field is required.
+// bit 1: whether the field requires UTF-8 validation.
+// bit 2: whether the field needs isInitialized check.
+// bit 3: whether the field is a map field with proto2 enum value.
+// bits 4-7: unused
+int GetExperimentalJavaFieldType(const FieldDescriptor* field);
+
+// To get the total number of entries need to be built for experimental runtime
+// and the first field number that are not in the table part
+std::pair<int, int> GetTableDrivenNumberOfEntriesAndLookUpStartFieldNumber(
+ const FieldDescriptor** fields, int count);
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_HELPERS_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_kotlin_generator.cc b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_kotlin_generator.cc
new file mode 100644
index 00000000..d043ed80
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_kotlin_generator.cc
@@ -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.
+
+#include <compiler/java/java_kotlin_generator.h>
+
+#include <compiler/java/java_file.h>
+#include <compiler/java/java_helpers.h>
+#include <compiler/java/java_options.h>
+#include <compiler/java/java_generator.h>
+#include <compiler/code_generator.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+KotlinGenerator::KotlinGenerator() {}
+KotlinGenerator::~KotlinGenerator() {}
+
+uint64_t KotlinGenerator::GetSupportedFeatures() const {
+ return CodeGenerator::Feature::FEATURE_PROTO3_OPTIONAL;
+}
+
+bool KotlinGenerator::Generate(const FileDescriptor* file,
+ const std::string& parameter,
+ GeneratorContext* context,
+ std::string* error) const {
+ // -----------------------------------------------------------------
+ // parse generator options
+
+ std::vector<std::pair<std::string, std::string> > options;
+ ParseGeneratorParameter(parameter, &options);
+ Options file_options;
+
+ for (auto& option : options) {
+ if (option.first == "output_list_file") {
+ file_options.output_list_file = option.second;
+ } else if (option.first == "immutable") {
+ file_options.generate_immutable_code = true;
+ } else if (option.first == "mutable") {
+ *error = "Mutable not supported by Kotlin generator";
+ return false;
+ } else if (option.first == "shared") {
+ file_options.generate_shared_code = true;
+ } else if (option.first == "lite") {
+ file_options.enforce_lite = true;
+ } else if (option.first == "annotate_code") {
+ file_options.annotate_code = true;
+ } else if (option.first == "annotation_list_file") {
+ file_options.annotation_list_file = option.second;
+ } else {
+ *error = "Unknown generator option: " + option.first;
+ return false;
+ }
+ }
+
+ // By default we generate immutable code and shared code for immutable API.
+ if (!file_options.generate_immutable_code &&
+ !file_options.generate_shared_code) {
+ file_options.generate_immutable_code = true;
+ file_options.generate_shared_code = true;
+ }
+
+ std::vector<std::string> all_files;
+ std::vector<std::string> all_annotations;
+
+ std::unique_ptr<FileGenerator> file_generator;
+ if (file_options.generate_immutable_code) {
+ file_generator.reset(
+ new FileGenerator(file, file_options, /* immutable_api = */ true));
+ }
+
+ if (!file_generator->Validate(error)) {
+ return false;
+ }
+
+ auto open_file = [context](const std::string& filename) {
+ return std::unique_ptr<io::ZeroCopyOutputStream>(context->Open(filename));
+ };
+ std::string package_dir = JavaPackageToDir(file_generator->java_package());
+ std::string kotlin_filename = package_dir;
+ kotlin_filename += file_generator->GetKotlinClassname();
+ kotlin_filename += ".kt";
+ all_files.push_back(kotlin_filename);
+ std::string info_full_path = kotlin_filename + ".pb.meta";
+ if (file_options.annotate_code) {
+ all_annotations.push_back(info_full_path);
+ }
+
+ // Generate main kotlin file.
+ auto output = open_file(kotlin_filename);
+ GeneratedCodeInfo annotations;
+ io::AnnotationProtoCollector<GeneratedCodeInfo> annotation_collector(
+ &annotations);
+ io::Printer printer(
+ output.get(), '$',
+ file_options.annotate_code ? &annotation_collector : nullptr);
+
+ file_generator->GenerateKotlinSiblings(package_dir, context, &all_files,
+ &all_annotations);
+
+ if (file_options.annotate_code) {
+ auto info_output = open_file(info_full_path);
+ annotations.SerializeToZeroCopyStream(info_output.get());
+ }
+
+ // Generate output list if requested.
+ if (!file_options.output_list_file.empty()) {
+ // Generate output list. This is just a simple text file placed in a
+ // deterministic location which lists the .kt files being generated.
+ auto srclist_raw_output = open_file(file_options.output_list_file);
+ io::Printer srclist_printer(srclist_raw_output.get(), '$');
+ for (auto& all_file : all_files) {
+ srclist_printer.Print("$filename$\n", "filename", all_file);
+ }
+ }
+
+ if (!file_options.annotation_list_file.empty()) {
+ // Generate output list. This is just a simple text file placed in a
+ // deterministic location which lists the .kt files being generated.
+ auto annotation_list_raw_output =
+ open_file(file_options.annotation_list_file);
+ io::Printer annotation_list_printer(annotation_list_raw_output.get(), '$');
+ for (auto& all_annotation : all_annotations) {
+ annotation_list_printer.Print("$filename$\n", "filename", all_annotation);
+ }
+ }
+
+ return true;
+}
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_kotlin_generator.h b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_kotlin_generator.h
new file mode 100644
index 00000000..87ae2507
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_kotlin_generator.h
@@ -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.
+
+// Generates Kotlin code for a given .proto file.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_KOTLIN_GENERATOR_H__
+#define GOOGLE_PROTOBUF_COMPILER_JAVA_KOTLIN_GENERATOR_H__
+
+#include <string>
+
+#include <compiler/code_generator.h>
+#include <port_def.inc>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+// CodeGenerator implementation which generates Kotlin code. If you create your
+// own protocol compiler binary and you want it to support Kotlin output, you
+// can do so by registering an instance of this CodeGenerator with the
+// CommandLineInterface in your main() function.
+class PROTOC_EXPORT KotlinGenerator : public CodeGenerator {
+ public:
+ KotlinGenerator();
+ ~KotlinGenerator() override;
+
+ // implements CodeGenerator ----------------------------------------
+ bool Generate(const FileDescriptor* file, const std::string& parameter,
+ GeneratorContext* context, std::string* error) const override;
+
+ uint64_t GetSupportedFeatures() const override;
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(KotlinGenerator);
+};
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#include <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_KOTLIN_GENERATOR_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_map_field.cc b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_map_field.cc
new file mode 100644
index 00000000..602e5954
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_map_field.cc
@@ -0,0 +1,876 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 <compiler/java/java_map_field.h>
+
+#include <compiler/java/java_context.h>
+#include <compiler/java/java_doc_comment.h>
+#include <compiler/java/java_helpers.h>
+#include <compiler/java/java_name_resolver.h>
+#include <io/printer.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+namespace {
+
+const FieldDescriptor* KeyField(const FieldDescriptor* descriptor) {
+ GOOGLE_CHECK_EQ(FieldDescriptor::TYPE_MESSAGE, descriptor->type());
+ const Descriptor* message = descriptor->message_type();
+ GOOGLE_CHECK(message->options().map_entry());
+ return message->FindFieldByName("key");
+}
+
+const FieldDescriptor* ValueField(const FieldDescriptor* descriptor) {
+ GOOGLE_CHECK_EQ(FieldDescriptor::TYPE_MESSAGE, descriptor->type());
+ const Descriptor* message = descriptor->message_type();
+ GOOGLE_CHECK(message->options().map_entry());
+ return message->FindFieldByName("value");
+}
+
+std::string TypeName(const FieldDescriptor* field,
+ ClassNameResolver* name_resolver, bool boxed) {
+ if (GetJavaType(field) == JAVATYPE_MESSAGE) {
+ return name_resolver->GetImmutableClassName(field->message_type());
+ } else if (GetJavaType(field) == JAVATYPE_ENUM) {
+ return name_resolver->GetImmutableClassName(field->enum_type());
+ } else {
+ return boxed ? BoxedPrimitiveTypeName(GetJavaType(field))
+ : PrimitiveTypeName(GetJavaType(field));
+ }
+}
+
+std::string KotlinTypeName(const FieldDescriptor* field,
+ ClassNameResolver* name_resolver) {
+ if (GetJavaType(field) == JAVATYPE_MESSAGE) {
+ return name_resolver->GetImmutableClassName(field->message_type());
+ } else if (GetJavaType(field) == JAVATYPE_ENUM) {
+ return name_resolver->GetImmutableClassName(field->enum_type());
+ } else {
+ return KotlinTypeName(GetJavaType(field));
+ }
+}
+
+std::string WireType(const FieldDescriptor* field) {
+ return "com.google.protobuf.WireFormat.FieldType." +
+ std::string(FieldTypeName(field->type()));
+}
+
+void SetMessageVariables(const FieldDescriptor* descriptor, int messageBitIndex,
+ int builderBitIndex, const FieldGeneratorInfo* info,
+ Context* context,
+ std::map<std::string, std::string>* variables) {
+ SetCommonFieldVariables(descriptor, info, variables);
+ ClassNameResolver* name_resolver = context->GetNameResolver();
+
+ (*variables)["type"] =
+ name_resolver->GetImmutableClassName(descriptor->message_type());
+ const FieldDescriptor* key = KeyField(descriptor);
+ const FieldDescriptor* value = ValueField(descriptor);
+ const JavaType keyJavaType = GetJavaType(key);
+ const JavaType valueJavaType = GetJavaType(value);
+
+ (*variables)["key_type"] = TypeName(key, name_resolver, false);
+ std::string boxed_key_type = TypeName(key, name_resolver, true);
+ (*variables)["boxed_key_type"] = boxed_key_type;
+ (*variables)["kt_key_type"] = KotlinTypeName(key, name_resolver);
+ (*variables)["kt_value_type"] = KotlinTypeName(value, name_resolver);
+ // Used for calling the serialization function.
+ (*variables)["short_key_type"] =
+ boxed_key_type.substr(boxed_key_type.rfind('.') + 1);
+ (*variables)["key_wire_type"] = WireType(key);
+ (*variables)["key_default_value"] = DefaultValue(key, true, name_resolver);
+ (*variables)["key_null_check"] =
+ IsReferenceType(keyJavaType)
+ ? "if (key == null) { throw new NullPointerException(\"map key\"); }"
+ : "";
+ (*variables)["value_null_check"] =
+ valueJavaType != JAVATYPE_ENUM && IsReferenceType(valueJavaType)
+ ? "if (value == null) {\n"
+ " throw new NullPointerException(\"map value\");\n"
+ "}\n"
+ : "";
+ if (valueJavaType == JAVATYPE_ENUM) {
+ // We store enums as Integers internally.
+ (*variables)["value_type"] = "int";
+ (*variables)["boxed_value_type"] = "java.lang.Integer";
+ (*variables)["value_wire_type"] = WireType(value);
+ (*variables)["value_default_value"] =
+ DefaultValue(value, true, name_resolver) + ".getNumber()";
+
+ (*variables)["value_enum_type"] = TypeName(value, name_resolver, false);
+
+ if (SupportUnknownEnumValue(descriptor->file())) {
+ // Map unknown values to a special UNRECOGNIZED value if supported.
+ (*variables)["unrecognized_value"] =
+ (*variables)["value_enum_type"] + ".UNRECOGNIZED";
+ } else {
+ // Map unknown values to the default value if we don't have UNRECOGNIZED.
+ (*variables)["unrecognized_value"] =
+ DefaultValue(value, true, name_resolver);
+ }
+ } else {
+ (*variables)["value_type"] = TypeName(value, name_resolver, false);
+ (*variables)["boxed_value_type"] = TypeName(value, name_resolver, true);
+ (*variables)["value_wire_type"] = WireType(value);
+ (*variables)["value_default_value"] =
+ DefaultValue(value, true, name_resolver);
+ }
+ (*variables)["type_parameters"] =
+ (*variables)["boxed_key_type"] + ", " + (*variables)["boxed_value_type"];
+ // TODO(birdo): Add @deprecated javadoc when generating javadoc is supported
+ // by the proto compiler
+ (*variables)["deprecation"] =
+ descriptor->options().deprecated() ? "@java.lang.Deprecated " : "";
+ (*variables)["kt_deprecation"] =
+ descriptor->options().deprecated()
+ ? "@kotlin.Deprecated(message = \"Field " + (*variables)["name"] +
+ " is deprecated\") "
+ : "";
+ (*variables)["on_changed"] = "onChanged();";
+
+ // For repeated fields, one bit is used for whether the array is immutable
+ // in the parsing constructor.
+ (*variables)["get_mutable_bit_parser"] =
+ GenerateGetBitMutableLocal(builderBitIndex);
+ (*variables)["set_mutable_bit_parser"] =
+ GenerateSetBitMutableLocal(builderBitIndex);
+
+ (*variables)["default_entry"] =
+ (*variables)["capitalized_name"] + "DefaultEntryHolder.defaultEntry";
+ (*variables)["map_field_parameter"] = (*variables)["default_entry"];
+ (*variables)["descriptor"] =
+ name_resolver->GetImmutableClassName(descriptor->file()) + ".internal_" +
+ UniqueFileScopeIdentifier(descriptor->message_type()) + "_descriptor, ";
+ (*variables)["ver"] = GeneratedCodeVersionSuffix();
+}
+
+} // namespace
+
+ImmutableMapFieldGenerator::ImmutableMapFieldGenerator(
+ const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex,
+ Context* context)
+ : descriptor_(descriptor), name_resolver_(context->GetNameResolver()) {
+ SetMessageVariables(descriptor, messageBitIndex, builderBitIndex,
+ context->GetFieldGeneratorInfo(descriptor), context,
+ &variables_);
+}
+
+ImmutableMapFieldGenerator::~ImmutableMapFieldGenerator() {}
+
+int ImmutableMapFieldGenerator::GetNumBitsForMessage() const { return 0; }
+
+int ImmutableMapFieldGenerator::GetNumBitsForBuilder() const { return 1; }
+
+void ImmutableMapFieldGenerator::GenerateInterfaceMembers(
+ io::Printer* printer) const {
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$int ${$get$capitalized_name$Count$}$();\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$boolean ${$contains$capitalized_name$$}$(\n"
+ " $key_type$ key);\n");
+ printer->Annotate("{", "}", descriptor_);
+ if (GetJavaType(ValueField(descriptor_)) == JAVATYPE_ENUM) {
+ printer->Print(variables_,
+ "/**\n"
+ " * Use {@link #get$capitalized_name$Map()} instead.\n"
+ " */\n"
+ "@java.lang.Deprecated\n"
+ "java.util.Map<$boxed_key_type$, $value_enum_type$>\n"
+ "${$get$capitalized_name$$}$();\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "$deprecation$java.util.Map<$boxed_key_type$, $value_enum_type$>\n"
+ "${$get$capitalized_name$Map$}$();\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "$deprecation$$value_enum_type$ ${$get$capitalized_name$OrDefault$}$(\n"
+ " $key_type$ key,\n"
+ " $value_enum_type$ defaultValue);\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "$deprecation$$value_enum_type$ ${$get$capitalized_name$OrThrow$}$(\n"
+ " $key_type$ key);\n");
+ printer->Annotate("{", "}", descriptor_);
+ if (SupportUnknownEnumValue(descriptor_->file())) {
+ printer->Print(
+ variables_,
+ "/**\n"
+ " * Use {@link #get$capitalized_name$ValueMap()} instead.\n"
+ " */\n"
+ "@java.lang.Deprecated\n"
+ "java.util.Map<$type_parameters$>\n"
+ "${$get$capitalized_name$Value$}$();\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$java.util.Map<$type_parameters$>\n"
+ "${$get$capitalized_name$ValueMap$}$();\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$\n"
+ "$value_type$ ${$get$capitalized_name$ValueOrDefault$}$(\n"
+ " $key_type$ key,\n"
+ " $value_type$ defaultValue);\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$\n"
+ "$value_type$ ${$get$capitalized_name$ValueOrThrow$}$(\n"
+ " $key_type$ key);\n");
+ printer->Annotate("{", "}", descriptor_);
+ }
+ } else {
+ printer->Print(variables_,
+ "/**\n"
+ " * Use {@link #get$capitalized_name$Map()} instead.\n"
+ " */\n"
+ "@java.lang.Deprecated\n"
+ "java.util.Map<$type_parameters$>\n"
+ "${$get$capitalized_name$$}$();\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$java.util.Map<$type_parameters$>\n"
+ "${$get$capitalized_name$Map$}$();\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$\n"
+ "$value_type$ ${$get$capitalized_name$OrDefault$}$(\n"
+ " $key_type$ key,\n"
+ " $value_type$ defaultValue);\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$\n"
+ "$value_type$ ${$get$capitalized_name$OrThrow$}$(\n"
+ " $key_type$ key);\n");
+ printer->Annotate("{", "}", descriptor_);
+ }
+}
+
+void ImmutableMapFieldGenerator::GenerateMembers(io::Printer* printer) const {
+ printer->Print(
+ variables_,
+ "private static final class $capitalized_name$DefaultEntryHolder {\n"
+ " static final com.google.protobuf.MapEntry<\n"
+ " $type_parameters$> defaultEntry =\n"
+ " com.google.protobuf.MapEntry\n"
+ " .<$type_parameters$>newDefaultInstance(\n"
+ " $descriptor$\n"
+ " $key_wire_type$,\n"
+ " $key_default_value$,\n"
+ " $value_wire_type$,\n"
+ " $value_default_value$);\n"
+ "}\n");
+ printer->Print(variables_,
+ "private com.google.protobuf.MapField<\n"
+ " $type_parameters$> $name$_;\n"
+ "private com.google.protobuf.MapField<$type_parameters$>\n"
+ "internalGet$capitalized_name$() {\n"
+ " if ($name$_ == null) {\n"
+ " return com.google.protobuf.MapField.emptyMapField(\n"
+ " $map_field_parameter$);\n"
+ " }\n"
+ " return $name$_;\n"
+ "}\n");
+ if (GetJavaType(ValueField(descriptor_)) == JAVATYPE_ENUM) {
+ printer->Print(
+ variables_,
+ "private static final\n"
+ "com.google.protobuf.Internal.MapAdapter.Converter<\n"
+ " java.lang.Integer, $value_enum_type$> $name$ValueConverter =\n"
+ " com.google.protobuf.Internal.MapAdapter.newEnumConverter(\n"
+ " $value_enum_type$.internalGetValueMap(),\n"
+ " $unrecognized_value$);\n");
+ printer->Print(
+ variables_,
+ "private static final java.util.Map<$boxed_key_type$, "
+ "$value_enum_type$>\n"
+ "internalGetAdapted$capitalized_name$Map(\n"
+ " java.util.Map<$boxed_key_type$, $boxed_value_type$> map) {\n"
+ " return new com.google.protobuf.Internal.MapAdapter<\n"
+ " $boxed_key_type$, $value_enum_type$, java.lang.Integer>(\n"
+ " map, $name$ValueConverter);\n"
+ "}\n");
+ }
+ GenerateMapGetters(printer);
+}
+
+void ImmutableMapFieldGenerator::GenerateBuilderMembers(
+ io::Printer* printer) const {
+ printer->Print(variables_,
+ "private com.google.protobuf.MapField<\n"
+ " $type_parameters$> $name$_;\n"
+ "private com.google.protobuf.MapField<$type_parameters$>\n"
+ "internalGet$capitalized_name$() {\n"
+ " if ($name$_ == null) {\n"
+ " return com.google.protobuf.MapField.emptyMapField(\n"
+ " $map_field_parameter$);\n"
+ " }\n"
+ " return $name$_;\n"
+ "}\n"
+ "private com.google.protobuf.MapField<$type_parameters$>\n"
+ "internalGetMutable$capitalized_name$() {\n"
+ " $on_changed$;\n"
+ " if ($name$_ == null) {\n"
+ " $name$_ = com.google.protobuf.MapField.newMapField(\n"
+ " $map_field_parameter$);\n"
+ " }\n"
+ " if (!$name$_.isMutable()) {\n"
+ " $name$_ = $name$_.copy();\n"
+ " }\n"
+ " return $name$_;\n"
+ "}\n");
+ GenerateMapGetters(printer);
+ printer->Print(variables_,
+ "$deprecation$\n"
+ "public Builder ${$clear$capitalized_name$$}$() {\n"
+ " internalGetMutable$capitalized_name$().getMutableMap()\n"
+ " .clear();\n"
+ " return this;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$\n"
+ "public Builder ${$remove$capitalized_name$$}$(\n"
+ " $key_type$ key) {\n"
+ " $key_null_check$\n"
+ " internalGetMutable$capitalized_name$().getMutableMap()\n"
+ " .remove(key);\n"
+ " return this;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ if (GetJavaType(ValueField(descriptor_)) == JAVATYPE_ENUM) {
+ printer->Print(
+ variables_,
+ "/**\n"
+ " * Use alternate mutation accessors instead.\n"
+ " */\n"
+ "@java.lang.Deprecated\n"
+ "public java.util.Map<$boxed_key_type$, $value_enum_type$>\n"
+ "${$getMutable$capitalized_name$$}$() {\n"
+ " return internalGetAdapted$capitalized_name$Map(\n"
+ " internalGetMutable$capitalized_name$().getMutableMap());\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public Builder ${$put$capitalized_name$$}$(\n"
+ " $key_type$ key,\n"
+ " $value_enum_type$ value) {\n"
+ " $key_null_check$\n"
+ " $value_null_check$\n"
+ " internalGetMutable$capitalized_name$().getMutableMap()\n"
+ " .put(key, $name$ValueConverter.doBackward(value));\n"
+ " return this;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "$deprecation$public Builder ${$putAll$capitalized_name$$}$(\n"
+ " java.util.Map<$boxed_key_type$, $value_enum_type$> values) {\n"
+ " internalGetAdapted$capitalized_name$Map(\n"
+ " internalGetMutable$capitalized_name$().getMutableMap())\n"
+ " .putAll(values);\n"
+ " return this;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ if (SupportUnknownEnumValue(descriptor_->file())) {
+ printer->Print(
+ variables_,
+ "/**\n"
+ " * Use alternate mutation accessors instead.\n"
+ " */\n"
+ "@java.lang.Deprecated\n"
+ "public java.util.Map<$boxed_key_type$, $boxed_value_type$>\n"
+ "${$getMutable$capitalized_name$Value$}$() {\n"
+ " return internalGetMutable$capitalized_name$().getMutableMap();\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "$deprecation$public Builder ${$put$capitalized_name$Value$}$(\n"
+ " $key_type$ key,\n"
+ " $value_type$ value) {\n"
+ " $key_null_check$\n"
+ " $value_null_check$\n"
+ " internalGetMutable$capitalized_name$().getMutableMap()\n"
+ " .put(key, value);\n"
+ " return this;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "$deprecation$public Builder ${$putAll$capitalized_name$Value$}$(\n"
+ " java.util.Map<$boxed_key_type$, $boxed_value_type$> values) {\n"
+ " internalGetMutable$capitalized_name$().getMutableMap()\n"
+ " .putAll(values);\n"
+ " return this;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ }
+ } else {
+ printer->Print(
+ variables_,
+ "/**\n"
+ " * Use alternate mutation accessors instead.\n"
+ " */\n"
+ "@java.lang.Deprecated\n"
+ "public java.util.Map<$type_parameters$>\n"
+ "${$getMutable$capitalized_name$$}$() {\n"
+ " return internalGetMutable$capitalized_name$().getMutableMap();\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$"
+ "public Builder ${$put$capitalized_name$$}$(\n"
+ " $key_type$ key,\n"
+ " $value_type$ value) {\n"
+ " $key_null_check$\n"
+ " $value_null_check$\n"
+ " internalGetMutable$capitalized_name$().getMutableMap()\n"
+ " .put(key, value);\n"
+ " return this;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$\n"
+ "public Builder ${$putAll$capitalized_name$$}$(\n"
+ " java.util.Map<$type_parameters$> values) {\n"
+ " internalGetMutable$capitalized_name$().getMutableMap()\n"
+ " .putAll(values);\n"
+ " return this;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ }
+}
+
+void ImmutableMapFieldGenerator::GenerateMapGetters(
+ io::Printer* printer) const {
+ printer->Print(variables_,
+ "$deprecation$\n"
+ "public int ${$get$capitalized_name$Count$}$() {\n"
+ " return internalGet$capitalized_name$().getMap().size();\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "$deprecation$\n"
+ "@java.lang.Override\n"
+ "public boolean ${$contains$capitalized_name$$}$(\n"
+ " $key_type$ key) {\n"
+ " $key_null_check$\n"
+ " return internalGet$capitalized_name$().getMap().containsKey(key);\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ if (GetJavaType(ValueField(descriptor_)) == JAVATYPE_ENUM) {
+ printer->Print(variables_,
+ "/**\n"
+ " * Use {@link #get$capitalized_name$Map()} instead.\n"
+ " */\n"
+ "@java.lang.Override\n"
+ "@java.lang.Deprecated\n"
+ "public java.util.Map<$boxed_key_type$, $value_enum_type$>\n"
+ "${$get$capitalized_name$$}$() {\n"
+ " return get$capitalized_name$Map();\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "@java.lang.Override\n"
+ "$deprecation$\n"
+ "public java.util.Map<$boxed_key_type$, $value_enum_type$>\n"
+ "${$get$capitalized_name$Map$}$() {\n"
+ " return internalGetAdapted$capitalized_name$Map(\n"
+ " internalGet$capitalized_name$().getMap());"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "@java.lang.Override\n"
+ "$deprecation$\n"
+ "public $value_enum_type$ ${$get$capitalized_name$OrDefault$}$(\n"
+ " $key_type$ key,\n"
+ " $value_enum_type$ defaultValue) {\n"
+ " $key_null_check$\n"
+ " java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n"
+ " internalGet$capitalized_name$().getMap();\n"
+ " return map.containsKey(key)\n"
+ " ? $name$ValueConverter.doForward(map.get(key))\n"
+ " : defaultValue;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "@java.lang.Override\n"
+ "$deprecation$\n"
+ "public $value_enum_type$ ${$get$capitalized_name$OrThrow$}$(\n"
+ " $key_type$ key) {\n"
+ " $key_null_check$\n"
+ " java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n"
+ " internalGet$capitalized_name$().getMap();\n"
+ " if (!map.containsKey(key)) {\n"
+ " throw new java.lang.IllegalArgumentException();\n"
+ " }\n"
+ " return $name$ValueConverter.doForward(map.get(key));\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ if (SupportUnknownEnumValue(descriptor_->file())) {
+ printer->Print(
+ variables_,
+ "/**\n"
+ " * Use {@link #get$capitalized_name$ValueMap()} instead.\n"
+ " */\n"
+ "@java.lang.Override\n"
+ "@java.lang.Deprecated\n"
+ "public java.util.Map<$boxed_key_type$, $boxed_value_type$>\n"
+ "${$get$capitalized_name$Value$}$() {\n"
+ " return get$capitalized_name$ValueMap();\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "@java.lang.Override\n"
+ "$deprecation$\n"
+ "public java.util.Map<$boxed_key_type$, $boxed_value_type$>\n"
+ "${$get$capitalized_name$ValueMap$}$() {\n"
+ " return internalGet$capitalized_name$().getMap();\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "@java.lang.Override\n"
+ "$deprecation$\n"
+ "public $value_type$ ${$get$capitalized_name$ValueOrDefault$}$(\n"
+ " $key_type$ key,\n"
+ " $value_type$ defaultValue) {\n"
+ " $key_null_check$\n"
+ " java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n"
+ " internalGet$capitalized_name$().getMap();\n"
+ " return map.containsKey(key) ? map.get(key) : defaultValue;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "@java.lang.Override\n"
+ "$deprecation$\n"
+ "public $value_type$ ${$get$capitalized_name$ValueOrThrow$}$(\n"
+ " $key_type$ key) {\n"
+ " $key_null_check$\n"
+ " java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n"
+ " internalGet$capitalized_name$().getMap();\n"
+ " if (!map.containsKey(key)) {\n"
+ " throw new java.lang.IllegalArgumentException();\n"
+ " }\n"
+ " return map.get(key);\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ }
+ } else {
+ printer->Print(variables_,
+ "/**\n"
+ " * Use {@link #get$capitalized_name$Map()} instead.\n"
+ " */\n"
+ "@java.lang.Override\n"
+ "@java.lang.Deprecated\n"
+ "public java.util.Map<$type_parameters$> "
+ "${$get$capitalized_name$$}$() {\n"
+ " return get$capitalized_name$Map();\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "@java.lang.Override\n"
+ "$deprecation$\n"
+ "public java.util.Map<$type_parameters$> "
+ "${$get$capitalized_name$Map$}$() {\n"
+ " return internalGet$capitalized_name$().getMap();\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "@java.lang.Override\n"
+ "$deprecation$\n"
+ "public $value_type$ ${$get$capitalized_name$OrDefault$}$(\n"
+ " $key_type$ key,\n"
+ " $value_type$ defaultValue) {\n"
+ " $key_null_check$\n"
+ " java.util.Map<$type_parameters$> map =\n"
+ " internalGet$capitalized_name$().getMap();\n"
+ " return map.containsKey(key) ? map.get(key) : defaultValue;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "@java.lang.Override\n"
+ "$deprecation$\n"
+ "public $value_type$ ${$get$capitalized_name$OrThrow$}$(\n"
+ " $key_type$ key) {\n"
+ " $key_null_check$\n"
+ " java.util.Map<$type_parameters$> map =\n"
+ " internalGet$capitalized_name$().getMap();\n"
+ " if (!map.containsKey(key)) {\n"
+ " throw new java.lang.IllegalArgumentException();\n"
+ " }\n"
+ " return map.get(key);\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ }
+}
+
+void ImmutableMapFieldGenerator::GenerateKotlinDslMembers(
+ io::Printer* printer) const {
+ printer->Print(
+ variables_,
+ "/**\n"
+ " * An uninstantiable, behaviorless type to represent the field in\n"
+ " * generics.\n"
+ " */\n"
+ "@kotlin.OptIn"
+ "(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)\n"
+ "public class ${$$kt_capitalized_name$Proxy$}$ private constructor()"
+ " : com.google.protobuf.kotlin.DslProxy()\n");
+
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "$kt_deprecation$ public val $kt_name$: "
+ "com.google.protobuf.kotlin.DslMap"
+ "<$kt_key_type$, $kt_value_type$, ${$$kt_capitalized_name$Proxy$}$>\n"
+ " @kotlin.jvm.JvmSynthetic\n"
+ " @JvmName(\"get$kt_capitalized_name$Map\")\n"
+ " get() = com.google.protobuf.kotlin.DslMap(\n"
+ " $kt_dsl_builder$.${$get$capitalized_name$Map$}$()\n"
+ " )\n");
+
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "@JvmName(\"put$kt_capitalized_name$\")\n"
+ "public fun com.google.protobuf.kotlin.DslMap"
+ "<$kt_key_type$, $kt_value_type$, ${$$kt_capitalized_name$Proxy$}$>\n"
+ " .put(key: $kt_key_type$, value: $kt_value_type$) {\n"
+ " $kt_dsl_builder$.${$put$capitalized_name$$}$(key, value)\n"
+ " }\n");
+
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "@kotlin.jvm.JvmSynthetic\n"
+ "@JvmName(\"set$kt_capitalized_name$\")\n"
+ "@Suppress(\"NOTHING_TO_INLINE\")\n"
+ "public inline operator fun com.google.protobuf.kotlin.DslMap"
+ "<$kt_key_type$, $kt_value_type$, ${$$kt_capitalized_name$Proxy$}$>\n"
+ " .set(key: $kt_key_type$, value: $kt_value_type$) {\n"
+ " put(key, value)\n"
+ " }\n");
+
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "@kotlin.jvm.JvmSynthetic\n"
+ "@JvmName(\"remove$kt_capitalized_name$\")\n"
+ "public fun com.google.protobuf.kotlin.DslMap"
+ "<$kt_key_type$, $kt_value_type$, ${$$kt_capitalized_name$Proxy$}$>\n"
+ " .remove(key: $kt_key_type$) {\n"
+ " $kt_dsl_builder$.${$remove$capitalized_name$$}$(key)\n"
+ " }\n");
+
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "@kotlin.jvm.JvmSynthetic\n"
+ "@JvmName(\"putAll$kt_capitalized_name$\")\n"
+ "public fun com.google.protobuf.kotlin.DslMap"
+ "<$kt_key_type$, $kt_value_type$, ${$$kt_capitalized_name$Proxy$}$>\n"
+ " .putAll(map: kotlin.collections.Map<$kt_key_type$, $kt_value_type$>) "
+ "{\n"
+ " $kt_dsl_builder$.${$putAll$capitalized_name$$}$(map)\n"
+ " }\n");
+
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "@kotlin.jvm.JvmSynthetic\n"
+ "@JvmName(\"clear$kt_capitalized_name$\")\n"
+ "public fun com.google.protobuf.kotlin.DslMap"
+ "<$kt_key_type$, $kt_value_type$, ${$$kt_capitalized_name$Proxy$}$>\n"
+ " .clear() {\n"
+ " $kt_dsl_builder$.${$clear$capitalized_name$$}$()\n"
+ " }\n");
+}
+
+void ImmutableMapFieldGenerator::GenerateFieldBuilderInitializationCode(
+ io::Printer* printer) const {
+ // Nothing to initialize.
+}
+
+void ImmutableMapFieldGenerator::GenerateInitializationCode(
+ io::Printer* printer) const {
+ // Nothing to initialize.
+}
+
+void ImmutableMapFieldGenerator::GenerateBuilderClearCode(
+ io::Printer* printer) const {
+ printer->Print(variables_,
+ "internalGetMutable$capitalized_name$().clear();\n");
+}
+
+void ImmutableMapFieldGenerator::GenerateMergingCode(
+ io::Printer* printer) const {
+ printer->Print(variables_,
+ "internalGetMutable$capitalized_name$().mergeFrom(\n"
+ " other.internalGet$capitalized_name$());\n");
+}
+
+void ImmutableMapFieldGenerator::GenerateBuildingCode(
+ io::Printer* printer) const {
+ printer->Print(variables_,
+ "result.$name$_ = internalGet$capitalized_name$();\n"
+ "result.$name$_.makeImmutable();\n");
+}
+
+void ImmutableMapFieldGenerator::GenerateParsingCode(
+ io::Printer* printer) const {
+ printer->Print(variables_,
+ "if (!$get_mutable_bit_parser$) {\n"
+ " $name$_ = com.google.protobuf.MapField.newMapField(\n"
+ " $map_field_parameter$);\n"
+ " $set_mutable_bit_parser$;\n"
+ "}\n");
+ if (!SupportUnknownEnumValue(descriptor_->file()) &&
+ GetJavaType(ValueField(descriptor_)) == JAVATYPE_ENUM) {
+ printer->Print(
+ variables_,
+ "com.google.protobuf.ByteString bytes = input.readBytes();\n"
+ "com.google.protobuf.MapEntry<$type_parameters$>\n"
+ "$name$__ = $default_entry$.getParserForType().parseFrom(bytes);\n");
+ printer->Print(
+ variables_,
+ "if ($value_enum_type$.forNumber($name$__.getValue()) == null) {\n"
+ " unknownFields.mergeLengthDelimitedField($number$, bytes);\n"
+ "} else {\n"
+ " $name$_.getMutableMap().put(\n"
+ " $name$__.getKey(), $name$__.getValue());\n"
+ "}\n");
+ } else {
+ printer->Print(
+ variables_,
+ "com.google.protobuf.MapEntry<$type_parameters$>\n"
+ "$name$__ = input.readMessage(\n"
+ " $default_entry$.getParserForType(), extensionRegistry);\n"
+ "$name$_.getMutableMap().put(\n"
+ " $name$__.getKey(), $name$__.getValue());\n");
+ }
+}
+
+void ImmutableMapFieldGenerator::GenerateParsingDoneCode(
+ io::Printer* printer) const {
+ // Nothing to do here.
+}
+
+void ImmutableMapFieldGenerator::GenerateSerializationCode(
+ io::Printer* printer) const {
+ printer->Print(variables_,
+ "com.google.protobuf.GeneratedMessage$ver$\n"
+ " .serialize$short_key_type$MapTo(\n"
+ " output,\n"
+ " internalGet$capitalized_name$(),\n"
+ " $default_entry$,\n"
+ " $number$);\n");
+}
+
+void ImmutableMapFieldGenerator::GenerateSerializedSizeCode(
+ io::Printer* printer) const {
+ printer->Print(
+ variables_,
+ "for (java.util.Map.Entry<$type_parameters$> entry\n"
+ " : internalGet$capitalized_name$().getMap().entrySet()) {\n"
+ " com.google.protobuf.MapEntry<$type_parameters$>\n"
+ " $name$__ = $default_entry$.newBuilderForType()\n"
+ " .setKey(entry.getKey())\n"
+ " .setValue(entry.getValue())\n"
+ " .build();\n"
+ " size += com.google.protobuf.CodedOutputStream\n"
+ " .computeMessageSize($number$, $name$__);\n"
+ "}\n");
+}
+
+void ImmutableMapFieldGenerator::GenerateEqualsCode(
+ io::Printer* printer) const {
+ printer->Print(variables_,
+ "if (!internalGet$capitalized_name$().equals(\n"
+ " other.internalGet$capitalized_name$())) return false;\n");
+}
+
+void ImmutableMapFieldGenerator::GenerateHashCode(io::Printer* printer) const {
+ printer->Print(
+ variables_,
+ "if (!internalGet$capitalized_name$().getMap().isEmpty()) {\n"
+ " hash = (37 * hash) + $constant_name$;\n"
+ " hash = (53 * hash) + internalGet$capitalized_name$().hashCode();\n"
+ "}\n");
+}
+
+std::string ImmutableMapFieldGenerator::GetBoxedType() const {
+ return name_resolver_->GetImmutableClassName(descriptor_->message_type());
+}
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_map_field.h b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_map_field.h
new file mode 100644
index 00000000..e309391f
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_map_field.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_COMPILER_JAVA_MAP_FIELD_H__
+#define GOOGLE_PROTOBUF_COMPILER_JAVA_MAP_FIELD_H__
+
+#include <compiler/java/java_field.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+class ImmutableMapFieldGenerator : public ImmutableFieldGenerator {
+ public:
+ explicit ImmutableMapFieldGenerator(const FieldDescriptor* descriptor,
+ int messageBitIndex, int builderBitIndex,
+ Context* context);
+ ~ImmutableMapFieldGenerator() override;
+
+ // implements ImmutableFieldGenerator ---------------------------------------
+ int GetNumBitsForMessage() const override;
+ int GetNumBitsForBuilder() const override;
+ void GenerateInterfaceMembers(io::Printer* printer) const override;
+ void GenerateMembers(io::Printer* printer) const override;
+ void GenerateBuilderMembers(io::Printer* printer) const override;
+ void GenerateInitializationCode(io::Printer* printer) const override;
+ void GenerateBuilderClearCode(io::Printer* printer) const override;
+ void GenerateMergingCode(io::Printer* printer) const override;
+ void GenerateBuildingCode(io::Printer* printer) const override;
+ void GenerateParsingCode(io::Printer* printer) const override;
+ void GenerateParsingDoneCode(io::Printer* printer) const override;
+ void GenerateSerializationCode(io::Printer* printer) const override;
+ void GenerateSerializedSizeCode(io::Printer* printer) const override;
+ void GenerateFieldBuilderInitializationCode(
+ io::Printer* printer) const override;
+ void GenerateEqualsCode(io::Printer* printer) const override;
+ void GenerateHashCode(io::Printer* printer) const override;
+ void GenerateKotlinDslMembers(io::Printer* printer) const override;
+
+ std::string GetBoxedType() const override;
+
+ private:
+ const FieldDescriptor* descriptor_;
+ std::map<std::string, std::string> variables_;
+ ClassNameResolver* name_resolver_;
+ void GenerateMapGetters(io::Printer* printer) const;
+};
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_MAP_FIELD_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_map_field_lite.cc b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_map_field_lite.cc
new file mode 100644
index 00000000..b210bc45
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_map_field_lite.cc
@@ -0,0 +1,909 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 <compiler/java/java_map_field_lite.h>
+
+#include <cstdint>
+
+#include <compiler/java/java_context.h>
+#include <compiler/java/java_doc_comment.h>
+#include <compiler/java/java_helpers.h>
+#include <compiler/java/java_name_resolver.h>
+#include <io/printer.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+namespace {
+
+const FieldDescriptor* KeyField(const FieldDescriptor* descriptor) {
+ GOOGLE_CHECK_EQ(FieldDescriptor::TYPE_MESSAGE, descriptor->type());
+ const Descriptor* message = descriptor->message_type();
+ GOOGLE_CHECK(message->options().map_entry());
+ return message->FindFieldByName("key");
+}
+
+const FieldDescriptor* ValueField(const FieldDescriptor* descriptor) {
+ GOOGLE_CHECK_EQ(FieldDescriptor::TYPE_MESSAGE, descriptor->type());
+ const Descriptor* message = descriptor->message_type();
+ GOOGLE_CHECK(message->options().map_entry());
+ return message->FindFieldByName("value");
+}
+
+std::string TypeName(const FieldDescriptor* field,
+ ClassNameResolver* name_resolver, bool boxed) {
+ if (GetJavaType(field) == JAVATYPE_MESSAGE) {
+ return name_resolver->GetImmutableClassName(field->message_type());
+ } else if (GetJavaType(field) == JAVATYPE_ENUM) {
+ return name_resolver->GetImmutableClassName(field->enum_type());
+ } else {
+ return boxed ? BoxedPrimitiveTypeName(GetJavaType(field))
+ : PrimitiveTypeName(GetJavaType(field));
+ }
+}
+
+std::string KotlinTypeName(const FieldDescriptor* field,
+ ClassNameResolver* name_resolver) {
+ if (GetJavaType(field) == JAVATYPE_MESSAGE) {
+ return name_resolver->GetImmutableClassName(field->message_type());
+ } else if (GetJavaType(field) == JAVATYPE_ENUM) {
+ return name_resolver->GetImmutableClassName(field->enum_type());
+ } else {
+ return KotlinTypeName(GetJavaType(field));
+ }
+}
+
+std::string WireType(const FieldDescriptor* field) {
+ return "com.google.protobuf.WireFormat.FieldType." +
+ std::string(FieldTypeName(field->type()));
+}
+
+void SetMessageVariables(const FieldDescriptor* descriptor, int messageBitIndex,
+ int builderBitIndex, const FieldGeneratorInfo* info,
+ Context* context,
+ std::map<std::string, std::string>* variables) {
+ SetCommonFieldVariables(descriptor, info, variables);
+
+ ClassNameResolver* name_resolver = context->GetNameResolver();
+ (*variables)["type"] =
+ name_resolver->GetImmutableClassName(descriptor->message_type());
+ const FieldDescriptor* key = KeyField(descriptor);
+ const FieldDescriptor* value = ValueField(descriptor);
+ const JavaType keyJavaType = GetJavaType(key);
+ const JavaType valueJavaType = GetJavaType(value);
+
+ (*variables)["key_type"] = TypeName(key, name_resolver, false);
+ (*variables)["boxed_key_type"] = TypeName(key, name_resolver, true);
+ (*variables)["kt_key_type"] = KotlinTypeName(key, name_resolver);
+ (*variables)["kt_value_type"] = KotlinTypeName(value, name_resolver);
+ (*variables)["key_wire_type"] = WireType(key);
+ (*variables)["key_default_value"] = DefaultValue(key, true, name_resolver);
+ // We use `x.getClass()` as a null check because it generates less bytecode
+ // than an `if (x == null) { throw ... }` statement.
+ (*variables)["key_null_check"] =
+ IsReferenceType(keyJavaType)
+ ? "java.lang.Class<?> keyClass = key.getClass();"
+ : "";
+ (*variables)["value_null_check"] =
+ IsReferenceType(valueJavaType)
+ ? "java.lang.Class<?> valueClass = value.getClass();"
+ : "";
+
+ if (GetJavaType(value) == JAVATYPE_ENUM) {
+ // We store enums as Integers internally.
+ (*variables)["value_type"] = "int";
+ (*variables)["boxed_value_type"] = "java.lang.Integer";
+ (*variables)["value_wire_type"] = WireType(value);
+ (*variables)["value_default_value"] =
+ DefaultValue(value, true, name_resolver) + ".getNumber()";
+
+ (*variables)["value_enum_type"] = TypeName(value, name_resolver, false);
+
+ if (SupportUnknownEnumValue(descriptor->file())) {
+ // Map unknown values to a special UNRECOGNIZED value if supported.
+ (*variables)["unrecognized_value"] =
+ (*variables)["value_enum_type"] + ".UNRECOGNIZED";
+ } else {
+ // Map unknown values to the default value if we don't have UNRECOGNIZED.
+ (*variables)["unrecognized_value"] =
+ DefaultValue(value, true, name_resolver);
+ }
+ } else {
+ (*variables)["value_type"] = TypeName(value, name_resolver, false);
+ (*variables)["boxed_value_type"] = TypeName(value, name_resolver, true);
+ (*variables)["value_wire_type"] = WireType(value);
+ (*variables)["value_default_value"] =
+ DefaultValue(value, true, name_resolver);
+ }
+ (*variables)["type_parameters"] =
+ (*variables)["boxed_key_type"] + ", " + (*variables)["boxed_value_type"];
+ // TODO(birdo): Add @deprecated javadoc when generating javadoc is supported
+ // by the proto compiler
+ (*variables)["deprecation"] =
+ descriptor->options().deprecated() ? "@java.lang.Deprecated " : "";
+ (*variables)["kt_deprecation"] =
+ descriptor->options().deprecated()
+ ? "@kotlin.Deprecated(message = \"Field " + (*variables)["name"] +
+ " is deprecated\") "
+ : "";
+
+ (*variables)["default_entry"] =
+ (*variables)["capitalized_name"] + "DefaultEntryHolder.defaultEntry";
+}
+
+} // namespace
+
+ImmutableMapFieldLiteGenerator::ImmutableMapFieldLiteGenerator(
+ const FieldDescriptor* descriptor, int messageBitIndex, Context* context)
+ : descriptor_(descriptor),
+ context_(context),
+ name_resolver_(context->GetNameResolver()) {
+ SetMessageVariables(descriptor, messageBitIndex, 0,
+ context->GetFieldGeneratorInfo(descriptor), context,
+ &variables_);
+}
+
+ImmutableMapFieldLiteGenerator::~ImmutableMapFieldLiteGenerator() {}
+
+int ImmutableMapFieldLiteGenerator::GetNumBitsForMessage() const { return 0; }
+
+void ImmutableMapFieldLiteGenerator::GenerateInterfaceMembers(
+ io::Printer* printer) const {
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$int ${$get$capitalized_name$Count$}$();\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$boolean ${$contains$capitalized_name$$}$(\n"
+ " $key_type$ key);\n");
+ printer->Annotate("{", "}", descriptor_);
+ if (GetJavaType(ValueField(descriptor_)) == JAVATYPE_ENUM) {
+ printer->Print(variables_,
+ "/**\n"
+ " * Use {@link #get$capitalized_name$Map()} instead.\n"
+ " */\n"
+ "@java.lang.Deprecated\n"
+ "java.util.Map<$boxed_key_type$, $value_enum_type$>\n"
+ "${$get$capitalized_name$$}$();\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "$deprecation$java.util.Map<$boxed_key_type$, $value_enum_type$>\n"
+ "${$get$capitalized_name$Map$}$();\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "$deprecation$$value_enum_type$ ${$get$capitalized_name$OrDefault$}$(\n"
+ " $key_type$ key,\n"
+ " $value_enum_type$ defaultValue);\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "$deprecation$$value_enum_type$ ${$get$capitalized_name$OrThrow$}$(\n"
+ " $key_type$ key);\n");
+ printer->Annotate("{", "}", descriptor_);
+ if (SupportUnknownEnumValue(descriptor_->file())) {
+ printer->Print(
+ variables_,
+ "/**\n"
+ " * Use {@link #get$capitalized_name$ValueMap()} instead.\n"
+ " */\n"
+ "@java.lang.Deprecated\n"
+ "java.util.Map<$type_parameters$>\n"
+ "${$get$capitalized_name$Value$}$();\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$java.util.Map<$type_parameters$>\n"
+ "${$get$capitalized_name$ValueMap$}$();\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$\n"
+ "$value_type$ ${$get$capitalized_name$ValueOrDefault$}$(\n"
+ " $key_type$ key,\n"
+ " $value_type$ defaultValue);\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$\n"
+ "$value_type$ ${$get$capitalized_name$ValueOrThrow$}$(\n"
+ " $key_type$ key);\n");
+ printer->Annotate("{", "}", descriptor_);
+ }
+ } else {
+ printer->Print(variables_,
+ "/**\n"
+ " * Use {@link #get$capitalized_name$Map()} instead.\n"
+ " */\n"
+ "@java.lang.Deprecated\n"
+ "java.util.Map<$type_parameters$>\n"
+ "${$get$capitalized_name$$}$();\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$java.util.Map<$type_parameters$>\n"
+ "${$get$capitalized_name$Map$}$();\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$\n"
+ "$value_type$ ${$get$capitalized_name$OrDefault$}$(\n"
+ " $key_type$ key,\n"
+ " $value_type$ defaultValue);\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$\n"
+ "$value_type$ ${$get$capitalized_name$OrThrow$}$(\n"
+ " $key_type$ key);\n");
+ printer->Annotate("{", "}", descriptor_);
+ }
+}
+
+void ImmutableMapFieldLiteGenerator::GenerateMembers(
+ io::Printer* printer) const {
+ printer->Print(
+ variables_,
+ "private static final class $capitalized_name$DefaultEntryHolder {\n"
+ " static final com.google.protobuf.MapEntryLite<\n"
+ " $type_parameters$> defaultEntry =\n"
+ " com.google.protobuf.MapEntryLite\n"
+ " .<$type_parameters$>newDefaultInstance(\n"
+ " $key_wire_type$,\n"
+ " $key_default_value$,\n"
+ " $value_wire_type$,\n"
+ " $value_default_value$);\n"
+ "}\n");
+ printer->Print(variables_,
+ "private com.google.protobuf.MapFieldLite<\n"
+ " $type_parameters$> $name$_ =\n"
+ " com.google.protobuf.MapFieldLite.emptyMapField();\n"
+ "private com.google.protobuf.MapFieldLite<$type_parameters$>\n"
+ "internalGet$capitalized_name$() {\n"
+ " return $name$_;\n"
+ "}\n"
+ "private com.google.protobuf.MapFieldLite<$type_parameters$>\n"
+ "internalGetMutable$capitalized_name$() {\n"
+ " if (!$name$_.isMutable()) {\n"
+ " $name$_ = $name$_.mutableCopy();\n"
+ " }\n"
+ " return $name$_;\n"
+ "}\n");
+ printer->Print(variables_,
+ "@java.lang.Override\n"
+ "$deprecation$\n"
+ "public int ${$get$capitalized_name$Count$}$() {\n"
+ " return internalGet$capitalized_name$().size();\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "@java.lang.Override\n"
+ "$deprecation$\n"
+ "public boolean ${$contains$capitalized_name$$}$(\n"
+ " $key_type$ key) {\n"
+ " $key_null_check$\n"
+ " return internalGet$capitalized_name$().containsKey(key);\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ if (GetJavaType(ValueField(descriptor_)) == JAVATYPE_ENUM) {
+ printer->Print(
+ variables_,
+ "private static final\n"
+ "com.google.protobuf.Internal.MapAdapter.Converter<\n"
+ " java.lang.Integer, $value_enum_type$> $name$ValueConverter =\n"
+ " com.google.protobuf.Internal.MapAdapter.newEnumConverter(\n"
+ " $value_enum_type$.internalGetValueMap(),\n"
+ " $unrecognized_value$);\n");
+ printer->Print(variables_,
+ "/**\n"
+ " * Use {@link #get$capitalized_name$Map()} instead.\n"
+ " */\n"
+ "@java.lang.Deprecated\n"
+ "public java.util.Map<$boxed_key_type$, $value_enum_type$>\n"
+ "${$get$capitalized_name$$}$() {\n"
+ " return get$capitalized_name$Map();\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "@java.lang.Override\n"
+ "$deprecation$\n"
+ "public java.util.Map<$boxed_key_type$, $value_enum_type$>\n"
+ "${$get$capitalized_name$Map$}$() {\n"
+ " return java.util.Collections.unmodifiableMap(\n"
+ " new com.google.protobuf.Internal.MapAdapter<\n"
+ " $boxed_key_type$, $value_enum_type$, java.lang.Integer>(\n"
+ " internalGet$capitalized_name$(),\n"
+ " $name$ValueConverter));\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "@java.lang.Override\n"
+ "$deprecation$\n"
+ "public $value_enum_type$ ${$get$capitalized_name$OrDefault$}$(\n"
+ " $key_type$ key,\n"
+ " $value_enum_type$ defaultValue) {\n"
+ " $key_null_check$\n"
+ " java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n"
+ " internalGet$capitalized_name$();\n"
+ " return map.containsKey(key)\n"
+ " ? $name$ValueConverter.doForward(map.get(key))\n"
+ " : defaultValue;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "@java.lang.Override\n"
+ "$deprecation$\n"
+ "public $value_enum_type$ ${$get$capitalized_name$OrThrow$}$(\n"
+ " $key_type$ key) {\n"
+ " $key_null_check$\n"
+ " java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n"
+ " internalGet$capitalized_name$();\n"
+ " if (!map.containsKey(key)) {\n"
+ " throw new java.lang.IllegalArgumentException();\n"
+ " }\n"
+ " return $name$ValueConverter.doForward(map.get(key));\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ if (SupportUnknownEnumValue(descriptor_->file())) {
+ printer->Print(
+ variables_,
+ "/**\n"
+ " * Use {@link #get$capitalized_name$ValueMap()} instead.\n"
+ " */\n"
+ "@java.lang.Override\n"
+ "@java.lang.Deprecated\n"
+ "public java.util.Map<$boxed_key_type$, $boxed_value_type$>\n"
+ "${$get$capitalized_name$Value$}$() {\n"
+ " return get$capitalized_name$ValueMap();\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "@java.lang.Override\n"
+ "$deprecation$\n"
+ "public java.util.Map<$boxed_key_type$, $boxed_value_type$>\n"
+ "${$get$capitalized_name$ValueMap$}$() {\n"
+ " return java.util.Collections.unmodifiableMap(\n"
+ " internalGet$capitalized_name$());\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "@java.lang.Override\n"
+ "$deprecation$\n"
+ "public $value_type$ ${$get$capitalized_name$ValueOrDefault$}$(\n"
+ " $key_type$ key,\n"
+ " $value_type$ defaultValue) {\n"
+ " $key_null_check$\n"
+ " java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n"
+ " internalGet$capitalized_name$();\n"
+ " return map.containsKey(key) ? map.get(key) : defaultValue;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "@java.lang.Override\n"
+ "$deprecation$\n"
+ "public $value_type$ ${$get$capitalized_name$ValueOrThrow$}$(\n"
+ " $key_type$ key) {\n"
+ " $key_null_check$\n"
+ " java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n"
+ " internalGet$capitalized_name$();\n"
+ " if (!map.containsKey(key)) {\n"
+ " throw new java.lang.IllegalArgumentException();\n"
+ " }\n"
+ " return map.get(key);\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ }
+ } else {
+ printer->Print(variables_,
+ "/**\n"
+ " * Use {@link #get$capitalized_name$Map()} instead.\n"
+ " */\n"
+ "@java.lang.Override\n"
+ "@java.lang.Deprecated\n"
+ "public java.util.Map<$type_parameters$> "
+ "${$get$capitalized_name$$}$() {\n"
+ " return get$capitalized_name$Map();\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "@java.lang.Override\n"
+ "$deprecation$\n"
+ "public java.util.Map<$type_parameters$> "
+ "${$get$capitalized_name$Map$}$() {\n"
+ " return java.util.Collections.unmodifiableMap(\n"
+ " internalGet$capitalized_name$());\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "@java.lang.Override\n"
+ "$deprecation$\n"
+ "public $value_type$ ${$get$capitalized_name$OrDefault$}$(\n"
+ " $key_type$ key,\n"
+ " $value_type$ defaultValue) {\n"
+ " $key_null_check$\n"
+ " java.util.Map<$type_parameters$> map =\n"
+ " internalGet$capitalized_name$();\n"
+ " return map.containsKey(key) ? map.get(key) : defaultValue;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "@java.lang.Override\n"
+ "$deprecation$\n"
+ "public $value_type$ ${$get$capitalized_name$OrThrow$}$(\n"
+ " $key_type$ key) {\n"
+ " $key_null_check$\n"
+ " java.util.Map<$type_parameters$> map =\n"
+ " internalGet$capitalized_name$();\n"
+ " if (!map.containsKey(key)) {\n"
+ " throw new java.lang.IllegalArgumentException();\n"
+ " }\n"
+ " return map.get(key);\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ }
+
+ // Generate private setters for the builder to proxy into.
+ if (GetJavaType(ValueField(descriptor_)) == JAVATYPE_ENUM) {
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "private java.util.Map<$boxed_key_type$, $value_enum_type$>\n"
+ "getMutable$capitalized_name$Map() {\n"
+ " return new com.google.protobuf.Internal.MapAdapter<\n"
+ " $boxed_key_type$, $value_enum_type$, java.lang.Integer>(\n"
+ " internalGetMutable$capitalized_name$(),\n"
+ " $name$ValueConverter);\n"
+ "}\n");
+ if (SupportUnknownEnumValue(descriptor_->file())) {
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "private java.util.Map<$boxed_key_type$, $boxed_value_type$>\n"
+ "getMutable$capitalized_name$ValueMap() {\n"
+ " return internalGetMutable$capitalized_name$();\n"
+ "}\n");
+ }
+ } else {
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "private java.util.Map<$type_parameters$>\n"
+ "getMutable$capitalized_name$Map() {\n"
+ " return internalGetMutable$capitalized_name$();\n"
+ "}\n");
+ }
+}
+
+void ImmutableMapFieldLiteGenerator::GenerateFieldInfo(
+ io::Printer* printer, std::vector<uint16_t>* output) const {
+ WriteIntToUtf16CharSequence(descriptor_->number(), output);
+ WriteIntToUtf16CharSequence(GetExperimentalJavaFieldType(descriptor_),
+ output);
+ printer->Print(variables_,
+ "\"$name$_\",\n"
+ "$default_entry$,\n");
+ if (!SupportUnknownEnumValue(descriptor_) &&
+ GetJavaType(ValueField(descriptor_)) == JAVATYPE_ENUM) {
+ PrintEnumVerifierLogic(printer, ValueField(descriptor_), variables_,
+ /*var_name=*/"$value_enum_type$",
+ /*terminating_string=*/",\n",
+ /*enforce_lite=*/context_->EnforceLite());
+ }
+}
+
+void ImmutableMapFieldLiteGenerator::GenerateBuilderMembers(
+ io::Printer* printer) const {
+ printer->Print(variables_,
+ "@java.lang.Override\n"
+ "$deprecation$\n"
+ "public int ${$get$capitalized_name$Count$}$() {\n"
+ " return instance.get$capitalized_name$Map().size();\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "@java.lang.Override\n"
+ "$deprecation$\n"
+ "public boolean ${$contains$capitalized_name$$}$(\n"
+ " $key_type$ key) {\n"
+ " $key_null_check$\n"
+ " return instance.get$capitalized_name$Map().containsKey(key);\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ printer->Print(variables_,
+ "$deprecation$\n"
+ "public Builder ${$clear$capitalized_name$$}$() {\n"
+ " copyOnWrite();\n"
+ " instance.getMutable$capitalized_name$Map().clear();\n"
+ " return this;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$\n"
+ "public Builder ${$remove$capitalized_name$$}$(\n"
+ " $key_type$ key) {\n"
+ " $key_null_check$\n"
+ " copyOnWrite();\n"
+ " instance.getMutable$capitalized_name$Map().remove(key);\n"
+ " return this;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ if (GetJavaType(ValueField(descriptor_)) == JAVATYPE_ENUM) {
+ printer->Print(variables_,
+ "/**\n"
+ " * Use {@link #get$capitalized_name$Map()} instead.\n"
+ " */\n"
+ "@java.lang.Deprecated\n"
+ "public java.util.Map<$boxed_key_type$, $value_enum_type$>\n"
+ "${$get$capitalized_name$$}$() {\n"
+ " return get$capitalized_name$Map();\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "@java.lang.Override\n"
+ "$deprecation$\n"
+ "public java.util.Map<$boxed_key_type$, $value_enum_type$>\n"
+ "${$get$capitalized_name$Map$}$() {\n"
+ " return java.util.Collections.unmodifiableMap(\n"
+ " instance.get$capitalized_name$Map());\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "@java.lang.Override\n"
+ "$deprecation$\n"
+ "public $value_enum_type$ ${$get$capitalized_name$OrDefault$}$(\n"
+ " $key_type$ key,\n"
+ " $value_enum_type$ defaultValue) {\n"
+ " $key_null_check$\n"
+ " java.util.Map<$boxed_key_type$, $value_enum_type$> map =\n"
+ " instance.get$capitalized_name$Map();\n"
+ " return map.containsKey(key)\n"
+ " ? map.get(key)\n"
+ " : defaultValue;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "@java.lang.Override\n"
+ "$deprecation$\n"
+ "public $value_enum_type$ ${$get$capitalized_name$OrThrow$}$(\n"
+ " $key_type$ key) {\n"
+ " $key_null_check$\n"
+ " java.util.Map<$boxed_key_type$, $value_enum_type$> map =\n"
+ " instance.get$capitalized_name$Map();\n"
+ " if (!map.containsKey(key)) {\n"
+ " throw new java.lang.IllegalArgumentException();\n"
+ " }\n"
+ " return map.get(key);\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "$deprecation$public Builder ${$put$capitalized_name$$}$(\n"
+ " $key_type$ key,\n"
+ " $value_enum_type$ value) {\n"
+ " $key_null_check$\n"
+ " $value_null_check$\n"
+ " copyOnWrite();\n"
+ " instance.getMutable$capitalized_name$Map().put(key, value);\n"
+ " return this;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "$deprecation$public Builder ${$putAll$capitalized_name$$}$(\n"
+ " java.util.Map<$boxed_key_type$, $value_enum_type$> values) {\n"
+ " copyOnWrite();\n"
+ " instance.getMutable$capitalized_name$Map().putAll(values);\n"
+ " return this;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ if (SupportUnknownEnumValue(descriptor_->file())) {
+ printer->Print(
+ variables_,
+ "/**\n"
+ " * Use {@link #get$capitalized_name$ValueMap()} instead.\n"
+ " */\n"
+ "@java.lang.Override\n"
+ "@java.lang.Deprecated\n"
+ "public java.util.Map<$boxed_key_type$, $boxed_value_type$>\n"
+ "${$get$capitalized_name$Value$}$() {\n"
+ " return get$capitalized_name$ValueMap();\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "@java.lang.Override\n"
+ "$deprecation$\n"
+ "public java.util.Map<$boxed_key_type$, $boxed_value_type$>\n"
+ "${$get$capitalized_name$ValueMap$}$() {\n"
+ " return java.util.Collections.unmodifiableMap(\n"
+ " instance.get$capitalized_name$ValueMap());\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "@java.lang.Override\n"
+ "$deprecation$\n"
+ "public $value_type$ ${$get$capitalized_name$ValueOrDefault$}$(\n"
+ " $key_type$ key,\n"
+ " $value_type$ defaultValue) {\n"
+ " $key_null_check$\n"
+ " java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n"
+ " instance.get$capitalized_name$ValueMap();\n"
+ " return map.containsKey(key) ? map.get(key) : defaultValue;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "@java.lang.Override\n"
+ "$deprecation$\n"
+ "public $value_type$ ${$get$capitalized_name$ValueOrThrow$}$(\n"
+ " $key_type$ key) {\n"
+ " $key_null_check$\n"
+ " java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n"
+ " instance.get$capitalized_name$ValueMap();\n"
+ " if (!map.containsKey(key)) {\n"
+ " throw new java.lang.IllegalArgumentException();\n"
+ " }\n"
+ " return map.get(key);\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "$deprecation$public Builder ${$put$capitalized_name$Value$}$(\n"
+ " $key_type$ key,\n"
+ " $value_type$ value) {\n"
+ " $key_null_check$\n"
+ " copyOnWrite();\n"
+ " instance.getMutable$capitalized_name$ValueMap().put(key, value);\n"
+ " return this;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "$deprecation$public Builder ${$putAll$capitalized_name$Value$}$(\n"
+ " java.util.Map<$boxed_key_type$, $boxed_value_type$> values) {\n"
+ " copyOnWrite();\n"
+ " instance.getMutable$capitalized_name$ValueMap().putAll(values);\n"
+ " return this;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ }
+ } else {
+ printer->Print(variables_,
+ "/**\n"
+ " * Use {@link #get$capitalized_name$Map()} instead.\n"
+ " */\n"
+ "@java.lang.Override\n"
+ "@java.lang.Deprecated\n"
+ "public java.util.Map<$type_parameters$> "
+ "${$get$capitalized_name$$}$() {\n"
+ " return get$capitalized_name$Map();\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "@java.lang.Override\n"
+ "$deprecation$"
+ "public java.util.Map<$type_parameters$> "
+ "${$get$capitalized_name$Map$}$() {\n"
+ " return java.util.Collections.unmodifiableMap(\n"
+ " instance.get$capitalized_name$Map());\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "@java.lang.Override\n"
+ "$deprecation$\n"
+ "public $value_type$ ${$get$capitalized_name$OrDefault$}$(\n"
+ " $key_type$ key,\n"
+ " $value_type$ defaultValue) {\n"
+ " $key_null_check$\n"
+ " java.util.Map<$type_parameters$> map =\n"
+ " instance.get$capitalized_name$Map();\n"
+ " return map.containsKey(key) ? map.get(key) : defaultValue;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "@java.lang.Override\n"
+ "$deprecation$\n"
+ "public $value_type$ ${$get$capitalized_name$OrThrow$}$(\n"
+ " $key_type$ key) {\n"
+ " $key_null_check$\n"
+ " java.util.Map<$type_parameters$> map =\n"
+ " instance.get$capitalized_name$Map();\n"
+ " if (!map.containsKey(key)) {\n"
+ " throw new java.lang.IllegalArgumentException();\n"
+ " }\n"
+ " return map.get(key);\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "$deprecation$"
+ "public Builder ${$put$capitalized_name$$}$(\n"
+ " $key_type$ key,\n"
+ " $value_type$ value) {\n"
+ " $key_null_check$\n"
+ " $value_null_check$\n"
+ " copyOnWrite();\n"
+ " instance.getMutable$capitalized_name$Map().put(key, value);\n"
+ " return this;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "$deprecation$"
+ "public Builder ${$putAll$capitalized_name$$}$(\n"
+ " java.util.Map<$type_parameters$> values) {\n"
+ " copyOnWrite();\n"
+ " instance.getMutable$capitalized_name$Map().putAll(values);\n"
+ " return this;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ }
+}
+
+void ImmutableMapFieldLiteGenerator::GenerateKotlinDslMembers(
+ io::Printer* printer) const {
+ printer->Print(
+ variables_,
+ "/**\n"
+ " * An uninstantiable, behaviorless type to represent the field in\n"
+ " * generics.\n"
+ " */\n"
+ "@kotlin.OptIn"
+ "(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)\n"
+ "public class ${$$kt_capitalized_name$Proxy$}$ private constructor()"
+ " : com.google.protobuf.kotlin.DslProxy()\n");
+
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "$kt_deprecation$ public val $kt_name$: "
+ "com.google.protobuf.kotlin.DslMap"
+ "<$kt_key_type$, $kt_value_type$, ${$$kt_capitalized_name$Proxy$}$>\n"
+ " @kotlin.jvm.JvmSynthetic\n"
+ " @JvmName(\"get$kt_capitalized_name$Map\")\n"
+ " get() = com.google.protobuf.kotlin.DslMap(\n"
+ " $kt_dsl_builder$.${$get$capitalized_name$Map$}$()\n"
+ " )\n");
+
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "@JvmName(\"put$kt_capitalized_name$\")\n"
+ "public fun com.google.protobuf.kotlin.DslMap"
+ "<$kt_key_type$, $kt_value_type$, ${$$kt_capitalized_name$Proxy$}$>\n"
+ " .put(key: $kt_key_type$, value: $kt_value_type$) {\n"
+ " $kt_dsl_builder$.${$put$capitalized_name$$}$(key, value)\n"
+ " }\n");
+
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "@kotlin.jvm.JvmSynthetic\n"
+ "@JvmName(\"set$kt_capitalized_name$\")\n"
+ "@Suppress(\"NOTHING_TO_INLINE\")\n"
+ "public inline operator fun com.google.protobuf.kotlin.DslMap"
+ "<$kt_key_type$, $kt_value_type$, ${$$kt_capitalized_name$Proxy$}$>\n"
+ " .set(key: $kt_key_type$, value: $kt_value_type$) {\n"
+ " put(key, value)\n"
+ " }\n");
+
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "@kotlin.jvm.JvmSynthetic\n"
+ "@JvmName(\"remove$kt_capitalized_name$\")\n"
+ "public fun com.google.protobuf.kotlin.DslMap"
+ "<$kt_key_type$, $kt_value_type$, ${$$kt_capitalized_name$Proxy$}$>\n"
+ " .remove(key: $kt_key_type$) {\n"
+ " $kt_dsl_builder$.${$remove$capitalized_name$$}$(key)\n"
+ " }\n");
+
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "@kotlin.jvm.JvmSynthetic\n"
+ "@JvmName(\"putAll$kt_capitalized_name$\")\n"
+ "public fun com.google.protobuf.kotlin.DslMap"
+ "<$kt_key_type$, $kt_value_type$, ${$$kt_capitalized_name$Proxy$}$>\n"
+ " .putAll(map: kotlin.collections.Map<$kt_key_type$, $kt_value_type$>) "
+ "{\n"
+ " $kt_dsl_builder$.${$putAll$capitalized_name$$}$(map)\n"
+ " }\n");
+
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "@kotlin.jvm.JvmSynthetic\n"
+ "@JvmName(\"clear$kt_capitalized_name$\")\n"
+ "public fun com.google.protobuf.kotlin.DslMap"
+ "<$kt_key_type$, $kt_value_type$, ${$$kt_capitalized_name$Proxy$}$>\n"
+ " .clear() {\n"
+ " $kt_dsl_builder$.${$clear$capitalized_name$$}$()\n"
+ " }\n");
+}
+
+void ImmutableMapFieldLiteGenerator::GenerateInitializationCode(
+ io::Printer* printer) const {
+ // Nothing to initialize.
+}
+
+std::string ImmutableMapFieldLiteGenerator::GetBoxedType() const {
+ return name_resolver_->GetImmutableClassName(descriptor_->message_type());
+}
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_map_field_lite.h b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_map_field_lite.h
new file mode 100644
index 00000000..7017982d
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_map_field_lite.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.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_MAP_FIELD_LITE_H__
+#define GOOGLE_PROTOBUF_COMPILER_JAVA_MAP_FIELD_LITE_H__
+
+#include <cstdint>
+
+#include <compiler/java/java_field.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+class ImmutableMapFieldLiteGenerator : public ImmutableFieldLiteGenerator {
+ public:
+ explicit ImmutableMapFieldLiteGenerator(const FieldDescriptor* descriptor,
+ int messageBitIndex,
+ Context* context);
+ ~ImmutableMapFieldLiteGenerator() override;
+
+ // implements ImmutableFieldLiteGenerator ------------------------------------
+ int GetNumBitsForMessage() const override;
+ void GenerateInterfaceMembers(io::Printer* printer) const override;
+ void GenerateMembers(io::Printer* printer) const override;
+ void GenerateBuilderMembers(io::Printer* printer) const override;
+ void GenerateInitializationCode(io::Printer* printer) const override;
+ void GenerateFieldInfo(io::Printer* printer,
+ std::vector<uint16_t>* output) const override;
+ void GenerateKotlinDslMembers(io::Printer* printer) const override;
+
+ std::string GetBoxedType() const override;
+
+ private:
+ const FieldDescriptor* descriptor_;
+ std::map<std::string, std::string> variables_;
+ Context* context_;
+ ClassNameResolver* name_resolver_;
+};
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_MAP_FIELD_LITE_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_message.cc b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_message.cc
new file mode 100644
index 00000000..38edc769
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_message.cc
@@ -0,0 +1,1729 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 <compiler/java/java_message.h>
+
+#include <algorithm>
+#include <cstdint>
+#include <map>
+#include <memory>
+#include <vector>
+
+#include <compiler/java/java_context.h>
+#include <compiler/java/java_doc_comment.h>
+#include <compiler/java/java_enum.h>
+#include <compiler/java/java_extension.h>
+#include <compiler/java/java_generator_factory.h>
+#include <compiler/java/java_helpers.h>
+#include <compiler/java/java_message_builder.h>
+#include <compiler/java/java_message_builder_lite.h>
+#include <compiler/java/java_name_resolver.h>
+#include <descriptor.pb.h>
+#include <io/coded_stream.h>
+#include <io/printer.h>
+#include <wire_format.h>
+#include <stubs/strutil.h>
+#include <stubs/substitute.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+using internal::WireFormat;
+using internal::WireFormatLite;
+
+namespace {
+std::string MapValueImmutableClassdName(const Descriptor* descriptor,
+ ClassNameResolver* name_resolver) {
+ const FieldDescriptor* value_field = descriptor->FindFieldByName("value");
+ GOOGLE_CHECK_EQ(FieldDescriptor::TYPE_MESSAGE, value_field->type());
+ return name_resolver->GetImmutableClassName(value_field->message_type());
+}
+} // namespace
+
+// ===================================================================
+
+MessageGenerator::MessageGenerator(const Descriptor* descriptor)
+ : descriptor_(descriptor) {
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ if (IsRealOneof(descriptor_->field(i))) {
+ oneofs_.insert(descriptor_->field(i)->containing_oneof());
+ }
+ }
+}
+
+MessageGenerator::~MessageGenerator() {}
+
+// ===================================================================
+ImmutableMessageGenerator::ImmutableMessageGenerator(
+ const Descriptor* descriptor, Context* context)
+ : MessageGenerator(descriptor),
+ context_(context),
+ name_resolver_(context->GetNameResolver()),
+ field_generators_(descriptor, context_) {
+ GOOGLE_CHECK(HasDescriptorMethods(descriptor->file(), context->EnforceLite()))
+ << "Generator factory error: A non-lite message generator is used to "
+ "generate lite messages.";
+}
+
+ImmutableMessageGenerator::~ImmutableMessageGenerator() {}
+
+void ImmutableMessageGenerator::GenerateStaticVariables(
+ io::Printer* printer, int* bytecode_estimate) {
+ // Because descriptor.proto (com.google.protobuf.DescriptorProtos) is
+ // used in the construction of descriptors, we have a tricky bootstrapping
+ // problem. To help control static initialization order, we make sure all
+ // descriptors and other static data that depends on them are members of
+ // the outermost class in the file. This way, they will be initialized in
+ // a deterministic order.
+
+ std::map<std::string, std::string> vars;
+ vars["identifier"] = UniqueFileScopeIdentifier(descriptor_);
+ vars["index"] = StrCat(descriptor_->index());
+ vars["classname"] = name_resolver_->GetImmutableClassName(descriptor_);
+ if (descriptor_->containing_type() != NULL) {
+ vars["parent"] = UniqueFileScopeIdentifier(descriptor_->containing_type());
+ }
+ if (MultipleJavaFiles(descriptor_->file(), /* immutable = */ true)) {
+ // We can only make these package-private since the classes that use them
+ // are in separate files.
+ vars["private"] = "";
+ } else {
+ vars["private"] = "private ";
+ }
+ if (*bytecode_estimate <= kMaxStaticSize) {
+ vars["final"] = "final ";
+ } else {
+ vars["final"] = "";
+ }
+
+ // The descriptor for this type.
+ printer->Print(
+ vars,
+ // TODO(teboring): final needs to be added back. The way to fix it is to
+ // generate methods that can construct the types, and then still declare
+ // the types, and then init them in clinit with the new method calls.
+ "$private$static $final$com.google.protobuf.Descriptors.Descriptor\n"
+ " internal_$identifier$_descriptor;\n");
+ *bytecode_estimate += 30;
+
+ // And the FieldAccessorTable.
+ GenerateFieldAccessorTable(printer, bytecode_estimate);
+
+ // Generate static members for all nested types.
+ for (int i = 0; i < descriptor_->nested_type_count(); i++) {
+ // TODO(kenton): Reuse MessageGenerator objects?
+ ImmutableMessageGenerator(descriptor_->nested_type(i), context_)
+ .GenerateStaticVariables(printer, bytecode_estimate);
+ }
+}
+
+int ImmutableMessageGenerator::GenerateStaticVariableInitializers(
+ io::Printer* printer) {
+ int bytecode_estimate = 0;
+ std::map<std::string, std::string> vars;
+ vars["identifier"] = UniqueFileScopeIdentifier(descriptor_);
+ vars["index"] = StrCat(descriptor_->index());
+ vars["classname"] = name_resolver_->GetImmutableClassName(descriptor_);
+ if (descriptor_->containing_type() != NULL) {
+ vars["parent"] = UniqueFileScopeIdentifier(descriptor_->containing_type());
+ }
+
+ // The descriptor for this type.
+ if (descriptor_->containing_type() == NULL) {
+ printer->Print(vars,
+ "internal_$identifier$_descriptor =\n"
+ " getDescriptor().getMessageTypes().get($index$);\n");
+ bytecode_estimate += 30;
+ } else {
+ printer->Print(
+ vars,
+ "internal_$identifier$_descriptor =\n"
+ " internal_$parent$_descriptor.getNestedTypes().get($index$);\n");
+ bytecode_estimate += 30;
+ }
+
+ // And the FieldAccessorTable.
+ bytecode_estimate += GenerateFieldAccessorTableInitializer(printer);
+
+ // Generate static member initializers for all nested types.
+ for (int i = 0; i < descriptor_->nested_type_count(); i++) {
+ // TODO(kenton): Reuse MessageGenerator objects?
+ bytecode_estimate +=
+ ImmutableMessageGenerator(descriptor_->nested_type(i), context_)
+ .GenerateStaticVariableInitializers(printer);
+ }
+ return bytecode_estimate;
+}
+
+void ImmutableMessageGenerator::GenerateFieldAccessorTable(
+ io::Printer* printer, int* bytecode_estimate) {
+ std::map<std::string, std::string> vars;
+ vars["identifier"] = UniqueFileScopeIdentifier(descriptor_);
+ if (MultipleJavaFiles(descriptor_->file(), /* immutable = */ true)) {
+ // We can only make these package-private since the classes that use them
+ // are in separate files.
+ vars["private"] = "";
+ } else {
+ vars["private"] = "private ";
+ }
+ if (*bytecode_estimate <= kMaxStaticSize) {
+ vars["final"] = "final ";
+ } else {
+ vars["final"] = "";
+ }
+ vars["ver"] = GeneratedCodeVersionSuffix();
+ printer->Print(
+ vars,
+ "$private$static $final$\n"
+ " com.google.protobuf.GeneratedMessage$ver$.FieldAccessorTable\n"
+ " internal_$identifier$_fieldAccessorTable;\n");
+
+ // The following bytecode_estimate calculation logic must stay in sync with
+ // the similar logic in the GenerateFieldAccessorTableInitializer method below
+ // to make sure that the generated static final fields are initialized in the
+ // static initialization block directly.
+ //
+ // 6 bytes per field and oneof
+ *bytecode_estimate +=
+ 10 + 6 * descriptor_->field_count() + 6 * descriptor_->oneof_decl_count();
+}
+
+int ImmutableMessageGenerator::GenerateFieldAccessorTableInitializer(
+ io::Printer* printer) {
+ int bytecode_estimate = 10;
+ printer->Print(
+ "internal_$identifier$_fieldAccessorTable = new\n"
+ " com.google.protobuf.GeneratedMessage$ver$.FieldAccessorTable(\n"
+ " internal_$identifier$_descriptor,\n"
+ " new java.lang.String[] { ",
+ "identifier", UniqueFileScopeIdentifier(descriptor_), "ver",
+ GeneratedCodeVersionSuffix());
+ // All the bytecode_estimate calculation logic in this method must stay in
+ // sync with the similar logic in the GenerateFieldAccessorTable method
+ // above. See the corresponding comment in GenerateFieldAccessorTable for
+ // details.
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ const FieldDescriptor* field = descriptor_->field(i);
+ const FieldGeneratorInfo* info = context_->GetFieldGeneratorInfo(field);
+ bytecode_estimate += 6;
+ printer->Print("\"$field_name$\", ", "field_name", info->capitalized_name);
+ }
+ // We reproduce synthetic oneofs here since proto reflection needs these.
+ for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
+ const OneofDescriptor* oneof = descriptor_->oneof_decl(i);
+ const OneofGeneratorInfo* info = context_->GetOneofGeneratorInfo(oneof);
+ bytecode_estimate += 6;
+ printer->Print("\"$oneof_name$\", ", "oneof_name", info->capitalized_name);
+ }
+ printer->Print("});\n");
+ return bytecode_estimate;
+}
+
+// ===================================================================
+
+void ImmutableMessageGenerator::GenerateInterface(io::Printer* printer) {
+ MaybePrintGeneratedAnnotation(context_, printer, descriptor_,
+ /* immutable = */ true, "OrBuilder");
+ if (descriptor_->extension_range_count() > 0) {
+ printer->Print(
+ "$deprecation$public interface ${$$classname$OrBuilder$}$ extends\n"
+ " $extra_interfaces$\n"
+ " com.google.protobuf.GeneratedMessage$ver$.\n"
+ " ExtendableMessageOrBuilder<$classname$> {\n",
+ "deprecation",
+ descriptor_->options().deprecated() ? "@java.lang.Deprecated " : "",
+ "extra_interfaces", ExtraMessageOrBuilderInterfaces(descriptor_),
+ "classname", descriptor_->name(), "{", "", "}", "", "ver",
+ GeneratedCodeVersionSuffix());
+ } else {
+ printer->Print(
+ "$deprecation$public interface ${$$classname$OrBuilder$}$ extends\n"
+ " $extra_interfaces$\n"
+ " com.google.protobuf.MessageOrBuilder {\n",
+ "deprecation",
+ descriptor_->options().deprecated() ? "@java.lang.Deprecated " : "",
+ "extra_interfaces", ExtraMessageOrBuilderInterfaces(descriptor_),
+ "classname", descriptor_->name(), "{", "", "}", "");
+ }
+ printer->Annotate("{", "}", descriptor_);
+
+ printer->Indent();
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ printer->Print("\n");
+ field_generators_.get(descriptor_->field(i))
+ .GenerateInterfaceMembers(printer);
+ }
+ for (auto oneof : oneofs_) {
+ printer->Print(
+ "\n"
+ "public $classname$.$oneof_capitalized_name$Case "
+ "get$oneof_capitalized_name$Case();\n",
+ "oneof_capitalized_name",
+ context_->GetOneofGeneratorInfo(oneof)->capitalized_name, "classname",
+ context_->GetNameResolver()->GetImmutableClassName(descriptor_));
+ }
+ printer->Outdent();
+
+ printer->Print("}\n");
+}
+
+// ===================================================================
+
+void ImmutableMessageGenerator::Generate(io::Printer* printer) {
+ bool is_own_file = IsOwnFile(descriptor_, /* immutable = */ true);
+
+ std::map<std::string, std::string> variables;
+ variables["static"] = is_own_file ? "" : "static ";
+ variables["classname"] = descriptor_->name();
+ variables["extra_interfaces"] = ExtraMessageInterfaces(descriptor_);
+ variables["ver"] = GeneratedCodeVersionSuffix();
+ variables["deprecation"] =
+ descriptor_->options().deprecated() ? "@java.lang.Deprecated " : "";
+
+ WriteMessageDocComment(printer, descriptor_);
+ MaybePrintGeneratedAnnotation(context_, printer, descriptor_,
+ /* immutable = */ true);
+ // The builder_type stores the super type name of the nested Builder class.
+ std::string builder_type;
+ if (descriptor_->extension_range_count() > 0) {
+ printer->Print(
+ variables,
+ "$deprecation$public $static$final class $classname$ extends\n");
+ printer->Annotate("classname", descriptor_);
+ printer->Print(
+ variables,
+ " com.google.protobuf.GeneratedMessage$ver$.ExtendableMessage<\n"
+ " $classname$> implements\n"
+ " $extra_interfaces$\n"
+ " $classname$OrBuilder {\n");
+ builder_type = strings::Substitute(
+ "com.google.protobuf.GeneratedMessage$1.ExtendableBuilder<$0, ?>",
+ name_resolver_->GetImmutableClassName(descriptor_),
+ GeneratedCodeVersionSuffix());
+ } else {
+ printer->Print(
+ variables,
+ "$deprecation$public $static$final class $classname$ extends\n");
+ printer->Annotate("classname", descriptor_);
+ printer->Print(variables,
+ " com.google.protobuf.GeneratedMessage$ver$ implements\n"
+ " $extra_interfaces$\n"
+ " $classname$OrBuilder {\n");
+ builder_type =
+ strings::Substitute("com.google.protobuf.GeneratedMessage$0.Builder<?>",
+ GeneratedCodeVersionSuffix());
+ }
+ printer->Print("private static final long serialVersionUID = 0L;\n");
+
+ printer->Indent();
+ // Using builder_type, instead of Builder, prevents the Builder class from
+ // being loaded into PermGen space when the default instance is created.
+ // This optimizes the PermGen space usage for clients that do not modify
+ // messages.
+ printer->Print(
+ "// Use $classname$.newBuilder() to construct.\n"
+ "private $classname$($buildertype$ builder) {\n"
+ " super(builder);\n"
+ "}\n",
+ "classname", descriptor_->name(), "buildertype", builder_type);
+ printer->Print("private $classname$() {\n", "classname", descriptor_->name());
+ printer->Indent();
+ GenerateInitializers(printer);
+ printer->Outdent();
+ printer->Print(
+ "}\n"
+ "\n");
+
+ printer->Print(variables,
+ "@java.lang.Override\n"
+ "@SuppressWarnings({\"unused\"})\n"
+ "protected java.lang.Object newInstance(\n"
+ " UnusedPrivateParameter unused) {\n"
+ " return new $classname$();\n"
+ "}\n"
+ "\n");
+
+ printer->Print(
+ "@java.lang.Override\n"
+ "public final com.google.protobuf.UnknownFieldSet\n"
+ "getUnknownFields() {\n"
+ " return this.unknownFields;\n"
+ "}\n");
+
+ if (context_->HasGeneratedMethods(descriptor_)) {
+ GenerateParsingConstructor(printer);
+ }
+
+ GenerateDescriptorMethods(printer);
+
+ // Nested types
+ for (int i = 0; i < descriptor_->enum_type_count(); i++) {
+ EnumGenerator(descriptor_->enum_type(i), true, context_).Generate(printer);
+ }
+
+ for (int i = 0; i < descriptor_->nested_type_count(); i++) {
+ // Don't generate Java classes for map entry messages.
+ if (IsMapEntry(descriptor_->nested_type(i))) continue;
+ ImmutableMessageGenerator messageGenerator(descriptor_->nested_type(i),
+ context_);
+ messageGenerator.GenerateInterface(printer);
+ messageGenerator.Generate(printer);
+ }
+
+ // Integers for bit fields.
+ int totalBits = 0;
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ totalBits +=
+ field_generators_.get(descriptor_->field(i)).GetNumBitsForMessage();
+ }
+ int totalInts = (totalBits + 31) / 32;
+ for (int i = 0; i < totalInts; i++) {
+ printer->Print("private int $bit_field_name$;\n", "bit_field_name",
+ GetBitFieldName(i));
+ }
+
+ // oneof
+ std::map<std::string, std::string> vars;
+ for (auto oneof : oneofs_) {
+ vars["oneof_name"] = context_->GetOneofGeneratorInfo(oneof)->name;
+ vars["oneof_capitalized_name"] =
+ context_->GetOneofGeneratorInfo(oneof)->capitalized_name;
+ vars["oneof_index"] = StrCat((oneof)->index());
+ // oneofCase_ and oneof_
+ printer->Print(vars,
+ "private int $oneof_name$Case_ = 0;\n"
+ "private java.lang.Object $oneof_name$_;\n");
+ // OneofCase enum
+ printer->Print(
+ vars,
+ "public enum $oneof_capitalized_name$Case\n"
+ // TODO(dweis): Remove EnumLite when we want to break compatibility with
+ // 3.x users
+ " implements com.google.protobuf.Internal.EnumLite,\n"
+ " com.google.protobuf.AbstractMessage.InternalOneOfEnum {\n");
+ printer->Indent();
+ for (int j = 0; j < (oneof)->field_count(); j++) {
+ const FieldDescriptor* field = (oneof)->field(j);
+ printer->Print(
+ "$deprecation$$field_name$($field_number$),\n", "deprecation",
+ field->options().deprecated() ? "@java.lang.Deprecated " : "",
+ "field_name", ToUpper(field->name()), "field_number",
+ StrCat(field->number()));
+ }
+ printer->Print("$cap_oneof_name$_NOT_SET(0);\n", "cap_oneof_name",
+ ToUpper(vars["oneof_name"]));
+ printer->Print(vars,
+ "private final int value;\n"
+ "private $oneof_capitalized_name$Case(int value) {\n"
+ " this.value = value;\n"
+ "}\n");
+ printer->Print(
+ vars,
+ "/**\n"
+ " * @param value The number of the enum to look for.\n"
+ " * @return The enum associated with the given number.\n"
+ " * @deprecated Use {@link #forNumber(int)} instead.\n"
+ " */\n"
+ "@java.lang.Deprecated\n"
+ "public static $oneof_capitalized_name$Case valueOf(int value) {\n"
+ " return forNumber(value);\n"
+ "}\n"
+ "\n"
+ "public static $oneof_capitalized_name$Case forNumber(int value) {\n"
+ " switch (value) {\n");
+ for (int j = 0; j < (oneof)->field_count(); j++) {
+ const FieldDescriptor* field = (oneof)->field(j);
+ printer->Print(" case $field_number$: return $field_name$;\n",
+ "field_number", StrCat(field->number()),
+ "field_name", ToUpper(field->name()));
+ }
+ printer->Print(
+ " case 0: return $cap_oneof_name$_NOT_SET;\n"
+ " default: return null;\n"
+ " }\n"
+ "}\n"
+ "public int getNumber() {\n"
+ " return this.value;\n"
+ "}\n",
+ "cap_oneof_name", ToUpper(vars["oneof_name"]));
+ printer->Outdent();
+ printer->Print("};\n\n");
+ // oneofCase()
+ printer->Print(vars,
+ "public $oneof_capitalized_name$Case\n"
+ "get$oneof_capitalized_name$Case() {\n"
+ " return $oneof_capitalized_name$Case.forNumber(\n"
+ " $oneof_name$Case_);\n"
+ "}\n"
+ "\n");
+ }
+
+ if (IsAnyMessage(descriptor_)) {
+ GenerateAnyMethods(printer);
+ }
+
+ // Fields
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ printer->Print("public static final int $constant_name$ = $number$;\n",
+ "constant_name", FieldConstantName(descriptor_->field(i)),
+ "number", StrCat(descriptor_->field(i)->number()));
+ printer->Annotate("constant_name", descriptor_->field(i));
+ field_generators_.get(descriptor_->field(i)).GenerateMembers(printer);
+ printer->Print("\n");
+ }
+
+ if (context_->HasGeneratedMethods(descriptor_)) {
+ GenerateIsInitialized(printer);
+ GenerateMessageSerializationMethods(printer);
+ GenerateEqualsAndHashCode(printer);
+ }
+
+
+ GenerateParseFromMethods(printer);
+ GenerateBuilder(printer);
+
+ printer->Print(
+ "\n"
+ "// @@protoc_insertion_point(class_scope:$full_name$)\n",
+ "full_name", descriptor_->full_name());
+
+ // Carefully initialize the default instance in such a way that it doesn't
+ // conflict with other initialization.
+ printer->Print("private static final $classname$ DEFAULT_INSTANCE;\n",
+ "classname",
+ name_resolver_->GetImmutableClassName(descriptor_));
+ printer->Print(
+ "static {\n"
+ " DEFAULT_INSTANCE = new $classname$();\n"
+ "}\n"
+ "\n",
+ "classname", name_resolver_->GetImmutableClassName(descriptor_));
+
+ printer->Print(
+ "public static $classname$ getDefaultInstance() {\n"
+ " return DEFAULT_INSTANCE;\n"
+ "}\n"
+ "\n",
+ "classname", name_resolver_->GetImmutableClassName(descriptor_));
+
+ // 'of' method for Wrappers
+ if (IsWrappersProtoFile(descriptor_->file())) {
+ printer->Print(
+ "public static $classname$ of($field_type$ value) {\n"
+ " return newBuilder().setValue(value).build();\n"
+ "}\n"
+ "\n",
+ "classname", name_resolver_->GetImmutableClassName(descriptor_),
+ "field_type", PrimitiveTypeName(GetJavaType(descriptor_->field(0))));
+ }
+
+ GenerateParser(printer);
+
+ printer->Print(
+ "@java.lang.Override\n"
+ "public $classname$ getDefaultInstanceForType() {\n"
+ " return DEFAULT_INSTANCE;\n"
+ "}\n"
+ "\n",
+ "classname", name_resolver_->GetImmutableClassName(descriptor_));
+
+ // Extensions must be declared after the DEFAULT_INSTANCE is initialized
+ // because the DEFAULT_INSTANCE is used by the extension to lazily retrieve
+ // the outer class's FileDescriptor.
+ for (int i = 0; i < descriptor_->extension_count(); i++) {
+ ImmutableExtensionGenerator(descriptor_->extension(i), context_)
+ .Generate(printer);
+ }
+
+ printer->Outdent();
+ printer->Print("}\n\n");
+}
+
+// ===================================================================
+
+void ImmutableMessageGenerator::GenerateMessageSerializationMethods(
+ io::Printer* printer) {
+ std::unique_ptr<const FieldDescriptor*[]> sorted_fields(
+ SortFieldsByNumber(descriptor_));
+
+ std::vector<const Descriptor::ExtensionRange*> sorted_extensions;
+ sorted_extensions.reserve(descriptor_->extension_range_count());
+ for (int i = 0; i < descriptor_->extension_range_count(); ++i) {
+ sorted_extensions.push_back(descriptor_->extension_range(i));
+ }
+ std::sort(sorted_extensions.begin(), sorted_extensions.end(),
+ ExtensionRangeOrdering());
+ printer->Print(
+ "@java.lang.Override\n"
+ "public void writeTo(com.google.protobuf.CodedOutputStream output)\n"
+ " throws java.io.IOException {\n");
+ printer->Indent();
+
+ if (HasPackedFields(descriptor_)) {
+ // writeTo(CodedOutputStream output) might be invoked without
+ // getSerializedSize() ever being called, but we need the memoized
+ // sizes in case this message has packed fields. Rather than emit checks
+ // for each packed field, just call getSerializedSize() up front. In most
+ // cases, getSerializedSize() will have already been called anyway by one
+ // of the wrapper writeTo() methods, making this call cheap.
+ printer->Print("getSerializedSize();\n");
+ }
+
+ if (descriptor_->extension_range_count() > 0) {
+ if (descriptor_->options().message_set_wire_format()) {
+ printer->Print(
+ "com.google.protobuf.GeneratedMessage$ver$\n"
+ " .ExtendableMessage<$classname$>.ExtensionWriter\n"
+ " extensionWriter = newMessageSetExtensionWriter();\n",
+ "classname", name_resolver_->GetImmutableClassName(descriptor_),
+ "ver", GeneratedCodeVersionSuffix());
+ } else {
+ printer->Print(
+ "com.google.protobuf.GeneratedMessage$ver$\n"
+ " .ExtendableMessage<$classname$>.ExtensionWriter\n"
+ " extensionWriter = newExtensionWriter();\n",
+ "classname", name_resolver_->GetImmutableClassName(descriptor_),
+ "ver", GeneratedCodeVersionSuffix());
+ }
+ }
+
+ // Merge the fields and the extension ranges, both sorted by field number.
+ for (int i = 0, j = 0;
+ i < descriptor_->field_count() || j < sorted_extensions.size();) {
+ if (i == descriptor_->field_count()) {
+ GenerateSerializeOneExtensionRange(printer, sorted_extensions[j++]);
+ } else if (j == sorted_extensions.size()) {
+ GenerateSerializeOneField(printer, sorted_fields[i++]);
+ } else if (sorted_fields[i]->number() < sorted_extensions[j]->start) {
+ GenerateSerializeOneField(printer, sorted_fields[i++]);
+ } else {
+ GenerateSerializeOneExtensionRange(printer, sorted_extensions[j++]);
+ }
+ }
+
+ if (descriptor_->options().message_set_wire_format()) {
+ printer->Print("unknownFields.writeAsMessageSetTo(output);\n");
+ } else {
+ printer->Print("unknownFields.writeTo(output);\n");
+ }
+
+ printer->Outdent();
+ printer->Print(
+ "}\n"
+ "\n"
+ "@java.lang.Override\n"
+ "public int getSerializedSize() {\n"
+ " int size = memoizedSize;\n"
+ " if (size != -1) return size;\n"
+ "\n");
+ printer->Indent();
+
+ printer->Print("size = 0;\n");
+
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ field_generators_.get(sorted_fields[i]).GenerateSerializedSizeCode(printer);
+ }
+
+ if (descriptor_->extension_range_count() > 0) {
+ if (descriptor_->options().message_set_wire_format()) {
+ printer->Print("size += extensionsSerializedSizeAsMessageSet();\n");
+ } else {
+ printer->Print("size += extensionsSerializedSize();\n");
+ }
+ }
+
+ if (descriptor_->options().message_set_wire_format()) {
+ printer->Print("size += unknownFields.getSerializedSizeAsMessageSet();\n");
+ } else {
+ printer->Print("size += unknownFields.getSerializedSize();\n");
+ }
+
+ printer->Print(
+ "memoizedSize = size;\n"
+ "return size;\n");
+
+ printer->Outdent();
+ printer->Print(
+ "}\n"
+ "\n");
+}
+
+void ImmutableMessageGenerator::GenerateParseFromMethods(io::Printer* printer) {
+ // Note: These are separate from GenerateMessageSerializationMethods()
+ // because they need to be generated even for messages that are optimized
+ // for code size.
+ printer->Print(
+ "public static $classname$ parseFrom(\n"
+ " java.nio.ByteBuffer data)\n"
+ " throws com.google.protobuf.InvalidProtocolBufferException {\n"
+ " return PARSER.parseFrom(data);\n"
+ "}\n"
+ "public static $classname$ parseFrom(\n"
+ " java.nio.ByteBuffer data,\n"
+ " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
+ " throws com.google.protobuf.InvalidProtocolBufferException {\n"
+ " return PARSER.parseFrom(data, extensionRegistry);\n"
+ "}\n"
+ "public static $classname$ parseFrom(\n"
+ " com.google.protobuf.ByteString data)\n"
+ " throws com.google.protobuf.InvalidProtocolBufferException {\n"
+ " return PARSER.parseFrom(data);\n"
+ "}\n"
+ "public static $classname$ parseFrom(\n"
+ " com.google.protobuf.ByteString data,\n"
+ " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
+ " throws com.google.protobuf.InvalidProtocolBufferException {\n"
+ " return PARSER.parseFrom(data, extensionRegistry);\n"
+ "}\n"
+ "public static $classname$ parseFrom(byte[] data)\n"
+ " throws com.google.protobuf.InvalidProtocolBufferException {\n"
+ " return PARSER.parseFrom(data);\n"
+ "}\n"
+ "public static $classname$ parseFrom(\n"
+ " byte[] data,\n"
+ " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
+ " throws com.google.protobuf.InvalidProtocolBufferException {\n"
+ " return PARSER.parseFrom(data, extensionRegistry);\n"
+ "}\n"
+ "public static $classname$ parseFrom(java.io.InputStream input)\n"
+ " throws java.io.IOException {\n"
+ " return com.google.protobuf.GeneratedMessage$ver$\n"
+ " .parseWithIOException(PARSER, input);\n"
+ "}\n"
+ "public static $classname$ parseFrom(\n"
+ " java.io.InputStream input,\n"
+ " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
+ " throws java.io.IOException {\n"
+ " return com.google.protobuf.GeneratedMessage$ver$\n"
+ " .parseWithIOException(PARSER, input, extensionRegistry);\n"
+ "}\n"
+ "public static $classname$ parseDelimitedFrom(java.io.InputStream "
+ "input)\n"
+ " throws java.io.IOException {\n"
+ " return com.google.protobuf.GeneratedMessage$ver$\n"
+ " .parseDelimitedWithIOException(PARSER, input);\n"
+ "}\n"
+ "public static $classname$ parseDelimitedFrom(\n"
+ " java.io.InputStream input,\n"
+ " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
+ " throws java.io.IOException {\n"
+ " return com.google.protobuf.GeneratedMessage$ver$\n"
+ " .parseDelimitedWithIOException(PARSER, input, "
+ "extensionRegistry);\n"
+ "}\n"
+ "public static $classname$ parseFrom(\n"
+ " com.google.protobuf.CodedInputStream input)\n"
+ " throws java.io.IOException {\n"
+ " return com.google.protobuf.GeneratedMessage$ver$\n"
+ " .parseWithIOException(PARSER, input);\n"
+ "}\n"
+ "public static $classname$ parseFrom(\n"
+ " com.google.protobuf.CodedInputStream input,\n"
+ " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
+ " throws java.io.IOException {\n"
+ " return com.google.protobuf.GeneratedMessage$ver$\n"
+ " .parseWithIOException(PARSER, input, extensionRegistry);\n"
+ "}\n"
+ "\n",
+ "classname", name_resolver_->GetImmutableClassName(descriptor_), "ver",
+ GeneratedCodeVersionSuffix());
+}
+
+void ImmutableMessageGenerator::GenerateSerializeOneField(
+ io::Printer* printer, const FieldDescriptor* field) {
+ field_generators_.get(field).GenerateSerializationCode(printer);
+}
+
+void ImmutableMessageGenerator::GenerateSerializeOneExtensionRange(
+ io::Printer* printer, const Descriptor::ExtensionRange* range) {
+ printer->Print("extensionWriter.writeUntil($end$, output);\n", "end",
+ StrCat(range->end));
+}
+
+// ===================================================================
+
+void ImmutableMessageGenerator::GenerateBuilder(io::Printer* printer) {
+ // LITE_RUNTIME implements this at the GeneratedMessageLite level.
+ printer->Print(
+ "@java.lang.Override\n"
+ "public Builder newBuilderForType() { return newBuilder(); }\n");
+
+ printer->Print(
+ "public static Builder newBuilder() {\n"
+ " return DEFAULT_INSTANCE.toBuilder();\n"
+ "}\n"
+ "public static Builder newBuilder($classname$ prototype) {\n"
+ " return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);\n"
+ "}\n"
+ "@java.lang.Override\n"
+ "public Builder toBuilder() {\n"
+ " return this == DEFAULT_INSTANCE\n"
+ " ? new Builder() : new Builder().mergeFrom(this);\n"
+ "}\n"
+ "\n",
+ "classname", name_resolver_->GetImmutableClassName(descriptor_));
+
+ printer->Print(
+ "@java.lang.Override\n"
+ "protected Builder newBuilderForType(\n"
+ " com.google.protobuf.GeneratedMessage$ver$.BuilderParent parent) {\n"
+ " Builder builder = new Builder(parent);\n"
+ " return builder;\n"
+ "}\n",
+ "ver", GeneratedCodeVersionSuffix());
+
+ MessageBuilderGenerator builderGenerator(descriptor_, context_);
+ builderGenerator.Generate(printer);
+}
+
+void ImmutableMessageGenerator::GenerateDescriptorMethods(
+ io::Printer* printer) {
+ if (!descriptor_->options().no_standard_descriptor_accessor()) {
+ printer->Print(
+ "public static final com.google.protobuf.Descriptors.Descriptor\n"
+ " getDescriptor() {\n"
+ " return $fileclass$.internal_$identifier$_descriptor;\n"
+ "}\n"
+ "\n",
+ "fileclass", name_resolver_->GetImmutableClassName(descriptor_->file()),
+ "identifier", UniqueFileScopeIdentifier(descriptor_));
+ }
+ std::vector<const FieldDescriptor*> map_fields;
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ const FieldDescriptor* field = descriptor_->field(i);
+ if (GetJavaType(field) == JAVATYPE_MESSAGE &&
+ IsMapEntry(field->message_type())) {
+ map_fields.push_back(field);
+ }
+ }
+ if (!map_fields.empty()) {
+ printer->Print(
+ "@SuppressWarnings({\"rawtypes\"})\n"
+ "@java.lang.Override\n"
+ "protected com.google.protobuf.MapField internalGetMapField(\n"
+ " int number) {\n"
+ " switch (number) {\n");
+ printer->Indent();
+ printer->Indent();
+ for (int i = 0; i < map_fields.size(); ++i) {
+ const FieldDescriptor* field = map_fields[i];
+ const FieldGeneratorInfo* info = context_->GetFieldGeneratorInfo(field);
+ printer->Print(
+ "case $number$:\n"
+ " return internalGet$capitalized_name$();\n",
+ "number", StrCat(field->number()), "capitalized_name",
+ info->capitalized_name);
+ }
+ printer->Print(
+ "default:\n"
+ " throw new RuntimeException(\n"
+ " \"Invalid map field number: \" + number);\n");
+ printer->Outdent();
+ printer->Outdent();
+ printer->Print(
+ " }\n"
+ "}\n");
+ }
+ printer->Print(
+ "@java.lang.Override\n"
+ "protected com.google.protobuf.GeneratedMessage$ver$.FieldAccessorTable\n"
+ " internalGetFieldAccessorTable() {\n"
+ " return $fileclass$.internal_$identifier$_fieldAccessorTable\n"
+ " .ensureFieldAccessorsInitialized(\n"
+ " $classname$.class, $classname$.Builder.class);\n"
+ "}\n"
+ "\n",
+ "classname", name_resolver_->GetImmutableClassName(descriptor_),
+ "fileclass", name_resolver_->GetImmutableClassName(descriptor_->file()),
+ "identifier", UniqueFileScopeIdentifier(descriptor_), "ver",
+ GeneratedCodeVersionSuffix());
+}
+
+// ===================================================================
+
+void ImmutableMessageGenerator::GenerateIsInitialized(io::Printer* printer) {
+ // Memoizes whether the protocol buffer is fully initialized (has all
+ // required fields). -1 means not yet computed. 0 means false and 1 means
+ // true.
+ printer->Print("private byte memoizedIsInitialized = -1;\n");
+ printer->Print(
+ "@java.lang.Override\n"
+ "public final boolean isInitialized() {\n");
+ printer->Indent();
+
+ // Don't directly compare to -1 to avoid an Android x86 JIT bug.
+ printer->Print(
+ "byte isInitialized = memoizedIsInitialized;\n"
+ "if (isInitialized == 1) return true;\n"
+ "if (isInitialized == 0) return false;\n"
+ "\n");
+
+ // Check that all required fields in this message are set.
+ // TODO(kenton): We can optimize this when we switch to putting all the
+ // "has" fields into a single bitfield.
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ const FieldDescriptor* field = descriptor_->field(i);
+ const FieldGeneratorInfo* info = context_->GetFieldGeneratorInfo(field);
+
+ if (field->is_required()) {
+ printer->Print(
+ "if (!has$name$()) {\n"
+ " memoizedIsInitialized = 0;\n"
+ " return false;\n"
+ "}\n",
+ "name", info->capitalized_name);
+ }
+ }
+
+ // Now check that all embedded messages are initialized.
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ const FieldDescriptor* field = descriptor_->field(i);
+ const FieldGeneratorInfo* info = context_->GetFieldGeneratorInfo(field);
+ if (GetJavaType(field) == JAVATYPE_MESSAGE &&
+ HasRequiredFields(field->message_type())) {
+ switch (field->label()) {
+ case FieldDescriptor::LABEL_REQUIRED:
+ printer->Print(
+ "if (!get$name$().isInitialized()) {\n"
+ " memoizedIsInitialized = 0;\n"
+ " return false;\n"
+ "}\n",
+ "type",
+ name_resolver_->GetImmutableClassName(field->message_type()),
+ "name", info->capitalized_name);
+ break;
+ case FieldDescriptor::LABEL_OPTIONAL:
+ printer->Print(
+ "if (has$name$()) {\n"
+ " if (!get$name$().isInitialized()) {\n"
+ " memoizedIsInitialized = 0;\n"
+ " return false;\n"
+ " }\n"
+ "}\n",
+ "name", info->capitalized_name);
+ break;
+ case FieldDescriptor::LABEL_REPEATED:
+ if (IsMapEntry(field->message_type())) {
+ printer->Print(
+ "for ($type$ item : get$name$Map().values()) {\n"
+ " if (!item.isInitialized()) {\n"
+ " memoizedIsInitialized = 0;\n"
+ " return false;\n"
+ " }\n"
+ "}\n",
+ "type",
+ MapValueImmutableClassdName(field->message_type(),
+ name_resolver_),
+ "name", info->capitalized_name);
+ } else {
+ printer->Print(
+ "for (int i = 0; i < get$name$Count(); i++) {\n"
+ " if (!get$name$(i).isInitialized()) {\n"
+ " memoizedIsInitialized = 0;\n"
+ " return false;\n"
+ " }\n"
+ "}\n",
+ "type",
+ name_resolver_->GetImmutableClassName(field->message_type()),
+ "name", info->capitalized_name);
+ }
+ break;
+ }
+ }
+ }
+
+ if (descriptor_->extension_range_count() > 0) {
+ printer->Print(
+ "if (!extensionsAreInitialized()) {\n"
+ " memoizedIsInitialized = 0;\n"
+ " return false;\n"
+ "}\n");
+ }
+
+ printer->Outdent();
+
+ printer->Print(" memoizedIsInitialized = 1;\n");
+
+ printer->Print(
+ " return true;\n"
+ "}\n"
+ "\n");
+}
+
+// ===================================================================
+
+namespace {
+bool CheckHasBitsForEqualsAndHashCode(const FieldDescriptor* field) {
+ if (field->is_repeated()) {
+ return false;
+ }
+ if (HasHasbit(field)) {
+ return true;
+ }
+ return GetJavaType(field) == JAVATYPE_MESSAGE && !IsRealOneof(field);
+}
+} // namespace
+
+void ImmutableMessageGenerator::GenerateEqualsAndHashCode(
+ io::Printer* printer) {
+ printer->Print(
+ "@java.lang.Override\n"
+ "public boolean equals(");
+ printer->Print("final java.lang.Object obj) {\n");
+ printer->Indent();
+ printer->Print(
+ "if (obj == this) {\n"
+ " return true;\n"
+ "}\n"
+ "if (!(obj instanceof $classname$)) {\n"
+ " return super.equals(obj);\n"
+ "}\n"
+ "$classname$ other = ($classname$) obj;\n"
+ "\n",
+ "classname", name_resolver_->GetImmutableClassName(descriptor_));
+
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ const FieldDescriptor* field = descriptor_->field(i);
+ if (!IsRealOneof(field)) {
+ const FieldGeneratorInfo* info = context_->GetFieldGeneratorInfo(field);
+ bool check_has_bits = CheckHasBitsForEqualsAndHashCode(field);
+ if (check_has_bits) {
+ printer->Print(
+ "if (has$name$() != other.has$name$()) return false;\n"
+ "if (has$name$()) {\n",
+ "name", info->capitalized_name);
+ printer->Indent();
+ }
+ field_generators_.get(field).GenerateEqualsCode(printer);
+ if (check_has_bits) {
+ printer->Outdent();
+ printer->Print("}\n");
+ }
+ }
+ }
+
+ // Compare oneofs.
+ for (auto oneof : oneofs_) {
+ printer->Print(
+ "if (!get$oneof_capitalized_name$Case().equals("
+ "other.get$oneof_capitalized_name$Case())) return false;\n",
+ "oneof_capitalized_name",
+ context_->GetOneofGeneratorInfo(oneof)->capitalized_name);
+ printer->Print("switch ($oneof_name$Case_) {\n", "oneof_name",
+ context_->GetOneofGeneratorInfo(oneof)->name);
+ printer->Indent();
+ for (int j = 0; j < (oneof)->field_count(); j++) {
+ const FieldDescriptor* field = (oneof)->field(j);
+ printer->Print("case $field_number$:\n", "field_number",
+ StrCat(field->number()));
+ printer->Indent();
+ field_generators_.get(field).GenerateEqualsCode(printer);
+ printer->Print("break;\n");
+ printer->Outdent();
+ }
+ printer->Print(
+ "case 0:\n"
+ "default:\n");
+ printer->Outdent();
+ printer->Print("}\n");
+ }
+
+ // Always consider unknown fields for equality. This will sometimes return
+ // false for non-canonical ordering when running in LITE_RUNTIME but it's
+ // the best we can do.
+ printer->Print(
+ "if (!unknownFields.equals(other.unknownFields)) return false;\n");
+ if (descriptor_->extension_range_count() > 0) {
+ printer->Print(
+ "if (!getExtensionFields().equals(other.getExtensionFields()))\n"
+ " return false;\n");
+ }
+ printer->Print("return true;\n");
+ printer->Outdent();
+ printer->Print(
+ "}\n"
+ "\n");
+
+ printer->Print(
+ "@java.lang.Override\n"
+ "public int hashCode() {\n");
+ printer->Indent();
+ printer->Print("if (memoizedHashCode != 0) {\n");
+ printer->Indent();
+ printer->Print("return memoizedHashCode;\n");
+ printer->Outdent();
+ printer->Print(
+ "}\n"
+ "int hash = 41;\n");
+
+ // If we output a getDescriptor() method, use that as it is more efficient.
+ if (descriptor_->options().no_standard_descriptor_accessor()) {
+ printer->Print("hash = (19 * hash) + getDescriptorForType().hashCode();\n");
+ } else {
+ printer->Print("hash = (19 * hash) + getDescriptor().hashCode();\n");
+ }
+
+ // hashCode non-oneofs.
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ const FieldDescriptor* field = descriptor_->field(i);
+ if (!IsRealOneof(field)) {
+ const FieldGeneratorInfo* info = context_->GetFieldGeneratorInfo(field);
+ bool check_has_bits = CheckHasBitsForEqualsAndHashCode(field);
+ if (check_has_bits) {
+ printer->Print("if (has$name$()) {\n", "name", info->capitalized_name);
+ printer->Indent();
+ }
+ field_generators_.get(field).GenerateHashCode(printer);
+ if (check_has_bits) {
+ printer->Outdent();
+ printer->Print("}\n");
+ }
+ }
+ }
+
+ // hashCode oneofs.
+ for (auto oneof : oneofs_) {
+ printer->Print("switch ($oneof_name$Case_) {\n", "oneof_name",
+ context_->GetOneofGeneratorInfo(oneof)->name);
+ printer->Indent();
+ for (int j = 0; j < (oneof)->field_count(); j++) {
+ const FieldDescriptor* field = (oneof)->field(j);
+ printer->Print("case $field_number$:\n", "field_number",
+ StrCat(field->number()));
+ printer->Indent();
+ field_generators_.get(field).GenerateHashCode(printer);
+ printer->Print("break;\n");
+ printer->Outdent();
+ }
+ printer->Print(
+ "case 0:\n"
+ "default:\n");
+ printer->Outdent();
+ printer->Print("}\n");
+ }
+
+ if (descriptor_->extension_range_count() > 0) {
+ printer->Print("hash = hashFields(hash, getExtensionFields());\n");
+ }
+
+ printer->Print("hash = (29 * hash) + unknownFields.hashCode();\n");
+ printer->Print(
+ "memoizedHashCode = hash;\n"
+ "return hash;\n");
+ printer->Outdent();
+ printer->Print(
+ "}\n"
+ "\n");
+}
+
+// ===================================================================
+
+void ImmutableMessageGenerator::GenerateExtensionRegistrationCode(
+ io::Printer* printer) {
+ for (int i = 0; i < descriptor_->extension_count(); i++) {
+ ImmutableExtensionGenerator(descriptor_->extension(i), context_)
+ .GenerateRegistrationCode(printer);
+ }
+
+ for (int i = 0; i < descriptor_->nested_type_count(); i++) {
+ ImmutableMessageGenerator(descriptor_->nested_type(i), context_)
+ .GenerateExtensionRegistrationCode(printer);
+ }
+}
+
+// ===================================================================
+void ImmutableMessageGenerator::GenerateParsingConstructor(
+ io::Printer* printer) {
+ std::unique_ptr<const FieldDescriptor*[]> sorted_fields(
+ SortFieldsByNumber(descriptor_));
+
+ printer->Print(
+ "private $classname$(\n"
+ " com.google.protobuf.CodedInputStream input,\n"
+ " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
+ " throws com.google.protobuf.InvalidProtocolBufferException {\n",
+ "classname", descriptor_->name());
+ printer->Indent();
+
+ // Initialize all fields to default.
+ printer->Print(
+ "this();\n"
+ "if (extensionRegistry == null) {\n"
+ " throw new java.lang.NullPointerException();\n"
+ "}\n");
+
+ // Use builder bits to track mutable repeated fields.
+ int totalBuilderBits = 0;
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ const ImmutableFieldGenerator& field =
+ field_generators_.get(descriptor_->field(i));
+ totalBuilderBits += field.GetNumBitsForBuilder();
+ }
+ int totalBuilderInts = (totalBuilderBits + 31) / 32;
+ for (int i = 0; i < totalBuilderInts; i++) {
+ printer->Print("int mutable_$bit_field_name$ = 0;\n", "bit_field_name",
+ GetBitFieldName(i));
+ }
+
+ printer->Print(
+ "com.google.protobuf.UnknownFieldSet.Builder unknownFields =\n"
+ " com.google.protobuf.UnknownFieldSet.newBuilder();\n");
+
+ printer->Print("try {\n");
+ printer->Indent();
+
+ printer->Print(
+ "boolean done = false;\n"
+ "while (!done) {\n");
+ printer->Indent();
+
+ printer->Print(
+ "int tag = input.readTag();\n"
+ "switch (tag) {\n");
+ printer->Indent();
+
+ printer->Print(
+ "case 0:\n" // zero signals EOF / limit reached
+ " done = true;\n"
+ " break;\n");
+
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ const FieldDescriptor* field = sorted_fields[i];
+ uint32_t tag = WireFormatLite::MakeTag(
+ field->number(), WireFormat::WireTypeForFieldType(field->type()));
+
+ printer->Print("case $tag$: {\n", "tag",
+ StrCat(static_cast<int32_t>(tag)));
+ printer->Indent();
+
+ field_generators_.get(field).GenerateParsingCode(printer);
+
+ printer->Outdent();
+ printer->Print(
+ " break;\n"
+ "}\n");
+
+ if (field->is_packable()) {
+ // To make packed = true wire compatible, we generate parsing code from a
+ // packed version of this field regardless of field->options().packed().
+ uint32_t packed_tag = WireFormatLite::MakeTag(
+ field->number(), WireFormatLite::WIRETYPE_LENGTH_DELIMITED);
+ printer->Print("case $tag$: {\n", "tag",
+ StrCat(static_cast<int32_t>(packed_tag)));
+ printer->Indent();
+
+ field_generators_.get(field).GenerateParsingCodeFromPacked(printer);
+
+ printer->Outdent();
+ printer->Print(
+ " break;\n"
+ "}\n");
+ }
+ }
+
+ printer->Print(
+ "default: {\n"
+ " if (!parseUnknownField(\n"
+ " input, unknownFields, extensionRegistry, tag)) {\n"
+ " done = true;\n" // it's an endgroup tag
+ " }\n"
+ " break;\n"
+ "}\n");
+
+ printer->Outdent();
+ printer->Outdent();
+ printer->Print(
+ " }\n" // switch (tag)
+ "}\n"); // while (!done)
+
+ printer->Outdent();
+ printer->Print(
+ "} catch (com.google.protobuf.InvalidProtocolBufferException e) {\n"
+ " throw e.setUnfinishedMessage(this);\n"
+ "} catch (java.io.IOException e) {\n"
+ " throw new com.google.protobuf.InvalidProtocolBufferException(\n"
+ " e).setUnfinishedMessage(this);\n"
+ "} finally {\n");
+ printer->Indent();
+
+ // Make repeated field list immutable.
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ const FieldDescriptor* field = sorted_fields[i];
+ field_generators_.get(field).GenerateParsingDoneCode(printer);
+ }
+
+ // Make unknown fields immutable.
+ printer->Print("this.unknownFields = unknownFields.build();\n");
+
+ // Make extensions immutable.
+ printer->Print("makeExtensionsImmutable();\n");
+
+ printer->Outdent();
+ printer->Outdent();
+ printer->Print(
+ " }\n" // finally
+ "}\n");
+}
+
+// ===================================================================
+void ImmutableMessageGenerator::GenerateParser(io::Printer* printer) {
+ printer->Print(
+ "$visibility$ static final com.google.protobuf.Parser<$classname$>\n"
+ " PARSER = new com.google.protobuf.AbstractParser<$classname$>() {\n",
+ "visibility",
+ ExposePublicParser(descriptor_->file()) ? "@java.lang.Deprecated public"
+ : "private",
+ "classname", descriptor_->name());
+ printer->Indent();
+ printer->Print(
+ "@java.lang.Override\n"
+ "public $classname$ parsePartialFrom(\n"
+ " com.google.protobuf.CodedInputStream input,\n"
+ " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
+ " throws com.google.protobuf.InvalidProtocolBufferException {\n",
+ "classname", descriptor_->name());
+ if (context_->HasGeneratedMethods(descriptor_)) {
+ printer->Print(" return new $classname$(input, extensionRegistry);\n",
+ "classname", descriptor_->name());
+ } else {
+ // When parsing constructor isn't generated, use builder to parse
+ // messages. Note, will fallback to use reflection based mergeFieldFrom()
+ // in AbstractMessage.Builder.
+ printer->Indent();
+ printer->Print(
+ "Builder builder = newBuilder();\n"
+ "try {\n"
+ " builder.mergeFrom(input, extensionRegistry);\n"
+ "} catch (com.google.protobuf.InvalidProtocolBufferException e) {\n"
+ " throw e.setUnfinishedMessage(builder.buildPartial());\n"
+ "} catch (java.io.IOException e) {\n"
+ " throw new com.google.protobuf.InvalidProtocolBufferException(\n"
+ " e.getMessage()).setUnfinishedMessage(\n"
+ " builder.buildPartial());\n"
+ "}\n"
+ "return builder.buildPartial();\n");
+ printer->Outdent();
+ }
+ printer->Print("}\n");
+ printer->Outdent();
+ printer->Print(
+ "};\n"
+ "\n");
+
+ printer->Print(
+ "public static com.google.protobuf.Parser<$classname$> parser() {\n"
+ " return PARSER;\n"
+ "}\n"
+ "\n"
+ "@java.lang.Override\n"
+ "public com.google.protobuf.Parser<$classname$> getParserForType() {\n"
+ " return PARSER;\n"
+ "}\n"
+ "\n",
+ "classname", descriptor_->name());
+}
+
+// ===================================================================
+void ImmutableMessageGenerator::GenerateInitializers(io::Printer* printer) {
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ if (!IsRealOneof(descriptor_->field(i))) {
+ field_generators_.get(descriptor_->field(i))
+ .GenerateInitializationCode(printer);
+ }
+ }
+}
+
+// ===================================================================
+void ImmutableMessageGenerator::GenerateMutableCopy(io::Printer* printer) {
+ printer->Print(
+ "protected com.google.protobuf.MutableMessage\n"
+ " internalMutableDefault() {\n"
+ " return MutableDefaultLoader.get();\n"
+ "}\n"
+ "\n"
+ "private static final class MutableDefaultLoader {\n"
+ " private static final java.lang.Object defaultOrRuntimeException;\n"
+ " static {\n"
+ " java.lang.Object local;\n"
+ " try {\n"
+ " local = internalMutableDefault(\"$mutable_name$\");\n"
+ " } catch (java.lang.RuntimeException e) {\n"
+ " local = e;\n"
+ " }\n"
+ " defaultOrRuntimeException = local;\n"
+ " }\n"
+ "\n"
+ " private MutableDefaultLoader() {}\n"
+ "\n"
+ " public static com.google.protobuf.MutableMessage get() {\n"
+ " if (defaultOrRuntimeException\n"
+ " instanceof java.lang.RuntimeException) {\n"
+ " throw (java.lang.RuntimeException) defaultOrRuntimeException;\n"
+ " }\n"
+ " return\n"
+ " (com.google.protobuf.MutableMessage) "
+ "defaultOrRuntimeException;\n"
+ " }\n"
+ "}\n",
+ "mutable_name", name_resolver_->GetJavaMutableClassName(descriptor_));
+}
+
+void ImmutableMessageGenerator::GenerateKotlinDsl(io::Printer* printer) const {
+ printer->Print(
+ "@kotlin.OptIn"
+ "(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)\n"
+ "@com.google.protobuf.kotlin.ProtoDslMarker\n");
+ printer->Print(
+ "public class Dsl private constructor(\n"
+ " private val _builder: $message$.Builder\n"
+ ") {\n"
+ " public companion object {\n"
+ " @kotlin.jvm.JvmSynthetic\n"
+ " @kotlin.PublishedApi\n"
+ " internal fun _create(builder: $message$.Builder): Dsl = "
+ "Dsl(builder)\n"
+ " }\n"
+ "\n"
+ " @kotlin.jvm.JvmSynthetic\n"
+ " @kotlin.PublishedApi\n"
+ " internal fun _build(): $message$ = _builder.build()\n",
+ "message", name_resolver_->GetClassName(descriptor_, true));
+
+ printer->Indent();
+
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ printer->Print("\n");
+ field_generators_.get(descriptor_->field(i))
+ .GenerateKotlinDslMembers(printer);
+ }
+
+ for (auto oneof : oneofs_) {
+ printer->Print(
+ "public val $oneof_name$Case: $message$.$oneof_capitalized_name$Case\n"
+ " @JvmName(\"get$oneof_capitalized_name$Case\")\n"
+ " get() = _builder.get$oneof_capitalized_name$Case()\n\n"
+ "public fun clear$oneof_capitalized_name$() {\n"
+ " _builder.clear$oneof_capitalized_name$()\n"
+ "}\n",
+ "oneof_name", context_->GetOneofGeneratorInfo(oneof)->name,
+ "oneof_capitalized_name",
+ context_->GetOneofGeneratorInfo(oneof)->capitalized_name, "message",
+ name_resolver_->GetClassName(descriptor_, true));
+ }
+
+ if (descriptor_->extension_range_count() > 0) {
+ GenerateKotlinExtensions(printer);
+ }
+
+ printer->Outdent();
+ printer->Print("}\n");
+}
+
+void ImmutableMessageGenerator::GenerateKotlinMembers(
+ io::Printer* printer) const {
+ printer->Print(
+ "@kotlin.jvm.JvmSynthetic\n"
+ "public inline fun $camelcase_name$(block: $message_kt$.Dsl.() -> "
+ "kotlin.Unit): "
+ "$message$ "
+ "=\n"
+ " $message_kt$.Dsl._create($message$.newBuilder()).apply { block() "
+ "}._build()\n",
+ "camelcase_name", name_resolver_->GetKotlinFactoryName(descriptor_),
+ "message_kt", name_resolver_->GetKotlinExtensionsClassName(descriptor_),
+ "message", name_resolver_->GetClassName(descriptor_, true));
+
+ printer->Print("public object $name$Kt {\n", "name", descriptor_->name());
+ printer->Indent();
+ GenerateKotlinDsl(printer);
+ for (int i = 0; i < descriptor_->nested_type_count(); i++) {
+ if (IsMapEntry(descriptor_->nested_type(i))) continue;
+ ImmutableMessageGenerator(descriptor_->nested_type(i), context_)
+ .GenerateKotlinMembers(printer);
+ }
+ printer->Outdent();
+ printer->Print("}\n");
+}
+
+void ImmutableMessageGenerator::GenerateTopLevelKotlinMembers(
+ io::Printer* printer) const {
+ printer->Print(
+ "@kotlin.jvm.JvmSynthetic\n"
+ "public inline fun $message$.copy(block: $message_kt$.Dsl.() -> "
+ "kotlin.Unit): "
+ "$message$ =\n"
+ " $message_kt$.Dsl._create(this.toBuilder()).apply { block() "
+ "}._build()\n",
+ "message", name_resolver_->GetClassName(descriptor_, true), "message_kt",
+ name_resolver_->GetKotlinExtensionsClassName(descriptor_));
+
+ for (int i = 0; i < descriptor_->nested_type_count(); i++) {
+ if (IsMapEntry(descriptor_->nested_type(i))) continue;
+ ImmutableMessageGenerator(descriptor_->nested_type(i), context_)
+ .GenerateTopLevelKotlinMembers(printer);
+ }
+}
+
+void ImmutableMessageGenerator::GenerateKotlinExtensions(
+ io::Printer* printer) const {
+ std::string message_name = name_resolver_->GetClassName(descriptor_, true);
+
+ printer->Print(
+ "@Suppress(\"UNCHECKED_CAST\")\n"
+ "@kotlin.jvm.JvmSynthetic\n"
+ "public operator fun <T> get(extension: "
+ "com.google.protobuf.ExtensionLite<$message$, T>): T {\n"
+ " return if (extension.isRepeated) {\n"
+ " get(extension as com.google.protobuf.ExtensionLite<$message$, "
+ "List<*>>) as T\n"
+ " } else {\n"
+ " _builder.getExtension(extension)\n"
+ " }\n"
+ "}\n\n",
+ "message", message_name);
+
+ printer->Print(
+ "@kotlin.jvm.JvmSynthetic\n"
+ "@kotlin.OptIn"
+ "(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)\n"
+ "@kotlin.jvm.JvmName(\"-getRepeatedExtension\")\n"
+ "public operator fun <E> get(\n"
+ " extension: com.google.protobuf.ExtensionLite<$message$, List<E>>\n"
+ "): com.google.protobuf.kotlin.ExtensionList<E, $message$> {\n"
+ " return com.google.protobuf.kotlin.ExtensionList(extension, "
+ "_builder.getExtension(extension))\n"
+ "}\n\n",
+ "message", message_name);
+
+ printer->Print(
+ "@kotlin.jvm.JvmSynthetic\n"
+ "public operator fun contains(extension: "
+ "com.google.protobuf.ExtensionLite<$message$, *>): "
+ "Boolean {\n"
+ " return _builder.hasExtension(extension)\n"
+ "}\n\n",
+ "message", message_name);
+
+ printer->Print(
+ "@kotlin.jvm.JvmSynthetic\n"
+ "public fun clear(extension: "
+ "com.google.protobuf.ExtensionLite<$message$, *>) "
+ "{\n"
+ " _builder.clearExtension(extension)\n"
+ "}\n\n",
+ "message", message_name);
+
+ printer->Print(
+ "@kotlin.jvm.JvmSynthetic\n"
+ "@kotlin.PublishedApi\n"
+ "internal fun <T> setExtension(extension: "
+ "com.google.protobuf.ExtensionLite<$message$, T>, "
+ "value: T) {\n"
+ " _builder.setExtension(extension, value)\n"
+ "}\n\n",
+ "message", message_name);
+
+ printer->Print(
+ "@kotlin.jvm.JvmSynthetic\n"
+ "@Suppress(\"NOTHING_TO_INLINE\")\n"
+ "public inline operator fun <T : Comparable<T>> set(\n"
+ " extension: com.google.protobuf.ExtensionLite<$message$, T>,\n"
+ " value: T\n"
+ ") {\n"
+ " setExtension(extension, value)\n"
+ "}\n\n",
+ "message", message_name);
+
+ printer->Print(
+ "@kotlin.jvm.JvmSynthetic\n"
+ "@Suppress(\"NOTHING_TO_INLINE\")\n"
+ "public inline operator fun set(\n"
+ " extension: com.google.protobuf.ExtensionLite<$message$, "
+ "com.google.protobuf.ByteString>,\n"
+ " value: com.google.protobuf.ByteString\n"
+ ") {\n"
+ " setExtension(extension, value)\n"
+ "}\n\n",
+ "message", message_name);
+
+ printer->Print(
+ "@kotlin.jvm.JvmSynthetic\n"
+ "@Suppress(\"NOTHING_TO_INLINE\")\n"
+ "public inline operator fun <T : com.google.protobuf.MessageLite> set(\n"
+ " extension: com.google.protobuf.ExtensionLite<$message$, T>,\n"
+ " value: T\n"
+ ") {\n"
+ " setExtension(extension, value)\n"
+ "}\n\n",
+ "message", message_name);
+
+ printer->Print(
+ "@kotlin.jvm.JvmSynthetic\n"
+ "public fun <E> com.google.protobuf.kotlin.ExtensionList<E, "
+ "$message$>.add(value: E) {\n"
+ " _builder.addExtension(this.extension, value)\n"
+ "}\n\n",
+ "message", message_name);
+
+ printer->Print(
+ "@kotlin.jvm.JvmSynthetic\n"
+ "@Suppress(\"NOTHING_TO_INLINE\")\n"
+ "public inline operator fun <E> "
+ "com.google.protobuf.kotlin.ExtensionList<E, "
+ "$message$>.plusAssign"
+ "(value: E) {\n"
+ " add(value)\n"
+ "}\n\n",
+ "message", message_name);
+
+ printer->Print(
+ "@kotlin.jvm.JvmSynthetic\n"
+ "public fun <E> com.google.protobuf.kotlin.ExtensionList<E, "
+ "$message$>.addAll(values: Iterable<E>) {\n"
+ " for (value in values) {\n"
+ " add(value)\n"
+ " }\n"
+ "}\n\n",
+ "message", message_name);
+
+ printer->Print(
+ "@kotlin.jvm.JvmSynthetic\n"
+ "@Suppress(\"NOTHING_TO_INLINE\")\n"
+ "public inline operator fun <E> "
+ "com.google.protobuf.kotlin.ExtensionList<E, "
+ "$message$>.plusAssign(values: "
+ "Iterable<E>) {\n"
+ " addAll(values)\n"
+ "}\n\n",
+ "message", message_name);
+
+ printer->Print(
+ "@kotlin.jvm.JvmSynthetic\n"
+ "public operator fun <E> com.google.protobuf.kotlin.ExtensionList<E, "
+ "$message$>.set(index: Int, value: "
+ "E) {\n"
+ " _builder.setExtension(this.extension, index, value)\n"
+ "}\n\n",
+ "message", message_name);
+
+ printer->Print(
+ "@kotlin.jvm.JvmSynthetic\n"
+ "@Suppress(\"NOTHING_TO_INLINE\")\n"
+ "public inline fun com.google.protobuf.kotlin.ExtensionList<*, "
+ "$message$>.clear() {\n"
+ " clear(extension)\n"
+ "}\n\n",
+ "message", message_name);
+}
+
+void ImmutableMessageGenerator::GenerateAnyMethods(io::Printer* printer) {
+ printer->Print(
+ "private static String getTypeUrl(\n"
+ " java.lang.String typeUrlPrefix,\n"
+ " com.google.protobuf.Descriptors.Descriptor descriptor) {\n"
+ " return typeUrlPrefix.endsWith(\"/\")\n"
+ " ? typeUrlPrefix + descriptor.getFullName()\n"
+ " : typeUrlPrefix + \"/\" + descriptor.getFullName();\n"
+ "}\n"
+ "\n"
+ "private static String getTypeNameFromTypeUrl(\n"
+ " java.lang.String typeUrl) {\n"
+ " int pos = typeUrl.lastIndexOf('/');\n"
+ " return pos == -1 ? \"\" : typeUrl.substring(pos + 1);\n"
+ "}\n"
+ "\n"
+ "public static <T extends com.google.protobuf.Message> Any pack(\n"
+ " T message) {\n"
+ " return Any.newBuilder()\n"
+ " .setTypeUrl(getTypeUrl(\"type.googleapis.com\",\n"
+ " message.getDescriptorForType()))\n"
+ " .setValue(message.toByteString())\n"
+ " .build();\n"
+ "}\n"
+ "\n"
+ "/**\n"
+ " * Packs a message using the given type URL prefix. The type URL will\n"
+ " * be constructed by concatenating the message type's full name to the\n"
+ " * prefix with an optional \"/\" separator if the prefix doesn't end\n"
+ " * with \"/\" already.\n"
+ " */\n"
+ "public static <T extends com.google.protobuf.Message> Any pack(\n"
+ " T message, java.lang.String typeUrlPrefix) {\n"
+ " return Any.newBuilder()\n"
+ " .setTypeUrl(getTypeUrl(typeUrlPrefix,\n"
+ " message.getDescriptorForType()))\n"
+ " .setValue(message.toByteString())\n"
+ " .build();\n"
+ "}\n"
+ "\n"
+ "public <T extends com.google.protobuf.Message> boolean is(\n"
+ " java.lang.Class<T> clazz) {\n"
+ " T defaultInstance =\n"
+ " com.google.protobuf.Internal.getDefaultInstance(clazz);\n"
+ " return getTypeNameFromTypeUrl(getTypeUrl()).equals(\n"
+ " defaultInstance.getDescriptorForType().getFullName());\n"
+ "}\n"
+ "\n"
+ "private volatile com.google.protobuf.Message cachedUnpackValue;\n"
+ "\n"
+ "@java.lang.SuppressWarnings(\"unchecked\")\n"
+ "public <T extends com.google.protobuf.Message> T unpack(\n"
+ " java.lang.Class<T> clazz)\n"
+ " throws com.google.protobuf.InvalidProtocolBufferException {\n"
+ " boolean invalidClazz = false;\n"
+ " if (cachedUnpackValue != null) {\n"
+ " if (cachedUnpackValue.getClass() == clazz) {\n"
+ " return (T) cachedUnpackValue;\n"
+ " }\n"
+ " invalidClazz = true;\n"
+ " }\n"
+ " if (invalidClazz || !is(clazz)) {\n"
+ " throw new com.google.protobuf.InvalidProtocolBufferException(\n"
+ " \"Type of the Any message does not match the given class.\");\n"
+ " }\n"
+ " T defaultInstance =\n"
+ " com.google.protobuf.Internal.getDefaultInstance(clazz);\n"
+ " T result = (T) defaultInstance.getParserForType()\n"
+ " .parseFrom(getValue());\n"
+ " cachedUnpackValue = result;\n"
+ " return result;\n"
+ "}\n");
+}
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_message.h b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_message.h
new file mode 100644
index 00000000..7ee4e431
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_message.h
@@ -0,0 +1,153 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 GOOGLE_PROTOBUF_COMPILER_JAVA_MESSAGE_H__
+#define GOOGLE_PROTOBUF_COMPILER_JAVA_MESSAGE_H__
+
+#include <map>
+#include <string>
+#include <compiler/java/java_field.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+class Context; // context.h
+class ClassNameResolver; // name_resolver.h
+} // namespace java
+} // namespace compiler
+namespace io {
+class Printer; // printer.h
+}
+} // namespace protobuf
+} // namespace google
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+static const int kMaxStaticSize = 1 << 15; // aka 32k
+
+class MessageGenerator {
+ public:
+ explicit MessageGenerator(const Descriptor* descriptor);
+ virtual ~MessageGenerator();
+
+ // All static variables have to be declared at the top-level of the file
+ // so that we can control initialization order, which is important for
+ // DescriptorProto bootstrapping to work.
+ virtual void GenerateStaticVariables(io::Printer* printer,
+ int* bytecode_estimate) = 0;
+
+ // Output code which initializes the static variables generated by
+ // GenerateStaticVariables(). Returns an estimate of bytecode size.
+ virtual int GenerateStaticVariableInitializers(io::Printer* printer) = 0;
+
+ // Generate the class itself.
+ virtual void Generate(io::Printer* printer) = 0;
+
+ // Generates the base interface that both the class and its builder
+ // implement
+ virtual void GenerateInterface(io::Printer* printer) = 0;
+
+ // Generate code to register all contained extensions with an
+ // ExtensionRegistry.
+ virtual void GenerateExtensionRegistrationCode(io::Printer* printer) = 0;
+ virtual void GenerateKotlinDsl(io::Printer* printer) const = 0;
+ virtual void GenerateKotlinMembers(io::Printer* printer) const = 0;
+ virtual void GenerateTopLevelKotlinMembers(io::Printer* printer) const = 0;
+
+ protected:
+ const Descriptor* descriptor_;
+ std::set<const OneofDescriptor*> oneofs_;
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageGenerator);
+};
+
+class ImmutableMessageGenerator : public MessageGenerator {
+ public:
+ ImmutableMessageGenerator(const Descriptor* descriptor, Context* context);
+ virtual ~ImmutableMessageGenerator();
+
+ void Generate(io::Printer* printer) override;
+ void GenerateInterface(io::Printer* printer) override;
+ void GenerateExtensionRegistrationCode(io::Printer* printer) override;
+ void GenerateStaticVariables(io::Printer* printer,
+ int* bytecode_estimate) override;
+
+ // Returns an estimate of the number of bytes the printed code will compile to
+ int GenerateStaticVariableInitializers(io::Printer* printer) override;
+ void GenerateKotlinDsl(io::Printer* printer) const override;
+ void GenerateKotlinMembers(io::Printer* printer) const override;
+ void GenerateTopLevelKotlinMembers(io::Printer* printer) const override;
+
+ private:
+ void GenerateFieldAccessorTable(io::Printer* printer, int* bytecode_estimate);
+
+ // Returns an estimate of the number of bytes the printed code will compile to
+ int GenerateFieldAccessorTableInitializer(io::Printer* printer);
+
+ void GenerateMessageSerializationMethods(io::Printer* printer);
+ void GenerateParseFromMethods(io::Printer* printer);
+ void GenerateSerializeOneField(io::Printer* printer,
+ const FieldDescriptor* field);
+ void GenerateSerializeOneExtensionRange(
+ io::Printer* printer, const Descriptor::ExtensionRange* range);
+
+ void GenerateBuilder(io::Printer* printer);
+ void GenerateIsInitialized(io::Printer* printer);
+ void GenerateDescriptorMethods(io::Printer* printer);
+ void GenerateInitializers(io::Printer* printer);
+ void GenerateEqualsAndHashCode(io::Printer* printer);
+ void GenerateParser(io::Printer* printer);
+ void GenerateParsingConstructor(io::Printer* printer);
+ void GenerateMutableCopy(io::Printer* printer);
+ void GenerateKotlinExtensions(io::Printer* printer) const;
+ void GenerateAnyMethods(io::Printer* printer);
+
+ Context* context_;
+ ClassNameResolver* name_resolver_;
+ FieldGeneratorMap<ImmutableFieldGenerator> field_generators_;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableMessageGenerator);
+};
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_MESSAGE_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_message_builder.cc b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_message_builder.cc
new file mode 100644
index 00000000..ac72da8e
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_message_builder.cc
@@ -0,0 +1,712 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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: dweis@google.com (Daniel Weis)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <compiler/java/java_message_builder.h>
+
+#include <algorithm>
+#include <map>
+#include <memory>
+#include <vector>
+
+#include <compiler/java/java_context.h>
+#include <compiler/java/java_doc_comment.h>
+#include <compiler/java/java_enum.h>
+#include <compiler/java/java_extension.h>
+#include <compiler/java/java_generator_factory.h>
+#include <compiler/java/java_helpers.h>
+#include <compiler/java/java_name_resolver.h>
+#include <descriptor.pb.h>
+#include <io/coded_stream.h>
+#include <io/printer.h>
+#include <wire_format.h>
+#include <stubs/strutil.h>
+#include <stubs/substitute.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+namespace {
+std::string MapValueImmutableClassdName(const Descriptor* descriptor,
+ ClassNameResolver* name_resolver) {
+ const FieldDescriptor* value_field = descriptor->FindFieldByName("value");
+ GOOGLE_CHECK_EQ(FieldDescriptor::TYPE_MESSAGE, value_field->type());
+ return name_resolver->GetImmutableClassName(value_field->message_type());
+}
+} // namespace
+
+MessageBuilderGenerator::MessageBuilderGenerator(const Descriptor* descriptor,
+ Context* context)
+ : descriptor_(descriptor),
+ context_(context),
+ name_resolver_(context->GetNameResolver()),
+ field_generators_(descriptor, context_) {
+ GOOGLE_CHECK(HasDescriptorMethods(descriptor->file(), context->EnforceLite()))
+ << "Generator factory error: A non-lite message generator is used to "
+ "generate lite messages.";
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ if (IsRealOneof(descriptor_->field(i))) {
+ oneofs_.insert(descriptor_->field(i)->containing_oneof());
+ }
+ }
+}
+
+MessageBuilderGenerator::~MessageBuilderGenerator() {}
+
+void MessageBuilderGenerator::Generate(io::Printer* printer) {
+ WriteMessageDocComment(printer, descriptor_);
+ if (descriptor_->extension_range_count() > 0) {
+ printer->Print(
+ "public static final class Builder extends\n"
+ " com.google.protobuf.GeneratedMessage$ver$.ExtendableBuilder<\n"
+ " $classname$, Builder> implements\n"
+ " $extra_interfaces$\n"
+ " $classname$OrBuilder {\n",
+ "classname", name_resolver_->GetImmutableClassName(descriptor_),
+ "extra_interfaces", ExtraBuilderInterfaces(descriptor_), "ver",
+ GeneratedCodeVersionSuffix());
+ } else {
+ printer->Print(
+ "public static final class Builder extends\n"
+ " com.google.protobuf.GeneratedMessage$ver$.Builder<Builder> "
+ "implements\n"
+ " $extra_interfaces$\n"
+ " $classname$OrBuilder {\n",
+ "classname", name_resolver_->GetImmutableClassName(descriptor_),
+ "extra_interfaces", ExtraBuilderInterfaces(descriptor_), "ver",
+ GeneratedCodeVersionSuffix());
+ }
+ printer->Indent();
+
+ GenerateDescriptorMethods(printer);
+ GenerateCommonBuilderMethods(printer);
+
+ if (context_->HasGeneratedMethods(descriptor_)) {
+ GenerateIsInitialized(printer);
+ GenerateBuilderParsingMethods(printer);
+ }
+
+ // oneof
+ std::map<std::string, std::string> vars;
+ for (auto oneof : oneofs_) {
+ vars["oneof_name"] = context_->GetOneofGeneratorInfo(oneof)->name;
+ vars["oneof_capitalized_name"] =
+ context_->GetOneofGeneratorInfo(oneof)->capitalized_name;
+ vars["oneof_index"] = StrCat(oneof->index());
+ // oneofCase_ and oneof_
+ printer->Print(vars,
+ "private int $oneof_name$Case_ = 0;\n"
+ "private java.lang.Object $oneof_name$_;\n");
+ // oneofCase() and clearOneof()
+ printer->Print(vars,
+ "public $oneof_capitalized_name$Case\n"
+ " get$oneof_capitalized_name$Case() {\n"
+ " return $oneof_capitalized_name$Case.forNumber(\n"
+ " $oneof_name$Case_);\n"
+ "}\n"
+ "\n"
+ "public Builder clear$oneof_capitalized_name$() {\n"
+ " $oneof_name$Case_ = 0;\n"
+ " $oneof_name$_ = null;\n");
+ printer->Print(" onChanged();\n");
+ printer->Print(
+ " return this;\n"
+ "}\n"
+ "\n");
+ }
+
+ // Integers for bit fields.
+ int totalBits = 0;
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ totalBits +=
+ field_generators_.get(descriptor_->field(i)).GetNumBitsForBuilder();
+ }
+ int totalInts = (totalBits + 31) / 32;
+ for (int i = 0; i < totalInts; i++) {
+ printer->Print("private int $bit_field_name$;\n", "bit_field_name",
+ GetBitFieldName(i));
+ }
+
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ printer->Print("\n");
+ field_generators_.get(descriptor_->field(i))
+ .GenerateBuilderMembers(printer);
+ }
+
+ // Override methods declared in GeneratedMessage to return the concrete
+ // generated type so callsites won't depend on GeneratedMessage. This
+ // is needed to keep binary compatibility when we change generated code
+ // to subclass a different GeneratedMessage class (e.g., in v3.0.0 release
+ // we changed all generated code to subclass GeneratedMessageV3).
+ printer->Print(
+ "@java.lang.Override\n"
+ "public final Builder setUnknownFields(\n"
+ " final com.google.protobuf.UnknownFieldSet unknownFields) {\n"
+ " return super.setUnknownFields(unknownFields);\n"
+ "}\n"
+ "\n"
+ "@java.lang.Override\n"
+ "public final Builder mergeUnknownFields(\n"
+ " final com.google.protobuf.UnknownFieldSet unknownFields) {\n"
+ " return super.mergeUnknownFields(unknownFields);\n"
+ "}\n"
+ "\n");
+
+ printer->Print(
+ "\n"
+ "// @@protoc_insertion_point(builder_scope:$full_name$)\n",
+ "full_name", descriptor_->full_name());
+
+ printer->Outdent();
+ printer->Print("}\n");
+}
+
+// ===================================================================
+
+void MessageBuilderGenerator::GenerateDescriptorMethods(io::Printer* printer) {
+ if (!descriptor_->options().no_standard_descriptor_accessor()) {
+ printer->Print(
+ "public static final com.google.protobuf.Descriptors.Descriptor\n"
+ " getDescriptor() {\n"
+ " return $fileclass$.internal_$identifier$_descriptor;\n"
+ "}\n"
+ "\n",
+ "fileclass", name_resolver_->GetImmutableClassName(descriptor_->file()),
+ "identifier", UniqueFileScopeIdentifier(descriptor_));
+ }
+ std::vector<const FieldDescriptor*> map_fields;
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ const FieldDescriptor* field = descriptor_->field(i);
+ if (GetJavaType(field) == JAVATYPE_MESSAGE &&
+ IsMapEntry(field->message_type())) {
+ map_fields.push_back(field);
+ }
+ }
+ if (!map_fields.empty()) {
+ printer->Print(
+ "@SuppressWarnings({\"rawtypes\"})\n"
+ "protected com.google.protobuf.MapField internalGetMapField(\n"
+ " int number) {\n"
+ " switch (number) {\n");
+ printer->Indent();
+ printer->Indent();
+ for (int i = 0; i < map_fields.size(); ++i) {
+ const FieldDescriptor* field = map_fields[i];
+ const FieldGeneratorInfo* info = context_->GetFieldGeneratorInfo(field);
+ printer->Print(
+ "case $number$:\n"
+ " return internalGet$capitalized_name$();\n",
+ "number", StrCat(field->number()), "capitalized_name",
+ info->capitalized_name);
+ }
+ printer->Print(
+ "default:\n"
+ " throw new RuntimeException(\n"
+ " \"Invalid map field number: \" + number);\n");
+ printer->Outdent();
+ printer->Outdent();
+ printer->Print(
+ " }\n"
+ "}\n");
+ printer->Print(
+ "@SuppressWarnings({\"rawtypes\"})\n"
+ "protected com.google.protobuf.MapField internalGetMutableMapField(\n"
+ " int number) {\n"
+ " switch (number) {\n");
+ printer->Indent();
+ printer->Indent();
+ for (int i = 0; i < map_fields.size(); ++i) {
+ const FieldDescriptor* field = map_fields[i];
+ const FieldGeneratorInfo* info = context_->GetFieldGeneratorInfo(field);
+ printer->Print(
+ "case $number$:\n"
+ " return internalGetMutable$capitalized_name$();\n",
+ "number", StrCat(field->number()), "capitalized_name",
+ info->capitalized_name);
+ }
+ printer->Print(
+ "default:\n"
+ " throw new RuntimeException(\n"
+ " \"Invalid map field number: \" + number);\n");
+ printer->Outdent();
+ printer->Outdent();
+ printer->Print(
+ " }\n"
+ "}\n");
+ }
+ printer->Print(
+ "@java.lang.Override\n"
+ "protected com.google.protobuf.GeneratedMessage$ver$.FieldAccessorTable\n"
+ " internalGetFieldAccessorTable() {\n"
+ " return $fileclass$.internal_$identifier$_fieldAccessorTable\n"
+ " .ensureFieldAccessorsInitialized(\n"
+ " $classname$.class, $classname$.Builder.class);\n"
+ "}\n"
+ "\n",
+ "classname", name_resolver_->GetImmutableClassName(descriptor_),
+ "fileclass", name_resolver_->GetImmutableClassName(descriptor_->file()),
+ "identifier", UniqueFileScopeIdentifier(descriptor_), "ver",
+ GeneratedCodeVersionSuffix());
+}
+
+// ===================================================================
+
+void MessageBuilderGenerator::GenerateCommonBuilderMethods(
+ io::Printer* printer) {
+ printer->Print(
+ "// Construct using $classname$.newBuilder()\n"
+ "private Builder() {\n"
+ " maybeForceBuilderInitialization();\n"
+ "}\n"
+ "\n",
+ "classname", name_resolver_->GetImmutableClassName(descriptor_));
+
+ printer->Print(
+ "private Builder(\n"
+ " com.google.protobuf.GeneratedMessage$ver$.BuilderParent parent) {\n"
+ " super(parent);\n"
+ " maybeForceBuilderInitialization();\n"
+ "}\n",
+ "classname", name_resolver_->GetImmutableClassName(descriptor_), "ver",
+ GeneratedCodeVersionSuffix());
+
+ printer->Print(
+ "private void maybeForceBuilderInitialization() {\n"
+ " if (com.google.protobuf.GeneratedMessage$ver$\n"
+ " .alwaysUseFieldBuilders) {\n",
+ "ver", GeneratedCodeVersionSuffix());
+
+ printer->Indent();
+ printer->Indent();
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ if (!IsRealOneof(descriptor_->field(i))) {
+ field_generators_.get(descriptor_->field(i))
+ .GenerateFieldBuilderInitializationCode(printer);
+ }
+ }
+ printer->Outdent();
+ printer->Outdent();
+
+ printer->Print(
+ " }\n"
+ "}\n");
+
+ printer->Print(
+ "@java.lang.Override\n"
+ "public Builder clear() {\n"
+ " super.clear();\n");
+
+ printer->Indent();
+
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ if (!IsRealOneof(descriptor_->field(i))) {
+ field_generators_.get(descriptor_->field(i))
+ .GenerateBuilderClearCode(printer);
+ }
+ }
+
+ for (auto oneof : oneofs_) {
+ printer->Print(
+ "$oneof_name$Case_ = 0;\n"
+ "$oneof_name$_ = null;\n",
+ "oneof_name", context_->GetOneofGeneratorInfo(oneof)->name);
+ }
+
+ printer->Outdent();
+
+ printer->Print(
+ " return this;\n"
+ "}\n"
+ "\n");
+
+ printer->Print(
+ "@java.lang.Override\n"
+ "public com.google.protobuf.Descriptors.Descriptor\n"
+ " getDescriptorForType() {\n"
+ " return $fileclass$.internal_$identifier$_descriptor;\n"
+ "}\n"
+ "\n",
+ "fileclass", name_resolver_->GetImmutableClassName(descriptor_->file()),
+ "identifier", UniqueFileScopeIdentifier(descriptor_));
+
+ // LITE runtime implements this in GeneratedMessageLite.
+ printer->Print(
+ "@java.lang.Override\n"
+ "public $classname$ getDefaultInstanceForType() {\n"
+ " return $classname$.getDefaultInstance();\n"
+ "}\n"
+ "\n",
+ "classname", name_resolver_->GetImmutableClassName(descriptor_));
+
+ printer->Print(
+ "@java.lang.Override\n"
+ "public $classname$ build() {\n"
+ " $classname$ result = buildPartial();\n"
+ " if (!result.isInitialized()) {\n"
+ " throw newUninitializedMessageException(result);\n"
+ " }\n"
+ " return result;\n"
+ "}\n"
+ "\n",
+ "classname", name_resolver_->GetImmutableClassName(descriptor_));
+
+ printer->Print(
+ "@java.lang.Override\n"
+ "public $classname$ buildPartial() {\n"
+ " $classname$ result = new $classname$(this);\n",
+ "classname", name_resolver_->GetImmutableClassName(descriptor_));
+
+ printer->Indent();
+
+ int totalBuilderBits = 0;
+ int totalMessageBits = 0;
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ const ImmutableFieldGenerator& field =
+ field_generators_.get(descriptor_->field(i));
+ totalBuilderBits += field.GetNumBitsForBuilder();
+ totalMessageBits += field.GetNumBitsForMessage();
+ }
+ int totalBuilderInts = (totalBuilderBits + 31) / 32;
+ int totalMessageInts = (totalMessageBits + 31) / 32;
+
+ // Local vars for from and to bit fields to avoid accessing the builder and
+ // message over and over for these fields. Seems to provide a slight
+ // perforamance improvement in micro benchmark and this is also what proto1
+ // code does.
+ for (int i = 0; i < totalBuilderInts; i++) {
+ printer->Print("int from_$bit_field_name$ = $bit_field_name$;\n",
+ "bit_field_name", GetBitFieldName(i));
+ }
+ for (int i = 0; i < totalMessageInts; i++) {
+ printer->Print("int to_$bit_field_name$ = 0;\n", "bit_field_name",
+ GetBitFieldName(i));
+ }
+
+ // Output generation code for each field.
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ field_generators_.get(descriptor_->field(i)).GenerateBuildingCode(printer);
+ }
+
+ // Copy the bit field results to the generated message
+ for (int i = 0; i < totalMessageInts; i++) {
+ printer->Print("result.$bit_field_name$ = to_$bit_field_name$;\n",
+ "bit_field_name", GetBitFieldName(i));
+ }
+
+ for (auto oneof : oneofs_) {
+ printer->Print("result.$oneof_name$Case_ = $oneof_name$Case_;\n",
+ "oneof_name", context_->GetOneofGeneratorInfo(oneof)->name);
+ }
+
+ printer->Outdent();
+
+ printer->Print(" onBuilt();\n");
+
+ printer->Print(
+ " return result;\n"
+ "}\n"
+ "\n",
+ "classname", name_resolver_->GetImmutableClassName(descriptor_));
+
+ // Override methods declared in GeneratedMessage to return the concrete
+ // generated type so callsites won't depend on GeneratedMessage. This
+ // is needed to keep binary compatibility when we change generated code
+ // to subclass a different GeneratedMessage class (e.g., in v3.0.0 release
+ // we changed all generated code to subclass GeneratedMessageV3).
+ printer->Print(
+ "@java.lang.Override\n"
+ "public Builder clone() {\n"
+ " return super.clone();\n"
+ "}\n"
+ "@java.lang.Override\n"
+ "public Builder setField(\n"
+ " com.google.protobuf.Descriptors.FieldDescriptor field,\n"
+ " java.lang.Object value) {\n"
+ " return super.setField(field, value);\n"
+ "}\n"
+ "@java.lang.Override\n"
+ "public Builder clearField(\n"
+ " com.google.protobuf.Descriptors.FieldDescriptor field) {\n"
+ " return super.clearField(field);\n"
+ "}\n"
+ "@java.lang.Override\n"
+ "public Builder clearOneof(\n"
+ " com.google.protobuf.Descriptors.OneofDescriptor oneof) {\n"
+ " return super.clearOneof(oneof);\n"
+ "}\n"
+ "@java.lang.Override\n"
+ "public Builder setRepeatedField(\n"
+ " com.google.protobuf.Descriptors.FieldDescriptor field,\n"
+ " int index, java.lang.Object value) {\n"
+ " return super.setRepeatedField(field, index, value);\n"
+ "}\n"
+ "@java.lang.Override\n"
+ "public Builder addRepeatedField(\n"
+ " com.google.protobuf.Descriptors.FieldDescriptor field,\n"
+ " java.lang.Object value) {\n"
+ " return super.addRepeatedField(field, value);\n"
+ "}\n");
+
+ if (descriptor_->extension_range_count() > 0) {
+ printer->Print(
+ "@java.lang.Override\n"
+ "public <Type> Builder setExtension(\n"
+ " com.google.protobuf.GeneratedMessage.GeneratedExtension<\n"
+ " $classname$, Type> extension,\n"
+ " Type value) {\n"
+ " return super.setExtension(extension, value);\n"
+ "}\n"
+ "@java.lang.Override\n"
+ "public <Type> Builder setExtension(\n"
+ " com.google.protobuf.GeneratedMessage.GeneratedExtension<\n"
+ " $classname$, java.util.List<Type>> extension,\n"
+ " int index, Type value) {\n"
+ " return super.setExtension(extension, index, value);\n"
+ "}\n"
+ "@java.lang.Override\n"
+ "public <Type> Builder addExtension(\n"
+ " com.google.protobuf.GeneratedMessage.GeneratedExtension<\n"
+ " $classname$, java.util.List<Type>> extension,\n"
+ " Type value) {\n"
+ " return super.addExtension(extension, value);\n"
+ "}\n"
+ "@java.lang.Override\n"
+ "public <Type> Builder clearExtension(\n"
+ " com.google.protobuf.GeneratedMessage.GeneratedExtension<\n"
+ " $classname$, ?> extension) {\n"
+ " return super.clearExtension(extension);\n"
+ "}\n",
+ "classname", name_resolver_->GetImmutableClassName(descriptor_));
+ }
+
+ // -----------------------------------------------------------------
+
+ if (context_->HasGeneratedMethods(descriptor_)) {
+ printer->Print(
+ "@java.lang.Override\n"
+ "public Builder mergeFrom(com.google.protobuf.Message other) {\n"
+ " if (other instanceof $classname$) {\n"
+ " return mergeFrom(($classname$)other);\n"
+ " } else {\n"
+ " super.mergeFrom(other);\n"
+ " return this;\n"
+ " }\n"
+ "}\n"
+ "\n",
+ "classname", name_resolver_->GetImmutableClassName(descriptor_));
+
+ printer->Print(
+ "public Builder mergeFrom($classname$ other) {\n"
+ // Optimization: If other is the default instance, we know none of its
+ // fields are set so we can skip the merge.
+ " if (other == $classname$.getDefaultInstance()) return this;\n",
+ "classname", name_resolver_->GetImmutableClassName(descriptor_));
+ printer->Indent();
+
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ if (!IsRealOneof(descriptor_->field(i))) {
+ field_generators_.get(descriptor_->field(i))
+ .GenerateMergingCode(printer);
+ }
+ }
+
+ // Merge oneof fields.
+ for (auto oneof : oneofs_) {
+ printer->Print("switch (other.get$oneof_capitalized_name$Case()) {\n",
+ "oneof_capitalized_name",
+ context_->GetOneofGeneratorInfo(oneof)->capitalized_name);
+ printer->Indent();
+ for (int j = 0; j < oneof->field_count(); j++) {
+ const FieldDescriptor* field = oneof->field(j);
+ printer->Print("case $field_name$: {\n", "field_name",
+ ToUpper(field->name()));
+ printer->Indent();
+ field_generators_.get(field).GenerateMergingCode(printer);
+ printer->Print("break;\n");
+ printer->Outdent();
+ printer->Print("}\n");
+ }
+ printer->Print(
+ "case $cap_oneof_name$_NOT_SET: {\n"
+ " break;\n"
+ "}\n",
+ "cap_oneof_name",
+ ToUpper(context_->GetOneofGeneratorInfo(oneof)->name));
+ printer->Outdent();
+ printer->Print("}\n");
+ }
+
+ printer->Outdent();
+
+ // if message type has extensions
+ if (descriptor_->extension_range_count() > 0) {
+ printer->Print(" this.mergeExtensionFields(other);\n");
+ }
+
+ printer->Print(" this.mergeUnknownFields(other.unknownFields);\n");
+
+ printer->Print(" onChanged();\n");
+
+ printer->Print(
+ " return this;\n"
+ "}\n"
+ "\n");
+ }
+}
+
+// ===================================================================
+
+void MessageBuilderGenerator::GenerateBuilderParsingMethods(
+ io::Printer* printer) {
+ printer->Print(
+ "@java.lang.Override\n"
+ "public Builder mergeFrom(\n"
+ " com.google.protobuf.CodedInputStream input,\n"
+ " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
+ " throws java.io.IOException {\n"
+ " $classname$ parsedMessage = null;\n"
+ " try {\n"
+ " parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);\n"
+ " } catch (com.google.protobuf.InvalidProtocolBufferException e) {\n"
+ " parsedMessage = ($classname$) e.getUnfinishedMessage();\n"
+ " throw e.unwrapIOException();\n"
+ " } finally {\n"
+ " if (parsedMessage != null) {\n"
+ " mergeFrom(parsedMessage);\n"
+ " }\n"
+ " }\n"
+ " return this;\n"
+ "}\n",
+ "classname", name_resolver_->GetImmutableClassName(descriptor_));
+}
+
+// ===================================================================
+
+void MessageBuilderGenerator::GenerateIsInitialized(io::Printer* printer) {
+ printer->Print(
+ "@java.lang.Override\n"
+ "public final boolean isInitialized() {\n");
+ printer->Indent();
+
+ // Check that all required fields in this message are set.
+ // TODO(kenton): We can optimize this when we switch to putting all the
+ // "has" fields into a single bitfield.
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ const FieldDescriptor* field = descriptor_->field(i);
+ const FieldGeneratorInfo* info = context_->GetFieldGeneratorInfo(field);
+
+ if (field->is_required()) {
+ printer->Print(
+ "if (!has$name$()) {\n"
+ " return false;\n"
+ "}\n",
+ "name", info->capitalized_name);
+ }
+ }
+
+ // Now check that all embedded messages are initialized.
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ const FieldDescriptor* field = descriptor_->field(i);
+ const FieldGeneratorInfo* info = context_->GetFieldGeneratorInfo(field);
+ if (GetJavaType(field) == JAVATYPE_MESSAGE &&
+ HasRequiredFields(field->message_type())) {
+ switch (field->label()) {
+ case FieldDescriptor::LABEL_REQUIRED:
+ printer->Print(
+ "if (!get$name$().isInitialized()) {\n"
+ " return false;\n"
+ "}\n",
+ "type",
+ name_resolver_->GetImmutableClassName(field->message_type()),
+ "name", info->capitalized_name);
+ break;
+ case FieldDescriptor::LABEL_OPTIONAL:
+ printer->Print(
+ "if (has$name$()) {\n"
+ " if (!get$name$().isInitialized()) {\n"
+ " return false;\n"
+ " }\n"
+ "}\n",
+ "name", info->capitalized_name);
+ break;
+ case FieldDescriptor::LABEL_REPEATED:
+ if (IsMapEntry(field->message_type())) {
+ printer->Print(
+ "for ($type$ item : get$name$Map().values()) {\n"
+ " if (!item.isInitialized()) {\n"
+ " return false;\n"
+ " }\n"
+ "}\n",
+ "type",
+ MapValueImmutableClassdName(field->message_type(),
+ name_resolver_),
+ "name", info->capitalized_name);
+ } else {
+ printer->Print(
+ "for (int i = 0; i < get$name$Count(); i++) {\n"
+ " if (!get$name$(i).isInitialized()) {\n"
+ " return false;\n"
+ " }\n"
+ "}\n",
+ "type",
+ name_resolver_->GetImmutableClassName(field->message_type()),
+ "name", info->capitalized_name);
+ }
+ break;
+ }
+ }
+ }
+
+ if (descriptor_->extension_range_count() > 0) {
+ printer->Print(
+ "if (!extensionsAreInitialized()) {\n"
+ " return false;\n"
+ "}\n");
+ }
+
+ printer->Outdent();
+
+ printer->Print(
+ " return true;\n"
+ "}\n"
+ "\n");
+}
+
+// ===================================================================
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_message_builder.h b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_message_builder.h
new file mode 100644
index 00000000..7d6da17d
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_message_builder.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.
+
+// Author: dweis@google.com (Daniel Weis)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_MESSAGE_BUILDER_H__
+#define GOOGLE_PROTOBUF_COMPILER_JAVA_MESSAGE_BUILDER_H__
+
+#include <map>
+#include <string>
+#include <compiler/java/java_field.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+class Context; // context.h
+class ClassNameResolver; // name_resolver.h
+} // namespace java
+} // namespace compiler
+namespace io {
+class Printer; // printer.h
+}
+} // namespace protobuf
+} // namespace google
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+class MessageBuilderGenerator {
+ public:
+ explicit MessageBuilderGenerator(const Descriptor* descriptor,
+ Context* context);
+ virtual ~MessageBuilderGenerator();
+
+ virtual void Generate(io::Printer* printer);
+
+ private:
+ void GenerateCommonBuilderMethods(io::Printer* printer);
+ void GenerateDescriptorMethods(io::Printer* printer);
+ void GenerateBuilderParsingMethods(io::Printer* printer);
+ void GenerateIsInitialized(io::Printer* printer);
+
+ const Descriptor* descriptor_;
+ Context* context_;
+ ClassNameResolver* name_resolver_;
+ FieldGeneratorMap<ImmutableFieldGenerator> field_generators_;
+ std::set<const OneofDescriptor*> oneofs_;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageBuilderGenerator);
+};
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_MESSAGE_BUILDER_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_message_builder_lite.cc b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_message_builder_lite.cc
new file mode 100644
index 00000000..83f5d072
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_message_builder_lite.cc
@@ -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.
+
+// Author: dweis@google.com (Daniel Weis)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <compiler/java/java_message_builder_lite.h>
+
+#include <algorithm>
+#include <map>
+#include <memory>
+#include <vector>
+
+#include <compiler/java/java_context.h>
+#include <compiler/java/java_doc_comment.h>
+#include <compiler/java/java_enum.h>
+#include <compiler/java/java_extension.h>
+#include <compiler/java/java_generator_factory.h>
+#include <compiler/java/java_helpers.h>
+#include <compiler/java/java_name_resolver.h>
+#include <descriptor.pb.h>
+#include <io/coded_stream.h>
+#include <io/printer.h>
+#include <wire_format.h>
+#include <stubs/strutil.h>
+#include <stubs/substitute.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+MessageBuilderLiteGenerator::MessageBuilderLiteGenerator(
+ const Descriptor* descriptor, Context* context)
+ : descriptor_(descriptor),
+ context_(context),
+ name_resolver_(context->GetNameResolver()),
+ field_generators_(descriptor, context_) {
+ GOOGLE_CHECK(!HasDescriptorMethods(descriptor->file(), context->EnforceLite()))
+ << "Generator factory error: A lite message generator is used to "
+ "generate non-lite messages.";
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ if (IsRealOneof(descriptor_->field(i))) {
+ oneofs_.insert(descriptor_->field(i)->containing_oneof());
+ }
+ }
+}
+
+MessageBuilderLiteGenerator::~MessageBuilderLiteGenerator() {}
+
+void MessageBuilderLiteGenerator::Generate(io::Printer* printer) {
+ WriteMessageDocComment(printer, descriptor_);
+ printer->Print(
+ "public static final class Builder extends\n"
+ " com.google.protobuf.GeneratedMessageLite.$extendible$Builder<\n"
+ " $classname$, Builder> implements\n"
+ " $extra_interfaces$\n"
+ " $classname$OrBuilder {\n",
+ "classname", name_resolver_->GetImmutableClassName(descriptor_),
+ "extra_interfaces", ExtraBuilderInterfaces(descriptor_), "extendible",
+ descriptor_->extension_range_count() > 0 ? "Extendable" : "");
+ printer->Indent();
+
+ GenerateCommonBuilderMethods(printer);
+
+ // oneof
+ std::map<std::string, std::string> vars;
+ for (auto oneof : oneofs_) {
+ vars["oneof_name"] = context_->GetOneofGeneratorInfo(oneof)->name;
+ vars["oneof_capitalized_name"] =
+ context_->GetOneofGeneratorInfo(oneof)->capitalized_name;
+ vars["oneof_index"] = StrCat(oneof->index());
+
+ // oneofCase() and clearOneof()
+ printer->Print(vars,
+ "@java.lang.Override\n"
+ "public $oneof_capitalized_name$Case\n"
+ " get$oneof_capitalized_name$Case() {\n"
+ " return instance.get$oneof_capitalized_name$Case();\n"
+ "}\n"
+ "\n"
+ "public Builder clear$oneof_capitalized_name$() {\n"
+ " copyOnWrite();\n"
+ " instance.clear$oneof_capitalized_name$();\n"
+ " return this;\n"
+ "}\n"
+ "\n");
+ }
+
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ printer->Print("\n");
+ field_generators_.get(descriptor_->field(i))
+ .GenerateBuilderMembers(printer);
+ }
+
+ printer->Print(
+ "\n"
+ "// @@protoc_insertion_point(builder_scope:$full_name$)\n",
+ "full_name", descriptor_->full_name());
+
+ printer->Outdent();
+ printer->Print("}\n");
+}
+
+// ===================================================================
+
+void MessageBuilderLiteGenerator::GenerateCommonBuilderMethods(
+ io::Printer* printer) {
+ printer->Print(
+ "// Construct using $classname$.newBuilder()\n"
+ "private Builder() {\n"
+ " super(DEFAULT_INSTANCE);\n"
+ "}\n"
+ "\n",
+ "classname", name_resolver_->GetImmutableClassName(descriptor_));
+}
+
+// ===================================================================
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_message_builder_lite.h b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_message_builder_lite.h
new file mode 100644
index 00000000..8ad4e94b
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_message_builder_lite.h
@@ -0,0 +1,86 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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: dweis@google.com (Daniel Weis)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_MESSAGE_BUILDER_LITE_H__
+#define GOOGLE_PROTOBUF_COMPILER_JAVA_MESSAGE_BUILDER_LITE_H__
+
+#include <map>
+#include <string>
+#include <compiler/java/java_field.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+class Context; // context.h
+class ClassNameResolver; // name_resolver.h
+} // namespace java
+} // namespace compiler
+namespace io {
+class Printer; // printer.h
+}
+} // namespace protobuf
+} // namespace google
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+class MessageBuilderLiteGenerator {
+ public:
+ explicit MessageBuilderLiteGenerator(const Descriptor* descriptor,
+ Context* context);
+ virtual ~MessageBuilderLiteGenerator();
+
+ virtual void Generate(io::Printer* printer);
+
+ private:
+ void GenerateCommonBuilderMethods(io::Printer* printer);
+
+ const Descriptor* descriptor_;
+ Context* context_;
+ ClassNameResolver* name_resolver_;
+ FieldGeneratorMap<ImmutableFieldLiteGenerator> field_generators_;
+ std::set<const OneofDescriptor*> oneofs_;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageBuilderLiteGenerator);
+};
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_MESSAGE_BUILDER_LITE_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_message_field.cc b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_message_field.cc
new file mode 100644
index 00000000..394735d1
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_message_field.cc
@@ -0,0 +1,1494 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 <map>
+#include <string>
+
+#include <compiler/java/java_context.h>
+#include <compiler/java/java_doc_comment.h>
+#include <compiler/java/java_helpers.h>
+#include <compiler/java/java_message_field.h>
+#include <compiler/java/java_name_resolver.h>
+#include <io/printer.h>
+#include <wire_format.h>
+#include <stubs/strutil.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+
+namespace {
+
+void SetMessageVariables(const FieldDescriptor* descriptor, int messageBitIndex,
+ int builderBitIndex, const FieldGeneratorInfo* info,
+ ClassNameResolver* name_resolver,
+ std::map<std::string, std::string>* variables) {
+ SetCommonFieldVariables(descriptor, info, variables);
+
+ (*variables)["type"] =
+ name_resolver->GetImmutableClassName(descriptor->message_type());
+ (*variables)["kt_type"] = (*variables)["type"];
+ (*variables)["mutable_type"] =
+ name_resolver->GetMutableClassName(descriptor->message_type());
+ (*variables)["group_or_message"] =
+ (GetType(descriptor) == FieldDescriptor::TYPE_GROUP) ? "Group"
+ : "Message";
+ // TODO(birdo): Add @deprecated javadoc when generating javadoc is supported
+ // by the proto compiler
+ (*variables)["deprecation"] =
+ descriptor->options().deprecated() ? "@java.lang.Deprecated " : "";
+ (*variables)["kt_deprecation"] =
+ descriptor->options().deprecated()
+ ? "@kotlin.Deprecated(message = \"Field " + (*variables)["name"] +
+ " is deprecated\") "
+ : "";
+ (*variables)["on_changed"] = "onChanged();";
+ (*variables)["ver"] = GeneratedCodeVersionSuffix();
+ (*variables)["get_parser"] =
+ ExposePublicParser(descriptor->message_type()->file()) ? "PARSER"
+ : "parser()";
+
+ if (HasHasbit(descriptor)) {
+ // For singular messages and builders, one bit is used for the hasField bit.
+ (*variables)["get_has_field_bit_message"] = GenerateGetBit(messageBitIndex);
+ (*variables)["get_has_field_bit_builder"] = GenerateGetBit(builderBitIndex);
+
+ // Note that these have a trailing ";".
+ (*variables)["set_has_field_bit_message"] =
+ GenerateSetBit(messageBitIndex) + ";";
+ (*variables)["set_has_field_bit_builder"] =
+ GenerateSetBit(builderBitIndex) + ";";
+ (*variables)["clear_has_field_bit_builder"] =
+ GenerateClearBit(builderBitIndex) + ";";
+
+ (*variables)["is_field_present_message"] = GenerateGetBit(messageBitIndex);
+ } else {
+ (*variables)["set_has_field_bit_message"] = "";
+ (*variables)["set_has_field_bit_builder"] = "";
+ (*variables)["clear_has_field_bit_builder"] = "";
+
+ (*variables)["is_field_present_message"] =
+ (*variables)["name"] + "_ != null";
+ }
+
+ // For repeated builders, one bit is used for whether the array is immutable.
+ (*variables)["get_mutable_bit_builder"] = GenerateGetBit(builderBitIndex);
+ (*variables)["set_mutable_bit_builder"] = GenerateSetBit(builderBitIndex);
+ (*variables)["clear_mutable_bit_builder"] = GenerateClearBit(builderBitIndex);
+
+ // For repeated fields, one bit is used for whether the array is immutable
+ // in the parsing constructor.
+ (*variables)["get_mutable_bit_parser"] =
+ GenerateGetBitMutableLocal(builderBitIndex);
+ (*variables)["set_mutable_bit_parser"] =
+ GenerateSetBitMutableLocal(builderBitIndex);
+
+ (*variables)["get_has_field_bit_from_local"] =
+ GenerateGetBitFromLocal(builderBitIndex);
+ (*variables)["set_has_field_bit_to_local"] =
+ GenerateSetBitToLocal(messageBitIndex);
+}
+
+} // namespace
+
+// ===================================================================
+
+ImmutableMessageFieldGenerator::ImmutableMessageFieldGenerator(
+ const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex,
+ Context* context)
+ : descriptor_(descriptor), name_resolver_(context->GetNameResolver()) {
+ SetMessageVariables(descriptor, messageBitIndex, builderBitIndex,
+ context->GetFieldGeneratorInfo(descriptor),
+ name_resolver_, &variables_);
+}
+
+ImmutableMessageFieldGenerator::~ImmutableMessageFieldGenerator() {}
+
+int ImmutableMessageFieldGenerator::GetNumBitsForMessage() const {
+ return HasHasbit(descriptor_) ? 1 : 0;
+}
+
+int ImmutableMessageFieldGenerator::GetNumBitsForBuilder() const {
+ return GetNumBitsForMessage();
+}
+
+void ImmutableMessageFieldGenerator::GenerateInterfaceMembers(
+ io::Printer* printer) const {
+ // TODO(jonp): In the future, consider having a method specific to the
+ // interface so that builders can choose dynamically to either return a
+ // message or a nested builder, so that asking for the interface doesn't
+ // cause a message to ever be built.
+ WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
+ printer->Print(variables_, "$deprecation$boolean has$capitalized_name$();\n");
+ WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
+ printer->Print(variables_, "$deprecation$$type$ get$capitalized_name$();\n");
+
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "$deprecation$$type$OrBuilder get$capitalized_name$OrBuilder();\n");
+}
+
+void ImmutableMessageFieldGenerator::GenerateMembers(
+ io::Printer* printer) const {
+ printer->Print(variables_, "private $type$ $name$_;\n");
+ PrintExtraFieldInfo(variables_, printer);
+
+ if (HasHasbit(descriptor_)) {
+ WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
+ printer->Print(
+ variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
+ " return $get_has_field_bit_message$;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
+ printer->Print(
+ variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
+ " return $name$_ == null ? $type$.getDefaultInstance() : $name$_;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public $type$OrBuilder "
+ "${$get$capitalized_name$OrBuilder$}$() {\n"
+ " return $name$_ == null ? $type$.getDefaultInstance() : $name$_;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ } else {
+ WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
+ printer->Print(
+ variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
+ " return $name$_ != null;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
+ printer->Print(
+ variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
+ " return $name$_ == null ? $type$.getDefaultInstance() : $name$_;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public $type$OrBuilder "
+ "${$get$capitalized_name$OrBuilder$}$() {\n"
+ " return get$capitalized_name$();\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ }
+}
+
+void ImmutableMessageFieldGenerator::PrintNestedBuilderCondition(
+ io::Printer* printer, const char* regular_case,
+ const char* nested_builder_case) const {
+ printer->Print(variables_, "if ($name$Builder_ == null) {\n");
+ printer->Indent();
+ printer->Print(variables_, regular_case);
+ printer->Outdent();
+ printer->Print("} else {\n");
+ printer->Indent();
+ printer->Print(variables_, nested_builder_case);
+ printer->Outdent();
+ printer->Print("}\n");
+}
+
+void ImmutableMessageFieldGenerator::PrintNestedBuilderFunction(
+ io::Printer* printer, const char* method_prototype,
+ const char* regular_case, const char* nested_builder_case,
+ const char* trailing_code) const {
+ printer->Print(variables_, method_prototype);
+ printer->Annotate("{", "}", descriptor_);
+ printer->Print(" {\n");
+ printer->Indent();
+ PrintNestedBuilderCondition(printer, regular_case, nested_builder_case);
+ if (trailing_code != NULL) {
+ printer->Print(variables_, trailing_code);
+ }
+ printer->Outdent();
+ printer->Print("}\n");
+}
+
+void ImmutableMessageFieldGenerator::GenerateBuilderMembers(
+ io::Printer* printer) const {
+ // When using nested-builders, the code initially works just like the
+ // non-nested builder case. It only creates a nested builder lazily on
+ // demand and then forever delegates to it after creation.
+
+ bool has_hasbit = HasHasbit(descriptor_);
+
+ printer->Print(variables_, "private $type$ $name$_;\n");
+
+ printer->Print(variables_,
+ // If this builder is non-null, it is used and the other fields
+ // are ignored.
+ "private com.google.protobuf.SingleFieldBuilder$ver$<\n"
+ " $type$, $type$.Builder, $type$OrBuilder> $name$Builder_;"
+ "\n");
+
+ // The comments above the methods below are based on a hypothetical
+ // field of type "Field" called "Field".
+
+ // boolean hasField()
+ WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
+ if (has_hasbit) {
+ printer->Print(
+ variables_,
+ "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
+ " return $get_has_field_bit_builder$;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ } else {
+ printer->Print(
+ variables_,
+ "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
+ " return $name$Builder_ != null || $name$_ != null;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ }
+
+ // Field getField()
+ WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
+ PrintNestedBuilderFunction(
+ printer, "$deprecation$public $type$ ${$get$capitalized_name$$}$()",
+ "return $name$_ == null ? $type$.getDefaultInstance() : $name$_;\n",
+ "return $name$Builder_.getMessage();\n", NULL);
+
+ // Field.Builder setField(Field value)
+ WriteFieldDocComment(printer, descriptor_);
+ PrintNestedBuilderFunction(
+ printer,
+ "$deprecation$public Builder ${$set$capitalized_name$$}$($type$ value)",
+
+ "if (value == null) {\n"
+ " throw new NullPointerException();\n"
+ "}\n"
+ "$name$_ = value;\n"
+ "$on_changed$\n",
+
+ "$name$Builder_.setMessage(value);\n",
+
+ "$set_has_field_bit_builder$\n"
+ "return this;\n");
+
+ // Field.Builder setField(Field.Builder builderForValue)
+ WriteFieldDocComment(printer, descriptor_);
+ PrintNestedBuilderFunction(
+ printer,
+ "$deprecation$public Builder ${$set$capitalized_name$$}$(\n"
+ " $type$.Builder builderForValue)",
+
+ "$name$_ = builderForValue.build();\n"
+ "$on_changed$\n",
+
+ "$name$Builder_.setMessage(builderForValue.build());\n",
+
+ "$set_has_field_bit_builder$\n"
+ "return this;\n");
+
+ // Field.Builder mergeField(Field value)
+ WriteFieldDocComment(printer, descriptor_);
+ PrintNestedBuilderFunction(
+ printer,
+ "$deprecation$public Builder ${$merge$capitalized_name$$}$($type$ value)",
+
+ has_hasbit
+ ? "if ($get_has_field_bit_builder$ &&\n"
+ " $name$_ != null &&\n"
+ " $name$_ != $type$.getDefaultInstance()) {\n"
+ " $name$_ =\n"
+ " $type$.newBuilder($name$_).mergeFrom(value).buildPartial();\n"
+ "} else {\n"
+ " $name$_ = value;\n"
+ "}\n"
+ "$on_changed$\n"
+ : "if ($name$_ != null) {\n"
+ " $name$_ =\n"
+ " $type$.newBuilder($name$_).mergeFrom(value).buildPartial();\n"
+ "} else {\n"
+ " $name$_ = value;\n"
+ "}\n"
+ "$on_changed$\n",
+
+ "$name$Builder_.mergeFrom(value);\n",
+
+ "$set_has_field_bit_builder$\n"
+ "return this;\n");
+
+ // Field.Builder clearField()
+ WriteFieldDocComment(printer, descriptor_);
+ PrintNestedBuilderFunction(
+ printer, "$deprecation$public Builder ${$clear$capitalized_name$$}$()",
+
+ "$name$_ = null;\n"
+ "$on_changed$\n",
+
+ has_hasbit ? "$name$Builder_.clear();\n"
+ : "$name$_ = null;\n"
+ "$name$Builder_ = null;\n",
+
+ "$clear_has_field_bit_builder$\n"
+ "return this;\n");
+
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public $type$.Builder "
+ "${$get$capitalized_name$Builder$}$() {\n"
+ " $set_has_field_bit_builder$\n"
+ " $on_changed$\n"
+ " return get$capitalized_name$FieldBuilder().getBuilder();\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public $type$OrBuilder "
+ "${$get$capitalized_name$OrBuilder$}$() {\n"
+ " if ($name$Builder_ != null) {\n"
+ " return $name$Builder_.getMessageOrBuilder();\n"
+ " } else {\n"
+ " return $name$_ == null ?\n"
+ " $type$.getDefaultInstance() : $name$_;\n"
+ " }\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "private com.google.protobuf.SingleFieldBuilder$ver$<\n"
+ " $type$, $type$.Builder, $type$OrBuilder> \n"
+ " get$capitalized_name$FieldBuilder() {\n"
+ " if ($name$Builder_ == null) {\n"
+ " $name$Builder_ = new com.google.protobuf.SingleFieldBuilder$ver$<\n"
+ " $type$, $type$.Builder, $type$OrBuilder>(\n"
+ " get$capitalized_name$(),\n"
+ " getParentForChildren(),\n"
+ " isClean());\n"
+ " $name$_ = null;\n"
+ " }\n"
+ " return $name$Builder_;\n"
+ "}\n");
+}
+
+void ImmutableMessageFieldGenerator::GenerateKotlinDslMembers(
+ io::Printer* printer) const {
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$kt_deprecation$public var $kt_name$: $kt_type$\n"
+ " @JvmName(\"${$get$kt_capitalized_name$$}$\")\n"
+ " get() = $kt_dsl_builder$.${$get$capitalized_name$$}$()\n"
+ " @JvmName(\"${$set$kt_capitalized_name$$}$\")\n"
+ " set(value) {\n"
+ " $kt_dsl_builder$.${$set$capitalized_name$$}$(value)\n"
+ " }\n");
+
+ WriteFieldAccessorDocComment(printer, descriptor_, CLEARER,
+ /* builder */ false);
+ printer->Print(variables_,
+ "public fun ${$clear$kt_capitalized_name$$}$() {\n"
+ " $kt_dsl_builder$.${$clear$capitalized_name$$}$()\n"
+ "}\n");
+
+ WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
+ printer->Print(
+ variables_,
+ "public fun ${$has$kt_capitalized_name$$}$(): kotlin.Boolean {\n"
+ " return $kt_dsl_builder$.${$has$capitalized_name$$}$()\n"
+ "}\n");
+}
+
+void ImmutableMessageFieldGenerator::GenerateFieldBuilderInitializationCode(
+ io::Printer* printer) const {
+ if (HasHasbit(descriptor_)) {
+ printer->Print(variables_, "get$capitalized_name$FieldBuilder();\n");
+ }
+}
+
+void ImmutableMessageFieldGenerator::GenerateInitializationCode(
+ io::Printer* printer) const {}
+
+void ImmutableMessageFieldGenerator::GenerateBuilderClearCode(
+ io::Printer* printer) const {
+ if (HasHasbit(descriptor_)) {
+ PrintNestedBuilderCondition(printer, "$name$_ = null;\n",
+
+ "$name$Builder_.clear();\n");
+ printer->Print(variables_, "$clear_has_field_bit_builder$\n");
+ } else {
+ PrintNestedBuilderCondition(printer, "$name$_ = null;\n",
+
+ "$name$_ = null;\n"
+ "$name$Builder_ = null;\n");
+ }
+}
+
+void ImmutableMessageFieldGenerator::GenerateMergingCode(
+ io::Printer* printer) const {
+ printer->Print(variables_,
+ "if (other.has$capitalized_name$()) {\n"
+ " merge$capitalized_name$(other.get$capitalized_name$());\n"
+ "}\n");
+}
+
+void ImmutableMessageFieldGenerator::GenerateBuildingCode(
+ io::Printer* printer) const {
+ if (HasHasbit(descriptor_)) {
+ printer->Print(variables_, "if ($get_has_field_bit_from_local$) {\n");
+ printer->Indent();
+ PrintNestedBuilderCondition(printer, "result.$name$_ = $name$_;\n",
+ "result.$name$_ = $name$Builder_.build();\n");
+ printer->Outdent();
+ printer->Print(variables_,
+ " $set_has_field_bit_to_local$;\n"
+ "}\n");
+ } else {
+ PrintNestedBuilderCondition(printer, "result.$name$_ = $name$_;\n",
+ "result.$name$_ = $name$Builder_.build();\n");
+ }
+}
+
+void ImmutableMessageFieldGenerator::GenerateParsingCode(
+ io::Printer* printer) const {
+ printer->Print(variables_,
+ "$type$.Builder subBuilder = null;\n"
+ "if ($is_field_present_message$) {\n"
+ " subBuilder = $name$_.toBuilder();\n"
+ "}\n");
+
+ if (GetType(descriptor_) == FieldDescriptor::TYPE_GROUP) {
+ printer->Print(variables_,
+ "$name$_ = input.readGroup($number$, $type$.$get_parser$,\n"
+ " extensionRegistry);\n");
+ } else {
+ printer->Print(variables_,
+ "$name$_ = input.readMessage($type$.$get_parser$, "
+ "extensionRegistry);\n");
+ }
+
+ printer->Print(variables_,
+ "if (subBuilder != null) {\n"
+ " subBuilder.mergeFrom($name$_);\n"
+ " $name$_ = subBuilder.buildPartial();\n"
+ "}\n"
+ "$set_has_field_bit_message$\n");
+}
+
+void ImmutableMessageFieldGenerator::GenerateParsingDoneCode(
+ io::Printer* printer) const {
+ // noop for messages.
+}
+
+void ImmutableMessageFieldGenerator::GenerateSerializationCode(
+ io::Printer* printer) const {
+ printer->Print(
+ variables_,
+ "if ($is_field_present_message$) {\n"
+ " output.write$group_or_message$($number$, get$capitalized_name$());\n"
+ "}\n");
+}
+
+void ImmutableMessageFieldGenerator::GenerateSerializedSizeCode(
+ io::Printer* printer) const {
+ printer->Print(
+ variables_,
+ "if ($is_field_present_message$) {\n"
+ " size += com.google.protobuf.CodedOutputStream\n"
+ " .compute$group_or_message$Size($number$, get$capitalized_name$());\n"
+ "}\n");
+}
+
+void ImmutableMessageFieldGenerator::GenerateEqualsCode(
+ io::Printer* printer) const {
+ printer->Print(variables_,
+ "if (!get$capitalized_name$()\n"
+ " .equals(other.get$capitalized_name$())) return false;\n");
+}
+
+void ImmutableMessageFieldGenerator::GenerateHashCode(
+ io::Printer* printer) const {
+ printer->Print(variables_,
+ "hash = (37 * hash) + $constant_name$;\n"
+ "hash = (53 * hash) + get$capitalized_name$().hashCode();\n");
+}
+
+std::string ImmutableMessageFieldGenerator::GetBoxedType() const {
+ return name_resolver_->GetImmutableClassName(descriptor_->message_type());
+}
+
+// ===================================================================
+
+ImmutableMessageOneofFieldGenerator::ImmutableMessageOneofFieldGenerator(
+ const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex,
+ Context* context)
+ : ImmutableMessageFieldGenerator(descriptor, messageBitIndex,
+ builderBitIndex, context) {
+ const OneofGeneratorInfo* info =
+ context->GetOneofGeneratorInfo(descriptor->containing_oneof());
+ SetCommonOneofVariables(descriptor, info, &variables_);
+}
+
+ImmutableMessageOneofFieldGenerator::~ImmutableMessageOneofFieldGenerator() {}
+
+void ImmutableMessageOneofFieldGenerator::GenerateMembers(
+ io::Printer* printer) const {
+ PrintExtraFieldInfo(variables_, printer);
+ WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
+ printer->Print(variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
+ " return $has_oneof_case_message$;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
+ printer->Print(variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
+ " if ($has_oneof_case_message$) {\n"
+ " return ($type$) $oneof_name$_;\n"
+ " }\n"
+ " return $type$.getDefaultInstance();\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public $type$OrBuilder "
+ "${$get$capitalized_name$OrBuilder$}$() {\n"
+ " if ($has_oneof_case_message$) {\n"
+ " return ($type$) $oneof_name$_;\n"
+ " }\n"
+ " return $type$.getDefaultInstance();\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+}
+
+void ImmutableMessageOneofFieldGenerator::GenerateBuilderMembers(
+ io::Printer* printer) const {
+ // When using nested-builders, the code initially works just like the
+ // non-nested builder case. It only creates a nested builder lazily on
+ // demand and then forever delegates to it after creation.
+ printer->Print(variables_,
+ // If this builder is non-null, it is used and the other fields
+ // are ignored.
+ "private com.google.protobuf.SingleFieldBuilder$ver$<\n"
+ " $type$, $type$.Builder, $type$OrBuilder> $name$Builder_;"
+ "\n");
+
+ // The comments above the methods below are based on a hypothetical
+ // field of type "Field" called "Field".
+
+ // boolean hasField()
+ WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
+ printer->Print(variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
+ " return $has_oneof_case_message$;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+
+ // Field getField()
+ WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
+ PrintNestedBuilderFunction(
+ printer,
+ "@java.lang.Override\n"
+ "$deprecation$public $type$ ${$get$capitalized_name$$}$()",
+
+ "if ($has_oneof_case_message$) {\n"
+ " return ($type$) $oneof_name$_;\n"
+ "}\n"
+ "return $type$.getDefaultInstance();\n",
+
+ "if ($has_oneof_case_message$) {\n"
+ " return $name$Builder_.getMessage();\n"
+ "}\n"
+ "return $type$.getDefaultInstance();\n",
+
+ NULL);
+
+ // Field.Builder setField(Field value)
+ WriteFieldDocComment(printer, descriptor_);
+ PrintNestedBuilderFunction(
+ printer,
+ "$deprecation$public Builder ${$set$capitalized_name$$}$($type$ value)",
+
+ "if (value == null) {\n"
+ " throw new NullPointerException();\n"
+ "}\n"
+ "$oneof_name$_ = value;\n"
+ "$on_changed$\n",
+
+ "$name$Builder_.setMessage(value);\n",
+
+ "$set_oneof_case_message$;\n"
+ "return this;\n");
+
+ // Field.Builder setField(Field.Builder builderForValue)
+ WriteFieldDocComment(printer, descriptor_);
+ PrintNestedBuilderFunction(
+ printer,
+ "$deprecation$public Builder ${$set$capitalized_name$$}$(\n"
+ " $type$.Builder builderForValue)",
+
+ "$oneof_name$_ = builderForValue.build();\n"
+ "$on_changed$\n",
+
+ "$name$Builder_.setMessage(builderForValue.build());\n",
+
+ "$set_oneof_case_message$;\n"
+ "return this;\n");
+
+ // Field.Builder mergeField(Field value)
+ WriteFieldDocComment(printer, descriptor_);
+ PrintNestedBuilderFunction(
+ printer,
+ "$deprecation$public Builder ${$merge$capitalized_name$$}$($type$ value)",
+
+ "if ($has_oneof_case_message$ &&\n"
+ " $oneof_name$_ != $type$.getDefaultInstance()) {\n"
+ " $oneof_name$_ = $type$.newBuilder(($type$) $oneof_name$_)\n"
+ " .mergeFrom(value).buildPartial();\n"
+ "} else {\n"
+ " $oneof_name$_ = value;\n"
+ "}\n"
+ "$on_changed$\n",
+
+ "if ($has_oneof_case_message$) {\n"
+ " $name$Builder_.mergeFrom(value);\n"
+ "}\n"
+ "$name$Builder_.setMessage(value);\n",
+
+ "$set_oneof_case_message$;\n"
+ "return this;\n");
+
+ // Field.Builder clearField()
+ WriteFieldDocComment(printer, descriptor_);
+ PrintNestedBuilderFunction(
+ printer, "$deprecation$public Builder ${$clear$capitalized_name$$}$()",
+
+ "if ($has_oneof_case_message$) {\n"
+ " $clear_oneof_case_message$;\n"
+ " $oneof_name$_ = null;\n"
+ " $on_changed$\n"
+ "}\n",
+
+ "if ($has_oneof_case_message$) {\n"
+ " $clear_oneof_case_message$;\n"
+ " $oneof_name$_ = null;\n"
+ "}\n"
+ "$name$Builder_.clear();\n",
+
+ "return this;\n");
+
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public $type$.Builder "
+ "${$get$capitalized_name$Builder$}$() {\n"
+ " return get$capitalized_name$FieldBuilder().getBuilder();\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public $type$OrBuilder "
+ "${$get$capitalized_name$OrBuilder$}$() {\n"
+ " if (($has_oneof_case_message$) && ($name$Builder_ != null)) {\n"
+ " return $name$Builder_.getMessageOrBuilder();\n"
+ " } else {\n"
+ " if ($has_oneof_case_message$) {\n"
+ " return ($type$) $oneof_name$_;\n"
+ " }\n"
+ " return $type$.getDefaultInstance();\n"
+ " }\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "private com.google.protobuf.SingleFieldBuilder$ver$<\n"
+ " $type$, $type$.Builder, $type$OrBuilder> \n"
+ " ${$get$capitalized_name$FieldBuilder$}$() {\n"
+ " if ($name$Builder_ == null) {\n"
+ " if (!($has_oneof_case_message$)) {\n"
+ " $oneof_name$_ = $type$.getDefaultInstance();\n"
+ " }\n"
+ " $name$Builder_ = new com.google.protobuf.SingleFieldBuilder$ver$<\n"
+ " $type$, $type$.Builder, $type$OrBuilder>(\n"
+ " ($type$) $oneof_name$_,\n"
+ " getParentForChildren(),\n"
+ " isClean());\n"
+ " $oneof_name$_ = null;\n"
+ " }\n"
+ " $set_oneof_case_message$;\n"
+ " $on_changed$;\n"
+ " return $name$Builder_;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+}
+
+void ImmutableMessageOneofFieldGenerator::GenerateBuildingCode(
+ io::Printer* printer) const {
+ printer->Print(variables_, "if ($has_oneof_case_message$) {\n");
+ printer->Indent();
+
+ PrintNestedBuilderCondition(
+ printer, "result.$oneof_name$_ = $oneof_name$_;\n",
+
+ "result.$oneof_name$_ = $name$Builder_.build();\n");
+
+ printer->Outdent();
+ printer->Print("}\n");
+}
+
+void ImmutableMessageOneofFieldGenerator::GenerateMergingCode(
+ io::Printer* printer) const {
+ printer->Print(variables_,
+ "merge$capitalized_name$(other.get$capitalized_name$());\n");
+}
+
+void ImmutableMessageOneofFieldGenerator::GenerateParsingCode(
+ io::Printer* printer) const {
+ printer->Print(variables_,
+ "$type$.Builder subBuilder = null;\n"
+ "if ($has_oneof_case_message$) {\n"
+ " subBuilder = (($type$) $oneof_name$_).toBuilder();\n"
+ "}\n");
+
+ if (GetType(descriptor_) == FieldDescriptor::TYPE_GROUP) {
+ printer->Print(
+ variables_,
+ "$oneof_name$_ = input.readGroup($number$, $type$.$get_parser$,\n"
+ " extensionRegistry);\n");
+ } else {
+ printer->Print(
+ variables_,
+ "$oneof_name$_ =\n"
+ " input.readMessage($type$.$get_parser$, extensionRegistry);\n");
+ }
+
+ printer->Print(variables_,
+ "if (subBuilder != null) {\n"
+ " subBuilder.mergeFrom(($type$) $oneof_name$_);\n"
+ " $oneof_name$_ = subBuilder.buildPartial();\n"
+ "}\n");
+ printer->Print(variables_, "$set_oneof_case_message$;\n");
+}
+
+void ImmutableMessageOneofFieldGenerator::GenerateSerializationCode(
+ io::Printer* printer) const {
+ printer->Print(
+ variables_,
+ "if ($has_oneof_case_message$) {\n"
+ " output.write$group_or_message$($number$, ($type$) $oneof_name$_);\n"
+ "}\n");
+}
+
+void ImmutableMessageOneofFieldGenerator::GenerateSerializedSizeCode(
+ io::Printer* printer) const {
+ printer->Print(
+ variables_,
+ "if ($has_oneof_case_message$) {\n"
+ " size += com.google.protobuf.CodedOutputStream\n"
+ " .compute$group_or_message$Size($number$, ($type$) $oneof_name$_);\n"
+ "}\n");
+}
+
+// ===================================================================
+
+RepeatedImmutableMessageFieldGenerator::RepeatedImmutableMessageFieldGenerator(
+ const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex,
+ Context* context)
+ : descriptor_(descriptor), name_resolver_(context->GetNameResolver()) {
+ SetMessageVariables(descriptor, messageBitIndex, builderBitIndex,
+ context->GetFieldGeneratorInfo(descriptor),
+ name_resolver_, &variables_);
+}
+
+RepeatedImmutableMessageFieldGenerator::
+ ~RepeatedImmutableMessageFieldGenerator() {}
+
+int RepeatedImmutableMessageFieldGenerator::GetNumBitsForMessage() const {
+ return 0;
+}
+
+int RepeatedImmutableMessageFieldGenerator::GetNumBitsForBuilder() const {
+ return 1;
+}
+
+void RepeatedImmutableMessageFieldGenerator::GenerateInterfaceMembers(
+ io::Printer* printer) const {
+ // TODO(jonp): In the future, consider having methods specific to the
+ // interface so that builders can choose dynamically to either return a
+ // message or a nested builder, so that asking for the interface doesn't
+ // cause a message to ever be built.
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$java.util.List<$type$> \n"
+ " get$capitalized_name$List();\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$$type$ get$capitalized_name$(int index);\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$int get$capitalized_name$Count();\n");
+
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$java.util.List<? extends $type$OrBuilder> \n"
+ " get$capitalized_name$OrBuilderList();\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "$deprecation$$type$OrBuilder get$capitalized_name$OrBuilder(\n"
+ " int index);\n");
+}
+
+void RepeatedImmutableMessageFieldGenerator::GenerateMembers(
+ io::Printer* printer) const {
+ printer->Print(variables_, "private java.util.List<$type$> $name$_;\n");
+ PrintExtraFieldInfo(variables_, printer);
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public java.util.List<$type$> "
+ "${$get$capitalized_name$List$}$() {\n"
+ " return $name$_;\n" // note: unmodifiable list
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public java.util.List<? extends $type$OrBuilder> \n"
+ " ${$get$capitalized_name$OrBuilderList$}$() {\n"
+ " return $name$_;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n"
+ " return $name$_.size();\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n"
+ " return $name$_.get(index);\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public $type$OrBuilder "
+ "${$get$capitalized_name$OrBuilder$}$(\n"
+ " int index) {\n"
+ " return $name$_.get(index);\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+}
+
+void RepeatedImmutableMessageFieldGenerator::PrintNestedBuilderCondition(
+ io::Printer* printer, const char* regular_case,
+ const char* nested_builder_case) const {
+ printer->Print(variables_, "if ($name$Builder_ == null) {\n");
+ printer->Indent();
+ printer->Print(variables_, regular_case);
+ printer->Outdent();
+ printer->Print("} else {\n");
+ printer->Indent();
+ printer->Print(variables_, nested_builder_case);
+ printer->Outdent();
+ printer->Print("}\n");
+}
+
+void RepeatedImmutableMessageFieldGenerator::PrintNestedBuilderFunction(
+ io::Printer* printer, const char* method_prototype,
+ const char* regular_case, const char* nested_builder_case,
+ const char* trailing_code) const {
+ printer->Print(variables_, method_prototype);
+ printer->Annotate("{", "}", descriptor_);
+ printer->Print(" {\n");
+ printer->Indent();
+ PrintNestedBuilderCondition(printer, regular_case, nested_builder_case);
+ if (trailing_code != NULL) {
+ printer->Print(variables_, trailing_code);
+ }
+ printer->Outdent();
+ printer->Print("}\n");
+}
+
+void RepeatedImmutableMessageFieldGenerator::GenerateBuilderMembers(
+ io::Printer* printer) const {
+ // When using nested-builders, the code initially works just like the
+ // non-nested builder case. It only creates a nested builder lazily on
+ // demand and then forever delegates to it after creation.
+
+ printer->Print(
+ variables_,
+ // Used when the builder is null.
+ // One field is the list and the other field keeps track of whether the
+ // list is immutable. If it's immutable, the invariant is that it must
+ // either an instance of Collections.emptyList() or it's an ArrayList
+ // wrapped in a Collections.unmodifiableList() wrapper and nobody else has
+ // a reference to the underlying ArrayList. This invariant allows us to
+ // share instances of lists between protocol buffers avoiding expensive
+ // memory allocations. Note, immutable is a strong guarantee here -- not
+ // just that the list cannot be modified via the reference but that the
+ // list can never be modified.
+ "private java.util.List<$type$> $name$_ =\n"
+ " java.util.Collections.emptyList();\n"
+
+ "private void ensure$capitalized_name$IsMutable() {\n"
+ " if (!$get_mutable_bit_builder$) {\n"
+ " $name$_ = new java.util.ArrayList<$type$>($name$_);\n"
+ " $set_mutable_bit_builder$;\n"
+ " }\n"
+ "}\n"
+ "\n");
+
+ printer->Print(
+ variables_,
+ // If this builder is non-null, it is used and the other fields are
+ // ignored.
+ "private com.google.protobuf.RepeatedFieldBuilder$ver$<\n"
+ " $type$, $type$.Builder, $type$OrBuilder> $name$Builder_;\n"
+ "\n");
+
+ // The comments above the methods below are based on a hypothetical
+ // repeated field of type "Field" called "RepeatedField".
+
+ // List<Field> getRepeatedFieldList()
+ WriteFieldDocComment(printer, descriptor_);
+ PrintNestedBuilderFunction(
+ printer,
+ "$deprecation$public java.util.List<$type$> "
+ "${$get$capitalized_name$List$}$()",
+
+ "return java.util.Collections.unmodifiableList($name$_);\n",
+ "return $name$Builder_.getMessageList();\n",
+
+ NULL);
+
+ // int getRepeatedFieldCount()
+ WriteFieldDocComment(printer, descriptor_);
+ PrintNestedBuilderFunction(
+ printer, "$deprecation$public int ${$get$capitalized_name$Count$}$()",
+
+ "return $name$_.size();\n", "return $name$Builder_.getCount();\n",
+
+ NULL);
+
+ // Field getRepeatedField(int index)
+ WriteFieldDocComment(printer, descriptor_);
+ PrintNestedBuilderFunction(
+ printer,
+ "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index)",
+
+ "return $name$_.get(index);\n",
+
+ "return $name$Builder_.getMessage(index);\n",
+
+ NULL);
+
+ // Builder setRepeatedField(int index, Field value)
+ WriteFieldDocComment(printer, descriptor_);
+ PrintNestedBuilderFunction(
+ printer,
+ "$deprecation$public Builder ${$set$capitalized_name$$}$(\n"
+ " int index, $type$ value)",
+ "if (value == null) {\n"
+ " throw new NullPointerException();\n"
+ "}\n"
+ "ensure$capitalized_name$IsMutable();\n"
+ "$name$_.set(index, value);\n"
+ "$on_changed$\n",
+ "$name$Builder_.setMessage(index, value);\n", "return this;\n");
+
+ // Builder setRepeatedField(int index, Field.Builder builderForValue)
+ WriteFieldDocComment(printer, descriptor_);
+ PrintNestedBuilderFunction(
+ printer,
+ "$deprecation$public Builder ${$set$capitalized_name$$}$(\n"
+ " int index, $type$.Builder builderForValue)",
+
+ "ensure$capitalized_name$IsMutable();\n"
+ "$name$_.set(index, builderForValue.build());\n"
+ "$on_changed$\n",
+
+ "$name$Builder_.setMessage(index, builderForValue.build());\n",
+
+ "return this;\n");
+
+ // Builder addRepeatedField(Field value)
+ WriteFieldDocComment(printer, descriptor_);
+ PrintNestedBuilderFunction(
+ printer,
+ "$deprecation$public Builder ${$add$capitalized_name$$}$($type$ value)",
+
+ "if (value == null) {\n"
+ " throw new NullPointerException();\n"
+ "}\n"
+ "ensure$capitalized_name$IsMutable();\n"
+ "$name$_.add(value);\n"
+
+ "$on_changed$\n",
+
+ "$name$Builder_.addMessage(value);\n",
+
+ "return this;\n");
+
+ // Builder addRepeatedField(int index, Field value)
+ WriteFieldDocComment(printer, descriptor_);
+ PrintNestedBuilderFunction(
+ printer,
+ "$deprecation$public Builder ${$add$capitalized_name$$}$(\n"
+ " int index, $type$ value)",
+
+ "if (value == null) {\n"
+ " throw new NullPointerException();\n"
+ "}\n"
+ "ensure$capitalized_name$IsMutable();\n"
+ "$name$_.add(index, value);\n"
+ "$on_changed$\n",
+
+ "$name$Builder_.addMessage(index, value);\n",
+
+ "return this;\n");
+
+ // Builder addRepeatedField(Field.Builder builderForValue)
+ WriteFieldDocComment(printer, descriptor_);
+ PrintNestedBuilderFunction(
+ printer,
+ "$deprecation$public Builder ${$add$capitalized_name$$}$(\n"
+ " $type$.Builder builderForValue)",
+
+ "ensure$capitalized_name$IsMutable();\n"
+ "$name$_.add(builderForValue.build());\n"
+ "$on_changed$\n",
+
+ "$name$Builder_.addMessage(builderForValue.build());\n",
+
+ "return this;\n");
+
+ // Builder addRepeatedField(int index, Field.Builder builderForValue)
+ WriteFieldDocComment(printer, descriptor_);
+ PrintNestedBuilderFunction(
+ printer,
+ "$deprecation$public Builder ${$add$capitalized_name$$}$(\n"
+ " int index, $type$.Builder builderForValue)",
+
+ "ensure$capitalized_name$IsMutable();\n"
+ "$name$_.add(index, builderForValue.build());\n"
+ "$on_changed$\n",
+
+ "$name$Builder_.addMessage(index, builderForValue.build());\n",
+
+ "return this;\n");
+
+ // Builder addAllRepeatedField(Iterable<Field> values)
+ WriteFieldDocComment(printer, descriptor_);
+ PrintNestedBuilderFunction(
+ printer,
+ "$deprecation$public Builder ${$addAll$capitalized_name$$}$(\n"
+ " java.lang.Iterable<? extends $type$> values)",
+
+ "ensure$capitalized_name$IsMutable();\n"
+ "com.google.protobuf.AbstractMessageLite.Builder.addAll(\n"
+ " values, $name$_);\n"
+ "$on_changed$\n",
+
+ "$name$Builder_.addAllMessages(values);\n",
+
+ "return this;\n");
+
+ // Builder clearAllRepeatedField()
+ WriteFieldDocComment(printer, descriptor_);
+ PrintNestedBuilderFunction(
+ printer, "$deprecation$public Builder ${$clear$capitalized_name$$}$()",
+
+ "$name$_ = java.util.Collections.emptyList();\n"
+ "$clear_mutable_bit_builder$;\n"
+ "$on_changed$\n",
+
+ "$name$Builder_.clear();\n",
+
+ "return this;\n");
+
+ // Builder removeRepeatedField(int index)
+ WriteFieldDocComment(printer, descriptor_);
+ PrintNestedBuilderFunction(
+ printer,
+ "$deprecation$public Builder ${$remove$capitalized_name$$}$(int index)",
+
+ "ensure$capitalized_name$IsMutable();\n"
+ "$name$_.remove(index);\n"
+ "$on_changed$\n",
+
+ "$name$Builder_.remove(index);\n",
+
+ "return this;\n");
+
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "$deprecation$public $type$.Builder ${$get$capitalized_name$Builder$}$(\n"
+ " int index) {\n"
+ " return get$capitalized_name$FieldBuilder().getBuilder(index);\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public $type$OrBuilder "
+ "${$get$capitalized_name$OrBuilder$}$(\n"
+ " int index) {\n"
+ " if ($name$Builder_ == null) {\n"
+ " return $name$_.get(index);"
+ " } else {\n"
+ " return $name$Builder_.getMessageOrBuilder(index);\n"
+ " }\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "$deprecation$public java.util.List<? extends $type$OrBuilder> \n"
+ " ${$get$capitalized_name$OrBuilderList$}$() {\n"
+ " if ($name$Builder_ != null) {\n"
+ " return $name$Builder_.getMessageOrBuilderList();\n"
+ " } else {\n"
+ " return java.util.Collections.unmodifiableList($name$_);\n"
+ " }\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public $type$.Builder "
+ "${$add$capitalized_name$Builder$}$() {\n"
+ " return get$capitalized_name$FieldBuilder().addBuilder(\n"
+ " $type$.getDefaultInstance());\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "$deprecation$public $type$.Builder ${$add$capitalized_name$Builder$}$(\n"
+ " int index) {\n"
+ " return get$capitalized_name$FieldBuilder().addBuilder(\n"
+ " index, $type$.getDefaultInstance());\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "$deprecation$public java.util.List<$type$.Builder> \n"
+ " ${$get$capitalized_name$BuilderList$}$() {\n"
+ " return get$capitalized_name$FieldBuilder().getBuilderList();\n"
+ "}\n"
+ "private com.google.protobuf.RepeatedFieldBuilder$ver$<\n"
+ " $type$, $type$.Builder, $type$OrBuilder> \n"
+ " get$capitalized_name$FieldBuilder() {\n"
+ " if ($name$Builder_ == null) {\n"
+ " $name$Builder_ = new "
+ "com.google.protobuf.RepeatedFieldBuilder$ver$<\n"
+ " $type$, $type$.Builder, $type$OrBuilder>(\n"
+ " $name$_,\n"
+ " $get_mutable_bit_builder$,\n"
+ " getParentForChildren(),\n"
+ " isClean());\n"
+ " $name$_ = null;\n"
+ " }\n"
+ " return $name$Builder_;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+}
+
+void RepeatedImmutableMessageFieldGenerator::
+ GenerateFieldBuilderInitializationCode(io::Printer* printer) const {
+ printer->Print(variables_, "get$capitalized_name$FieldBuilder();\n");
+}
+
+void RepeatedImmutableMessageFieldGenerator::GenerateInitializationCode(
+ io::Printer* printer) const {
+ printer->Print(variables_, "$name$_ = java.util.Collections.emptyList();\n");
+}
+
+void RepeatedImmutableMessageFieldGenerator::GenerateBuilderClearCode(
+ io::Printer* printer) const {
+ PrintNestedBuilderCondition(printer,
+ "$name$_ = java.util.Collections.emptyList();\n"
+ "$clear_mutable_bit_builder$;\n",
+
+ "$name$Builder_.clear();\n");
+}
+
+void RepeatedImmutableMessageFieldGenerator::GenerateMergingCode(
+ io::Printer* printer) const {
+ // The code below does two optimizations (non-nested builder case):
+ // 1. If the other list is empty, there's nothing to do. This ensures we
+ // don't allocate a new array if we already have an immutable one.
+ // 2. If the other list is non-empty and our current list is empty, we can
+ // reuse the other list which is guaranteed to be immutable.
+ PrintNestedBuilderCondition(
+ printer,
+ "if (!other.$name$_.isEmpty()) {\n"
+ " if ($name$_.isEmpty()) {\n"
+ " $name$_ = other.$name$_;\n"
+ " $clear_mutable_bit_builder$;\n"
+ " } else {\n"
+ " ensure$capitalized_name$IsMutable();\n"
+ " $name$_.addAll(other.$name$_);\n"
+ " }\n"
+ " $on_changed$\n"
+ "}\n",
+
+ "if (!other.$name$_.isEmpty()) {\n"
+ " if ($name$Builder_.isEmpty()) {\n"
+ " $name$Builder_.dispose();\n"
+ " $name$Builder_ = null;\n"
+ " $name$_ = other.$name$_;\n"
+ " $clear_mutable_bit_builder$;\n"
+ " $name$Builder_ = \n"
+ " com.google.protobuf.GeneratedMessage$ver$.alwaysUseFieldBuilders "
+ "?\n"
+ " get$capitalized_name$FieldBuilder() : null;\n"
+ " } else {\n"
+ " $name$Builder_.addAllMessages(other.$name$_);\n"
+ " }\n"
+ "}\n");
+}
+
+void RepeatedImmutableMessageFieldGenerator::GenerateBuildingCode(
+ io::Printer* printer) const {
+ // The code below (non-nested builder case) ensures that the result has an
+ // immutable list. If our list is immutable, we can just reuse it. If not,
+ // we make it immutable.
+ PrintNestedBuilderCondition(
+ printer,
+ "if ($get_mutable_bit_builder$) {\n"
+ " $name$_ = java.util.Collections.unmodifiableList($name$_);\n"
+ " $clear_mutable_bit_builder$;\n"
+ "}\n"
+ "result.$name$_ = $name$_;\n",
+
+ "result.$name$_ = $name$Builder_.build();\n");
+}
+
+void RepeatedImmutableMessageFieldGenerator::GenerateParsingCode(
+ io::Printer* printer) const {
+ printer->Print(variables_,
+ "if (!$get_mutable_bit_parser$) {\n"
+ " $name$_ = new java.util.ArrayList<$type$>();\n"
+ " $set_mutable_bit_parser$;\n"
+ "}\n");
+
+ if (GetType(descriptor_) == FieldDescriptor::TYPE_GROUP) {
+ printer->Print(
+ variables_,
+ "$name$_.add(input.readGroup($number$, $type$.$get_parser$,\n"
+ " extensionRegistry));\n");
+ } else {
+ printer->Print(
+ variables_,
+ "$name$_.add(\n"
+ " input.readMessage($type$.$get_parser$, extensionRegistry));\n");
+ }
+}
+
+void RepeatedImmutableMessageFieldGenerator::GenerateParsingDoneCode(
+ io::Printer* printer) const {
+ printer->Print(
+ variables_,
+ "if ($get_mutable_bit_parser$) {\n"
+ " $name$_ = java.util.Collections.unmodifiableList($name$_);\n"
+ "}\n");
+}
+
+void RepeatedImmutableMessageFieldGenerator::GenerateSerializationCode(
+ io::Printer* printer) const {
+ printer->Print(variables_,
+ "for (int i = 0; i < $name$_.size(); i++) {\n"
+ " output.write$group_or_message$($number$, $name$_.get(i));\n"
+ "}\n");
+}
+
+void RepeatedImmutableMessageFieldGenerator::GenerateSerializedSizeCode(
+ io::Printer* printer) const {
+ printer->Print(
+ variables_,
+ "for (int i = 0; i < $name$_.size(); i++) {\n"
+ " size += com.google.protobuf.CodedOutputStream\n"
+ " .compute$group_or_message$Size($number$, $name$_.get(i));\n"
+ "}\n");
+}
+
+void RepeatedImmutableMessageFieldGenerator::GenerateEqualsCode(
+ io::Printer* printer) const {
+ printer->Print(
+ variables_,
+ "if (!get$capitalized_name$List()\n"
+ " .equals(other.get$capitalized_name$List())) return false;\n");
+}
+
+void RepeatedImmutableMessageFieldGenerator::GenerateHashCode(
+ io::Printer* printer) const {
+ printer->Print(
+ variables_,
+ "if (get$capitalized_name$Count() > 0) {\n"
+ " hash = (37 * hash) + $constant_name$;\n"
+ " hash = (53 * hash) + get$capitalized_name$List().hashCode();\n"
+ "}\n");
+}
+
+std::string RepeatedImmutableMessageFieldGenerator::GetBoxedType() const {
+ return name_resolver_->GetImmutableClassName(descriptor_->message_type());
+}
+
+void RepeatedImmutableMessageFieldGenerator::GenerateKotlinDslMembers(
+ io::Printer* printer) const {
+ printer->Print(
+ variables_,
+ "/**\n"
+ " * An uninstantiable, behaviorless type to represent the field in\n"
+ " * generics.\n"
+ " */\n"
+ "@kotlin.OptIn"
+ "(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)\n"
+ "public class ${$$kt_capitalized_name$Proxy$}$ private constructor()"
+ " : com.google.protobuf.kotlin.DslProxy()\n");
+
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$kt_deprecation$ public val $kt_name$: "
+ "com.google.protobuf.kotlin.DslList"
+ "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>\n"
+ " @kotlin.jvm.JvmSynthetic\n"
+ " get() = com.google.protobuf.kotlin.DslList(\n"
+ " $kt_dsl_builder$.${$get$capitalized_name$List$}$()\n"
+ " )\n");
+
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_ADDER,
+ /* builder */ false);
+ printer->Print(variables_,
+ "@kotlin.jvm.JvmSynthetic\n"
+ "@kotlin.jvm.JvmName(\"add$kt_capitalized_name$\")\n"
+ "public fun com.google.protobuf.kotlin.DslList"
+ "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>."
+ "add(value: $kt_type$) {\n"
+ " $kt_dsl_builder$.${$add$capitalized_name$$}$(value)\n"
+ "}");
+
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_ADDER,
+ /* builder */ false);
+ printer->Print(variables_,
+ "@kotlin.jvm.JvmSynthetic\n"
+ "@kotlin.jvm.JvmName(\"plusAssign$kt_capitalized_name$\")\n"
+ "@Suppress(\"NOTHING_TO_INLINE\")\n"
+ "public inline operator fun com.google.protobuf.kotlin.DslList"
+ "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>."
+ "plusAssign(value: $kt_type$) {\n"
+ " add(value)\n"
+ "}");
+
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_MULTI_ADDER,
+ /* builder */ false);
+ printer->Print(variables_,
+ "@kotlin.jvm.JvmSynthetic\n"
+ "@kotlin.jvm.JvmName(\"addAll$kt_capitalized_name$\")\n"
+ "public fun com.google.protobuf.kotlin.DslList"
+ "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>."
+ "addAll(values: kotlin.collections.Iterable<$kt_type$>) {\n"
+ " $kt_dsl_builder$.${$addAll$capitalized_name$$}$(values)\n"
+ "}");
+
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_MULTI_ADDER,
+ /* builder */ false);
+ printer->Print(
+ variables_,
+ "@kotlin.jvm.JvmSynthetic\n"
+ "@kotlin.jvm.JvmName(\"plusAssignAll$kt_capitalized_name$\")\n"
+ "@Suppress(\"NOTHING_TO_INLINE\")\n"
+ "public inline operator fun com.google.protobuf.kotlin.DslList"
+ "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>."
+ "plusAssign(values: kotlin.collections.Iterable<$kt_type$>) {\n"
+ " addAll(values)\n"
+ "}");
+
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_SETTER,
+ /* builder */ false);
+ printer->Print(
+ variables_,
+ "@kotlin.jvm.JvmSynthetic\n"
+ "@kotlin.jvm.JvmName(\"set$kt_capitalized_name$\")\n"
+ "public operator fun com.google.protobuf.kotlin.DslList"
+ "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>."
+ "set(index: kotlin.Int, value: $kt_type$) {\n"
+ " $kt_dsl_builder$.${$set$capitalized_name$$}$(index, value)\n"
+ "}");
+
+ WriteFieldAccessorDocComment(printer, descriptor_, CLEARER,
+ /* builder */ false);
+ printer->Print(variables_,
+ "@kotlin.jvm.JvmSynthetic\n"
+ "@kotlin.jvm.JvmName(\"clear$kt_capitalized_name$\")\n"
+ "public fun com.google.protobuf.kotlin.DslList"
+ "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>."
+ "clear() {\n"
+ " $kt_dsl_builder$.${$clear$capitalized_name$$}$()\n"
+ "}");
+}
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_message_field.h b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_message_field.h
new file mode 100644
index 00000000..2ade2ba8
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_message_field.h
@@ -0,0 +1,179 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 GOOGLE_PROTOBUF_COMPILER_JAVA_MESSAGE_FIELD_H__
+#define GOOGLE_PROTOBUF_COMPILER_JAVA_MESSAGE_FIELD_H__
+
+#include <map>
+#include <string>
+#include <compiler/java/java_field.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+class Context; // context.h
+class ClassNameResolver; // name_resolver.h
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+class ImmutableMessageFieldGenerator : public ImmutableFieldGenerator {
+ public:
+ explicit ImmutableMessageFieldGenerator(const FieldDescriptor* descriptor,
+ int messageBitIndex,
+ int builderBitIndex,
+ Context* context);
+ ~ImmutableMessageFieldGenerator();
+
+ // implements ImmutableFieldGenerator
+ // ---------------------------------------
+ int GetNumBitsForMessage() const override;
+ int GetNumBitsForBuilder() const override;
+ void GenerateInterfaceMembers(io::Printer* printer) const override;
+ void GenerateMembers(io::Printer* printer) const override;
+ void GenerateBuilderMembers(io::Printer* printer) const override;
+ void GenerateInitializationCode(io::Printer* printer) const override;
+ void GenerateBuilderClearCode(io::Printer* printer) const override;
+ void GenerateMergingCode(io::Printer* printer) const override;
+ void GenerateBuildingCode(io::Printer* printer) const override;
+ void GenerateParsingCode(io::Printer* printer) const override;
+ void GenerateParsingDoneCode(io::Printer* printer) const override;
+ void GenerateSerializationCode(io::Printer* printer) const override;
+ void GenerateSerializedSizeCode(io::Printer* printer) const override;
+ void GenerateFieldBuilderInitializationCode(
+ io::Printer* printer) const override;
+ void GenerateEqualsCode(io::Printer* printer) const override;
+ void GenerateHashCode(io::Printer* printer) const override;
+ void GenerateKotlinDslMembers(io::Printer* printer) const override;
+
+ std::string GetBoxedType() const override;
+
+ protected:
+ const FieldDescriptor* descriptor_;
+ std::map<std::string, std::string> variables_;
+ ClassNameResolver* name_resolver_;
+
+ void PrintNestedBuilderCondition(io::Printer* printer,
+ const char* regular_case,
+ const char* nested_builder_case) const;
+ void PrintNestedBuilderFunction(io::Printer* printer,
+ const char* method_prototype,
+ const char* regular_case,
+ const char* nested_builder_case,
+ const char* trailing_code) const;
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableMessageFieldGenerator);
+};
+
+class ImmutableMessageOneofFieldGenerator
+ : public ImmutableMessageFieldGenerator {
+ public:
+ ImmutableMessageOneofFieldGenerator(const FieldDescriptor* descriptor,
+ int messageBitIndex, int builderBitIndex,
+ Context* context);
+ ~ImmutableMessageOneofFieldGenerator();
+
+ void GenerateMembers(io::Printer* printer) const override;
+ void GenerateBuilderMembers(io::Printer* printer) const override;
+ void GenerateBuildingCode(io::Printer* printer) const override;
+ void GenerateMergingCode(io::Printer* printer) const override;
+ void GenerateParsingCode(io::Printer* printer) const override;
+ void GenerateSerializationCode(io::Printer* printer) const override;
+ void GenerateSerializedSizeCode(io::Printer* printer) const override;
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableMessageOneofFieldGenerator);
+};
+
+class RepeatedImmutableMessageFieldGenerator : public ImmutableFieldGenerator {
+ public:
+ explicit RepeatedImmutableMessageFieldGenerator(
+ const FieldDescriptor* descriptor, int messageBitIndex,
+ int builderBitIndex, Context* context);
+ ~RepeatedImmutableMessageFieldGenerator() override;
+
+ // implements ImmutableFieldGenerator ---------------------------------------
+ int GetNumBitsForMessage() const override;
+ int GetNumBitsForBuilder() const override;
+ void GenerateInterfaceMembers(io::Printer* printer) const override;
+ void GenerateMembers(io::Printer* printer) const override;
+ void GenerateBuilderMembers(io::Printer* printer) const override;
+ void GenerateInitializationCode(io::Printer* printer) const override;
+ void GenerateBuilderClearCode(io::Printer* printer) const override;
+ void GenerateMergingCode(io::Printer* printer) const override;
+ void GenerateBuildingCode(io::Printer* printer) const override;
+ void GenerateParsingCode(io::Printer* printer) const override;
+ void GenerateParsingDoneCode(io::Printer* printer) const override;
+ void GenerateSerializationCode(io::Printer* printer) const override;
+ void GenerateSerializedSizeCode(io::Printer* printer) const override;
+ void GenerateFieldBuilderInitializationCode(
+ io::Printer* printer) const override;
+ void GenerateEqualsCode(io::Printer* printer) const override;
+ void GenerateHashCode(io::Printer* printer) const override;
+ void GenerateKotlinDslMembers(io::Printer* printer) const override;
+
+ std::string GetBoxedType() const override;
+
+ protected:
+ const FieldDescriptor* descriptor_;
+ std::map<std::string, std::string> variables_;
+ ClassNameResolver* name_resolver_;
+
+ void PrintNestedBuilderCondition(io::Printer* printer,
+ const char* regular_case,
+ const char* nested_builder_case) const;
+ void PrintNestedBuilderFunction(io::Printer* printer,
+ const char* method_prototype,
+ const char* regular_case,
+ const char* nested_builder_case,
+ const char* trailing_code) const;
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedImmutableMessageFieldGenerator);
+};
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_MESSAGE_FIELD_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_message_field_lite.cc b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_message_field_lite.cc
new file mode 100644
index 00000000..f3050db3
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_message_field_lite.cc
@@ -0,0 +1,884 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 <compiler/java/java_message_field_lite.h>
+
+#include <cstdint>
+#include <map>
+#include <string>
+
+#include <compiler/java/java_context.h>
+#include <compiler/java/java_doc_comment.h>
+#include <compiler/java/java_helpers.h>
+#include <compiler/java/java_name_resolver.h>
+#include <io/printer.h>
+#include <wire_format.h>
+#include <stubs/strutil.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+namespace {
+
+void SetMessageVariables(const FieldDescriptor* descriptor, int messageBitIndex,
+ int builderBitIndex, const FieldGeneratorInfo* info,
+ ClassNameResolver* name_resolver,
+ std::map<std::string, std::string>* variables) {
+ SetCommonFieldVariables(descriptor, info, variables);
+
+ (*variables)["type"] =
+ name_resolver->GetImmutableClassName(descriptor->message_type());
+ (*variables)["kt_type"] = (*variables)["type"];
+ (*variables)["mutable_type"] =
+ name_resolver->GetMutableClassName(descriptor->message_type());
+ (*variables)["group_or_message"] =
+ (GetType(descriptor) == FieldDescriptor::TYPE_GROUP) ? "Group"
+ : "Message";
+ // TODO(birdo): Add @deprecated javadoc when generating javadoc is supported
+ // by the proto compiler
+ (*variables)["deprecation"] =
+ descriptor->options().deprecated() ? "@java.lang.Deprecated " : "";
+ (*variables)["kt_deprecation"] =
+ descriptor->options().deprecated()
+ ? "@kotlin.Deprecated(message = \"Field " + (*variables)["name"] +
+ " is deprecated\") "
+ : "";
+ (*variables)["required"] = descriptor->is_required() ? "true" : "false";
+
+ if (HasHasbit(descriptor)) {
+ // For singular messages and builders, one bit is used for the hasField bit.
+ (*variables)["get_has_field_bit_message"] = GenerateGetBit(messageBitIndex);
+
+ // Note that these have a trailing ";".
+ (*variables)["set_has_field_bit_message"] =
+ GenerateSetBit(messageBitIndex) + ";";
+ (*variables)["clear_has_field_bit_message"] =
+ GenerateClearBit(messageBitIndex) + ";";
+
+ (*variables)["is_field_present_message"] = GenerateGetBit(messageBitIndex);
+ } else {
+ (*variables)["set_has_field_bit_message"] = "";
+ (*variables)["clear_has_field_bit_message"] = "";
+
+ (*variables)["is_field_present_message"] =
+ (*variables)["name"] + "_ != null";
+ }
+
+ (*variables)["get_has_field_bit_from_local"] =
+ GenerateGetBitFromLocal(builderBitIndex);
+ (*variables)["set_has_field_bit_to_local"] =
+ GenerateSetBitToLocal(messageBitIndex);
+
+ // We use `x.getClass()` as a null check because it generates less bytecode
+ // than an `if (x == null) { throw ... }` statement.
+ (*variables)["null_check"] = "value.getClass();\n";
+}
+
+} // namespace
+
+// ===================================================================
+
+ImmutableMessageFieldLiteGenerator::ImmutableMessageFieldLiteGenerator(
+ const FieldDescriptor* descriptor, int messageBitIndex, Context* context)
+ : descriptor_(descriptor),
+ messageBitIndex_(messageBitIndex),
+ name_resolver_(context->GetNameResolver()) {
+ SetMessageVariables(descriptor, messageBitIndex, 0,
+ context->GetFieldGeneratorInfo(descriptor),
+ name_resolver_, &variables_);
+}
+
+ImmutableMessageFieldLiteGenerator::~ImmutableMessageFieldLiteGenerator() {}
+
+int ImmutableMessageFieldLiteGenerator::GetNumBitsForMessage() const {
+ // TODO(dweis): We don't need a has bit for messages as they have null
+ // sentinels and no user should be reflecting on this. We could save some
+ // bits by setting to 0 and updating the runtimes but this might come at a
+ // runtime performance cost since we can't memoize has-bit reads.
+ return HasHasbit(descriptor_) ? 1 : 0;
+}
+
+void ImmutableMessageFieldLiteGenerator::GenerateInterfaceMembers(
+ io::Printer* printer) const {
+ WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
+ printer->Print(variables_, "$deprecation$boolean has$capitalized_name$();\n");
+ WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
+ printer->Print(variables_, "$deprecation$$type$ get$capitalized_name$();\n");
+}
+
+void ImmutableMessageFieldLiteGenerator::GenerateMembers(
+ io::Printer* printer) const {
+
+ printer->Print(variables_, "private $type$ $name$_;\n");
+ PrintExtraFieldInfo(variables_, printer);
+
+ if (HasHasbit(descriptor_)) {
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
+ " return $get_has_field_bit_message$;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
+ " return $name$_ == null ? $type$.getDefaultInstance() : $name$_;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ } else {
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
+ " return $name$_ != null;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
+ " return $name$_ == null ? $type$.getDefaultInstance() : $name$_;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ }
+
+ // Field.Builder setField(Field value)
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "private void set$capitalized_name$($type$ value) {\n"
+ " $null_check$"
+ " $name$_ = value;\n"
+ " $set_has_field_bit_message$\n"
+ " }\n");
+
+ // Field.Builder mergeField(Field value)
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "@java.lang.SuppressWarnings({\"ReferenceEquality\"})\n"
+ "private void merge$capitalized_name$($type$ value) {\n"
+ " $null_check$"
+ " if ($name$_ != null &&\n"
+ " $name$_ != $type$.getDefaultInstance()) {\n"
+ " $name$_ =\n"
+ " $type$.newBuilder($name$_).mergeFrom(value).buildPartial();\n"
+ " } else {\n"
+ " $name$_ = value;\n"
+ " }\n"
+ " $set_has_field_bit_message$\n"
+ "}\n");
+
+ // Field.Builder clearField()
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "private void clear$capitalized_name$() {"
+ " $name$_ = null;\n"
+ " $clear_has_field_bit_message$\n"
+ "}\n");
+}
+
+void ImmutableMessageFieldLiteGenerator::GenerateBuilderMembers(
+ io::Printer* printer) const {
+ // The comments above the methods below are based on a hypothetical
+ // field of type "Field" called "Field".
+
+ // boolean hasField()
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
+ " return instance.has$capitalized_name$();\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+
+ // Field getField()
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
+ " return instance.get$capitalized_name$();\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+
+ // Field.Builder setField(Field value)
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public Builder "
+ "${$set$capitalized_name$$}$($type$ value) {\n"
+ " copyOnWrite();\n"
+ " instance.set$capitalized_name$(value);\n"
+ " return this;\n"
+ " }\n");
+ printer->Annotate("{", "}", descriptor_);
+
+ // Field.Builder setField(Field.Builder builderForValue)
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public Builder ${$set$capitalized_name$$}$(\n"
+ " $type$.Builder builderForValue) {\n"
+ " copyOnWrite();\n"
+ " instance.set$capitalized_name$(builderForValue.build());\n"
+ " return this;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+
+ // Field.Builder mergeField(Field value)
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public Builder "
+ "${$merge$capitalized_name$$}$($type$ value) {\n"
+ " copyOnWrite();\n"
+ " instance.merge$capitalized_name$(value);\n"
+ " return this;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+
+ // Field.Builder clearField()
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public Builder ${$clear$capitalized_name$$}$() {"
+ " copyOnWrite();\n"
+ " instance.clear$capitalized_name$();\n"
+ " return this;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+}
+
+void ImmutableMessageFieldLiteGenerator::GenerateKotlinDslMembers(
+ io::Printer* printer) const {
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$kt_deprecation$public var $kt_name$: $kt_type$\n"
+ " @JvmName(\"${$get$kt_capitalized_name$$}$\")\n"
+ " get() = $kt_dsl_builder$.${$get$capitalized_name$$}$()\n"
+ " @JvmName(\"${$set$kt_capitalized_name$$}$\")\n"
+ " set(value) {\n"
+ " $kt_dsl_builder$.${$set$capitalized_name$$}$(value)\n"
+ " }\n");
+
+ WriteFieldAccessorDocComment(printer, descriptor_, CLEARER,
+ /* builder */ false);
+ printer->Print(variables_,
+ "public fun ${$clear$kt_capitalized_name$$}$() {\n"
+ " $kt_dsl_builder$.${$clear$capitalized_name$$}$()\n"
+ "}\n");
+
+ WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
+ printer->Print(
+ variables_,
+ "public fun ${$has$kt_capitalized_name$$}$(): kotlin.Boolean {\n"
+ " return $kt_dsl_builder$.${$has$capitalized_name$$}$()\n"
+ "}\n");
+}
+
+void ImmutableMessageFieldLiteGenerator::GenerateFieldInfo(
+ io::Printer* printer, std::vector<uint16_t>* output) const {
+ WriteIntToUtf16CharSequence(descriptor_->number(), output);
+ WriteIntToUtf16CharSequence(GetExperimentalJavaFieldType(descriptor_),
+ output);
+ if (HasHasbit(descriptor_)) {
+ WriteIntToUtf16CharSequence(messageBitIndex_, output);
+ }
+ printer->Print(variables_, "\"$name$_\",\n");
+}
+
+void ImmutableMessageFieldLiteGenerator::GenerateInitializationCode(
+ io::Printer* printer) const {}
+
+std::string ImmutableMessageFieldLiteGenerator::GetBoxedType() const {
+ return name_resolver_->GetImmutableClassName(descriptor_->message_type());
+}
+
+// ===================================================================
+
+ImmutableMessageOneofFieldLiteGenerator::
+ ImmutableMessageOneofFieldLiteGenerator(const FieldDescriptor* descriptor,
+ int messageBitIndex,
+ Context* context)
+ : ImmutableMessageFieldLiteGenerator(descriptor, messageBitIndex, context) {
+ const OneofGeneratorInfo* info =
+ context->GetOneofGeneratorInfo(descriptor->containing_oneof());
+ SetCommonOneofVariables(descriptor, info, &variables_);
+}
+
+ImmutableMessageOneofFieldLiteGenerator::
+ ~ImmutableMessageOneofFieldLiteGenerator() {}
+
+void ImmutableMessageOneofFieldLiteGenerator::GenerateMembers(
+ io::Printer* printer) const {
+ PrintExtraFieldInfo(variables_, printer);
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
+ " return $has_oneof_case_message$;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
+ " if ($has_oneof_case_message$) {\n"
+ " return ($type$) $oneof_name$_;\n"
+ " }\n"
+ " return $type$.getDefaultInstance();\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+
+ // Field.Builder setField(Field value)
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "private void set$capitalized_name$($type$ value) {\n"
+ " $null_check$"
+ " $oneof_name$_ = value;\n"
+ " $set_oneof_case_message$;\n"
+ "}\n");
+
+ // Field.Builder mergeField(Field value)
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "private void merge$capitalized_name$($type$ value) {\n"
+ " $null_check$"
+ " if ($has_oneof_case_message$ &&\n"
+ " $oneof_name$_ != $type$.getDefaultInstance()) {\n"
+ " $oneof_name$_ = $type$.newBuilder(($type$) $oneof_name$_)\n"
+ " .mergeFrom(value).buildPartial();\n"
+ " } else {\n"
+ " $oneof_name$_ = value;\n"
+ " }\n"
+ " $set_oneof_case_message$;\n"
+ "}\n");
+
+ // Field.Builder clearField()
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "private void clear$capitalized_name$() {\n"
+ " if ($has_oneof_case_message$) {\n"
+ " $clear_oneof_case_message$;\n"
+ " $oneof_name$_ = null;\n"
+ " }\n"
+ "}\n");
+}
+
+void ImmutableMessageOneofFieldLiteGenerator::GenerateFieldInfo(
+ io::Printer* printer, std::vector<uint16_t>* output) const {
+ WriteIntToUtf16CharSequence(descriptor_->number(), output);
+ WriteIntToUtf16CharSequence(GetExperimentalJavaFieldType(descriptor_),
+ output);
+ WriteIntToUtf16CharSequence(descriptor_->containing_oneof()->index(), output);
+ printer->Print(variables_, "$oneof_stored_type$.class,\n");
+}
+
+void ImmutableMessageOneofFieldLiteGenerator::GenerateBuilderMembers(
+ io::Printer* printer) const {
+ // The comments above the methods below are based on a hypothetical
+ // field of type "Field" called "Field".
+
+ // boolean hasField()
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
+ " return instance.has$capitalized_name$();\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+
+ // Field getField()
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
+ " return instance.get$capitalized_name$();\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+
+ // Field.Builder setField(Field value)
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public Builder "
+ "${$set$capitalized_name$$}$($type$ value) {\n"
+ " copyOnWrite();\n"
+ " instance.set$capitalized_name$(value);\n"
+ " return this;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+
+ // Field.Builder setField(Field.Builder builderForValue)
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public Builder ${$set$capitalized_name$$}$(\n"
+ " $type$.Builder builderForValue) {\n"
+ " copyOnWrite();\n"
+ " instance.set$capitalized_name$(builderForValue.build());\n"
+ " return this;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+
+ // Field.Builder mergeField(Field value)
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public Builder "
+ "${$merge$capitalized_name$$}$($type$ value) {\n"
+ " copyOnWrite();\n"
+ " instance.merge$capitalized_name$(value);\n"
+ " return this;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+
+ // Field.Builder clearField()
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n"
+ " copyOnWrite();\n"
+ " instance.clear$capitalized_name$();\n"
+ " return this;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+}
+
+// ===================================================================
+
+RepeatedImmutableMessageFieldLiteGenerator::
+ RepeatedImmutableMessageFieldLiteGenerator(
+ const FieldDescriptor* descriptor, int messageBitIndex,
+ Context* context)
+ : descriptor_(descriptor), name_resolver_(context->GetNameResolver()) {
+ SetMessageVariables(descriptor, messageBitIndex, 0,
+ context->GetFieldGeneratorInfo(descriptor),
+ name_resolver_, &variables_);
+}
+
+RepeatedImmutableMessageFieldLiteGenerator::
+ ~RepeatedImmutableMessageFieldLiteGenerator() {}
+
+int RepeatedImmutableMessageFieldLiteGenerator::GetNumBitsForMessage() const {
+ return 0;
+}
+
+void RepeatedImmutableMessageFieldLiteGenerator::GenerateInterfaceMembers(
+ io::Printer* printer) const {
+ // TODO(jonp): In the future, consider having methods specific to the
+ // interface so that builders can choose dynamically to either return a
+ // message or a nested builder, so that asking for the interface doesn't
+ // cause a message to ever be built.
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$java.util.List<$type$> \n"
+ " get$capitalized_name$List();\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$$type$ get$capitalized_name$(int index);\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$int get$capitalized_name$Count();\n");
+}
+
+void RepeatedImmutableMessageFieldLiteGenerator::GenerateMembers(
+ io::Printer* printer) const {
+ printer->Print(
+ variables_,
+ "private com.google.protobuf.Internal.ProtobufList<$type$> $name$_;\n");
+ PrintExtraFieldInfo(variables_, printer);
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public java.util.List<$type$> "
+ "${$get$capitalized_name$List$}$() {\n"
+ " return $name$_;\n" // note: unmodifiable list
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "$deprecation$public java.util.List<? extends $type$OrBuilder> \n"
+ " ${$get$capitalized_name$OrBuilderList$}$() {\n"
+ " return $name$_;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n"
+ " return $name$_.size();\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n"
+ " return $name$_.get(index);\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public $type$OrBuilder "
+ "${$get$capitalized_name$OrBuilder$}$(\n"
+ " int index) {\n"
+ " return $name$_.get(index);\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+
+ printer->Print(
+ variables_,
+ "private void ensure$capitalized_name$IsMutable() {\n"
+ // Use a temporary to avoid a redundant iget-object.
+ " com.google.protobuf.Internal.ProtobufList<$type$> tmp = $name$_;\n"
+ " if (!tmp.isModifiable()) {\n"
+ " $name$_ =\n"
+ " com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);\n"
+ " }\n"
+ "}\n"
+ "\n");
+
+ // Builder setRepeatedField(int index, Field value)
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "private void set$capitalized_name$(\n"
+ " int index, $type$ value) {\n"
+ " $null_check$"
+ " ensure$capitalized_name$IsMutable();\n"
+ " $name$_.set(index, value);\n"
+ "}\n");
+
+ // Builder addRepeatedField(Field value)
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "private void add$capitalized_name$($type$ value) {\n"
+ " $null_check$"
+ " ensure$capitalized_name$IsMutable();\n"
+ " $name$_.add(value);\n"
+ "}\n");
+
+ // Builder addRepeatedField(int index, Field value)
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "private void add$capitalized_name$(\n"
+ " int index, $type$ value) {\n"
+ " $null_check$"
+ " ensure$capitalized_name$IsMutable();\n"
+ " $name$_.add(index, value);\n"
+ "}\n");
+
+ // Builder addAllRepeatedField(Iterable<Field> values)
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "private void addAll$capitalized_name$(\n"
+ " java.lang.Iterable<? extends $type$> values) {\n"
+ " ensure$capitalized_name$IsMutable();\n"
+ " com.google.protobuf.AbstractMessageLite.addAll(\n"
+ " values, $name$_);\n"
+ "}\n");
+
+ // Builder clearAllRepeatedField()
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "private void clear$capitalized_name$() {\n"
+ " $name$_ = emptyProtobufList();\n"
+ "}\n");
+
+ // Builder removeRepeatedField(int index)
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "private void remove$capitalized_name$(int index) {\n"
+ " ensure$capitalized_name$IsMutable();\n"
+ " $name$_.remove(index);\n"
+ "}\n");
+}
+
+void RepeatedImmutableMessageFieldLiteGenerator::GenerateBuilderMembers(
+ io::Printer* printer) const {
+ // The comments above the methods below are based on a hypothetical
+ // repeated field of type "Field" called "RepeatedField".
+
+ // List<Field> getRepeatedFieldList()
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public java.util.List<$type$> "
+ "${$get$capitalized_name$List$}$() {\n"
+ " return java.util.Collections.unmodifiableList(\n"
+ " instance.get$capitalized_name$List());\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+
+ // int getRepeatedFieldCount()
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n"
+ " return instance.get$capitalized_name$Count();\n"
+ "}");
+ printer->Annotate("{", "}", descriptor_);
+
+ // Field getRepeatedField(int index)
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n"
+ " return instance.get$capitalized_name$(index);\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+
+ // Builder setRepeatedField(int index, Field value)
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public Builder ${$set$capitalized_name$$}$(\n"
+ " int index, $type$ value) {\n"
+ " copyOnWrite();\n"
+ " instance.set$capitalized_name$(index, value);\n"
+ " return this;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+
+ // Builder setRepeatedField(int index, Field.Builder builderForValue)
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public Builder ${$set$capitalized_name$$}$(\n"
+ " int index, $type$.Builder builderForValue) {\n"
+ " copyOnWrite();\n"
+ " instance.set$capitalized_name$(index,\n"
+ " builderForValue.build());\n"
+ " return this;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+
+ // Builder addRepeatedField(Field value)
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public Builder "
+ "${$add$capitalized_name$$}$($type$ value) {\n"
+ " copyOnWrite();\n"
+ " instance.add$capitalized_name$(value);\n"
+ " return this;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+
+ // Builder addRepeatedField(int index, Field value)
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public Builder ${$add$capitalized_name$$}$(\n"
+ " int index, $type$ value) {\n"
+ " copyOnWrite();\n"
+ " instance.add$capitalized_name$(index, value);\n"
+ " return this;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ // Builder addRepeatedField(Field.Builder builderForValue)
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public Builder ${$add$capitalized_name$$}$(\n"
+ " $type$.Builder builderForValue) {\n"
+ " copyOnWrite();\n"
+ " instance.add$capitalized_name$(builderForValue.build());\n"
+ " return this;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+
+ // Builder addRepeatedField(int index, Field.Builder builderForValue)
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public Builder ${$add$capitalized_name$$}$(\n"
+ " int index, $type$.Builder builderForValue) {\n"
+ " copyOnWrite();\n"
+ " instance.add$capitalized_name$(index,\n"
+ " builderForValue.build());\n"
+ " return this;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+
+ // Builder addAllRepeatedField(Iterable<Field> values)
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public Builder ${$addAll$capitalized_name$$}$(\n"
+ " java.lang.Iterable<? extends $type$> values) {\n"
+ " copyOnWrite();\n"
+ " instance.addAll$capitalized_name$(values);\n"
+ " return this;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+
+ // Builder clearAllRepeatedField()
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n"
+ " copyOnWrite();\n"
+ " instance.clear$capitalized_name$();\n"
+ " return this;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+
+ // Builder removeRepeatedField(int index)
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$deprecation$public Builder "
+ "${$remove$capitalized_name$$}$(int index) {\n"
+ " copyOnWrite();\n"
+ " instance.remove$capitalized_name$(index);\n"
+ " return this;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+}
+
+void RepeatedImmutableMessageFieldLiteGenerator::GenerateFieldInfo(
+ io::Printer* printer, std::vector<uint16_t>* output) const {
+ WriteIntToUtf16CharSequence(descriptor_->number(), output);
+ WriteIntToUtf16CharSequence(GetExperimentalJavaFieldType(descriptor_),
+ output);
+ printer->Print(variables_,
+ "\"$name$_\",\n"
+ "$type$.class,\n");
+}
+
+void RepeatedImmutableMessageFieldLiteGenerator::GenerateInitializationCode(
+ io::Printer* printer) const {
+ printer->Print(variables_, "$name$_ = emptyProtobufList();\n");
+}
+
+std::string RepeatedImmutableMessageFieldLiteGenerator::GetBoxedType() const {
+ return name_resolver_->GetImmutableClassName(descriptor_->message_type());
+}
+
+void RepeatedImmutableMessageFieldLiteGenerator::GenerateKotlinDslMembers(
+ io::Printer* printer) const {
+ printer->Print(
+ variables_,
+ "/**\n"
+ " * An uninstantiable, behaviorless type to represent the field in\n"
+ " * generics.\n"
+ " */\n"
+ "@kotlin.OptIn"
+ "(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)\n"
+ "public class ${$$kt_capitalized_name$Proxy$}$ private constructor()"
+ " : com.google.protobuf.kotlin.DslProxy()\n");
+
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$kt_deprecation$ public val $kt_name$: "
+ "com.google.protobuf.kotlin.DslList"
+ "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>\n"
+ " @kotlin.jvm.JvmSynthetic\n"
+ " get() = com.google.protobuf.kotlin.DslList(\n"
+ " $kt_dsl_builder$.${$get$capitalized_name$List$}$()\n"
+ " )\n");
+
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_ADDER,
+ /* builder */ false);
+ printer->Print(variables_,
+ "@kotlin.jvm.JvmSynthetic\n"
+ "@kotlin.jvm.JvmName(\"add$kt_capitalized_name$\")\n"
+ "public fun com.google.protobuf.kotlin.DslList"
+ "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>."
+ "add(value: $kt_type$) {\n"
+ " $kt_dsl_builder$.${$add$capitalized_name$$}$(value)\n"
+ "}");
+
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_ADDER,
+ /* builder */ false);
+ printer->Print(variables_,
+ "@kotlin.jvm.JvmSynthetic\n"
+ "@kotlin.jvm.JvmName(\"plusAssign$kt_capitalized_name$\")\n"
+ "@Suppress(\"NOTHING_TO_INLINE\")\n"
+ "public inline operator fun com.google.protobuf.kotlin.DslList"
+ "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>."
+ "plusAssign(value: $kt_type$) {\n"
+ " add(value)\n"
+ "}");
+
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_MULTI_ADDER,
+ /* builder */ false);
+ printer->Print(variables_,
+ "@kotlin.jvm.JvmSynthetic\n"
+ "@kotlin.jvm.JvmName(\"addAll$kt_capitalized_name$\")\n"
+ "public fun com.google.protobuf.kotlin.DslList"
+ "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>."
+ "addAll(values: kotlin.collections.Iterable<$kt_type$>) {\n"
+ " $kt_dsl_builder$.${$addAll$capitalized_name$$}$(values)\n"
+ "}");
+
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_MULTI_ADDER,
+ /* builder */ false);
+ printer->Print(
+ variables_,
+ "@kotlin.jvm.JvmSynthetic\n"
+ "@kotlin.jvm.JvmName(\"plusAssignAll$kt_capitalized_name$\")\n"
+ "@Suppress(\"NOTHING_TO_INLINE\")\n"
+ "public inline operator fun com.google.protobuf.kotlin.DslList"
+ "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>."
+ "plusAssign(values: kotlin.collections.Iterable<$kt_type$>) {\n"
+ " addAll(values)\n"
+ "}");
+
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_SETTER,
+ /* builder */ false);
+ printer->Print(
+ variables_,
+ "@kotlin.jvm.JvmSynthetic\n"
+ "@kotlin.jvm.JvmName(\"set$kt_capitalized_name$\")\n"
+ "public operator fun com.google.protobuf.kotlin.DslList"
+ "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>."
+ "set(index: kotlin.Int, value: $kt_type$) {\n"
+ " $kt_dsl_builder$.${$set$capitalized_name$$}$(index, value)\n"
+ "}");
+
+ WriteFieldAccessorDocComment(printer, descriptor_, CLEARER,
+ /* builder */ false);
+ printer->Print(variables_,
+ "@kotlin.jvm.JvmSynthetic\n"
+ "@kotlin.jvm.JvmName(\"clear$kt_capitalized_name$\")\n"
+ "public fun com.google.protobuf.kotlin.DslList"
+ "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>."
+ "clear() {\n"
+ " $kt_dsl_builder$.${$clear$capitalized_name$$}$()\n"
+ "}");
+}
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_message_field_lite.h b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_message_field_lite.h
new file mode 100644
index 00000000..d34e61a5
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_message_field_lite.h
@@ -0,0 +1,140 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_MESSAGE_FIELD_LITE_H__
+#define GOOGLE_PROTOBUF_COMPILER_JAVA_MESSAGE_FIELD_LITE_H__
+
+#include <cstdint>
+#include <map>
+#include <string>
+
+#include <compiler/java/java_field.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+class Context; // context.h
+class ClassNameResolver; // name_resolver.h
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+class ImmutableMessageFieldLiteGenerator : public ImmutableFieldLiteGenerator {
+ public:
+ explicit ImmutableMessageFieldLiteGenerator(const FieldDescriptor* descriptor,
+ int messageBitIndex,
+ Context* context);
+ ~ImmutableMessageFieldLiteGenerator();
+
+ // implements ImmutableFieldLiteGenerator
+ // ------------------------------------
+ int GetNumBitsForMessage() const override;
+ void GenerateInterfaceMembers(io::Printer* printer) const override;
+ void GenerateMembers(io::Printer* printer) const override;
+ void GenerateBuilderMembers(io::Printer* printer) const override;
+ void GenerateInitializationCode(io::Printer* printer) const override;
+ void GenerateFieldInfo(io::Printer* printer,
+ std::vector<uint16_t>* output) const override;
+ void GenerateKotlinDslMembers(io::Printer* printer) const override;
+
+ std::string GetBoxedType() const override;
+
+ protected:
+ const FieldDescriptor* descriptor_;
+ std::map<std::string, std::string> variables_;
+ const int messageBitIndex_;
+ ClassNameResolver* name_resolver_;
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableMessageFieldLiteGenerator);
+};
+
+class ImmutableMessageOneofFieldLiteGenerator
+ : public ImmutableMessageFieldLiteGenerator {
+ public:
+ ImmutableMessageOneofFieldLiteGenerator(const FieldDescriptor* descriptor,
+ int messageBitIndex,
+ Context* context);
+ ~ImmutableMessageOneofFieldLiteGenerator();
+
+ void GenerateMembers(io::Printer* printer) const override;
+ void GenerateBuilderMembers(io::Printer* printer) const override;
+ void GenerateFieldInfo(io::Printer* printer,
+ std::vector<uint16_t>* output) const override;
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableMessageOneofFieldLiteGenerator);
+};
+
+class RepeatedImmutableMessageFieldLiteGenerator
+ : public ImmutableFieldLiteGenerator {
+ public:
+ explicit RepeatedImmutableMessageFieldLiteGenerator(
+ const FieldDescriptor* descriptor, int messageBitIndex, Context* context);
+ ~RepeatedImmutableMessageFieldLiteGenerator() override;
+
+ // implements ImmutableFieldLiteGenerator ------------------------------------
+ int GetNumBitsForMessage() const override;
+ void GenerateInterfaceMembers(io::Printer* printer) const override;
+ void GenerateMembers(io::Printer* printer) const override;
+ void GenerateBuilderMembers(io::Printer* printer) const override;
+ void GenerateInitializationCode(io::Printer* printer) const override;
+ void GenerateFieldInfo(io::Printer* printer,
+ std::vector<uint16_t>* output) const override;
+ void GenerateKotlinDslMembers(io::Printer* printer) const override;
+
+ std::string GetBoxedType() const override;
+
+ protected:
+ const FieldDescriptor* descriptor_;
+ std::map<std::string, std::string> variables_;
+ ClassNameResolver* name_resolver_;
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedImmutableMessageFieldLiteGenerator);
+};
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_MESSAGE_FIELD_LITE_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_message_lite.cc b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_message_lite.cc
new file mode 100644
index 00000000..a8196c2d
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_message_lite.cc
@@ -0,0 +1,977 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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: dweis@google.com (Daniel Weis)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <compiler/java/java_message_lite.h>
+
+#include <algorithm>
+#include <cstdint>
+#include <map>
+#include <memory>
+#include <vector>
+
+#include <compiler/java/java_context.h>
+#include <compiler/java/java_doc_comment.h>
+#include <compiler/java/java_enum_lite.h>
+#include <compiler/java/java_extension_lite.h>
+#include <compiler/java/java_generator_factory.h>
+#include <compiler/java/java_helpers.h>
+#include <compiler/java/java_message_builder.h>
+#include <compiler/java/java_message_builder_lite.h>
+#include <compiler/java/java_name_resolver.h>
+#include <descriptor.pb.h>
+#include <io/coded_stream.h>
+#include <io/printer.h>
+#include <wire_format.h>
+#include <stubs/strutil.h>
+#include <stubs/substitute.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+using internal::WireFormat;
+using internal::WireFormatLite;
+
+// ===================================================================
+ImmutableMessageLiteGenerator::ImmutableMessageLiteGenerator(
+ const Descriptor* descriptor, Context* context)
+ : MessageGenerator(descriptor),
+ context_(context),
+ name_resolver_(context->GetNameResolver()),
+ field_generators_(descriptor, context_) {
+ GOOGLE_CHECK(!HasDescriptorMethods(descriptor->file(), context->EnforceLite()))
+ << "Generator factory error: A lite message generator is used to "
+ "generate non-lite messages.";
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ if (IsRealOneof(descriptor_->field(i))) {
+ oneofs_.insert(descriptor_->field(i)->containing_oneof());
+ }
+ }
+}
+
+ImmutableMessageLiteGenerator::~ImmutableMessageLiteGenerator() {}
+
+void ImmutableMessageLiteGenerator::GenerateStaticVariables(
+ io::Printer* printer, int* bytecode_estimate) {
+ // Generate static members for all nested types.
+ for (int i = 0; i < descriptor_->nested_type_count(); i++) {
+ // TODO(kenton): Reuse MessageGenerator objects?
+ ImmutableMessageLiteGenerator(descriptor_->nested_type(i), context_)
+ .GenerateStaticVariables(printer, bytecode_estimate);
+ }
+}
+
+int ImmutableMessageLiteGenerator::GenerateStaticVariableInitializers(
+ io::Printer* printer) {
+ int bytecode_estimate = 0;
+ // Generate static member initializers for all nested types.
+ for (int i = 0; i < descriptor_->nested_type_count(); i++) {
+ // TODO(kenton): Reuse MessageGenerator objects?
+ bytecode_estimate +=
+ ImmutableMessageLiteGenerator(descriptor_->nested_type(i), context_)
+ .GenerateStaticVariableInitializers(printer);
+ }
+ return bytecode_estimate;
+}
+
+// ===================================================================
+
+void ImmutableMessageLiteGenerator::GenerateInterface(io::Printer* printer) {
+ MaybePrintGeneratedAnnotation(context_, printer, descriptor_,
+ /* immutable = */ true, "OrBuilder");
+ if (descriptor_->extension_range_count() > 0) {
+ printer->Print(
+ "$deprecation$public interface ${$$classname$OrBuilder$}$ extends \n"
+ " $extra_interfaces$\n"
+ " com.google.protobuf.GeneratedMessageLite.\n"
+ " ExtendableMessageOrBuilder<\n"
+ " $classname$, $classname$.Builder> {\n",
+ "deprecation",
+ descriptor_->options().deprecated() ? "@java.lang.Deprecated " : "",
+ "extra_interfaces", ExtraMessageOrBuilderInterfaces(descriptor_),
+ "classname", descriptor_->name(), "{", "", "}", "");
+ } else {
+ printer->Print(
+ "$deprecation$public interface ${$$classname$OrBuilder$}$ extends\n"
+ " $extra_interfaces$\n"
+ " com.google.protobuf.MessageLiteOrBuilder {\n",
+ "deprecation",
+ descriptor_->options().deprecated() ? "@java.lang.Deprecated " : "",
+ "extra_interfaces", ExtraMessageOrBuilderInterfaces(descriptor_),
+ "classname", descriptor_->name(), "{", "", "}", "");
+ }
+ printer->Annotate("{", "}", descriptor_);
+
+ printer->Indent();
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ printer->Print("\n");
+ field_generators_.get(descriptor_->field(i))
+ .GenerateInterfaceMembers(printer);
+ }
+ for (auto oneof : oneofs_) {
+ printer->Print(
+ "\n"
+ "public $classname$.$oneof_capitalized_name$Case "
+ "get$oneof_capitalized_name$Case();\n",
+ "oneof_capitalized_name",
+ context_->GetOneofGeneratorInfo(oneof)->capitalized_name, "classname",
+ context_->GetNameResolver()->GetImmutableClassName(descriptor_));
+ }
+ printer->Outdent();
+
+ printer->Print("}\n");
+}
+
+// ===================================================================
+
+void ImmutableMessageLiteGenerator::Generate(io::Printer* printer) {
+ bool is_own_file = IsOwnFile(descriptor_, /* immutable = */ true);
+
+ std::map<std::string, std::string> variables;
+ variables["static"] = is_own_file ? " " : " static ";
+ variables["classname"] = descriptor_->name();
+ variables["extra_interfaces"] = ExtraMessageInterfaces(descriptor_);
+ variables["deprecation"] =
+ descriptor_->options().deprecated() ? "@java.lang.Deprecated " : "";
+
+ WriteMessageDocComment(printer, descriptor_);
+ MaybePrintGeneratedAnnotation(context_, printer, descriptor_,
+ /* immutable = */ true);
+
+
+ // The builder_type stores the super type name of the nested Builder class.
+ std::string builder_type;
+ if (descriptor_->extension_range_count() > 0) {
+ printer->Print(
+ variables,
+ "$deprecation$public $static$final class $classname$ extends\n"
+ " com.google.protobuf.GeneratedMessageLite.ExtendableMessage<\n"
+ " $classname$, $classname$.Builder> implements\n"
+ " $extra_interfaces$\n"
+ " $classname$OrBuilder {\n");
+ builder_type = strings::Substitute(
+ "com.google.protobuf.GeneratedMessageLite.ExtendableBuilder<$0, ?>",
+ name_resolver_->GetImmutableClassName(descriptor_));
+ } else {
+ printer->Print(
+ variables,
+ "$deprecation$public $static$final class $classname$ extends\n"
+ " com.google.protobuf.GeneratedMessageLite<\n"
+ " $classname$, $classname$.Builder> implements\n"
+ " $extra_interfaces$\n"
+ " $classname$OrBuilder {\n");
+
+ builder_type = "com.google.protobuf.GeneratedMessageLite.Builder";
+ }
+ printer->Indent();
+
+ GenerateConstructor(printer);
+
+ // Nested types
+ for (int i = 0; i < descriptor_->enum_type_count(); i++) {
+ EnumLiteGenerator(descriptor_->enum_type(i), true, context_)
+ .Generate(printer);
+ }
+
+ for (int i = 0; i < descriptor_->nested_type_count(); i++) {
+ // Don't generate Java classes for map entry messages.
+ if (IsMapEntry(descriptor_->nested_type(i))) continue;
+ ImmutableMessageLiteGenerator messageGenerator(descriptor_->nested_type(i),
+ context_);
+ messageGenerator.GenerateInterface(printer);
+ messageGenerator.Generate(printer);
+ }
+
+ // Integers for bit fields.
+ int totalBits = 0;
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ totalBits +=
+ field_generators_.get(descriptor_->field(i)).GetNumBitsForMessage();
+ }
+ int totalInts = (totalBits + 31) / 32;
+ for (int i = 0; i < totalInts; i++) {
+ printer->Print("private int $bit_field_name$;\n", "bit_field_name",
+ GetBitFieldName(i));
+ }
+
+ // oneof
+ std::map<std::string, std::string> vars;
+ for (auto oneof : oneofs_) {
+ vars["oneof_name"] = context_->GetOneofGeneratorInfo(oneof)->name;
+ vars["oneof_capitalized_name"] =
+ context_->GetOneofGeneratorInfo(oneof)->capitalized_name;
+ vars["oneof_index"] = StrCat((oneof)->index());
+ // oneofCase_ and oneof_
+ printer->Print(vars,
+ "private int $oneof_name$Case_ = 0;\n"
+ "private java.lang.Object $oneof_name$_;\n");
+ // OneofCase enum
+ printer->Print(vars, "public enum $oneof_capitalized_name$Case {\n");
+ printer->Indent();
+ for (int j = 0; j < (oneof)->field_count(); j++) {
+ const FieldDescriptor* field = (oneof)->field(j);
+ printer->Print("$field_name$($field_number$),\n", "field_name",
+ ToUpper(field->name()), "field_number",
+ StrCat(field->number()));
+ }
+ printer->Print("$cap_oneof_name$_NOT_SET(0);\n", "cap_oneof_name",
+ ToUpper(vars["oneof_name"]));
+ printer->Print(vars,
+ "private final int value;\n"
+ "private $oneof_capitalized_name$Case(int value) {\n"
+ " this.value = value;\n"
+ "}\n");
+ printer->Print(
+ vars,
+ "/**\n"
+ " * @deprecated Use {@link #forNumber(int)} instead.\n"
+ " */\n"
+ "@java.lang.Deprecated\n"
+ "public static $oneof_capitalized_name$Case valueOf(int value) {\n"
+ " return forNumber(value);\n"
+ "}\n"
+ "\n"
+ "public static $oneof_capitalized_name$Case forNumber(int value) {\n"
+ " switch (value) {\n");
+ for (int j = 0; j < (oneof)->field_count(); j++) {
+ const FieldDescriptor* field = (oneof)->field(j);
+ printer->Print(" case $field_number$: return $field_name$;\n",
+ "field_number", StrCat(field->number()),
+ "field_name", ToUpper(field->name()));
+ }
+ printer->Print(
+ " case 0: return $cap_oneof_name$_NOT_SET;\n"
+ " default: return null;\n"
+ " }\n"
+ "}\n"
+ // TODO(b/135620659): Rename this to "getFieldNumber" or something to
+ // disambiguate it from actual proto enums.
+ "public int getNumber() {\n"
+ " return this.value;\n"
+ "}\n",
+ "cap_oneof_name", ToUpper(vars["oneof_name"]));
+ printer->Outdent();
+ printer->Print("};\n\n");
+ // oneofCase()
+ printer->Print(vars,
+ "@java.lang.Override\n"
+ "public $oneof_capitalized_name$Case\n"
+ "get$oneof_capitalized_name$Case() {\n"
+ " return $oneof_capitalized_name$Case.forNumber(\n"
+ " $oneof_name$Case_);\n"
+ "}\n"
+ "\n"
+ "private void clear$oneof_capitalized_name$() {\n"
+ " $oneof_name$Case_ = 0;\n"
+ " $oneof_name$_ = null;\n"
+ "}\n"
+ "\n");
+ }
+
+ // Fields
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ printer->Print("public static final int $constant_name$ = $number$;\n",
+ "constant_name", FieldConstantName(descriptor_->field(i)),
+ "number", StrCat(descriptor_->field(i)->number()));
+ field_generators_.get(descriptor_->field(i)).GenerateMembers(printer);
+ printer->Print("\n");
+ }
+
+ GenerateParseFromMethods(printer);
+ GenerateBuilder(printer);
+
+ if (HasRequiredFields(descriptor_)) {
+ // Memoizes whether the protocol buffer is fully initialized (has all
+ // required fields). 0 means false, 1 means true, and all other values
+ // mean not yet computed.
+ printer->Print("private byte memoizedIsInitialized = 2;\n");
+ }
+
+ printer->Print(
+ "@java.lang.Override\n"
+ "@java.lang.SuppressWarnings({\"unchecked\", \"fallthrough\"})\n"
+ "protected final java.lang.Object dynamicMethod(\n"
+ " com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,\n"
+ " java.lang.Object arg0, java.lang.Object arg1) {\n"
+ " switch (method) {\n"
+ " case NEW_MUTABLE_INSTANCE: {\n"
+ " return new $classname$();\n"
+ " }\n",
+ "classname", name_resolver_->GetImmutableClassName(descriptor_));
+
+ printer->Indent();
+ printer->Indent();
+
+ printer->Print("case NEW_BUILDER: {\n");
+
+ printer->Indent();
+ GenerateDynamicMethodNewBuilder(printer);
+ printer->Outdent();
+
+ printer->Print(
+ "}\n"
+ "case BUILD_MESSAGE_INFO: {\n");
+
+ printer->Indent();
+ GenerateDynamicMethodNewBuildMessageInfo(printer);
+ printer->Outdent();
+
+ printer->Print(
+ "}\n"
+ "// fall through\n"
+ "case GET_DEFAULT_INSTANCE: {\n"
+ " return DEFAULT_INSTANCE;\n"
+ "}\n"
+ "case GET_PARSER: {\n"
+ // Generally one would use the lazy initialization holder pattern for
+ // manipulating static fields but that has exceptional cost on Android as
+ // it will generate an extra class for every message. Instead, use the
+ // double-check locking pattern which works just as well.
+ //
+ // The "parser" temporary mirrors the "PARSER" field to eliminate a read
+ // at the final return statement.
+ " com.google.protobuf.Parser<$classname$> parser = PARSER;\n"
+ " if (parser == null) {\n"
+ " synchronized ($classname$.class) {\n"
+ " parser = PARSER;\n"
+ " if (parser == null) {\n"
+ " parser =\n"
+ " new DefaultInstanceBasedParser<$classname$>(\n"
+ " DEFAULT_INSTANCE);\n"
+ " PARSER = parser;\n"
+ " }\n"
+ " }\n"
+ " }\n"
+ " return parser;\n",
+ "classname", name_resolver_->GetImmutableClassName(descriptor_));
+
+ printer->Outdent();
+
+ if (HasRequiredFields(descriptor_)) {
+ printer->Print(
+ "}\n"
+ "case GET_MEMOIZED_IS_INITIALIZED: {\n"
+ " return memoizedIsInitialized;\n"
+ "}\n"
+ "case SET_MEMOIZED_IS_INITIALIZED: {\n"
+ " memoizedIsInitialized = (byte) (arg0 == null ? 0 : 1);\n"
+ " return null;\n"
+ "}\n");
+ } else {
+ printer->Print(
+ "}\n"
+ "case GET_MEMOIZED_IS_INITIALIZED: {\n"
+ " return (byte) 1;\n"
+ "}\n"
+ "case SET_MEMOIZED_IS_INITIALIZED: {\n"
+ " return null;\n"
+ "}\n");
+ }
+
+ printer->Outdent();
+ printer->Print(
+ " }\n"
+ " throw new UnsupportedOperationException();\n"
+ "}\n"
+ "\n",
+ "classname", name_resolver_->GetImmutableClassName(descriptor_));
+
+ printer->Print(
+ "\n"
+ "// @@protoc_insertion_point(class_scope:$full_name$)\n",
+ "full_name", descriptor_->full_name());
+
+ // Carefully initialize the default instance in such a way that it doesn't
+ // conflict with other initialization.
+ printer->Print("private static final $classname$ DEFAULT_INSTANCE;\n",
+ "classname",
+ name_resolver_->GetImmutableClassName(descriptor_));
+
+ printer->Print(
+ "static {\n"
+ " $classname$ defaultInstance = new $classname$();\n"
+ " // New instances are implicitly immutable so no need to make\n"
+ " // immutable.\n"
+ " DEFAULT_INSTANCE = defaultInstance;\n"
+ // Register the default instance in a map. This map will be used by
+ // experimental runtime to lookup default instance given a class instance
+ // without using Java reflection.
+ " com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(\n"
+ " $classname$.class, defaultInstance);\n"
+ "}\n"
+ "\n",
+ "classname", descriptor_->name());
+
+ printer->Print(
+ "public static $classname$ getDefaultInstance() {\n"
+ " return DEFAULT_INSTANCE;\n"
+ "}\n"
+ "\n",
+ "classname", name_resolver_->GetImmutableClassName(descriptor_));
+
+ // 'of' method for Wrappers
+ if (IsWrappersProtoFile(descriptor_->file())) {
+ printer->Print(
+ "public static $classname$ of($field_type$ value) {\n"
+ " return newBuilder().setValue(value).build();\n"
+ "}\n"
+ "\n",
+ "classname", name_resolver_->GetImmutableClassName(descriptor_),
+ "field_type", PrimitiveTypeName(GetJavaType(descriptor_->field(0))));
+ }
+
+ GenerateParser(printer);
+
+ // Extensions must be declared after the DEFAULT_INSTANCE is initialized
+ // because the DEFAULT_INSTANCE is used by the extension to lazily retrieve
+ // the outer class's FileDescriptor.
+ for (int i = 0; i < descriptor_->extension_count(); i++) {
+ ImmutableExtensionLiteGenerator(descriptor_->extension(i), context_)
+ .Generate(printer);
+ }
+
+ printer->Outdent();
+ printer->Print("}\n\n");
+}
+
+void ImmutableMessageLiteGenerator::GenerateDynamicMethodNewBuildMessageInfo(
+ io::Printer* printer) {
+ printer->Indent();
+
+ // Collect field info into a sequence of UTF-16 chars. It will be embedded
+ // as a Java string in the generated code.
+ std::vector<uint16_t> chars;
+
+ int flags = 0;
+ if (IsProto2(descriptor_->file())) {
+ flags |= 0x1;
+ }
+ if (descriptor_->options().message_set_wire_format()) {
+ flags |= 0x2;
+ }
+ WriteIntToUtf16CharSequence(flags, &chars);
+ WriteIntToUtf16CharSequence(descriptor_->field_count(), &chars);
+
+ if (descriptor_->field_count() == 0) {
+ printer->Print("java.lang.Object[] objects = null;");
+ } else {
+ // A single array of all fields (including oneof, oneofCase, hasBits).
+ printer->Print("java.lang.Object[] objects = new java.lang.Object[] {\n");
+ printer->Indent();
+
+ // Record the number of oneofs.
+ WriteIntToUtf16CharSequence(oneofs_.size(), &chars);
+ for (auto oneof : oneofs_) {
+ printer->Print(
+ "\"$oneof_name$_\",\n"
+ "\"$oneof_name$Case_\",\n",
+ "oneof_name", context_->GetOneofGeneratorInfo(oneof)->name);
+ }
+
+ // Integers for bit fields.
+ int total_bits = 0;
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ total_bits +=
+ field_generators_.get(descriptor_->field(i)).GetNumBitsForMessage();
+ }
+ int total_ints = (total_bits + 31) / 32;
+ for (int i = 0; i < total_ints; i++) {
+ printer->Print("\"$bit_field_name$\",\n", "bit_field_name",
+ GetBitFieldName(i));
+ }
+ WriteIntToUtf16CharSequence(total_ints, &chars);
+
+ int map_count = 0;
+ int repeated_count = 0;
+ std::unique_ptr<const FieldDescriptor*[]> sorted_fields(
+ SortFieldsByNumber(descriptor_));
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ const FieldDescriptor* field = sorted_fields[i];
+ if (field->is_map()) {
+ map_count++;
+ } else if (field->is_repeated()) {
+ repeated_count++;
+ }
+ }
+
+ WriteIntToUtf16CharSequence(sorted_fields[0]->number(), &chars);
+ WriteIntToUtf16CharSequence(
+ sorted_fields[descriptor_->field_count() - 1]->number(), &chars);
+ WriteIntToUtf16CharSequence(descriptor_->field_count(), &chars);
+ WriteIntToUtf16CharSequence(map_count, &chars);
+ WriteIntToUtf16CharSequence(repeated_count, &chars);
+
+ std::vector<const FieldDescriptor*> fields_for_is_initialized_check;
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ if (descriptor_->field(i)->is_required() ||
+ (GetJavaType(descriptor_->field(i)) == JAVATYPE_MESSAGE &&
+ HasRequiredFields(descriptor_->field(i)->message_type()))) {
+ fields_for_is_initialized_check.push_back(descriptor_->field(i));
+ }
+ }
+ WriteIntToUtf16CharSequence(fields_for_is_initialized_check.size(), &chars);
+
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ const FieldDescriptor* field = sorted_fields[i];
+ field_generators_.get(field).GenerateFieldInfo(printer, &chars);
+ }
+ printer->Outdent();
+ printer->Print("};\n");
+ }
+
+ printer->Print("java.lang.String info =\n");
+ std::string line;
+ for (size_t i = 0; i < chars.size(); i++) {
+ uint16_t code = chars[i];
+ EscapeUtf16ToString(code, &line);
+ if (line.size() >= 80) {
+ printer->Print(" \"$string$\" +\n", "string", line);
+ line.clear();
+ }
+ }
+ printer->Print(" \"$string$\";\n", "string", line);
+
+ printer->Print("return newMessageInfo(DEFAULT_INSTANCE, info, objects);\n");
+ printer->Outdent();
+}
+
+// ===================================================================
+
+void ImmutableMessageLiteGenerator::GenerateParseFromMethods(
+ io::Printer* printer) {
+ printer->Print(
+ "public static $classname$ parseFrom(\n"
+ " java.nio.ByteBuffer data)\n"
+ " throws com.google.protobuf.InvalidProtocolBufferException {\n"
+ " return com.google.protobuf.GeneratedMessageLite.parseFrom(\n"
+ " DEFAULT_INSTANCE, data);\n"
+ "}\n"
+ "public static $classname$ parseFrom(\n"
+ " java.nio.ByteBuffer data,\n"
+ " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
+ " throws com.google.protobuf.InvalidProtocolBufferException {\n"
+ " return com.google.protobuf.GeneratedMessageLite.parseFrom(\n"
+ " DEFAULT_INSTANCE, data, extensionRegistry);\n"
+ "}\n"
+ "public static $classname$ parseFrom(\n"
+ " com.google.protobuf.ByteString data)\n"
+ " throws com.google.protobuf.InvalidProtocolBufferException {\n"
+ " return com.google.protobuf.GeneratedMessageLite.parseFrom(\n"
+ " DEFAULT_INSTANCE, data);\n"
+ "}\n"
+ "public static $classname$ parseFrom(\n"
+ " com.google.protobuf.ByteString data,\n"
+ " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
+ " throws com.google.protobuf.InvalidProtocolBufferException {\n"
+ " return com.google.protobuf.GeneratedMessageLite.parseFrom(\n"
+ " DEFAULT_INSTANCE, data, extensionRegistry);\n"
+ "}\n"
+ "public static $classname$ parseFrom(byte[] data)\n"
+ " throws com.google.protobuf.InvalidProtocolBufferException {\n"
+ " return com.google.protobuf.GeneratedMessageLite.parseFrom(\n"
+ " DEFAULT_INSTANCE, data);\n"
+ "}\n"
+ "public static $classname$ parseFrom(\n"
+ " byte[] data,\n"
+ " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
+ " throws com.google.protobuf.InvalidProtocolBufferException {\n"
+ " return com.google.protobuf.GeneratedMessageLite.parseFrom(\n"
+ " DEFAULT_INSTANCE, data, extensionRegistry);\n"
+ "}\n"
+ "public static $classname$ parseFrom(java.io.InputStream input)\n"
+ " throws java.io.IOException {\n"
+ " return com.google.protobuf.GeneratedMessageLite.parseFrom(\n"
+ " DEFAULT_INSTANCE, input);\n"
+ "}\n"
+ "public static $classname$ parseFrom(\n"
+ " java.io.InputStream input,\n"
+ " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
+ " throws java.io.IOException {\n"
+ " return com.google.protobuf.GeneratedMessageLite.parseFrom(\n"
+ " DEFAULT_INSTANCE, input, extensionRegistry);\n"
+ "}\n"
+ "public static $classname$ parseDelimitedFrom(java.io.InputStream "
+ "input)\n"
+ " throws java.io.IOException {\n"
+ " return parseDelimitedFrom(DEFAULT_INSTANCE, input);\n"
+ "}\n"
+ "public static $classname$ parseDelimitedFrom(\n"
+ " java.io.InputStream input,\n"
+ " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
+ " throws java.io.IOException {\n"
+ " return parseDelimitedFrom(DEFAULT_INSTANCE, input, "
+ "extensionRegistry);\n"
+ "}\n"
+ "public static $classname$ parseFrom(\n"
+ " com.google.protobuf.CodedInputStream input)\n"
+ " throws java.io.IOException {\n"
+ " return com.google.protobuf.GeneratedMessageLite.parseFrom(\n"
+ " DEFAULT_INSTANCE, input);\n"
+ "}\n"
+ "public static $classname$ parseFrom(\n"
+ " com.google.protobuf.CodedInputStream input,\n"
+ " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
+ " throws java.io.IOException {\n"
+ " return com.google.protobuf.GeneratedMessageLite.parseFrom(\n"
+ " DEFAULT_INSTANCE, input, extensionRegistry);\n"
+ "}\n"
+ "\n",
+ "classname", name_resolver_->GetImmutableClassName(descriptor_));
+}
+
+// ===================================================================
+
+void ImmutableMessageLiteGenerator::GenerateBuilder(io::Printer* printer) {
+ printer->Print(
+ "public static Builder newBuilder() {\n"
+ " return (Builder) DEFAULT_INSTANCE.createBuilder();\n"
+ "}\n"
+ "public static Builder newBuilder($classname$ prototype) {\n"
+ " return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);\n"
+ "}\n"
+ "\n",
+ "classname", name_resolver_->GetImmutableClassName(descriptor_));
+
+ MessageBuilderLiteGenerator builderGenerator(descriptor_, context_);
+ builderGenerator.Generate(printer);
+}
+
+// ===================================================================
+
+void ImmutableMessageLiteGenerator::GenerateDynamicMethodNewBuilder(
+ io::Printer* printer) {
+ printer->Print("return new Builder();\n");
+}
+
+// ===================================================================
+
+void ImmutableMessageLiteGenerator::GenerateExtensionRegistrationCode(
+ io::Printer* printer) {
+ for (int i = 0; i < descriptor_->extension_count(); i++) {
+ ImmutableExtensionLiteGenerator(descriptor_->extension(i), context_)
+ .GenerateRegistrationCode(printer);
+ }
+
+ for (int i = 0; i < descriptor_->nested_type_count(); i++) {
+ ImmutableMessageLiteGenerator(descriptor_->nested_type(i), context_)
+ .GenerateExtensionRegistrationCode(printer);
+ }
+}
+
+// ===================================================================
+void ImmutableMessageLiteGenerator::GenerateConstructor(io::Printer* printer) {
+ printer->Print("private $classname$() {\n", "classname", descriptor_->name());
+ printer->Indent();
+
+ // Initialize all fields to default.
+ GenerateInitializers(printer);
+
+ printer->Outdent();
+ printer->Print("}\n");
+}
+
+// ===================================================================
+void ImmutableMessageLiteGenerator::GenerateParser(io::Printer* printer) {
+ printer->Print(
+ "private static volatile com.google.protobuf.Parser<$classname$> "
+ "PARSER;\n"
+ "\n"
+ "public static com.google.protobuf.Parser<$classname$> parser() {\n"
+ " return DEFAULT_INSTANCE.getParserForType();\n"
+ "}\n",
+ "classname", descriptor_->name());
+}
+
+// ===================================================================
+void ImmutableMessageLiteGenerator::GenerateInitializers(io::Printer* printer) {
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ if (!IsRealOneof(descriptor_->field(i))) {
+ field_generators_.get(descriptor_->field(i))
+ .GenerateInitializationCode(printer);
+ }
+ }
+}
+
+void ImmutableMessageLiteGenerator::GenerateKotlinDsl(
+ io::Printer* printer) const {
+ printer->Print(
+ "@kotlin.OptIn"
+ "(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)\n"
+ "@com.google.protobuf.kotlin.ProtoDslMarker\n");
+ printer->Print(
+ "public class Dsl private constructor(\n"
+ " private val _builder: $message$.Builder\n"
+ ") {\n"
+ " public companion object {\n"
+ " @kotlin.jvm.JvmSynthetic\n"
+ " @kotlin.PublishedApi\n"
+ " internal fun _create(builder: $message$.Builder): Dsl = "
+ "Dsl(builder)\n"
+ " }\n"
+ "\n"
+ " @kotlin.jvm.JvmSynthetic\n"
+ " @kotlin.PublishedApi\n"
+ " internal fun _build(): $message$ = _builder.build()\n",
+ "message", name_resolver_->GetClassName(descriptor_, true));
+
+ printer->Indent();
+
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ printer->Print("\n");
+ field_generators_.get(descriptor_->field(i))
+ .GenerateKotlinDslMembers(printer);
+ }
+
+ for (auto oneof : oneofs_) {
+ printer->Print(
+ "public val $oneof_name$Case: $message$.$oneof_capitalized_name$Case\n"
+ " @JvmName(\"get$oneof_capitalized_name$Case\")\n"
+ " get() = _builder.get$oneof_capitalized_name$Case()\n\n"
+ "public fun clear$oneof_capitalized_name$() {\n"
+ " _builder.clear$oneof_capitalized_name$()\n"
+ "}\n",
+ "oneof_name", context_->GetOneofGeneratorInfo(oneof)->name,
+ "oneof_capitalized_name",
+ context_->GetOneofGeneratorInfo(oneof)->capitalized_name, "message",
+ name_resolver_->GetClassName(descriptor_, true));
+ }
+
+ if (descriptor_->extension_range_count() > 0) {
+ GenerateKotlinExtensions(printer);
+ }
+
+ printer->Outdent();
+ printer->Print("}\n");
+}
+
+void ImmutableMessageLiteGenerator::GenerateKotlinMembers(
+ io::Printer* printer) const {
+ printer->Print(
+ "@kotlin.jvm.JvmSynthetic\n"
+ "public inline fun $camelcase_name$(block: $message_kt$.Dsl.() -> "
+ "kotlin.Unit): "
+ "$message$ =\n"
+ " $message_kt$.Dsl._create($message$.newBuilder()).apply { block() "
+ "}._build()\n",
+ "camelcase_name", name_resolver_->GetKotlinFactoryName(descriptor_),
+ "message_kt", name_resolver_->GetKotlinExtensionsClassName(descriptor_),
+ "message", name_resolver_->GetClassName(descriptor_, true));
+
+ printer->Print("public object $name$Kt {\n", "name", descriptor_->name());
+ printer->Indent();
+ GenerateKotlinDsl(printer);
+ for (int i = 0; i < descriptor_->nested_type_count(); i++) {
+ if (IsMapEntry(descriptor_->nested_type(i))) continue;
+ ImmutableMessageLiteGenerator(descriptor_->nested_type(i), context_)
+ .GenerateKotlinMembers(printer);
+ }
+ printer->Outdent();
+ printer->Print("}\n");
+}
+
+void ImmutableMessageLiteGenerator::GenerateTopLevelKotlinMembers(
+ io::Printer* printer) const {
+ printer->Print(
+ "public inline fun $message$.copy(block: $message_kt$.Dsl.() -> "
+ "kotlin.Unit): "
+ "$message$ =\n"
+ " $message_kt$.Dsl._create(this.toBuilder()).apply { block() "
+ "}._build()\n",
+ "message", name_resolver_->GetClassName(descriptor_, true), "message_kt",
+ name_resolver_->GetKotlinExtensionsClassName(descriptor_));
+
+ for (int i = 0; i < descriptor_->nested_type_count(); i++) {
+ if (IsMapEntry(descriptor_->nested_type(i))) continue;
+ ImmutableMessageLiteGenerator(descriptor_->nested_type(i), context_)
+ .GenerateTopLevelKotlinMembers(printer);
+ }
+}
+
+void ImmutableMessageLiteGenerator::GenerateKotlinExtensions(
+ io::Printer* printer) const {
+ std::string message_name = name_resolver_->GetClassName(descriptor_, true);
+
+ printer->Print(
+ "@Suppress(\"UNCHECKED_CAST\")\n"
+ "@kotlin.jvm.JvmSynthetic\n"
+ "public operator fun <T> get(extension: "
+ "com.google.protobuf.ExtensionLite<$message$, T>): T {\n"
+ " return if (extension.isRepeated) {\n"
+ " get(extension as com.google.protobuf.ExtensionLite<$message$, "
+ "List<*>>) as T\n"
+ " } else {\n"
+ " _builder.getExtension(extension)\n"
+ " }\n"
+ "}\n\n",
+ "message", message_name);
+
+ printer->Print(
+ "@kotlin.jvm.JvmSynthetic\n"
+ "@kotlin.OptIn"
+ "(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)\n"
+ "@kotlin.jvm.JvmName(\"-getRepeatedExtension\")\n"
+ "public operator fun <E> get(\n"
+ " extension: com.google.protobuf.ExtensionLite<$message$, List<E>>\n"
+ "): com.google.protobuf.kotlin.ExtensionList<E, $message$> {\n"
+ " return com.google.protobuf.kotlin.ExtensionList(extension, "
+ "_builder.getExtension(extension))\n"
+ "}\n\n",
+ "message", message_name);
+
+ printer->Print(
+ "@kotlin.jvm.JvmSynthetic\n"
+ "public operator fun contains(extension: "
+ "com.google.protobuf.ExtensionLite<$message$, *>): "
+ "Boolean {\n"
+ " return _builder.hasExtension(extension)\n"
+ "}\n\n",
+ "message", message_name);
+
+ printer->Print(
+ "@kotlin.jvm.JvmSynthetic\n"
+ "public fun clear(extension: "
+ "com.google.protobuf.ExtensionLite<$message$, *>) "
+ "{\n"
+ " _builder.clearExtension(extension)\n"
+ "}\n\n",
+ "message", message_name);
+
+ printer->Print(
+ "@kotlin.jvm.JvmSynthetic\n"
+ "@kotlin.PublishedApi\n"
+ "internal fun <T> setExtension(extension: "
+ "com.google.protobuf.ExtensionLite<$message$, T>, "
+ "value: T) {\n"
+ " _builder.setExtension(extension, value)\n"
+ "}\n\n",
+ "message", message_name);
+
+ printer->Print(
+ "@kotlin.jvm.JvmSynthetic\n"
+ "@Suppress(\"NOTHING_TO_INLINE\")\n"
+ "public inline operator fun <T : Comparable<T>> set(\n"
+ " extension: com.google.protobuf.ExtensionLite<$message$, T>,\n"
+ " value: T\n"
+ ") {\n"
+ " setExtension(extension, value)\n"
+ "}\n\n",
+ "message", message_name);
+
+ printer->Print(
+ "@kotlin.jvm.JvmSynthetic\n"
+ "@Suppress(\"NOTHING_TO_INLINE\")\n"
+ "public inline operator fun set(\n"
+ " extension: com.google.protobuf.ExtensionLite<$message$, "
+ "com.google.protobuf.ByteString>,\n"
+ " value: com.google.protobuf.ByteString\n"
+ ") {\n"
+ " setExtension(extension, value)\n"
+ "}\n\n",
+ "message", message_name);
+
+ printer->Print(
+ "@kotlin.jvm.JvmSynthetic\n"
+ "@Suppress(\"NOTHING_TO_INLINE\")\n"
+ "public inline operator fun <T : com.google.protobuf.MessageLite> set(\n"
+ " extension: com.google.protobuf.ExtensionLite<$message$, T>,\n"
+ " value: T\n"
+ ") {\n"
+ " setExtension(extension, value)\n"
+ "}\n\n",
+ "message", message_name);
+
+ printer->Print(
+ "@kotlin.jvm.JvmSynthetic\n"
+ "public fun<E> com.google.protobuf.kotlin.ExtensionList<E, "
+ "$message$>.add(value: E) {\n"
+ " _builder.addExtension(this.extension, value)\n"
+ "}\n\n",
+ "message", message_name);
+
+ printer->Print(
+ "@kotlin.jvm.JvmSynthetic\n"
+ "@Suppress(\"NOTHING_TO_INLINE\")\n"
+ "public inline operator fun <E> "
+ "com.google.protobuf.kotlin.ExtensionList<E, "
+ "$message$>.plusAssign"
+ "(value: E) {\n"
+ " add(value)\n"
+ "}\n\n",
+ "message", message_name);
+
+ printer->Print(
+ "@kotlin.jvm.JvmSynthetic\n"
+ "public fun<E> com.google.protobuf.kotlin.ExtensionList<E, "
+ "$message$>.addAll(values: Iterable<E>) {\n"
+ " for (value in values) {\n"
+ " add(value)\n"
+ " }\n"
+ "}\n\n",
+ "message", message_name);
+
+ printer->Print(
+ "@kotlin.jvm.JvmSynthetic\n"
+ "@Suppress(\"NOTHING_TO_INLINE\")\n"
+ "public inline operator fun <E> "
+ "com.google.protobuf.kotlin.ExtensionList<E, "
+ "$message$>.plusAssign(values: "
+ "Iterable<E>) {\n"
+ " addAll(values)\n"
+ "}\n\n",
+ "message", message_name);
+
+ printer->Print(
+ "@kotlin.jvm.JvmSynthetic\n"
+ "public operator fun <E> com.google.protobuf.kotlin.ExtensionList<E, "
+ "$message$>.set(index: Int, value: "
+ "E) {\n"
+ " _builder.setExtension(this.extension, index, value)\n"
+ "}\n\n",
+ "message", message_name);
+
+ printer->Print(
+ "@kotlin.jvm.JvmSynthetic\n"
+ "@Suppress(\"NOTHING_TO_INLINE\")\n"
+ "public inline fun com.google.protobuf.kotlin.ExtensionList<*, "
+ "$message$>.clear() {\n"
+ " clear(extension)\n"
+ "}\n\n",
+ "message", message_name);
+}
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_message_lite.h b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_message_lite.h
new file mode 100644
index 00000000..02f144bd
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_message_lite.h
@@ -0,0 +1,86 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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: dweis@google.com (Daniel Weis)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_MESSAGE_LITE_H__
+#define GOOGLE_PROTOBUF_COMPILER_JAVA_MESSAGE_LITE_H__
+
+#include <map>
+#include <string>
+#include <compiler/java/java_field.h>
+#include <compiler/java/java_message.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+class ImmutableMessageLiteGenerator : public MessageGenerator {
+ public:
+ ImmutableMessageLiteGenerator(const Descriptor* descriptor, Context* context);
+ virtual ~ImmutableMessageLiteGenerator();
+
+ void Generate(io::Printer* printer) override;
+ void GenerateInterface(io::Printer* printer) override;
+ void GenerateExtensionRegistrationCode(io::Printer* printer) override;
+ void GenerateStaticVariables(io::Printer* printer,
+ int* bytecode_estimate) override;
+ int GenerateStaticVariableInitializers(io::Printer* printer) override;
+ void GenerateKotlinDsl(io::Printer* printer) const override;
+ void GenerateKotlinMembers(io::Printer* printer) const override;
+ void GenerateTopLevelKotlinMembers(io::Printer* printer) const override;
+
+ private:
+ void GenerateParseFromMethods(io::Printer* printer);
+
+ void GenerateBuilder(io::Printer* printer);
+ void GenerateDynamicMethodNewBuilder(io::Printer* printer);
+ void GenerateInitializers(io::Printer* printer);
+ void GenerateParser(io::Printer* printer);
+ void GenerateConstructor(io::Printer* printer);
+ void GenerateDynamicMethodNewBuildMessageInfo(io::Printer* printer);
+ void GenerateKotlinExtensions(io::Printer* printer) const;
+
+ Context* context_;
+ ClassNameResolver* name_resolver_;
+ FieldGeneratorMap<ImmutableFieldLiteGenerator> field_generators_;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableMessageLiteGenerator);
+};
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_MESSAGE_LITE_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_name_resolver.cc b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_name_resolver.cc
new file mode 100644
index 00000000..2d753bc5
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_name_resolver.cc
@@ -0,0 +1,380 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 <compiler/java/java_name_resolver.h>
+
+#include <map>
+#include <string>
+
+#include <compiler/java/java_helpers.h>
+#include <compiler/java/java_names.h>
+#include <compiler/code_generator.h>
+#include <stubs/substitute.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+namespace {
+// A suffix that will be appended to the file's outer class name if the name
+// conflicts with some other types defined in the file.
+const char* kOuterClassNameSuffix = "OuterClass";
+
+// Strip package name from a descriptor's full name.
+// For example:
+// Full name : foo.Bar.Baz
+// Package name: foo
+// After strip : Bar.Baz
+std::string StripPackageName(const std::string& full_name,
+ const FileDescriptor* file) {
+ if (file->package().empty()) {
+ return full_name;
+ } else {
+ // Strip package name
+ return full_name.substr(file->package().size() + 1);
+ }
+}
+
+// Get the name of a message's Java class without package name prefix.
+std::string ClassNameWithoutPackage(const Descriptor* descriptor,
+ bool immutable) {
+ return StripPackageName(descriptor->full_name(), descriptor->file());
+}
+
+std::string ClassNameWithoutPackageKotlin(const Descriptor* descriptor) {
+ std::string result = descriptor->name();
+ const Descriptor* temp = descriptor->containing_type();
+
+ while (temp) {
+ result = temp->name() + "Kt." + result;
+ temp = temp->containing_type();
+ }
+ return result;
+}
+
+// Get the name of an enum's Java class without package name prefix.
+std::string ClassNameWithoutPackage(const EnumDescriptor* descriptor,
+ bool immutable) {
+ // Doesn't append "Mutable" for enum type's name.
+ const Descriptor* message_descriptor = descriptor->containing_type();
+ if (message_descriptor == NULL) {
+ return descriptor->name();
+ } else {
+ return ClassNameWithoutPackage(message_descriptor, immutable) + "." +
+ descriptor->name();
+ }
+}
+
+// Get the name of a service's Java class without package name prefix.
+std::string ClassNameWithoutPackage(const ServiceDescriptor* descriptor,
+ bool immutable) {
+ std::string full_name =
+ StripPackageName(descriptor->full_name(), descriptor->file());
+ // We don't allow nested service definitions.
+ GOOGLE_CHECK(full_name.find('.') == std::string::npos);
+ return full_name;
+}
+
+// Return true if a and b are equals (case insensitive).
+NameEquality CheckNameEquality(const std::string& a, const std::string& b) {
+ if (ToUpper(a) == ToUpper(b)) {
+ if (a == b) {
+ return NameEquality::EXACT_EQUAL;
+ }
+ return NameEquality::EQUAL_IGNORE_CASE;
+ }
+ return NameEquality::NO_MATCH;
+}
+
+// Check whether a given message or its nested types has the given class name.
+bool MessageHasConflictingClassName(const Descriptor* message,
+ const std::string& classname,
+ NameEquality equality_mode) {
+ if (CheckNameEquality(message->name(), classname) == equality_mode) {
+ return true;
+ }
+ for (int i = 0; i < message->nested_type_count(); ++i) {
+ if (MessageHasConflictingClassName(message->nested_type(i), classname,
+ equality_mode)) {
+ return true;
+ }
+ }
+ for (int i = 0; i < message->enum_type_count(); ++i) {
+ if (CheckNameEquality(message->enum_type(i)->name(), classname) ==
+ equality_mode) {
+ return true;
+ }
+ }
+ return false;
+}
+
+} // namespace
+
+ClassNameResolver::ClassNameResolver() {}
+
+ClassNameResolver::~ClassNameResolver() {}
+
+std::string ClassNameResolver::GetFileDefaultImmutableClassName(
+ const FileDescriptor* file) {
+ std::string basename;
+ std::string::size_type last_slash = file->name().find_last_of('/');
+ if (last_slash == std::string::npos) {
+ basename = file->name();
+ } else {
+ basename = file->name().substr(last_slash + 1);
+ }
+ return UnderscoresToCamelCase(StripProto(basename), true);
+}
+
+std::string ClassNameResolver::GetFileImmutableClassName(
+ const FileDescriptor* file) {
+ std::string& class_name = file_immutable_outer_class_names_[file];
+ if (class_name.empty()) {
+ if (file->options().has_java_outer_classname()) {
+ class_name = file->options().java_outer_classname();
+ } else {
+ class_name = GetFileDefaultImmutableClassName(file);
+ if (HasConflictingClassName(file, class_name,
+ NameEquality::EXACT_EQUAL)) {
+ class_name += kOuterClassNameSuffix;
+ }
+ }
+ }
+ return class_name;
+}
+
+std::string ClassNameResolver::GetFileClassName(const FileDescriptor* file,
+ bool immutable) {
+ return GetFileClassName(file, immutable, false);
+}
+
+std::string ClassNameResolver::GetFileClassName(const FileDescriptor* file,
+ bool immutable, bool kotlin) {
+ if (kotlin) {
+ return GetFileImmutableClassName(file) + "Kt";
+ } else if (immutable) {
+ return GetFileImmutableClassName(file);
+ } else {
+ return "Mutable" + GetFileImmutableClassName(file);
+ }
+}
+
+// Check whether there is any type defined in the proto file that has
+// the given class name.
+bool ClassNameResolver::HasConflictingClassName(const FileDescriptor* file,
+ const std::string& classname,
+ NameEquality equality_mode) {
+ for (int i = 0; i < file->enum_type_count(); i++) {
+ if (CheckNameEquality(file->enum_type(i)->name(), classname) ==
+ equality_mode) {
+ return true;
+ }
+ }
+ for (int i = 0; i < file->service_count(); i++) {
+ if (CheckNameEquality(file->service(i)->name(), classname) ==
+ equality_mode) {
+ return true;
+ }
+ }
+ for (int i = 0; i < file->message_type_count(); i++) {
+ if (MessageHasConflictingClassName(file->message_type(i), classname,
+ equality_mode)) {
+ return true;
+ }
+ }
+ return false;
+}
+
+std::string ClassNameResolver::GetDescriptorClassName(
+ const FileDescriptor* descriptor) {
+ return GetFileImmutableClassName(descriptor);
+}
+
+std::string ClassNameResolver::GetClassName(const FileDescriptor* descriptor,
+ bool immutable) {
+ return GetClassName(descriptor, immutable, false);
+}
+
+std::string ClassNameResolver::GetClassName(const FileDescriptor* descriptor,
+ bool immutable, bool kotlin) {
+ std::string result = FileJavaPackage(descriptor, immutable);
+ if (!result.empty()) result += '.';
+ result += GetFileClassName(descriptor, immutable, kotlin);
+ return result;
+}
+
+// Get the full name of a Java class by prepending the Java package name
+// or outer class name.
+std::string ClassNameResolver::GetClassFullName(
+ const std::string& name_without_package, const FileDescriptor* file,
+ bool immutable, bool is_own_file) {
+ return GetClassFullName(name_without_package, file, immutable, is_own_file,
+ false);
+}
+
+std::string ClassNameResolver::GetClassFullName(
+ const std::string& name_without_package, const FileDescriptor* file,
+ bool immutable, bool is_own_file, bool kotlin) {
+ std::string result;
+ if (is_own_file) {
+ result = FileJavaPackage(file, immutable);
+ } else {
+ result = GetClassName(file, immutable, kotlin);
+ }
+ if (!result.empty()) {
+ result += '.';
+ }
+ result += name_without_package;
+ if (kotlin) result += "Kt";
+ return result;
+}
+
+std::string ClassNameResolver::GetClassName(const Descriptor* descriptor,
+ bool immutable) {
+ return GetClassName(descriptor, immutable, false);
+}
+
+std::string ClassNameResolver::GetClassName(const Descriptor* descriptor,
+ bool immutable, bool kotlin) {
+ return GetClassFullName(
+ ClassNameWithoutPackage(descriptor, immutable), descriptor->file(),
+ immutable, MultipleJavaFiles(descriptor->file(), immutable), kotlin);
+}
+
+std::string ClassNameResolver::GetClassName(const EnumDescriptor* descriptor,
+ bool immutable) {
+ return GetClassName(descriptor, immutable, false);
+}
+
+std::string ClassNameResolver::GetClassName(const EnumDescriptor* descriptor,
+ bool immutable, bool kotlin) {
+ return GetClassFullName(
+ ClassNameWithoutPackage(descriptor, immutable), descriptor->file(),
+ immutable, MultipleJavaFiles(descriptor->file(), immutable), kotlin);
+}
+
+std::string ClassNameResolver::GetClassName(const ServiceDescriptor* descriptor,
+ bool immutable) {
+ return GetClassName(descriptor, immutable, false);
+}
+
+std::string ClassNameResolver::GetClassName(const ServiceDescriptor* descriptor,
+ bool immutable, bool kotlin) {
+ return GetClassFullName(ClassNameWithoutPackage(descriptor, immutable),
+ descriptor->file(), immutable,
+ IsOwnFile(descriptor, immutable), kotlin);
+}
+
+// Get the Java Class style full name of a message.
+std::string ClassNameResolver::GetJavaClassFullName(
+ const std::string& name_without_package, const FileDescriptor* file,
+ bool immutable) {
+ return GetJavaClassFullName(name_without_package, file, immutable, false);
+}
+
+std::string ClassNameResolver::GetJavaClassFullName(
+ const std::string& name_without_package, const FileDescriptor* file,
+ bool immutable, bool kotlin) {
+ std::string result;
+ if (MultipleJavaFiles(file, immutable)) {
+ result = FileJavaPackage(file, immutable);
+ if (!result.empty()) result += '.';
+ } else {
+ result = GetClassName(file, immutable, kotlin);
+ if (!result.empty()) result += '$';
+ }
+ result += StringReplace(name_without_package, ".", "$", true);
+ return result;
+}
+
+std::string ClassNameResolver::GetExtensionIdentifierName(
+ const FieldDescriptor* descriptor, bool immutable) {
+ return GetExtensionIdentifierName(descriptor, immutable, false);
+}
+
+std::string ClassNameResolver::GetExtensionIdentifierName(
+ const FieldDescriptor* descriptor, bool immutable, bool kotlin) {
+ return GetClassName(descriptor->containing_type(), immutable, kotlin) + "." +
+ descriptor->name();
+}
+
+std::string ClassNameResolver::GetKotlinFactoryName(
+ const Descriptor* descriptor) {
+ std::string name = ToCamelCase(descriptor->name(), /* lower_first = */ true);
+ return IsForbiddenKotlin(name) ? name + "_" : name;
+}
+
+std::string ClassNameResolver::GetJavaImmutableClassName(
+ const Descriptor* descriptor) {
+ return GetJavaClassFullName(ClassNameWithoutPackage(descriptor, true),
+ descriptor->file(), true);
+}
+
+std::string ClassNameResolver::GetJavaImmutableClassName(
+ const EnumDescriptor* descriptor) {
+ return GetJavaClassFullName(ClassNameWithoutPackage(descriptor, true),
+ descriptor->file(), true);
+}
+
+std::string ClassNameResolver::GetKotlinExtensionsClassName(
+ const Descriptor* descriptor) {
+ return GetClassFullName(ClassNameWithoutPackageKotlin(descriptor),
+ descriptor->file(), true, true, true);
+}
+
+std::string ClassNameResolver::GetJavaMutableClassName(
+ const Descriptor* descriptor) {
+ return GetJavaClassFullName(ClassNameWithoutPackage(descriptor, false),
+ descriptor->file(), false);
+}
+
+std::string ClassNameResolver::GetJavaMutableClassName(
+ const EnumDescriptor* descriptor) {
+ return GetJavaClassFullName(ClassNameWithoutPackage(descriptor, false),
+ descriptor->file(), false);
+}
+
+std::string ClassNameResolver::GetDowngradedFileClassName(
+ const FileDescriptor* file) {
+ return "Downgraded" + GetFileClassName(file, false);
+}
+
+std::string ClassNameResolver::GetDowngradedClassName(
+ const Descriptor* descriptor) {
+ return FileJavaPackage(descriptor->file()) + "." +
+ GetDowngradedFileClassName(descriptor->file()) + "." +
+ ClassNameWithoutPackage(descriptor, false);
+}
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_name_resolver.h b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_name_resolver.h
new file mode 100644
index 00000000..4d5a9bf6
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_name_resolver.h
@@ -0,0 +1,153 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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_COMPILER_JAVA_NAME_RESOLVER_H__
+#define GOOGLE_PROTOBUF_COMPILER_JAVA_NAME_RESOLVER_H__
+
+#include <map>
+#include <string>
+
+#include <stubs/common.h>
+
+namespace google {
+namespace protobuf {
+class Descriptor;
+class EnumDescriptor;
+class FieldDescriptor;
+class FileDescriptor;
+class ServiceDescriptor;
+
+namespace compiler {
+namespace java {
+
+// Indicates how closely the two class names match.
+enum NameEquality { NO_MATCH, EXACT_EQUAL, EQUAL_IGNORE_CASE };
+
+// Used to get the Java class related names for a given descriptor. It caches
+// the results to avoid redundant calculation across multiple name queries.
+// Thread-safety note: This class is *not* thread-safe.
+class ClassNameResolver {
+ public:
+ ClassNameResolver();
+ ~ClassNameResolver();
+
+ // Gets the unqualified outer class name for the file.
+ std::string GetFileClassName(const FileDescriptor* file, bool immutable);
+ std::string GetFileClassName(const FileDescriptor* file, bool immutable,
+ bool kotlin);
+ // Gets the unqualified immutable outer class name of a file.
+ std::string GetFileImmutableClassName(const FileDescriptor* file);
+ // Gets the unqualified default immutable outer class name of a file
+ // (converted from the proto file's name).
+ std::string GetFileDefaultImmutableClassName(const FileDescriptor* file);
+
+ // Check whether there is any type defined in the proto file that has
+ // the given class name.
+ bool HasConflictingClassName(const FileDescriptor* file,
+ const std::string& classname,
+ NameEquality equality_mode);
+
+ // Gets the name of the outer class that holds descriptor information.
+ // Descriptors are shared between immutable messages and mutable messages.
+ // Since both of them are generated optionally, the descriptors need to be
+ // put in another common place.
+ std::string GetDescriptorClassName(const FileDescriptor* file);
+
+ // Gets the fully-qualified class name corresponding to the given descriptor.
+ std::string GetClassName(const Descriptor* descriptor, bool immutable);
+ std::string GetClassName(const Descriptor* descriptor, bool immutable,
+ bool kotlin);
+ std::string GetClassName(const EnumDescriptor* descriptor, bool immutable);
+ std::string GetClassName(const EnumDescriptor* descriptor, bool immutable,
+ bool kotlin);
+ std::string GetClassName(const ServiceDescriptor* descriptor, bool immutable);
+ std::string GetClassName(const ServiceDescriptor* descriptor, bool immutable,
+ bool kotlin);
+ std::string GetClassName(const FileDescriptor* descriptor, bool immutable);
+ std::string GetClassName(const FileDescriptor* descriptor, bool immutable,
+ bool kotlin);
+
+ template <class DescriptorType>
+ std::string GetImmutableClassName(const DescriptorType* descriptor) {
+ return GetClassName(descriptor, true);
+ }
+ template <class DescriptorType>
+ std::string GetMutableClassName(const DescriptorType* descriptor) {
+ return GetClassName(descriptor, false);
+ }
+
+ // Gets the fully qualified name of an extension identifier.
+ std::string GetExtensionIdentifierName(const FieldDescriptor* descriptor,
+ bool immutable);
+ std::string GetExtensionIdentifierName(const FieldDescriptor* descriptor,
+ bool immutable, bool kotlin);
+
+ // Gets the fully qualified name for generated classes in Java convention.
+ // Nested classes will be separated using '$' instead of '.'
+ // For example:
+ // com.package.OuterClass$OuterMessage$InnerMessage
+ std::string GetJavaImmutableClassName(const Descriptor* descriptor);
+ std::string GetJavaImmutableClassName(const EnumDescriptor* descriptor);
+ std::string GetKotlinFactoryName(const Descriptor* descriptor);
+ std::string GetKotlinExtensionsClassName(const Descriptor* descriptor);
+ std::string GetJavaMutableClassName(const Descriptor* descriptor);
+ std::string GetJavaMutableClassName(const EnumDescriptor* descriptor);
+ // Gets the outer class and the actual class for downgraded mutable messages.
+ std::string GetDowngradedFileClassName(const FileDescriptor* file);
+ std::string GetDowngradedClassName(const Descriptor* descriptor);
+
+ private:
+ // Get the full name of a Java class by prepending the Java package name
+ // or outer class name.
+ std::string GetClassFullName(const std::string& name_without_package,
+ const FileDescriptor* file, bool immutable,
+ bool is_own_file);
+ std::string GetClassFullName(const std::string& name_without_package,
+ const FileDescriptor* file, bool immutable,
+ bool is_own_file, bool kotlin);
+ // Get the Java Class style full name of a message.
+ std::string GetJavaClassFullName(const std::string& name_without_package,
+ const FileDescriptor* file, bool immutable);
+ std::string GetJavaClassFullName(const std::string& name_without_package,
+ const FileDescriptor* file, bool immutable,
+ bool kotlin);
+ // Caches the result to provide better performance.
+ std::map<const FileDescriptor*, std::string>
+ file_immutable_outer_class_names_;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ClassNameResolver);
+};
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_NAME_RESOLVER_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_names.h b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_names.h
new file mode 100644
index 00000000..313ace4f
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_names.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: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// Provides a mechanism for mapping a descriptor to the
+// fully-qualified name of the corresponding Java class.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_NAMES_H__
+#define GOOGLE_PROTOBUF_COMPILER_JAVA_NAMES_H__
+
+#include <string>
+
+namespace google {
+namespace protobuf {
+
+class Descriptor;
+class EnumDescriptor;
+class FileDescriptor;
+class FieldDescriptor;
+class ServiceDescriptor;
+
+namespace compiler {
+namespace java {
+
+// Requires:
+// descriptor != NULL
+//
+// Returns:
+// The fully-qualified Java class name.
+std::string ClassName(const Descriptor* descriptor);
+
+// Requires:
+// descriptor != NULL
+//
+// Returns:
+// The fully-qualified Java class name.
+std::string ClassName(const EnumDescriptor* descriptor);
+
+// Requires:
+// descriptor != NULL
+//
+// Returns:
+// The fully-qualified Java class name.
+std::string ClassName(const FileDescriptor* descriptor);
+
+// Requires:
+// descriptor != NULL
+//
+// Returns:
+// The fully-qualified Java class name.
+std::string ClassName(const ServiceDescriptor* descriptor);
+
+// Requires:
+// descriptor != NULL
+//
+// Returns:
+// Java package name.
+std::string FileJavaPackage(const FileDescriptor* descriptor);
+
+// Requires:
+// descriptor != NULL
+// Returns:
+// Capitalized camel case name field name.
+std::string CapitalizedFieldName(const FieldDescriptor* descriptor);
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_NAMES_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_options.h b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_options.h
new file mode 100644
index 00000000..6c29be15
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_options.h
@@ -0,0 +1,73 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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_COMPILER_JAVA_OPTIONS_H__
+#define GOOGLE_PROTOBUF_COMPILER_JAVA_OPTIONS_H__
+
+#include <string>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+// Generator options
+struct Options {
+ Options()
+ : generate_immutable_code(false),
+ generate_mutable_code(false),
+ generate_shared_code(false),
+ enforce_lite(false),
+ annotate_code(false) {
+ }
+
+ bool generate_immutable_code;
+ bool generate_mutable_code;
+ bool generate_shared_code;
+ // When set, the protoc will generate the current files and all the transitive
+ // dependencies as lite runtime.
+ bool enforce_lite;
+ // If true, we should build .meta files and emit @Generated annotations into
+ // generated code.
+ bool annotate_code;
+ // Name of a file where we will write a list of generated .meta file names,
+ // one per line.
+ std::string annotation_list_file;
+ // Name of a file where we will write a list of generated file names, one
+ // per line.
+ std::string output_list_file;
+};
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_OPTIONS_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_plugin_unittest.cc b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_plugin_unittest.cc
new file mode 100644
index 00000000..22ae3f24
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_plugin_unittest.cc
@@ -0,0 +1,119 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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)
+//
+// TODO(kenton): Share code with the versions of this test in other languages?
+// It seemed like parameterizing it would add more complexity than it is
+// worth.
+
+#include <memory>
+
+#include <testing/file.h>
+#include <testing/file.h>
+#include <compiler/java/java_generator.h>
+#include <compiler/command_line_interface.h>
+#include <io/printer.h>
+#include <io/zero_copy_stream.h>
+#include <testing/googletest.h>
+#include <gtest/gtest.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+namespace {
+
+class TestGenerator : public CodeGenerator {
+ public:
+ TestGenerator() {}
+ ~TestGenerator() {}
+
+ virtual bool Generate(const FileDescriptor* file,
+ const std::string& parameter, GeneratorContext* context,
+ std::string* error) const {
+ std::string filename = "Test.java";
+ TryInsert(filename, "outer_class_scope", context);
+ TryInsert(filename, "class_scope:foo.Bar", context);
+ TryInsert(filename, "class_scope:foo.Bar.Baz", context);
+ TryInsert(filename, "builder_scope:foo.Bar", context);
+ TryInsert(filename, "builder_scope:foo.Bar.Baz", context);
+ TryInsert(filename, "enum_scope:foo.Qux", context);
+ return true;
+ }
+
+ void TryInsert(const std::string& filename,
+ const std::string& insertion_point,
+ GeneratorContext* context) const {
+ std::unique_ptr<io::ZeroCopyOutputStream> output(
+ context->OpenForInsert(filename, insertion_point));
+ io::Printer printer(output.get(), '$');
+ printer.Print("// inserted $name$\n", "name", insertion_point);
+ }
+};
+
+// This test verifies that all the expected insertion points exist. It does
+// not verify that they are correctly-placed; that would require actually
+// compiling the output which is a bit more than I care to do for this test.
+TEST(JavaPluginTest, PluginTest) {
+ GOOGLE_CHECK_OK(File::SetContents(TestTempDir() + "/test.proto",
+ "syntax = \"proto2\";\n"
+ "package foo;\n"
+ "option java_package = \"\";\n"
+ "option java_outer_classname = \"Test\";\n"
+ "message Bar {\n"
+ " message Baz {}\n"
+ "}\n"
+ "enum Qux { BLAH = 1; }\n",
+ true));
+
+ CommandLineInterface cli;
+ cli.SetInputsAreProtoPathRelative(true);
+
+ JavaGenerator java_generator;
+ TestGenerator test_generator;
+ cli.RegisterGenerator("--java_out", &java_generator, "");
+ cli.RegisterGenerator("--test_out", &test_generator, "");
+
+ std::string proto_path = "-I" + TestTempDir();
+ std::string java_out = "--java_out=" + TestTempDir();
+ std::string test_out = "--test_out=" + TestTempDir();
+
+ const char* argv[] = {"protoc", proto_path.c_str(), java_out.c_str(),
+ test_out.c_str(), "test.proto"};
+
+ EXPECT_EQ(0, cli.Run(5, argv));
+}
+
+} // namespace
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_primitive_field.cc b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_primitive_field.cc
new file mode 100644
index 00000000..23d00b28
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_primitive_field.cc
@@ -0,0 +1,1111 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 <compiler/java/java_primitive_field.h>
+
+#include <cstdint>
+#include <map>
+#include <string>
+
+#include <stubs/logging.h>
+#include <stubs/common.h>
+#include <compiler/java/java_context.h>
+#include <compiler/java/java_doc_comment.h>
+#include <compiler/java/java_helpers.h>
+#include <compiler/java/java_name_resolver.h>
+#include <io/printer.h>
+#include <wire_format.h>
+#include <stubs/strutil.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+using internal::WireFormat;
+
+namespace {
+
+void SetPrimitiveVariables(const FieldDescriptor* descriptor,
+ int messageBitIndex, int builderBitIndex,
+ const FieldGeneratorInfo* info,
+ ClassNameResolver* name_resolver,
+ std::map<std::string, std::string>* variables) {
+ SetCommonFieldVariables(descriptor, info, variables);
+ JavaType javaType = GetJavaType(descriptor);
+
+ (*variables)["type"] = PrimitiveTypeName(javaType);
+ (*variables)["boxed_type"] = BoxedPrimitiveTypeName(javaType);
+ (*variables)["kt_type"] = KotlinTypeName(javaType);
+ (*variables)["field_type"] = (*variables)["type"];
+
+ if (javaType == JAVATYPE_BOOLEAN || javaType == JAVATYPE_DOUBLE ||
+ javaType == JAVATYPE_FLOAT || javaType == JAVATYPE_INT ||
+ javaType == JAVATYPE_LONG) {
+ std::string capitalized_type = UnderscoresToCamelCase(
+ PrimitiveTypeName(javaType), /*cap_first_letter=*/true);
+ (*variables)["field_list_type"] =
+ "com.google.protobuf.Internal." + capitalized_type + "List";
+ (*variables)["empty_list"] = "empty" + capitalized_type + "List()";
+ (*variables)["create_list"] = "new" + capitalized_type + "List()";
+ (*variables)["mutable_copy_list"] =
+ "mutableCopy(" + (*variables)["name"] + "_)";
+ (*variables)["name_make_immutable"] =
+ (*variables)["name"] + "_.makeImmutable()";
+ (*variables)["repeated_get"] =
+ (*variables)["name"] + "_.get" + capitalized_type;
+ (*variables)["repeated_add"] =
+ (*variables)["name"] + "_.add" + capitalized_type;
+ (*variables)["repeated_set"] =
+ (*variables)["name"] + "_.set" + capitalized_type;
+ } else {
+ (*variables)["field_list_type"] =
+ "java.util.List<" + (*variables)["boxed_type"] + ">";
+ (*variables)["create_list"] =
+ "new java.util.ArrayList<" + (*variables)["boxed_type"] + ">()";
+ (*variables)["mutable_copy_list"] = "new java.util.ArrayList<" +
+ (*variables)["boxed_type"] + ">(" +
+ (*variables)["name"] + "_)";
+ (*variables)["empty_list"] = "java.util.Collections.emptyList()";
+ (*variables)["name_make_immutable"] =
+ (*variables)["name"] + "_ = java.util.Collections.unmodifiableList(" +
+ (*variables)["name"] + "_)";
+ (*variables)["repeated_get"] = (*variables)["name"] + "_.get";
+ (*variables)["repeated_add"] = (*variables)["name"] + "_.add";
+ (*variables)["repeated_set"] = (*variables)["name"] + "_.set";
+ }
+
+ (*variables)["default"] = ImmutableDefaultValue(descriptor, name_resolver);
+ (*variables)["default_init"] =
+ IsDefaultValueJavaDefault(descriptor)
+ ? ""
+ : ("= " + ImmutableDefaultValue(descriptor, name_resolver));
+ (*variables)["capitalized_type"] =
+ GetCapitalizedType(descriptor, /* immutable = */ true);
+ (*variables)["tag"] =
+ StrCat(static_cast<int32_t>(WireFormat::MakeTag(descriptor)));
+ (*variables)["tag_size"] = StrCat(
+ WireFormat::TagSize(descriptor->number(), GetType(descriptor)));
+ if (IsReferenceType(GetJavaType(descriptor))) {
+ (*variables)["null_check"] =
+ " if (value == null) {\n"
+ " throw new NullPointerException();\n"
+ " }\n";
+ } else {
+ (*variables)["null_check"] = "";
+ }
+ // TODO(birdo): Add @deprecated javadoc when generating javadoc is supported
+ // by the proto compiler
+ (*variables)["deprecation"] =
+ descriptor->options().deprecated() ? "@java.lang.Deprecated " : "";
+ (*variables)["kt_deprecation"] =
+ descriptor->options().deprecated()
+ ? "@kotlin.Deprecated(message = \"Field " + (*variables)["name"] +
+ " is deprecated\") "
+ : "";
+ int fixed_size = FixedSize(GetType(descriptor));
+ if (fixed_size != -1) {
+ (*variables)["fixed_size"] = StrCat(fixed_size);
+ }
+ (*variables)["on_changed"] = "onChanged();";
+
+ if (HasHasbit(descriptor)) {
+ // For singular messages and builders, one bit is used for the hasField bit.
+ (*variables)["get_has_field_bit_message"] = GenerateGetBit(messageBitIndex);
+ (*variables)["get_has_field_bit_builder"] = GenerateGetBit(builderBitIndex);
+
+ // Note that these have a trailing ";".
+ (*variables)["set_has_field_bit_message"] =
+ GenerateSetBit(messageBitIndex) + ";";
+ (*variables)["set_has_field_bit_builder"] =
+ GenerateSetBit(builderBitIndex) + ";";
+ (*variables)["clear_has_field_bit_builder"] =
+ GenerateClearBit(builderBitIndex) + ";";
+
+ (*variables)["is_field_present_message"] = GenerateGetBit(messageBitIndex);
+ } else {
+ (*variables)["set_has_field_bit_message"] = "";
+ (*variables)["set_has_field_bit_builder"] = "";
+ (*variables)["clear_has_field_bit_builder"] = "";
+
+ switch (descriptor->type()) {
+ case FieldDescriptor::TYPE_BYTES:
+ (*variables)["is_field_present_message"] =
+ "!" + (*variables)["name"] + "_.isEmpty()";
+ break;
+ case FieldDescriptor::TYPE_FLOAT:
+ (*variables)["is_field_present_message"] =
+ "java.lang.Float.floatToRawIntBits(" + (*variables)["name"] +
+ "_) != 0";
+ break;
+ case FieldDescriptor::TYPE_DOUBLE:
+ (*variables)["is_field_present_message"] =
+ "java.lang.Double.doubleToRawLongBits(" + (*variables)["name"] +
+ "_) != 0";
+ break;
+ default:
+ (*variables)["is_field_present_message"] =
+ (*variables)["name"] + "_ != " + (*variables)["default"];
+ break;
+ }
+ }
+
+ // For repeated builders, one bit is used for whether the array is immutable.
+ (*variables)["get_mutable_bit_builder"] = GenerateGetBit(builderBitIndex);
+ (*variables)["set_mutable_bit_builder"] = GenerateSetBit(builderBitIndex);
+ (*variables)["clear_mutable_bit_builder"] = GenerateClearBit(builderBitIndex);
+
+ // For repeated fields, one bit is used for whether the array is immutable
+ // in the parsing constructor.
+ (*variables)["get_mutable_bit_parser"] =
+ GenerateGetBitMutableLocal(builderBitIndex);
+ (*variables)["set_mutable_bit_parser"] =
+ GenerateSetBitMutableLocal(builderBitIndex);
+
+ (*variables)["get_has_field_bit_from_local"] =
+ GenerateGetBitFromLocal(builderBitIndex);
+ (*variables)["set_has_field_bit_to_local"] =
+ GenerateSetBitToLocal(messageBitIndex);
+}
+
+} // namespace
+
+// ===================================================================
+
+ImmutablePrimitiveFieldGenerator::ImmutablePrimitiveFieldGenerator(
+ const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex,
+ Context* context)
+ : descriptor_(descriptor), name_resolver_(context->GetNameResolver()) {
+ SetPrimitiveVariables(descriptor, messageBitIndex, builderBitIndex,
+ context->GetFieldGeneratorInfo(descriptor),
+ name_resolver_, &variables_);
+}
+
+ImmutablePrimitiveFieldGenerator::~ImmutablePrimitiveFieldGenerator() {}
+
+int ImmutablePrimitiveFieldGenerator::GetNumBitsForMessage() const {
+ return HasHasbit(descriptor_) ? 1 : 0;
+}
+
+int ImmutablePrimitiveFieldGenerator::GetNumBitsForBuilder() const {
+ return GetNumBitsForMessage();
+}
+
+void ImmutablePrimitiveFieldGenerator::GenerateInterfaceMembers(
+ io::Printer* printer) const {
+ if (HasHazzer(descriptor_)) {
+ WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
+ printer->Print(variables_,
+ "$deprecation$boolean has$capitalized_name$();\n");
+ }
+ WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
+ printer->Print(variables_, "$deprecation$$type$ get$capitalized_name$();\n");
+}
+
+void ImmutablePrimitiveFieldGenerator::GenerateMembers(
+ io::Printer* printer) const {
+ printer->Print(variables_, "private $field_type$ $name$_;\n");
+ PrintExtraFieldInfo(variables_, printer);
+ if (HasHazzer(descriptor_)) {
+ WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
+ printer->Print(
+ variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
+ " return $get_has_field_bit_message$;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ }
+
+ WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
+ printer->Print(variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
+ " return $name$_;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+}
+
+void ImmutablePrimitiveFieldGenerator::GenerateBuilderMembers(
+ io::Printer* printer) const {
+ printer->Print(variables_, "private $field_type$ $name$_ $default_init$;\n");
+
+ if (HasHazzer(descriptor_)) {
+ WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
+ printer->Print(
+ variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
+ " return $get_has_field_bit_builder$;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ }
+
+ WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
+ printer->Print(variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
+ " return $name$_;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+
+ WriteFieldAccessorDocComment(printer, descriptor_, SETTER,
+ /* builder */ true);
+ printer->Print(variables_,
+ "$deprecation$public Builder "
+ "${$set$capitalized_name$$}$($type$ value) {\n"
+ "$null_check$"
+ " $set_has_field_bit_builder$\n"
+ " $name$_ = value;\n"
+ " $on_changed$\n"
+ " return this;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+
+ WriteFieldAccessorDocComment(printer, descriptor_, CLEARER,
+ /* builder */ true);
+ printer->Print(
+ variables_,
+ "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n"
+ " $clear_has_field_bit_builder$\n");
+ printer->Annotate("{", "}", descriptor_);
+ JavaType type = GetJavaType(descriptor_);
+ if (type == JAVATYPE_STRING || type == JAVATYPE_BYTES) {
+ // The default value is not a simple literal so we want to avoid executing
+ // it multiple times. Instead, get the default out of the default instance.
+ printer->Print(
+ variables_,
+ " $name$_ = getDefaultInstance().get$capitalized_name$();\n");
+ } else {
+ printer->Print(variables_, " $name$_ = $default$;\n");
+ }
+ printer->Print(variables_,
+ " $on_changed$\n"
+ " return this;\n"
+ "}\n");
+}
+
+void ImmutablePrimitiveFieldGenerator::GenerateKotlinDslMembers(
+ io::Printer* printer) const {
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$kt_deprecation$public var $kt_name$: $kt_type$\n"
+ " @JvmName(\"${$get$kt_capitalized_name$$}$\")\n"
+ " get() = $kt_dsl_builder$.${$get$capitalized_name$$}$()\n"
+ " @JvmName(\"${$set$kt_capitalized_name$$}$\")\n"
+ " set(value) {\n"
+ " $kt_dsl_builder$.${$set$capitalized_name$$}$(value)\n"
+ " }\n");
+
+ WriteFieldAccessorDocComment(printer, descriptor_, CLEARER,
+ /* builder */ false);
+ printer->Print(variables_,
+ "public fun ${$clear$kt_capitalized_name$$}$() {\n"
+ " $kt_dsl_builder$.${$clear$capitalized_name$$}$()\n"
+ "}\n");
+
+ if (HasHazzer(descriptor_)) {
+ WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
+ printer->Print(
+ variables_,
+ "public fun ${$has$kt_capitalized_name$$}$(): kotlin.Boolean {\n"
+ " return $kt_dsl_builder$.${$has$capitalized_name$$}$()\n"
+ "}\n");
+ }
+}
+
+void ImmutablePrimitiveFieldGenerator::GenerateFieldBuilderInitializationCode(
+ io::Printer* printer) const {
+ // noop for primitives
+}
+
+void ImmutablePrimitiveFieldGenerator::GenerateInitializationCode(
+ io::Printer* printer) const {
+ if (!IsDefaultValueJavaDefault(descriptor_)) {
+ printer->Print(variables_, "$name$_ = $default$;\n");
+ }
+}
+
+void ImmutablePrimitiveFieldGenerator::GenerateBuilderClearCode(
+ io::Printer* printer) const {
+ printer->Print(variables_,
+ "$name$_ = $default$;\n"
+ "$clear_has_field_bit_builder$\n");
+}
+
+void ImmutablePrimitiveFieldGenerator::GenerateMergingCode(
+ io::Printer* printer) const {
+ if (HasHazzer(descriptor_)) {
+ printer->Print(variables_,
+ "if (other.has$capitalized_name$()) {\n"
+ " set$capitalized_name$(other.get$capitalized_name$());\n"
+ "}\n");
+ } else {
+ printer->Print(variables_,
+ "if (other.get$capitalized_name$() != $default$) {\n"
+ " set$capitalized_name$(other.get$capitalized_name$());\n"
+ "}\n");
+ }
+}
+
+void ImmutablePrimitiveFieldGenerator::GenerateBuildingCode(
+ io::Printer* printer) const {
+ if (HasHazzer(descriptor_)) {
+ if (IsDefaultValueJavaDefault(descriptor_)) {
+ printer->Print(variables_,
+ "if ($get_has_field_bit_from_local$) {\n"
+ " result.$name$_ = $name$_;\n"
+ " $set_has_field_bit_to_local$;\n"
+ "}\n");
+ } else {
+ printer->Print(variables_,
+ "if ($get_has_field_bit_from_local$) {\n"
+ " $set_has_field_bit_to_local$;\n"
+ "}\n"
+ "result.$name$_ = $name$_;\n");
+ }
+ } else {
+ printer->Print(variables_, "result.$name$_ = $name$_;\n");
+ }
+}
+
+void ImmutablePrimitiveFieldGenerator::GenerateParsingCode(
+ io::Printer* printer) const {
+ printer->Print(variables_,
+ "$set_has_field_bit_message$\n"
+ "$name$_ = input.read$capitalized_type$();\n");
+}
+
+void ImmutablePrimitiveFieldGenerator::GenerateParsingDoneCode(
+ io::Printer* printer) const {
+ // noop for primitives.
+}
+
+void ImmutablePrimitiveFieldGenerator::GenerateSerializationCode(
+ io::Printer* printer) const {
+ printer->Print(variables_,
+ "if ($is_field_present_message$) {\n"
+ " output.write$capitalized_type$($number$, $name$_);\n"
+ "}\n");
+}
+
+void ImmutablePrimitiveFieldGenerator::GenerateSerializedSizeCode(
+ io::Printer* printer) const {
+ printer->Print(variables_,
+ "if ($is_field_present_message$) {\n"
+ " size += com.google.protobuf.CodedOutputStream\n"
+ " .compute$capitalized_type$Size($number$, $name$_);\n"
+ "}\n");
+}
+
+void ImmutablePrimitiveFieldGenerator::GenerateEqualsCode(
+ io::Printer* printer) const {
+ switch (GetJavaType(descriptor_)) {
+ case JAVATYPE_INT:
+ case JAVATYPE_LONG:
+ case JAVATYPE_BOOLEAN:
+ printer->Print(variables_,
+ "if (get$capitalized_name$()\n"
+ " != other.get$capitalized_name$()) return false;\n");
+ break;
+
+ case JAVATYPE_FLOAT:
+ printer->Print(
+ variables_,
+ "if (java.lang.Float.floatToIntBits(get$capitalized_name$())\n"
+ " != java.lang.Float.floatToIntBits(\n"
+ " other.get$capitalized_name$())) return false;\n");
+ break;
+
+ case JAVATYPE_DOUBLE:
+ printer->Print(
+ variables_,
+ "if (java.lang.Double.doubleToLongBits(get$capitalized_name$())\n"
+ " != java.lang.Double.doubleToLongBits(\n"
+ " other.get$capitalized_name$())) return false;\n");
+ break;
+
+ case JAVATYPE_STRING:
+ case JAVATYPE_BYTES:
+ printer->Print(
+ variables_,
+ "if (!get$capitalized_name$()\n"
+ " .equals(other.get$capitalized_name$())) return false;\n");
+ break;
+
+ case JAVATYPE_ENUM:
+ case JAVATYPE_MESSAGE:
+ default:
+ GOOGLE_LOG(FATAL) << "Can't get here.";
+ break;
+ }
+}
+
+void ImmutablePrimitiveFieldGenerator::GenerateHashCode(
+ io::Printer* printer) const {
+ printer->Print(variables_, "hash = (37 * hash) + $constant_name$;\n");
+ switch (GetJavaType(descriptor_)) {
+ case JAVATYPE_INT:
+ printer->Print(variables_,
+ "hash = (53 * hash) + get$capitalized_name$();\n");
+ break;
+
+ case JAVATYPE_LONG:
+ printer->Print(
+ variables_,
+ "hash = (53 * hash) + com.google.protobuf.Internal.hashLong(\n"
+ " get$capitalized_name$());\n");
+ break;
+
+ case JAVATYPE_BOOLEAN:
+ printer->Print(
+ variables_,
+ "hash = (53 * hash) + com.google.protobuf.Internal.hashBoolean(\n"
+ " get$capitalized_name$());\n");
+ break;
+
+ case JAVATYPE_FLOAT:
+ printer->Print(variables_,
+ "hash = (53 * hash) + java.lang.Float.floatToIntBits(\n"
+ " get$capitalized_name$());\n");
+ break;
+
+ case JAVATYPE_DOUBLE:
+ printer->Print(
+ variables_,
+ "hash = (53 * hash) + com.google.protobuf.Internal.hashLong(\n"
+ " java.lang.Double.doubleToLongBits(get$capitalized_name$()));\n");
+ break;
+
+ case JAVATYPE_STRING:
+ case JAVATYPE_BYTES:
+ printer->Print(
+ variables_,
+ "hash = (53 * hash) + get$capitalized_name$().hashCode();\n");
+ break;
+
+ case JAVATYPE_ENUM:
+ case JAVATYPE_MESSAGE:
+ default:
+ GOOGLE_LOG(FATAL) << "Can't get here.";
+ break;
+ }
+}
+
+std::string ImmutablePrimitiveFieldGenerator::GetBoxedType() const {
+ return BoxedPrimitiveTypeName(GetJavaType(descriptor_));
+}
+
+// ===================================================================
+
+ImmutablePrimitiveOneofFieldGenerator::ImmutablePrimitiveOneofFieldGenerator(
+ const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex,
+ Context* context)
+ : ImmutablePrimitiveFieldGenerator(descriptor, messageBitIndex,
+ builderBitIndex, context) {
+ const OneofGeneratorInfo* info =
+ context->GetOneofGeneratorInfo(descriptor->containing_oneof());
+ SetCommonOneofVariables(descriptor, info, &variables_);
+}
+
+ImmutablePrimitiveOneofFieldGenerator::
+ ~ImmutablePrimitiveOneofFieldGenerator() {}
+
+void ImmutablePrimitiveOneofFieldGenerator::GenerateMembers(
+ io::Printer* printer) const {
+ PrintExtraFieldInfo(variables_, printer);
+ GOOGLE_DCHECK(HasHazzer(descriptor_));
+ WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
+ printer->Print(variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
+ " return $has_oneof_case_message$;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+
+ WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
+ printer->Print(variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
+ " if ($has_oneof_case_message$) {\n"
+ " return ($boxed_type$) $oneof_name$_;\n"
+ " }\n"
+ " return $default$;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+}
+
+void ImmutablePrimitiveOneofFieldGenerator::GenerateBuilderMembers(
+ io::Printer* printer) const {
+ GOOGLE_DCHECK(HasHazzer(descriptor_));
+ WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
+ printer->Print(variables_,
+ "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
+ " return $has_oneof_case_message$;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+
+ WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
+ printer->Print(variables_,
+ "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
+ " if ($has_oneof_case_message$) {\n"
+ " return ($boxed_type$) $oneof_name$_;\n"
+ " }\n"
+ " return $default$;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+
+ WriteFieldAccessorDocComment(printer, descriptor_, SETTER,
+ /* builder */ true);
+ printer->Print(variables_,
+ "$deprecation$public Builder "
+ "${$set$capitalized_name$$}$($type$ value) {\n"
+ "$null_check$"
+ " $set_oneof_case_message$;\n"
+ " $oneof_name$_ = value;\n"
+ " $on_changed$\n"
+ " return this;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+
+ WriteFieldAccessorDocComment(printer, descriptor_, CLEARER,
+ /* builder */ true);
+ printer->Print(
+ variables_,
+ "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n"
+ " if ($has_oneof_case_message$) {\n"
+ " $clear_oneof_case_message$;\n"
+ " $oneof_name$_ = null;\n"
+ " $on_changed$\n"
+ " }\n"
+ " return this;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+}
+
+void ImmutablePrimitiveOneofFieldGenerator::GenerateBuildingCode(
+ io::Printer* printer) const {
+ printer->Print(variables_,
+ "if ($has_oneof_case_message$) {\n"
+ " result.$oneof_name$_ = $oneof_name$_;\n"
+ "}\n");
+}
+
+void ImmutablePrimitiveOneofFieldGenerator::GenerateMergingCode(
+ io::Printer* printer) const {
+ printer->Print(variables_,
+ "set$capitalized_name$(other.get$capitalized_name$());\n");
+}
+
+void ImmutablePrimitiveOneofFieldGenerator::GenerateParsingCode(
+ io::Printer* printer) const {
+ printer->Print(variables_,
+ "$oneof_name$_ = input.read$capitalized_type$();\n"
+ "$set_oneof_case_message$;\n");
+}
+
+void ImmutablePrimitiveOneofFieldGenerator::GenerateSerializationCode(
+ io::Printer* printer) const {
+ printer->Print(variables_,
+ "if ($has_oneof_case_message$) {\n"
+ " output.write$capitalized_type$(\n");
+ // $type$ and $boxed_type$ is the same for bytes fields so we don't need to
+ // do redundant casts.
+ if (GetJavaType(descriptor_) == JAVATYPE_BYTES) {
+ printer->Print(variables_, " $number$, ($type$) $oneof_name$_);\n");
+ } else {
+ printer->Print(
+ variables_,
+ " $number$, ($type$)(($boxed_type$) $oneof_name$_));\n");
+ }
+ printer->Print("}\n");
+}
+
+void ImmutablePrimitiveOneofFieldGenerator::GenerateSerializedSizeCode(
+ io::Printer* printer) const {
+ printer->Print(variables_,
+ "if ($has_oneof_case_message$) {\n"
+ " size += com.google.protobuf.CodedOutputStream\n"
+ " .compute$capitalized_type$Size(\n");
+ // $type$ and $boxed_type$ is the same for bytes fields so we don't need to
+ // do redundant casts.
+ if (GetJavaType(descriptor_) == JAVATYPE_BYTES) {
+ printer->Print(variables_, " $number$, ($type$) $oneof_name$_);\n");
+ } else {
+ printer->Print(
+ variables_,
+ " $number$, ($type$)(($boxed_type$) $oneof_name$_));\n");
+ }
+ printer->Print("}\n");
+}
+
+// ===================================================================
+
+RepeatedImmutablePrimitiveFieldGenerator::
+ RepeatedImmutablePrimitiveFieldGenerator(const FieldDescriptor* descriptor,
+ int messageBitIndex,
+ int builderBitIndex,
+ Context* context)
+ : descriptor_(descriptor), name_resolver_(context->GetNameResolver()) {
+ SetPrimitiveVariables(descriptor, messageBitIndex, builderBitIndex,
+ context->GetFieldGeneratorInfo(descriptor),
+ name_resolver_, &variables_);
+}
+
+RepeatedImmutablePrimitiveFieldGenerator::
+ ~RepeatedImmutablePrimitiveFieldGenerator() {}
+
+int RepeatedImmutablePrimitiveFieldGenerator::GetNumBitsForMessage() const {
+ return 0;
+}
+
+int RepeatedImmutablePrimitiveFieldGenerator::GetNumBitsForBuilder() const {
+ return 1;
+}
+
+void RepeatedImmutablePrimitiveFieldGenerator::GenerateInterfaceMembers(
+ io::Printer* printer) const {
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_GETTER);
+ printer->Print(variables_,
+ "$deprecation$java.util.List<$boxed_type$> "
+ "get$capitalized_name$List();\n");
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_COUNT);
+ printer->Print(variables_,
+ "$deprecation$int get$capitalized_name$Count();\n");
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_GETTER);
+ printer->Print(variables_,
+ "$deprecation$$type$ get$capitalized_name$(int index);\n");
+}
+
+void RepeatedImmutablePrimitiveFieldGenerator::GenerateMembers(
+ io::Printer* printer) const {
+ printer->Print(variables_, "private $field_list_type$ $name$_;\n");
+ PrintExtraFieldInfo(variables_, printer);
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_GETTER);
+ printer->Print(variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public java.util.List<$boxed_type$>\n"
+ " ${$get$capitalized_name$List$}$() {\n"
+ " return $name$_;\n" // note: unmodifiable list
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_COUNT);
+ printer->Print(
+ variables_,
+ "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n"
+ " return $name$_.size();\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_GETTER);
+ printer->Print(
+ variables_,
+ "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n"
+ " return $repeated_get$(index);\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+
+ if (descriptor_->is_packed()) {
+ printer->Print(variables_,
+ "private int $name$MemoizedSerializedSize = -1;\n");
+ }
+}
+
+void RepeatedImmutablePrimitiveFieldGenerator::GenerateBuilderMembers(
+ io::Printer* printer) const {
+ // One field is the list and the bit field keeps track of whether the
+ // list is immutable. If it's immutable, the invariant is that it must
+ // either an instance of Collections.emptyList() or it's an ArrayList
+ // wrapped in a Collections.unmodifiableList() wrapper and nobody else has
+ // a reference to the underlying ArrayList. This invariant allows us to
+ // share instances of lists between protocol buffers avoiding expensive
+ // memory allocations. Note, immutable is a strong guarantee here -- not
+ // just that the list cannot be modified via the reference but that the
+ // list can never be modified.
+ printer->Print(variables_,
+ "private $field_list_type$ $name$_ = $empty_list$;\n");
+
+ printer->Print(variables_,
+ "private void ensure$capitalized_name$IsMutable() {\n"
+ " if (!$get_mutable_bit_builder$) {\n"
+ " $name$_ = $mutable_copy_list$;\n"
+ " $set_mutable_bit_builder$;\n"
+ " }\n"
+ "}\n");
+
+ // Note: We return an unmodifiable list because otherwise the caller
+ // could hold on to the returned list and modify it after the message
+ // has been built, thus mutating the message which is supposed to be
+ // immutable.
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_GETTER);
+ printer->Print(
+ variables_,
+ "$deprecation$public java.util.List<$boxed_type$>\n"
+ " ${$get$capitalized_name$List$}$() {\n"
+ " return $get_mutable_bit_builder$ ?\n"
+ " java.util.Collections.unmodifiableList($name$_) : $name$_;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_COUNT);
+ printer->Print(
+ variables_,
+ "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n"
+ " return $name$_.size();\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_GETTER);
+ printer->Print(
+ variables_,
+ "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n"
+ " return $repeated_get$(index);\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_SETTER,
+ /* builder */ true);
+ printer->Print(variables_,
+ "$deprecation$public Builder ${$set$capitalized_name$$}$(\n"
+ " int index, $type$ value) {\n"
+ "$null_check$"
+ " ensure$capitalized_name$IsMutable();\n"
+ " $repeated_set$(index, value);\n"
+ " $on_changed$\n"
+ " return this;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_ADDER,
+ /* builder */ true);
+ printer->Print(variables_,
+ "$deprecation$public Builder "
+ "${$add$capitalized_name$$}$($type$ value) {\n"
+ "$null_check$"
+ " ensure$capitalized_name$IsMutable();\n"
+ " $repeated_add$(value);\n"
+ " $on_changed$\n"
+ " return this;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_MULTI_ADDER,
+ /* builder */ true);
+ printer->Print(variables_,
+ "$deprecation$public Builder ${$addAll$capitalized_name$$}$(\n"
+ " java.lang.Iterable<? extends $boxed_type$> values) {\n"
+ " ensure$capitalized_name$IsMutable();\n"
+ " com.google.protobuf.AbstractMessageLite.Builder.addAll(\n"
+ " values, $name$_);\n"
+ " $on_changed$\n"
+ " return this;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldAccessorDocComment(printer, descriptor_, CLEARER,
+ /* builder */ true);
+ printer->Print(
+ variables_,
+ "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n"
+ " $name$_ = $empty_list$;\n"
+ " $clear_mutable_bit_builder$;\n"
+ " $on_changed$\n"
+ " return this;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+}
+
+void RepeatedImmutablePrimitiveFieldGenerator::GenerateKotlinDslMembers(
+ io::Printer* printer) const {
+ printer->Print(
+ variables_,
+ "/**\n"
+ " * An uninstantiable, behaviorless type to represent the field in\n"
+ " * generics.\n"
+ " */\n"
+ "@kotlin.OptIn"
+ "(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)\n"
+ "public class ${$$kt_capitalized_name$Proxy$}$ private constructor()"
+ " : com.google.protobuf.kotlin.DslProxy()\n");
+
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$kt_deprecation$ public val $kt_name$: "
+ "com.google.protobuf.kotlin.DslList"
+ "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>\n"
+ " @kotlin.jvm.JvmSynthetic\n"
+ " get() = com.google.protobuf.kotlin.DslList(\n"
+ " $kt_dsl_builder$.${$get$capitalized_name$List$}$()\n"
+ " )\n");
+
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_ADDER,
+ /* builder */ false);
+ printer->Print(variables_,
+ "@kotlin.jvm.JvmSynthetic\n"
+ "@kotlin.jvm.JvmName(\"add$kt_capitalized_name$\")\n"
+ "public fun com.google.protobuf.kotlin.DslList"
+ "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>."
+ "add(value: $kt_type$) {\n"
+ " $kt_dsl_builder$.${$add$capitalized_name$$}$(value)\n"
+ "}");
+
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_ADDER,
+ /* builder */ false);
+ printer->Print(variables_,
+ "@kotlin.jvm.JvmSynthetic\n"
+ "@kotlin.jvm.JvmName(\"plusAssign$kt_capitalized_name$\")\n"
+ "@Suppress(\"NOTHING_TO_INLINE\")\n"
+ "public inline operator fun com.google.protobuf.kotlin.DslList"
+ "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>."
+ "plusAssign(value: $kt_type$) {\n"
+ " add(value)\n"
+ "}");
+
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_MULTI_ADDER,
+ /* builder */ false);
+ printer->Print(variables_,
+ "@kotlin.jvm.JvmSynthetic\n"
+ "@kotlin.jvm.JvmName(\"addAll$kt_capitalized_name$\")\n"
+ "public fun com.google.protobuf.kotlin.DslList"
+ "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>."
+ "addAll(values: kotlin.collections.Iterable<$kt_type$>) {\n"
+ " $kt_dsl_builder$.${$addAll$capitalized_name$$}$(values)\n"
+ "}");
+
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_MULTI_ADDER,
+ /* builder */ false);
+ printer->Print(
+ variables_,
+ "@kotlin.jvm.JvmSynthetic\n"
+ "@kotlin.jvm.JvmName(\"plusAssignAll$kt_capitalized_name$\")\n"
+ "@Suppress(\"NOTHING_TO_INLINE\")\n"
+ "public inline operator fun com.google.protobuf.kotlin.DslList"
+ "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>."
+ "plusAssign(values: kotlin.collections.Iterable<$kt_type$>) {\n"
+ " addAll(values)\n"
+ "}");
+
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_SETTER,
+ /* builder */ false);
+ printer->Print(
+ variables_,
+ "@kotlin.jvm.JvmSynthetic\n"
+ "@kotlin.jvm.JvmName(\"set$kt_capitalized_name$\")\n"
+ "public operator fun com.google.protobuf.kotlin.DslList"
+ "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>."
+ "set(index: kotlin.Int, value: $kt_type$) {\n"
+ " $kt_dsl_builder$.${$set$capitalized_name$$}$(index, value)\n"
+ "}");
+
+ WriteFieldAccessorDocComment(printer, descriptor_, CLEARER,
+ /* builder */ false);
+ printer->Print(variables_,
+ "@kotlin.jvm.JvmSynthetic\n"
+ "@kotlin.jvm.JvmName(\"clear$kt_capitalized_name$\")\n"
+ "public fun com.google.protobuf.kotlin.DslList"
+ "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>."
+ "clear() {\n"
+ " $kt_dsl_builder$.${$clear$capitalized_name$$}$()\n"
+ "}");
+}
+
+void RepeatedImmutablePrimitiveFieldGenerator::
+ GenerateFieldBuilderInitializationCode(io::Printer* printer) const {
+ // noop for primitives
+}
+
+void RepeatedImmutablePrimitiveFieldGenerator::GenerateInitializationCode(
+ io::Printer* printer) const {
+ printer->Print(variables_, "$name$_ = $empty_list$;\n");
+}
+
+void RepeatedImmutablePrimitiveFieldGenerator::GenerateBuilderClearCode(
+ io::Printer* printer) const {
+ printer->Print(variables_,
+ "$name$_ = $empty_list$;\n"
+ "$clear_mutable_bit_builder$;\n");
+}
+
+void RepeatedImmutablePrimitiveFieldGenerator::GenerateMergingCode(
+ io::Printer* printer) const {
+ // The code below does two optimizations:
+ // 1. If the other list is empty, there's nothing to do. This ensures we
+ // don't allocate a new array if we already have an immutable one.
+ // 2. If the other list is non-empty and our current list is empty, we can
+ // reuse the other list which is guaranteed to be immutable.
+ printer->Print(variables_,
+ "if (!other.$name$_.isEmpty()) {\n"
+ " if ($name$_.isEmpty()) {\n"
+ " $name$_ = other.$name$_;\n"
+ " $clear_mutable_bit_builder$;\n"
+ " } else {\n"
+ " ensure$capitalized_name$IsMutable();\n"
+ " $name$_.addAll(other.$name$_);\n"
+ " }\n"
+ " $on_changed$\n"
+ "}\n");
+}
+
+void RepeatedImmutablePrimitiveFieldGenerator::GenerateBuildingCode(
+ io::Printer* printer) const {
+ // The code below ensures that the result has an immutable list. If our
+ // list is immutable, we can just reuse it. If not, we make it immutable.
+ printer->Print(variables_,
+ "if ($get_mutable_bit_builder$) {\n"
+ " $name_make_immutable$;\n"
+ " $clear_mutable_bit_builder$;\n"
+ "}\n"
+ "result.$name$_ = $name$_;\n");
+}
+
+void RepeatedImmutablePrimitiveFieldGenerator::GenerateParsingCode(
+ io::Printer* printer) const {
+ printer->Print(variables_,
+ "if (!$get_mutable_bit_parser$) {\n"
+ " $name$_ = $create_list$;\n"
+ " $set_mutable_bit_parser$;\n"
+ "}\n"
+ "$repeated_add$(input.read$capitalized_type$());\n");
+}
+
+void RepeatedImmutablePrimitiveFieldGenerator::GenerateParsingCodeFromPacked(
+ io::Printer* printer) const {
+ printer->Print(
+ variables_,
+ "int length = input.readRawVarint32();\n"
+ "int limit = input.pushLimit(length);\n"
+ "if (!$get_mutable_bit_parser$ && input.getBytesUntilLimit() > 0) {\n"
+ " $name$_ = $create_list$;\n"
+ " $set_mutable_bit_parser$;\n"
+ "}\n"
+ "while (input.getBytesUntilLimit() > 0) {\n"
+ " $repeated_add$(input.read$capitalized_type$());\n"
+ "}\n"
+ "input.popLimit(limit);\n");
+}
+
+void RepeatedImmutablePrimitiveFieldGenerator::GenerateParsingDoneCode(
+ io::Printer* printer) const {
+ printer->Print(variables_,
+ "if ($get_mutable_bit_parser$) {\n"
+ " $name_make_immutable$; // C\n"
+ "}\n");
+}
+
+void RepeatedImmutablePrimitiveFieldGenerator::GenerateSerializationCode(
+ io::Printer* printer) const {
+ if (descriptor_->is_packed()) {
+ // We invoke getSerializedSize in writeTo for messages that have packed
+ // fields in ImmutableMessageGenerator::GenerateMessageSerializationMethods.
+ // That makes it safe to rely on the memoized size here.
+ printer->Print(variables_,
+ "if (get$capitalized_name$List().size() > 0) {\n"
+ " output.writeUInt32NoTag($tag$);\n"
+ " output.writeUInt32NoTag($name$MemoizedSerializedSize);\n"
+ "}\n"
+ "for (int i = 0; i < $name$_.size(); i++) {\n"
+ " output.write$capitalized_type$NoTag($repeated_get$(i));\n"
+ "}\n");
+ } else {
+ printer->Print(
+ variables_,
+ "for (int i = 0; i < $name$_.size(); i++) {\n"
+ " output.write$capitalized_type$($number$, $repeated_get$(i));\n"
+ "}\n");
+ }
+}
+
+void RepeatedImmutablePrimitiveFieldGenerator::GenerateSerializedSizeCode(
+ io::Printer* printer) const {
+ printer->Print(variables_,
+ "{\n"
+ " int dataSize = 0;\n");
+ printer->Indent();
+
+ if (FixedSize(GetType(descriptor_)) == -1) {
+ printer->Print(
+ variables_,
+ "for (int i = 0; i < $name$_.size(); i++) {\n"
+ " dataSize += com.google.protobuf.CodedOutputStream\n"
+ " .compute$capitalized_type$SizeNoTag($repeated_get$(i));\n"
+ "}\n");
+ } else {
+ printer->Print(
+ variables_,
+ "dataSize = $fixed_size$ * get$capitalized_name$List().size();\n");
+ }
+
+ printer->Print("size += dataSize;\n");
+
+ if (descriptor_->is_packed()) {
+ printer->Print(variables_,
+ "if (!get$capitalized_name$List().isEmpty()) {\n"
+ " size += $tag_size$;\n"
+ " size += com.google.protobuf.CodedOutputStream\n"
+ " .computeInt32SizeNoTag(dataSize);\n"
+ "}\n");
+ } else {
+ printer->Print(
+ variables_,
+ "size += $tag_size$ * get$capitalized_name$List().size();\n");
+ }
+
+ // cache the data size for packed fields.
+ if (descriptor_->is_packed()) {
+ printer->Print(variables_, "$name$MemoizedSerializedSize = dataSize;\n");
+ }
+
+ printer->Outdent();
+ printer->Print("}\n");
+}
+
+void RepeatedImmutablePrimitiveFieldGenerator::GenerateEqualsCode(
+ io::Printer* printer) const {
+ printer->Print(
+ variables_,
+ "if (!get$capitalized_name$List()\n"
+ " .equals(other.get$capitalized_name$List())) return false;\n");
+}
+
+void RepeatedImmutablePrimitiveFieldGenerator::GenerateHashCode(
+ io::Printer* printer) const {
+ printer->Print(
+ variables_,
+ "if (get$capitalized_name$Count() > 0) {\n"
+ " hash = (37 * hash) + $constant_name$;\n"
+ " hash = (53 * hash) + get$capitalized_name$List().hashCode();\n"
+ "}\n");
+}
+
+std::string RepeatedImmutablePrimitiveFieldGenerator::GetBoxedType() const {
+ return BoxedPrimitiveTypeName(GetJavaType(descriptor_));
+}
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_primitive_field.h b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_primitive_field.h
new file mode 100644
index 00000000..2291ecb2
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_primitive_field.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.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_PRIMITIVE_FIELD_H__
+#define GOOGLE_PROTOBUF_COMPILER_JAVA_PRIMITIVE_FIELD_H__
+
+#include <map>
+#include <string>
+#include <compiler/java/java_field.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+class Context; // context.h
+class ClassNameResolver; // name_resolver.h
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+class ImmutablePrimitiveFieldGenerator : public ImmutableFieldGenerator {
+ public:
+ explicit ImmutablePrimitiveFieldGenerator(const FieldDescriptor* descriptor,
+ int messageBitIndex,
+ int builderBitIndex,
+ Context* context);
+ ~ImmutablePrimitiveFieldGenerator() override;
+
+ // implements ImmutableFieldGenerator
+ // ---------------------------------------
+ int GetNumBitsForMessage() const override;
+ int GetNumBitsForBuilder() const override;
+ void GenerateInterfaceMembers(io::Printer* printer) const override;
+ void GenerateMembers(io::Printer* printer) const override;
+ void GenerateBuilderMembers(io::Printer* printer) const override;
+ void GenerateInitializationCode(io::Printer* printer) const override;
+ void GenerateBuilderClearCode(io::Printer* printer) const override;
+ void GenerateMergingCode(io::Printer* printer) const override;
+ void GenerateBuildingCode(io::Printer* printer) const override;
+ void GenerateParsingCode(io::Printer* printer) const override;
+ void GenerateParsingDoneCode(io::Printer* printer) const override;
+ void GenerateSerializationCode(io::Printer* printer) const override;
+ void GenerateSerializedSizeCode(io::Printer* printer) const override;
+ void GenerateFieldBuilderInitializationCode(
+ io::Printer* printer) const override;
+ void GenerateEqualsCode(io::Printer* printer) const override;
+ void GenerateHashCode(io::Printer* printer) const override;
+ void GenerateKotlinDslMembers(io::Printer* printer) const override;
+
+ std::string GetBoxedType() const override;
+
+ protected:
+ const FieldDescriptor* descriptor_;
+ std::map<std::string, std::string> variables_;
+ ClassNameResolver* name_resolver_;
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutablePrimitiveFieldGenerator);
+};
+
+class ImmutablePrimitiveOneofFieldGenerator
+ : public ImmutablePrimitiveFieldGenerator {
+ public:
+ ImmutablePrimitiveOneofFieldGenerator(const FieldDescriptor* descriptor,
+ int messageBitIndex,
+ int builderBitIndex, Context* context);
+ ~ImmutablePrimitiveOneofFieldGenerator();
+
+ void GenerateMembers(io::Printer* printer) const override;
+ void GenerateBuilderMembers(io::Printer* printer) const override;
+ void GenerateBuildingCode(io::Printer* printer) const override;
+ void GenerateMergingCode(io::Printer* printer) const override;
+ void GenerateParsingCode(io::Printer* printer) const override;
+ void GenerateSerializationCode(io::Printer* printer) const override;
+ void GenerateSerializedSizeCode(io::Printer* printer) const override;
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutablePrimitiveOneofFieldGenerator);
+};
+
+class RepeatedImmutablePrimitiveFieldGenerator
+ : public ImmutableFieldGenerator {
+ public:
+ explicit RepeatedImmutablePrimitiveFieldGenerator(
+ const FieldDescriptor* descriptor, int messageBitIndex,
+ int builderBitIndex, Context* context);
+ ~RepeatedImmutablePrimitiveFieldGenerator() override;
+
+ // implements ImmutableFieldGenerator ---------------------------------------
+ int GetNumBitsForMessage() const override;
+ int GetNumBitsForBuilder() const override;
+ void GenerateInterfaceMembers(io::Printer* printer) const override;
+ void GenerateMembers(io::Printer* printer) const override;
+ void GenerateBuilderMembers(io::Printer* printer) const override;
+ void GenerateInitializationCode(io::Printer* printer) const override;
+ void GenerateBuilderClearCode(io::Printer* printer) const override;
+ void GenerateMergingCode(io::Printer* printer) const override;
+ void GenerateBuildingCode(io::Printer* printer) const override;
+ void GenerateParsingCode(io::Printer* printer) const override;
+ void GenerateParsingCodeFromPacked(io::Printer* printer) const override;
+ void GenerateParsingDoneCode(io::Printer* printer) const override;
+ void GenerateSerializationCode(io::Printer* printer) const override;
+ void GenerateSerializedSizeCode(io::Printer* printer) const override;
+ void GenerateFieldBuilderInitializationCode(
+ io::Printer* printer) const override;
+ void GenerateEqualsCode(io::Printer* printer) const override;
+ void GenerateHashCode(io::Printer* printer) const override;
+ void GenerateKotlinDslMembers(io::Printer* printer) const override;
+
+ std::string GetBoxedType() const override;
+
+ private:
+ const FieldDescriptor* descriptor_;
+ std::map<std::string, std::string> variables_;
+ ClassNameResolver* name_resolver_;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedImmutablePrimitiveFieldGenerator);
+};
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_PRIMITIVE_FIELD_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_primitive_field_lite.cc b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_primitive_field_lite.cc
new file mode 100644
index 00000000..7b680a70
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_primitive_field_lite.cc
@@ -0,0 +1,779 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <compiler/java/java_primitive_field_lite.h>
+
+#include <cstdint>
+#include <map>
+#include <string>
+
+#include <stubs/logging.h>
+#include <stubs/common.h>
+#include <compiler/java/java_context.h>
+#include <compiler/java/java_doc_comment.h>
+#include <compiler/java/java_helpers.h>
+#include <compiler/java/java_name_resolver.h>
+#include <io/printer.h>
+#include <wire_format.h>
+#include <stubs/strutil.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+using internal::WireFormat;
+using internal::WireFormatLite;
+
+namespace {
+bool EnableExperimentalRuntimeForLite() {
+#ifdef PROTOBUF_EXPERIMENT
+ return PROTOBUF_EXPERIMENT;
+#else // PROTOBUF_EXPERIMENT
+ return false;
+#endif // !PROTOBUF_EXPERIMENT
+}
+
+void SetPrimitiveVariables(const FieldDescriptor* descriptor,
+ int messageBitIndex, int builderBitIndex,
+ const FieldGeneratorInfo* info,
+ ClassNameResolver* name_resolver,
+ std::map<std::string, std::string>* variables) {
+ SetCommonFieldVariables(descriptor, info, variables);
+ JavaType javaType = GetJavaType(descriptor);
+ (*variables)["type"] = PrimitiveTypeName(javaType);
+ (*variables)["boxed_type"] = BoxedPrimitiveTypeName(javaType);
+ (*variables)["kt_type"] = KotlinTypeName(javaType);
+ (*variables)["field_type"] = (*variables)["type"];
+ (*variables)["default"] = ImmutableDefaultValue(descriptor, name_resolver);
+ (*variables)["capitalized_type"] =
+ GetCapitalizedType(descriptor, /* immutable = */ true);
+ (*variables)["tag"] =
+ StrCat(static_cast<int32_t>(WireFormat::MakeTag(descriptor)));
+ (*variables)["tag_size"] = StrCat(
+ WireFormat::TagSize(descriptor->number(), GetType(descriptor)));
+ (*variables)["required"] = descriptor->is_required() ? "true" : "false";
+
+ std::string capitalized_type = UnderscoresToCamelCase(
+ PrimitiveTypeName(javaType), true /* cap_next_letter */);
+ switch (javaType) {
+ case JAVATYPE_INT:
+ case JAVATYPE_LONG:
+ case JAVATYPE_FLOAT:
+ case JAVATYPE_DOUBLE:
+ case JAVATYPE_BOOLEAN:
+ (*variables)["field_list_type"] =
+ "com.google.protobuf.Internal." + capitalized_type + "List";
+ (*variables)["empty_list"] = "empty" + capitalized_type + "List()";
+ (*variables)["make_name_unmodifiable"] =
+ (*variables)["name"] + "_.makeImmutable()";
+ (*variables)["repeated_get"] =
+ (*variables)["name"] + "_.get" + capitalized_type;
+ (*variables)["repeated_add"] =
+ (*variables)["name"] + "_.add" + capitalized_type;
+ (*variables)["repeated_set"] =
+ (*variables)["name"] + "_.set" + capitalized_type;
+ (*variables)["visit_type"] = capitalized_type;
+ (*variables)["visit_type_list"] = "visit" + capitalized_type + "List";
+ break;
+ default:
+ (*variables)["field_list_type"] =
+ "com.google.protobuf.Internal.ProtobufList<" +
+ (*variables)["boxed_type"] + ">";
+ (*variables)["empty_list"] = "emptyProtobufList()";
+ (*variables)["make_name_unmodifiable"] =
+ (*variables)["name"] + "_.makeImmutable()";
+ (*variables)["repeated_get"] = (*variables)["name"] + "_.get";
+ (*variables)["repeated_add"] = (*variables)["name"] + "_.add";
+ (*variables)["repeated_set"] = (*variables)["name"] + "_.set";
+ (*variables)["visit_type"] = "ByteString";
+ (*variables)["visit_type_list"] = "visitList";
+ }
+
+ if (javaType == JAVATYPE_BYTES) {
+ (*variables)["bytes_default"] =
+ ToUpper((*variables)["name"]) + "_DEFAULT_VALUE";
+ }
+
+ if (IsReferenceType(javaType)) {
+ // We use `x.getClass()` as a null check because it generates less bytecode
+ // than an `if (x == null) { throw ... }` statement.
+ (*variables)["null_check"] =
+ " java.lang.Class<?> valueClass = value.getClass();\n";
+ } else {
+ (*variables)["null_check"] = "";
+ }
+ // TODO(birdo): Add @deprecated javadoc when generating javadoc is supported
+ // by the proto compiler
+ (*variables)["deprecation"] =
+ descriptor->options().deprecated() ? "@java.lang.Deprecated " : "";
+ (*variables)["kt_deprecation"] =
+ descriptor->options().deprecated()
+ ? "@kotlin.Deprecated(message = \"Field " + (*variables)["name"] +
+ " is deprecated\") "
+ : "";
+ int fixed_size = FixedSize(GetType(descriptor));
+ if (fixed_size != -1) {
+ (*variables)["fixed_size"] = StrCat(fixed_size);
+ }
+
+ if (HasHasbit(descriptor)) {
+ // For singular messages and builders, one bit is used for the hasField bit.
+ (*variables)["get_has_field_bit_message"] = GenerateGetBit(messageBitIndex);
+
+ // Note that these have a trailing ";".
+ (*variables)["set_has_field_bit_message"] =
+ GenerateSetBit(messageBitIndex) + ";";
+ (*variables)["clear_has_field_bit_message"] =
+ GenerateClearBit(messageBitIndex) + ";";
+
+ (*variables)["is_field_present_message"] = GenerateGetBit(messageBitIndex);
+ } else {
+ (*variables)["set_has_field_bit_message"] = "";
+ (*variables)["set_has_field_bit_message"] = "";
+ (*variables)["clear_has_field_bit_message"] = "";
+
+ switch (descriptor->type()) {
+ case FieldDescriptor::TYPE_BYTES:
+ (*variables)["is_field_present_message"] =
+ "!" + (*variables)["name"] + "_.isEmpty()";
+ break;
+ case FieldDescriptor::TYPE_FLOAT:
+ (*variables)["is_field_present_message"] =
+ "java.lang.Float.floatToRawIntBits(" + (*variables)["name"] +
+ "_) != 0";
+ break;
+ case FieldDescriptor::TYPE_DOUBLE:
+ (*variables)["is_field_present_message"] =
+ "java.lang.Double.doubleToRawLongBits(" + (*variables)["name"] +
+ "_) != 0";
+ break;
+ default:
+ (*variables)["is_field_present_message"] =
+ (*variables)["name"] + "_ != " + (*variables)["default"];
+ break;
+ }
+ }
+
+ (*variables)["get_has_field_bit_from_local"] =
+ GenerateGetBitFromLocal(builderBitIndex);
+ (*variables)["set_has_field_bit_to_local"] =
+ GenerateSetBitToLocal(messageBitIndex);
+}
+
+} // namespace
+
+// ===================================================================
+
+ImmutablePrimitiveFieldLiteGenerator::ImmutablePrimitiveFieldLiteGenerator(
+ const FieldDescriptor* descriptor, int messageBitIndex, Context* context)
+ : descriptor_(descriptor),
+ messageBitIndex_(messageBitIndex),
+ name_resolver_(context->GetNameResolver()) {
+ SetPrimitiveVariables(descriptor, messageBitIndex, 0,
+ context->GetFieldGeneratorInfo(descriptor),
+ name_resolver_, &variables_);
+}
+
+ImmutablePrimitiveFieldLiteGenerator::~ImmutablePrimitiveFieldLiteGenerator() {}
+
+int ImmutablePrimitiveFieldLiteGenerator::GetNumBitsForMessage() const {
+ return HasHasbit(descriptor_) ? 1 : 0;
+}
+
+void ImmutablePrimitiveFieldLiteGenerator::GenerateInterfaceMembers(
+ io::Printer* printer) const {
+ if (HasHazzer(descriptor_)) {
+ WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
+ printer->Print(variables_,
+ "$deprecation$boolean has$capitalized_name$();\n");
+ }
+ WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
+ printer->Print(variables_, "$deprecation$$type$ get$capitalized_name$();\n");
+}
+
+void ImmutablePrimitiveFieldLiteGenerator::GenerateMembers(
+ io::Printer* printer) const {
+ if (IsByteStringWithCustomDefaultValue(descriptor_)) {
+ // allocate this once statically since we know ByteStrings are immutable
+ // values that can be reused.
+ printer->Print(
+ variables_,
+ "private static final $field_type$ $bytes_default$ = $default$;\n");
+ }
+ printer->Print(variables_, "private $field_type$ $name$_;\n");
+ PrintExtraFieldInfo(variables_, printer);
+ if (HasHazzer(descriptor_)) {
+ WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
+ printer->Print(
+ variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
+ " return $get_has_field_bit_message$;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ }
+
+ WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
+ printer->Print(variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
+ " return $name$_;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+
+ WriteFieldAccessorDocComment(printer, descriptor_, SETTER);
+ printer->Print(variables_,
+ "private void set$capitalized_name$($type$ value) {\n"
+ "$null_check$"
+ " $set_has_field_bit_message$\n"
+ " $name$_ = value;\n"
+ "}\n");
+
+ WriteFieldAccessorDocComment(printer, descriptor_, CLEARER);
+ printer->Print(variables_,
+ "private void clear$capitalized_name$() {\n"
+ " $clear_has_field_bit_message$\n");
+ JavaType type = GetJavaType(descriptor_);
+ if (type == JAVATYPE_STRING || type == JAVATYPE_BYTES) {
+ // The default value is not a simple literal so we want to avoid executing
+ // it multiple times. Instead, get the default out of the default instance.
+ printer->Print(
+ variables_,
+ " $name$_ = getDefaultInstance().get$capitalized_name$();\n");
+ } else {
+ printer->Print(variables_, " $name$_ = $default$;\n");
+ }
+ printer->Print(variables_, "}\n");
+}
+
+void ImmutablePrimitiveFieldLiteGenerator::GenerateBuilderMembers(
+ io::Printer* printer) const {
+ if (HasHazzer(descriptor_)) {
+ WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
+ printer->Print(
+ variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
+ " return instance.has$capitalized_name$();\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ }
+
+ WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
+ printer->Print(variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
+ " return instance.get$capitalized_name$();\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+
+ WriteFieldAccessorDocComment(printer, descriptor_, SETTER,
+ /* builder */ true);
+ printer->Print(variables_,
+ "$deprecation$public Builder "
+ "${$set$capitalized_name$$}$($type$ value) {\n"
+ " copyOnWrite();\n"
+ " instance.set$capitalized_name$(value);\n"
+ " return this;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+
+ WriteFieldAccessorDocComment(printer, descriptor_, CLEARER,
+ /* builder */ true);
+ printer->Print(
+ variables_,
+ "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n"
+ " copyOnWrite();\n"
+ " instance.clear$capitalized_name$();\n"
+ " return this;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+}
+
+void ImmutablePrimitiveFieldLiteGenerator::GenerateKotlinDslMembers(
+ io::Printer* printer) const {
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$kt_deprecation$public var $kt_name$: $kt_type$\n"
+ " @JvmName(\"${$get$kt_capitalized_name$$}$\")\n"
+ " get() = $kt_dsl_builder$.${$get$capitalized_name$$}$()\n"
+ " @JvmName(\"${$set$kt_capitalized_name$$}$\")\n"
+ " set(value) {\n"
+ " $kt_dsl_builder$.${$set$capitalized_name$$}$(value)\n"
+ " }\n");
+
+ WriteFieldAccessorDocComment(printer, descriptor_, CLEARER,
+ /* builder */ false);
+ printer->Print(variables_,
+ "public fun ${$clear$kt_capitalized_name$$}$() {\n"
+ " $kt_dsl_builder$.${$clear$capitalized_name$$}$()\n"
+ "}\n");
+
+ if (HasHazzer(descriptor_)) {
+ WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
+ printer->Print(
+ variables_,
+ "public fun ${$has$kt_capitalized_name$$}$(): kotlin.Boolean {\n"
+ " return $kt_dsl_builder$.${$has$capitalized_name$$}$()\n"
+ "}\n");
+ }
+}
+
+void ImmutablePrimitiveFieldLiteGenerator::GenerateFieldInfo(
+ io::Printer* printer, std::vector<uint16_t>* output) const {
+ WriteIntToUtf16CharSequence(descriptor_->number(), output);
+ WriteIntToUtf16CharSequence(GetExperimentalJavaFieldType(descriptor_),
+ output);
+ if (HasHasbit(descriptor_)) {
+ WriteIntToUtf16CharSequence(messageBitIndex_, output);
+ }
+ printer->Print(variables_, "\"$name$_\",\n");
+}
+
+void ImmutablePrimitiveFieldLiteGenerator::GenerateInitializationCode(
+ io::Printer* printer) const {
+ if (IsByteStringWithCustomDefaultValue(descriptor_)) {
+ printer->Print(variables_, "$name$_ = $bytes_default$;\n");
+ } else if (!IsDefaultValueJavaDefault(descriptor_)) {
+ printer->Print(variables_, "$name$_ = $default$;\n");
+ }
+}
+
+std::string ImmutablePrimitiveFieldLiteGenerator::GetBoxedType() const {
+ return BoxedPrimitiveTypeName(GetJavaType(descriptor_));
+}
+
+// ===================================================================
+
+ImmutablePrimitiveOneofFieldLiteGenerator::
+ ImmutablePrimitiveOneofFieldLiteGenerator(const FieldDescriptor* descriptor,
+ int messageBitIndex,
+ Context* context)
+ : ImmutablePrimitiveFieldLiteGenerator(descriptor, messageBitIndex,
+ context) {
+ const OneofGeneratorInfo* info =
+ context->GetOneofGeneratorInfo(descriptor->containing_oneof());
+ SetCommonOneofVariables(descriptor, info, &variables_);
+}
+
+ImmutablePrimitiveOneofFieldLiteGenerator::
+ ~ImmutablePrimitiveOneofFieldLiteGenerator() {}
+
+void ImmutablePrimitiveOneofFieldLiteGenerator::GenerateMembers(
+ io::Printer* printer) const {
+ PrintExtraFieldInfo(variables_, printer);
+ GOOGLE_DCHECK(HasHazzer(descriptor_));
+ WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
+ printer->Print(variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
+ " return $has_oneof_case_message$;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+
+ WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
+ printer->Print(variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
+ " if ($has_oneof_case_message$) {\n"
+ " return ($boxed_type$) $oneof_name$_;\n"
+ " }\n"
+ " return $default$;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+
+ WriteFieldAccessorDocComment(printer, descriptor_, SETTER);
+ printer->Print(variables_,
+ "private void set$capitalized_name$($type$ value) {\n"
+ "$null_check$"
+ " $set_oneof_case_message$;\n"
+ " $oneof_name$_ = value;\n"
+ "}\n");
+
+ WriteFieldAccessorDocComment(printer, descriptor_, CLEARER);
+ printer->Print(variables_,
+ "private void clear$capitalized_name$() {\n"
+ " if ($has_oneof_case_message$) {\n"
+ " $clear_oneof_case_message$;\n"
+ " $oneof_name$_ = null;\n"
+ " }\n"
+ "}\n");
+}
+
+void ImmutablePrimitiveOneofFieldLiteGenerator::GenerateFieldInfo(
+ io::Printer* printer, std::vector<uint16_t>* output) const {
+ WriteIntToUtf16CharSequence(descriptor_->number(), output);
+ WriteIntToUtf16CharSequence(GetExperimentalJavaFieldType(descriptor_),
+ output);
+ WriteIntToUtf16CharSequence(descriptor_->containing_oneof()->index(), output);
+}
+
+void ImmutablePrimitiveOneofFieldLiteGenerator::GenerateBuilderMembers(
+ io::Printer* printer) const {
+ GOOGLE_DCHECK(HasHazzer(descriptor_));
+ WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
+ printer->Print(variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
+ " return instance.has$capitalized_name$();\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+
+ WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
+ printer->Print(variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
+ " return instance.get$capitalized_name$();\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+
+ WriteFieldAccessorDocComment(printer, descriptor_, SETTER,
+ /* builder */ true);
+ printer->Print(variables_,
+ "$deprecation$public Builder "
+ "${$set$capitalized_name$$}$($type$ value) {\n"
+ " copyOnWrite();\n"
+ " instance.set$capitalized_name$(value);\n"
+ " return this;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+
+ WriteFieldAccessorDocComment(printer, descriptor_, CLEARER,
+ /* builder */ true);
+ printer->Print(
+ variables_,
+ "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n"
+ " copyOnWrite();\n"
+ " instance.clear$capitalized_name$();\n"
+ " return this;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+}
+
+// ===================================================================
+
+RepeatedImmutablePrimitiveFieldLiteGenerator::
+ RepeatedImmutablePrimitiveFieldLiteGenerator(
+ const FieldDescriptor* descriptor, int messageBitIndex,
+ Context* context)
+ : descriptor_(descriptor),
+ context_(context),
+ name_resolver_(context->GetNameResolver()) {
+ SetPrimitiveVariables(descriptor, messageBitIndex, 0,
+ context->GetFieldGeneratorInfo(descriptor),
+ name_resolver_, &variables_);
+}
+
+RepeatedImmutablePrimitiveFieldLiteGenerator::
+ ~RepeatedImmutablePrimitiveFieldLiteGenerator() {}
+
+int RepeatedImmutablePrimitiveFieldLiteGenerator::GetNumBitsForMessage() const {
+ return 0;
+}
+
+void RepeatedImmutablePrimitiveFieldLiteGenerator::GenerateInterfaceMembers(
+ io::Printer* printer) const {
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_GETTER);
+ printer->Print(variables_,
+ "$deprecation$java.util.List<$boxed_type$> "
+ "get$capitalized_name$List();\n");
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_COUNT);
+ printer->Print(variables_,
+ "$deprecation$int get$capitalized_name$Count();\n");
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_GETTER);
+ printer->Print(variables_,
+ "$deprecation$$type$ get$capitalized_name$(int index);\n");
+}
+
+void RepeatedImmutablePrimitiveFieldLiteGenerator::GenerateMembers(
+ io::Printer* printer) const {
+ printer->Print(variables_, "private $field_list_type$ $name$_;\n");
+ PrintExtraFieldInfo(variables_, printer);
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_GETTER);
+ printer->Print(variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public java.util.List<$boxed_type$>\n"
+ " ${$get$capitalized_name$List$}$() {\n"
+ " return $name$_;\n" // note: unmodifiable list
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_COUNT);
+ printer->Print(
+ variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n"
+ " return $name$_.size();\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_GETTER);
+ printer->Print(
+ variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n"
+ " return $repeated_get$(index);\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+
+ if (!EnableExperimentalRuntimeForLite() && descriptor_->is_packed() &&
+ context_->HasGeneratedMethods(descriptor_->containing_type())) {
+ printer->Print(variables_,
+ "private int $name$MemoizedSerializedSize = -1;\n");
+ }
+
+ printer->Print(
+ variables_,
+ "private void ensure$capitalized_name$IsMutable() {\n"
+ // Use a temporary to avoid a redundant iget-object.
+ " $field_list_type$ tmp = $name$_;\n"
+ " if (!tmp.isModifiable()) {\n"
+ " $name$_ =\n"
+ " com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);\n"
+ " }\n"
+ "}\n");
+
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_SETTER);
+ printer->Print(variables_,
+ "private void set$capitalized_name$(\n"
+ " int index, $type$ value) {\n"
+ "$null_check$"
+ " ensure$capitalized_name$IsMutable();\n"
+ " $repeated_set$(index, value);\n"
+ "}\n");
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_ADDER);
+ printer->Print(variables_,
+ "private void add$capitalized_name$($type$ value) {\n"
+ "$null_check$"
+ " ensure$capitalized_name$IsMutable();\n"
+ " $repeated_add$(value);\n"
+ "}\n");
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_MULTI_ADDER);
+ printer->Print(variables_,
+ "private void addAll$capitalized_name$(\n"
+ " java.lang.Iterable<? extends $boxed_type$> values) {\n"
+ " ensure$capitalized_name$IsMutable();\n"
+ " com.google.protobuf.AbstractMessageLite.addAll(\n"
+ " values, $name$_);\n"
+ "}\n");
+ WriteFieldAccessorDocComment(printer, descriptor_, CLEARER);
+ printer->Print(variables_,
+ "private void clear$capitalized_name$() {\n"
+ " $name$_ = $empty_list$;\n"
+ "}\n");
+}
+
+void RepeatedImmutablePrimitiveFieldLiteGenerator::GenerateBuilderMembers(
+ io::Printer* printer) const {
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_GETTER);
+ printer->Print(variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public java.util.List<$boxed_type$>\n"
+ " ${$get$capitalized_name$List$}$() {\n"
+ " return java.util.Collections.unmodifiableList(\n"
+ " instance.get$capitalized_name$List());\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_COUNT);
+ printer->Print(
+ variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n"
+ " return instance.get$capitalized_name$Count();\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_GETTER);
+ printer->Print(
+ variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n"
+ " return instance.get$capitalized_name$(index);\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldAccessorDocComment(printer, descriptor_, SETTER,
+ /* builder */ true);
+ printer->Print(variables_,
+ "$deprecation$public Builder ${$set$capitalized_name$$}$(\n"
+ " int index, $type$ value) {\n"
+ " copyOnWrite();\n"
+ " instance.set$capitalized_name$(index, value);\n"
+ " return this;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_ADDER,
+ /* builder */ true);
+ printer->Print(variables_,
+ "$deprecation$public Builder "
+ "${$add$capitalized_name$$}$($type$ value) {\n"
+ " copyOnWrite();\n"
+ " instance.add$capitalized_name$(value);\n"
+ " return this;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_MULTI_ADDER,
+ /* builder */ true);
+ printer->Print(variables_,
+ "$deprecation$public Builder ${$addAll$capitalized_name$$}$(\n"
+ " java.lang.Iterable<? extends $boxed_type$> values) {\n"
+ " copyOnWrite();\n"
+ " instance.addAll$capitalized_name$(values);\n"
+ " return this;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldAccessorDocComment(printer, descriptor_, CLEARER,
+ /* builder */ true);
+ printer->Print(
+ variables_,
+ "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n"
+ " copyOnWrite();\n"
+ " instance.clear$capitalized_name$();\n"
+ " return this;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+}
+
+void RepeatedImmutablePrimitiveFieldLiteGenerator::GenerateKotlinDslMembers(
+ io::Printer* printer) const {
+ printer->Print(
+ variables_,
+ "/**\n"
+ " * An uninstantiable, behaviorless type to represent the field in\n"
+ " * generics.\n"
+ " */\n"
+ "@kotlin.OptIn"
+ "(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)\n"
+ "public class ${$$kt_capitalized_name$Proxy$}$ private constructor()"
+ " : com.google.protobuf.kotlin.DslProxy()\n");
+
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$kt_deprecation$ public val $kt_name$: "
+ "com.google.protobuf.kotlin.DslList"
+ "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>\n"
+ " @kotlin.jvm.JvmSynthetic\n"
+ " get() = com.google.protobuf.kotlin.DslList(\n"
+ " $kt_dsl_builder$.${$get$capitalized_name$List$}$()\n"
+ " )\n");
+
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_ADDER,
+ /* builder */ false);
+ printer->Print(variables_,
+ "@kotlin.jvm.JvmSynthetic\n"
+ "@kotlin.jvm.JvmName(\"add$kt_capitalized_name$\")\n"
+ "public fun com.google.protobuf.kotlin.DslList"
+ "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>."
+ "add(value: $kt_type$) {\n"
+ " $kt_dsl_builder$.${$add$capitalized_name$$}$(value)\n"
+ "}");
+
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_ADDER,
+ /* builder */ false);
+ printer->Print(variables_,
+ "@kotlin.jvm.JvmSynthetic\n"
+ "@kotlin.jvm.JvmName(\"plusAssign$kt_capitalized_name$\")\n"
+ "@Suppress(\"NOTHING_TO_INLINE\")\n"
+ "public inline operator fun com.google.protobuf.kotlin.DslList"
+ "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>."
+ "plusAssign(value: $kt_type$) {\n"
+ " add(value)\n"
+ "}");
+
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_MULTI_ADDER,
+ /* builder */ false);
+ printer->Print(variables_,
+ "@kotlin.jvm.JvmSynthetic\n"
+ "@kotlin.jvm.JvmName(\"addAll$kt_capitalized_name$\")\n"
+ "public fun com.google.protobuf.kotlin.DslList"
+ "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>."
+ "addAll(values: kotlin.collections.Iterable<$kt_type$>) {\n"
+ " $kt_dsl_builder$.${$addAll$capitalized_name$$}$(values)\n"
+ "}");
+
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_MULTI_ADDER,
+ /* builder */ false);
+ printer->Print(
+ variables_,
+ "@kotlin.jvm.JvmSynthetic\n"
+ "@kotlin.jvm.JvmName(\"plusAssignAll$kt_capitalized_name$\")\n"
+ "@Suppress(\"NOTHING_TO_INLINE\")\n"
+ "public inline operator fun com.google.protobuf.kotlin.DslList"
+ "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>."
+ "plusAssign(values: kotlin.collections.Iterable<$kt_type$>) {\n"
+ " addAll(values)\n"
+ "}");
+
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_SETTER,
+ /* builder */ false);
+ printer->Print(
+ variables_,
+ "@kotlin.jvm.JvmSynthetic\n"
+ "@kotlin.jvm.JvmName(\"set$kt_capitalized_name$\")\n"
+ "public operator fun com.google.protobuf.kotlin.DslList"
+ "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>."
+ "set(index: kotlin.Int, value: $kt_type$) {\n"
+ " $kt_dsl_builder$.${$set$capitalized_name$$}$(index, value)\n"
+ "}");
+
+ WriteFieldAccessorDocComment(printer, descriptor_, CLEARER,
+ /* builder */ false);
+ printer->Print(variables_,
+ "@kotlin.jvm.JvmSynthetic\n"
+ "@kotlin.jvm.JvmName(\"clear$kt_capitalized_name$\")\n"
+ "public fun com.google.protobuf.kotlin.DslList"
+ "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>."
+ "clear() {\n"
+ " $kt_dsl_builder$.${$clear$capitalized_name$$}$()\n"
+ "}");
+}
+
+void RepeatedImmutablePrimitiveFieldLiteGenerator::GenerateFieldInfo(
+ io::Printer* printer, std::vector<uint16_t>* output) const {
+ WriteIntToUtf16CharSequence(descriptor_->number(), output);
+ WriteIntToUtf16CharSequence(GetExperimentalJavaFieldType(descriptor_),
+ output);
+ printer->Print(variables_, "\"$name$_\",\n");
+}
+
+void RepeatedImmutablePrimitiveFieldLiteGenerator::GenerateInitializationCode(
+ io::Printer* printer) const {
+ printer->Print(variables_, "$name$_ = $empty_list$;\n");
+}
+
+std::string RepeatedImmutablePrimitiveFieldLiteGenerator::GetBoxedType() const {
+ return BoxedPrimitiveTypeName(GetJavaType(descriptor_));
+}
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_primitive_field_lite.h b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_primitive_field_lite.h
new file mode 100644
index 00000000..8bfd7ae2
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_primitive_field_lite.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: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_PRIMITIVE_FIELD_LITE_H__
+#define GOOGLE_PROTOBUF_COMPILER_JAVA_PRIMITIVE_FIELD_LITE_H__
+
+#include <cstdint>
+#include <map>
+#include <string>
+
+#include <compiler/java/java_field.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+class Context; // context.h
+class ClassNameResolver; // name_resolver.h
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+class ImmutablePrimitiveFieldLiteGenerator
+ : public ImmutableFieldLiteGenerator {
+ public:
+ explicit ImmutablePrimitiveFieldLiteGenerator(
+ const FieldDescriptor* descriptor, int messageBitIndex, Context* context);
+ ~ImmutablePrimitiveFieldLiteGenerator() override;
+
+ // implements ImmutableFieldLiteGenerator
+ // ------------------------------------
+ int GetNumBitsForMessage() const override;
+ void GenerateInterfaceMembers(io::Printer* printer) const override;
+ void GenerateMembers(io::Printer* printer) const override;
+ void GenerateBuilderMembers(io::Printer* printer) const override;
+ void GenerateInitializationCode(io::Printer* printer) const override;
+ void GenerateFieldInfo(io::Printer* printer,
+ std::vector<uint16_t>* output) const override;
+ void GenerateKotlinDslMembers(io::Printer* printer) const override;
+
+ std::string GetBoxedType() const override;
+
+ protected:
+ const FieldDescriptor* descriptor_;
+ std::map<std::string, std::string> variables_;
+ const int messageBitIndex_;
+ ClassNameResolver* name_resolver_;
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutablePrimitiveFieldLiteGenerator);
+};
+
+class ImmutablePrimitiveOneofFieldLiteGenerator
+ : public ImmutablePrimitiveFieldLiteGenerator {
+ public:
+ ImmutablePrimitiveOneofFieldLiteGenerator(const FieldDescriptor* descriptor,
+ int messageBitIndex,
+ Context* context);
+ ~ImmutablePrimitiveOneofFieldLiteGenerator();
+
+ void GenerateMembers(io::Printer* printer) const override;
+ void GenerateBuilderMembers(io::Printer* printer) const override;
+
+ void GenerateFieldInfo(io::Printer* printer,
+ std::vector<uint16_t>* output) const override;
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutablePrimitiveOneofFieldLiteGenerator);
+};
+
+class RepeatedImmutablePrimitiveFieldLiteGenerator
+ : public ImmutableFieldLiteGenerator {
+ public:
+ explicit RepeatedImmutablePrimitiveFieldLiteGenerator(
+ const FieldDescriptor* descriptor, int messageBitIndex, Context* context);
+ ~RepeatedImmutablePrimitiveFieldLiteGenerator() override;
+
+ // implements ImmutableFieldLiteGenerator ------------------------------------
+ int GetNumBitsForMessage() const override;
+ void GenerateInterfaceMembers(io::Printer* printer) const override;
+ void GenerateMembers(io::Printer* printer) const override;
+ void GenerateBuilderMembers(io::Printer* printer) const override;
+ void GenerateInitializationCode(io::Printer* printer) const override;
+ void GenerateFieldInfo(io::Printer* printer,
+ std::vector<uint16_t>* output) const override;
+ void GenerateKotlinDslMembers(io::Printer* printer) const override;
+
+ std::string GetBoxedType() const override;
+
+ private:
+ const FieldDescriptor* descriptor_;
+ std::map<std::string, std::string> variables_;
+ Context* context_;
+ ClassNameResolver* name_resolver_;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedImmutablePrimitiveFieldLiteGenerator);
+};
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_PRIMITIVE_FIELD_LITE_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_service.cc b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_service.cc
new file mode 100644
index 00000000..28407660
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_service.cc
@@ -0,0 +1,474 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 <compiler/java/java_service.h>
+
+#include <compiler/java/java_context.h>
+#include <compiler/java/java_doc_comment.h>
+#include <compiler/java/java_helpers.h>
+#include <compiler/java/java_name_resolver.h>
+#include <io/printer.h>
+#include <stubs/strutil.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+ServiceGenerator::ServiceGenerator(const ServiceDescriptor* descriptor)
+ : descriptor_(descriptor) {}
+
+ServiceGenerator::~ServiceGenerator() {}
+
+// ===================================================================
+ImmutableServiceGenerator::ImmutableServiceGenerator(
+ const ServiceDescriptor* descriptor, Context* context)
+ : ServiceGenerator(descriptor),
+ context_(context),
+ name_resolver_(context->GetNameResolver()) {}
+
+ImmutableServiceGenerator::~ImmutableServiceGenerator() {}
+
+void ImmutableServiceGenerator::Generate(io::Printer* printer) {
+ bool is_own_file = IsOwnFile(descriptor_, /* immutable = */ true);
+ WriteServiceDocComment(printer, descriptor_);
+ MaybePrintGeneratedAnnotation(context_, printer, descriptor_,
+ /* immutable = */ true);
+ printer->Print(
+ "public $static$ abstract class $classname$\n"
+ " implements com.google.protobuf.Service {\n",
+ "static", is_own_file ? "" : "static", "classname", descriptor_->name());
+ printer->Indent();
+
+ printer->Print("protected $classname$() {}\n\n", "classname",
+ descriptor_->name());
+
+ GenerateInterface(printer);
+
+ GenerateNewReflectiveServiceMethod(printer);
+ GenerateNewReflectiveBlockingServiceMethod(printer);
+
+ GenerateAbstractMethods(printer);
+
+ // Generate getDescriptor() and getDescriptorForType().
+ printer->Print(
+ "public static final\n"
+ " com.google.protobuf.Descriptors.ServiceDescriptor\n"
+ " getDescriptor() {\n"
+ " return $file$.getDescriptor().getServices().get($index$);\n"
+ "}\n",
+ "file", name_resolver_->GetImmutableClassName(descriptor_->file()),
+ "index", StrCat(descriptor_->index()));
+ GenerateGetDescriptorForType(printer);
+
+ // Generate more stuff.
+ GenerateCallMethod(printer);
+ GenerateGetPrototype(REQUEST, printer);
+ GenerateGetPrototype(RESPONSE, printer);
+ GenerateStub(printer);
+ GenerateBlockingStub(printer);
+
+ // Add an insertion point.
+ printer->Print(
+ "\n"
+ "// @@protoc_insertion_point(class_scope:$full_name$)\n",
+ "full_name", descriptor_->full_name());
+
+ printer->Outdent();
+ printer->Print("}\n\n");
+}
+
+void ImmutableServiceGenerator::GenerateGetDescriptorForType(
+ io::Printer* printer) {
+ printer->Print(
+ "public final com.google.protobuf.Descriptors.ServiceDescriptor\n"
+ " getDescriptorForType() {\n"
+ " return getDescriptor();\n"
+ "}\n");
+}
+
+void ImmutableServiceGenerator::GenerateInterface(io::Printer* printer) {
+ printer->Print("public interface Interface {\n");
+ printer->Indent();
+ GenerateAbstractMethods(printer);
+ printer->Outdent();
+ printer->Print("}\n\n");
+}
+
+void ImmutableServiceGenerator::GenerateNewReflectiveServiceMethod(
+ io::Printer* printer) {
+ printer->Print(
+ "public static com.google.protobuf.Service newReflectiveService(\n"
+ " final Interface impl) {\n"
+ " return new $classname$() {\n",
+ "classname", descriptor_->name());
+ printer->Indent();
+ printer->Indent();
+
+ for (int i = 0; i < descriptor_->method_count(); i++) {
+ const MethodDescriptor* method = descriptor_->method(i);
+ printer->Print("@java.lang.Override\n");
+ GenerateMethodSignature(printer, method, IS_CONCRETE);
+ printer->Print(
+ " {\n"
+ " impl.$method$(controller, request, done);\n"
+ "}\n\n",
+ "method", UnderscoresToCamelCase(method));
+ }
+
+ printer->Outdent();
+ printer->Print("};\n");
+ printer->Outdent();
+ printer->Print("}\n\n");
+}
+
+void ImmutableServiceGenerator::GenerateNewReflectiveBlockingServiceMethod(
+ io::Printer* printer) {
+ printer->Print(
+ "public static com.google.protobuf.BlockingService\n"
+ " newReflectiveBlockingService(final BlockingInterface impl) {\n"
+ " return new com.google.protobuf.BlockingService() {\n");
+ printer->Indent();
+ printer->Indent();
+
+ GenerateGetDescriptorForType(printer);
+
+ GenerateCallBlockingMethod(printer);
+ GenerateGetPrototype(REQUEST, printer);
+ GenerateGetPrototype(RESPONSE, printer);
+
+ printer->Outdent();
+ printer->Print("};\n");
+ printer->Outdent();
+ printer->Print("}\n\n");
+}
+
+void ImmutableServiceGenerator::GenerateAbstractMethods(io::Printer* printer) {
+ for (int i = 0; i < descriptor_->method_count(); i++) {
+ const MethodDescriptor* method = descriptor_->method(i);
+ WriteMethodDocComment(printer, method);
+ GenerateMethodSignature(printer, method, IS_ABSTRACT);
+ printer->Print(";\n\n");
+ }
+}
+
+std::string ImmutableServiceGenerator::GetOutput(
+ const MethodDescriptor* method) {
+ return name_resolver_->GetImmutableClassName(method->output_type());
+}
+
+void ImmutableServiceGenerator::GenerateCallMethod(io::Printer* printer) {
+ printer->Print(
+ "\n"
+ "public final void callMethod(\n"
+ " com.google.protobuf.Descriptors.MethodDescriptor method,\n"
+ " com.google.protobuf.RpcController controller,\n"
+ " com.google.protobuf.Message request,\n"
+ " com.google.protobuf.RpcCallback<\n"
+ " com.google.protobuf.Message> done) {\n"
+ " if (method.getService() != getDescriptor()) {\n"
+ " throw new java.lang.IllegalArgumentException(\n"
+ " \"Service.callMethod() given method descriptor for wrong \" +\n"
+ " \"service type.\");\n"
+ " }\n"
+ " switch(method.getIndex()) {\n");
+ printer->Indent();
+ printer->Indent();
+
+ for (int i = 0; i < descriptor_->method_count(); i++) {
+ const MethodDescriptor* method = descriptor_->method(i);
+ std::map<std::string, std::string> vars;
+ vars["index"] = StrCat(i);
+ vars["method"] = UnderscoresToCamelCase(method);
+ vars["input"] = name_resolver_->GetImmutableClassName(method->input_type());
+ vars["output"] = GetOutput(method);
+ printer->Print(
+ vars,
+ "case $index$:\n"
+ " this.$method$(controller, ($input$)request,\n"
+ " com.google.protobuf.RpcUtil.<$output$>specializeCallback(\n"
+ " done));\n"
+ " return;\n");
+ }
+
+ printer->Print(
+ "default:\n"
+ " throw new java.lang.AssertionError(\"Can't get here.\");\n");
+
+ printer->Outdent();
+ printer->Outdent();
+
+ printer->Print(
+ " }\n"
+ "}\n"
+ "\n");
+}
+
+void ImmutableServiceGenerator::GenerateCallBlockingMethod(
+ io::Printer* printer) {
+ printer->Print(
+ "\n"
+ "public final com.google.protobuf.Message callBlockingMethod(\n"
+ " com.google.protobuf.Descriptors.MethodDescriptor method,\n"
+ " com.google.protobuf.RpcController controller,\n"
+ " com.google.protobuf.Message request)\n"
+ " throws com.google.protobuf.ServiceException {\n"
+ " if (method.getService() != getDescriptor()) {\n"
+ " throw new java.lang.IllegalArgumentException(\n"
+ " \"Service.callBlockingMethod() given method descriptor for \" +\n"
+ " \"wrong service type.\");\n"
+ " }\n"
+ " switch(method.getIndex()) {\n");
+ printer->Indent();
+ printer->Indent();
+
+ for (int i = 0; i < descriptor_->method_count(); i++) {
+ const MethodDescriptor* method = descriptor_->method(i);
+ std::map<std::string, std::string> vars;
+ vars["index"] = StrCat(i);
+ vars["method"] = UnderscoresToCamelCase(method);
+ vars["input"] = name_resolver_->GetImmutableClassName(method->input_type());
+ vars["output"] = GetOutput(method);
+ printer->Print(vars,
+ "case $index$:\n"
+ " return impl.$method$(controller, ($input$)request);\n");
+ }
+
+ printer->Print(
+ "default:\n"
+ " throw new java.lang.AssertionError(\"Can't get here.\");\n");
+
+ printer->Outdent();
+ printer->Outdent();
+
+ printer->Print(
+ " }\n"
+ "}\n"
+ "\n");
+}
+
+void ImmutableServiceGenerator::GenerateGetPrototype(RequestOrResponse which,
+ io::Printer* printer) {
+ /*
+ * TODO(cpovirk): The exception message says "Service.foo" when it may be
+ * "BlockingService.foo." Consider fixing.
+ */
+ printer->Print(
+ "public final com.google.protobuf.Message\n"
+ " get$request_or_response$Prototype(\n"
+ " com.google.protobuf.Descriptors.MethodDescriptor method) {\n"
+ " if (method.getService() != getDescriptor()) {\n"
+ " throw new java.lang.IllegalArgumentException(\n"
+ " \"Service.get$request_or_response$Prototype() given method \" +\n"
+ " \"descriptor for wrong service type.\");\n"
+ " }\n"
+ " switch(method.getIndex()) {\n",
+ "request_or_response", (which == REQUEST) ? "Request" : "Response");
+ printer->Indent();
+ printer->Indent();
+
+ for (int i = 0; i < descriptor_->method_count(); i++) {
+ const MethodDescriptor* method = descriptor_->method(i);
+ std::map<std::string, std::string> vars;
+ vars["index"] = StrCat(i);
+ vars["type"] =
+ (which == REQUEST)
+ ? name_resolver_->GetImmutableClassName(method->input_type())
+ : GetOutput(method);
+ printer->Print(vars,
+ "case $index$:\n"
+ " return $type$.getDefaultInstance();\n");
+ }
+
+ printer->Print(
+ "default:\n"
+ " throw new java.lang.AssertionError(\"Can't get here.\");\n");
+
+ printer->Outdent();
+ printer->Outdent();
+
+ printer->Print(
+ " }\n"
+ "}\n"
+ "\n");
+}
+
+void ImmutableServiceGenerator::GenerateStub(io::Printer* printer) {
+ printer->Print(
+ "public static Stub newStub(\n"
+ " com.google.protobuf.RpcChannel channel) {\n"
+ " return new Stub(channel);\n"
+ "}\n"
+ "\n"
+ "public static final class Stub extends $classname$ implements Interface "
+ "{"
+ "\n",
+ "classname", name_resolver_->GetImmutableClassName(descriptor_));
+ printer->Indent();
+
+ printer->Print(
+ "private Stub(com.google.protobuf.RpcChannel channel) {\n"
+ " this.channel = channel;\n"
+ "}\n"
+ "\n"
+ "private final com.google.protobuf.RpcChannel channel;\n"
+ "\n"
+ "public com.google.protobuf.RpcChannel getChannel() {\n"
+ " return channel;\n"
+ "}\n");
+
+ for (int i = 0; i < descriptor_->method_count(); i++) {
+ const MethodDescriptor* method = descriptor_->method(i);
+ printer->Print("\n");
+ GenerateMethodSignature(printer, method, IS_CONCRETE);
+ printer->Print(" {\n");
+ printer->Indent();
+
+ std::map<std::string, std::string> vars;
+ vars["index"] = StrCat(i);
+ vars["output"] = GetOutput(method);
+ printer->Print(vars,
+ "channel.callMethod(\n"
+ " getDescriptor().getMethods().get($index$),\n"
+ " controller,\n"
+ " request,\n"
+ " $output$.getDefaultInstance(),\n"
+ " com.google.protobuf.RpcUtil.generalizeCallback(\n"
+ " done,\n"
+ " $output$.class,\n"
+ " $output$.getDefaultInstance()));\n");
+
+ printer->Outdent();
+ printer->Print("}\n");
+ }
+
+ printer->Outdent();
+ printer->Print(
+ "}\n"
+ "\n");
+}
+
+void ImmutableServiceGenerator::GenerateBlockingStub(io::Printer* printer) {
+ printer->Print(
+ "public static BlockingInterface newBlockingStub(\n"
+ " com.google.protobuf.BlockingRpcChannel channel) {\n"
+ " return new BlockingStub(channel);\n"
+ "}\n"
+ "\n");
+
+ printer->Print("public interface BlockingInterface {");
+ printer->Indent();
+
+ for (int i = 0; i < descriptor_->method_count(); i++) {
+ const MethodDescriptor* method = descriptor_->method(i);
+ GenerateBlockingMethodSignature(printer, method);
+ printer->Print(";\n");
+ }
+
+ printer->Outdent();
+ printer->Print(
+ "}\n"
+ "\n");
+
+ printer->Print(
+ "private static final class BlockingStub implements BlockingInterface "
+ "{\n");
+ printer->Indent();
+
+ printer->Print(
+ "private BlockingStub(com.google.protobuf.BlockingRpcChannel channel) {\n"
+ " this.channel = channel;\n"
+ "}\n"
+ "\n"
+ "private final com.google.protobuf.BlockingRpcChannel channel;\n");
+
+ for (int i = 0; i < descriptor_->method_count(); i++) {
+ const MethodDescriptor* method = descriptor_->method(i);
+ GenerateBlockingMethodSignature(printer, method);
+ printer->Print(" {\n");
+ printer->Indent();
+
+ std::map<std::string, std::string> vars;
+ vars["index"] = StrCat(i);
+ vars["output"] = GetOutput(method);
+ printer->Print(vars,
+ "return ($output$) channel.callBlockingMethod(\n"
+ " getDescriptor().getMethods().get($index$),\n"
+ " controller,\n"
+ " request,\n"
+ " $output$.getDefaultInstance());\n");
+
+ printer->Outdent();
+ printer->Print(
+ "}\n"
+ "\n");
+ }
+
+ printer->Outdent();
+ printer->Print("}\n");
+}
+
+void ImmutableServiceGenerator::GenerateMethodSignature(
+ io::Printer* printer, const MethodDescriptor* method,
+ IsAbstract is_abstract) {
+ std::map<std::string, std::string> vars;
+ vars["name"] = UnderscoresToCamelCase(method);
+ vars["input"] = name_resolver_->GetImmutableClassName(method->input_type());
+ vars["output"] = GetOutput(method);
+ vars["abstract"] = (is_abstract == IS_ABSTRACT) ? "abstract" : "";
+ printer->Print(vars,
+ "public $abstract$ void $name$(\n"
+ " com.google.protobuf.RpcController controller,\n"
+ " $input$ request,\n"
+ " com.google.protobuf.RpcCallback<$output$> done)");
+}
+
+void ImmutableServiceGenerator::GenerateBlockingMethodSignature(
+ io::Printer* printer, const MethodDescriptor* method) {
+ std::map<std::string, std::string> vars;
+ vars["method"] = UnderscoresToCamelCase(method);
+ vars["input"] = name_resolver_->GetImmutableClassName(method->input_type());
+ vars["output"] = GetOutput(method);
+ printer->Print(vars,
+ "\n"
+ "public $output$ $method$(\n"
+ " com.google.protobuf.RpcController controller,\n"
+ " $input$ request)\n"
+ " throws com.google.protobuf.ServiceException");
+}
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_service.h b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_service.h
new file mode 100644
index 00000000..f21d5f11
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_service.h
@@ -0,0 +1,139 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_SERVICE_H__
+#define GOOGLE_PROTOBUF_COMPILER_JAVA_SERVICE_H__
+
+#include <map>
+#include <descriptor.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+class Context; // context.h
+class ClassNameResolver; // name_resolver.h
+} // namespace java
+} // namespace compiler
+namespace io {
+class Printer; // printer.h
+}
+} // namespace protobuf
+} // namespace google
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+class ServiceGenerator {
+ public:
+ explicit ServiceGenerator(const ServiceDescriptor* descriptor);
+ virtual ~ServiceGenerator();
+
+ virtual void Generate(io::Printer* printer) = 0;
+
+ enum RequestOrResponse { REQUEST, RESPONSE };
+ enum IsAbstract { IS_ABSTRACT, IS_CONCRETE };
+
+ protected:
+ const ServiceDescriptor* descriptor_;
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ServiceGenerator);
+};
+
+class ImmutableServiceGenerator : public ServiceGenerator {
+ public:
+ ImmutableServiceGenerator(const ServiceDescriptor* descriptor,
+ Context* context);
+ virtual ~ImmutableServiceGenerator();
+
+ void Generate(io::Printer* printer) override;
+
+ private:
+ // Generate the getDescriptorForType() method.
+ void GenerateGetDescriptorForType(io::Printer* printer);
+
+ // Generate a Java interface for the service.
+ void GenerateInterface(io::Printer* printer);
+
+ // Generate newReflectiveService() method.
+ void GenerateNewReflectiveServiceMethod(io::Printer* printer);
+
+ // Generate newReflectiveBlockingService() method.
+ void GenerateNewReflectiveBlockingServiceMethod(io::Printer* printer);
+
+ // Generate abstract method declarations for all methods.
+ void GenerateAbstractMethods(io::Printer* printer);
+
+ // Generate the implementation of Service.callMethod().
+ void GenerateCallMethod(io::Printer* printer);
+
+ // Generate the implementation of BlockingService.callBlockingMethod().
+ void GenerateCallBlockingMethod(io::Printer* printer);
+
+ // Generate the implementations of Service.get{Request,Response}Prototype().
+ void GenerateGetPrototype(RequestOrResponse which, io::Printer* printer);
+
+ // Generate a stub implementation of the service.
+ void GenerateStub(io::Printer* printer);
+
+ // Generate a method signature, possibly abstract, without body or trailing
+ // semicolon.
+ void GenerateMethodSignature(io::Printer* printer,
+ const MethodDescriptor* method,
+ IsAbstract is_abstract);
+
+ // Generate a blocking stub interface and implementation of the service.
+ void GenerateBlockingStub(io::Printer* printer);
+
+ // Generate the method signature for one method of a blocking stub.
+ void GenerateBlockingMethodSignature(io::Printer* printer,
+ const MethodDescriptor* method);
+
+ // Return the output type of the method.
+ std::string GetOutput(const MethodDescriptor* method);
+
+ Context* context_;
+ ClassNameResolver* name_resolver_;
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableServiceGenerator);
+};
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#endif // NET_PROTO2_COMPILER_JAVA_SERVICE_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_shared_code_generator.cc b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_shared_code_generator.cc
new file mode 100644
index 00000000..935ce7bb
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_shared_code_generator.cc
@@ -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.
+
+// Author: xiaofeng@google.com (Feng Xiao)
+
+#include <compiler/java/java_shared_code_generator.h>
+
+#include <memory>
+
+#include <compiler/java/java_helpers.h>
+#include <compiler/java/java_name_resolver.h>
+#include <compiler/java/java_names.h>
+#include <compiler/code_generator.h>
+#include <descriptor.pb.h>
+#include <io/printer.h>
+#include <io/zero_copy_stream.h>
+#include <descriptor.h>
+#include <stubs/strutil.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+SharedCodeGenerator::SharedCodeGenerator(const FileDescriptor* file,
+ const Options& options)
+ : name_resolver_(new ClassNameResolver), file_(file), options_(options) {}
+
+SharedCodeGenerator::~SharedCodeGenerator() {}
+
+void SharedCodeGenerator::Generate(
+ GeneratorContext* context, std::vector<std::string>* file_list,
+ std::vector<std::string>* annotation_file_list) {
+ std::string java_package = FileJavaPackage(file_);
+ std::string package_dir = JavaPackageToDir(java_package);
+
+ if (HasDescriptorMethods(file_, options_.enforce_lite)) {
+ // Generate descriptors.
+ std::string classname = name_resolver_->GetDescriptorClassName(file_);
+ std::string filename = package_dir + classname + ".java";
+ file_list->push_back(filename);
+ std::unique_ptr<io::ZeroCopyOutputStream> output(context->Open(filename));
+ GeneratedCodeInfo annotations;
+ io::AnnotationProtoCollector<GeneratedCodeInfo> annotation_collector(
+ &annotations);
+ std::unique_ptr<io::Printer> printer(
+ new io::Printer(output.get(), '$',
+ options_.annotate_code ? &annotation_collector : NULL));
+ std::string info_relative_path = classname + ".java.pb.meta";
+ std::string info_full_path = filename + ".pb.meta";
+ printer->Print(
+ "// Generated by the protocol buffer compiler. DO NOT EDIT!\n"
+ "// source: $filename$\n"
+ "\n",
+ "filename", file_->name());
+ if (!java_package.empty()) {
+ printer->Print(
+ "package $package$;\n"
+ "\n",
+ "package", java_package);
+ }
+ PrintGeneratedAnnotation(printer.get(), '$',
+ options_.annotate_code ? info_relative_path : "");
+ printer->Print(
+ "public final class $classname$ {\n"
+ " public static com.google.protobuf.Descriptors.FileDescriptor\n"
+ " descriptor;\n"
+ " static {\n",
+ "classname", classname);
+ printer->Annotate("classname", file_->name());
+ printer->Indent();
+ printer->Indent();
+ GenerateDescriptors(printer.get());
+ printer->Outdent();
+ printer->Outdent();
+ printer->Print(
+ " }\n"
+ "}\n");
+
+ if (options_.annotate_code) {
+ std::unique_ptr<io::ZeroCopyOutputStream> info_output(
+ context->Open(info_full_path));
+ annotations.SerializeToZeroCopyStream(info_output.get());
+ annotation_file_list->push_back(info_full_path);
+ }
+
+ printer.reset();
+ output.reset();
+ }
+}
+
+void SharedCodeGenerator::GenerateDescriptors(io::Printer* printer) {
+ // Embed the descriptor. We simply serialize the entire FileDescriptorProto
+ // and embed it as a string literal, which is parsed and built into real
+ // descriptors at initialization time. We unfortunately have to put it in
+ // a string literal, not a byte array, because apparently using a literal
+ // byte array causes the Java compiler to generate *instructions* to
+ // initialize each and every byte of the array, e.g. as if you typed:
+ // b[0] = 123; b[1] = 456; b[2] = 789;
+ // This makes huge bytecode files and can easily hit the compiler's internal
+ // code size limits (error "code to large"). String literals are apparently
+ // embedded raw, which is what we want.
+ FileDescriptorProto file_proto;
+ file_->CopyTo(&file_proto);
+
+ std::string file_data;
+ file_proto.SerializeToString(&file_data);
+
+ printer->Print("java.lang.String[] descriptorData = {\n");
+ printer->Indent();
+
+ // Limit the number of bytes per line.
+ static const int kBytesPerLine = 40;
+ // Limit the number of lines per string part.
+ static const int kLinesPerPart = 400;
+ // Every block of bytes, start a new string literal, in order to avoid the
+ // 64k length limit. Note that this value needs to be <64k.
+ static const int kBytesPerPart = kBytesPerLine * kLinesPerPart;
+ for (int i = 0; i < file_data.size(); i += kBytesPerLine) {
+ if (i > 0) {
+ if (i % kBytesPerPart == 0) {
+ printer->Print(",\n");
+ } else {
+ printer->Print(" +\n");
+ }
+ }
+ printer->Print("\"$data$\"", "data",
+ CEscape(file_data.substr(i, kBytesPerLine)));
+ }
+
+ printer->Outdent();
+ printer->Print("\n};\n");
+
+ // -----------------------------------------------------------------
+ // Find out all dependencies.
+ std::vector<std::pair<std::string, std::string> > dependencies;
+ for (int i = 0; i < file_->dependency_count(); i++) {
+ std::string filename = file_->dependency(i)->name();
+ std::string package = FileJavaPackage(file_->dependency(i));
+ std::string classname =
+ name_resolver_->GetDescriptorClassName(file_->dependency(i));
+ std::string full_name;
+ if (package.empty()) {
+ full_name = classname;
+ } else {
+ full_name = package + "." + classname;
+ }
+ dependencies.push_back(std::make_pair(filename, full_name));
+ }
+
+ // -----------------------------------------------------------------
+ // Invoke internalBuildGeneratedFileFrom() to build the file.
+ printer->Print(
+ "descriptor = com.google.protobuf.Descriptors.FileDescriptor\n"
+ " .internalBuildGeneratedFileFrom(descriptorData,\n");
+ printer->Print(
+ " new com.google.protobuf.Descriptors.FileDescriptor[] {\n");
+
+ for (int i = 0; i < dependencies.size(); i++) {
+ const std::string& dependency = dependencies[i].second;
+ printer->Print(" $dependency$.getDescriptor(),\n", "dependency",
+ dependency);
+ }
+
+ printer->Print(" });\n");
+}
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_shared_code_generator.h b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_shared_code_generator.h
new file mode 100644
index 00000000..1e315863
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_shared_code_generator.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.
+
+// Author: xiaofeng@google.com (Feng Xiao)
+//
+// Generators that generate shared code between immutable API and mutable API.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_SHARED_CODE_GENERATOR_H__
+#define GOOGLE_PROTOBUF_COMPILER_JAVA_SHARED_CODE_GENERATOR_H__
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include <stubs/common.h>
+#include <compiler/java/java_options.h>
+
+namespace google {
+namespace protobuf {
+class FileDescriptor; // descriptor.h
+namespace compiler {
+class GeneratorContext; // code_generator.h
+namespace java {
+class ClassNameResolver; // name_resolver.h
+}
+} // namespace compiler
+namespace io {
+class Printer; // printer.h
+}
+} // namespace protobuf
+} // namespace google
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+// A generator that generates code that are shared between immutable API
+// and mutable API. Currently only descriptors are shared.
+class SharedCodeGenerator {
+ public:
+ SharedCodeGenerator(const FileDescriptor* file, const Options& options);
+ ~SharedCodeGenerator();
+
+ void Generate(GeneratorContext* generator_context,
+ std::vector<std::string>* file_list,
+ std::vector<std::string>* annotation_file_list);
+
+ void GenerateDescriptors(io::Printer* printer);
+
+ private:
+ std::unique_ptr<ClassNameResolver> name_resolver_;
+ const FileDescriptor* file_;
+ const Options options_;
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(SharedCodeGenerator);
+};
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_SHARED_CODE_GENERATOR_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_string_field.cc b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_string_field.cc
new file mode 100644
index 00000000..454148ca
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_string_field.cc
@@ -0,0 +1,1190 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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)
+// Author: jonp@google.com (Jon Perlow)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <compiler/java/java_string_field.h>
+
+#include <cstdint>
+#include <map>
+#include <string>
+
+#include <stubs/logging.h>
+#include <stubs/common.h>
+#include <compiler/java/java_context.h>
+#include <compiler/java/java_doc_comment.h>
+#include <compiler/java/java_helpers.h>
+#include <compiler/java/java_name_resolver.h>
+#include <io/printer.h>
+#include <wire_format.h>
+#include <stubs/strutil.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+using internal::WireFormat;
+using internal::WireFormatLite;
+
+namespace {
+
+void SetPrimitiveVariables(const FieldDescriptor* descriptor,
+ int messageBitIndex, int builderBitIndex,
+ const FieldGeneratorInfo* info,
+ ClassNameResolver* name_resolver,
+ std::map<std::string, std::string>* variables) {
+ SetCommonFieldVariables(descriptor, info, variables);
+
+ (*variables)["empty_list"] = "com.google.protobuf.LazyStringArrayList.EMPTY";
+
+ (*variables)["default"] = ImmutableDefaultValue(descriptor, name_resolver);
+ (*variables)["default_init"] =
+ "= " + ImmutableDefaultValue(descriptor, name_resolver);
+ (*variables)["capitalized_type"] = "String";
+ (*variables)["tag"] =
+ StrCat(static_cast<int32_t>(WireFormat::MakeTag(descriptor)));
+ (*variables)["tag_size"] = StrCat(
+ WireFormat::TagSize(descriptor->number(), GetType(descriptor)));
+ (*variables)["null_check"] =
+ " if (value == null) {\n"
+ " throw new NullPointerException();\n"
+ " }\n";
+ (*variables)["isStringEmpty"] = "com.google.protobuf.GeneratedMessage" +
+ GeneratedCodeVersionSuffix() +
+ ".isStringEmpty";
+ (*variables)["writeString"] = "com.google.protobuf.GeneratedMessage" +
+ GeneratedCodeVersionSuffix() + ".writeString";
+ (*variables)["computeStringSize"] = "com.google.protobuf.GeneratedMessage" +
+ GeneratedCodeVersionSuffix() +
+ ".computeStringSize";
+
+ // TODO(birdo): Add @deprecated javadoc when generating javadoc is supported
+ // by the proto compiler
+ (*variables)["deprecation"] =
+ descriptor->options().deprecated() ? "@java.lang.Deprecated " : "";
+ (*variables)["kt_deprecation"] =
+ descriptor->options().deprecated()
+ ? "@kotlin.Deprecated(message = \"Field " + (*variables)["name"] +
+ " is deprecated\") "
+ : "";
+ (*variables)["on_changed"] = "onChanged();";
+
+ if (HasHasbit(descriptor)) {
+ // For singular messages and builders, one bit is used for the hasField bit.
+ (*variables)["get_has_field_bit_message"] = GenerateGetBit(messageBitIndex);
+ (*variables)["get_has_field_bit_builder"] = GenerateGetBit(builderBitIndex);
+
+ // Note that these have a trailing ";".
+ (*variables)["set_has_field_bit_message"] =
+ GenerateSetBit(messageBitIndex) + ";";
+ (*variables)["set_has_field_bit_builder"] =
+ GenerateSetBit(builderBitIndex) + ";";
+ (*variables)["clear_has_field_bit_builder"] =
+ GenerateClearBit(builderBitIndex) + ";";
+
+ (*variables)["is_field_present_message"] = GenerateGetBit(messageBitIndex);
+ } else {
+ (*variables)["set_has_field_bit_message"] = "";
+ (*variables)["set_has_field_bit_builder"] = "";
+ (*variables)["clear_has_field_bit_builder"] = "";
+
+ (*variables)["is_field_present_message"] =
+ "!" + (*variables)["isStringEmpty"] + "(" + (*variables)["name"] + "_)";
+ }
+
+ // For repeated builders, one bit is used for whether the array is immutable.
+ (*variables)["get_mutable_bit_builder"] = GenerateGetBit(builderBitIndex);
+ (*variables)["set_mutable_bit_builder"] = GenerateSetBit(builderBitIndex);
+ (*variables)["clear_mutable_bit_builder"] = GenerateClearBit(builderBitIndex);
+
+ // For repeated fields, one bit is used for whether the array is immutable
+ // in the parsing constructor.
+ (*variables)["get_mutable_bit_parser"] =
+ GenerateGetBitMutableLocal(builderBitIndex);
+ (*variables)["set_mutable_bit_parser"] =
+ GenerateSetBitMutableLocal(builderBitIndex);
+
+ (*variables)["get_has_field_bit_from_local"] =
+ GenerateGetBitFromLocal(builderBitIndex);
+ (*variables)["set_has_field_bit_to_local"] =
+ GenerateSetBitToLocal(messageBitIndex);
+}
+
+} // namespace
+
+// ===================================================================
+
+ImmutableStringFieldGenerator::ImmutableStringFieldGenerator(
+ const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex,
+ Context* context)
+ : descriptor_(descriptor), name_resolver_(context->GetNameResolver()) {
+ SetPrimitiveVariables(descriptor, messageBitIndex, builderBitIndex,
+ context->GetFieldGeneratorInfo(descriptor),
+ name_resolver_, &variables_);
+}
+
+ImmutableStringFieldGenerator::~ImmutableStringFieldGenerator() {}
+
+int ImmutableStringFieldGenerator::GetNumBitsForMessage() const {
+ return HasHasbit(descriptor_) ? 1 : 0;
+}
+
+int ImmutableStringFieldGenerator::GetNumBitsForBuilder() const {
+ return GetNumBitsForMessage();
+}
+
+// A note about how strings are handled. This code used to just store a String
+// in the Message. This had two issues:
+//
+// 1. It wouldn't roundtrip byte arrays that were not valid UTF-8 encoded
+// strings, but rather fields that were raw bytes incorrectly marked
+// as strings in the proto file. This is common because in the proto1
+// syntax, string was the way to indicate bytes and C++ engineers can
+// easily make this mistake without affecting the C++ API. By converting to
+// strings immediately, some java code might corrupt these byte arrays as
+// it passes through a java server even if the field was never accessed by
+// application code.
+//
+// 2. There's a performance hit to converting between bytes and strings and
+// it many cases, the field is never even read by the application code. This
+// avoids unnecessary conversions in the common use cases.
+//
+// So now, the field for String is maintained as an Object reference which can
+// either store a String or a ByteString. The code uses an instanceof check
+// to see which one it has and converts to the other one if needed. It remembers
+// the last value requested (in a thread safe manner) as this is most likely
+// the one needed next. The thread safety is such that if two threads both
+// convert the field because the changes made by each thread were not visible to
+// the other, they may cause a conversion to happen more times than would
+// otherwise be necessary. This was deemed better than adding synchronization
+// overhead. It will not cause any corruption issues or affect the behavior of
+// the API. The instanceof check is also highly optimized in the JVM and we
+// decided it was better to reduce the memory overhead by not having two
+// separate fields but rather use dynamic type checking.
+//
+// For single fields, the logic for this is done inside the generated code. For
+// repeated fields, the logic is done in LazyStringArrayList and
+// UnmodifiableLazyStringList.
+void ImmutableStringFieldGenerator::GenerateInterfaceMembers(
+ io::Printer* printer) const {
+ if (HasHazzer(descriptor_)) {
+ WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
+ printer->Print(variables_,
+ "$deprecation$boolean has$capitalized_name$();\n");
+ }
+ WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
+ printer->Print(variables_,
+ "$deprecation$java.lang.String get$capitalized_name$();\n");
+ WriteFieldStringBytesAccessorDocComment(printer, descriptor_, GETTER);
+ printer->Print(variables_,
+ "$deprecation$com.google.protobuf.ByteString\n"
+ " get$capitalized_name$Bytes();\n");
+}
+
+void ImmutableStringFieldGenerator::GenerateMembers(
+ io::Printer* printer) const {
+ printer->Print(variables_, "private volatile java.lang.Object $name$_;\n");
+ PrintExtraFieldInfo(variables_, printer);
+
+ if (HasHazzer(descriptor_)) {
+ WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
+ printer->Print(
+ variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
+ " return $get_has_field_bit_message$;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ }
+
+ WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
+ printer->Print(
+ variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public java.lang.String ${$get$capitalized_name$$}$() {\n"
+ " java.lang.Object ref = $name$_;\n"
+ " if (ref instanceof java.lang.String) {\n"
+ " return (java.lang.String) ref;\n"
+ " } else {\n"
+ " com.google.protobuf.ByteString bs = \n"
+ " (com.google.protobuf.ByteString) ref;\n"
+ " java.lang.String s = bs.toStringUtf8();\n");
+ printer->Annotate("{", "}", descriptor_);
+ if (CheckUtf8(descriptor_)) {
+ printer->Print(variables_, " $name$_ = s;\n");
+ } else {
+ printer->Print(variables_,
+ " if (bs.isValidUtf8()) {\n"
+ " $name$_ = s;\n"
+ " }\n");
+ }
+ printer->Print(variables_,
+ " return s;\n"
+ " }\n"
+ "}\n");
+ WriteFieldStringBytesAccessorDocComment(printer, descriptor_, GETTER);
+ printer->Print(variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public com.google.protobuf.ByteString\n"
+ " ${$get$capitalized_name$Bytes$}$() {\n"
+ " java.lang.Object ref = $name$_;\n"
+ " if (ref instanceof java.lang.String) {\n"
+ " com.google.protobuf.ByteString b = \n"
+ " com.google.protobuf.ByteString.copyFromUtf8(\n"
+ " (java.lang.String) ref);\n"
+ " $name$_ = b;\n"
+ " return b;\n"
+ " } else {\n"
+ " return (com.google.protobuf.ByteString) ref;\n"
+ " }\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+}
+
+void ImmutableStringFieldGenerator::GenerateBuilderMembers(
+ io::Printer* printer) const {
+ printer->Print(variables_,
+ "private java.lang.Object $name$_ $default_init$;\n");
+ if (HasHazzer(descriptor_)) {
+ WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
+ printer->Print(
+ variables_,
+ "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
+ " return $get_has_field_bit_builder$;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ }
+
+ WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
+ printer->Print(
+ variables_,
+ "$deprecation$public java.lang.String ${$get$capitalized_name$$}$() {\n"
+ " java.lang.Object ref = $name$_;\n"
+ " if (!(ref instanceof java.lang.String)) {\n"
+ " com.google.protobuf.ByteString bs =\n"
+ " (com.google.protobuf.ByteString) ref;\n"
+ " java.lang.String s = bs.toStringUtf8();\n");
+ printer->Annotate("{", "}", descriptor_);
+ if (CheckUtf8(descriptor_)) {
+ printer->Print(variables_, " $name$_ = s;\n");
+ } else {
+ printer->Print(variables_,
+ " if (bs.isValidUtf8()) {\n"
+ " $name$_ = s;\n"
+ " }\n");
+ }
+ printer->Print(variables_,
+ " return s;\n"
+ " } else {\n"
+ " return (java.lang.String) ref;\n"
+ " }\n"
+ "}\n");
+
+ WriteFieldStringBytesAccessorDocComment(printer, descriptor_, GETTER);
+ printer->Print(variables_,
+ "$deprecation$public com.google.protobuf.ByteString\n"
+ " ${$get$capitalized_name$Bytes$}$() {\n"
+ " java.lang.Object ref = $name$_;\n"
+ " if (ref instanceof String) {\n"
+ " com.google.protobuf.ByteString b = \n"
+ " com.google.protobuf.ByteString.copyFromUtf8(\n"
+ " (java.lang.String) ref);\n"
+ " $name$_ = b;\n"
+ " return b;\n"
+ " } else {\n"
+ " return (com.google.protobuf.ByteString) ref;\n"
+ " }\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+
+ WriteFieldAccessorDocComment(printer, descriptor_, SETTER,
+ /* builder */ true);
+ printer->Print(variables_,
+ "$deprecation$public Builder ${$set$capitalized_name$$}$(\n"
+ " java.lang.String value) {\n"
+ "$null_check$"
+ " $set_has_field_bit_builder$\n"
+ " $name$_ = value;\n"
+ " $on_changed$\n"
+ " return this;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldAccessorDocComment(printer, descriptor_, CLEARER,
+ /* builder */ true);
+ printer->Print(
+ variables_,
+ "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n"
+ " $clear_has_field_bit_builder$\n");
+ printer->Annotate("{", "}", descriptor_);
+ // The default value is not a simple literal so we want to avoid executing
+ // it multiple times. Instead, get the default out of the default instance.
+ printer->Print(variables_,
+ " $name$_ = getDefaultInstance().get$capitalized_name$();\n");
+ printer->Print(variables_,
+ " $on_changed$\n"
+ " return this;\n"
+ "}\n");
+
+ WriteFieldStringBytesAccessorDocComment(printer, descriptor_, SETTER,
+ /* builder */ true);
+ printer->Print(
+ variables_,
+ "$deprecation$public Builder ${$set$capitalized_name$Bytes$}$(\n"
+ " com.google.protobuf.ByteString value) {\n"
+ "$null_check$");
+ printer->Annotate("{", "}", descriptor_);
+ if (CheckUtf8(descriptor_)) {
+ printer->Print(variables_, " checkByteStringIsUtf8(value);\n");
+ }
+ printer->Print(variables_,
+ " $set_has_field_bit_builder$\n"
+ " $name$_ = value;\n"
+ " $on_changed$\n"
+ " return this;\n"
+ "}\n");
+}
+
+void ImmutableStringFieldGenerator::GenerateKotlinDslMembers(
+ io::Printer* printer) const {
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$kt_deprecation$public var $kt_name$: kotlin.String\n"
+ " @JvmName(\"${$get$kt_capitalized_name$$}$\")\n"
+ " get() = $kt_dsl_builder$.${$get$capitalized_name$$}$()\n"
+ " @JvmName(\"${$set$kt_capitalized_name$$}$\")\n"
+ " set(value) {\n"
+ " $kt_dsl_builder$.${$set$capitalized_name$$}$(value)\n"
+ " }\n");
+
+ WriteFieldAccessorDocComment(printer, descriptor_, CLEARER,
+ /* builder */ false);
+ printer->Print(variables_,
+ "public fun ${$clear$kt_capitalized_name$$}$() {\n"
+ " $kt_dsl_builder$.${$clear$capitalized_name$$}$()\n"
+ "}\n");
+
+ if (HasHazzer(descriptor_)) {
+ WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
+ printer->Print(
+ variables_,
+ "public fun ${$has$kt_capitalized_name$$}$(): kotlin.Boolean {\n"
+ " return $kt_dsl_builder$.${$has$capitalized_name$$}$()\n"
+ "}\n");
+ }
+}
+
+void ImmutableStringFieldGenerator::GenerateFieldBuilderInitializationCode(
+ io::Printer* printer) const {
+ // noop for primitives
+}
+
+void ImmutableStringFieldGenerator::GenerateInitializationCode(
+ io::Printer* printer) const {
+ printer->Print(variables_, "$name$_ = $default$;\n");
+}
+
+void ImmutableStringFieldGenerator::GenerateBuilderClearCode(
+ io::Printer* printer) const {
+ printer->Print(variables_,
+ "$name$_ = $default$;\n"
+ "$clear_has_field_bit_builder$\n");
+}
+
+void ImmutableStringFieldGenerator::GenerateMergingCode(
+ io::Printer* printer) const {
+ if (HasHazzer(descriptor_)) {
+ // Allow a slight breach of abstraction here in order to avoid forcing
+ // all string fields to Strings when copying fields from a Message.
+ printer->Print(variables_,
+ "if (other.has$capitalized_name$()) {\n"
+ " $set_has_field_bit_builder$\n"
+ " $name$_ = other.$name$_;\n"
+ " $on_changed$\n"
+ "}\n");
+ } else {
+ printer->Print(variables_,
+ "if (!other.get$capitalized_name$().isEmpty()) {\n"
+ " $name$_ = other.$name$_;\n"
+ " $on_changed$\n"
+ "}\n");
+ }
+}
+
+void ImmutableStringFieldGenerator::GenerateBuildingCode(
+ io::Printer* printer) const {
+ if (HasHazzer(descriptor_)) {
+ printer->Print(variables_,
+ "if ($get_has_field_bit_from_local$) {\n"
+ " $set_has_field_bit_to_local$;\n"
+ "}\n");
+ }
+ printer->Print(variables_, "result.$name$_ = $name$_;\n");
+}
+
+void ImmutableStringFieldGenerator::GenerateParsingCode(
+ io::Printer* printer) const {
+ if (CheckUtf8(descriptor_)) {
+ printer->Print(variables_,
+ "java.lang.String s = input.readStringRequireUtf8();\n"
+ "$set_has_field_bit_message$\n"
+ "$name$_ = s;\n");
+ } else {
+ printer->Print(variables_,
+ "com.google.protobuf.ByteString bs = input.readBytes();\n"
+ "$set_has_field_bit_message$\n"
+ "$name$_ = bs;\n");
+ }
+}
+
+void ImmutableStringFieldGenerator::GenerateParsingDoneCode(
+ io::Printer* printer) const {
+ // noop for strings.
+}
+
+void ImmutableStringFieldGenerator::GenerateSerializationCode(
+ io::Printer* printer) const {
+ printer->Print(variables_,
+ "if ($is_field_present_message$) {\n"
+ " $writeString$(output, $number$, $name$_);\n"
+ "}\n");
+}
+
+void ImmutableStringFieldGenerator::GenerateSerializedSizeCode(
+ io::Printer* printer) const {
+ printer->Print(variables_,
+ "if ($is_field_present_message$) {\n"
+ " size += $computeStringSize$($number$, $name$_);\n"
+ "}\n");
+}
+
+void ImmutableStringFieldGenerator::GenerateEqualsCode(
+ io::Printer* printer) const {
+ printer->Print(variables_,
+ "if (!get$capitalized_name$()\n"
+ " .equals(other.get$capitalized_name$())) return false;\n");
+}
+
+void ImmutableStringFieldGenerator::GenerateHashCode(
+ io::Printer* printer) const {
+ printer->Print(variables_, "hash = (37 * hash) + $constant_name$;\n");
+ printer->Print(variables_,
+ "hash = (53 * hash) + get$capitalized_name$().hashCode();\n");
+}
+
+std::string ImmutableStringFieldGenerator::GetBoxedType() const {
+ return "java.lang.String";
+}
+
+// ===================================================================
+
+ImmutableStringOneofFieldGenerator::ImmutableStringOneofFieldGenerator(
+ const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex,
+ Context* context)
+ : ImmutableStringFieldGenerator(descriptor, messageBitIndex,
+ builderBitIndex, context) {
+ const OneofGeneratorInfo* info =
+ context->GetOneofGeneratorInfo(descriptor->containing_oneof());
+ SetCommonOneofVariables(descriptor, info, &variables_);
+}
+
+ImmutableStringOneofFieldGenerator::~ImmutableStringOneofFieldGenerator() {}
+
+void ImmutableStringOneofFieldGenerator::GenerateMembers(
+ io::Printer* printer) const {
+ PrintExtraFieldInfo(variables_, printer);
+ GOOGLE_DCHECK(HasHazzer(descriptor_));
+ WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
+ printer->Print(variables_,
+ "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
+ " return $has_oneof_case_message$;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+
+ WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
+ printer->Print(
+ variables_,
+ "$deprecation$public java.lang.String ${$get$capitalized_name$$}$() {\n"
+ " java.lang.Object ref $default_init$;\n"
+ " if ($has_oneof_case_message$) {\n"
+ " ref = $oneof_name$_;\n"
+ " }\n"
+ " if (ref instanceof java.lang.String) {\n"
+ " return (java.lang.String) ref;\n"
+ " } else {\n"
+ " com.google.protobuf.ByteString bs = \n"
+ " (com.google.protobuf.ByteString) ref;\n"
+ " java.lang.String s = bs.toStringUtf8();\n");
+ printer->Annotate("{", "}", descriptor_);
+ if (CheckUtf8(descriptor_)) {
+ printer->Print(variables_,
+ " if ($has_oneof_case_message$) {\n"
+ " $oneof_name$_ = s;\n"
+ " }\n");
+ } else {
+ printer->Print(variables_,
+ " if (bs.isValidUtf8() && ($has_oneof_case_message$)) {\n"
+ " $oneof_name$_ = s;\n"
+ " }\n");
+ }
+ printer->Print(variables_,
+ " return s;\n"
+ " }\n"
+ "}\n");
+ WriteFieldStringBytesAccessorDocComment(printer, descriptor_, GETTER);
+
+ printer->Print(variables_,
+ "$deprecation$public com.google.protobuf.ByteString\n"
+ " ${$get$capitalized_name$Bytes$}$() {\n"
+ " java.lang.Object ref $default_init$;\n"
+ " if ($has_oneof_case_message$) {\n"
+ " ref = $oneof_name$_;\n"
+ " }\n"
+ " if (ref instanceof java.lang.String) {\n"
+ " com.google.protobuf.ByteString b = \n"
+ " com.google.protobuf.ByteString.copyFromUtf8(\n"
+ " (java.lang.String) ref);\n"
+ " if ($has_oneof_case_message$) {\n"
+ " $oneof_name$_ = b;\n"
+ " }\n"
+ " return b;\n"
+ " } else {\n"
+ " return (com.google.protobuf.ByteString) ref;\n"
+ " }\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+}
+
+void ImmutableStringOneofFieldGenerator::GenerateBuilderMembers(
+ io::Printer* printer) const {
+ GOOGLE_DCHECK(HasHazzer(descriptor_));
+ WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
+ printer->Print(variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
+ " return $has_oneof_case_message$;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+
+ WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
+ printer->Print(
+ variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public java.lang.String ${$get$capitalized_name$$}$() {\n"
+ " java.lang.Object ref $default_init$;\n"
+ " if ($has_oneof_case_message$) {\n"
+ " ref = $oneof_name$_;\n"
+ " }\n"
+ " if (!(ref instanceof java.lang.String)) {\n"
+ " com.google.protobuf.ByteString bs =\n"
+ " (com.google.protobuf.ByteString) ref;\n"
+ " java.lang.String s = bs.toStringUtf8();\n"
+ " if ($has_oneof_case_message$) {\n");
+ printer->Annotate("{", "}", descriptor_);
+ if (CheckUtf8(descriptor_)) {
+ printer->Print(variables_, " $oneof_name$_ = s;\n");
+ } else {
+ printer->Print(variables_,
+ " if (bs.isValidUtf8()) {\n"
+ " $oneof_name$_ = s;\n"
+ " }\n");
+ }
+ printer->Print(variables_,
+ " }\n"
+ " return s;\n"
+ " } else {\n"
+ " return (java.lang.String) ref;\n"
+ " }\n"
+ "}\n");
+
+ WriteFieldStringBytesAccessorDocComment(printer, descriptor_, GETTER);
+ printer->Print(variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public com.google.protobuf.ByteString\n"
+ " ${$get$capitalized_name$Bytes$}$() {\n"
+ " java.lang.Object ref $default_init$;\n"
+ " if ($has_oneof_case_message$) {\n"
+ " ref = $oneof_name$_;\n"
+ " }\n"
+ " if (ref instanceof String) {\n"
+ " com.google.protobuf.ByteString b = \n"
+ " com.google.protobuf.ByteString.copyFromUtf8(\n"
+ " (java.lang.String) ref);\n"
+ " if ($has_oneof_case_message$) {\n"
+ " $oneof_name$_ = b;\n"
+ " }\n"
+ " return b;\n"
+ " } else {\n"
+ " return (com.google.protobuf.ByteString) ref;\n"
+ " }\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+
+ WriteFieldAccessorDocComment(printer, descriptor_, SETTER,
+ /* builder */ true);
+ printer->Print(variables_,
+ "$deprecation$public Builder ${$set$capitalized_name$$}$(\n"
+ " java.lang.String value) {\n"
+ "$null_check$"
+ " $set_oneof_case_message$;\n"
+ " $oneof_name$_ = value;\n"
+ " $on_changed$\n"
+ " return this;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldAccessorDocComment(printer, descriptor_, CLEARER,
+ /* builder */ true);
+ printer->Print(
+ variables_,
+ "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n"
+ " if ($has_oneof_case_message$) {\n"
+ " $clear_oneof_case_message$;\n"
+ " $oneof_name$_ = null;\n"
+ " $on_changed$\n"
+ " }\n"
+ " return this;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+
+ WriteFieldStringBytesAccessorDocComment(printer, descriptor_, SETTER,
+ /* builder */ true);
+ printer->Print(
+ variables_,
+ "$deprecation$public Builder ${$set$capitalized_name$Bytes$}$(\n"
+ " com.google.protobuf.ByteString value) {\n"
+ "$null_check$");
+ printer->Annotate("{", "}", descriptor_);
+ if (CheckUtf8(descriptor_)) {
+ printer->Print(variables_, " checkByteStringIsUtf8(value);\n");
+ }
+ printer->Print(variables_,
+ " $set_oneof_case_message$;\n"
+ " $oneof_name$_ = value;\n"
+ " $on_changed$\n"
+ " return this;\n"
+ "}\n");
+}
+
+void ImmutableStringOneofFieldGenerator::GenerateMergingCode(
+ io::Printer* printer) const {
+ // Allow a slight breach of abstraction here in order to avoid forcing
+ // all string fields to Strings when copying fields from a Message.
+ printer->Print(variables_,
+ "$set_oneof_case_message$;\n"
+ "$oneof_name$_ = other.$oneof_name$_;\n"
+ "$on_changed$\n");
+}
+
+void ImmutableStringOneofFieldGenerator::GenerateBuildingCode(
+ io::Printer* printer) const {
+ printer->Print(variables_,
+ "if ($has_oneof_case_message$) {\n"
+ " result.$oneof_name$_ = $oneof_name$_;\n"
+ "}\n");
+}
+
+void ImmutableStringOneofFieldGenerator::GenerateParsingCode(
+ io::Printer* printer) const {
+ if (CheckUtf8(descriptor_)) {
+ printer->Print(variables_,
+ "java.lang.String s = input.readStringRequireUtf8();\n"
+ "$set_oneof_case_message$;\n"
+ "$oneof_name$_ = s;\n");
+ } else {
+ printer->Print(variables_,
+ "com.google.protobuf.ByteString bs = input.readBytes();\n"
+ "$set_oneof_case_message$;\n"
+ "$oneof_name$_ = bs;\n");
+ }
+}
+
+void ImmutableStringOneofFieldGenerator::GenerateSerializationCode(
+ io::Printer* printer) const {
+ printer->Print(variables_,
+ "if ($has_oneof_case_message$) {\n"
+ " $writeString$(output, $number$, $oneof_name$_);\n"
+ "}\n");
+}
+
+void ImmutableStringOneofFieldGenerator::GenerateSerializedSizeCode(
+ io::Printer* printer) const {
+ printer->Print(variables_,
+ "if ($has_oneof_case_message$) {\n"
+ " size += $computeStringSize$($number$, $oneof_name$_);\n"
+ "}\n");
+}
+
+// ===================================================================
+
+RepeatedImmutableStringFieldGenerator::RepeatedImmutableStringFieldGenerator(
+ const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex,
+ Context* context)
+ : descriptor_(descriptor), name_resolver_(context->GetNameResolver()) {
+ SetPrimitiveVariables(descriptor, messageBitIndex, builderBitIndex,
+ context->GetFieldGeneratorInfo(descriptor),
+ name_resolver_, &variables_);
+}
+
+RepeatedImmutableStringFieldGenerator::
+ ~RepeatedImmutableStringFieldGenerator() {}
+
+int RepeatedImmutableStringFieldGenerator::GetNumBitsForMessage() const {
+ return 0;
+}
+
+int RepeatedImmutableStringFieldGenerator::GetNumBitsForBuilder() const {
+ return 1;
+}
+
+void RepeatedImmutableStringFieldGenerator::GenerateInterfaceMembers(
+ io::Printer* printer) const {
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_GETTER);
+ printer->Print(
+ variables_,
+ // NOTE: the same method in the implementation class actually returns
+ // com.google.protobuf.ProtocolStringList (a subclass of List). It's
+ // changed between protobuf 2.5.0 release and protobuf 2.6.1 release.
+ // To retain binary compatibility with both 2.5.0 and 2.6.1 generated
+ // code, we make this interface method return List so both methods
+ // with different return types exist in the compiled byte code.
+ "$deprecation$java.util.List<java.lang.String>\n"
+ " get$capitalized_name$List();\n");
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_COUNT);
+ printer->Print(variables_,
+ "$deprecation$int get$capitalized_name$Count();\n");
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_GETTER);
+ printer->Print(
+ variables_,
+ "$deprecation$java.lang.String get$capitalized_name$(int index);\n");
+ WriteFieldStringBytesAccessorDocComment(printer, descriptor_,
+ LIST_INDEXED_GETTER);
+ printer->Print(variables_,
+ "$deprecation$com.google.protobuf.ByteString\n"
+ " get$capitalized_name$Bytes(int index);\n");
+}
+
+void RepeatedImmutableStringFieldGenerator::GenerateMembers(
+ io::Printer* printer) const {
+ printer->Print(variables_,
+ "private com.google.protobuf.LazyStringList $name$_;\n");
+ PrintExtraFieldInfo(variables_, printer);
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_GETTER);
+ printer->Print(variables_,
+ "$deprecation$public com.google.protobuf.ProtocolStringList\n"
+ " ${$get$capitalized_name$List$}$() {\n"
+ " return $name$_;\n" // note: unmodifiable list
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_COUNT);
+ printer->Print(
+ variables_,
+ "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n"
+ " return $name$_.size();\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_GETTER);
+ printer->Print(variables_,
+ "$deprecation$public java.lang.String "
+ "${$get$capitalized_name$$}$(int index) {\n"
+ " return $name$_.get(index);\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldStringBytesAccessorDocComment(printer, descriptor_,
+ LIST_INDEXED_GETTER);
+ printer->Print(variables_,
+ "$deprecation$public com.google.protobuf.ByteString\n"
+ " ${$get$capitalized_name$Bytes$}$(int index) {\n"
+ " return $name$_.getByteString(index);\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+}
+
+void RepeatedImmutableStringFieldGenerator::GenerateBuilderMembers(
+ io::Printer* printer) const {
+ // One field is the list and the bit field keeps track of whether the
+ // list is immutable. If it's immutable, the invariant is that it must
+ // either an instance of Collections.emptyList() or it's an ArrayList
+ // wrapped in a Collections.unmodifiableList() wrapper and nobody else has
+ // a reference to the underlying ArrayList. This invariant allows us to
+ // share instances of lists between protocol buffers avoiding expensive
+ // memory allocations. Note, immutable is a strong guarantee here -- not
+ // just that the list cannot be modified via the reference but that the
+ // list can never be modified.
+ printer->Print(
+ variables_,
+ "private com.google.protobuf.LazyStringList $name$_ = $empty_list$;\n");
+
+ printer->Print(
+ variables_,
+ "private void ensure$capitalized_name$IsMutable() {\n"
+ " if (!$get_mutable_bit_builder$) {\n"
+ " $name$_ = new com.google.protobuf.LazyStringArrayList($name$_);\n"
+ " $set_mutable_bit_builder$;\n"
+ " }\n"
+ "}\n");
+
+ // Note: We return an unmodifiable list because otherwise the caller
+ // could hold on to the returned list and modify it after the message
+ // has been built, thus mutating the message which is supposed to be
+ // immutable.
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_GETTER);
+ printer->Print(variables_,
+ "$deprecation$public com.google.protobuf.ProtocolStringList\n"
+ " ${$get$capitalized_name$List$}$() {\n"
+ " return $name$_.getUnmodifiableView();\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_COUNT);
+ printer->Print(
+ variables_,
+ "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n"
+ " return $name$_.size();\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_GETTER);
+ printer->Print(variables_,
+ "$deprecation$public java.lang.String "
+ "${$get$capitalized_name$$}$(int index) {\n"
+ " return $name$_.get(index);\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldStringBytesAccessorDocComment(printer, descriptor_,
+ LIST_INDEXED_GETTER);
+ printer->Print(variables_,
+ "$deprecation$public com.google.protobuf.ByteString\n"
+ " ${$get$capitalized_name$Bytes$}$(int index) {\n"
+ " return $name$_.getByteString(index);\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_SETTER,
+ /* builder */ true);
+ printer->Print(variables_,
+ "$deprecation$public Builder ${$set$capitalized_name$$}$(\n"
+ " int index, java.lang.String value) {\n"
+ "$null_check$"
+ " ensure$capitalized_name$IsMutable();\n"
+ " $name$_.set(index, value);\n"
+ " $on_changed$\n"
+ " return this;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_ADDER,
+ /* builder */ true);
+ printer->Print(variables_,
+ "$deprecation$public Builder ${$add$capitalized_name$$}$(\n"
+ " java.lang.String value) {\n"
+ "$null_check$"
+ " ensure$capitalized_name$IsMutable();\n"
+ " $name$_.add(value);\n"
+ " $on_changed$\n"
+ " return this;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_MULTI_ADDER,
+ /* builder */ true);
+ printer->Print(variables_,
+ "$deprecation$public Builder ${$addAll$capitalized_name$$}$(\n"
+ " java.lang.Iterable<java.lang.String> values) {\n"
+ " ensure$capitalized_name$IsMutable();\n"
+ " com.google.protobuf.AbstractMessageLite.Builder.addAll(\n"
+ " values, $name$_);\n"
+ " $on_changed$\n"
+ " return this;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldAccessorDocComment(printer, descriptor_, CLEARER,
+ /* builder */ true);
+ printer->Print(
+ variables_,
+ "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n"
+ " $name$_ = $empty_list$;\n"
+ " $clear_mutable_bit_builder$;\n"
+ " $on_changed$\n"
+ " return this;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+
+ WriteFieldStringBytesAccessorDocComment(printer, descriptor_, LIST_ADDER,
+ /* builder */ true);
+ printer->Print(
+ variables_,
+ "$deprecation$public Builder ${$add$capitalized_name$Bytes$}$(\n"
+ " com.google.protobuf.ByteString value) {\n"
+ "$null_check$");
+ printer->Annotate("{", "}", descriptor_);
+ if (CheckUtf8(descriptor_)) {
+ printer->Print(variables_, " checkByteStringIsUtf8(value);\n");
+ }
+ printer->Print(variables_,
+ " ensure$capitalized_name$IsMutable();\n"
+ " $name$_.add(value);\n"
+ " $on_changed$\n"
+ " return this;\n"
+ "}\n");
+}
+
+void RepeatedImmutableStringFieldGenerator::GenerateKotlinDslMembers(
+ io::Printer* printer) const {
+ printer->Print(
+ variables_,
+ "/**\n"
+ " * An uninstantiable, behaviorless type to represent the field in\n"
+ " * generics.\n"
+ " */\n"
+ "@kotlin.OptIn"
+ "(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)\n"
+ "public class ${$$kt_capitalized_name$Proxy$}$ private constructor()"
+ " : com.google.protobuf.kotlin.DslProxy()\n");
+
+ // property for List<String>
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_GETTER);
+ printer->Print(variables_,
+ "$kt_deprecation$public val $kt_name$: "
+ "com.google.protobuf.kotlin.DslList"
+ "<kotlin.String, ${$$kt_capitalized_name$Proxy$}$>\n"
+ " @kotlin.jvm.JvmSynthetic\n"
+ " get() = com.google.protobuf.kotlin.DslList(\n"
+ " $kt_dsl_builder$.${$get$capitalized_name$List$}$()\n"
+ " )\n");
+
+ // List<String>.add(String)
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_ADDER,
+ /* builder */ false);
+ printer->Print(variables_,
+ "@kotlin.jvm.JvmSynthetic\n"
+ "@kotlin.jvm.JvmName(\"add$kt_capitalized_name$\")\n"
+ "public fun com.google.protobuf.kotlin.DslList"
+ "<kotlin.String, ${$$kt_capitalized_name$Proxy$}$>."
+ "add(value: kotlin.String) {\n"
+ " $kt_dsl_builder$.${$add$capitalized_name$$}$(value)\n"
+ "}\n");
+
+ // List<String> += String
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_ADDER,
+ /* builder */ false);
+ printer->Print(variables_,
+ "@kotlin.jvm.JvmSynthetic\n"
+ "@kotlin.jvm.JvmName(\"plusAssign$kt_capitalized_name$\")\n"
+ "@Suppress(\"NOTHING_TO_INLINE\")\n"
+ "public inline operator fun com.google.protobuf.kotlin.DslList"
+ "<kotlin.String, ${$$kt_capitalized_name$Proxy$}$>."
+ "plusAssign(value: kotlin.String) {\n"
+ " add(value)\n"
+ "}\n");
+
+ // List<String>.addAll(Iterable<String>)
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_MULTI_ADDER,
+ /* builder */ false);
+ printer->Print(
+ variables_,
+ "@kotlin.jvm.JvmSynthetic\n"
+ "@kotlin.jvm.JvmName(\"addAll$kt_capitalized_name$\")\n"
+ "public fun com.google.protobuf.kotlin.DslList"
+ "<kotlin.String, ${$$kt_capitalized_name$Proxy$}$>."
+ "addAll(values: kotlin.collections.Iterable<kotlin.String>) {\n"
+ " $kt_dsl_builder$.${$addAll$capitalized_name$$}$(values)\n"
+ "}\n");
+
+ // List<String> += Iterable<String>
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_MULTI_ADDER,
+ /* builder */ false);
+ printer->Print(
+ variables_,
+ "@kotlin.jvm.JvmSynthetic\n"
+ "@kotlin.jvm.JvmName(\"plusAssignAll$kt_capitalized_name$\")\n"
+ "@Suppress(\"NOTHING_TO_INLINE\")\n"
+ "public inline operator fun com.google.protobuf.kotlin.DslList"
+ "<kotlin.String, ${$$kt_capitalized_name$Proxy$}$>."
+ "plusAssign(values: kotlin.collections.Iterable<kotlin.String>) {\n"
+ " addAll(values)\n"
+ "}\n");
+
+ // List<String>[Int] = String
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_SETTER,
+ /* builder */ false);
+ printer->Print(
+ variables_,
+ "@kotlin.jvm.JvmSynthetic\n"
+ "@kotlin.jvm.JvmName(\"set$kt_capitalized_name$\")\n"
+ "public operator fun com.google.protobuf.kotlin.DslList"
+ "<kotlin.String, ${$$kt_capitalized_name$Proxy$}$>."
+ "set(index: kotlin.Int, value: kotlin.String) {\n"
+ " $kt_dsl_builder$.${$set$capitalized_name$$}$(index, value)\n"
+ "}");
+
+ WriteFieldAccessorDocComment(printer, descriptor_, CLEARER,
+ /* builder */ false);
+ printer->Print(variables_,
+ "@kotlin.jvm.JvmSynthetic\n"
+ "@kotlin.jvm.JvmName(\"clear$kt_capitalized_name$\")\n"
+ "public fun com.google.protobuf.kotlin.DslList"
+ "<kotlin.String, ${$$kt_capitalized_name$Proxy$}$>."
+ "clear() {\n"
+ " $kt_dsl_builder$.${$clear$capitalized_name$$}$()\n"
+ "}");
+}
+
+void RepeatedImmutableStringFieldGenerator::
+ GenerateFieldBuilderInitializationCode(io::Printer* printer) const {
+ // noop for primitives
+}
+
+void RepeatedImmutableStringFieldGenerator::GenerateInitializationCode(
+ io::Printer* printer) const {
+ printer->Print(variables_, "$name$_ = $empty_list$;\n");
+}
+
+void RepeatedImmutableStringFieldGenerator::GenerateBuilderClearCode(
+ io::Printer* printer) const {
+ printer->Print(variables_,
+ "$name$_ = $empty_list$;\n"
+ "$clear_mutable_bit_builder$;\n");
+}
+
+void RepeatedImmutableStringFieldGenerator::GenerateMergingCode(
+ io::Printer* printer) const {
+ // The code below does two optimizations:
+ // 1. If the other list is empty, there's nothing to do. This ensures we
+ // don't allocate a new array if we already have an immutable one.
+ // 2. If the other list is non-empty and our current list is empty, we can
+ // reuse the other list which is guaranteed to be immutable.
+ printer->Print(variables_,
+ "if (!other.$name$_.isEmpty()) {\n"
+ " if ($name$_.isEmpty()) {\n"
+ " $name$_ = other.$name$_;\n"
+ " $clear_mutable_bit_builder$;\n"
+ " } else {\n"
+ " ensure$capitalized_name$IsMutable();\n"
+ " $name$_.addAll(other.$name$_);\n"
+ " }\n"
+ " $on_changed$\n"
+ "}\n");
+}
+
+void RepeatedImmutableStringFieldGenerator::GenerateBuildingCode(
+ io::Printer* printer) const {
+ // The code below ensures that the result has an immutable list. If our
+ // list is immutable, we can just reuse it. If not, we make it immutable.
+
+ printer->Print(variables_,
+ "if ($get_mutable_bit_builder$) {\n"
+ " $name$_ = $name$_.getUnmodifiableView();\n"
+ " $clear_mutable_bit_builder$;\n"
+ "}\n"
+ "result.$name$_ = $name$_;\n");
+}
+
+void RepeatedImmutableStringFieldGenerator::GenerateParsingCode(
+ io::Printer* printer) const {
+ if (CheckUtf8(descriptor_)) {
+ printer->Print(variables_,
+ "java.lang.String s = input.readStringRequireUtf8();\n");
+ } else {
+ printer->Print(variables_,
+ "com.google.protobuf.ByteString bs = input.readBytes();\n");
+ }
+ printer->Print(variables_,
+ "if (!$get_mutable_bit_parser$) {\n"
+ " $name$_ = new com.google.protobuf.LazyStringArrayList();\n"
+ " $set_mutable_bit_parser$;\n"
+ "}\n");
+ if (CheckUtf8(descriptor_)) {
+ printer->Print(variables_, "$name$_.add(s);\n");
+ } else {
+ printer->Print(variables_, "$name$_.add(bs);\n");
+ }
+}
+
+void RepeatedImmutableStringFieldGenerator::GenerateParsingDoneCode(
+ io::Printer* printer) const {
+ printer->Print(variables_,
+ "if ($get_mutable_bit_parser$) {\n"
+ " $name$_ = $name$_.getUnmodifiableView();\n"
+ "}\n");
+}
+
+void RepeatedImmutableStringFieldGenerator::GenerateSerializationCode(
+ io::Printer* printer) const {
+ printer->Print(variables_,
+ "for (int i = 0; i < $name$_.size(); i++) {\n"
+ " $writeString$(output, $number$, $name$_.getRaw(i));\n"
+ "}\n");
+}
+
+void RepeatedImmutableStringFieldGenerator::GenerateSerializedSizeCode(
+ io::Printer* printer) const {
+ printer->Print(variables_,
+ "{\n"
+ " int dataSize = 0;\n");
+ printer->Indent();
+
+ printer->Print(variables_,
+ "for (int i = 0; i < $name$_.size(); i++) {\n"
+ " dataSize += computeStringSizeNoTag($name$_.getRaw(i));\n"
+ "}\n");
+
+ printer->Print("size += dataSize;\n");
+
+ printer->Print(variables_,
+ "size += $tag_size$ * get$capitalized_name$List().size();\n");
+
+ printer->Outdent();
+ printer->Print("}\n");
+}
+
+void RepeatedImmutableStringFieldGenerator::GenerateEqualsCode(
+ io::Printer* printer) const {
+ printer->Print(
+ variables_,
+ "if (!get$capitalized_name$List()\n"
+ " .equals(other.get$capitalized_name$List())) return false;\n");
+}
+
+void RepeatedImmutableStringFieldGenerator::GenerateHashCode(
+ io::Printer* printer) const {
+ printer->Print(
+ variables_,
+ "if (get$capitalized_name$Count() > 0) {\n"
+ " hash = (37 * hash) + $constant_name$;\n"
+ " hash = (53 * hash) + get$capitalized_name$List().hashCode();\n"
+ "}\n");
+}
+
+std::string RepeatedImmutableStringFieldGenerator::GetBoxedType() const {
+ return "String";
+}
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_string_field.h b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_string_field.h
new file mode 100644
index 00000000..03fd43ec
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_string_field.h
@@ -0,0 +1,160 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Author: jonp@google.com (Jon Perlow)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_STRING_FIELD_H__
+#define GOOGLE_PROTOBUF_COMPILER_JAVA_STRING_FIELD_H__
+
+#include <map>
+#include <string>
+#include <compiler/java/java_field.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+class Context; // context.h
+class ClassNameResolver; // name_resolver.h
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+class ImmutableStringFieldGenerator : public ImmutableFieldGenerator {
+ public:
+ explicit ImmutableStringFieldGenerator(const FieldDescriptor* descriptor,
+ int messageBitIndex,
+ int builderBitIndex, Context* context);
+ ~ImmutableStringFieldGenerator();
+
+ // implements ImmutableFieldGenerator
+ // ---------------------------------------
+ int GetNumBitsForMessage() const override;
+ int GetNumBitsForBuilder() const override;
+ void GenerateInterfaceMembers(io::Printer* printer) const override;
+ void GenerateMembers(io::Printer* printer) const override;
+ void GenerateBuilderMembers(io::Printer* printer) const override;
+ void GenerateInitializationCode(io::Printer* printer) const override;
+ void GenerateBuilderClearCode(io::Printer* printer) const override;
+ void GenerateMergingCode(io::Printer* printer) const override;
+ void GenerateBuildingCode(io::Printer* printer) const override;
+ void GenerateParsingCode(io::Printer* printer) const override;
+ void GenerateParsingDoneCode(io::Printer* printer) const override;
+ void GenerateSerializationCode(io::Printer* printer) const override;
+ void GenerateSerializedSizeCode(io::Printer* printer) const override;
+ void GenerateFieldBuilderInitializationCode(
+ io::Printer* printer) const override;
+ void GenerateEqualsCode(io::Printer* printer) const override;
+ void GenerateHashCode(io::Printer* printer) const override;
+ void GenerateKotlinDslMembers(io::Printer* printer) const override;
+
+ std::string GetBoxedType() const override;
+
+ protected:
+ const FieldDescriptor* descriptor_;
+ std::map<std::string, std::string> variables_;
+ ClassNameResolver* name_resolver_;
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableStringFieldGenerator);
+};
+
+class ImmutableStringOneofFieldGenerator
+ : public ImmutableStringFieldGenerator {
+ public:
+ ImmutableStringOneofFieldGenerator(const FieldDescriptor* descriptor,
+ int messageBitIndex, int builderBitIndex,
+ Context* context);
+ ~ImmutableStringOneofFieldGenerator();
+
+ private:
+ void GenerateMembers(io::Printer* printer) const override;
+ void GenerateBuilderMembers(io::Printer* printer) const override;
+ void GenerateMergingCode(io::Printer* printer) const override;
+ void GenerateBuildingCode(io::Printer* printer) const override;
+ void GenerateParsingCode(io::Printer* printer) const override;
+ void GenerateSerializationCode(io::Printer* printer) const override;
+ void GenerateSerializedSizeCode(io::Printer* printer) const override;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableStringOneofFieldGenerator);
+};
+
+class RepeatedImmutableStringFieldGenerator : public ImmutableFieldGenerator {
+ public:
+ explicit RepeatedImmutableStringFieldGenerator(
+ const FieldDescriptor* descriptor, int messageBitIndex,
+ int builderBitIndex, Context* context);
+ ~RepeatedImmutableStringFieldGenerator() override;
+
+ // implements ImmutableFieldGenerator ---------------------------------------
+ int GetNumBitsForMessage() const override;
+ int GetNumBitsForBuilder() const override;
+ void GenerateInterfaceMembers(io::Printer* printer) const override;
+ void GenerateMembers(io::Printer* printer) const override;
+ void GenerateBuilderMembers(io::Printer* printer) const override;
+ void GenerateInitializationCode(io::Printer* printer) const override;
+ void GenerateBuilderClearCode(io::Printer* printer) const override;
+ void GenerateMergingCode(io::Printer* printer) const override;
+ void GenerateBuildingCode(io::Printer* printer) const override;
+ void GenerateParsingCode(io::Printer* printer) const override;
+ void GenerateParsingDoneCode(io::Printer* printer) const override;
+ void GenerateSerializationCode(io::Printer* printer) const override;
+ void GenerateSerializedSizeCode(io::Printer* printer) const override;
+ void GenerateFieldBuilderInitializationCode(
+ io::Printer* printer) const override;
+ void GenerateEqualsCode(io::Printer* printer) const override;
+ void GenerateHashCode(io::Printer* printer) const override;
+ void GenerateKotlinDslMembers(io::Printer* printer) const override;
+
+ std::string GetBoxedType() const override;
+
+ private:
+ const FieldDescriptor* descriptor_;
+ std::map<std::string, std::string> variables_;
+ ClassNameResolver* name_resolver_;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedImmutableStringFieldGenerator);
+};
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_STRING_FIELD_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_string_field_lite.cc b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_string_field_lite.cc
new file mode 100644
index 00000000..6f52fd8f
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_string_field_lite.cc
@@ -0,0 +1,864 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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)
+// Author: jonp@google.com (Jon Perlow)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <compiler/java/java_string_field_lite.h>
+
+#include <cstdint>
+#include <map>
+#include <string>
+
+#include <stubs/logging.h>
+#include <stubs/common.h>
+#include <compiler/java/java_context.h>
+#include <compiler/java/java_doc_comment.h>
+#include <compiler/java/java_helpers.h>
+#include <compiler/java/java_name_resolver.h>
+#include <io/printer.h>
+#include <wire_format.h>
+#include <stubs/strutil.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+using internal::WireFormat;
+using internal::WireFormatLite;
+
+namespace {
+
+void SetPrimitiveVariables(const FieldDescriptor* descriptor,
+ int messageBitIndex, int builderBitIndex,
+ const FieldGeneratorInfo* info,
+ ClassNameResolver* name_resolver,
+ std::map<std::string, std::string>* variables) {
+ SetCommonFieldVariables(descriptor, info, variables);
+
+ (*variables)["empty_list"] =
+ "com.google.protobuf.GeneratedMessageLite.emptyProtobufList()";
+
+ (*variables)["default"] = ImmutableDefaultValue(descriptor, name_resolver);
+ (*variables)["default_init"] =
+ "= " + ImmutableDefaultValue(descriptor, name_resolver);
+ (*variables)["capitalized_type"] = "java.lang.String";
+ (*variables)["tag"] =
+ StrCat(static_cast<int32_t>(WireFormat::MakeTag(descriptor)));
+ (*variables)["tag_size"] = StrCat(
+ WireFormat::TagSize(descriptor->number(), GetType(descriptor)));
+ // We use `x.getClass()` as a null check because it generates less bytecode
+ // than an `if (x == null) { throw ... }` statement.
+ (*variables)["null_check"] =
+ " java.lang.Class<?> valueClass = value.getClass();\n";
+
+ // TODO(birdo): Add @deprecated javadoc when generating javadoc is supported
+ // by the proto compiler
+ (*variables)["deprecation"] =
+ descriptor->options().deprecated() ? "@java.lang.Deprecated " : "";
+ (*variables)["kt_deprecation"] =
+ descriptor->options().deprecated()
+ ? "@kotlin.Deprecated(message = \"Field " + (*variables)["name"] +
+ " is deprecated\") "
+ : "";
+ (*variables)["required"] = descriptor->is_required() ? "true" : "false";
+
+ if (HasHasbit(descriptor)) {
+ // For singular messages and builders, one bit is used for the hasField bit.
+ (*variables)["get_has_field_bit_message"] = GenerateGetBit(messageBitIndex);
+
+ // Note that these have a trailing ";".
+ (*variables)["set_has_field_bit_message"] =
+ GenerateSetBit(messageBitIndex) + ";";
+ (*variables)["clear_has_field_bit_message"] =
+ GenerateClearBit(messageBitIndex) + ";";
+
+ (*variables)["is_field_present_message"] = GenerateGetBit(messageBitIndex);
+ } else {
+ (*variables)["set_has_field_bit_message"] = "";
+ (*variables)["clear_has_field_bit_message"] = "";
+
+ (*variables)["is_field_present_message"] =
+ "!" + (*variables)["name"] + "_.isEmpty()";
+ }
+
+ (*variables)["get_has_field_bit_from_local"] =
+ GenerateGetBitFromLocal(builderBitIndex);
+ (*variables)["set_has_field_bit_to_local"] =
+ GenerateSetBitToLocal(messageBitIndex);
+}
+
+} // namespace
+
+// ===================================================================
+
+ImmutableStringFieldLiteGenerator::ImmutableStringFieldLiteGenerator(
+ const FieldDescriptor* descriptor, int messageBitIndex, Context* context)
+ : descriptor_(descriptor),
+ messageBitIndex_(messageBitIndex),
+ name_resolver_(context->GetNameResolver()) {
+ SetPrimitiveVariables(descriptor, messageBitIndex, 0,
+ context->GetFieldGeneratorInfo(descriptor),
+ name_resolver_, &variables_);
+}
+
+ImmutableStringFieldLiteGenerator::~ImmutableStringFieldLiteGenerator() {}
+
+int ImmutableStringFieldLiteGenerator::GetNumBitsForMessage() const {
+ return HasHasbit(descriptor_) ? 1 : 0;
+}
+
+// A note about how strings are handled. In the SPEED and CODE_SIZE runtimes,
+// strings are not stored as java.lang.String in the Message because of two
+// issues:
+//
+// 1. It wouldn't roundtrip byte arrays that were not valid UTF-8 encoded
+// strings, but rather fields that were raw bytes incorrectly marked
+// as strings in the proto file. This is common because in the proto1
+// syntax, string was the way to indicate bytes and C++ engineers can
+// easily make this mistake without affecting the C++ API. By converting to
+// strings immediately, some java code might corrupt these byte arrays as
+// it passes through a java server even if the field was never accessed by
+// application code.
+//
+// 2. There's a performance hit to converting between bytes and strings and
+// it many cases, the field is never even read by the application code. This
+// avoids unnecessary conversions in the common use cases.
+//
+// In the LITE_RUNTIME, we store strings as java.lang.String because we assume
+// that the users of this runtime are not subject to proto1 constraints and are
+// running code on devices that are user facing. That is, the developers are
+// properly incentivized to only fetch the data they need to read and wish to
+// reduce the number of allocations incurred when running on a user's device.
+
+// TODO(dweis): Consider dropping all of the *Bytes() methods. They really
+// shouldn't be necessary or used on devices.
+void ImmutableStringFieldLiteGenerator::GenerateInterfaceMembers(
+ io::Printer* printer) const {
+ if (HasHazzer(descriptor_)) {
+ WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
+ printer->Print(variables_,
+ "$deprecation$boolean has$capitalized_name$();\n");
+ }
+ WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
+ printer->Print(variables_,
+ "$deprecation$java.lang.String get$capitalized_name$();\n");
+ WriteFieldStringBytesAccessorDocComment(printer, descriptor_, GETTER);
+ printer->Print(variables_,
+ "$deprecation$com.google.protobuf.ByteString\n"
+ " get$capitalized_name$Bytes();\n");
+}
+
+void ImmutableStringFieldLiteGenerator::GenerateMembers(
+ io::Printer* printer) const {
+ printer->Print(variables_, "private java.lang.String $name$_;\n");
+ PrintExtraFieldInfo(variables_, printer);
+
+ if (HasHazzer(descriptor_)) {
+ WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
+ printer->Print(
+ variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
+ " return $get_has_field_bit_message$;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ }
+
+ WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
+ printer->Print(
+ variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public java.lang.String ${$get$capitalized_name$$}$() {\n"
+ " return $name$_;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldStringBytesAccessorDocComment(printer, descriptor_, GETTER);
+ printer->Print(
+ variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public com.google.protobuf.ByteString\n"
+ " ${$get$capitalized_name$Bytes$}$() {\n"
+ " return com.google.protobuf.ByteString.copyFromUtf8($name$_);\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+
+ WriteFieldAccessorDocComment(printer, descriptor_, SETTER);
+ printer->Print(variables_,
+ "private void set$capitalized_name$(\n"
+ " java.lang.String value) {\n"
+ "$null_check$"
+ " $set_has_field_bit_message$\n"
+ " $name$_ = value;\n"
+ "}\n");
+ WriteFieldAccessorDocComment(printer, descriptor_, CLEARER);
+ printer->Print(variables_,
+ "private void clear$capitalized_name$() {\n"
+ " $clear_has_field_bit_message$\n"
+ // The default value is not a simple literal so we want to
+ // avoid executing it multiple times. Instead, get the default
+ // out of the default instance.
+ " $name$_ = getDefaultInstance().get$capitalized_name$();\n"
+ "}\n");
+
+ WriteFieldStringBytesAccessorDocComment(printer, descriptor_, SETTER);
+ printer->Print(variables_,
+ "private void set$capitalized_name$Bytes(\n"
+ " com.google.protobuf.ByteString value) {\n");
+ if (CheckUtf8(descriptor_)) {
+ printer->Print(variables_, " checkByteStringIsUtf8(value);\n");
+ }
+ printer->Print(variables_,
+ " $name$_ = value.toStringUtf8();\n"
+ " $set_has_field_bit_message$\n"
+ "}\n");
+}
+
+void ImmutableStringFieldLiteGenerator::GenerateBuilderMembers(
+ io::Printer* printer) const {
+ if (HasHazzer(descriptor_)) {
+ WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
+ printer->Print(
+ variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
+ " return instance.has$capitalized_name$();\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ }
+
+ WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
+ printer->Print(
+ variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public java.lang.String ${$get$capitalized_name$$}$() {\n"
+ " return instance.get$capitalized_name$();\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+
+ WriteFieldStringBytesAccessorDocComment(printer, descriptor_, GETTER);
+ printer->Print(variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public com.google.protobuf.ByteString\n"
+ " ${$get$capitalized_name$Bytes$}$() {\n"
+ " return instance.get$capitalized_name$Bytes();\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+
+ WriteFieldAccessorDocComment(printer, descriptor_, SETTER,
+ /* builder */ true);
+ printer->Print(variables_,
+ "$deprecation$public Builder ${$set$capitalized_name$$}$(\n"
+ " java.lang.String value) {\n"
+ " copyOnWrite();\n"
+ " instance.set$capitalized_name$(value);\n"
+ " return this;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldAccessorDocComment(printer, descriptor_, CLEARER,
+ /* builder */ true);
+ printer->Print(
+ variables_,
+ "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n"
+ " copyOnWrite();\n"
+ " instance.clear$capitalized_name$();\n"
+ " return this;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+
+ WriteFieldStringBytesAccessorDocComment(printer, descriptor_, SETTER,
+ /* builder */ true);
+ printer->Print(
+ variables_,
+ "$deprecation$public Builder ${$set$capitalized_name$Bytes$}$(\n"
+ " com.google.protobuf.ByteString value) {\n"
+ " copyOnWrite();\n"
+ " instance.set$capitalized_name$Bytes(value);\n"
+ " return this;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+}
+
+void ImmutableStringFieldLiteGenerator::GenerateKotlinDslMembers(
+ io::Printer* printer) const {
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(variables_,
+ "$kt_deprecation$public var $kt_name$: kotlin.String\n"
+ " @JvmName(\"${$get$kt_capitalized_name$$}$\")\n"
+ " get() = $kt_dsl_builder$.${$get$capitalized_name$$}$()\n"
+ " @JvmName(\"${$set$kt_capitalized_name$$}$\")\n"
+ " set(value) {\n"
+ " $kt_dsl_builder$.${$set$capitalized_name$$}$(value)\n"
+ " }\n");
+
+ WriteFieldAccessorDocComment(printer, descriptor_, CLEARER,
+ /* builder */ false);
+ printer->Print(variables_,
+ "public fun ${$clear$kt_capitalized_name$$}$() {\n"
+ " $kt_dsl_builder$.${$clear$capitalized_name$$}$()\n"
+ "}\n");
+
+ if (HasHazzer(descriptor_)) {
+ WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
+ printer->Print(
+ variables_,
+ "public fun ${$has$kt_capitalized_name$$}$(): kotlin.Boolean {\n"
+ " return $kt_dsl_builder$.${$has$capitalized_name$$}$()\n"
+ "}\n");
+ }
+}
+
+void ImmutableStringFieldLiteGenerator::GenerateFieldInfo(
+ io::Printer* printer, std::vector<uint16_t>* output) const {
+ WriteIntToUtf16CharSequence(descriptor_->number(), output);
+ WriteIntToUtf16CharSequence(GetExperimentalJavaFieldType(descriptor_),
+ output);
+ if (HasHasbit(descriptor_)) {
+ WriteIntToUtf16CharSequence(messageBitIndex_, output);
+ }
+ printer->Print(variables_, "\"$name$_\",\n");
+}
+
+void ImmutableStringFieldLiteGenerator::GenerateInitializationCode(
+ io::Printer* printer) const {
+ printer->Print(variables_, "$name$_ = $default$;\n");
+}
+
+std::string ImmutableStringFieldLiteGenerator::GetBoxedType() const {
+ return "java.lang.String";
+}
+
+// ===================================================================
+
+ImmutableStringOneofFieldLiteGenerator::ImmutableStringOneofFieldLiteGenerator(
+ const FieldDescriptor* descriptor, int messageBitIndex, Context* context)
+ : ImmutableStringFieldLiteGenerator(descriptor, messageBitIndex, context) {
+ const OneofGeneratorInfo* info =
+ context->GetOneofGeneratorInfo(descriptor->containing_oneof());
+ SetCommonOneofVariables(descriptor, info, &variables_);
+}
+
+ImmutableStringOneofFieldLiteGenerator::
+ ~ImmutableStringOneofFieldLiteGenerator() {}
+
+void ImmutableStringOneofFieldLiteGenerator::GenerateMembers(
+ io::Printer* printer) const {
+ PrintExtraFieldInfo(variables_, printer);
+ GOOGLE_DCHECK(HasHazzer(descriptor_));
+ WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
+ printer->Print(variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
+ " return $has_oneof_case_message$;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+
+ WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
+ printer->Print(
+ variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public java.lang.String ${$get$capitalized_name$$}$() {\n"
+ " java.lang.String ref $default_init$;\n"
+ " if ($has_oneof_case_message$) {\n"
+ " ref = (java.lang.String) $oneof_name$_;\n"
+ " }\n"
+ " return ref;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+
+ WriteFieldStringBytesAccessorDocComment(printer, descriptor_, GETTER);
+ printer->Print(variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public com.google.protobuf.ByteString\n"
+ " ${$get$capitalized_name$Bytes$}$() {\n"
+ " java.lang.String ref $default_init$;\n"
+ " if ($has_oneof_case_message$) {\n"
+ " ref = (java.lang.String) $oneof_name$_;\n"
+ " }\n"
+ " return com.google.protobuf.ByteString.copyFromUtf8(ref);\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+
+ WriteFieldAccessorDocComment(printer, descriptor_, SETTER);
+ printer->Print(variables_,
+ "private void ${$set$capitalized_name$$}$(\n"
+ " java.lang.String value) {\n"
+ "$null_check$"
+ " $set_oneof_case_message$;\n"
+ " $oneof_name$_ = value;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldAccessorDocComment(printer, descriptor_, CLEARER);
+ printer->Print(variables_,
+ "private void ${$clear$capitalized_name$$}$() {\n"
+ " if ($has_oneof_case_message$) {\n"
+ " $clear_oneof_case_message$;\n"
+ " $oneof_name$_ = null;\n"
+ " }\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+
+ WriteFieldStringBytesAccessorDocComment(printer, descriptor_, SETTER);
+ printer->Print(variables_,
+ "private void ${$set$capitalized_name$Bytes$}$(\n"
+ " com.google.protobuf.ByteString value) {\n");
+ printer->Annotate("{", "}", descriptor_);
+ if (CheckUtf8(descriptor_)) {
+ printer->Print(variables_, " checkByteStringIsUtf8(value);\n");
+ }
+ printer->Print(variables_,
+ " $oneof_name$_ = value.toStringUtf8();\n"
+ " $set_oneof_case_message$;\n"
+ "}\n");
+}
+
+void ImmutableStringOneofFieldLiteGenerator::GenerateFieldInfo(
+ io::Printer* printer, std::vector<uint16_t>* output) const {
+ WriteIntToUtf16CharSequence(descriptor_->number(), output);
+ WriteIntToUtf16CharSequence(GetExperimentalJavaFieldType(descriptor_),
+ output);
+ WriteIntToUtf16CharSequence(descriptor_->containing_oneof()->index(), output);
+}
+
+void ImmutableStringOneofFieldLiteGenerator::GenerateBuilderMembers(
+ io::Printer* printer) const {
+ GOOGLE_DCHECK(HasHazzer(descriptor_));
+ WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
+ printer->Print(variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
+ " return instance.has$capitalized_name$();\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+
+ WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
+ printer->Print(
+ variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public java.lang.String ${$get$capitalized_name$$}$() {\n"
+ " return instance.get$capitalized_name$();\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+
+ WriteFieldStringBytesAccessorDocComment(printer, descriptor_, GETTER);
+ printer->Print(variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public com.google.protobuf.ByteString\n"
+ " ${$get$capitalized_name$Bytes$}$() {\n"
+ " return instance.get$capitalized_name$Bytes();\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+
+ WriteFieldAccessorDocComment(printer, descriptor_, SETTER,
+ /* builder */ true);
+ printer->Print(variables_,
+ "$deprecation$public Builder ${$set$capitalized_name$$}$(\n"
+ " java.lang.String value) {\n"
+ " copyOnWrite();\n"
+ " instance.set$capitalized_name$(value);\n"
+ " return this;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldAccessorDocComment(printer, descriptor_, CLEARER,
+ /* builder */ true);
+ printer->Print(
+ variables_,
+ "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n"
+ " copyOnWrite();\n"
+ " instance.clear$capitalized_name$();\n"
+ " return this;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+
+ WriteFieldStringBytesAccessorDocComment(printer, descriptor_, SETTER,
+ /* builder */ true);
+ printer->Print(
+ variables_,
+ "$deprecation$public Builder ${$set$capitalized_name$Bytes$}$(\n"
+ " com.google.protobuf.ByteString value) {\n"
+ " copyOnWrite();\n"
+ " instance.set$capitalized_name$Bytes(value);\n"
+ " return this;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+}
+
+// ===================================================================
+
+RepeatedImmutableStringFieldLiteGenerator::
+ RepeatedImmutableStringFieldLiteGenerator(const FieldDescriptor* descriptor,
+ int messageBitIndex,
+ Context* context)
+ : descriptor_(descriptor), name_resolver_(context->GetNameResolver()) {
+ SetPrimitiveVariables(descriptor, messageBitIndex, 0,
+ context->GetFieldGeneratorInfo(descriptor),
+ name_resolver_, &variables_);
+}
+
+RepeatedImmutableStringFieldLiteGenerator::
+ ~RepeatedImmutableStringFieldLiteGenerator() {}
+
+int RepeatedImmutableStringFieldLiteGenerator::GetNumBitsForMessage() const {
+ return 0;
+}
+
+void RepeatedImmutableStringFieldLiteGenerator::GenerateInterfaceMembers(
+ io::Printer* printer) const {
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_GETTER);
+ printer->Print(variables_,
+ "$deprecation$java.util.List<java.lang.String>\n"
+ " get$capitalized_name$List();\n");
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_COUNT);
+ printer->Print(variables_,
+ "$deprecation$int get$capitalized_name$Count();\n");
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_GETTER);
+ printer->Print(
+ variables_,
+ "$deprecation$java.lang.String get$capitalized_name$(int index);\n");
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_GETTER);
+ printer->Print(variables_,
+ "$deprecation$com.google.protobuf.ByteString\n"
+ " get$capitalized_name$Bytes(int index);\n");
+}
+
+void RepeatedImmutableStringFieldLiteGenerator::GenerateMembers(
+ io::Printer* printer) const {
+ printer->Print(
+ variables_,
+ "private com.google.protobuf.Internal.ProtobufList<java.lang.String> "
+ "$name$_;\n");
+ PrintExtraFieldInfo(variables_, printer);
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_GETTER);
+ printer->Print(variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public java.util.List<java.lang.String> "
+ "${$get$capitalized_name$List$}$() {\n"
+ " return $name$_;\n" // note: unmodifiable list
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_COUNT);
+ printer->Print(
+ variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n"
+ " return $name$_.size();\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_GETTER);
+ printer->Print(variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public java.lang.String "
+ "${$get$capitalized_name$$}$(int index) {\n"
+ " return $name$_.get(index);\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldStringBytesAccessorDocComment(printer, descriptor_,
+ LIST_INDEXED_GETTER);
+ printer->Print(variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public com.google.protobuf.ByteString\n"
+ " ${$get$capitalized_name$Bytes$}$(int index) {\n"
+ " return com.google.protobuf.ByteString.copyFromUtf8(\n"
+ " $name$_.get(index));\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+
+ printer->Print(
+ variables_,
+ "private void ensure$capitalized_name$IsMutable() {\n"
+ // Use a temporary to avoid a redundant iget-object.
+ " com.google.protobuf.Internal.ProtobufList<java.lang.String> tmp =\n"
+ " $name$_;"
+ " if (!tmp.isModifiable()) {\n"
+ " $name$_ =\n"
+ " com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);\n"
+ " }\n"
+ "}\n");
+
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_SETTER);
+ printer->Print(variables_,
+ "private void set$capitalized_name$(\n"
+ " int index, java.lang.String value) {\n"
+ "$null_check$"
+ " ensure$capitalized_name$IsMutable();\n"
+ " $name$_.set(index, value);\n"
+ "}\n");
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_ADDER);
+ printer->Print(variables_,
+ "private void add$capitalized_name$(\n"
+ " java.lang.String value) {\n"
+ "$null_check$"
+ " ensure$capitalized_name$IsMutable();\n"
+ " $name$_.add(value);\n"
+ "}\n");
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_MULTI_ADDER);
+ printer->Print(variables_,
+ "private void addAll$capitalized_name$(\n"
+ " java.lang.Iterable<java.lang.String> values) {\n"
+ " ensure$capitalized_name$IsMutable();\n"
+ " com.google.protobuf.AbstractMessageLite.addAll(\n"
+ " values, $name$_);\n"
+ "}\n");
+ WriteFieldAccessorDocComment(printer, descriptor_, CLEARER);
+ printer->Print(variables_,
+ "private void clear$capitalized_name$() {\n"
+ " $name$_ = $empty_list$;\n"
+ "}\n");
+
+ WriteFieldStringBytesAccessorDocComment(printer, descriptor_, LIST_ADDER);
+ printer->Print(variables_,
+ "private void add$capitalized_name$Bytes(\n"
+ " com.google.protobuf.ByteString value) {\n");
+ if (CheckUtf8(descriptor_)) {
+ printer->Print(variables_, " checkByteStringIsUtf8(value);\n");
+ }
+ printer->Print(variables_,
+ " ensure$capitalized_name$IsMutable();\n"
+ " $name$_.add(value.toStringUtf8());\n"
+ "}\n");
+}
+
+void RepeatedImmutableStringFieldLiteGenerator::GenerateBuilderMembers(
+ io::Printer* printer) const {
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_GETTER);
+ printer->Print(variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public java.util.List<java.lang.String>\n"
+ " ${$get$capitalized_name$List$}$() {\n"
+ " return java.util.Collections.unmodifiableList(\n"
+ " instance.get$capitalized_name$List());\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_COUNT);
+ printer->Print(
+ variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n"
+ " return instance.get$capitalized_name$Count();\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_GETTER);
+ printer->Print(variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public java.lang.String "
+ "${$get$capitalized_name$$}$(int index) {\n"
+ " return instance.get$capitalized_name$(index);\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldStringBytesAccessorDocComment(printer, descriptor_,
+ LIST_INDEXED_GETTER);
+ printer->Print(variables_,
+ "@java.lang.Override\n"
+ "$deprecation$public com.google.protobuf.ByteString\n"
+ " ${$get$capitalized_name$Bytes$}$(int index) {\n"
+ " return instance.get$capitalized_name$Bytes(index);\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_SETTER,
+ /* builder */ true);
+ printer->Print(variables_,
+ "$deprecation$public Builder ${$set$capitalized_name$$}$(\n"
+ " int index, java.lang.String value) {\n"
+ " copyOnWrite();\n"
+ " instance.set$capitalized_name$(index, value);\n"
+ " return this;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_ADDER,
+ /* builder */ true);
+ printer->Print(variables_,
+ "$deprecation$public Builder ${$add$capitalized_name$$}$(\n"
+ " java.lang.String value) {\n"
+ " copyOnWrite();\n"
+ " instance.add$capitalized_name$(value);\n"
+ " return this;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_MULTI_ADDER,
+ /* builder */ true);
+ printer->Print(variables_,
+ "$deprecation$public Builder ${$addAll$capitalized_name$$}$(\n"
+ " java.lang.Iterable<java.lang.String> values) {\n"
+ " copyOnWrite();\n"
+ " instance.addAll$capitalized_name$(values);\n"
+ " return this;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+ WriteFieldAccessorDocComment(printer, descriptor_, CLEARER,
+ /* builder */ true);
+ printer->Print(
+ variables_,
+ "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n"
+ " copyOnWrite();\n"
+ " instance.clear$capitalized_name$();\n"
+ " return this;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+
+ WriteFieldStringBytesAccessorDocComment(printer, descriptor_, LIST_ADDER,
+ /* builder */ true);
+ printer->Print(
+ variables_,
+ "$deprecation$public Builder ${$add$capitalized_name$Bytes$}$(\n"
+ " com.google.protobuf.ByteString value) {\n"
+ " copyOnWrite();\n"
+ " instance.add$capitalized_name$Bytes(value);\n"
+ " return this;\n"
+ "}\n");
+ printer->Annotate("{", "}", descriptor_);
+}
+
+void RepeatedImmutableStringFieldLiteGenerator::GenerateKotlinDslMembers(
+ io::Printer* printer) const {
+ printer->Print(
+ variables_,
+ "/**\n"
+ " * An uninstantiable, behaviorless type to represent the field in\n"
+ " * generics.\n"
+ " */\n"
+ "@kotlin.OptIn"
+ "(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)\n"
+ "public class ${$$kt_capitalized_name$Proxy$}$ private constructor()"
+ " : com.google.protobuf.kotlin.DslProxy()\n");
+
+ // property for List<String>
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_GETTER);
+ printer->Print(
+ variables_,
+ "$kt_deprecation$public val $kt_name$: "
+ "com.google.protobuf.kotlin.DslList"
+ "<kotlin.String, ${$$kt_capitalized_name$Proxy$}$>\n"
+ " @kotlin.OptIn"
+ "(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)\n"
+ " get() = com.google.protobuf.kotlin.DslList(\n"
+ " $kt_dsl_builder$.${$get$capitalized_name$List$}$()\n"
+ " )\n");
+
+ // List<String>.add(String)
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_ADDER,
+ /* builder */ false);
+ printer->Print(variables_,
+ "@kotlin.jvm.JvmSynthetic\n"
+ "@kotlin.jvm.JvmName(\"add$kt_capitalized_name$\")\n"
+ "public fun com.google.protobuf.kotlin.DslList"
+ "<kotlin.String, ${$$kt_capitalized_name$Proxy$}$>."
+ "add(value: kotlin.String) {\n"
+ " $kt_dsl_builder$.${$add$capitalized_name$$}$(value)\n"
+ "}\n");
+
+ // List<String> += String
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_ADDER,
+ /* builder */ false);
+ printer->Print(variables_,
+ "@kotlin.jvm.JvmSynthetic\n"
+ "@kotlin.jvm.JvmName(\"plusAssign$kt_capitalized_name$\")\n"
+ "@Suppress(\"NOTHING_TO_INLINE\")\n"
+ "public inline operator fun com.google.protobuf.kotlin.DslList"
+ "<kotlin.String, ${$$kt_capitalized_name$Proxy$}$>."
+ "plusAssign(value: kotlin.String) {\n"
+ " add(value)\n"
+ "}\n");
+
+ // List<String>.addAll(Iterable<String>)
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_MULTI_ADDER,
+ /* builder */ false);
+ printer->Print(
+ variables_,
+ "@kotlin.jvm.JvmSynthetic\n"
+ "@kotlin.jvm.JvmName(\"addAll$kt_capitalized_name$\")\n"
+ "public fun com.google.protobuf.kotlin.DslList"
+ "<kotlin.String, ${$$kt_capitalized_name$Proxy$}$>."
+ "addAll(values: kotlin.collections.Iterable<kotlin.String>) {\n"
+ " $kt_dsl_builder$.${$addAll$capitalized_name$$}$(values)\n"
+ "}\n");
+
+ // List<String> += Iterable<String>
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_MULTI_ADDER,
+ /* builder */ false);
+ printer->Print(
+ variables_,
+ "@kotlin.jvm.JvmSynthetic\n"
+ "@kotlin.jvm.JvmName(\"plusAssignAll$kt_capitalized_name$\")\n"
+ "@Suppress(\"NOTHING_TO_INLINE\")\n"
+ "public inline operator fun com.google.protobuf.kotlin.DslList"
+ "<kotlin.String, ${$$kt_capitalized_name$Proxy$}$>."
+ "plusAssign(values: kotlin.collections.Iterable<kotlin.String>) {\n"
+ " addAll(values)\n"
+ "}\n");
+
+ // List<String>[Int] = String
+ WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_SETTER,
+ /* builder */ false);
+ printer->Print(
+ variables_,
+ "@kotlin.jvm.JvmSynthetic\n"
+ "@kotlin.jvm.JvmName(\"set$kt_capitalized_name$\")\n"
+ "public operator fun com.google.protobuf.kotlin.DslList"
+ "<kotlin.String, ${$$kt_capitalized_name$Proxy$}$>."
+ "set(index: kotlin.Int, value: kotlin.String) {\n"
+ " $kt_dsl_builder$.${$set$capitalized_name$$}$(index, value)\n"
+ "}");
+
+ WriteFieldAccessorDocComment(printer, descriptor_, CLEARER,
+ /* builder */ false);
+ printer->Print(variables_,
+ "@kotlin.jvm.JvmSynthetic\n"
+ "@kotlin.jvm.JvmName(\"clear$kt_capitalized_name$\")\n"
+ "public fun com.google.protobuf.kotlin.DslList"
+ "<kotlin.String, ${$$kt_capitalized_name$Proxy$}$>."
+ "clear() {\n"
+ " $kt_dsl_builder$.${$clear$capitalized_name$$}$()\n"
+ "}");
+}
+
+void RepeatedImmutableStringFieldLiteGenerator::GenerateFieldInfo(
+ io::Printer* printer, std::vector<uint16_t>* output) const {
+ WriteIntToUtf16CharSequence(descriptor_->number(), output);
+ WriteIntToUtf16CharSequence(GetExperimentalJavaFieldType(descriptor_),
+ output);
+ printer->Print(variables_, "\"$name$_\",\n");
+}
+
+void RepeatedImmutableStringFieldLiteGenerator::GenerateInitializationCode(
+ io::Printer* printer) const {
+ printer->Print(variables_, "$name$_ = $empty_list$;\n");
+}
+
+std::string RepeatedImmutableStringFieldLiteGenerator::GetBoxedType() const {
+ return "java.lang.String";
+}
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_string_field_lite.h b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_string_field_lite.h
new file mode 100644
index 00000000..880d41cc
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_string_field_lite.h
@@ -0,0 +1,139 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Author: jonp@google.com (Jon Perlow)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_STRING_FIELD_LITE_H__
+#define GOOGLE_PROTOBUF_COMPILER_JAVA_STRING_FIELD_LITE_H__
+
+#include <cstdint>
+#include <map>
+#include <string>
+
+#include <compiler/java/java_field.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+class Context; // context.h
+class ClassNameResolver; // name_resolver.h
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+class ImmutableStringFieldLiteGenerator : public ImmutableFieldLiteGenerator {
+ public:
+ explicit ImmutableStringFieldLiteGenerator(const FieldDescriptor* descriptor,
+ int messageBitIndex,
+ Context* context);
+ ~ImmutableStringFieldLiteGenerator() override;
+
+ // implements ImmutableFieldLiteGenerator
+ // ------------------------------------
+ int GetNumBitsForMessage() const override;
+ void GenerateInterfaceMembers(io::Printer* printer) const override;
+ void GenerateMembers(io::Printer* printer) const override;
+ void GenerateBuilderMembers(io::Printer* printer) const override;
+ void GenerateInitializationCode(io::Printer* printer) const override;
+ void GenerateFieldInfo(io::Printer* printer,
+ std::vector<uint16_t>* output) const override;
+ void GenerateKotlinDslMembers(io::Printer* printer) const override;
+
+ std::string GetBoxedType() const override;
+
+ protected:
+ const FieldDescriptor* descriptor_;
+ std::map<std::string, std::string> variables_;
+ const int messageBitIndex_;
+ ClassNameResolver* name_resolver_;
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableStringFieldLiteGenerator);
+};
+
+class ImmutableStringOneofFieldLiteGenerator
+ : public ImmutableStringFieldLiteGenerator {
+ public:
+ ImmutableStringOneofFieldLiteGenerator(const FieldDescriptor* descriptor,
+ int messageBitIndex, Context* context);
+ ~ImmutableStringOneofFieldLiteGenerator() override;
+
+ private:
+ void GenerateMembers(io::Printer* printer) const override;
+ void GenerateBuilderMembers(io::Printer* printer) const override;
+ void GenerateFieldInfo(io::Printer* printer,
+ std::vector<uint16_t>* output) const override;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableStringOneofFieldLiteGenerator);
+};
+
+class RepeatedImmutableStringFieldLiteGenerator
+ : public ImmutableFieldLiteGenerator {
+ public:
+ explicit RepeatedImmutableStringFieldLiteGenerator(
+ const FieldDescriptor* descriptor, int messageBitIndex, Context* context);
+ ~RepeatedImmutableStringFieldLiteGenerator() override;
+
+ // implements ImmutableFieldLiteGenerator ------------------------------------
+ int GetNumBitsForMessage() const override;
+ void GenerateInterfaceMembers(io::Printer* printer) const override;
+ void GenerateMembers(io::Printer* printer) const override;
+ void GenerateBuilderMembers(io::Printer* printer) const override;
+ void GenerateInitializationCode(io::Printer* printer) const override;
+ void GenerateFieldInfo(io::Printer* printer,
+ std::vector<uint16_t>* output) const override;
+ void GenerateKotlinDslMembers(io::Printer* printer) const override;
+
+ std::string GetBoxedType() const override;
+
+ private:
+ const FieldDescriptor* descriptor_;
+ std::map<std::string, std::string> variables_;
+ ClassNameResolver* name_resolver_;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedImmutableStringFieldLiteGenerator);
+};
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_STRING_FIELD_LITE_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/js/js_generator.cc b/NorthstarDedicatedTest/include/protobuf/compiler/js/js_generator.cc
new file mode 100644
index 00000000..0a1fbb58
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/js/js_generator.cc
@@ -0,0 +1,3941 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 <assert.h>
+#include <compiler/js/js_generator.h>
+#include <compiler/js/well_known_types_embed.h>
+#include <compiler/scc.h>
+#include <descriptor.h>
+#include <descriptor.pb.h>
+#include <io/printer.h>
+#include <io/zero_copy_stream.h>
+#include <stubs/common.h>
+#include <stubs/logging.h>
+#include <stubs/stringprintf.h>
+#include <stubs/strutil.h>
+
+#include <algorithm>
+#include <limits>
+#include <map>
+#include <memory>
+#include <string>
+#include <utility>
+#include <vector>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace js {
+
+// Sorted list of JavaScript keywords. These cannot be used as names. If they
+// appear, we prefix them with "pb_".
+const char* kKeyword[] = {
+ "abstract", "boolean", "break", "byte", "case",
+ "catch", "char", "class", "const", "continue",
+ "debugger", "default", "delete", "do", "double",
+ "else", "enum", "export", "extends", "false",
+ "final", "finally", "float", "for", "function",
+ "goto", "if", "implements", "import", "in",
+ "instanceof", "int", "interface", "long", "native",
+ "new", "null", "package", "private", "protected",
+ "public", "return", "short", "static", "super",
+ "switch", "synchronized", "this", "throw", "throws",
+ "transient", "try", "typeof", "var", "void",
+ "volatile", "while", "with",
+};
+
+static const int kNumKeyword = sizeof(kKeyword) / sizeof(char*);
+
+namespace {
+
+// The mode of operation for bytes fields. Historically JSPB always carried
+// bytes as JS {string}, containing base64 content by convention. With binary
+// and proto3 serialization the new convention is to represent it as binary
+// data in Uint8Array. See b/26173701 for background on the migration.
+enum BytesMode {
+ BYTES_DEFAULT, // Default type for getBytesField to return.
+ BYTES_B64, // Explicitly coerce to base64 string where needed.
+ BYTES_U8, // Explicitly coerce to Uint8Array where needed.
+};
+
+bool IsReserved(const std::string& ident) {
+ for (int i = 0; i < kNumKeyword; i++) {
+ if (ident == kKeyword[i]) {
+ return true;
+ }
+ }
+ return false;
+}
+
+std::string GetSnakeFilename(const std::string& filename) {
+ std::string snake_name = filename;
+ ReplaceCharacters(&snake_name, "/", '_');
+ return snake_name;
+}
+
+// Given a filename like foo/bar/baz.proto, returns the corresponding JavaScript
+// file foo/bar/baz.js.
+std::string GetJSFilename(const GeneratorOptions& options,
+ const std::string& filename) {
+ return StripProto(filename) + options.GetFileNameExtension();
+}
+
+// Given a filename like foo/bar/baz.proto, returns the root directory
+// path ../../
+std::string GetRootPath(const std::string& from_filename,
+ const std::string& to_filename) {
+ if (to_filename.find("google/protobuf") == 0) {
+ // Well-known types (.proto files in the google/protobuf directory) are
+ // assumed to come from the 'google-protobuf' npm package. We may want to
+ // generalize this exception later by letting others put generated code in
+ // their own npm packages.
+ return "google-protobuf/";
+ }
+
+ size_t slashes = std::count(from_filename.begin(), from_filename.end(), '/');
+ if (slashes == 0) {
+ return "./";
+ }
+ std::string result = "";
+ for (size_t i = 0; i < slashes; i++) {
+ result += "../";
+ }
+ return result;
+}
+
+// Returns the alias we assign to the module of the given .proto filename
+// when importing.
+std::string ModuleAlias(const std::string& filename) {
+ // This scheme could technically cause problems if a file includes any 2 of:
+ // foo/bar_baz.proto
+ // foo_bar_baz.proto
+ // foo_bar/baz.proto
+ //
+ // We'll worry about this problem if/when we actually see it. This name isn't
+ // exposed to users so we can change it later if we need to.
+ std::string basename = StripProto(filename);
+ ReplaceCharacters(&basename, "-", '$');
+ ReplaceCharacters(&basename, "/", '_');
+ ReplaceCharacters(&basename, ".", '_');
+ return basename + "_pb";
+}
+
+// Returns the fully normalized JavaScript namespace for the given
+// file descriptor's package.
+std::string GetNamespace(const GeneratorOptions& options,
+ const FileDescriptor* file) {
+ if (!options.namespace_prefix.empty()) {
+ return options.namespace_prefix;
+ } else if (!file->package().empty()) {
+ return "proto." + file->package();
+ } else {
+ return "proto";
+ }
+}
+
+// Returns the name of the message with a leading dot and taking into account
+// nesting, for example ".OuterMessage.InnerMessage", or returns empty if
+// descriptor is null. This function does not handle namespacing, only message
+// nesting.
+std::string GetNestedMessageName(const Descriptor* descriptor) {
+ if (descriptor == NULL) {
+ return "";
+ }
+ std::string result =
+ StripPrefixString(descriptor->full_name(), descriptor->file()->package());
+ // Add a leading dot if one is not already present.
+ if (!result.empty() && result[0] != '.') {
+ result = "." + result;
+ }
+ return result;
+}
+
+// Returns the path prefix for a message or enumeration that
+// lives under the given file and containing type.
+std::string GetPrefix(const GeneratorOptions& options,
+ const FileDescriptor* file_descriptor,
+ const Descriptor* containing_type) {
+ std::string prefix = GetNamespace(options, file_descriptor) +
+ GetNestedMessageName(containing_type);
+ if (!prefix.empty()) {
+ prefix += ".";
+ }
+ return prefix;
+}
+
+// Returns the fully normalized JavaScript path prefix for the given
+// message descriptor.
+std::string GetMessagePathPrefix(const GeneratorOptions& options,
+ const Descriptor* descriptor) {
+ return GetPrefix(options, descriptor->file(), descriptor->containing_type());
+}
+
+// Returns the fully normalized JavaScript path for the given
+// message descriptor.
+std::string GetMessagePath(const GeneratorOptions& options,
+ const Descriptor* descriptor) {
+ return GetMessagePathPrefix(options, descriptor) + descriptor->name();
+}
+
+// Returns the fully normalized JavaScript path prefix for the given
+// enumeration descriptor.
+std::string GetEnumPathPrefix(const GeneratorOptions& options,
+ const EnumDescriptor* enum_descriptor) {
+ return GetPrefix(options, enum_descriptor->file(),
+ enum_descriptor->containing_type());
+}
+
+// Returns the fully normalized JavaScript path for the given
+// enumeration descriptor.
+std::string GetEnumPath(const GeneratorOptions& options,
+ const EnumDescriptor* enum_descriptor) {
+ return GetEnumPathPrefix(options, enum_descriptor) + enum_descriptor->name();
+}
+
+std::string MaybeCrossFileRef(const GeneratorOptions& options,
+ const FileDescriptor* from_file,
+ const Descriptor* to_message) {
+ if ((options.import_style == GeneratorOptions::kImportCommonJs ||
+ options.import_style == GeneratorOptions::kImportCommonJsStrict) &&
+ from_file != to_message->file()) {
+ // Cross-file ref in CommonJS needs to use the module alias instead of
+ // the global name.
+ return ModuleAlias(to_message->file()->name()) +
+ GetNestedMessageName(to_message->containing_type()) + "." +
+ to_message->name();
+ } else {
+ // Within a single file we use a full name.
+ return GetMessagePath(options, to_message);
+ }
+}
+
+std::string SubmessageTypeRef(const GeneratorOptions& options,
+ const FieldDescriptor* field) {
+ GOOGLE_CHECK(field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE);
+ return MaybeCrossFileRef(options, field->file(), field->message_type());
+}
+
+// - Object field name: LOWER_UNDERSCORE -> LOWER_CAMEL, except for group fields
+// (UPPER_CAMEL -> LOWER_CAMEL), with "List" (or "Map") appended if appropriate,
+// and with reserved words triggering a "pb_" prefix.
+// - Getters/setters: LOWER_UNDERSCORE -> UPPER_CAMEL, except for group fields
+// (use the name directly), then append "List" if appropriate, then append "$"
+// if resulting name is equal to a reserved word.
+// - Enums: just uppercase.
+
+// Locale-independent version of ToLower that deals only with ASCII A-Z.
+char ToLowerASCII(char c) {
+ if (c >= 'A' && c <= 'Z') {
+ return (c - 'A') + 'a';
+ } else {
+ return c;
+ }
+}
+
+std::vector<std::string> ParseLowerUnderscore(const std::string& input) {
+ std::vector<std::string> words;
+ std::string running = "";
+ for (int i = 0; i < input.size(); i++) {
+ if (input[i] == '_') {
+ if (!running.empty()) {
+ words.push_back(running);
+ running.clear();
+ }
+ } else {
+ running += ToLowerASCII(input[i]);
+ }
+ }
+ if (!running.empty()) {
+ words.push_back(running);
+ }
+ return words;
+}
+
+std::vector<std::string> ParseUpperCamel(const std::string& input) {
+ std::vector<std::string> words;
+ std::string running = "";
+ for (int i = 0; i < input.size(); i++) {
+ if (input[i] >= 'A' && input[i] <= 'Z' && !running.empty()) {
+ words.push_back(running);
+ running.clear();
+ }
+ running += ToLowerASCII(input[i]);
+ }
+ if (!running.empty()) {
+ words.push_back(running);
+ }
+ return words;
+}
+
+std::string ToLowerCamel(const std::vector<std::string>& words) {
+ std::string result;
+ for (int i = 0; i < words.size(); i++) {
+ std::string word = words[i];
+ if (i == 0 && (word[0] >= 'A' && word[0] <= 'Z')) {
+ word[0] = (word[0] - 'A') + 'a';
+ } else if (i != 0 && (word[0] >= 'a' && word[0] <= 'z')) {
+ word[0] = (word[0] - 'a') + 'A';
+ }
+ result += word;
+ }
+ return result;
+}
+
+std::string ToUpperCamel(const std::vector<std::string>& words) {
+ std::string result;
+ for (int i = 0; i < words.size(); i++) {
+ std::string word = words[i];
+ if (word[0] >= 'a' && word[0] <= 'z') {
+ word[0] = (word[0] - 'a') + 'A';
+ }
+ result += word;
+ }
+ return result;
+}
+
+// Based on code from descriptor.cc (Thanks Kenton!)
+// Uppercases the entire string, turning ValueName into
+// VALUENAME.
+std::string ToEnumCase(const std::string& input) {
+ std::string result;
+ result.reserve(input.size());
+
+ for (int i = 0; i < input.size(); i++) {
+ if ('a' <= input[i] && input[i] <= 'z') {
+ result.push_back(input[i] - 'a' + 'A');
+ } else {
+ result.push_back(input[i]);
+ }
+ }
+
+ return result;
+}
+
+std::string ToLower(const std::string& input) {
+ std::string result;
+ result.reserve(input.size());
+
+ for (int i = 0; i < input.size(); i++) {
+ if ('A' <= input[i] && input[i] <= 'Z') {
+ result.push_back(input[i] - 'A' + 'a');
+ } else {
+ result.push_back(input[i]);
+ }
+ }
+
+ return result;
+}
+
+// When we're generating one output file per SCC, this is the filename
+// that top-level extensions should go in.
+// e.g. one proto file (test.proto):
+// package a;
+// extends Foo {
+// ...
+// }
+// If "with_filename" equals true, the extension filename will be
+// "proto.a_test_extensions.js", otherwise will be "proto.a.js"
+std::string GetExtensionFileName(const GeneratorOptions& options,
+ const FileDescriptor* file,
+ bool with_filename) {
+ std::string snake_name = StripProto(GetSnakeFilename(file->name()));
+ return options.output_dir + "/" + ToLower(GetNamespace(options, file)) +
+ (with_filename ? ("_" + snake_name + "_extensions") : "") +
+ options.GetFileNameExtension();
+}
+// When we're generating one output file per SCC, this is the filename
+// that all messages in the SCC should go in.
+// If with_package equals true, filename will have package prefix,
+// If the filename length is longer than 200, the filename will be the
+// SCC's proto filename with suffix "_long_sccs_(index)" (if with_package equals
+// true it still has package prefix)
+std::string GetMessagesFileName(const GeneratorOptions& options, const SCC* scc,
+ bool with_package) {
+ static std::map<const Descriptor*, std::string>* long_name_dict =
+ new std::map<const Descriptor*, std::string>();
+ std::string package_base =
+ with_package
+ ? ToLower(GetNamespace(options, scc->GetRepresentative()->file()) +
+ "_")
+ : "";
+ std::string filename_base = "";
+ std::vector<std::string> all_message_names;
+ for (auto one_desc : scc->descriptors) {
+ if (one_desc->containing_type() == nullptr) {
+ all_message_names.push_back(ToLower(one_desc->name()));
+ }
+ }
+ sort(all_message_names.begin(), all_message_names.end());
+ for (auto one_message : all_message_names) {
+ if (!filename_base.empty()) {
+ filename_base += "_";
+ }
+ filename_base += one_message;
+ }
+ if (filename_base.size() + package_base.size() > 200) {
+ if ((*long_name_dict).find(scc->GetRepresentative()) ==
+ (*long_name_dict).end()) {
+ std::string snake_name = StripProto(
+ GetSnakeFilename(scc->GetRepresentative()->file()->name()));
+ (*long_name_dict)[scc->GetRepresentative()] =
+ StrCat(snake_name, "_long_sccs_",
+ static_cast<uint64>((*long_name_dict).size()));
+ }
+ filename_base = (*long_name_dict)[scc->GetRepresentative()];
+ }
+ return options.output_dir + "/" + package_base + filename_base +
+ options.GetFileNameExtension();
+}
+
+// When we're generating one output file per type name, this is the filename
+// that a top-level enum should go in.
+// If with_package equals true, filename will have package prefix.
+std::string GetEnumFileName(const GeneratorOptions& options,
+ const EnumDescriptor* desc, bool with_package) {
+ return options.output_dir + "/" +
+ (with_package ? ToLower(GetNamespace(options, desc->file()) + "_")
+ : "") +
+ ToLower(desc->name()) + options.GetFileNameExtension();
+}
+
+// Returns the message/response ID, if set.
+std::string GetMessageId(const Descriptor* desc) { return std::string(); }
+
+bool IgnoreExtensionField(const FieldDescriptor* field) {
+ // Exclude descriptor extensions from output "to avoid clutter" (from original
+ // codegen).
+ if (!field->is_extension()) return false;
+ const FileDescriptor* file = field->containing_type()->file();
+ return file->name() == "net/proto2/proto/descriptor.proto" ||
+ file->name() == "google/protobuf/descriptor.proto";
+}
+
+// Used inside Google only -- do not remove.
+bool IsResponse(const Descriptor* desc) { return false; }
+
+bool IgnoreField(const FieldDescriptor* field) {
+ return IgnoreExtensionField(field);
+}
+
+// Do we ignore this message type?
+bool IgnoreMessage(const Descriptor* d) { return d->options().map_entry(); }
+
+// Does JSPB ignore this entire oneof? True only if all fields are ignored.
+bool IgnoreOneof(const OneofDescriptor* oneof) {
+ if (oneof->is_synthetic()) return true;
+ for (int i = 0; i < oneof->field_count(); i++) {
+ if (!IgnoreField(oneof->field(i))) {
+ return false;
+ }
+ }
+ return true;
+}
+
+std::string JSIdent(const GeneratorOptions& options,
+ const FieldDescriptor* field, bool is_upper_camel,
+ bool is_map, bool drop_list) {
+ std::string result;
+ if (field->type() == FieldDescriptor::TYPE_GROUP) {
+ result = is_upper_camel
+ ? ToUpperCamel(ParseUpperCamel(field->message_type()->name()))
+ : ToLowerCamel(ParseUpperCamel(field->message_type()->name()));
+ } else {
+ result = is_upper_camel ? ToUpperCamel(ParseLowerUnderscore(field->name()))
+ : ToLowerCamel(ParseLowerUnderscore(field->name()));
+ }
+ if (is_map || field->is_map()) {
+ // JSPB-style or proto3-style map.
+ result += "Map";
+ } else if (!drop_list && field->is_repeated()) {
+ // Repeated field.
+ result += "List";
+ }
+ return result;
+}
+
+std::string JSObjectFieldName(const GeneratorOptions& options,
+ const FieldDescriptor* field) {
+ std::string name = JSIdent(options, field,
+ /* is_upper_camel = */ false,
+ /* is_map = */ false,
+ /* drop_list = */ false);
+ if (IsReserved(name)) {
+ name = "pb_" + name;
+ }
+ return name;
+}
+
+std::string JSByteGetterSuffix(BytesMode bytes_mode) {
+ switch (bytes_mode) {
+ case BYTES_DEFAULT:
+ return "";
+ case BYTES_B64:
+ return "B64";
+ case BYTES_U8:
+ return "U8";
+ default:
+ assert(false);
+ }
+ return "";
+}
+
+// Returns the field name as a capitalized portion of a getter/setter method
+// name, e.g. MyField for .getMyField().
+std::string JSGetterName(const GeneratorOptions& options,
+ const FieldDescriptor* field,
+ BytesMode bytes_mode = BYTES_DEFAULT,
+ bool drop_list = false) {
+ std::string name = JSIdent(options, field,
+ /* is_upper_camel = */ true,
+ /* is_map = */ false, drop_list);
+ if (field->type() == FieldDescriptor::TYPE_BYTES) {
+ std::string suffix = JSByteGetterSuffix(bytes_mode);
+ if (!suffix.empty()) {
+ name += "_as" + suffix;
+ }
+ }
+ if (name == "Extension" || name == "JsPbMessageId") {
+ // Avoid conflicts with base-class names.
+ name += "$";
+ }
+ return name;
+}
+
+std::string JSOneofName(const OneofDescriptor* oneof) {
+ return ToUpperCamel(ParseLowerUnderscore(oneof->name()));
+}
+
+// Returns the index corresponding to this field in the JSPB array (underlying
+// data storage array).
+std::string JSFieldIndex(const FieldDescriptor* field) {
+ // Determine whether this field is a member of a group. Group fields are a bit
+ // wonky: their "containing type" is a message type created just for the
+ // group, and that type's parent type has a field with the group-message type
+ // as its message type and TYPE_GROUP as its field type. For such fields, the
+ // index we use is relative to the field number of the group submessage field.
+ // For all other fields, we just use the field number.
+ const Descriptor* containing_type = field->containing_type();
+ const Descriptor* parent_type = containing_type->containing_type();
+ if (parent_type != NULL) {
+ for (int i = 0; i < parent_type->field_count(); i++) {
+ if (parent_type->field(i)->type() == FieldDescriptor::TYPE_GROUP &&
+ parent_type->field(i)->message_type() == containing_type) {
+ return StrCat(field->number() - parent_type->field(i)->number());
+ }
+ }
+ }
+ return StrCat(field->number());
+}
+
+std::string JSOneofIndex(const OneofDescriptor* oneof) {
+ int index = -1;
+ for (int i = 0; i < oneof->containing_type()->oneof_decl_count(); i++) {
+ const OneofDescriptor* o = oneof->containing_type()->oneof_decl(i);
+ if (o->is_synthetic()) continue;
+ // If at least one field in this oneof is not JSPB-ignored, count the oneof.
+ for (int j = 0; j < o->field_count(); j++) {
+ const FieldDescriptor* f = o->field(j);
+ if (!IgnoreField(f)) {
+ index++;
+ break; // inner loop
+ }
+ }
+ if (o == oneof) {
+ break;
+ }
+ }
+ return StrCat(index);
+}
+
+// Decodes a codepoint in \x0000 -- \xFFFF.
+uint16 DecodeUTF8Codepoint(uint8* bytes, size_t* length) {
+ if (*length == 0) {
+ return 0;
+ }
+ size_t expected = 0;
+ if ((*bytes & 0x80) == 0) {
+ expected = 1;
+ } else if ((*bytes & 0xe0) == 0xc0) {
+ expected = 2;
+ } else if ((*bytes & 0xf0) == 0xe0) {
+ expected = 3;
+ } else {
+ // Too long -- don't accept.
+ *length = 0;
+ return 0;
+ }
+
+ if (*length < expected) {
+ // Not enough bytes -- don't accept.
+ *length = 0;
+ return 0;
+ }
+
+ *length = expected;
+ switch (expected) {
+ case 1:
+ return bytes[0];
+ case 2:
+ return ((bytes[0] & 0x1F) << 6) | ((bytes[1] & 0x3F) << 0);
+ case 3:
+ return ((bytes[0] & 0x0F) << 12) | ((bytes[1] & 0x3F) << 6) |
+ ((bytes[2] & 0x3F) << 0);
+ default:
+ return 0;
+ }
+}
+
+// Escapes the contents of a string to be included within double-quotes ("") in
+// JavaScript. The input data should be a UTF-8 encoded C++ string of chars.
+// Returns false if |out| was truncated because |in| contained invalid UTF-8 or
+// codepoints outside the BMP.
+// TODO(b/115551870): Support codepoints outside the BMP.
+bool EscapeJSString(const std::string& in, std::string* out) {
+ size_t decoded = 0;
+ for (size_t i = 0; i < in.size(); i += decoded) {
+ uint16 codepoint = 0;
+ // Decode the next UTF-8 codepoint.
+ size_t have_bytes = in.size() - i;
+ uint8 bytes[3] = {
+ static_cast<uint8>(in[i]),
+ static_cast<uint8>(((i + 1) < in.size()) ? in[i + 1] : 0),
+ static_cast<uint8>(((i + 2) < in.size()) ? in[i + 2] : 0),
+ };
+ codepoint = DecodeUTF8Codepoint(bytes, &have_bytes);
+ if (have_bytes == 0) {
+ return false;
+ }
+ decoded = have_bytes;
+
+ switch (codepoint) {
+ case '\'':
+ *out += "\\x27";
+ break;
+ case '"':
+ *out += "\\x22";
+ break;
+ case '<':
+ *out += "\\x3c";
+ break;
+ case '=':
+ *out += "\\x3d";
+ break;
+ case '>':
+ *out += "\\x3e";
+ break;
+ case '&':
+ *out += "\\x26";
+ break;
+ case '\b':
+ *out += "\\b";
+ break;
+ case '\t':
+ *out += "\\t";
+ break;
+ case '\n':
+ *out += "\\n";
+ break;
+ case '\f':
+ *out += "\\f";
+ break;
+ case '\r':
+ *out += "\\r";
+ break;
+ case '\\':
+ *out += "\\\\";
+ break;
+ default:
+ // TODO(b/115551870): Once we're supporting codepoints outside the BMP,
+ // use a single Unicode codepoint escape if the output language is
+ // ECMAScript 2015 or above. Otherwise, use a surrogate pair.
+ // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Lexical_grammar#String_literals
+ if (codepoint >= 0x20 && codepoint <= 0x7e) {
+ *out += static_cast<char>(codepoint);
+ } else if (codepoint >= 0x100) {
+ *out += StringPrintf("\\u%04x", codepoint);
+ } else {
+ *out += StringPrintf("\\x%02x", codepoint);
+ }
+ break;
+ }
+ }
+ return true;
+}
+
+std::string EscapeBase64(const std::string& in) {
+ static const char* kAlphabet =
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+ std::string result;
+
+ for (size_t i = 0; i < in.size(); i += 3) {
+ int value = (in[i] << 16) | (((i + 1) < in.size()) ? (in[i + 1] << 8) : 0) |
+ (((i + 2) < in.size()) ? (in[i + 2] << 0) : 0);
+ result += kAlphabet[(value >> 18) & 0x3f];
+ result += kAlphabet[(value >> 12) & 0x3f];
+ if ((i + 1) < in.size()) {
+ result += kAlphabet[(value >> 6) & 0x3f];
+ } else {
+ result += '=';
+ }
+ if ((i + 2) < in.size()) {
+ result += kAlphabet[(value >> 0) & 0x3f];
+ } else {
+ result += '=';
+ }
+ }
+
+ return result;
+}
+
+// Post-process the result of SimpleFtoa/SimpleDtoa to *exactly* match the
+// original codegen's formatting (which is just .toString() on java.lang.Double
+// or java.lang.Float).
+std::string PostProcessFloat(std::string result) {
+ // If inf, -inf or nan, replace with +Infinity, -Infinity or NaN.
+ if (result == "inf") {
+ return "Infinity";
+ } else if (result == "-inf") {
+ return "-Infinity";
+ } else if (result == "nan") {
+ return "NaN";
+ }
+
+ // If scientific notation (e.g., "1e10"), (i) capitalize the "e", (ii)
+ // ensure that the mantissa (portion prior to the "e") has at least one
+ // fractional digit (after the decimal point), and (iii) strip any unnecessary
+ // leading zeroes and/or '+' signs from the exponent.
+ std::string::size_type exp_pos = result.find('e');
+ if (exp_pos != std::string::npos) {
+ std::string mantissa = result.substr(0, exp_pos);
+ std::string exponent = result.substr(exp_pos + 1);
+
+ // Add ".0" to mantissa if no fractional part exists.
+ if (mantissa.find('.') == std::string::npos) {
+ mantissa += ".0";
+ }
+
+ // Strip the sign off the exponent and store as |exp_neg|.
+ bool exp_neg = false;
+ if (!exponent.empty() && exponent[0] == '+') {
+ exponent = exponent.substr(1);
+ } else if (!exponent.empty() && exponent[0] == '-') {
+ exp_neg = true;
+ exponent = exponent.substr(1);
+ }
+
+ // Strip any leading zeroes off the exponent.
+ while (exponent.size() > 1 && exponent[0] == '0') {
+ exponent = exponent.substr(1);
+ }
+
+ return mantissa + "E" + std::string(exp_neg ? "-" : "") + exponent;
+ }
+
+ // Otherwise, this is an ordinary decimal number. Append ".0" if result has no
+ // decimal/fractional part in order to match output of original codegen.
+ if (result.find('.') == std::string::npos) {
+ result += ".0";
+ }
+
+ return result;
+}
+
+std::string FloatToString(float value) {
+ std::string result = SimpleFtoa(value);
+ return PostProcessFloat(result);
+}
+
+std::string DoubleToString(double value) {
+ std::string result = SimpleDtoa(value);
+ return PostProcessFloat(result);
+}
+
+bool InRealOneof(const FieldDescriptor* field) {
+ return field->containing_oneof() &&
+ !field->containing_oneof()->is_synthetic();
+}
+
+// Return true if this is an integral field that should be represented as string
+// in JS.
+bool IsIntegralFieldWithStringJSType(const FieldDescriptor* field) {
+ switch (field->cpp_type()) {
+ case FieldDescriptor::CPPTYPE_INT64:
+ case FieldDescriptor::CPPTYPE_UINT64:
+ // The default value of JSType is JS_NORMAL, which behaves the same as
+ // JS_NUMBER.
+ return field->options().jstype() == FieldOptions::JS_STRING;
+ default:
+ return false;
+ }
+}
+
+std::string MaybeNumberString(const FieldDescriptor* field,
+ const std::string& orig) {
+ return IsIntegralFieldWithStringJSType(field) ? ("\"" + orig + "\"") : orig;
+}
+
+std::string JSFieldDefault(const FieldDescriptor* field) {
+ if (field->is_repeated()) {
+ return "[]";
+ }
+
+ switch (field->cpp_type()) {
+ case FieldDescriptor::CPPTYPE_INT32:
+ return MaybeNumberString(field, StrCat(field->default_value_int32()));
+ case FieldDescriptor::CPPTYPE_UINT32:
+ // The original codegen is in Java, and Java protobufs store unsigned
+ // integer values as signed integer values. In order to exactly match the
+ // output, we need to reinterpret as base-2 signed. Ugh.
+ return MaybeNumberString(
+ field, StrCat(static_cast<int32>(field->default_value_uint32())));
+ case FieldDescriptor::CPPTYPE_INT64:
+ return MaybeNumberString(field, StrCat(field->default_value_int64()));
+ case FieldDescriptor::CPPTYPE_UINT64:
+ // See above note for uint32 -- reinterpreting as signed.
+ return MaybeNumberString(
+ field, StrCat(static_cast<int64>(field->default_value_uint64())));
+ case FieldDescriptor::CPPTYPE_ENUM:
+ return StrCat(field->default_value_enum()->number());
+ case FieldDescriptor::CPPTYPE_BOOL:
+ return field->default_value_bool() ? "true" : "false";
+ case FieldDescriptor::CPPTYPE_FLOAT:
+ return FloatToString(field->default_value_float());
+ case FieldDescriptor::CPPTYPE_DOUBLE:
+ return DoubleToString(field->default_value_double());
+ case FieldDescriptor::CPPTYPE_STRING:
+ if (field->type() == FieldDescriptor::TYPE_STRING) {
+ std::string out;
+ bool is_valid = EscapeJSString(field->default_value_string(), &out);
+ if (!is_valid) {
+ // TODO(b/115551870): Decide whether this should be a hard error.
+ GOOGLE_LOG(WARNING)
+ << "The default value for field " << field->full_name()
+ << " was truncated since it contained invalid UTF-8 or"
+ " codepoints outside the basic multilingual plane.";
+ }
+ return "\"" + out + "\"";
+ } else { // Bytes
+ return "\"" + EscapeBase64(field->default_value_string()) + "\"";
+ }
+ case FieldDescriptor::CPPTYPE_MESSAGE:
+ return "null";
+ }
+ GOOGLE_LOG(FATAL) << "Shouldn't reach here.";
+ return "";
+}
+
+std::string ProtoTypeName(const GeneratorOptions& options,
+ const FieldDescriptor* field) {
+ switch (field->type()) {
+ case FieldDescriptor::TYPE_BOOL:
+ return "bool";
+ case FieldDescriptor::TYPE_INT32:
+ return "int32";
+ case FieldDescriptor::TYPE_UINT32:
+ return "uint32";
+ case FieldDescriptor::TYPE_SINT32:
+ return "sint32";
+ case FieldDescriptor::TYPE_FIXED32:
+ return "fixed32";
+ case FieldDescriptor::TYPE_SFIXED32:
+ return "sfixed32";
+ case FieldDescriptor::TYPE_INT64:
+ return "int64";
+ case FieldDescriptor::TYPE_UINT64:
+ return "uint64";
+ case FieldDescriptor::TYPE_SINT64:
+ return "sint64";
+ case FieldDescriptor::TYPE_FIXED64:
+ return "fixed64";
+ case FieldDescriptor::TYPE_SFIXED64:
+ return "sfixed64";
+ case FieldDescriptor::TYPE_FLOAT:
+ return "float";
+ case FieldDescriptor::TYPE_DOUBLE:
+ return "double";
+ case FieldDescriptor::TYPE_STRING:
+ return "string";
+ case FieldDescriptor::TYPE_BYTES:
+ return "bytes";
+ case FieldDescriptor::TYPE_GROUP:
+ return GetMessagePath(options, field->message_type());
+ case FieldDescriptor::TYPE_ENUM:
+ return GetEnumPath(options, field->enum_type());
+ case FieldDescriptor::TYPE_MESSAGE:
+ return GetMessagePath(options, field->message_type());
+ default:
+ return "";
+ }
+}
+
+std::string JSIntegerTypeName(const FieldDescriptor* field) {
+ return IsIntegralFieldWithStringJSType(field) ? "string" : "number";
+}
+
+std::string JSStringTypeName(const GeneratorOptions& options,
+ const FieldDescriptor* field,
+ BytesMode bytes_mode) {
+ if (field->type() == FieldDescriptor::TYPE_BYTES) {
+ switch (bytes_mode) {
+ case BYTES_DEFAULT:
+ return "(string|Uint8Array)";
+ case BYTES_B64:
+ return "string";
+ case BYTES_U8:
+ return "Uint8Array";
+ default:
+ assert(false);
+ }
+ }
+ return "string";
+}
+
+std::string JSTypeName(const GeneratorOptions& options,
+ const FieldDescriptor* field, BytesMode bytes_mode) {
+ switch (field->cpp_type()) {
+ case FieldDescriptor::CPPTYPE_BOOL:
+ return "boolean";
+ case FieldDescriptor::CPPTYPE_INT32:
+ return JSIntegerTypeName(field);
+ case FieldDescriptor::CPPTYPE_INT64:
+ return JSIntegerTypeName(field);
+ case FieldDescriptor::CPPTYPE_UINT32:
+ return JSIntegerTypeName(field);
+ case FieldDescriptor::CPPTYPE_UINT64:
+ return JSIntegerTypeName(field);
+ case FieldDescriptor::CPPTYPE_FLOAT:
+ return "number";
+ case FieldDescriptor::CPPTYPE_DOUBLE:
+ return "number";
+ case FieldDescriptor::CPPTYPE_STRING:
+ return JSStringTypeName(options, field, bytes_mode);
+ case FieldDescriptor::CPPTYPE_ENUM:
+ return GetEnumPath(options, field->enum_type());
+ case FieldDescriptor::CPPTYPE_MESSAGE:
+ return GetMessagePath(options, field->message_type());
+ default:
+ return "";
+ }
+}
+
+// Used inside Google only -- do not remove.
+bool UseBrokenPresenceSemantics(const GeneratorOptions& options,
+ const FieldDescriptor* field) {
+ return false;
+}
+
+// Returns true for fields that return "null" from accessors when they are
+// unset. This should normally only be true for non-repeated submessages, but we
+// have legacy users who relied on old behavior where accessors behaved this
+// way.
+bool ReturnsNullWhenUnset(const GeneratorOptions& options,
+ const FieldDescriptor* field) {
+ if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
+ field->is_optional()) {
+ return true;
+ }
+
+ // TODO(haberman): remove this case and unconditionally return false.
+ return UseBrokenPresenceSemantics(options, field) && !field->is_repeated() &&
+ !field->has_default_value();
+}
+
+// In a sane world, this would be the same as ReturnsNullWhenUnset(). But in
+// the status quo, some fields declare that they never return null/undefined
+// even though they actually do:
+// * required fields
+// * optional enum fields
+// * proto3 primitive fields.
+bool DeclaredReturnTypeIsNullable(const GeneratorOptions& options,
+ const FieldDescriptor* field) {
+ if (field->is_required() || field->type() == FieldDescriptor::TYPE_ENUM) {
+ return false;
+ }
+
+ if (field->file()->syntax() == FileDescriptor::SYNTAX_PROTO3 &&
+ field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) {
+ return false;
+ }
+
+ return ReturnsNullWhenUnset(options, field);
+}
+
+bool SetterAcceptsUndefined(const GeneratorOptions& options,
+ const FieldDescriptor* field) {
+ if (ReturnsNullWhenUnset(options, field)) {
+ return true;
+ }
+
+ // Broken presence semantics always accepts undefined for setters.
+ return UseBrokenPresenceSemantics(options, field);
+}
+
+bool SetterAcceptsNull(const GeneratorOptions& options,
+ const FieldDescriptor* field) {
+ if (ReturnsNullWhenUnset(options, field)) {
+ return true;
+ }
+
+ // With broken presence semantics, fields with defaults accept "null" for
+ // setters, but other fields do not. This is a strange quirk of the old
+ // codegen.
+ return UseBrokenPresenceSemantics(options, field) &&
+ field->has_default_value();
+}
+
+// Returns types which are known to by non-nullable by default.
+// The style guide requires that we omit "!" in this case.
+bool IsPrimitive(const std::string& type) {
+ return type == "undefined" || type == "string" || type == "number" ||
+ type == "boolean";
+}
+
+std::string JSFieldTypeAnnotation(const GeneratorOptions& options,
+ const FieldDescriptor* field,
+ bool is_setter_argument, bool force_present,
+ bool singular_if_not_packed,
+ BytesMode bytes_mode = BYTES_DEFAULT,
+ bool force_singular = false) {
+ std::string jstype = JSTypeName(options, field, bytes_mode);
+
+ if (!force_singular && field->is_repeated() &&
+ (field->is_packed() || !singular_if_not_packed)) {
+ if (field->type() == FieldDescriptor::TYPE_BYTES &&
+ bytes_mode == BYTES_DEFAULT) {
+ jstype = "(Array<!Uint8Array>|Array<string>)";
+ } else {
+ if (!IsPrimitive(jstype)) {
+ jstype = "!" + jstype;
+ }
+ jstype = "Array<" + jstype + ">";
+ }
+ }
+
+ bool is_null_or_undefined = false;
+
+ if (is_setter_argument) {
+ if (SetterAcceptsNull(options, field)) {
+ jstype = "?" + jstype;
+ is_null_or_undefined = true;
+ }
+
+ if (SetterAcceptsUndefined(options, field)) {
+ jstype += "|undefined";
+ is_null_or_undefined = true;
+ }
+ } else if (force_present) {
+ // Don't add null or undefined.
+ } else {
+ if (DeclaredReturnTypeIsNullable(options, field)) {
+ jstype = "?" + jstype;
+ is_null_or_undefined = true;
+ }
+ }
+
+ if (!is_null_or_undefined && !IsPrimitive(jstype)) {
+ jstype = "!" + jstype;
+ }
+
+ return jstype;
+}
+
+std::string JSBinaryReaderMethodType(const FieldDescriptor* field) {
+ std::string name = field->type_name();
+ if (name[0] >= 'a' && name[0] <= 'z') {
+ name[0] = (name[0] - 'a') + 'A';
+ }
+ return IsIntegralFieldWithStringJSType(field) ? (name + "String") : name;
+}
+
+std::string JSBinaryReadWriteMethodName(const FieldDescriptor* field,
+ bool is_writer) {
+ std::string name = JSBinaryReaderMethodType(field);
+ if (field->is_packed()) {
+ name = "Packed" + name;
+ } else if (is_writer && field->is_repeated()) {
+ name = "Repeated" + name;
+ }
+ return name;
+}
+
+std::string JSBinaryReaderMethodName(const GeneratorOptions& options,
+ const FieldDescriptor* field) {
+ return "jspb.BinaryReader.prototype.read" +
+ JSBinaryReadWriteMethodName(field, /* is_writer = */ false);
+}
+
+std::string JSBinaryWriterMethodName(const GeneratorOptions& options,
+ const FieldDescriptor* field) {
+ if (field->containing_type() &&
+ field->containing_type()->options().message_set_wire_format()) {
+ return "jspb.BinaryWriter.prototype.writeMessageSet";
+ }
+ return "jspb.BinaryWriter.prototype.write" +
+ JSBinaryReadWriteMethodName(field, /* is_writer = */ true);
+}
+
+std::string JSTypeTag(const FieldDescriptor* desc) {
+ switch (desc->type()) {
+ case FieldDescriptor::TYPE_DOUBLE:
+ case FieldDescriptor::TYPE_FLOAT:
+ return "Float";
+ case FieldDescriptor::TYPE_INT32:
+ case FieldDescriptor::TYPE_UINT32:
+ case FieldDescriptor::TYPE_INT64:
+ case FieldDescriptor::TYPE_UINT64:
+ case FieldDescriptor::TYPE_FIXED32:
+ case FieldDescriptor::TYPE_FIXED64:
+ case FieldDescriptor::TYPE_SINT32:
+ case FieldDescriptor::TYPE_SINT64:
+ case FieldDescriptor::TYPE_SFIXED32:
+ case FieldDescriptor::TYPE_SFIXED64:
+ if (IsIntegralFieldWithStringJSType(desc)) {
+ return "StringInt";
+ } else {
+ return "Int";
+ }
+ case FieldDescriptor::TYPE_BOOL:
+ return "Boolean";
+ case FieldDescriptor::TYPE_STRING:
+ return "String";
+ case FieldDescriptor::TYPE_BYTES:
+ return "Bytes";
+ case FieldDescriptor::TYPE_ENUM:
+ return "Enum";
+ default:
+ assert(false);
+ }
+ return "";
+}
+
+bool HasRepeatedFields(const GeneratorOptions& options,
+ const Descriptor* desc) {
+ for (int i = 0; i < desc->field_count(); i++) {
+ if (desc->field(i)->is_repeated() && !desc->field(i)->is_map()) {
+ return true;
+ }
+ }
+ return false;
+}
+
+static const char* kRepeatedFieldArrayName = ".repeatedFields_";
+
+std::string RepeatedFieldsArrayName(const GeneratorOptions& options,
+ const Descriptor* desc) {
+ return HasRepeatedFields(options, desc)
+ ? (GetMessagePath(options, desc) + kRepeatedFieldArrayName)
+ : "null";
+}
+
+bool HasOneofFields(const Descriptor* desc) {
+ for (int i = 0; i < desc->field_count(); i++) {
+ if (InRealOneof(desc->field(i))) {
+ return true;
+ }
+ }
+ return false;
+}
+
+static const char* kOneofGroupArrayName = ".oneofGroups_";
+
+std::string OneofFieldsArrayName(const GeneratorOptions& options,
+ const Descriptor* desc) {
+ return HasOneofFields(desc)
+ ? (GetMessagePath(options, desc) + kOneofGroupArrayName)
+ : "null";
+}
+
+std::string RepeatedFieldNumberList(const GeneratorOptions& options,
+ const Descriptor* desc) {
+ std::vector<std::string> numbers;
+ for (int i = 0; i < desc->field_count(); i++) {
+ if (desc->field(i)->is_repeated() && !desc->field(i)->is_map()) {
+ numbers.push_back(JSFieldIndex(desc->field(i)));
+ }
+ }
+ return "[" + Join(numbers, ",") + "]";
+}
+
+std::string OneofGroupList(const Descriptor* desc) {
+ // List of arrays (one per oneof), each of which is a list of field indices
+ std::vector<std::string> oneof_entries;
+ for (int i = 0; i < desc->oneof_decl_count(); i++) {
+ const OneofDescriptor* oneof = desc->oneof_decl(i);
+ if (IgnoreOneof(oneof)) {
+ continue;
+ }
+
+ std::vector<std::string> oneof_fields;
+ for (int j = 0; j < oneof->field_count(); j++) {
+ if (IgnoreField(oneof->field(j))) {
+ continue;
+ }
+ oneof_fields.push_back(JSFieldIndex(oneof->field(j)));
+ }
+ oneof_entries.push_back("[" + Join(oneof_fields, ",") + "]");
+ }
+ return "[" + Join(oneof_entries, ",") + "]";
+}
+
+std::string JSOneofArray(const GeneratorOptions& options,
+ const FieldDescriptor* field) {
+ return OneofFieldsArrayName(options, field->containing_type()) + "[" +
+ JSOneofIndex(field->containing_oneof()) + "]";
+}
+
+std::string RelativeTypeName(const FieldDescriptor* field) {
+ assert(field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM ||
+ field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE);
+ // For a field with an enum or message type, compute a name relative to the
+ // path name of the message type containing this field.
+ std::string package = field->file()->package();
+ std::string containing_type = field->containing_type()->full_name() + ".";
+ std::string type = (field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM)
+ ? field->enum_type()->full_name()
+ : field->message_type()->full_name();
+
+ // |prefix| is advanced as we find separators '.' past the common package
+ // prefix that yield common prefixes in the containing type's name and this
+ // type's name.
+ int prefix = 0;
+ for (int i = 0; i < type.size() && i < containing_type.size(); i++) {
+ if (type[i] != containing_type[i]) {
+ break;
+ }
+ if (type[i] == '.' && i >= package.size()) {
+ prefix = i + 1;
+ }
+ }
+
+ return type.substr(prefix);
+}
+
+std::string JSExtensionsObjectName(const GeneratorOptions& options,
+ const FileDescriptor* from_file,
+ const Descriptor* desc) {
+ if (desc->full_name() == "google.protobuf.bridge.MessageSet") {
+ // TODO(haberman): fix this for the kImportCommonJs case.
+ return "jspb.Message.messageSetExtensions";
+ } else {
+ return MaybeCrossFileRef(options, from_file, desc) + ".extensions";
+ }
+}
+
+static const int kMapKeyField = 1;
+static const int kMapValueField = 2;
+
+const FieldDescriptor* MapFieldKey(const FieldDescriptor* field) {
+ assert(field->is_map());
+ return field->message_type()->FindFieldByNumber(kMapKeyField);
+}
+
+const FieldDescriptor* MapFieldValue(const FieldDescriptor* field) {
+ assert(field->is_map());
+ return field->message_type()->FindFieldByNumber(kMapValueField);
+}
+
+std::string FieldDefinition(const GeneratorOptions& options,
+ const FieldDescriptor* field) {
+ if (field->is_map()) {
+ const FieldDescriptor* key_field = MapFieldKey(field);
+ const FieldDescriptor* value_field = MapFieldValue(field);
+ std::string key_type = ProtoTypeName(options, key_field);
+ std::string value_type;
+ if (value_field->type() == FieldDescriptor::TYPE_ENUM ||
+ value_field->type() == FieldDescriptor::TYPE_MESSAGE) {
+ value_type = RelativeTypeName(value_field);
+ } else {
+ value_type = ProtoTypeName(options, value_field);
+ }
+ return StringPrintf("map<%s, %s> %s = %d;", key_type.c_str(),
+ value_type.c_str(), field->name().c_str(),
+ field->number());
+ } else {
+ std::string qualifier =
+ field->is_repeated() ? "repeated"
+ : (field->is_optional() ? "optional" : "required");
+ std::string type, name;
+ if (field->type() == FieldDescriptor::TYPE_ENUM ||
+ field->type() == FieldDescriptor::TYPE_MESSAGE) {
+ type = RelativeTypeName(field);
+ name = field->name();
+ } else if (field->type() == FieldDescriptor::TYPE_GROUP) {
+ type = "group";
+ name = field->message_type()->name();
+ } else {
+ type = ProtoTypeName(options, field);
+ name = field->name();
+ }
+ return StringPrintf("%s %s %s = %d;", qualifier.c_str(), type.c_str(),
+ name.c_str(), field->number());
+ }
+}
+
+std::string FieldComments(const FieldDescriptor* field, BytesMode bytes_mode) {
+ std::string comments;
+ if (field->type() == FieldDescriptor::TYPE_BYTES && bytes_mode == BYTES_U8) {
+ comments +=
+ " * Note that Uint8Array is not supported on all browsers.\n"
+ " * @see http://caniuse.com/Uint8Array\n";
+ }
+ return comments;
+}
+
+bool ShouldGenerateExtension(const FieldDescriptor* field) {
+ return field->is_extension() && !IgnoreField(field);
+}
+
+bool HasExtensions(const Descriptor* desc) {
+ for (int i = 0; i < desc->extension_count(); i++) {
+ if (ShouldGenerateExtension(desc->extension(i))) {
+ return true;
+ }
+ }
+ for (int i = 0; i < desc->nested_type_count(); i++) {
+ if (HasExtensions(desc->nested_type(i))) {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool HasExtensions(const FileDescriptor* file) {
+ for (int i = 0; i < file->extension_count(); i++) {
+ if (ShouldGenerateExtension(file->extension(i))) {
+ return true;
+ }
+ }
+ for (int i = 0; i < file->message_type_count(); i++) {
+ if (HasExtensions(file->message_type(i))) {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool HasMap(const GeneratorOptions& options, const Descriptor* desc) {
+ for (int i = 0; i < desc->field_count(); i++) {
+ if (desc->field(i)->is_map()) {
+ return true;
+ }
+ }
+ for (int i = 0; i < desc->nested_type_count(); i++) {
+ if (HasMap(options, desc->nested_type(i))) {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool FileHasMap(const GeneratorOptions& options, const FileDescriptor* desc) {
+ for (int i = 0; i < desc->message_type_count(); i++) {
+ if (HasMap(options, desc->message_type(i))) {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool IsExtendable(const Descriptor* desc) {
+ return desc->extension_range_count() > 0;
+}
+
+// Returns the max index in the underlying data storage array beyond which the
+// extension object is used.
+std::string GetPivot(const Descriptor* desc) {
+ static const int kDefaultPivot = 500;
+
+ // Find the max field number
+ int max_field_number = 0;
+ for (int i = 0; i < desc->field_count(); i++) {
+ if (!IgnoreField(desc->field(i)) &&
+ desc->field(i)->number() > max_field_number) {
+ max_field_number = desc->field(i)->number();
+ }
+ }
+
+ int pivot = -1;
+ if (IsExtendable(desc) || (max_field_number >= kDefaultPivot)) {
+ pivot = ((max_field_number + 1) < kDefaultPivot) ? (max_field_number + 1)
+ : kDefaultPivot;
+ }
+
+ return StrCat(pivot);
+}
+
+// Whether this field represents presence. For fields with presence, we
+// generate extra methods (clearFoo() and hasFoo()) for this field.
+bool HasFieldPresence(const GeneratorOptions& options,
+ const FieldDescriptor* field) {
+ // This returns false for repeated fields and maps, but we still do
+ // generate clearFoo() methods for these through a special case elsewhere.
+ return field->has_presence();
+}
+
+// We use this to implement the semantics that same file can be generated
+// multiple times, but only the last one keep the short name. Others all use
+// long name with extra information to distinguish (For message and enum, the
+// extra information is package name, for file level extension, the extra
+// information is proto's filename).
+// We never actually write the files, but we keep a set of which descriptors
+// were the final one for a given filename.
+class FileDeduplicator {
+ public:
+ explicit FileDeduplicator(const GeneratorOptions& options) {}
+
+ // params:
+ // filenames: a pair of {short filename, full filename}
+ // (short filename don't have extra information, full filename
+ // contains extra information)
+ // desc: The Descriptor or SCC pointer or EnumDescriptor.
+ bool AddFile(const std::pair<std::string, std::string> filenames,
+ const void* desc) {
+ if (descs_by_shortname_.find(filenames.first) !=
+ descs_by_shortname_.end()) {
+ // Change old pointer's actual name to full name.
+ auto short_name_desc = descs_by_shortname_[filenames.first];
+ allowed_descs_actual_name_[short_name_desc] =
+ allowed_descs_full_name_[short_name_desc];
+ }
+ descs_by_shortname_[filenames.first] = desc;
+ allowed_descs_actual_name_[desc] = filenames.first;
+ allowed_descs_full_name_[desc] = filenames.second;
+
+ return true;
+ }
+
+ void GetAllowedMap(std::map<const void*, std::string>* allowed_set) {
+ *allowed_set = allowed_descs_actual_name_;
+ }
+
+ private:
+ // The map that restores all the descs that are using short name as filename.
+ std::map<std::string, const void*> descs_by_shortname_;
+ // The final actual filename map.
+ std::map<const void*, std::string> allowed_descs_actual_name_;
+ // The full name map.
+ std::map<const void*, std::string> allowed_descs_full_name_;
+};
+
+void DepthFirstSearch(const FileDescriptor* file,
+ std::vector<const FileDescriptor*>* list,
+ std::set<const FileDescriptor*>* seen) {
+ if (!seen->insert(file).second) {
+ return;
+ }
+
+ // Add all dependencies.
+ for (int i = 0; i < file->dependency_count(); i++) {
+ DepthFirstSearch(file->dependency(i), list, seen);
+ }
+
+ // Add this file.
+ list->push_back(file);
+}
+
+// A functor for the predicate to remove_if() below. Returns true if a given
+// FileDescriptor is not in the given set.
+class NotInSet {
+ public:
+ explicit NotInSet(const std::set<const FileDescriptor*>& file_set)
+ : file_set_(file_set) {}
+
+ bool operator()(const FileDescriptor* file) {
+ return file_set_.count(file) == 0;
+ }
+
+ private:
+ const std::set<const FileDescriptor*>& file_set_;
+};
+
+// This function generates an ordering of the input FileDescriptors that matches
+// the logic of the old code generator. The order is significant because two
+// different input files can generate the same output file, and the last one
+// needs to win.
+void GenerateJspbFileOrder(const std::vector<const FileDescriptor*>& input,
+ std::vector<const FileDescriptor*>* ordered) {
+ // First generate an ordering of all reachable files (including dependencies)
+ // with depth-first search. This mimics the behavior of --include_imports,
+ // which is what the old codegen used.
+ ordered->clear();
+ std::set<const FileDescriptor*> seen;
+ std::set<const FileDescriptor*> input_set;
+ for (int i = 0; i < input.size(); i++) {
+ DepthFirstSearch(input[i], ordered, &seen);
+ input_set.insert(input[i]);
+ }
+
+ // Now remove the entries that are not actually in our input list.
+ ordered->erase(
+ std::remove_if(ordered->begin(), ordered->end(), NotInSet(input_set)),
+ ordered->end());
+}
+
+// If we're generating code in file-per-type mode, avoid overwriting files
+// by choosing the last descriptor that writes each filename and permitting
+// only those to generate code.
+
+struct DepsGenerator {
+ std::vector<const Descriptor*> operator()(const Descriptor* desc) const {
+ std::vector<const Descriptor*> deps;
+ auto maybe_add = [&](const Descriptor* d) {
+ if (d) deps.push_back(d);
+ };
+ for (int i = 0; i < desc->field_count(); i++) {
+ if (!IgnoreField(desc->field(i))) {
+ maybe_add(desc->field(i)->message_type());
+ }
+ }
+ for (int i = 0; i < desc->extension_count(); i++) {
+ maybe_add(desc->extension(i)->message_type());
+ maybe_add(desc->extension(i)->containing_type());
+ }
+ for (int i = 0; i < desc->nested_type_count(); i++) {
+ maybe_add(desc->nested_type(i));
+ }
+ maybe_add(desc->containing_type());
+
+ return deps;
+ }
+};
+
+bool GenerateJspbAllowedMap(const GeneratorOptions& options,
+ const std::vector<const FileDescriptor*>& files,
+ std::map<const void*, std::string>* allowed_set,
+ SCCAnalyzer<DepsGenerator>* analyzer) {
+ std::vector<const FileDescriptor*> files_ordered;
+ GenerateJspbFileOrder(files, &files_ordered);
+
+ // Choose the last descriptor for each filename.
+ FileDeduplicator dedup(options);
+ std::set<const SCC*> added;
+ for (int i = 0; i < files_ordered.size(); i++) {
+ for (int j = 0; j < files_ordered[i]->message_type_count(); j++) {
+ const Descriptor* desc = files_ordered[i]->message_type(j);
+ if (added.insert(analyzer->GetSCC(desc)).second &&
+ !dedup.AddFile(
+ std::make_pair(
+ GetMessagesFileName(options, analyzer->GetSCC(desc), false),
+ GetMessagesFileName(options, analyzer->GetSCC(desc), true)),
+ analyzer->GetSCC(desc))) {
+ return false;
+ }
+ }
+ for (int j = 0; j < files_ordered[i]->enum_type_count(); j++) {
+ const EnumDescriptor* desc = files_ordered[i]->enum_type(j);
+ if (!dedup.AddFile(std::make_pair(GetEnumFileName(options, desc, false),
+ GetEnumFileName(options, desc, true)),
+ desc)) {
+ return false;
+ }
+ }
+
+ // Pull out all free-floating extensions and generate files for those too.
+ bool has_extension = false;
+
+ for (int j = 0; j < files_ordered[i]->extension_count(); j++) {
+ if (ShouldGenerateExtension(files_ordered[i]->extension(j))) {
+ has_extension = true;
+ }
+ }
+
+ if (has_extension) {
+ if (!dedup.AddFile(
+ std::make_pair(
+ GetExtensionFileName(options, files_ordered[i], false),
+ GetExtensionFileName(options, files_ordered[i], true)),
+ files_ordered[i])) {
+ return false;
+ }
+ }
+ }
+
+ dedup.GetAllowedMap(allowed_set);
+
+ return true;
+}
+
+// Embeds base64 encoded GeneratedCodeInfo proto in a comment at the end of
+// file.
+void EmbedCodeAnnotations(const GeneratedCodeInfo& annotations,
+ io::Printer* printer) {
+ // Serialize annotations proto into base64 string.
+ std::string meta_content;
+ annotations.SerializeToString(&meta_content);
+ std::string meta_64;
+ Base64Escape(meta_content, &meta_64);
+
+ // Print base64 encoded annotations at the end of output file in
+ // a comment.
+ printer->Print("\n// Below is base64 encoded GeneratedCodeInfo proto");
+ printer->Print("\n// $encoded_proto$\n", "encoded_proto", meta_64);
+}
+
+bool IsWellKnownTypeFile(const FileDescriptor* file) {
+ return HasPrefixString(file->name(), "google/protobuf/");
+}
+
+} // anonymous namespace
+
+void Generator::GenerateHeader(const GeneratorOptions& options,
+ const FileDescriptor* file,
+ io::Printer* printer) const {
+ if (file != nullptr) {
+ printer->Print("// source: $filename$\n", "filename", file->name());
+ }
+ printer->Print(
+ "/**\n"
+ " * @fileoverview\n"
+ " * @enhanceable\n"
+ // TODO(b/152440355): requireType/requires diverged from internal version.
+ " * @suppress {missingRequire} reports error on implicit type usages.\n"
+ " * @suppress {messageConventions} JS Compiler reports an "
+ "error if a variable or\n"
+ " * field starts with 'MSG_' and isn't a translatable "
+ "message.\n"
+ " * @public\n"
+ " */\n"
+ "// GENERATED CODE -- DO NOT EDIT!\n"
+ "/* eslint-disable */\n"
+ "// @ts-nocheck\n"
+ "\n");
+}
+
+void Generator::FindProvidesForFile(const GeneratorOptions& options,
+ io::Printer* printer,
+ const FileDescriptor* file,
+ std::set<std::string>* provided) const {
+ for (int i = 0; i < file->message_type_count(); i++) {
+ FindProvidesForMessage(options, printer, file->message_type(i), provided);
+ }
+ for (int i = 0; i < file->enum_type_count(); i++) {
+ FindProvidesForEnum(options, printer, file->enum_type(i), provided);
+ }
+}
+
+void Generator::FindProvides(const GeneratorOptions& options,
+ io::Printer* printer,
+ const std::vector<const FileDescriptor*>& files,
+ std::set<std::string>* provided) const {
+ for (int i = 0; i < files.size(); i++) {
+ FindProvidesForFile(options, printer, files[i], provided);
+ }
+
+ printer->Print("\n");
+}
+
+void FindProvidesForOneOfEnum(const GeneratorOptions& options,
+ const OneofDescriptor* oneof,
+ std::set<std::string>* provided) {
+ std::string name = GetMessagePath(options, oneof->containing_type()) + "." +
+ JSOneofName(oneof) + "Case";
+ provided->insert(name);
+}
+
+void FindProvidesForOneOfEnums(const GeneratorOptions& options,
+ io::Printer* printer, const Descriptor* desc,
+ std::set<std::string>* provided) {
+ if (HasOneofFields(desc)) {
+ for (int i = 0; i < desc->oneof_decl_count(); i++) {
+ if (IgnoreOneof(desc->oneof_decl(i))) {
+ continue;
+ }
+ FindProvidesForOneOfEnum(options, desc->oneof_decl(i), provided);
+ }
+ }
+}
+
+void Generator::FindProvidesForMessage(const GeneratorOptions& options,
+ io::Printer* printer,
+ const Descriptor* desc,
+ std::set<std::string>* provided) const {
+ if (IgnoreMessage(desc)) {
+ return;
+ }
+
+ std::string name = GetMessagePath(options, desc);
+ provided->insert(name);
+
+ for (int i = 0; i < desc->enum_type_count(); i++) {
+ FindProvidesForEnum(options, printer, desc->enum_type(i), provided);
+ }
+
+ FindProvidesForOneOfEnums(options, printer, desc, provided);
+
+ for (int i = 0; i < desc->nested_type_count(); i++) {
+ FindProvidesForMessage(options, printer, desc->nested_type(i), provided);
+ }
+}
+void Generator::FindProvidesForEnum(const GeneratorOptions& options,
+ io::Printer* printer,
+ const EnumDescriptor* enumdesc,
+ std::set<std::string>* provided) const {
+ std::string name = GetEnumPath(options, enumdesc);
+ provided->insert(name);
+}
+
+void Generator::FindProvidesForFields(
+ const GeneratorOptions& options, io::Printer* printer,
+ const std::vector<const FieldDescriptor*>& fields,
+ std::set<std::string>* provided) const {
+ for (int i = 0; i < fields.size(); i++) {
+ const FieldDescriptor* field = fields[i];
+
+ if (IgnoreField(field)) {
+ continue;
+ }
+
+ std::string name = GetNamespace(options, field->file()) + "." +
+ JSObjectFieldName(options, field);
+ provided->insert(name);
+ }
+}
+
+void Generator::GenerateProvides(const GeneratorOptions& options,
+ io::Printer* printer,
+ std::set<std::string>* provided) const {
+ for (std::set<std::string>::iterator it = provided->begin();
+ it != provided->end(); ++it) {
+ if (options.import_style == GeneratorOptions::kImportClosure) {
+ printer->Print("goog.provide('$name$');\n", "name", *it);
+ } else {
+ // We aren't using Closure's import system, but we use goog.exportSymbol()
+ // to construct the expected tree of objects, eg.
+ //
+ // goog.exportSymbol('foo.bar.Baz', null, this);
+ //
+ // // Later generated code expects foo.bar = {} to exist:
+ // foo.bar.Baz = function() { /* ... */ }
+
+ // Do not use global scope in strict mode
+ if (options.import_style == GeneratorOptions::kImportCommonJsStrict) {
+ std::string namespaceObject = *it;
+ // Remove "proto." from the namespace object
+ GOOGLE_CHECK_EQ(0, namespaceObject.compare(0, 6, "proto."));
+ namespaceObject.erase(0, 6);
+ printer->Print("goog.exportSymbol('$name$', null, proto);\n", "name",
+ namespaceObject);
+ } else {
+ printer->Print("goog.exportSymbol('$name$', null, global);\n", "name",
+ *it);
+ }
+ }
+ }
+}
+
+void Generator::GenerateRequiresForSCC(const GeneratorOptions& options,
+ io::Printer* printer, const SCC* scc,
+ std::set<std::string>* provided) const {
+ std::set<std::string> required;
+ std::set<std::string> forwards;
+ bool have_message = false;
+ bool has_extension = false;
+ bool has_map = false;
+ for (auto desc : scc->descriptors) {
+ if (desc->containing_type() == nullptr) {
+ FindRequiresForMessage(options, desc, &required, &forwards,
+ &have_message);
+ has_extension = (has_extension || HasExtensions(desc));
+ has_map = (has_map || HasMap(options, desc));
+ }
+ }
+
+ GenerateRequiresImpl(options, printer, &required, &forwards, provided,
+ /* require_jspb = */ have_message,
+ /* require_extension = */ has_extension,
+ /* require_map = */ has_map);
+}
+
+void Generator::GenerateRequiresForLibrary(
+ const GeneratorOptions& options, io::Printer* printer,
+ const std::vector<const FileDescriptor*>& files,
+ std::set<std::string>* provided) const {
+ GOOGLE_CHECK_EQ(options.import_style, GeneratorOptions::kImportClosure);
+ // For Closure imports we need to import every message type individually.
+ std::set<std::string> required;
+ std::set<std::string> forwards;
+ bool have_extensions = false;
+ bool have_map = false;
+ bool have_message = false;
+
+ for (int i = 0; i < files.size(); i++) {
+ for (int j = 0; j < files[i]->message_type_count(); j++) {
+ const Descriptor* desc = files[i]->message_type(j);
+ if (!IgnoreMessage(desc)) {
+ FindRequiresForMessage(options, desc, &required, &forwards,
+ &have_message);
+ }
+ }
+
+ if (!have_extensions && HasExtensions(files[i])) {
+ have_extensions = true;
+ }
+
+ if (!have_map && FileHasMap(options, files[i])) {
+ have_map = true;
+ }
+
+ for (int j = 0; j < files[i]->extension_count(); j++) {
+ const FieldDescriptor* extension = files[i]->extension(j);
+ if (IgnoreField(extension)) {
+ continue;
+ }
+ if (extension->containing_type()->full_name() !=
+ "google.protobuf.bridge.MessageSet") {
+ required.insert(GetMessagePath(options, extension->containing_type()));
+ }
+ FindRequiresForField(options, extension, &required, &forwards);
+ have_extensions = true;
+ }
+ }
+
+ GenerateRequiresImpl(options, printer, &required, &forwards, provided,
+ /* require_jspb = */ have_message,
+ /* require_extension = */ have_extensions,
+ /* require_map = */ have_map);
+}
+
+void Generator::GenerateRequiresForExtensions(
+ const GeneratorOptions& options, io::Printer* printer,
+ const std::vector<const FieldDescriptor*>& fields,
+ std::set<std::string>* provided) const {
+ std::set<std::string> required;
+ std::set<std::string> forwards;
+ for (int i = 0; i < fields.size(); i++) {
+ const FieldDescriptor* field = fields[i];
+ if (IgnoreField(field)) {
+ continue;
+ }
+ FindRequiresForExtension(options, field, &required, &forwards);
+ }
+
+ GenerateRequiresImpl(options, printer, &required, &forwards, provided,
+ /* require_jspb = */ false,
+ /* require_extension = */ fields.size() > 0,
+ /* require_map = */ false);
+}
+
+void Generator::GenerateRequiresImpl(const GeneratorOptions& options,
+ io::Printer* printer,
+ std::set<std::string>* required,
+ std::set<std::string>* forwards,
+ std::set<std::string>* provided,
+ bool require_jspb, bool require_extension,
+ bool require_map) const {
+ if (require_jspb) {
+ required->insert("jspb.Message");
+ required->insert("jspb.BinaryReader");
+ required->insert("jspb.BinaryWriter");
+ }
+ if (require_extension) {
+ required->insert("jspb.ExtensionFieldBinaryInfo");
+ required->insert("jspb.ExtensionFieldInfo");
+ }
+ if (require_map) {
+ required->insert("jspb.Map");
+ }
+
+ std::set<std::string>::iterator it;
+ for (it = required->begin(); it != required->end(); ++it) {
+ if (provided->find(*it) != provided->end()) {
+ continue;
+ }
+ printer->Print("goog.require('$name$');\n", "name", *it);
+ }
+
+ printer->Print("\n");
+
+ for (it = forwards->begin(); it != forwards->end(); ++it) {
+ if (provided->find(*it) != provided->end()) {
+ continue;
+ }
+ printer->Print("goog.forwardDeclare('$name$');\n", "name", *it);
+ }
+}
+
+bool NamespaceOnly(const Descriptor* desc) { return false; }
+
+void Generator::FindRequiresForMessage(const GeneratorOptions& options,
+ const Descriptor* desc,
+ std::set<std::string>* required,
+ std::set<std::string>* forwards,
+ bool* have_message) const {
+ if (!NamespaceOnly(desc)) {
+ *have_message = true;
+ for (int i = 0; i < desc->field_count(); i++) {
+ const FieldDescriptor* field = desc->field(i);
+ if (IgnoreField(field)) {
+ continue;
+ }
+ FindRequiresForField(options, field, required, forwards);
+ }
+ }
+
+ for (int i = 0; i < desc->extension_count(); i++) {
+ const FieldDescriptor* field = desc->extension(i);
+ if (IgnoreField(field)) {
+ continue;
+ }
+ FindRequiresForExtension(options, field, required, forwards);
+ }
+
+ for (int i = 0; i < desc->nested_type_count(); i++) {
+ FindRequiresForMessage(options, desc->nested_type(i), required, forwards,
+ have_message);
+ }
+}
+
+void Generator::FindRequiresForField(const GeneratorOptions& options,
+ const FieldDescriptor* field,
+ std::set<std::string>* required,
+ std::set<std::string>* forwards) const {
+ if (field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM &&
+ // N.B.: file-level extensions with enum type do *not* create
+ // dependencies, as per original codegen.
+ !(field->is_extension() && field->extension_scope() == nullptr)) {
+ if (options.add_require_for_enums) {
+ required->insert(GetEnumPath(options, field->enum_type()));
+ } else {
+ forwards->insert(GetEnumPath(options, field->enum_type()));
+ }
+ } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+ if (!IgnoreMessage(field->message_type())) {
+ required->insert(GetMessagePath(options, field->message_type()));
+ }
+ }
+}
+
+void Generator::FindRequiresForExtension(
+ const GeneratorOptions& options, const FieldDescriptor* field,
+ std::set<std::string>* required, std::set<std::string>* forwards) const {
+ if (field->containing_type()->full_name() !=
+ "google.protobuf.bridge.MessageSet") {
+ required->insert(GetMessagePath(options, field->containing_type()));
+ }
+ FindRequiresForField(options, field, required, forwards);
+}
+
+void Generator::GenerateTestOnly(const GeneratorOptions& options,
+ io::Printer* printer) const {
+ if (options.testonly) {
+ printer->Print("goog.setTestOnly();\n\n");
+ }
+ printer->Print("\n");
+}
+
+void Generator::GenerateClassesAndEnums(const GeneratorOptions& options,
+ io::Printer* printer,
+ const FileDescriptor* file) const {
+ for (int i = 0; i < file->message_type_count(); i++) {
+ GenerateClassConstructorAndDeclareExtensionFieldInfo(options, printer,
+ file->message_type(i));
+ }
+ for (int i = 0; i < file->message_type_count(); i++) {
+ GenerateClass(options, printer, file->message_type(i));
+ }
+ for (int i = 0; i < file->enum_type_count(); i++) {
+ GenerateEnum(options, printer, file->enum_type(i));
+ }
+}
+
+void Generator::GenerateClass(const GeneratorOptions& options,
+ io::Printer* printer,
+ const Descriptor* desc) const {
+ if (IgnoreMessage(desc)) {
+ return;
+ }
+
+ if (!NamespaceOnly(desc)) {
+ printer->Print("\n");
+ GenerateClassFieldInfo(options, printer, desc);
+
+ GenerateClassToObject(options, printer, desc);
+ // These must come *before* the extension-field info generation in
+ // GenerateClassRegistration so that references to the binary
+ // serialization/deserialization functions may be placed in the extension
+ // objects.
+ GenerateClassDeserializeBinary(options, printer, desc);
+ GenerateClassSerializeBinary(options, printer, desc);
+ }
+
+ // Recurse on nested types. These must come *before* the extension-field
+ // info generation in GenerateClassRegistration so that extensions that
+ // reference nested types proceed the definitions of the nested types.
+ for (int i = 0; i < desc->enum_type_count(); i++) {
+ GenerateEnum(options, printer, desc->enum_type(i));
+ }
+ for (int i = 0; i < desc->nested_type_count(); i++) {
+ GenerateClass(options, printer, desc->nested_type(i));
+ }
+
+ if (!NamespaceOnly(desc)) {
+ GenerateClassRegistration(options, printer, desc);
+ GenerateClassFields(options, printer, desc);
+
+ if (options.import_style != GeneratorOptions::kImportClosure) {
+ for (int i = 0; i < desc->extension_count(); i++) {
+ GenerateExtension(options, printer, desc->extension(i));
+ }
+ }
+ }
+}
+
+void Generator::GenerateClassConstructor(const GeneratorOptions& options,
+ io::Printer* printer,
+ const Descriptor* desc) const {
+ printer->Print(
+ "/**\n"
+ " * Generated by JsPbCodeGenerator.\n"
+ " * @param {Array=} opt_data Optional initial data array, typically "
+ "from a\n"
+ " * server response, or constructed directly in Javascript. The array "
+ "is used\n"
+ " * in place and becomes part of the constructed object. It is not "
+ "cloned.\n"
+ " * If no data is provided, the constructed object will be empty, but "
+ "still\n"
+ " * valid.\n"
+ " * @extends {jspb.Message}\n"
+ " * @constructor\n"
+ " */\n"
+ "$classprefix$$classname$ = function(opt_data) {\n",
+ "classprefix", GetMessagePathPrefix(options, desc), "classname",
+ desc->name());
+ printer->Annotate("classname", desc);
+ std::string message_id = GetMessageId(desc);
+ printer->Print(
+ " jspb.Message.initialize(this, opt_data, $messageId$, $pivot$, "
+ "$rptfields$, $oneoffields$);\n",
+ "messageId",
+ !message_id.empty() ? ("'" + message_id + "'")
+ : (IsResponse(desc) ? "''" : "0"),
+ "pivot", GetPivot(desc), "rptfields",
+ RepeatedFieldsArrayName(options, desc), "oneoffields",
+ OneofFieldsArrayName(options, desc));
+ printer->Print(
+ "};\n"
+ "goog.inherits($classname$, jspb.Message);\n"
+ "if (goog.DEBUG && !COMPILED) {\n"
+ // displayName overrides Function.prototype.displayName
+ // http://google3/javascript/externs/es3.js?l=511
+ " /**\n"
+ " * @public\n"
+ " * @override\n"
+ " */\n"
+ " $classname$.displayName = '$classname$';\n"
+ "}\n",
+ "classname", GetMessagePath(options, desc));
+}
+
+void Generator::GenerateClassConstructorAndDeclareExtensionFieldInfo(
+ const GeneratorOptions& options, io::Printer* printer,
+ const Descriptor* desc) const {
+ if (!NamespaceOnly(desc)) {
+ GenerateClassConstructor(options, printer, desc);
+ if (IsExtendable(desc) &&
+ desc->full_name() != "google.protobuf.bridge.MessageSet") {
+ GenerateClassExtensionFieldInfo(options, printer, desc);
+ }
+ }
+ for (int i = 0; i < desc->nested_type_count(); i++) {
+ if (!IgnoreMessage(desc->nested_type(i))) {
+ GenerateClassConstructorAndDeclareExtensionFieldInfo(
+ options, printer, desc->nested_type(i));
+ }
+ }
+}
+
+void Generator::GenerateClassFieldInfo(const GeneratorOptions& options,
+ io::Printer* printer,
+ const Descriptor* desc) const {
+ if (HasRepeatedFields(options, desc)) {
+ printer->Print(
+ "/**\n"
+ " * List of repeated fields within this message type.\n"
+ " * @private {!Array<number>}\n"
+ " * @const\n"
+ " */\n"
+ "$classname$$rptfieldarray$ = $rptfields$;\n"
+ "\n",
+ "classname", GetMessagePath(options, desc), "rptfieldarray",
+ kRepeatedFieldArrayName, "rptfields",
+ RepeatedFieldNumberList(options, desc));
+ }
+
+ if (HasOneofFields(desc)) {
+ printer->Print(
+ "/**\n"
+ " * Oneof group definitions for this message. Each group defines the "
+ "field\n"
+ " * numbers belonging to that group. When of these fields' value is "
+ "set, all\n"
+ " * other fields in the group are cleared. During deserialization, if "
+ "multiple\n"
+ " * fields are encountered for a group, only the last value seen will "
+ "be kept.\n"
+ " * @private {!Array<!Array<number>>}\n"
+ " * @const\n"
+ " */\n"
+ "$classname$$oneofgrouparray$ = $oneofgroups$;\n"
+ "\n",
+ "classname", GetMessagePath(options, desc), "oneofgrouparray",
+ kOneofGroupArrayName, "oneofgroups", OneofGroupList(desc));
+
+ for (int i = 0; i < desc->oneof_decl_count(); i++) {
+ if (IgnoreOneof(desc->oneof_decl(i))) {
+ continue;
+ }
+ GenerateOneofCaseDefinition(options, printer, desc->oneof_decl(i));
+ }
+ }
+}
+
+void Generator::GenerateClassXid(const GeneratorOptions& options,
+ io::Printer* printer,
+ const Descriptor* desc) const {
+ printer->Print(
+ "\n"
+ "\n"
+ "$class$.prototype.messageXid = xid('$class$');\n",
+ "class", GetMessagePath(options, desc));
+}
+
+void Generator::GenerateOneofCaseDefinition(
+ const GeneratorOptions& options, io::Printer* printer,
+ const OneofDescriptor* oneof) const {
+ printer->Print(
+ "/**\n"
+ " * @enum {number}\n"
+ " */\n"
+ "$classname$.$oneof$Case = {\n"
+ " $upcase$_NOT_SET: 0",
+ "classname", GetMessagePath(options, oneof->containing_type()), "oneof",
+ JSOneofName(oneof), "upcase", ToEnumCase(oneof->name()));
+
+ for (int i = 0; i < oneof->field_count(); i++) {
+ if (IgnoreField(oneof->field(i))) {
+ continue;
+ }
+
+ printer->Print(
+ ",\n"
+ " $upcase$: $number$",
+ "upcase", ToEnumCase(oneof->field(i)->name()), "number",
+ JSFieldIndex(oneof->field(i)));
+ printer->Annotate("upcase", oneof->field(i));
+ }
+
+ printer->Print(
+ "\n"
+ "};\n"
+ "\n"
+ "/**\n"
+ " * @return {$class$.$oneof$Case}\n"
+ " */\n"
+ "$class$.prototype.get$oneof$Case = function() {\n"
+ " return /** @type {$class$.$oneof$Case} */(jspb.Message."
+ "computeOneofCase(this, $class$.oneofGroups_[$oneofindex$]));\n"
+ "};\n"
+ "\n",
+ "class", GetMessagePath(options, oneof->containing_type()), "oneof",
+ JSOneofName(oneof), "oneofindex", JSOneofIndex(oneof));
+}
+
+void Generator::GenerateClassToObject(const GeneratorOptions& options,
+ io::Printer* printer,
+ const Descriptor* desc) const {
+ printer->Print(
+ "\n"
+ "\n"
+ "if (jspb.Message.GENERATE_TO_OBJECT) {\n"
+ "/**\n"
+ " * Creates an object representation of this proto.\n"
+ " * Field names that are reserved in JavaScript and will be renamed to "
+ "pb_name.\n"
+ " * Optional fields that are not set will be set to undefined.\n"
+ " * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.\n"
+ " * For the list of reserved names please see:\n"
+ " * net/proto2/compiler/js/internal/generator.cc#kKeyword.\n"
+ " * @param {boolean=} opt_includeInstance Deprecated. whether to include "
+ "the\n"
+ " * JSPB instance for transitional soy proto support:\n"
+ " * http://goto/soy-param-migration\n"
+ " * @return {!Object}\n"
+ " */\n"
+ "$classname$.prototype.toObject = function(opt_includeInstance) {\n"
+ " return $classname$.toObject(opt_includeInstance, this);\n"
+ "};\n"
+ "\n"
+ "\n"
+ "/**\n"
+ " * Static version of the {@see toObject} method.\n"
+ " * @param {boolean|undefined} includeInstance Deprecated. Whether to "
+ "include\n"
+ " * the JSPB instance for transitional soy proto support:\n"
+ " * http://goto/soy-param-migration\n"
+ " * @param {!$classname$} msg The msg instance to transform.\n"
+ " * @return {!Object}\n"
+ " * @suppress {unusedLocalVariables} f is only used for nested messages\n"
+ " */\n"
+ "$classname$.toObject = function(includeInstance, msg) {\n"
+ " var f, obj = {",
+ "classname", GetMessagePath(options, desc));
+
+ bool first = true;
+ for (int i = 0; i < desc->field_count(); i++) {
+ const FieldDescriptor* field = desc->field(i);
+ if (IgnoreField(field)) {
+ continue;
+ }
+
+ if (!first) {
+ printer->Print(",\n ");
+ } else {
+ printer->Print("\n ");
+ first = false;
+ }
+
+ GenerateClassFieldToObject(options, printer, field);
+ }
+
+ if (!first) {
+ printer->Print("\n };\n\n");
+ } else {
+ printer->Print("\n\n };\n\n");
+ }
+
+ if (IsExtendable(desc)) {
+ printer->Print(
+ " jspb.Message.toObjectExtension(/** @type {!jspb.Message} */ (msg), "
+ "obj,\n"
+ " $extObject$, $class$.prototype.getExtension,\n"
+ " includeInstance);\n",
+ "extObject", JSExtensionsObjectName(options, desc->file(), desc),
+ "class", GetMessagePath(options, desc));
+ }
+
+ printer->Print(
+ " if (includeInstance) {\n"
+ " obj.$$jspbMessageInstance = msg;\n"
+ " }\n"
+ " return obj;\n"
+ "};\n"
+ "}\n"
+ "\n"
+ "\n",
+ "classname", GetMessagePath(options, desc));
+}
+
+void Generator::GenerateFieldValueExpression(io::Printer* printer,
+ const char* obj_reference,
+ const FieldDescriptor* field,
+ bool use_default) const {
+ const bool is_float_or_double =
+ field->cpp_type() == FieldDescriptor::CPPTYPE_FLOAT ||
+ field->cpp_type() == FieldDescriptor::CPPTYPE_DOUBLE;
+ const bool is_boolean = field->cpp_type() == FieldDescriptor::CPPTYPE_BOOL;
+
+ const std::string with_default = use_default ? "WithDefault" : "";
+ const std::string default_arg =
+ use_default ? StrCat(", ", JSFieldDefault(field)) : "";
+ const std::string cardinality = field->is_repeated() ? "Repeated" : "";
+ std::string type = "";
+ if (is_float_or_double) {
+ type = "FloatingPoint";
+ }
+ if (is_boolean) {
+ type = "Boolean";
+ }
+
+ // Prints the appropriate function, among:
+ // - getField
+ // - getBooleanField
+ // - getFloatingPointField => Replaced by getOptionalFloatingPointField to
+ // preserve backward compatibility.
+ // - getFieldWithDefault
+ // - getBooleanFieldWithDefault
+ // - getFloatingPointFieldWithDefault
+ // - getRepeatedField
+ // - getRepeatedBooleanField
+ // - getRepeatedFloatingPointField
+ if (is_float_or_double && !field->is_repeated() && !use_default) {
+ printer->Print(
+ "jspb.Message.getOptionalFloatingPointField($obj$, "
+ "$index$$default$)",
+ "obj", obj_reference, "index", JSFieldIndex(field), "default",
+ default_arg);
+ } else {
+ printer->Print(
+ "jspb.Message.get$cardinality$$type$Field$with_default$($obj$, "
+ "$index$$default$)",
+ "cardinality", cardinality, "type", type, "with_default", with_default,
+ "obj", obj_reference, "index", JSFieldIndex(field), "default",
+ default_arg);
+ }
+}
+
+void Generator::GenerateClassFieldToObject(const GeneratorOptions& options,
+ io::Printer* printer,
+ const FieldDescriptor* field) const {
+ printer->Print("$fieldname$: ", "fieldname",
+ JSObjectFieldName(options, field));
+
+ if (field->is_map()) {
+ const FieldDescriptor* value_field = MapFieldValue(field);
+ // If the map values are of a message type, we must provide their static
+ // toObject() method; otherwise we pass undefined for that argument.
+ std::string value_to_object;
+ if (value_field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+ value_to_object =
+ GetMessagePath(options, value_field->message_type()) + ".toObject";
+ } else {
+ value_to_object = "undefined";
+ }
+ printer->Print(
+ "(f = msg.get$name$()) ? f.toObject(includeInstance, $valuetoobject$) "
+ ": []",
+ "name", JSGetterName(options, field), "valuetoobject", value_to_object);
+ } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+ // Message field.
+ if (field->is_repeated()) {
+ {
+ printer->Print(
+ "jspb.Message.toObjectList(msg.get$getter$(),\n"
+ " $type$.toObject, includeInstance)",
+ "getter", JSGetterName(options, field), "type",
+ SubmessageTypeRef(options, field));
+ }
+ } else {
+ printer->Print(
+ "(f = msg.get$getter$()) && "
+ "$type$.toObject(includeInstance, f)",
+ "getter", JSGetterName(options, field), "type",
+ SubmessageTypeRef(options, field));
+ }
+ } else if (field->type() == FieldDescriptor::TYPE_BYTES) {
+ // For bytes fields we want to always return the B64 data.
+ printer->Print("msg.get$getter$()", "getter",
+ JSGetterName(options, field, BYTES_B64));
+ } else {
+ bool use_default = field->has_default_value();
+
+ if (field->file()->syntax() == FileDescriptor::SYNTAX_PROTO3 &&
+ // Repeated fields get initialized to their default in the constructor
+ // (why?), so we emit a plain getField() call for them.
+ !field->is_repeated()) {
+ // Proto3 puts all defaults (including implicit defaults) in toObject().
+ // But for proto2 we leave the existing semantics unchanged: unset fields
+ // without default are unset.
+ use_default = true;
+ }
+
+ // We don't implement this by calling the accessors, because the semantics
+ // of the accessors are changing independently of the toObject() semantics.
+ // We are migrating the accessors to return defaults instead of null, but
+ // it may take longer to migrate toObject (or we might not want to do it at
+ // all). So we want to generate independent code.
+ // The accessor for unset optional values without default should return
+ // null. Those are converted to undefined in the generated object.
+ if (!use_default) {
+ printer->Print("(f = ");
+ }
+ GenerateFieldValueExpression(printer, "msg", field, use_default);
+ if (!use_default) {
+ printer->Print(") == null ? undefined : f");
+ }
+ }
+}
+
+void Generator::GenerateObjectTypedef(const GeneratorOptions& options,
+ io::Printer* printer,
+ const Descriptor* desc) const {
+ // TODO(b/122687752): Consider renaming nested messages called ObjectFormat
+ // to prevent collisions.
+ const std::string type_name = GetMessagePath(options, desc) + ".ObjectFormat";
+
+ printer->Print(
+ "/**\n"
+ " * The raw object form of $messageName$ as accepted by the `fromObject` "
+ "method.\n"
+ " * @record\n"
+ " */\n"
+ "$typeName$ = function() {\n",
+ "messageName", desc->name(), "typeName", type_name);
+
+ for (int i = 0; i < desc->field_count(); i++) {
+ if (i > 0) {
+ printer->Print("\n");
+ }
+ printer->Print(
+ " /** @type {$fieldType$|undefined} */\n"
+ " this.$fieldName$;\n",
+ "fieldName", JSObjectFieldName(options, desc->field(i)),
+ // TODO(b/121097361): Add type checking for field values.
+ "fieldType", "?");
+ }
+
+ printer->Print("};\n\n");
+}
+
+void Generator::GenerateClassFromObject(const GeneratorOptions& options,
+ io::Printer* printer,
+ const Descriptor* desc) const {
+ printer->Print("if (jspb.Message.GENERATE_FROM_OBJECT) {\n\n");
+
+ GenerateObjectTypedef(options, printer, desc);
+
+ printer->Print(
+ "/**\n"
+ " * Loads data from an object into a new instance of this proto.\n"
+ " * @param {!$classname$.ObjectFormat} obj\n"
+ " * The object representation of this proto to load the data from.\n"
+ " * @return {!$classname$}\n"
+ " */\n"
+ "$classname$.fromObject = function(obj) {\n"
+ " var msg = new $classname$();\n",
+ "classname", GetMessagePath(options, desc));
+
+ for (int i = 0; i < desc->field_count(); i++) {
+ const FieldDescriptor* field = desc->field(i);
+ if (!IgnoreField(field)) {
+ GenerateClassFieldFromObject(options, printer, field);
+ }
+ }
+
+ printer->Print(
+ " return msg;\n"
+ "};\n"
+ "}\n\n");
+}
+
+void Generator::GenerateClassFieldFromObject(
+ const GeneratorOptions& options, io::Printer* printer,
+ const FieldDescriptor* field) const {
+ if (field->is_map()) {
+ const FieldDescriptor* value_field = MapFieldValue(field);
+ if (value_field->type() == FieldDescriptor::TYPE_MESSAGE) {
+ // Since the map values are of message type, we have to do some extra work
+ // to recursively call fromObject() on them before setting the map field.
+ printer->Print(
+ " obj.$name$ && jspb.Message.setWrapperField(\n"
+ " msg, $index$, jspb.Map.fromObject(obj.$name$, $fieldclass$, "
+ "$fieldclass$.fromObject));\n",
+ "name", JSObjectFieldName(options, field), "index",
+ JSFieldIndex(field), "fieldclass",
+ GetMessagePath(options, value_field->message_type()));
+ } else {
+ // `msg` is a newly-constructed message object that has not yet built any
+ // map containers wrapping underlying arrays, so we can simply directly
+ // set the array here without fear of a stale wrapper.
+ printer->Print(
+ " obj.$name$ && "
+ "jspb.Message.setField(msg, $index$, obj.$name$);\n",
+ "name", JSObjectFieldName(options, field), "index",
+ JSFieldIndex(field));
+ }
+ } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+ // Message field (singular or repeated)
+ if (field->is_repeated()) {
+ {
+ printer->Print(
+ " obj.$name$ && "
+ "jspb.Message.setRepeatedWrapperField(\n"
+ " msg, $index$, obj.$name$.map(\n"
+ " $fieldclass$.fromObject));\n",
+ "name", JSObjectFieldName(options, field), "index",
+ JSFieldIndex(field), "fieldclass",
+ SubmessageTypeRef(options, field));
+ }
+ } else {
+ printer->Print(
+ " obj.$name$ && jspb.Message.setWrapperField(\n"
+ " msg, $index$, $fieldclass$.fromObject(obj.$name$));\n",
+ "name", JSObjectFieldName(options, field), "index",
+ JSFieldIndex(field), "fieldclass", SubmessageTypeRef(options, field));
+ }
+ } else {
+ // Simple (primitive) field.
+ printer->Print(
+ " obj.$name$ != null && jspb.Message.setField(msg, $index$, "
+ "obj.$name$);\n",
+ "name", JSObjectFieldName(options, field), "index",
+ JSFieldIndex(field));
+ }
+}
+
+void Generator::GenerateClassRegistration(const GeneratorOptions& options,
+ io::Printer* printer,
+ const Descriptor* desc) const {
+ // Register any extensions defined inside this message type.
+ for (int i = 0; i < desc->extension_count(); i++) {
+ const FieldDescriptor* extension = desc->extension(i);
+ if (ShouldGenerateExtension(extension)) {
+ GenerateExtension(options, printer, extension);
+ }
+ }
+}
+
+void Generator::GenerateClassFields(const GeneratorOptions& options,
+ io::Printer* printer,
+ const Descriptor* desc) const {
+ for (int i = 0; i < desc->field_count(); i++) {
+ if (!IgnoreField(desc->field(i))) {
+ GenerateClassField(options, printer, desc->field(i));
+ }
+ }
+}
+
+void GenerateBytesWrapper(const GeneratorOptions& options, io::Printer* printer,
+ const FieldDescriptor* field, BytesMode bytes_mode) {
+ std::string type =
+ JSFieldTypeAnnotation(options, field,
+ /* is_setter_argument = */ false,
+ /* force_present = */ false,
+ /* singular_if_not_packed = */ false, bytes_mode);
+ printer->Print(
+ "/**\n"
+ " * $fielddef$\n"
+ "$comment$"
+ " * This is a type-conversion wrapper around `get$defname$()`\n"
+ " * @return {$type$}\n"
+ " */\n"
+ "$class$.prototype.get$name$ = function() {\n"
+ " return /** @type {$type$} */ (jspb.Message.bytes$list$As$suffix$(\n"
+ " this.get$defname$()));\n"
+ "};\n"
+ "\n"
+ "\n",
+ "fielddef", FieldDefinition(options, field), "comment",
+ FieldComments(field, bytes_mode), "type", type, "class",
+ GetMessagePath(options, field->containing_type()), "name",
+ JSGetterName(options, field, bytes_mode), "list",
+ field->is_repeated() ? "List" : "", "suffix",
+ JSByteGetterSuffix(bytes_mode), "defname",
+ JSGetterName(options, field, BYTES_DEFAULT));
+}
+
+void Generator::GenerateClassField(const GeneratorOptions& options,
+ io::Printer* printer,
+ const FieldDescriptor* field) const {
+ if (field->is_map()) {
+ const FieldDescriptor* key_field = MapFieldKey(field);
+ const FieldDescriptor* value_field = MapFieldValue(field);
+ // Map field: special handling to instantiate the map object on demand.
+ std::string key_type =
+ JSFieldTypeAnnotation(options, key_field,
+ /* is_setter_argument = */ false,
+ /* force_present = */ true,
+ /* singular_if_not_packed = */ false);
+ std::string value_type =
+ JSFieldTypeAnnotation(options, value_field,
+ /* is_setter_argument = */ false,
+ /* force_present = */ true,
+ /* singular_if_not_packed = */ false);
+
+ printer->Print(
+ "/**\n"
+ " * $fielddef$\n"
+ " * @param {boolean=} opt_noLazyCreate Do not create the map if\n"
+ " * empty, instead returning `undefined`\n"
+ " * @return {!jspb.Map<$keytype$,$valuetype$>}\n"
+ " */\n",
+ "fielddef", FieldDefinition(options, field), "keytype", key_type,
+ "valuetype", value_type);
+ printer->Print(
+ "$class$.prototype.$gettername$ = function(opt_noLazyCreate) {\n"
+ " return /** @type {!jspb.Map<$keytype$,$valuetype$>} */ (\n",
+ "class", GetMessagePath(options, field->containing_type()),
+ "gettername", "get" + JSGetterName(options, field), "keytype", key_type,
+ "valuetype", value_type);
+ printer->Annotate("gettername", field);
+ printer->Print(
+ " jspb.Message.getMapField(this, $index$, opt_noLazyCreate",
+ "index", JSFieldIndex(field));
+
+ if (value_field->type() == FieldDescriptor::TYPE_MESSAGE) {
+ printer->Print(
+ ",\n"
+ " $messageType$",
+ "messageType", GetMessagePath(options, value_field->message_type()));
+ } else {
+ printer->Print(
+ ",\n"
+ " null");
+ }
+
+ printer->Print("));\n");
+
+ printer->Print(
+ "};\n"
+ "\n"
+ "\n");
+ } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+ // Message field: special handling in order to wrap the underlying data
+ // array with a message object.
+
+ printer->Print(
+ "/**\n"
+ " * $fielddef$\n"
+ "$comment$"
+ " * @return {$type$}\n"
+ " */\n",
+ "fielddef", FieldDefinition(options, field), "comment",
+ FieldComments(field, BYTES_DEFAULT), "type",
+ JSFieldTypeAnnotation(options, field,
+ /* is_setter_argument = */ false,
+ /* force_present = */ false,
+ /* singular_if_not_packed = */ false));
+ printer->Print(
+ "$class$.prototype.$gettername$ = function() {\n"
+ " return /** @type{$type$} */ (\n"
+ " jspb.Message.get$rpt$WrapperField(this, $wrapperclass$, "
+ "$index$$required$));\n"
+ "};\n"
+ "\n"
+ "\n",
+ "class", GetMessagePath(options, field->containing_type()),
+ "gettername", "get" + JSGetterName(options, field), "type",
+ JSFieldTypeAnnotation(options, field,
+ /* is_setter_argument = */ false,
+ /* force_present = */ false,
+ /* singular_if_not_packed = */ false),
+ "rpt", (field->is_repeated() ? "Repeated" : ""), "index",
+ JSFieldIndex(field), "wrapperclass", SubmessageTypeRef(options, field),
+ "required",
+ (field->label() == FieldDescriptor::LABEL_REQUIRED ? ", 1" : ""));
+ printer->Annotate("gettername", field);
+ printer->Print(
+ "/**\n"
+ " * @param {$optionaltype$} value\n"
+ " * @return {!$class$} returns this\n"
+ "*/\n"
+ "$class$.prototype.$settername$ = function(value) {\n"
+ " return jspb.Message.set$oneoftag$$repeatedtag$WrapperField(",
+ "optionaltype",
+ JSFieldTypeAnnotation(options, field,
+ /* is_setter_argument = */ true,
+ /* force_present = */ false,
+ /* singular_if_not_packed = */ false),
+ "class", GetMessagePath(options, field->containing_type()),
+ "settername", "set" + JSGetterName(options, field), "oneoftag",
+ (InRealOneof(field) ? "Oneof" : ""), "repeatedtag",
+ (field->is_repeated() ? "Repeated" : ""));
+ printer->Annotate("settername", field);
+
+ printer->Print(
+ "this, $index$$oneofgroup$, value);\n"
+ "};\n"
+ "\n"
+ "\n",
+ "index", JSFieldIndex(field), "oneofgroup",
+ (InRealOneof(field) ? (", " + JSOneofArray(options, field)) : ""));
+
+ if (field->is_repeated()) {
+ GenerateRepeatedMessageHelperMethods(options, printer, field);
+ }
+
+ } else {
+ bool untyped = false;
+
+ // Simple (primitive) field, either singular or repeated.
+
+ // TODO(b/26173701): Always use BYTES_DEFAULT for the getter return type;
+ // at this point we "lie" to non-binary users and tell the return
+ // type is always base64 string, pending a LSC to migrate to typed getters.
+ BytesMode bytes_mode =
+ field->type() == FieldDescriptor::TYPE_BYTES && !options.binary
+ ? BYTES_B64
+ : BYTES_DEFAULT;
+ std::string typed_annotation =
+ JSFieldTypeAnnotation(options, field,
+ /* is_setter_argument = */ false,
+ /* force_present = */ false,
+ /* singular_if_not_packed = */ false,
+ /* bytes_mode = */ bytes_mode);
+ if (untyped) {
+ printer->Print(
+ "/**\n"
+ " * @return {?} Raw field, untyped.\n"
+ " */\n");
+ } else {
+ printer->Print(
+ "/**\n"
+ " * $fielddef$\n"
+ "$comment$"
+ " * @return {$type$}\n"
+ " */\n",
+ "fielddef", FieldDefinition(options, field), "comment",
+ FieldComments(field, bytes_mode), "type", typed_annotation);
+ }
+
+ printer->Print("$class$.prototype.$gettername$ = function() {\n", "class",
+ GetMessagePath(options, field->containing_type()),
+ "gettername", "get" + JSGetterName(options, field));
+ printer->Annotate("gettername", field);
+
+ if (untyped) {
+ printer->Print(" return ");
+ } else {
+ printer->Print(" return /** @type {$type$} */ (", "type",
+ typed_annotation);
+ }
+
+ bool use_default = !ReturnsNullWhenUnset(options, field);
+
+ // Raw fields with no default set should just return undefined.
+ if (untyped && !field->has_default_value()) {
+ use_default = false;
+ }
+
+ // Repeated fields get initialized to their default in the constructor
+ // (why?), so we emit a plain getField() call for them.
+ if (field->is_repeated()) {
+ use_default = false;
+ }
+
+ GenerateFieldValueExpression(printer, "this", field, use_default);
+
+ if (untyped) {
+ printer->Print(
+ ";\n"
+ "};\n"
+ "\n"
+ "\n");
+ } else {
+ printer->Print(
+ ");\n"
+ "};\n"
+ "\n"
+ "\n");
+ }
+
+ if (field->type() == FieldDescriptor::TYPE_BYTES && !untyped) {
+ GenerateBytesWrapper(options, printer, field, BYTES_B64);
+ GenerateBytesWrapper(options, printer, field, BYTES_U8);
+ }
+
+ printer->Print(
+ "/**\n"
+ " * @param {$optionaltype$} value\n"
+ " * @return {!$class$} returns this\n"
+ " */\n",
+ "class", GetMessagePath(options, field->containing_type()),
+ "optionaltype",
+ untyped ? "*"
+ : JSFieldTypeAnnotation(options, field,
+ /* is_setter_argument = */ true,
+ /* force_present = */ false,
+ /* singular_if_not_packed = */ false));
+
+ if (field->file()->syntax() == FileDescriptor::SYNTAX_PROTO3 &&
+ !field->is_repeated() && !field->is_map() &&
+ !HasFieldPresence(options, field)) {
+ // Proto3 non-repeated and non-map fields without presence use the
+ // setProto3*Field function.
+ printer->Print(
+ "$class$.prototype.$settername$ = function(value) {\n"
+ " return jspb.Message.setProto3$typetag$Field(this, $index$, "
+ "value);"
+ "\n"
+ "};\n"
+ "\n"
+ "\n",
+ "class", GetMessagePath(options, field->containing_type()),
+ "settername", "set" + JSGetterName(options, field), "typetag",
+ JSTypeTag(field), "index", JSFieldIndex(field));
+ printer->Annotate("settername", field);
+ } else {
+ // Otherwise, use the regular setField function.
+ printer->Print(
+ "$class$.prototype.$settername$ = function(value) {\n"
+ " return jspb.Message.set$oneoftag$Field(this, $index$",
+ "class", GetMessagePath(options, field->containing_type()),
+ "settername", "set" + JSGetterName(options, field), "oneoftag",
+ (InRealOneof(field) ? "Oneof" : ""), "index", JSFieldIndex(field));
+ printer->Annotate("settername", field);
+ printer->Print(
+ "$oneofgroup$, $type$value$rptvalueinit$$typeclose$);\n"
+ "};\n"
+ "\n"
+ "\n",
+ "type",
+ untyped ? "/** @type{string|number|boolean|Array|undefined} */(" : "",
+ "typeclose", untyped ? ")" : "", "oneofgroup",
+ (InRealOneof(field) ? (", " + JSOneofArray(options, field)) : ""),
+ "rptvalueinit", (field->is_repeated() ? " || []" : ""));
+ }
+
+ if (untyped) {
+ printer->Print(
+ "/**\n"
+ " * Clears the value.\n"
+ " * @return {!$class$} returns this\n"
+ " */\n",
+ "class", GetMessagePath(options, field->containing_type()));
+ }
+
+ if (field->is_repeated()) {
+ GenerateRepeatedPrimitiveHelperMethods(options, printer, field, untyped);
+ }
+ }
+
+ // Generate clearFoo() method for map fields, repeated fields, and other
+ // fields with presence.
+ if (field->is_map()) {
+ // clang-format off
+ printer->Print(
+ "/**\n"
+ " * Clears values from the map. The map will be non-null.\n"
+ " * @return {!$class$} returns this\n"
+ " */\n"
+ "$class$.prototype.$clearername$ = function() {\n"
+ " this.$gettername$().clear();\n"
+ " return this;"
+ "};\n"
+ "\n"
+ "\n",
+ "class", GetMessagePath(options, field->containing_type()),
+ "clearername", "clear" + JSGetterName(options, field),
+ "gettername", "get" + JSGetterName(options, field));
+ // clang-format on
+ printer->Annotate("clearername", field);
+ } else if (field->is_repeated() ||
+ (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
+ !field->is_required())) {
+ // Fields where we can delegate to the regular setter.
+ // clang-format off
+ printer->Print(
+ "/**\n"
+ " * $jsdoc$\n"
+ " * @return {!$class$} returns this\n"
+ " */\n"
+ "$class$.prototype.$clearername$ = function() {\n"
+ " return this.$settername$($clearedvalue$);\n"
+ "};\n"
+ "\n"
+ "\n",
+ "jsdoc", field->is_repeated()
+ ? "Clears the list making it empty but non-null."
+ : "Clears the message field making it undefined.",
+ "class", GetMessagePath(options, field->containing_type()),
+ "clearername", "clear" + JSGetterName(options, field),
+ "settername", "set" + JSGetterName(options, field),
+ "clearedvalue", (field->is_repeated() ? "[]" : "undefined"));
+ // clang-format on
+ printer->Annotate("clearername", field);
+ } else if (HasFieldPresence(options, field)) {
+ // Fields where we can't delegate to the regular setter because it doesn't
+ // accept "undefined" as an argument.
+ // clang-format off
+ printer->Print(
+ "/**\n"
+ " * Clears the field making it undefined.\n"
+ " * @return {!$class$} returns this\n"
+ " */\n"
+ "$class$.prototype.$clearername$ = function() {\n"
+ " return jspb.Message.set$maybeoneof$Field(this, "
+ "$index$$maybeoneofgroup$, ",
+ "class", GetMessagePath(options, field->containing_type()),
+ "clearername", "clear" + JSGetterName(options, field),
+ "maybeoneof", (InRealOneof(field) ? "Oneof" : ""),
+ "maybeoneofgroup", (InRealOneof(field)
+ ? (", " + JSOneofArray(options, field))
+ : ""),
+ "index", JSFieldIndex(field));
+ // clang-format on
+ printer->Annotate("clearername", field);
+ printer->Print(
+ "$clearedvalue$);\n"
+ "};\n"
+ "\n"
+ "\n",
+ "clearedvalue", (field->is_repeated() ? "[]" : "undefined"));
+ }
+
+ if (HasFieldPresence(options, field)) {
+ printer->Print(
+ "/**\n"
+ " * Returns whether this field is set.\n"
+ " * @return {boolean}\n"
+ " */\n"
+ "$class$.prototype.$hasername$ = function() {\n"
+ " return jspb.Message.getField(this, $index$) != null;\n"
+ "};\n"
+ "\n"
+ "\n",
+ "class", GetMessagePath(options, field->containing_type()), "hasername",
+ "has" + JSGetterName(options, field), "index", JSFieldIndex(field));
+ printer->Annotate("hasername", field);
+ }
+}
+
+void Generator::GenerateRepeatedPrimitiveHelperMethods(
+ const GeneratorOptions& options, io::Printer* printer,
+ const FieldDescriptor* field, bool untyped) const {
+ // clang-format off
+ printer->Print(
+ "/**\n"
+ " * @param {$optionaltype$} value\n"
+ " * @param {number=} opt_index\n"
+ " * @return {!$class$} returns this\n"
+ " */\n"
+ "$class$.prototype.$addername$ = function(value, opt_index) {\n"
+ " return jspb.Message.addToRepeatedField(this, "
+ "$index$",
+ "class", GetMessagePath(options, field->containing_type()), "addername",
+ "add" + JSGetterName(options, field, BYTES_DEFAULT,
+ /* drop_list = */ true),
+ "optionaltype",
+ JSFieldTypeAnnotation(
+ options, field,
+ /* is_setter_argument = */ false,
+ /* force_present = */ true,
+ /* singular_if_not_packed = */ false,
+ BYTES_DEFAULT,
+ /* force_singular = */ true),
+ "index", JSFieldIndex(field));
+ printer->Annotate("addername", field);
+ printer->Print(
+ "$oneofgroup$, $type$value$rptvalueinit$$typeclose$, "
+ "opt_index);\n"
+ "};\n"
+ "\n"
+ "\n",
+ "type", untyped ? "/** @type{string|number|boolean|!Uint8Array} */(" : "",
+ "typeclose", untyped ? ")" : "", "oneofgroup",
+ (InRealOneof(field) ? (", " + JSOneofArray(options, field)) : ""),
+ "rptvalueinit", "");
+ // clang-format on
+}
+
+void Generator::GenerateRepeatedMessageHelperMethods(
+ const GeneratorOptions& options, io::Printer* printer,
+ const FieldDescriptor* field) const {
+ printer->Print(
+ "/**\n"
+ " * @param {!$optionaltype$=} opt_value\n"
+ " * @param {number=} opt_index\n"
+ " * @return {!$optionaltype$}\n"
+ " */\n"
+ "$class$.prototype.$addername$ = function(opt_value, opt_index) {\n"
+ " return jspb.Message.addTo$repeatedtag$WrapperField(",
+ "optionaltype", JSTypeName(options, field, BYTES_DEFAULT), "class",
+ GetMessagePath(options, field->containing_type()), "addername",
+ "add" + JSGetterName(options, field, BYTES_DEFAULT,
+ /* drop_list = */ true),
+ "repeatedtag", (field->is_repeated() ? "Repeated" : ""));
+
+ printer->Annotate("addername", field);
+ printer->Print(
+ "this, $index$$oneofgroup$, opt_value, $ctor$, opt_index);\n"
+ "};\n"
+ "\n"
+ "\n",
+ "index", JSFieldIndex(field), "oneofgroup",
+ (InRealOneof(field) ? (", " + JSOneofArray(options, field)) : ""), "ctor",
+ GetMessagePath(options, field->message_type()));
+}
+
+void Generator::GenerateClassExtensionFieldInfo(const GeneratorOptions& options,
+ io::Printer* printer,
+ const Descriptor* desc) const {
+ if (IsExtendable(desc)) {
+ printer->Print(
+ "\n"
+ "/**\n"
+ " * The extensions registered with this message class. This is a "
+ "map of\n"
+ " * extension field number to fieldInfo object.\n"
+ " *\n"
+ " * For example:\n"
+ " * { 123: {fieldIndex: 123, fieldName: {my_field_name: 0}, "
+ "ctor: proto.example.MyMessage} }\n"
+ " *\n"
+ " * fieldName contains the JsCompiler renamed field name property "
+ "so that it\n"
+ " * works in OPTIMIZED mode.\n"
+ " *\n"
+ " * @type {!Object<number, jspb.ExtensionFieldInfo>}\n"
+ " */\n"
+ "$class$.extensions = {};\n"
+ "\n",
+ "class", GetMessagePath(options, desc));
+
+ printer->Print(
+ "\n"
+ "/**\n"
+ " * The extensions registered with this message class. This is a "
+ "map of\n"
+ " * extension field number to fieldInfo object.\n"
+ " *\n"
+ " * For example:\n"
+ " * { 123: {fieldIndex: 123, fieldName: {my_field_name: 0}, "
+ "ctor: proto.example.MyMessage} }\n"
+ " *\n"
+ " * fieldName contains the JsCompiler renamed field name property "
+ "so that it\n"
+ " * works in OPTIMIZED mode.\n"
+ " *\n"
+ " * @type {!Object<number, jspb.ExtensionFieldBinaryInfo>}\n"
+ " */\n"
+ "$class$.extensionsBinary = {};\n"
+ "\n",
+ "class", GetMessagePath(options, desc));
+ }
+}
+
+void Generator::GenerateClassDeserializeBinary(const GeneratorOptions& options,
+ io::Printer* printer,
+ const Descriptor* desc) const {
+ // TODO(cfallin): Handle lazy decoding when requested by field option and/or
+ // by default for 'bytes' fields and packed repeated fields.
+
+ printer->Print(
+ "/**\n"
+ " * Deserializes binary data (in protobuf wire format).\n"
+ " * @param {jspb.ByteSource} bytes The bytes to deserialize.\n"
+ " * @return {!$class$}\n"
+ " */\n"
+ "$class$.deserializeBinary = function(bytes) {\n"
+ " var reader = new jspb.BinaryReader(bytes);\n"
+ " var msg = new $class$;\n"
+ " return $class$.deserializeBinaryFromReader(msg, reader);\n"
+ "};\n"
+ "\n"
+ "\n"
+ "/**\n"
+ " * Deserializes binary data (in protobuf wire format) from the\n"
+ " * given reader into the given message object.\n"
+ " * @param {!$class$} msg The message object to deserialize into.\n"
+ " * @param {!jspb.BinaryReader} reader The BinaryReader to use.\n"
+ " * @return {!$class$}\n"
+ " */\n"
+ "$class$.deserializeBinaryFromReader = function(msg, reader) {\n"
+ " while (reader.nextField()) {\n",
+ "class", GetMessagePath(options, desc));
+ printer->Print(
+ " if (reader.isEndGroup()) {\n"
+ " break;\n"
+ " }\n"
+ " var field = reader.getFieldNumber();\n"
+ " switch (field) {\n");
+
+ for (int i = 0; i < desc->field_count(); i++) {
+ if (!IgnoreField(desc->field(i))) {
+ GenerateClassDeserializeBinaryField(options, printer, desc->field(i));
+ }
+ }
+
+ printer->Print(" default:\n");
+ if (IsExtendable(desc)) {
+ printer->Print(
+ " jspb.Message.readBinaryExtension(msg, reader,\n"
+ " $extobj$Binary,\n"
+ " $class$.prototype.getExtension,\n"
+ " $class$.prototype.setExtension);\n"
+ " break;\n"
+ " }\n",
+ "extobj", JSExtensionsObjectName(options, desc->file(), desc), "class",
+ GetMessagePath(options, desc));
+ } else {
+ printer->Print(
+ " reader.skipField();\n"
+ " break;\n"
+ " }\n");
+ }
+
+ printer->Print(
+ " }\n"
+ " return msg;\n"
+ "};\n"
+ "\n"
+ "\n");
+}
+
+void Generator::GenerateClassDeserializeBinaryField(
+ const GeneratorOptions& options, io::Printer* printer,
+ const FieldDescriptor* field) const {
+ printer->Print(" case $num$:\n", "num", StrCat(field->number()));
+
+ if (field->is_map()) {
+ const FieldDescriptor* key_field = MapFieldKey(field);
+ const FieldDescriptor* value_field = MapFieldValue(field);
+ printer->Print(
+ " var value = msg.get$name$();\n"
+ " reader.readMessage(value, function(message, reader) {\n",
+ "name", JSGetterName(options, field));
+
+ printer->Print(
+ " jspb.Map.deserializeBinary(message, reader, "
+ "$keyReaderFn$, $valueReaderFn$",
+ "keyReaderFn", JSBinaryReaderMethodName(options, key_field),
+ "valueReaderFn", JSBinaryReaderMethodName(options, value_field));
+
+ if (value_field->type() == FieldDescriptor::TYPE_MESSAGE) {
+ printer->Print(", $messageType$.deserializeBinaryFromReader",
+ "messageType",
+ GetMessagePath(options, value_field->message_type()));
+ } else {
+ printer->Print(", null");
+ }
+ printer->Print(", $defaultKey$", "defaultKey", JSFieldDefault(key_field));
+ if (value_field->type() == FieldDescriptor::TYPE_MESSAGE) {
+ printer->Print(", new $messageType$()", "messageType",
+ GetMessagePath(options, value_field->message_type()));
+ } else {
+ printer->Print(", $defaultValue$", "defaultValue",
+ JSFieldDefault(value_field));
+ }
+ printer->Print(");\n");
+ printer->Print(" });\n");
+ } else {
+ if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+ printer->Print(
+ " var value = new $fieldclass$;\n"
+ " reader.read$msgOrGroup$($grpfield$value,"
+ "$fieldclass$.deserializeBinaryFromReader);\n",
+ "fieldclass", SubmessageTypeRef(options, field), "msgOrGroup",
+ (field->type() == FieldDescriptor::TYPE_GROUP) ? "Group" : "Message",
+ "grpfield",
+ (field->type() == FieldDescriptor::TYPE_GROUP)
+ ? (StrCat(field->number()) + ", ")
+ : "");
+ } else if (field->is_packable()) {
+ printer->Print(
+ " var values = /** @type {$fieldtype$} */ "
+ "(reader.isDelimited() "
+ "? reader.readPacked$reader$() : [reader.read$reader$()]);\n",
+ "fieldtype",
+ JSFieldTypeAnnotation(options, field, false, true,
+ /* singular_if_not_packed */ false, BYTES_U8),
+ "reader", JSBinaryReaderMethodType(field));
+ } else {
+ printer->Print(
+ " var value = /** @type {$fieldtype$} */ "
+ "(reader.read$reader$());\n",
+ "fieldtype",
+ JSFieldTypeAnnotation(options, field, false, true,
+ /* singular_if_not_packed */ true, BYTES_U8),
+ "reader",
+ JSBinaryReadWriteMethodName(field, /* is_writer = */ false));
+ }
+
+ if (field->is_packable()) {
+ printer->Print(
+ " for (var i = 0; i < values.length; i++) {\n"
+ " msg.add$name$(values[i]);\n"
+ " }\n",
+ "name",
+ JSGetterName(options, field, BYTES_DEFAULT, /* drop_list = */ true));
+ } else if (field->is_repeated()) {
+ printer->Print(
+ " msg.add$name$(value);\n", "name",
+ JSGetterName(options, field, BYTES_DEFAULT, /* drop_list = */ true));
+ } else {
+ // Singular fields, and packed repeated fields, receive a |value| either
+ // as the field's value or as the array of all the field's values; set
+ // this as the field's value directly.
+ printer->Print(" msg.set$name$(value);\n", "name",
+ JSGetterName(options, field));
+ }
+ }
+
+ printer->Print(" break;\n");
+}
+
+void Generator::GenerateClassSerializeBinary(const GeneratorOptions& options,
+ io::Printer* printer,
+ const Descriptor* desc) const {
+ printer->Print(
+ "/**\n"
+ " * Serializes the message to binary data (in protobuf wire format).\n"
+ " * @return {!Uint8Array}\n"
+ " */\n"
+ "$class$.prototype.serializeBinary = function() {\n"
+ " var writer = new jspb.BinaryWriter();\n"
+ " $class$.serializeBinaryToWriter(this, writer);\n"
+ " return writer.getResultBuffer();\n"
+ "};\n"
+ "\n"
+ "\n"
+ "/**\n"
+ " * Serializes the given message to binary data (in protobuf wire\n"
+ " * format), writing to the given BinaryWriter.\n"
+ " * @param {!$class$} message\n"
+ " * @param {!jspb.BinaryWriter} writer\n"
+ " * @suppress {unusedLocalVariables} f is only used for nested messages\n"
+ " */\n"
+ "$class$.serializeBinaryToWriter = function(message, "
+ "writer) {\n"
+ " var f = undefined;\n",
+ "class", GetMessagePath(options, desc));
+
+ for (int i = 0; i < desc->field_count(); i++) {
+ if (!IgnoreField(desc->field(i))) {
+ GenerateClassSerializeBinaryField(options, printer, desc->field(i));
+ }
+ }
+
+ if (IsExtendable(desc)) {
+ printer->Print(
+ " jspb.Message.serializeBinaryExtensions(message, writer,\n"
+ " $extobj$Binary, $class$.prototype.getExtension);\n",
+ "extobj", JSExtensionsObjectName(options, desc->file(), desc), "class",
+ GetMessagePath(options, desc));
+ }
+
+ printer->Print(
+ "};\n"
+ "\n"
+ "\n");
+}
+
+void Generator::GenerateClassSerializeBinaryField(
+ const GeneratorOptions& options, io::Printer* printer,
+ const FieldDescriptor* field) const {
+ if (HasFieldPresence(options, field) &&
+ field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) {
+ std::string typed_annotation =
+ JSFieldTypeAnnotation(options, field,
+ /* is_setter_argument = */ false,
+ /* force_present = */ false,
+ /* singular_if_not_packed = */ false,
+ /* bytes_mode = */ BYTES_DEFAULT);
+ printer->Print(
+ " f = /** @type {$type$} */ "
+ "(jspb.Message.getField(message, $index$));\n",
+ "index", JSFieldIndex(field), "type", typed_annotation);
+ } else {
+ printer->Print(
+ " f = message.get$name$($nolazy$);\n", "name",
+ JSGetterName(options, field, BYTES_U8),
+ // No lazy creation for maps containers -- fastpath the empty case.
+ "nolazy", field->is_map() ? "true" : "");
+ }
+
+ // Print an `if (condition)` statement that evaluates to true if the field
+ // goes on the wire.
+ if (field->is_map()) {
+ printer->Print(" if (f && f.getLength() > 0) {\n");
+ } else if (field->is_repeated()) {
+ printer->Print(" if (f.length > 0) {\n");
+ } else {
+ if (HasFieldPresence(options, field)) {
+ printer->Print(" if (f != null) {\n");
+ } else {
+ // No field presence: serialize onto the wire only if value is
+ // non-default. Defaults are documented here:
+ // https://goto.google.com/lhdfm
+ switch (field->cpp_type()) {
+ case FieldDescriptor::CPPTYPE_INT32:
+ case FieldDescriptor::CPPTYPE_INT64:
+ case FieldDescriptor::CPPTYPE_UINT32:
+ case FieldDescriptor::CPPTYPE_UINT64: {
+ if (IsIntegralFieldWithStringJSType(field)) {
+ // We can use `parseInt` here even though it will not be precise for
+ // 64-bit quantities because we are only testing for zero/nonzero,
+ // and JS numbers (64-bit floating point values, i.e., doubles) are
+ // integer-precise in the range that includes zero.
+ printer->Print(" if (parseInt(f, 10) !== 0) {\n");
+ } else {
+ printer->Print(" if (f !== 0) {\n");
+ }
+ break;
+ }
+
+ case FieldDescriptor::CPPTYPE_ENUM:
+ case FieldDescriptor::CPPTYPE_FLOAT:
+ case FieldDescriptor::CPPTYPE_DOUBLE:
+ printer->Print(" if (f !== 0.0) {\n");
+ break;
+ case FieldDescriptor::CPPTYPE_BOOL:
+ printer->Print(" if (f) {\n");
+ break;
+ case FieldDescriptor::CPPTYPE_STRING:
+ printer->Print(" if (f.length > 0) {\n");
+ break;
+ default:
+ assert(false);
+ break;
+ }
+ }
+ }
+
+ // Write the field on the wire.
+ if (field->is_map()) {
+ const FieldDescriptor* key_field = MapFieldKey(field);
+ const FieldDescriptor* value_field = MapFieldValue(field);
+ printer->Print(
+ " f.serializeBinary($index$, writer, "
+ "$keyWriterFn$, $valueWriterFn$",
+ "index", StrCat(field->number()), "keyWriterFn",
+ JSBinaryWriterMethodName(options, key_field), "valueWriterFn",
+ JSBinaryWriterMethodName(options, value_field));
+
+ if (value_field->type() == FieldDescriptor::TYPE_MESSAGE) {
+ printer->Print(", $messageType$.serializeBinaryToWriter", "messageType",
+ GetMessagePath(options, value_field->message_type()));
+ }
+
+ printer->Print(");\n");
+ } else {
+ printer->Print(
+ " writer.write$method$(\n"
+ " $index$,\n"
+ " f",
+ "method", JSBinaryReadWriteMethodName(field, /* is_writer = */ true),
+ "index", StrCat(field->number()));
+
+ if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
+ !field->is_map()) {
+ printer->Print(
+ ",\n"
+ " $submsg$.serializeBinaryToWriter\n",
+ "submsg", SubmessageTypeRef(options, field));
+ } else {
+ printer->Print("\n");
+ }
+
+ printer->Print(" );\n");
+ }
+
+ // Close the `if`.
+ printer->Print(" }\n");
+}
+
+void Generator::GenerateEnum(const GeneratorOptions& options,
+ io::Printer* printer,
+ const EnumDescriptor* enumdesc) const {
+ printer->Print(
+ "/**\n"
+ " * @enum {number}\n"
+ " */\n"
+ "$enumprefix$$name$ = {\n",
+ "enumprefix", GetEnumPathPrefix(options, enumdesc), "name",
+ enumdesc->name());
+ printer->Annotate("name", enumdesc);
+
+ std::set<std::string> used_name;
+ std::vector<int> valid_index;
+ for (int i = 0; i < enumdesc->value_count(); i++) {
+ if (enumdesc->options().allow_alias() &&
+ !used_name.insert(ToEnumCase(enumdesc->value(i)->name())).second) {
+ continue;
+ }
+ valid_index.push_back(i);
+ }
+ for (auto i : valid_index) {
+ const EnumValueDescriptor* value = enumdesc->value(i);
+ printer->Print(" $name$: $value$$comma$\n", "name",
+ ToEnumCase(value->name()), "value", StrCat(value->number()),
+ "comma", (i == valid_index.back()) ? "" : ",");
+ printer->Annotate("name", value);
+ }
+
+ printer->Print(
+ "};\n"
+ "\n");
+}
+
+void Generator::GenerateExtension(const GeneratorOptions& options,
+ io::Printer* printer,
+ const FieldDescriptor* field) const {
+ std::string extension_scope =
+ (field->extension_scope()
+ ? GetMessagePath(options, field->extension_scope())
+ : GetNamespace(options, field->file()));
+
+ const std::string extension_object_name = JSObjectFieldName(options, field);
+ printer->Print(
+ "\n"
+ "/**\n"
+ " * A tuple of {field number, class constructor} for the extension\n"
+ " * field named `$nameInComment$`.\n"
+ " * @type {!jspb.ExtensionFieldInfo<$extensionType$>}\n"
+ " */\n"
+ "$class$.$name$ = new jspb.ExtensionFieldInfo(\n",
+ "nameInComment", extension_object_name, "name", extension_object_name,
+ "class", extension_scope, "extensionType",
+ JSFieldTypeAnnotation(options, field,
+ /* is_setter_argument = */ false,
+ /* force_present = */ true,
+ /* singular_if_not_packed = */ false));
+ printer->Annotate("name", field);
+ printer->Print(
+ " $index$,\n"
+ " {$name$: 0},\n"
+ " $ctor$,\n"
+ " /** @type {?function((boolean|undefined),!jspb.Message=): "
+ "!Object} */ (\n"
+ " $toObject$),\n"
+ " $repeated$);\n",
+ "index", StrCat(field->number()), "name", extension_object_name, "ctor",
+ (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE
+ ? SubmessageTypeRef(options, field)
+ : std::string("null")),
+ "toObject",
+ (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE
+ ? (SubmessageTypeRef(options, field) + ".toObject")
+ : std::string("null")),
+ "repeated", (field->is_repeated() ? "1" : "0"));
+
+ printer->Print(
+ "\n"
+ "$extendName$Binary[$index$] = new jspb.ExtensionFieldBinaryInfo(\n"
+ " $class$.$name$,\n"
+ " $binaryReaderFn$,\n"
+ " $binaryWriterFn$,\n"
+ " $binaryMessageSerializeFn$,\n"
+ " $binaryMessageDeserializeFn$,\n",
+ "extendName",
+ JSExtensionsObjectName(options, field->file(), field->containing_type()),
+ "index", StrCat(field->number()), "class", extension_scope, "name",
+ extension_object_name, "binaryReaderFn",
+ JSBinaryReaderMethodName(options, field), "binaryWriterFn",
+ JSBinaryWriterMethodName(options, field), "binaryMessageSerializeFn",
+ (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE)
+ ? (SubmessageTypeRef(options, field) + ".serializeBinaryToWriter")
+ : "undefined",
+ "binaryMessageDeserializeFn",
+ (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE)
+ ? (SubmessageTypeRef(options, field) + ".deserializeBinaryFromReader")
+ : "undefined");
+
+ printer->Print(" $isPacked$);\n", "isPacked",
+ (field->is_packed() ? "true" : "false"));
+
+ printer->Print(
+ "// This registers the extension field with the extended class, so that\n"
+ "// toObject() will function correctly.\n"
+ "$extendName$[$index$] = $class$.$name$;\n"
+ "\n",
+ "extendName",
+ JSExtensionsObjectName(options, field->file(), field->containing_type()),
+ "index", StrCat(field->number()), "class", extension_scope, "name",
+ extension_object_name);
+}
+
+bool GeneratorOptions::ParseFromOptions(
+ const std::vector<std::pair<std::string, std::string> >& options,
+ std::string* error) {
+ for (int i = 0; i < options.size(); i++) {
+ if (options[i].first == "add_require_for_enums") {
+ if (options[i].second != "") {
+ *error = "Unexpected option value for add_require_for_enums";
+ return false;
+ }
+ add_require_for_enums = true;
+ } else if (options[i].first == "binary") {
+ if (options[i].second != "") {
+ *error = "Unexpected option value for binary";
+ return false;
+ }
+ binary = true;
+ } else if (options[i].first == "testonly") {
+ if (options[i].second != "") {
+ *error = "Unexpected option value for testonly";
+ return false;
+ }
+ testonly = true;
+
+ } else if (options[i].first == "error_on_name_conflict") {
+ GOOGLE_LOG(WARNING) << "Ignoring error_on_name_conflict option, this "
+ "will be removed in a future release";
+ } else if (options[i].first == "output_dir") {
+ output_dir = options[i].second;
+ } else if (options[i].first == "namespace_prefix") {
+ namespace_prefix = options[i].second;
+ } else if (options[i].first == "library") {
+ library = options[i].second;
+ } else if (options[i].first == "import_style") {
+ if (options[i].second == "closure") {
+ import_style = kImportClosure;
+ } else if (options[i].second == "commonjs") {
+ import_style = kImportCommonJs;
+ } else if (options[i].second == "commonjs_strict") {
+ import_style = kImportCommonJsStrict;
+ } else if (options[i].second == "browser") {
+ import_style = kImportBrowser;
+ } else if (options[i].second == "es6") {
+ import_style = kImportEs6;
+ } else {
+ *error = "Unknown import style " + options[i].second + ", expected " +
+ "one of: closure, commonjs, browser, es6.";
+ }
+ } else if (options[i].first == "extension") {
+ extension = options[i].second;
+ } else if (options[i].first == "one_output_file_per_input_file") {
+ if (!options[i].second.empty()) {
+ *error = "Unexpected option value for one_output_file_per_input_file";
+ return false;
+ }
+ one_output_file_per_input_file = true;
+ } else if (options[i].first == "annotate_code") {
+ if (!options[i].second.empty()) {
+ *error = "Unexpected option value for annotate_code";
+ return false;
+ }
+ annotate_code = true;
+ } else {
+ // Assume any other option is an output directory, as long as it is a bare
+ // `key` rather than a `key=value` option.
+ if (options[i].second != "") {
+ *error = "Unknown option: " + options[i].first;
+ return false;
+ }
+ output_dir = options[i].first;
+ }
+ }
+
+ if (import_style != kImportClosure &&
+ (add_require_for_enums || testonly || !library.empty() ||
+ extension != ".js" || one_output_file_per_input_file)) {
+ *error =
+ "The add_require_for_enums, testonly, library, extension, and "
+ "one_output_file_per_input_file options should only be "
+ "used for import_style=closure";
+ return false;
+ }
+
+ return true;
+}
+
+GeneratorOptions::OutputMode GeneratorOptions::output_mode() const {
+ // We use one output file per input file if we are not using Closure or if
+ // this is explicitly requested.
+ if (import_style != kImportClosure || one_output_file_per_input_file) {
+ return kOneOutputFilePerInputFile;
+ }
+
+ // If a library name is provided, we put everything in that one file.
+ if (!library.empty()) {
+ return kEverythingInOneFile;
+ }
+
+ // Otherwise, we create one output file per SCC.
+ return kOneOutputFilePerSCC;
+}
+
+void Generator::GenerateFilesInDepOrder(
+ const GeneratorOptions& options, io::Printer* printer,
+ const std::vector<const FileDescriptor*>& files) const {
+ // Build a std::set over all files so that the DFS can detect when it recurses
+ // into a dep not specified in the user's command line.
+ std::set<const FileDescriptor*> all_files(files.begin(), files.end());
+ // Track the in-progress set of files that have been generated already.
+ std::set<const FileDescriptor*> generated;
+ for (int i = 0; i < files.size(); i++) {
+ GenerateFileAndDeps(options, printer, files[i], &all_files, &generated);
+ }
+}
+
+void Generator::GenerateFileAndDeps(
+ const GeneratorOptions& options, io::Printer* printer,
+ const FileDescriptor* root, std::set<const FileDescriptor*>* all_files,
+ std::set<const FileDescriptor*>* generated) const {
+ // Skip if already generated.
+ if (generated->find(root) != generated->end()) {
+ return;
+ }
+ generated->insert(root);
+
+ // Generate all dependencies before this file's content.
+ for (int i = 0; i < root->dependency_count(); i++) {
+ const FileDescriptor* dep = root->dependency(i);
+ GenerateFileAndDeps(options, printer, dep, all_files, generated);
+ }
+
+ // Generate this file's content. Only generate if the file is part of the
+ // original set requested to be generated; i.e., don't take all transitive
+ // deps down to the roots.
+ if (all_files->find(root) != all_files->end()) {
+ GenerateClassesAndEnums(options, printer, root);
+ }
+}
+
+bool Generator::GenerateFile(const FileDescriptor* file,
+ const GeneratorOptions& options,
+ GeneratorContext* context,
+ bool use_short_name) const {
+ std::string filename =
+ options.output_dir + "/" +
+ GetJSFilename(options, use_short_name
+ ? file->name().substr(file->name().rfind('/'))
+ : file->name());
+ std::unique_ptr<io::ZeroCopyOutputStream> output(context->Open(filename));
+ GOOGLE_CHECK(output);
+ GeneratedCodeInfo annotations;
+ io::AnnotationProtoCollector<GeneratedCodeInfo> annotation_collector(
+ &annotations);
+ io::Printer printer(output.get(), '$',
+ options.annotate_code ? &annotation_collector : nullptr);
+
+ GenerateFile(options, &printer, file);
+
+ if (printer.failed()) {
+ return false;
+ }
+
+ if (options.annotate_code) {
+ EmbedCodeAnnotations(annotations, &printer);
+ }
+
+ return true;
+}
+
+void Generator::GenerateFile(const GeneratorOptions& options,
+ io::Printer* printer,
+ const FileDescriptor* file) const {
+ GenerateHeader(options, file, printer);
+
+ // Generate "require" statements.
+ if ((options.import_style == GeneratorOptions::kImportCommonJs ||
+ options.import_style == GeneratorOptions::kImportCommonJsStrict)) {
+ printer->Print("var jspb = require('google-protobuf');\n");
+ printer->Print("var goog = jspb;\n");
+
+ // Do not use global scope in strict mode
+ if (options.import_style == GeneratorOptions::kImportCommonJsStrict) {
+ printer->Print("var proto = {};\n\n");
+ } else {
+ // To get the global object we call a function with .call(null), this will set "this" inside the
+ // function to the global object.
+ // This does not work if we are running in strict mode ("use strict"),
+ // so we fallback to the following things (in order from first to last):
+ // - window: defined in browsers
+ // - global: defined in most server side environments like NodeJS
+ // - self: defined inside Web Workers (WorkerGlobalScope)
+ // - Function('return this')(): this will work on most platforms, but it may be blocked by things like CSP.
+ // Function('') is almost the same as eval('')
+ printer->Print(
+ "var global = (function() {\n"
+ " if (this) { return this; }\n"
+ " if (typeof window !== 'undefined') { return window; }\n"
+ " if (typeof global !== 'undefined') { return global; }\n"
+ " if (typeof self !== 'undefined') { return self; }\n"
+ " return Function('return this')();\n"
+ "}.call(null));\n\n");
+ }
+
+ for (int i = 0; i < file->dependency_count(); i++) {
+ const std::string& name = file->dependency(i)->name();
+ printer->Print(
+ "var $alias$ = require('$file$');\n"
+ "goog.object.extend(proto, $alias$);\n",
+ "alias", ModuleAlias(name), "file",
+ GetRootPath(file->name(), name) + GetJSFilename(options, name));
+ }
+ }
+
+ std::set<std::string> provided;
+ std::set<const FieldDescriptor*> extensions;
+ for (int i = 0; i < file->extension_count(); i++) {
+ // We honor the jspb::ignore option here only when working with
+ // Closure-style imports. Use of this option is discouraged and so we want
+ // to avoid adding new support for it.
+ if (options.import_style == GeneratorOptions::kImportClosure &&
+ IgnoreField(file->extension(i))) {
+ continue;
+ }
+ provided.insert(GetNamespace(options, file) + "." +
+ JSObjectFieldName(options, file->extension(i)));
+ extensions.insert(file->extension(i));
+ }
+
+ FindProvidesForFile(options, printer, file, &provided);
+ GenerateProvides(options, printer, &provided);
+ std::vector<const FileDescriptor*> files;
+ files.push_back(file);
+ if (options.import_style == GeneratorOptions::kImportClosure) {
+ GenerateRequiresForLibrary(options, printer, files, &provided);
+ }
+
+ GenerateClassesAndEnums(options, printer, file);
+
+ // Generate code for top-level extensions. Extensions nested inside messages
+ // are emitted inside GenerateClassesAndEnums().
+ for (std::set<const FieldDescriptor*>::const_iterator it = extensions.begin();
+ it != extensions.end(); ++it) {
+ GenerateExtension(options, printer, *it);
+ }
+
+ // if provided is empty, do not export anything
+ if (options.import_style == GeneratorOptions::kImportCommonJs &&
+ !provided.empty()) {
+ printer->Print("goog.object.extend(exports, $package$);\n", "package",
+ GetNamespace(options, file));
+ } else if (options.import_style == GeneratorOptions::kImportCommonJsStrict) {
+ printer->Print("goog.object.extend(exports, proto);\n", "package",
+ GetNamespace(options, file));
+ }
+
+ // Emit well-known type methods.
+ for (FileToc* toc = well_known_types_js; toc->name != NULL; toc++) {
+ std::string name = std::string("google/protobuf/") + toc->name;
+ if (name == StripProto(file->name()) + ".js") {
+ printer->Print(toc->data);
+ }
+ }
+}
+
+bool Generator::GenerateAll(const std::vector<const FileDescriptor*>& files,
+ const std::string& parameter,
+ GeneratorContext* context,
+ std::string* error) const {
+ std::vector<std::pair<std::string, std::string> > option_pairs;
+ ParseGeneratorParameter(parameter, &option_pairs);
+ GeneratorOptions options;
+ if (!options.ParseFromOptions(option_pairs, error)) {
+ return false;
+ }
+
+ if (options.output_mode() == GeneratorOptions::kEverythingInOneFile) {
+ // All output should go in a single file.
+ std::string filename = options.output_dir + "/" + options.library +
+ options.GetFileNameExtension();
+ std::unique_ptr<io::ZeroCopyOutputStream> output(context->Open(filename));
+ GOOGLE_CHECK(output.get());
+ GeneratedCodeInfo annotations;
+ io::AnnotationProtoCollector<GeneratedCodeInfo> annotation_collector(
+ &annotations);
+ io::Printer printer(
+ output.get(), '$',
+ options.annotate_code ? &annotation_collector : nullptr);
+
+ // Pull out all extensions -- we need these to generate all
+ // provides/requires.
+ std::vector<const FieldDescriptor*> extensions;
+ for (int i = 0; i < files.size(); i++) {
+ for (int j = 0; j < files[i]->extension_count(); j++) {
+ const FieldDescriptor* extension = files[i]->extension(j);
+ extensions.push_back(extension);
+ }
+ }
+
+ if (files.size() == 1) {
+ GenerateHeader(options, files[0], &printer);
+ } else {
+ GenerateHeader(options, nullptr, &printer);
+ }
+
+ std::set<std::string> provided;
+ FindProvides(options, &printer, files, &provided);
+ FindProvidesForFields(options, &printer, extensions, &provided);
+ GenerateProvides(options, &printer, &provided);
+ GenerateTestOnly(options, &printer);
+ GenerateRequiresForLibrary(options, &printer, files, &provided);
+
+ GenerateFilesInDepOrder(options, &printer, files);
+
+ for (int i = 0; i < extensions.size(); i++) {
+ if (ShouldGenerateExtension(extensions[i])) {
+ GenerateExtension(options, &printer, extensions[i]);
+ }
+ }
+
+ if (printer.failed()) {
+ return false;
+ }
+ if (options.annotate_code) {
+ EmbedCodeAnnotations(annotations, &printer);
+ }
+ } else if (options.output_mode() == GeneratorOptions::kOneOutputFilePerSCC) {
+ std::set<const Descriptor*> have_printed;
+ SCCAnalyzer<DepsGenerator> analyzer;
+ std::map<const void*, std::string> allowed_map;
+ if (!GenerateJspbAllowedMap(options, files, &allowed_map, &analyzer)) {
+ return false;
+ }
+
+ bool generated = false;
+ for (int i = 0; i < files.size(); i++) {
+ const FileDescriptor* file = files[i];
+ // Force well known type to generate in a whole file.
+ if (IsWellKnownTypeFile(file)) {
+ if (!GenerateFile(file, options, context, true)) {
+ return false;
+ }
+ generated = true;
+ continue;
+ }
+ for (int j = 0; j < file->message_type_count(); j++) {
+ const Descriptor* desc = file->message_type(j);
+ if (have_printed.count(desc) ||
+ allowed_map.count(analyzer.GetSCC(desc)) == 0) {
+ continue;
+ }
+
+ generated = true;
+ const SCC* scc = analyzer.GetSCC(desc);
+ const std::string& filename = allowed_map[scc];
+ std::unique_ptr<io::ZeroCopyOutputStream> output(
+ context->Open(filename));
+ GOOGLE_CHECK(output.get());
+ GeneratedCodeInfo annotations;
+ io::AnnotationProtoCollector<GeneratedCodeInfo> annotation_collector(
+ &annotations);
+ io::Printer printer(
+ output.get(), '$',
+ options.annotate_code ? &annotation_collector : nullptr);
+
+ GenerateHeader(options, file, &printer);
+
+ std::set<std::string> provided;
+ for (auto one_desc : scc->descriptors) {
+ if (one_desc->containing_type() == nullptr) {
+ FindProvidesForMessage(options, &printer, one_desc, &provided);
+ }
+ }
+ GenerateProvides(options, &printer, &provided);
+ GenerateTestOnly(options, &printer);
+ GenerateRequiresForSCC(options, &printer, scc, &provided);
+
+ for (auto one_desc : scc->descriptors) {
+ if (one_desc->containing_type() == nullptr) {
+ GenerateClassConstructorAndDeclareExtensionFieldInfo(
+ options, &printer, one_desc);
+ }
+ }
+ for (auto one_desc : scc->descriptors) {
+ if (one_desc->containing_type() == nullptr) {
+ GenerateClass(options, &printer, one_desc);
+ }
+ }
+
+ for (auto one_desc : scc->descriptors) {
+ have_printed.insert(one_desc);
+ }
+
+ if (printer.failed()) {
+ return false;
+ }
+ if (options.annotate_code) {
+ EmbedCodeAnnotations(annotations, &printer);
+ }
+ }
+ for (int j = 0; j < file->enum_type_count(); j++) {
+ const EnumDescriptor* enumdesc = file->enum_type(j);
+ if (allowed_map.count(enumdesc) == 0) {
+ continue;
+ }
+
+ generated = true;
+ const std::string& filename = allowed_map[enumdesc];
+ std::unique_ptr<io::ZeroCopyOutputStream> output(
+ context->Open(filename));
+ GOOGLE_CHECK(output.get());
+ GeneratedCodeInfo annotations;
+ io::AnnotationProtoCollector<GeneratedCodeInfo> annotation_collector(
+ &annotations);
+ io::Printer printer(
+ output.get(), '$',
+ options.annotate_code ? &annotation_collector : nullptr);
+
+ GenerateHeader(options, file, &printer);
+
+ std::set<std::string> provided;
+ FindProvidesForEnum(options, &printer, enumdesc, &provided);
+ GenerateProvides(options, &printer, &provided);
+ GenerateTestOnly(options, &printer);
+
+ GenerateEnum(options, &printer, enumdesc);
+
+ if (printer.failed()) {
+ return false;
+ }
+ if (options.annotate_code) {
+ EmbedCodeAnnotations(annotations, &printer);
+ }
+ }
+ // File-level extensions (message-level extensions are generated under
+ // the enclosing message).
+ if (allowed_map.count(file) == 1) {
+ generated = true;
+ const std::string& filename = allowed_map[file];
+
+ std::unique_ptr<io::ZeroCopyOutputStream> output(
+ context->Open(filename));
+ GOOGLE_CHECK(output.get());
+ GeneratedCodeInfo annotations;
+ io::AnnotationProtoCollector<GeneratedCodeInfo> annotation_collector(
+ &annotations);
+ io::Printer printer(
+ output.get(), '$',
+ options.annotate_code ? &annotation_collector : nullptr);
+
+ GenerateHeader(options, file, &printer);
+
+ std::set<std::string> provided;
+ std::vector<const FieldDescriptor*> fields;
+
+ for (int j = 0; j < files[i]->extension_count(); j++) {
+ if (ShouldGenerateExtension(files[i]->extension(j))) {
+ fields.push_back(files[i]->extension(j));
+ }
+ }
+
+ FindProvidesForFields(options, &printer, fields, &provided);
+ GenerateProvides(options, &printer, &provided);
+ GenerateTestOnly(options, &printer);
+ GenerateRequiresForExtensions(options, &printer, fields, &provided);
+
+ for (int j = 0; j < files[i]->extension_count(); j++) {
+ if (ShouldGenerateExtension(files[i]->extension(j))) {
+ GenerateExtension(options, &printer, files[i]->extension(j));
+ }
+ }
+ if (options.annotate_code) {
+ EmbedCodeAnnotations(annotations, &printer);
+ }
+ }
+ }
+ if (!generated) {
+ std::string filename = options.output_dir + "/" +
+ "empty_no_content_void_file" +
+ options.GetFileNameExtension();
+ std::unique_ptr<io::ZeroCopyOutputStream> output(context->Open(filename));
+ }
+ } else /* options.output_mode() == kOneOutputFilePerInputFile */ {
+ // Generate one output file per input (.proto) file.
+
+ for (int i = 0; i < files.size(); i++) {
+ const FileDescriptor* file = files[i];
+ if (!GenerateFile(file, options, context, false)) {
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
+} // namespace js
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/js/js_generator.h b/NorthstarDedicatedTest/include/protobuf/compiler/js/js_generator.h
new file mode 100644
index 00000000..b01b15e8
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/js/js_generator.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.
+
+// Generates JavaScript code for a given .proto file.
+//
+#ifndef GOOGLE_PROTOBUF_COMPILER_JS_GENERATOR_H__
+#define GOOGLE_PROTOBUF_COMPILER_JS_GENERATOR_H__
+
+#include <set>
+#include <string>
+
+#include <stubs/logging.h>
+#include <stubs/common.h>
+#include <compiler/scc.h>
+#include <compiler/code_generator.h>
+
+#include <port_def.inc>
+
+namespace google {
+namespace protobuf {
+
+class Descriptor;
+class EnumDescriptor;
+class FieldDescriptor;
+class OneofDescriptor;
+class FileDescriptor;
+
+namespace io {
+class Printer;
+}
+
+namespace compiler {
+namespace js {
+
+struct GeneratorOptions {
+ // Output path.
+ std::string output_dir;
+ // Namespace prefix.
+ std::string namespace_prefix;
+ // Enable binary-format support?
+ bool binary;
+ // What style of imports should be used.
+ enum ImportStyle {
+ kImportClosure, // goog.require()
+ kImportCommonJs, // require()
+ kImportCommonJsStrict, // require() with no global export
+ kImportBrowser, // no import statements
+ kImportEs6, // import { member } from ''
+ } import_style;
+
+ GeneratorOptions()
+ : output_dir("."),
+ namespace_prefix(""),
+ binary(false),
+ import_style(kImportClosure),
+ add_require_for_enums(false),
+ testonly(false),
+ library(""),
+ extension(".js"),
+ one_output_file_per_input_file(false),
+ annotate_code(false) {}
+
+ bool ParseFromOptions(
+ const std::vector<std::pair<std::string, std::string> >& options,
+ std::string* error);
+
+ // Returns the file name extension to use for generated code.
+ std::string GetFileNameExtension() const {
+ return import_style == kImportClosure ? extension : "_pb.js";
+ }
+
+ enum OutputMode {
+ // Create an output file for each input .proto file.
+ kOneOutputFilePerInputFile,
+ // Create an output file for each type.
+ kOneOutputFilePerSCC,
+ // Put everything in a single file named by the library option.
+ kEverythingInOneFile,
+ };
+
+ // Indicates how to output the generated code based on the provided options.
+ OutputMode output_mode() const;
+
+ // The remaining options are only relevant when we are using kImportClosure.
+
+ // Add a `goog.requires()` call for each enum type used. If not set, a
+ // forward declaration with `goog.forwardDeclare` is produced instead.
+ bool add_require_for_enums;
+ // Set this as a test-only module via `goog.setTestOnly();`.
+ bool testonly;
+ // Create a library with name <name>_lib.js rather than a separate .js file
+ // per type?
+ std::string library;
+ // The extension to use for output file names.
+ std::string extension;
+ // Create a separate output file for each input file?
+ bool one_output_file_per_input_file;
+ // If true, we should append annotations as comments on the last line for
+ // generated .js file. Annotations used by tools like https://kythe.io
+ // to provide cross-references between .js and .proto files. Annotations
+ // are encoded as base64 proto of GeneratedCodeInfo message (see
+ // descriptor.proto).
+ bool annotate_code;
+};
+
+// CodeGenerator implementation which generates a JavaScript source file and
+// header. If you create your own protocol compiler binary and you want it to
+// support JavaScript output, you can do so by registering an instance of this
+// CodeGenerator with the CommandLineInterface in your main() function.
+class PROTOC_EXPORT Generator : public CodeGenerator {
+ public:
+ Generator() {}
+ virtual ~Generator() {}
+
+ bool Generate(const FileDescriptor* file, const std::string& parameter,
+ GeneratorContext* context, std::string* error) const override {
+ *error = "Unimplemented Generate() method. Call GenerateAll() instead.";
+ return false;
+ }
+
+ bool HasGenerateAll() const override { return true; }
+
+ bool GenerateAll(const std::vector<const FileDescriptor*>& files,
+ const std::string& parameter, GeneratorContext* context,
+ std::string* error) const override;
+
+ uint64 GetSupportedFeatures() const override {
+ return FEATURE_PROTO3_OPTIONAL;
+ }
+
+ private:
+ void GenerateHeader(const GeneratorOptions& options,
+ const FileDescriptor* file, io::Printer* printer) const;
+
+ // Generate goog.provides() calls.
+ void FindProvides(const GeneratorOptions& options, io::Printer* printer,
+ const std::vector<const FileDescriptor*>& file,
+ std::set<std::string>* provided) const;
+ void FindProvidesForFile(const GeneratorOptions& options,
+ io::Printer* printer, const FileDescriptor* file,
+ std::set<std::string>* provided) const;
+ void FindProvidesForMessage(const GeneratorOptions& options,
+ io::Printer* printer, const Descriptor* desc,
+ std::set<std::string>* provided) const;
+ void FindProvidesForEnum(const GeneratorOptions& options,
+ io::Printer* printer, const EnumDescriptor* enumdesc,
+ std::set<std::string>* provided) const;
+ // For extension fields at file scope.
+ void FindProvidesForFields(const GeneratorOptions& options,
+ io::Printer* printer,
+ const std::vector<const FieldDescriptor*>& fields,
+ std::set<std::string>* provided) const;
+ // Print the goog.provides() found by the methods above.
+ void GenerateProvides(const GeneratorOptions& options, io::Printer* printer,
+ std::set<std::string>* provided) const;
+
+ // Generate goog.setTestOnly() if indicated.
+ void GenerateTestOnly(const GeneratorOptions& options,
+ io::Printer* printer) const;
+
+ // Generate goog.requires() calls.
+ void GenerateRequiresForLibrary(
+ const GeneratorOptions& options, io::Printer* printer,
+ const std::vector<const FileDescriptor*>& files,
+ std::set<std::string>* provided) const;
+ void GenerateRequiresForSCC(const GeneratorOptions& options,
+ io::Printer* printer, const SCC* scc,
+ std::set<std::string>* provided) const;
+ // For extension fields at file scope.
+ void GenerateRequiresForExtensions(
+ const GeneratorOptions& options, io::Printer* printer,
+ const std::vector<const FieldDescriptor*>& fields,
+ std::set<std::string>* provided) const;
+ void GenerateRequiresImpl(const GeneratorOptions& options,
+ io::Printer* printer,
+ std::set<std::string>* required,
+ std::set<std::string>* forwards,
+ std::set<std::string>* provided, bool require_jspb,
+ bool require_extension, bool require_map) const;
+ void FindRequiresForMessage(const GeneratorOptions& options,
+ const Descriptor* desc,
+ std::set<std::string>* required,
+ std::set<std::string>* forwards,
+ bool* have_message) const;
+ void FindRequiresForField(const GeneratorOptions& options,
+ const FieldDescriptor* field,
+ std::set<std::string>* required,
+ std::set<std::string>* forwards) const;
+ void FindRequiresForExtension(const GeneratorOptions& options,
+ const FieldDescriptor* field,
+ std::set<std::string>* required,
+ std::set<std::string>* forwards) const;
+ // Generate all things in a proto file into one file.
+ // If use_short_name is true, the generated file's name will only be short
+ // name that without directory, otherwise filename equals file->name()
+ bool GenerateFile(const FileDescriptor* file, const GeneratorOptions& options,
+ GeneratorContext* context, bool use_short_name) const;
+ void GenerateFile(const GeneratorOptions& options, io::Printer* printer,
+ const FileDescriptor* file) const;
+
+ // Generate definitions for all message classes and enums in all files,
+ // processing the files in dependence order.
+ void GenerateFilesInDepOrder(
+ const GeneratorOptions& options, io::Printer* printer,
+ const std::vector<const FileDescriptor*>& file) const;
+ // Helper for above.
+ void GenerateFileAndDeps(const GeneratorOptions& options,
+ io::Printer* printer, const FileDescriptor* root,
+ std::set<const FileDescriptor*>* all_files,
+ std::set<const FileDescriptor*>* generated) const;
+
+ // Generate definitions for all message classes and enums.
+ void GenerateClassesAndEnums(const GeneratorOptions& options,
+ io::Printer* printer,
+ const FileDescriptor* file) const;
+
+ void GenerateFieldValueExpression(io::Printer* printer,
+ const char* obj_reference,
+ const FieldDescriptor* field,
+ bool use_default) const;
+
+ // Generate definition for one class.
+ void GenerateClass(const GeneratorOptions& options, io::Printer* printer,
+ const Descriptor* desc) const;
+ void GenerateClassConstructor(const GeneratorOptions& options,
+ io::Printer* printer,
+ const Descriptor* desc) const;
+ void GenerateClassFieldInfo(const GeneratorOptions& options,
+ io::Printer* printer,
+ const Descriptor* desc) const;
+ void GenerateClassConstructorAndDeclareExtensionFieldInfo(
+ const GeneratorOptions& options, io::Printer* printer,
+ const Descriptor* desc) const;
+ void GenerateClassXid(const GeneratorOptions& options, io::Printer* printer,
+ const Descriptor* desc) const;
+ void GenerateOneofCaseDefinition(const GeneratorOptions& options,
+ io::Printer* printer,
+ const OneofDescriptor* oneof) const;
+ void GenerateObjectTypedef(const GeneratorOptions& options,
+ io::Printer* printer,
+ const Descriptor* desc) const;
+ void GenerateClassToObject(const GeneratorOptions& options,
+ io::Printer* printer,
+ const Descriptor* desc) const;
+ void GenerateClassFieldToObject(const GeneratorOptions& options,
+ io::Printer* printer,
+ const FieldDescriptor* field) const;
+ void GenerateClassFromObject(const GeneratorOptions& options,
+ io::Printer* printer,
+ const Descriptor* desc) const;
+ void GenerateClassFieldFromObject(const GeneratorOptions& options,
+ io::Printer* printer,
+ const FieldDescriptor* field) const;
+ void GenerateClassRegistration(const GeneratorOptions& options,
+ io::Printer* printer,
+ const Descriptor* desc) const;
+ void GenerateClassFields(const GeneratorOptions& options,
+ io::Printer* printer, const Descriptor* desc) const;
+ void GenerateClassField(const GeneratorOptions& options, io::Printer* printer,
+ const FieldDescriptor* desc) const;
+ void GenerateClassExtensionFieldInfo(const GeneratorOptions& options,
+ io::Printer* printer,
+ const Descriptor* desc) const;
+ void GenerateClassDeserialize(const GeneratorOptions& options,
+ io::Printer* printer,
+ const Descriptor* desc) const;
+ void GenerateClassDeserializeBinary(const GeneratorOptions& options,
+ io::Printer* printer,
+ const Descriptor* desc) const;
+ void GenerateClassDeserializeBinaryField(const GeneratorOptions& options,
+ io::Printer* printer,
+ const FieldDescriptor* field) const;
+ void GenerateClassSerializeBinary(const GeneratorOptions& options,
+ io::Printer* printer,
+ const Descriptor* desc) const;
+ void GenerateClassSerializeBinaryField(const GeneratorOptions& options,
+ io::Printer* printer,
+ const FieldDescriptor* field) const;
+
+ // Generate definition for one enum.
+ void GenerateEnum(const GeneratorOptions& options, io::Printer* printer,
+ const EnumDescriptor* enumdesc) const;
+
+ // Generate an extension definition.
+ void GenerateExtension(const GeneratorOptions& options, io::Printer* printer,
+ const FieldDescriptor* field) const;
+
+ // Generate addFoo() method for repeated primitive fields.
+ void GenerateRepeatedPrimitiveHelperMethods(const GeneratorOptions& options,
+ io::Printer* printer,
+ const FieldDescriptor* field,
+ bool untyped) const;
+
+ // Generate addFoo() method for repeated message fields.
+ void GenerateRepeatedMessageHelperMethods(const GeneratorOptions& options,
+ io::Printer* printer,
+ const FieldDescriptor* field) const;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Generator);
+};
+
+} // namespace js
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#include <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_COMPILER_JS_GENERATOR_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/js/well_known_types_embed.cc b/NorthstarDedicatedTest/include/protobuf/compiler/js/well_known_types_embed.cc
new file mode 100644
index 00000000..eaccdcf5
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/js/well_known_types_embed.cc
@@ -0,0 +1,270 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <compiler/js/well_known_types_embed.h>
+
+struct FileToc well_known_types_js[] = {
+ {"any.js",
+ "/* This code will be inserted into generated code for\n"
+ " * google/protobuf/any.proto. */\n"
+ "\n"
+ "/**\n"
+ " * Returns the type name contained in this instance, if any.\n"
+ " * @return {string|undefined}\n"
+ " */\n"
+ "proto.google.protobuf.Any.prototype.getTypeName = function() {\n"
+ " return this.getTypeUrl().split('/').pop();\n"
+ "};\n"
+ "\n"
+ "\n"
+ "/**\n"
+ " * Packs the given message instance into this Any.\n"
+ " * For binary format usage only.\n"
+ " * @param {!Uint8Array} serialized The serialized data to pack.\n"
+ " * @param {string} name The type name of this message object.\n"
+ " * @param {string=} opt_typeUrlPrefix the type URL prefix.\n"
+ " */\n"
+ "proto.google.protobuf.Any.prototype.pack = function(serialized, name,\n"
+ " opt_typeUrlPrefix) "
+ "{\n"
+ " if (!opt_typeUrlPrefix) {\n"
+ " opt_typeUrlPrefix = 'type.googleapis.com/';\n"
+ " }\n"
+ "\n"
+ " if (opt_typeUrlPrefix.substr(-1) != '/') {\n"
+ " this.setTypeUrl(opt_typeUrlPrefix + '/' + name);\n"
+ " } else {\n"
+ " this.setTypeUrl(opt_typeUrlPrefix + name);\n"
+ " }\n"
+ "\n"
+ " this.setValue(serialized);\n"
+ "};\n"
+ "\n"
+ "\n"
+ "/**\n"
+ " * @template T\n"
+ " * Unpacks this Any into the given message object.\n"
+ " * @param {function(Uint8Array):T} deserialize Function that will "
+ "deserialize\n"
+ " * the binary data properly.\n"
+ " * @param {string} name The expected type name of this message object.\n"
+ " * @return {?T} If the name matched the expected name, returns the "
+ "deserialized\n"
+ " * object, otherwise returns null.\n"
+ " */\n"
+ "proto.google.protobuf.Any.prototype.unpack = function(deserialize, name) "
+ "{\n"
+ " if (this.getTypeName() == name) {\n"
+ " return deserialize(this.getValue_asU8());\n"
+ " } else {\n"
+ " return null;\n"
+ " }\n"
+ "};\n"
+ },
+ {"timestamp.js",
+ "/* This code will be inserted into generated code for\n"
+ " * google/protobuf/timestamp.proto. */\n"
+ "\n"
+ "/**\n"
+ " * Returns a JavaScript 'Date' object corresponding to this Timestamp.\n"
+ " * @return {!Date}\n"
+ " */\n"
+ "proto.google.protobuf.Timestamp.prototype.toDate = function() {\n"
+ " var seconds = this.getSeconds();\n"
+ " var nanos = this.getNanos();\n"
+ "\n"
+ " return new Date((seconds * 1000) + (nanos / 1000000));\n"
+ "};\n"
+ "\n"
+ "\n"
+ "/**\n"
+ " * Sets the value of this Timestamp object to be the given Date.\n"
+ " * @param {!Date} value The value to set.\n"
+ " */\n"
+ "proto.google.protobuf.Timestamp.prototype.fromDate = function(value) {\n"
+ " this.setSeconds(Math.floor(value.getTime() / 1000));\n"
+ " this.setNanos(value.getMilliseconds() * 1000000);\n"
+ "};\n"
+ "\n"
+ "\n"
+ "/**\n"
+ " * Factory method that returns a Timestamp object with value equal to\n"
+ " * the given Date.\n"
+ " * @param {!Date} value The value to set.\n"
+ " * @return {!proto.google.protobuf.Timestamp}\n"
+ " */\n"
+ "proto.google.protobuf.Timestamp.fromDate = function(value) {\n"
+ " var timestamp = new proto.google.protobuf.Timestamp();\n"
+ " timestamp.fromDate(value);\n"
+ " return timestamp;\n"
+ "};\n"},
+ {"struct.js",
+ "/* This code will be inserted into generated code for\n"
+ " * google/protobuf/struct.proto. */\n"
+ "\n"
+ "/**\n"
+ " * Typedef representing plain JavaScript values that can go into a\n"
+ " * Struct.\n"
+ " * @typedef {null|number|string|boolean|Array|Object}\n"
+ " */\n"
+ "proto.google.protobuf.JavaScriptValue;\n"
+ "\n"
+ "\n"
+ "/**\n"
+ " * Converts this Value object to a plain JavaScript value.\n"
+ " * @return {?proto.google.protobuf.JavaScriptValue} a plain JavaScript\n"
+ " * value representing this Struct.\n"
+ " */\n"
+ "proto.google.protobuf.Value.prototype.toJavaScript = function() {\n"
+ " var kindCase = proto.google.protobuf.Value.KindCase;\n"
+ " switch (this.getKindCase()) {\n"
+ " case kindCase.NULL_VALUE:\n"
+ " return null;\n"
+ " case kindCase.NUMBER_VALUE:\n"
+ " return this.getNumberValue();\n"
+ " case kindCase.STRING_VALUE:\n"
+ " return this.getStringValue();\n"
+ " case kindCase.BOOL_VALUE:\n"
+ " return this.getBoolValue();\n"
+ " case kindCase.STRUCT_VALUE:\n"
+ " return this.getStructValue().toJavaScript();\n"
+ " case kindCase.LIST_VALUE:\n"
+ " return this.getListValue().toJavaScript();\n"
+ " default:\n"
+ " throw new Error('Unexpected struct type');\n"
+ " }\n"
+ "};\n"
+ "\n"
+ "\n"
+ "/**\n"
+ " * Converts this JavaScript value to a new Value proto.\n"
+ " * @param {!proto.google.protobuf.JavaScriptValue} value The value to\n"
+ " * convert.\n"
+ " * @return {!proto.google.protobuf.Value} The newly constructed value.\n"
+ " */\n"
+ "proto.google.protobuf.Value.fromJavaScript = function(value) {\n"
+ " var ret = new proto.google.protobuf.Value();\n"
+ " switch (goog.typeOf(value)) {\n"
+ " case 'string':\n"
+ " ret.setStringValue(/** @type {string} */ (value));\n"
+ " break;\n"
+ " case 'number':\n"
+ " ret.setNumberValue(/** @type {number} */ (value));\n"
+ " break;\n"
+ " case 'boolean':\n"
+ " ret.setBoolValue(/** @type {boolean} */ (value));\n"
+ " break;\n"
+ " case 'null':\n"
+ " ret.setNullValue(proto.google.protobuf.NullValue.NULL_VALUE);\n"
+ " break;\n"
+ " case 'array':\n"
+ " ret.setListValue(proto.google.protobuf.ListValue.fromJavaScript(\n"
+ " /** @type{!Array} */ (value)));\n"
+ " break;\n"
+ " case 'object':\n"
+ " ret.setStructValue(proto.google.protobuf.Struct.fromJavaScript(\n"
+ " /** @type{!Object} */ (value)));\n"
+ " break;\n"
+ " default:\n"
+ " throw new Error('Unexpected struct type.');\n"
+ " }\n"
+ "\n"
+ " return ret;\n"
+ "};\n"
+ "\n"
+ "\n"
+ "/**\n"
+ " * Converts this ListValue object to a plain JavaScript array.\n"
+ " * @return {!Array} a plain JavaScript array representing this List.\n"
+ " */\n"
+ "proto.google.protobuf.ListValue.prototype.toJavaScript = function() {\n"
+ " var ret = [];\n"
+ " var values = this.getValuesList();\n"
+ "\n"
+ " for (var i = 0; i < values.length; i++) {\n"
+ " ret[i] = values[i].toJavaScript();\n"
+ " }\n"
+ "\n"
+ " return ret;\n"
+ "};\n"
+ "\n"
+ "\n"
+ "/**\n"
+ " * Constructs a ListValue protobuf from this plain JavaScript array.\n"
+ " * @param {!Array} array a plain JavaScript array\n"
+ " * @return {proto.google.protobuf.ListValue} a new ListValue object\n"
+ " */\n"
+ "proto.google.protobuf.ListValue.fromJavaScript = function(array) {\n"
+ " var ret = new proto.google.protobuf.ListValue();\n"
+ "\n"
+ " for (var i = 0; i < array.length; i++) {\n"
+ " "
+ "ret.addValues(proto.google.protobuf.Value.fromJavaScript(array[i]));\n"
+ " }\n"
+ "\n"
+ " return ret;\n"
+ "};\n"
+ "\n"
+ "\n"
+ "/**\n"
+ " * Converts this Struct object to a plain JavaScript object.\n"
+ " * @return {!Object<string, !proto.google.protobuf.JavaScriptValue>} a "
+ "plain\n"
+ " * JavaScript object representing this Struct.\n"
+ " */\n"
+ "proto.google.protobuf.Struct.prototype.toJavaScript = function() {\n"
+ " var ret = {};\n"
+ "\n"
+ " this.getFieldsMap().forEach(function(value, key) {\n"
+ " ret[key] = value.toJavaScript();\n"
+ " });\n"
+ "\n"
+ " return ret;\n"
+ "};\n"
+ "\n"
+ "\n"
+ "/**\n"
+ " * Constructs a Struct protobuf from this plain JavaScript object.\n"
+ " * @param {!Object} obj a plain JavaScript object\n"
+ " * @return {proto.google.protobuf.Struct} a new Struct object\n"
+ " */\n"
+ "proto.google.protobuf.Struct.fromJavaScript = function(obj) {\n"
+ " var ret = new proto.google.protobuf.Struct();\n"
+ " var map = ret.getFieldsMap();\n"
+ "\n"
+ " for (var property in obj) {\n"
+ " var val = obj[property];\n"
+ " map.set(property, proto.google.protobuf.Value.fromJavaScript(val));\n"
+ " }\n"
+ "\n"
+ " return ret;\n"
+ "};\n"},
+ {NULL, NULL} // Terminate the list.
+};
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/js/well_known_types_embed.h b/NorthstarDedicatedTest/include/protobuf/compiler/js/well_known_types_embed.h
new file mode 100644
index 00000000..174c665e
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/js/well_known_types_embed.h
@@ -0,0 +1,43 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_JS_WELL_KNOWN_TYPES_EMBED_H__
+#define GOOGLE_PROTOBUF_COMPILER_JS_WELL_KNOWN_TYPES_EMBED_H__
+
+#include <stddef.h>
+
+struct FileToc {
+ const char* name;
+ const char* data;
+};
+
+extern struct FileToc well_known_types_js[];
+
+#endif // GOOGLE_PROTOBUF_COMPILER_JS_WELL_KNOWN_TYPES_EMBED_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/main.cc b/NorthstarDedicatedTest/include/protobuf/compiler/main.cc
new file mode 100644
index 00000000..2a5a2267
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/main.cc
@@ -0,0 +1,113 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 <compiler/cpp/cpp_generator.h>
+#include <compiler/java/java_generator.h>
+#include <compiler/java/java_kotlin_generator.h>
+#include <compiler/js/js_generator.h>
+#include <compiler/command_line_interface.h>
+#include <compiler/python/python_generator.h>
+#include <compiler/csharp/csharp_generator.h>
+#include <compiler/objectivec/objectivec_generator.h>
+#include <compiler/php/php_generator.h>
+#include <compiler/ruby/ruby_generator.h>
+
+#include <port_def.inc>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+
+int ProtobufMain(int argc, char* argv[]) {
+
+ CommandLineInterface cli;
+ cli.AllowPlugins("protoc-");
+
+ // Proto2 C++
+ cpp::CppGenerator cpp_generator;
+ cli.RegisterGenerator("--cpp_out", "--cpp_opt", &cpp_generator,
+ "Generate C++ header and source.");
+
+#ifdef GOOGLE_PROTOBUF_RUNTIME_INCLUDE_BASE
+ cpp_generator.set_opensource_runtime(true);
+ cpp_generator.set_runtime_include_base(GOOGLE_PROTOBUF_RUNTIME_INCLUDE_BASE);
+#endif
+
+ // Proto2 Java
+ java::JavaGenerator java_generator;
+ cli.RegisterGenerator("--java_out", "--java_opt", &java_generator,
+ "Generate Java source file.");
+
+ // Proto2 Kotlin
+ java::KotlinGenerator kt_generator;
+ cli.RegisterGenerator("--kotlin_out", "--kotlin_opt", &kt_generator,
+ "Generate Kotlin file.");
+
+
+ // Proto2 Python
+ python::Generator py_generator;
+ cli.RegisterGenerator("--python_out", "--python_opt", &py_generator,
+ "Generate Python source file.");
+
+ // PHP
+ php::Generator php_generator;
+ cli.RegisterGenerator("--php_out", "--php_opt", &php_generator,
+ "Generate PHP source file.");
+
+ // Ruby
+ ruby::Generator rb_generator;
+ cli.RegisterGenerator("--ruby_out", "--ruby_opt", &rb_generator,
+ "Generate Ruby source file.");
+
+ // CSharp
+ csharp::Generator csharp_generator;
+ cli.RegisterGenerator("--csharp_out", "--csharp_opt", &csharp_generator,
+ "Generate C# source file.");
+
+ // Objective-C
+ objectivec::ObjectiveCGenerator objc_generator;
+ cli.RegisterGenerator("--objc_out", "--objc_opt", &objc_generator,
+ "Generate Objective-C header and source.");
+
+ // JavaScript
+ js::Generator js_generator;
+ cli.RegisterGenerator("--js_out", "--js_opt", &js_generator,
+ "Generate JavaScript source.");
+
+ return cli.Run(argc, argv);
+}
+
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+int main(int argc, char* argv[]) {
+ return PROTOBUF_NAMESPACE_ID::compiler::ProtobufMain(argc, argv);
+}
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/mock_code_generator.cc b/NorthstarDedicatedTest/include/protobuf/compiler/mock_code_generator.cc
new file mode 100644
index 00000000..9de6b5b0
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/mock_code_generator.cc
@@ -0,0 +1,384 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+
+#include <compiler/mock_code_generator.h>
+
+#include <stdlib.h>
+
+#include <cstdint>
+#include <iostream>
+#include <memory>
+#include <vector>
+
+#include <stubs/strutil.h>
+
+#include <stubs/logging.h>
+#include <stubs/common.h>
+#include <testing/file.h>
+#include <testing/file.h>
+#include <testing/file.h>
+#include <compiler/plugin.pb.h>
+#include <io/printer.h>
+#include <io/zero_copy_stream.h>
+#include <descriptor.pb.h>
+#include <descriptor.h>
+#include <text_format.h>
+#include <gtest/gtest.h>
+#include <stubs/substitute.h>
+
+#ifdef major
+#undef major
+#endif
+#ifdef minor
+#undef minor
+#endif
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+
+// Returns the list of the names of files in all_files in the form of a
+// comma-separated string.
+std::string CommaSeparatedList(
+ const std::vector<const FileDescriptor*>& all_files) {
+ std::vector<std::string> names;
+ for (size_t i = 0; i < all_files.size(); i++) {
+ names.push_back(all_files[i]->name());
+ }
+ return Join(names, ",");
+}
+
+static const char* kFirstInsertionPointName = "first_mock_insertion_point";
+static const char* kSecondInsertionPointName = "second_mock_insertion_point";
+static const char* kFirstInsertionPoint =
+ "# @@protoc_insertion_point(first_mock_insertion_point) is here\n";
+static const char* kSecondInsertionPoint =
+ " # @@protoc_insertion_point(second_mock_insertion_point) is here\n";
+
+MockCodeGenerator::MockCodeGenerator(const std::string& name) : name_(name) {}
+
+MockCodeGenerator::~MockCodeGenerator() {}
+
+uint64_t MockCodeGenerator::GetSupportedFeatures() const {
+ uint64_t all_features = CodeGenerator::FEATURE_PROTO3_OPTIONAL;
+ return all_features & ~suppressed_features_;
+}
+
+void MockCodeGenerator::SuppressFeatures(uint64_t features) {
+ suppressed_features_ = features;
+}
+
+void MockCodeGenerator::ExpectGenerated(
+ const std::string& name, const std::string& parameter,
+ const std::string& insertions, const std::string& file,
+ const std::string& first_message_name,
+ const std::string& first_parsed_file_name,
+ const std::string& output_directory) {
+ std::string content;
+ GOOGLE_CHECK_OK(
+ File::GetContents(output_directory + "/" + GetOutputFileName(name, file),
+ &content, true));
+
+ std::vector<std::string> lines =
+ Split(content, "\n", true);
+
+ while (!lines.empty() && lines.back().empty()) {
+ lines.pop_back();
+ }
+ for (size_t i = 0; i < lines.size(); i++) {
+ lines[i] += "\n";
+ }
+
+ std::vector<std::string> insertion_list;
+ if (!insertions.empty()) {
+ insertion_list = Split(insertions, ",", true);
+ }
+
+ EXPECT_EQ(lines.size(), 3 + insertion_list.size() * 2);
+ EXPECT_EQ(GetOutputFileContent(name, parameter, file, first_parsed_file_name,
+ first_message_name),
+ lines[0]);
+
+ EXPECT_EQ(kFirstInsertionPoint, lines[1 + insertion_list.size()]);
+ EXPECT_EQ(kSecondInsertionPoint, lines[2 + insertion_list.size() * 2]);
+
+ for (size_t i = 0; i < insertion_list.size(); i++) {
+ EXPECT_EQ(GetOutputFileContent(insertion_list[i], "first_insert", file,
+ file, first_message_name),
+ lines[1 + i]);
+ // Second insertion point is indented, so the inserted text should
+ // automatically be indented too.
+ EXPECT_EQ(" " + GetOutputFileContent(insertion_list[i], "second_insert",
+ file, file, first_message_name),
+ lines[2 + insertion_list.size() + i]);
+ }
+}
+
+namespace {
+void CheckSingleAnnotation(const std::string& expected_file,
+ const std::string& expected_text,
+ const std::string& file_content,
+ const GeneratedCodeInfo::Annotation& annotation) {
+ EXPECT_EQ(expected_file, annotation.source_file());
+ ASSERT_GE(file_content.size(), annotation.begin());
+ ASSERT_GE(file_content.size(), annotation.end());
+ ASSERT_LE(annotation.begin(), annotation.end());
+ EXPECT_EQ(expected_text.size(), annotation.end() - annotation.begin());
+ EXPECT_EQ(expected_text,
+ file_content.substr(annotation.begin(), expected_text.size()));
+}
+} // anonymous namespace
+
+void MockCodeGenerator::CheckGeneratedAnnotations(
+ const std::string& name, const std::string& file,
+ const std::string& output_directory) {
+ std::string file_content;
+ GOOGLE_CHECK_OK(
+ File::GetContents(output_directory + "/" + GetOutputFileName(name, file),
+ &file_content, true));
+ std::string meta_content;
+ GOOGLE_CHECK_OK(File::GetContents(
+ output_directory + "/" + GetOutputFileName(name, file) + ".pb.meta",
+ &meta_content, true));
+ GeneratedCodeInfo annotations;
+ GOOGLE_CHECK(TextFormat::ParseFromString(meta_content, &annotations));
+ ASSERT_EQ(7, annotations.annotation_size());
+
+ CheckSingleAnnotation("first_annotation", "first", file_content,
+ annotations.annotation(0));
+ CheckSingleAnnotation("first_path",
+ "test_generator: first_insert,\n foo.proto,\n "
+ "MockCodeGenerator_Annotate,\n foo.proto\n",
+ file_content, annotations.annotation(1));
+ CheckSingleAnnotation("first_path",
+ "test_plugin: first_insert,\n foo.proto,\n "
+ "MockCodeGenerator_Annotate,\n foo.proto\n",
+ file_content, annotations.annotation(2));
+ CheckSingleAnnotation("second_annotation", "second", file_content,
+ annotations.annotation(3));
+ // This annotated text has changed because it was inserted at an indented
+ // insertion point.
+ CheckSingleAnnotation("second_path",
+ "test_generator: second_insert,\n foo.proto,\n "
+ "MockCodeGenerator_Annotate,\n foo.proto\n",
+ file_content, annotations.annotation(4));
+ CheckSingleAnnotation("second_path",
+ "test_plugin: second_insert,\n foo.proto,\n "
+ "MockCodeGenerator_Annotate,\n foo.proto\n",
+ file_content, annotations.annotation(5));
+ CheckSingleAnnotation("third_annotation", "third", file_content,
+ annotations.annotation(6));
+}
+
+bool MockCodeGenerator::Generate(const FileDescriptor* file,
+ const std::string& parameter,
+ GeneratorContext* context,
+ std::string* error) const {
+ bool annotate = false;
+ for (int i = 0; i < file->message_type_count(); i++) {
+ if (HasPrefixString(file->message_type(i)->name(), "MockCodeGenerator_")) {
+ std::string command = StripPrefixString(
+ file->message_type(i)->name(), "MockCodeGenerator_");
+ if (command == "Error") {
+ *error = "Saw message type MockCodeGenerator_Error.";
+ return false;
+ } else if (command == "Exit") {
+ std::cerr << "Saw message type MockCodeGenerator_Exit." << std::endl;
+ exit(123);
+ } else if (command == "Abort") {
+ std::cerr << "Saw message type MockCodeGenerator_Abort." << std::endl;
+ abort();
+ } else if (command == "HasSourceCodeInfo") {
+ FileDescriptorProto file_descriptor_proto;
+ file->CopySourceCodeInfoTo(&file_descriptor_proto);
+ bool has_source_code_info =
+ file_descriptor_proto.has_source_code_info() &&
+ file_descriptor_proto.source_code_info().location_size() > 0;
+ std::cerr << "Saw message type MockCodeGenerator_HasSourceCodeInfo: "
+ << has_source_code_info << "." << std::endl;
+ abort();
+ } else if (command == "HasJsonName") {
+ FieldDescriptorProto field_descriptor_proto;
+ file->message_type(i)->field(0)->CopyTo(&field_descriptor_proto);
+ std::cerr << "Saw json_name: " << field_descriptor_proto.has_json_name()
+ << std::endl;
+ abort();
+ } else if (command == "Annotate") {
+ annotate = true;
+ } else if (command == "ShowVersionNumber") {
+ Version compiler_version;
+ context->GetCompilerVersion(&compiler_version);
+ std::cerr << "Saw compiler_version: "
+ << compiler_version.major() * 1000000 +
+ compiler_version.minor() * 1000 +
+ compiler_version.patch()
+ << " " << compiler_version.suffix() << std::endl;
+ abort();
+ } else {
+ GOOGLE_LOG(FATAL) << "Unknown MockCodeGenerator command: " << command;
+ }
+ }
+ }
+
+ bool insert_endlines = HasPrefixString(parameter, "insert_endlines=");
+ if (insert_endlines || HasPrefixString(parameter, "insert=")) {
+ std::vector<std::string> insert_into = Split(
+ StripPrefixString(
+ parameter, insert_endlines ? "insert_endlines=" : "insert="),
+ ",", true);
+
+ for (size_t i = 0; i < insert_into.size(); i++) {
+ {
+ google::protobuf::GeneratedCodeInfo info;
+ std::string content =
+ GetOutputFileContent(name_, "first_insert", file, context);
+ if (insert_endlines) {
+ GlobalReplaceSubstring(",", ",\n", &content);
+ }
+ if (annotate) {
+ auto* annotation = info.add_annotation();
+ annotation->set_begin(0);
+ annotation->set_end(content.size());
+ annotation->set_source_file("first_path");
+ }
+ std::unique_ptr<io::ZeroCopyOutputStream> output(
+ context->OpenForInsertWithGeneratedCodeInfo(
+ GetOutputFileName(insert_into[i], file),
+ kFirstInsertionPointName, info));
+ io::Printer printer(output.get(), '$');
+ printer.PrintRaw(content);
+ if (printer.failed()) {
+ *error = "MockCodeGenerator detected write error.";
+ return false;
+ }
+ }
+
+ {
+ google::protobuf::GeneratedCodeInfo info;
+ std::string content =
+ GetOutputFileContent(name_, "second_insert", file, context);
+ if (insert_endlines) {
+ GlobalReplaceSubstring(",", ",\n", &content);
+ }
+ if (annotate) {
+ auto* annotation = info.add_annotation();
+ annotation->set_begin(0);
+ annotation->set_end(content.size());
+ annotation->set_source_file("second_path");
+ }
+ std::unique_ptr<io::ZeroCopyOutputStream> output(
+ context->OpenForInsertWithGeneratedCodeInfo(
+ GetOutputFileName(insert_into[i], file),
+ kSecondInsertionPointName, info));
+ io::Printer printer(output.get(), '$');
+ printer.PrintRaw(content);
+ if (printer.failed()) {
+ *error = "MockCodeGenerator detected write error.";
+ return false;
+ }
+ }
+ }
+ } else {
+ std::unique_ptr<io::ZeroCopyOutputStream> output(
+ context->Open(GetOutputFileName(name_, file)));
+
+ GeneratedCodeInfo annotations;
+ io::AnnotationProtoCollector<GeneratedCodeInfo> annotation_collector(
+ &annotations);
+ io::Printer printer(output.get(), '$',
+ annotate ? &annotation_collector : NULL);
+ printer.PrintRaw(GetOutputFileContent(name_, parameter, file, context));
+ std::string annotate_suffix = "_annotation";
+ if (annotate) {
+ printer.Print("$p$\n", "p", "first");
+ printer.Annotate("p", "first" + annotate_suffix);
+ }
+ printer.PrintRaw(kFirstInsertionPoint);
+ if (annotate) {
+ printer.Print("$p$\n", "p", "second");
+ printer.Annotate("p", "second" + annotate_suffix);
+ }
+ printer.PrintRaw(kSecondInsertionPoint);
+ if (annotate) {
+ printer.Print("$p$\n", "p", "third");
+ printer.Annotate("p", "third" + annotate_suffix);
+ }
+
+ if (printer.failed()) {
+ *error = "MockCodeGenerator detected write error.";
+ return false;
+ }
+ if (annotate) {
+ std::unique_ptr<io::ZeroCopyOutputStream> meta_output(
+ context->Open(GetOutputFileName(name_, file) + ".pb.meta"));
+ if (!TextFormat::Print(annotations, meta_output.get())) {
+ *error = "MockCodeGenerator couldn't write .pb.meta";
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+std::string MockCodeGenerator::GetOutputFileName(
+ const std::string& generator_name, const FileDescriptor* file) {
+ return GetOutputFileName(generator_name, file->name());
+}
+
+std::string MockCodeGenerator::GetOutputFileName(
+ const std::string& generator_name, const std::string& file) {
+ return file + ".MockCodeGenerator." + generator_name;
+}
+
+std::string MockCodeGenerator::GetOutputFileContent(
+ const std::string& generator_name, const std::string& parameter,
+ const FileDescriptor* file, GeneratorContext* context) {
+ std::vector<const FileDescriptor*> all_files;
+ context->ListParsedFiles(&all_files);
+ return GetOutputFileContent(
+ generator_name, parameter, file->name(), CommaSeparatedList(all_files),
+ file->message_type_count() > 0 ? file->message_type(0)->name()
+ : "(none)");
+}
+
+std::string MockCodeGenerator::GetOutputFileContent(
+ const std::string& generator_name, const std::string& parameter,
+ const std::string& file, const std::string& parsed_file_list,
+ const std::string& first_message_name) {
+ return strings::Substitute("$0: $1, $2, $3, $4\n", generator_name, parameter,
+ file, first_message_name, parsed_file_list);
+}
+
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/mock_code_generator.h b/NorthstarDedicatedTest/include/protobuf/compiler/mock_code_generator.h
new file mode 100644
index 00000000..4b7c4dd1
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/mock_code_generator.h
@@ -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)
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_MOCK_CODE_GENERATOR_H__
+#define GOOGLE_PROTOBUF_COMPILER_MOCK_CODE_GENERATOR_H__
+
+#include <cstdint>
+#include <string>
+
+#include <compiler/code_generator.h>
+
+namespace google {
+namespace protobuf {
+class FileDescriptor;
+} // namespace protobuf
+} // namespace google
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+
+// A mock CodeGenerator, used by command_line_interface_unittest. This is in
+// its own file so that it can be used both directly and as a plugin.
+//
+// Generate() produces some output which can be checked by ExpectCalled(). The
+// generator can run in a different process (e.g. a plugin).
+//
+// If the parameter is "insert=NAMES", the MockCodeGenerator will insert lines
+// into the files generated by other MockCodeGenerators instead of creating
+// its own file. NAMES is a comma-separated list of the names of those other
+// MockCodeGenerators. If the parameter is "insert_endlines=NAMES", the
+// MockCodeGenerator will insert data guaranteed to contain more than one
+// endline into the files generated by NAMES.
+//
+// MockCodeGenerator will also modify its behavior slightly if the input file
+// contains a message type with one of the following names:
+// MockCodeGenerator_Error: Causes Generate() to return false and set the
+// error message to "Saw message type MockCodeGenerator_Error."
+// MockCodeGenerator_Exit: Generate() prints "Saw message type
+// MockCodeGenerator_Exit." to stderr and then calls exit(123).
+// MockCodeGenerator_Abort: Generate() prints "Saw message type
+// MockCodeGenerator_Abort." to stderr and then calls abort().
+// MockCodeGenerator_HasSourceCodeInfo: Causes Generate() to abort after
+// printing "Saw message type MockCodeGenerator_HasSourceCodeInfo: FOO." to
+// stderr, where FOO is "1" if the supplied FileDescriptorProto has source
+// code info, and "0" otherwise.
+// MockCodeGenerator_Annotate: Generate() will add annotations to its output
+// that can later be verified with CheckGeneratedAnnotations.
+class MockCodeGenerator : public CodeGenerator {
+ public:
+ MockCodeGenerator(const std::string& name);
+ virtual ~MockCodeGenerator();
+
+ // Expect (via gTest) that a MockCodeGenerator with the given name was called
+ // with the given parameters by inspecting the output location.
+ //
+ // |insertions| is a comma-separated list of names of MockCodeGenerators which
+ // should have inserted lines into this file.
+ // |parsed_file_list| is a comma-separated list of names of the files
+ // that are being compiled together in this run.
+ static void ExpectGenerated(const std::string& name,
+ const std::string& parameter,
+ const std::string& insertions,
+ const std::string& file,
+ const std::string& first_message_name,
+ const std::string& parsed_file_list,
+ const std::string& output_directory);
+
+ // Checks that the correct text ranges were annotated by the
+ // MockCodeGenerator_Annotate directive.
+ static void CheckGeneratedAnnotations(const std::string& name,
+ const std::string& file,
+ const std::string& output_directory);
+
+ // Get the name of the file which would be written by the given generator.
+ static std::string GetOutputFileName(const std::string& generator_name,
+ const FileDescriptor* file);
+ static std::string GetOutputFileName(const std::string& generator_name,
+ const std::string& file);
+
+ // implements CodeGenerator ----------------------------------------
+
+ bool Generate(const FileDescriptor* file, const std::string& parameter,
+ GeneratorContext* context, std::string* error) const override;
+
+ uint64_t GetSupportedFeatures() const override;
+ void SuppressFeatures(uint64_t features);
+
+ private:
+ std::string name_;
+ uint64_t suppressed_features_ = 0;
+
+ static std::string GetOutputFileContent(const std::string& generator_name,
+ const std::string& parameter,
+ const FileDescriptor* file,
+ GeneratorContext* context);
+ static std::string GetOutputFileContent(
+ const std::string& generator_name, const std::string& parameter,
+ const std::string& file, const std::string& parsed_file_list,
+ const std::string& first_message_name);
+};
+
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_COMPILER_MOCK_CODE_GENERATOR_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_enum.cc b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_enum.cc
new file mode 100644
index 00000000..5510750a
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_enum.cc
@@ -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.
+
+#include <map>
+#include <string>
+
+#include <compiler/objectivec/objectivec_enum.h>
+#include <compiler/objectivec/objectivec_helpers.h>
+#include <io/printer.h>
+#include <stubs/strutil.h>
+#include <algorithm> // std::find()
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace objectivec {
+
+EnumGenerator::EnumGenerator(const EnumDescriptor* descriptor)
+ : descriptor_(descriptor),
+ name_(EnumName(descriptor_)) {
+ // Track the names for the enum values, and if an alias overlaps a base
+ // value, skip making a name for it. Likewise if two alias overlap, the
+ // first one wins.
+ // The one gap in this logic is if two base values overlap, but for that
+ // to happen you have to have "Foo" and "FOO" or "FOO_BAR" and "FooBar",
+ // and if an enum has that, it is already going to be confusing and a
+ // compile error is just fine.
+ // The values are still tracked to support the reflection apis and
+ // TextFormat handing since they are different there.
+ std::set<std::string> value_names;
+
+ for (int i = 0; i < descriptor_->value_count(); i++) {
+ const EnumValueDescriptor* value = descriptor_->value(i);
+ const EnumValueDescriptor* canonical_value =
+ descriptor_->FindValueByNumber(value->number());
+
+ if (value == canonical_value) {
+ base_values_.push_back(value);
+ value_names.insert(EnumValueName(value));
+ } else {
+ std::string value_name(EnumValueName(value));
+ if (value_names.find(value_name) != value_names.end()) {
+ alias_values_to_skip_.insert(value);
+ } else {
+ value_names.insert(value_name);
+ }
+ }
+ all_values_.push_back(value);
+ }
+}
+
+EnumGenerator::~EnumGenerator() {}
+
+void EnumGenerator::GenerateHeader(io::Printer* printer) {
+ std::string enum_comments;
+ SourceLocation location;
+ if (descriptor_->GetSourceLocation(&location)) {
+ enum_comments = BuildCommentsString(location, true);
+ } else {
+ enum_comments = "";
+ }
+
+ printer->Print(
+ "#pragma mark - Enum $name$\n"
+ "\n",
+ "name", name_);
+
+ // Swift 5 included SE0192 "Handling Future Enum Cases"
+ // https://github.com/apple/swift-evolution/blob/master/proposals/0192-non-exhaustive-enums.md
+ // Since a .proto file can get new values added to an enum at any time, they
+ // are effectively "non-frozen". Even in a proto3 syntax file where there is
+ // support for the unknown value, an edit to the file can always add a new
+ // value moving something from unknown to known. Since Swift is now ABI
+ // stable, it also means a binary could contain Swift compiled against one
+ // version of the .pbobjc.h file, but finally linked against an enum with
+ // more cases. So the Swift code will always have to treat ObjC Proto Enums
+ // as "non-frozen". The default behavior in SE0192 is for all objc enums to
+ // be "non-frozen" unless marked as otherwise, so this means this generation
+ // doesn't have to bother with the `enum_extensibility` attribute, as the
+ // default will be what is needed.
+
+ printer->Print("$comments$typedef$deprecated_attribute$ GPB_ENUM($name$) {\n",
+ "comments", enum_comments,
+ "deprecated_attribute", GetOptionalDeprecatedAttribute(descriptor_, descriptor_->file()),
+ "name", name_);
+ printer->Indent();
+
+ if (HasPreservingUnknownEnumSemantics(descriptor_->file())) {
+ // Include the unknown value.
+ printer->Print(
+ "/**\n"
+ " * Value used if any message's field encounters a value that is not defined\n"
+ " * by this enum. The message will also have C functions to get/set the rawValue\n"
+ " * of the field.\n"
+ " **/\n"
+ "$name$_GPBUnrecognizedEnumeratorValue = kGPBUnrecognizedEnumeratorValue,\n",
+ "name", name_);
+ }
+ for (int i = 0; i < all_values_.size(); i++) {
+ if (alias_values_to_skip_.find(all_values_[i]) != alias_values_to_skip_.end()) {
+ continue;
+ }
+ if (all_values_[i]->GetSourceLocation(&location)) {
+ std::string comments = BuildCommentsString(location, true).c_str();
+ if (comments.length() > 0) {
+ if (i > 0) {
+ printer->Print("\n");
+ }
+ printer->Print(comments.c_str());
+ }
+ }
+
+ printer->Print(
+ "$name$$deprecated_attribute$ = $value$,\n",
+ "name", EnumValueName(all_values_[i]),
+ "deprecated_attribute", GetOptionalDeprecatedAttribute(all_values_[i]),
+ "value", StrCat(all_values_[i]->number()));
+ }
+ printer->Outdent();
+ printer->Print(
+ "};\n"
+ "\n"
+ "GPBEnumDescriptor *$name$_EnumDescriptor(void);\n"
+ "\n"
+ "/**\n"
+ " * Checks to see if the given value is defined by the enum or was not known at\n"
+ " * the time this source was generated.\n"
+ " **/\n"
+ "BOOL $name$_IsValidValue(int32_t value);\n"
+ "\n",
+ "name", name_);
+}
+
+void EnumGenerator::GenerateSource(io::Printer* printer) {
+ printer->Print(
+ "#pragma mark - Enum $name$\n"
+ "\n",
+ "name", name_);
+
+ // Note: For the TextFormat decode info, we can't use the enum value as
+ // the key because protocol buffer enums have 'allow_alias', which lets
+ // a value be used more than once. Instead, the index into the list of
+ // enum value descriptions is used. Note: start with -1 so the first one
+ // will be zero.
+ TextFormatDecodeData text_format_decode_data;
+ int enum_value_description_key = -1;
+ std::string text_blob;
+
+ for (int i = 0; i < all_values_.size(); i++) {
+ ++enum_value_description_key;
+ std::string short_name(EnumValueShortName(all_values_[i]));
+ text_blob += short_name + '\0';
+ if (UnCamelCaseEnumShortName(short_name) != all_values_[i]->name()) {
+ text_format_decode_data.AddString(enum_value_description_key, short_name,
+ all_values_[i]->name());
+ }
+ }
+
+ printer->Print(
+ "GPBEnumDescriptor *$name$_EnumDescriptor(void) {\n"
+ " static _Atomic(GPBEnumDescriptor*) descriptor = nil;\n"
+ " if (!descriptor) {\n",
+ "name", name_);
+
+ static const int kBytesPerLine = 40; // allow for escaping
+ printer->Print(
+ " static const char *valueNames =");
+ for (int i = 0; i < text_blob.size(); i += kBytesPerLine) {
+ printer->Print(
+ "\n \"$data$\"",
+ "data", EscapeTrigraphs(CEscape(text_blob.substr(i, kBytesPerLine))));
+ }
+ printer->Print(
+ ";\n"
+ " static const int32_t values[] = {\n");
+ for (int i = 0; i < all_values_.size(); i++) {
+ printer->Print(" $name$,\n", "name", EnumValueName(all_values_[i]));
+ }
+ printer->Print(" };\n");
+
+ if (text_format_decode_data.num_entries() == 0) {
+ printer->Print(
+ " GPBEnumDescriptor *worker =\n"
+ " [GPBEnumDescriptor allocDescriptorForName:GPBNSStringifySymbol($name$)\n"
+ " valueNames:valueNames\n"
+ " values:values\n"
+ " count:(uint32_t)(sizeof(values) / sizeof(int32_t))\n"
+ " enumVerifier:$name$_IsValidValue];\n",
+ "name", name_);
+ } else {
+ printer->Print(
+ " static const char *extraTextFormatInfo = \"$extraTextFormatInfo$\";\n"
+ " GPBEnumDescriptor *worker =\n"
+ " [GPBEnumDescriptor allocDescriptorForName:GPBNSStringifySymbol($name$)\n"
+ " valueNames:valueNames\n"
+ " values:values\n"
+ " count:(uint32_t)(sizeof(values) / sizeof(int32_t))\n"
+ " enumVerifier:$name$_IsValidValue\n"
+ " extraTextFormatInfo:extraTextFormatInfo];\n",
+ "name", name_,
+ "extraTextFormatInfo", CEscape(text_format_decode_data.Data()));
+ }
+ printer->Print(
+ " GPBEnumDescriptor *expected = nil;\n"
+ " if (!atomic_compare_exchange_strong(&descriptor, &expected, worker)) {\n"
+ " [worker release];\n"
+ " }\n"
+ " }\n"
+ " return descriptor;\n"
+ "}\n\n");
+
+ printer->Print(
+ "BOOL $name$_IsValidValue(int32_t value__) {\n"
+ " switch (value__) {\n",
+ "name", name_);
+
+ for (int i = 0; i < base_values_.size(); i++) {
+ printer->Print(
+ " case $name$:\n",
+ "name", EnumValueName(base_values_[i]));
+ }
+
+ printer->Print(
+ " return YES;\n"
+ " default:\n"
+ " return NO;\n"
+ " }\n"
+ "}\n\n");
+}
+} // namespace objectivec
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_enum.h b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_enum.h
new file mode 100644
index 00000000..51560dd1
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_enum.h
@@ -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.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_ENUM_H__
+#define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_ENUM_H__
+
+#include <string>
+#include <set>
+#include <vector>
+#include <descriptor.h>
+#include <io/printer.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace objectivec {
+
+class EnumGenerator {
+ public:
+ explicit EnumGenerator(const EnumDescriptor* descriptor);
+ ~EnumGenerator();
+
+ EnumGenerator(const EnumGenerator&) = delete;
+ EnumGenerator& operator=(const EnumGenerator&) = delete;
+
+ void GenerateHeader(io::Printer* printer);
+ void GenerateSource(io::Printer* printer);
+
+ const std::string& name() const { return name_; }
+
+ private:
+ const EnumDescriptor* descriptor_;
+ std::vector<const EnumValueDescriptor*> base_values_;
+ std::vector<const EnumValueDescriptor*> all_values_;
+ std::set<const EnumValueDescriptor*> alias_values_to_skip_;
+ const std::string name_;
+};
+
+} // namespace objectivec
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_ENUM_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_enum_field.cc b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_enum_field.cc
new file mode 100644
index 00000000..66877afb
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_enum_field.cc
@@ -0,0 +1,149 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 <map>
+#include <string>
+
+#include <compiler/objectivec/objectivec_enum_field.h>
+#include <compiler/objectivec/objectivec_helpers.h>
+#include <io/printer.h>
+#include <wire_format.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace objectivec {
+
+namespace {
+
+void SetEnumVariables(const FieldDescriptor* descriptor,
+ std::map<std::string, std::string>* variables) {
+ std::string type = EnumName(descriptor->enum_type());
+ (*variables)["storage_type"] = type;
+ // For non repeated fields, if it was defined in a different file, the
+ // property decls need to use "enum NAME" rather than just "NAME" to support
+ // the forward declaration of the enums.
+ if (!descriptor->is_repeated() &&
+ (descriptor->file() != descriptor->enum_type()->file())) {
+ (*variables)["property_type"] = "enum " + type;
+ }
+ (*variables)["enum_verifier"] = type + "_IsValidValue";
+ (*variables)["enum_desc_func"] = type + "_EnumDescriptor";
+
+ (*variables)["dataTypeSpecific_name"] = "enumDescFunc";
+ (*variables)["dataTypeSpecific_value"] = (*variables)["enum_desc_func"];
+
+ const Descriptor* msg_descriptor = descriptor->containing_type();
+ (*variables)["owning_message_class"] = ClassName(msg_descriptor);
+}
+} // namespace
+
+EnumFieldGenerator::EnumFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options)
+ : SingleFieldGenerator(descriptor, options) {
+ SetEnumVariables(descriptor, &variables_);
+}
+
+EnumFieldGenerator::~EnumFieldGenerator() {}
+
+void EnumFieldGenerator::GenerateCFunctionDeclarations(
+ io::Printer* printer) const {
+ if (!HasPreservingUnknownEnumSemantics(descriptor_->file())) {
+ return;
+ }
+
+ printer->Print(
+ variables_,
+ "/**\n"
+ " * Fetches the raw value of a @c $owning_message_class$'s @c $name$ property, even\n"
+ " * if the value was not defined by the enum at the time the code was generated.\n"
+ " **/\n"
+ "int32_t $owning_message_class$_$capitalized_name$_RawValue($owning_message_class$ *message);\n"
+ "/**\n"
+ " * Sets the raw value of an @c $owning_message_class$'s @c $name$ property, allowing\n"
+ " * it to be set to a value that was not defined by the enum at the time the code\n"
+ " * was generated.\n"
+ " **/\n"
+ "void Set$owning_message_class$_$capitalized_name$_RawValue($owning_message_class$ *message, int32_t value);\n"
+ "\n");
+}
+
+void EnumFieldGenerator::GenerateCFunctionImplementations(
+ io::Printer* printer) const {
+ if (!HasPreservingUnknownEnumSemantics(descriptor_->file())) return;
+
+ printer->Print(
+ variables_,
+ "int32_t $owning_message_class$_$capitalized_name$_RawValue($owning_message_class$ *message) {\n"
+ " GPBDescriptor *descriptor = [$owning_message_class$ descriptor];\n"
+ " GPBFieldDescriptor *field = [descriptor fieldWithNumber:$field_number_name$];\n"
+ " return GPBGetMessageRawEnumField(message, field);\n"
+ "}\n"
+ "\n"
+ "void Set$owning_message_class$_$capitalized_name$_RawValue($owning_message_class$ *message, int32_t value) {\n"
+ " GPBDescriptor *descriptor = [$owning_message_class$ descriptor];\n"
+ " GPBFieldDescriptor *field = [descriptor fieldWithNumber:$field_number_name$];\n"
+ " GPBSetMessageRawEnumField(message, field, value);\n"
+ "}\n"
+ "\n");
+}
+
+void EnumFieldGenerator::DetermineForwardDeclarations(
+ std::set<std::string>* fwd_decls) const {
+ SingleFieldGenerator::DetermineForwardDeclarations(fwd_decls);
+ // If it is an enum defined in a different file, then we'll need a forward
+ // declaration for it. When it is in our file, all the enums are output
+ // before the message, so it will be declared before it is needed.
+ if (descriptor_->file() != descriptor_->enum_type()->file()) {
+ // Enum name is already in "storage_type".
+ const std::string& name = variable("storage_type");
+ fwd_decls->insert("GPB_ENUM_FWD_DECLARE(" + name + ")");
+ }
+}
+
+RepeatedEnumFieldGenerator::RepeatedEnumFieldGenerator(
+ const FieldDescriptor* descriptor, const Options& options)
+ : RepeatedFieldGenerator(descriptor, options) {
+ SetEnumVariables(descriptor, &variables_);
+ variables_["array_storage_type"] = "GPBEnumArray";
+}
+
+RepeatedEnumFieldGenerator::~RepeatedEnumFieldGenerator() {}
+
+void RepeatedEnumFieldGenerator::FinishInitialization(void) {
+ RepeatedFieldGenerator::FinishInitialization();
+ variables_["array_comment"] =
+ "// |" + variables_["name"] + "| contains |" + variables_["storage_type"] + "|\n";
+}
+
+} // namespace objectivec
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_enum_field.h b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_enum_field.h
new file mode 100644
index 00000000..1f11abcb
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_enum_field.h
@@ -0,0 +1,80 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_ENUM_FIELD_H__
+#define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_ENUM_FIELD_H__
+
+#include <map>
+#include <string>
+#include <compiler/objectivec/objectivec_field.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace objectivec {
+
+class EnumFieldGenerator : public SingleFieldGenerator {
+ friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field,
+ const Options& options);
+
+ EnumFieldGenerator(const EnumFieldGenerator&) = delete;
+ EnumFieldGenerator& operator=(const EnumFieldGenerator&) = delete;
+
+ public:
+ virtual void GenerateCFunctionDeclarations(
+ io::Printer* printer) const override;
+ virtual void GenerateCFunctionImplementations(
+ io::Printer* printer) const override;
+ virtual void DetermineForwardDeclarations(
+ std::set<std::string>* fwd_decls) const override;
+
+ protected:
+ EnumFieldGenerator(const FieldDescriptor* descriptor, const Options& options);
+ virtual ~EnumFieldGenerator();
+};
+
+class RepeatedEnumFieldGenerator : public RepeatedFieldGenerator {
+ friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field,
+ const Options& options);
+
+ public:
+ virtual void FinishInitialization() override;
+
+ protected:
+ RepeatedEnumFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options);
+ virtual ~RepeatedEnumFieldGenerator();
+};
+
+} // namespace objectivec
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+#endif // GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_ENUM_FIELD_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_extension.cc b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_extension.cc
new file mode 100644
index 00000000..7ec80bc9
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_extension.cc
@@ -0,0 +1,156 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <iostream>
+
+#include <compiler/objectivec/objectivec_extension.h>
+#include <compiler/objectivec/objectivec_helpers.h>
+#include <descriptor.pb.h>
+#include <stubs/strutil.h>
+#include <io/printer.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace objectivec {
+
+ExtensionGenerator::ExtensionGenerator(const std::string& root_class_name,
+ const FieldDescriptor* descriptor)
+ : method_name_(ExtensionMethodName(descriptor)),
+ root_class_and_method_name_(root_class_name + "_" + method_name_),
+ descriptor_(descriptor) {
+ if (descriptor->is_map()) {
+ // NOTE: src/google/protobuf/compiler/plugin.cc makes use of cerr for some
+ // error cases, so it seems to be ok to use as a back door for errors.
+ std::cerr << "error: Extension is a map<>!"
+ << " That used to be blocked by the compiler." << std::endl;
+ std::cerr.flush();
+ abort();
+ }
+}
+
+ExtensionGenerator::~ExtensionGenerator() {}
+
+void ExtensionGenerator::GenerateMembersHeader(io::Printer* printer) {
+ std::map<std::string, std::string> vars;
+ vars["method_name"] = method_name_;
+ if (IsRetainedName(method_name_)) {
+ vars["storage_attribute"] = " NS_RETURNS_NOT_RETAINED";
+ } else {
+ vars["storage_attribute"] = "";
+ }
+ SourceLocation location;
+ if (descriptor_->GetSourceLocation(&location)) {
+ vars["comments"] = BuildCommentsString(location, true);
+ } else {
+ vars["comments"] = "";
+ }
+ // Unlike normal message fields, check if the file for the extension was
+ // deprecated.
+ vars["deprecated_attribute"] = GetOptionalDeprecatedAttribute(descriptor_, descriptor_->file());
+ printer->Print(vars,
+ "$comments$"
+ "+ (GPBExtensionDescriptor *)$method_name$$storage_attribute$$deprecated_attribute$;\n");
+}
+
+void ExtensionGenerator::GenerateStaticVariablesInitialization(
+ io::Printer* printer) {
+ std::map<std::string, std::string> vars;
+ vars["root_class_and_method_name"] = root_class_and_method_name_;
+ const std::string containing_type = ClassName(descriptor_->containing_type());
+ vars["extended_type"] = ObjCClass(containing_type);
+ vars["number"] = StrCat(descriptor_->number());
+
+ std::vector<std::string> options;
+ if (descriptor_->is_repeated()) options.push_back("GPBExtensionRepeated");
+ if (descriptor_->is_packed()) options.push_back("GPBExtensionPacked");
+ if (descriptor_->containing_type()->options().message_set_wire_format()) {
+ options.push_back("GPBExtensionSetWireFormat");
+ }
+ vars["options"] = BuildFlagsString(FLAGTYPE_EXTENSION, options);
+
+ ObjectiveCType objc_type = GetObjectiveCType(descriptor_);
+ if (objc_type == OBJECTIVECTYPE_MESSAGE) {
+ std::string message_type = ClassName(descriptor_->message_type());
+ vars["type"] = ObjCClass(message_type);
+ } else {
+ vars["type"] = "Nil";
+ }
+
+ vars["default_name"] = GPBGenericValueFieldName(descriptor_);
+ if (descriptor_->is_repeated()) {
+ vars["default"] = "nil";
+ } else {
+ vars["default"] = DefaultValue(descriptor_);
+ }
+ std::string type = GetCapitalizedType(descriptor_);
+ vars["extension_type"] = std::string("GPBDataType") + type;
+
+ if (objc_type == OBJECTIVECTYPE_ENUM) {
+ vars["enum_desc_func_name"] =
+ EnumName(descriptor_->enum_type()) + "_EnumDescriptor";
+ } else {
+ vars["enum_desc_func_name"] = "NULL";
+ }
+
+ printer->Print(vars,
+ "{\n"
+ " .defaultValue.$default_name$ = $default$,\n"
+ " .singletonName = GPBStringifySymbol($root_class_and_method_name$),\n"
+ " .extendedClass.clazz = $extended_type$,\n"
+ " .messageOrGroupClass.clazz = $type$,\n"
+ " .enumDescriptorFunc = $enum_desc_func_name$,\n"
+ " .fieldNumber = $number$,\n"
+ " .dataType = $extension_type$,\n"
+ " .options = $options$,\n"
+ "},\n");
+}
+
+void ExtensionGenerator::DetermineObjectiveCClassDefinitions(
+ std::set<std::string>* fwd_decls) {
+ std::string extended_type = ClassName(descriptor_->containing_type());
+ fwd_decls->insert(ObjCClassDeclaration(extended_type));
+ ObjectiveCType objc_type = GetObjectiveCType(descriptor_);
+ if (objc_type == OBJECTIVECTYPE_MESSAGE) {
+ std::string message_type = ClassName(descriptor_->message_type());
+ fwd_decls->insert(ObjCClassDeclaration(message_type));
+ }
+}
+
+void ExtensionGenerator::GenerateRegistrationSource(io::Printer* printer) {
+ printer->Print(
+ "[registry addExtension:$root_class_and_method_name$];\n",
+ "root_class_and_method_name", root_class_and_method_name_);
+}
+
+} // namespace objectivec
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_extension.h b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_extension.h
new file mode 100644
index 00000000..b985d831
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_extension.h
@@ -0,0 +1,67 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_EXTENSION_H__
+#define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_EXTENSION_H__
+
+#include <descriptor.h>
+#include <io/printer.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace objectivec {
+
+class ExtensionGenerator {
+ public:
+ ExtensionGenerator(const std::string& root_class_name,
+ const FieldDescriptor* descriptor);
+ ~ExtensionGenerator();
+
+ ExtensionGenerator(const ExtensionGenerator&) = delete;
+ ExtensionGenerator& operator=(const ExtensionGenerator&) = delete;
+
+ void GenerateMembersHeader(io::Printer* printer);
+ void GenerateStaticVariablesInitialization(io::Printer* printer);
+ void GenerateRegistrationSource(io::Printer* printer);
+ void DetermineObjectiveCClassDefinitions(std::set<std::string>* fwd_decls);
+
+ private:
+ std::string method_name_;
+ std::string root_class_and_method_name_;
+ const FieldDescriptor* descriptor_;
+};
+
+} // namespace objectivec
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_MESSAGE_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_field.cc b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_field.cc
new file mode 100644
index 00000000..29f434b5
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_field.cc
@@ -0,0 +1,475 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 <iostream>
+
+#include <compiler/objectivec/objectivec_field.h>
+#include <compiler/objectivec/objectivec_helpers.h>
+#include <compiler/objectivec/objectivec_enum_field.h>
+#include <compiler/objectivec/objectivec_map_field.h>
+#include <compiler/objectivec/objectivec_message_field.h>
+#include <compiler/objectivec/objectivec_primitive_field.h>
+#include <io/printer.h>
+#include <wire_format.h>
+#include <stubs/strutil.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace objectivec {
+
+namespace {
+
+void SetCommonFieldVariables(const FieldDescriptor* descriptor,
+ std::map<std::string, std::string>* variables) {
+ std::string camel_case_name = FieldName(descriptor);
+ std::string raw_field_name;
+ if (descriptor->type() == FieldDescriptor::TYPE_GROUP) {
+ raw_field_name = descriptor->message_type()->name();
+ } else {
+ raw_field_name = descriptor->name();
+ }
+ // The logic here has to match -[GGPBFieldDescriptor textFormatName].
+ const std::string un_camel_case_name(
+ UnCamelCaseFieldName(camel_case_name, descriptor));
+ const bool needs_custom_name = (raw_field_name != un_camel_case_name);
+
+ SourceLocation location;
+ if (descriptor->GetSourceLocation(&location)) {
+ (*variables)["comments"] = BuildCommentsString(location, true);
+ } else {
+ (*variables)["comments"] = "\n";
+ }
+ const std::string& classname = ClassName(descriptor->containing_type());
+ (*variables)["classname"] = classname;
+ (*variables)["name"] = camel_case_name;
+ const std::string& capitalized_name = FieldNameCapitalized(descriptor);
+ (*variables)["capitalized_name"] = capitalized_name;
+ (*variables)["raw_field_name"] = raw_field_name;
+ (*variables)["field_number_name"] =
+ classname + "_FieldNumber_" + capitalized_name;
+ (*variables)["field_number"] = StrCat(descriptor->number());
+ (*variables)["field_type"] = GetCapitalizedType(descriptor);
+ (*variables)["deprecated_attribute"] = GetOptionalDeprecatedAttribute(descriptor);
+ std::vector<std::string> field_flags;
+ if (descriptor->is_repeated()) field_flags.push_back("GPBFieldRepeated");
+ if (descriptor->is_required()) field_flags.push_back("GPBFieldRequired");
+ if (descriptor->is_optional()) field_flags.push_back("GPBFieldOptional");
+ if (descriptor->is_packed()) field_flags.push_back("GPBFieldPacked");
+
+ // ObjC custom flags.
+ if (descriptor->has_default_value())
+ field_flags.push_back("GPBFieldHasDefaultValue");
+ if (needs_custom_name) field_flags.push_back("GPBFieldTextFormatNameCustom");
+ if (descriptor->type() == FieldDescriptor::TYPE_ENUM) {
+ field_flags.push_back("GPBFieldHasEnumDescriptor");
+ }
+ // It will clear on a zero value if...
+ // - not repeated/map
+ // - doesn't have presence
+ bool clear_on_zero =
+ (!descriptor->is_repeated() && !descriptor->has_presence());
+ if (clear_on_zero) {
+ field_flags.push_back("GPBFieldClearHasIvarOnZero");
+ }
+
+ (*variables)["fieldflags"] = BuildFlagsString(FLAGTYPE_FIELD, field_flags);
+
+ (*variables)["default"] = DefaultValue(descriptor);
+ (*variables)["default_name"] = GPBGenericValueFieldName(descriptor);
+
+ (*variables)["dataTypeSpecific_name"] = "clazz";
+ (*variables)["dataTypeSpecific_value"] = "Nil";
+
+ (*variables)["storage_offset_value"] =
+ "(uint32_t)offsetof(" + classname + "__storage_, " + camel_case_name + ")";
+ (*variables)["storage_offset_comment"] = "";
+
+ // Clear some common things so they can be set just when needed.
+ (*variables)["storage_attribute"] = "";
+}
+
+} // namespace
+
+FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field,
+ const Options& options) {
+ FieldGenerator* result = NULL;
+ if (field->is_repeated()) {
+ switch (GetObjectiveCType(field)) {
+ case OBJECTIVECTYPE_MESSAGE: {
+ if (field->is_map()) {
+ result = new MapFieldGenerator(field, options);
+ } else {
+ result = new RepeatedMessageFieldGenerator(field, options);
+ }
+ break;
+ }
+ case OBJECTIVECTYPE_ENUM:
+ result = new RepeatedEnumFieldGenerator(field, options);
+ break;
+ default:
+ result = new RepeatedPrimitiveFieldGenerator(field, options);
+ break;
+ }
+ } else {
+ switch (GetObjectiveCType(field)) {
+ case OBJECTIVECTYPE_MESSAGE: {
+ result = new MessageFieldGenerator(field, options);
+ break;
+ }
+ case OBJECTIVECTYPE_ENUM:
+ result = new EnumFieldGenerator(field, options);
+ break;
+ default:
+ if (IsReferenceType(field)) {
+ result = new PrimitiveObjFieldGenerator(field, options);
+ } else {
+ result = new PrimitiveFieldGenerator(field, options);
+ }
+ break;
+ }
+ }
+ result->FinishInitialization();
+ return result;
+}
+
+FieldGenerator::FieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options)
+ : descriptor_(descriptor) {
+ SetCommonFieldVariables(descriptor, &variables_);
+}
+
+FieldGenerator::~FieldGenerator() {}
+
+void FieldGenerator::GenerateFieldNumberConstant(io::Printer* printer) const {
+ printer->Print(
+ variables_,
+ "$field_number_name$ = $field_number$,\n");
+}
+
+void FieldGenerator::GenerateCFunctionDeclarations(
+ io::Printer* printer) const {
+ // Nothing
+}
+
+void FieldGenerator::GenerateCFunctionImplementations(
+ io::Printer* printer) const {
+ // Nothing
+}
+
+void FieldGenerator::DetermineForwardDeclarations(
+ std::set<std::string>* fwd_decls) const {
+ // Nothing
+}
+
+void FieldGenerator::DetermineObjectiveCClassDefinitions(
+ std::set<std::string>* fwd_decls) const {
+ // Nothing
+}
+
+void FieldGenerator::GenerateFieldDescription(
+ io::Printer* printer, bool include_default) const {
+ // Printed in the same order as the structure decl.
+ if (include_default) {
+ printer->Print(
+ variables_,
+ "{\n"
+ " .defaultValue.$default_name$ = $default$,\n"
+ " .core.name = \"$name$\",\n"
+ " .core.dataTypeSpecific.$dataTypeSpecific_name$ = $dataTypeSpecific_value$,\n"
+ " .core.number = $field_number_name$,\n"
+ " .core.hasIndex = $has_index$,\n"
+ " .core.offset = $storage_offset_value$,$storage_offset_comment$\n"
+ " .core.flags = $fieldflags$,\n"
+ " .core.dataType = GPBDataType$field_type$,\n"
+ "},\n");
+ } else {
+ printer->Print(
+ variables_,
+ "{\n"
+ " .name = \"$name$\",\n"
+ " .dataTypeSpecific.$dataTypeSpecific_name$ = $dataTypeSpecific_value$,\n"
+ " .number = $field_number_name$,\n"
+ " .hasIndex = $has_index$,\n"
+ " .offset = $storage_offset_value$,$storage_offset_comment$\n"
+ " .flags = $fieldflags$,\n"
+ " .dataType = GPBDataType$field_type$,\n"
+ "},\n");
+ }
+}
+
+void FieldGenerator::SetRuntimeHasBit(int has_index) {
+ variables_["has_index"] = StrCat(has_index);
+}
+
+void FieldGenerator::SetNoHasBit(void) {
+ variables_["has_index"] = "GPBNoHasBit";
+}
+
+int FieldGenerator::ExtraRuntimeHasBitsNeeded(void) const {
+ return 0;
+}
+
+void FieldGenerator::SetExtraRuntimeHasBitsBase(int index_base) {
+ // NOTE: src/google/protobuf/compiler/plugin.cc makes use of cerr for some
+ // error cases, so it seems to be ok to use as a back door for errors.
+ std::cerr << "Error: should have overridden SetExtraRuntimeHasBitsBase()." << std::endl;
+ std::cerr.flush();
+ abort();
+}
+
+void FieldGenerator::SetOneofIndexBase(int index_base) {
+ const OneofDescriptor* oneof = descriptor_->real_containing_oneof();
+ if (oneof != NULL) {
+ int index = oneof->index() + index_base;
+ // Flip the sign to mark it as a oneof.
+ variables_["has_index"] = StrCat(-index);
+ }
+}
+
+bool FieldGenerator::WantsHasProperty(void) const {
+ return descriptor_->has_presence() && !descriptor_->real_containing_oneof();
+}
+
+void FieldGenerator::FinishInitialization(void) {
+ // If "property_type" wasn't set, make it "storage_type".
+ if ((variables_.find("property_type") == variables_.end()) &&
+ (variables_.find("storage_type") != variables_.end())) {
+ variables_["property_type"] = variable("storage_type");
+ }
+}
+
+SingleFieldGenerator::SingleFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options)
+ : FieldGenerator(descriptor, options) {
+ // Nothing
+}
+
+SingleFieldGenerator::~SingleFieldGenerator() {}
+
+void SingleFieldGenerator::GenerateFieldStorageDeclaration(
+ io::Printer* printer) const {
+ printer->Print(variables_, "$storage_type$ $name$;\n");
+}
+
+void SingleFieldGenerator::GeneratePropertyDeclaration(
+ io::Printer* printer) const {
+ printer->Print(variables_, "$comments$");
+ printer->Print(
+ variables_,
+ "@property(nonatomic, readwrite) $property_type$ $name$$deprecated_attribute$;\n"
+ "\n");
+ if (WantsHasProperty()) {
+ printer->Print(
+ variables_,
+ "@property(nonatomic, readwrite) BOOL has$capitalized_name$$deprecated_attribute$;\n");
+ }
+}
+
+void SingleFieldGenerator::GeneratePropertyImplementation(
+ io::Printer* printer) const {
+ if (WantsHasProperty()) {
+ printer->Print(variables_, "@dynamic has$capitalized_name$, $name$;\n");
+ } else {
+ printer->Print(variables_, "@dynamic $name$;\n");
+ }
+}
+
+bool SingleFieldGenerator::RuntimeUsesHasBit(void) const {
+ if (descriptor_->real_containing_oneof()) {
+ // The oneof tracks what is set instead.
+ return false;
+ }
+ return true;
+}
+
+ObjCObjFieldGenerator::ObjCObjFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options)
+ : SingleFieldGenerator(descriptor, options) {
+ variables_["property_storage_attribute"] = "strong";
+ if (IsRetainedName(variables_["name"])) {
+ variables_["storage_attribute"] = " NS_RETURNS_NOT_RETAINED";
+ }
+}
+
+ObjCObjFieldGenerator::~ObjCObjFieldGenerator() {}
+
+void ObjCObjFieldGenerator::GenerateFieldStorageDeclaration(
+ io::Printer* printer) const {
+ printer->Print(variables_, "$storage_type$ *$name$;\n");
+}
+
+void ObjCObjFieldGenerator::GeneratePropertyDeclaration(
+ io::Printer* printer) const {
+
+ // Differs from SingleFieldGenerator::GeneratePropertyDeclaration() in that
+ // it uses pointers and deals with Objective C's rules around storage name
+ // conventions (init*, new*, etc.)
+
+ printer->Print(variables_, "$comments$");
+ printer->Print(
+ variables_,
+ "@property(nonatomic, readwrite, $property_storage_attribute$, null_resettable) $property_type$ *$name$$storage_attribute$$deprecated_attribute$;\n");
+ if (WantsHasProperty()) {
+ printer->Print(
+ variables_,
+ "/** Test to see if @c $name$ has been set. */\n"
+ "@property(nonatomic, readwrite) BOOL has$capitalized_name$$deprecated_attribute$;\n");
+ }
+ if (IsInitName(variables_.find("name")->second)) {
+ // If property name starts with init we need to annotate it to get past ARC.
+ // http://stackoverflow.com/questions/18723226/how-do-i-annotate-an-objective-c-property-with-an-objc-method-family/18723227#18723227
+ printer->Print(variables_,
+ "- ($property_type$ *)$name$ GPB_METHOD_FAMILY_NONE$deprecated_attribute$;\n");
+ }
+ printer->Print("\n");
+}
+
+RepeatedFieldGenerator::RepeatedFieldGenerator(
+ const FieldDescriptor* descriptor, const Options& options)
+ : ObjCObjFieldGenerator(descriptor, options) {
+ // Default to no comment and let the cases needing it fill it in.
+ variables_["array_comment"] = "";
+}
+
+RepeatedFieldGenerator::~RepeatedFieldGenerator() {}
+
+void RepeatedFieldGenerator::FinishInitialization(void) {
+ FieldGenerator::FinishInitialization();
+ if (variables_.find("array_property_type") == variables_.end()) {
+ variables_["array_property_type"] = variable("array_storage_type");
+ }
+}
+
+void RepeatedFieldGenerator::GenerateFieldStorageDeclaration(
+ io::Printer* printer) const {
+ printer->Print(variables_, "$array_storage_type$ *$name$;\n");
+}
+
+void RepeatedFieldGenerator::GeneratePropertyImplementation(
+ io::Printer* printer) const {
+ printer->Print(variables_, "@dynamic $name$, $name$_Count;\n");
+}
+
+void RepeatedFieldGenerator::GeneratePropertyDeclaration(
+ io::Printer* printer) const {
+
+ // Repeated fields don't need the has* properties, but they do expose a
+ // *Count (to check without autocreation). So for the field property we need
+ // the same logic as ObjCObjFieldGenerator::GeneratePropertyDeclaration() for
+ // dealing with needing Objective C's rules around storage name conventions
+ // (init*, new*, etc.)
+
+ printer->Print(
+ variables_,
+ "$comments$"
+ "$array_comment$"
+ "@property(nonatomic, readwrite, strong, null_resettable) $array_property_type$ *$name$$storage_attribute$$deprecated_attribute$;\n"
+ "/** The number of items in @c $name$ without causing the array to be created. */\n"
+ "@property(nonatomic, readonly) NSUInteger $name$_Count$deprecated_attribute$;\n");
+ if (IsInitName(variables_.find("name")->second)) {
+ // If property name starts with init we need to annotate it to get past ARC.
+ // http://stackoverflow.com/questions/18723226/how-do-i-annotate-an-objective-c-property-with-an-objc-method-family/18723227#18723227
+ printer->Print(variables_,
+ "- ($array_property_type$ *)$name$ GPB_METHOD_FAMILY_NONE$deprecated_attribute$;\n");
+ }
+ printer->Print("\n");
+}
+
+bool RepeatedFieldGenerator::RuntimeUsesHasBit(void) const {
+ return false; // The array (or map/dict) having anything is what is used.
+}
+
+FieldGeneratorMap::FieldGeneratorMap(const Descriptor* descriptor,
+ const Options& options)
+ : descriptor_(descriptor),
+ field_generators_(descriptor->field_count()),
+ extension_generators_(descriptor->extension_count()) {
+ // Construct all the FieldGenerators.
+ for (int i = 0; i < descriptor->field_count(); i++) {
+ field_generators_[i].reset(
+ FieldGenerator::Make(descriptor->field(i), options));
+ }
+ for (int i = 0; i < descriptor->extension_count(); i++) {
+ extension_generators_[i].reset(
+ FieldGenerator::Make(descriptor->extension(i), options));
+ }
+}
+
+FieldGeneratorMap::~FieldGeneratorMap() {}
+
+const FieldGenerator& FieldGeneratorMap::get(
+ const FieldDescriptor* field) const {
+ GOOGLE_CHECK_EQ(field->containing_type(), descriptor_);
+ return *field_generators_[field->index()];
+}
+
+const FieldGenerator& FieldGeneratorMap::get_extension(int index) const {
+ return *extension_generators_[index];
+}
+
+int FieldGeneratorMap::CalculateHasBits(void) {
+ int total_bits = 0;
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ if (field_generators_[i]->RuntimeUsesHasBit()) {
+ field_generators_[i]->SetRuntimeHasBit(total_bits);
+ ++total_bits;
+ } else {
+ field_generators_[i]->SetNoHasBit();
+ }
+ int extra_bits = field_generators_[i]->ExtraRuntimeHasBitsNeeded();
+ if (extra_bits) {
+ field_generators_[i]->SetExtraRuntimeHasBitsBase(total_bits);
+ total_bits += extra_bits;
+ }
+ }
+ return total_bits;
+}
+
+void FieldGeneratorMap::SetOneofIndexBase(int index_base) {
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ field_generators_[i]->SetOneofIndexBase(index_base);
+ }
+}
+
+bool FieldGeneratorMap::DoesAnyFieldHaveNonZeroDefault(void) const {
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ if (HasNonZeroDefaultValue(descriptor_->field(i))) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+} // namespace objectivec
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_field.h b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_field.h
new file mode 100644
index 00000000..ee213ff4
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_field.h
@@ -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.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_FIELD_H__
+#define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_FIELD_H__
+
+#include <map>
+#include <string>
+#include <compiler/objectivec/objectivec_helpers.h>
+#include <descriptor.h>
+#include <io/printer.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace objectivec {
+
+class FieldGenerator {
+ public:
+ static FieldGenerator* Make(const FieldDescriptor* field,
+ const Options& options);
+
+ virtual ~FieldGenerator();
+
+ FieldGenerator(const FieldGenerator&) = delete;
+ FieldGenerator& operator=(const FieldGenerator&) = delete;
+
+ // Exposed for subclasses to fill in.
+ virtual void GenerateFieldStorageDeclaration(io::Printer* printer) const = 0;
+ virtual void GeneratePropertyDeclaration(io::Printer* printer) const = 0;
+ virtual void GeneratePropertyImplementation(io::Printer* printer) const = 0;
+
+ // Called by GenerateFieldDescription, exposed for classes that need custom
+ // generation.
+
+ // Exposed for subclasses to extend, base does nothing.
+ virtual void GenerateCFunctionDeclarations(io::Printer* printer) const;
+ virtual void GenerateCFunctionImplementations(io::Printer* printer) const;
+
+ // Exposed for subclasses, should always call it on the parent class also.
+ virtual void DetermineForwardDeclarations(
+ std::set<std::string>* fwd_decls) const;
+ virtual void DetermineObjectiveCClassDefinitions(
+ std::set<std::string>* fwd_decls) const;
+
+ // Used during generation, not intended to be extended by subclasses.
+ void GenerateFieldDescription(
+ io::Printer* printer, bool include_default) const;
+ void GenerateFieldNumberConstant(io::Printer* printer) const;
+
+ // Exposed to get and set the has bits information.
+ virtual bool RuntimeUsesHasBit(void) const = 0;
+ void SetRuntimeHasBit(int has_index);
+ void SetNoHasBit(void);
+ virtual int ExtraRuntimeHasBitsNeeded(void) const;
+ virtual void SetExtraRuntimeHasBitsBase(int index_base);
+ void SetOneofIndexBase(int index_base);
+
+ std::string variable(const char* key) const {
+ return variables_.find(key)->second;
+ }
+
+ bool needs_textformat_name_support() const {
+ const std::string& field_flags = variable("fieldflags");
+ return field_flags.find("GPBFieldTextFormatNameCustom") !=
+ std::string::npos;
+ }
+ std::string generated_objc_name() const { return variable("name"); }
+ std::string raw_field_name() const { return variable("raw_field_name"); }
+
+ protected:
+ FieldGenerator(const FieldDescriptor* descriptor, const Options& options);
+
+ virtual void FinishInitialization(void);
+ bool WantsHasProperty(void) const;
+
+ const FieldDescriptor* descriptor_;
+ std::map<std::string, std::string> variables_;
+};
+
+class SingleFieldGenerator : public FieldGenerator {
+ public:
+ virtual ~SingleFieldGenerator();
+
+ SingleFieldGenerator(const SingleFieldGenerator&) = delete;
+ SingleFieldGenerator& operator=(const SingleFieldGenerator&) = delete;
+
+ virtual void GenerateFieldStorageDeclaration(io::Printer* printer) const override;
+ virtual void GeneratePropertyDeclaration(io::Printer* printer) const override;
+
+ virtual void GeneratePropertyImplementation(io::Printer* printer) const override;
+
+ virtual bool RuntimeUsesHasBit(void) const override;
+
+ protected:
+ SingleFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options);
+};
+
+// Subclass with common support for when the field ends up as an ObjC Object.
+class ObjCObjFieldGenerator : public SingleFieldGenerator {
+ public:
+ virtual ~ObjCObjFieldGenerator();
+
+ ObjCObjFieldGenerator(const ObjCObjFieldGenerator&) = delete;
+ ObjCObjFieldGenerator& operator=(const ObjCObjFieldGenerator&) = delete;
+
+ virtual void GenerateFieldStorageDeclaration(io::Printer* printer) const override;
+ virtual void GeneratePropertyDeclaration(io::Printer* printer) const override;
+
+ protected:
+ ObjCObjFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options);
+};
+
+class RepeatedFieldGenerator : public ObjCObjFieldGenerator {
+ public:
+ virtual ~RepeatedFieldGenerator();
+
+ RepeatedFieldGenerator(const RepeatedFieldGenerator&) = delete;
+ RepeatedFieldGenerator& operator=(const RepeatedFieldGenerator&) = delete;
+
+ virtual void GenerateFieldStorageDeclaration(io::Printer* printer) const override;
+ virtual void GeneratePropertyDeclaration(io::Printer* printer) const override;
+
+ virtual void GeneratePropertyImplementation(io::Printer* printer) const override;
+
+ virtual bool RuntimeUsesHasBit(void) const override;
+
+ protected:
+ RepeatedFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options);
+ virtual void FinishInitialization(void) override;
+};
+
+// Convenience class which constructs FieldGenerators for a Descriptor.
+class FieldGeneratorMap {
+ public:
+ FieldGeneratorMap(const Descriptor* descriptor, const Options& options);
+ ~FieldGeneratorMap();
+
+ FieldGeneratorMap(const FieldGeneratorMap&) = delete;
+ FieldGeneratorMap& operator=(const FieldGeneratorMap&) = delete;
+
+ const FieldGenerator& get(const FieldDescriptor* field) const;
+ const FieldGenerator& get_extension(int index) const;
+
+ // Assigns the has bits and returns the number of bits needed.
+ int CalculateHasBits(void);
+
+ void SetOneofIndexBase(int index_base);
+
+ // Check if any field of this message has a non zero default.
+ bool DoesAnyFieldHaveNonZeroDefault(void) const;
+
+ private:
+ const Descriptor* descriptor_;
+ std::vector<std::unique_ptr<FieldGenerator>> field_generators_;
+ std::vector<std::unique_ptr<FieldGenerator>> extension_generators_;
+};
+
+} // namespace objectivec
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_FIELD_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_file.cc b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_file.cc
new file mode 100644
index 00000000..e98a8985
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_file.cc
@@ -0,0 +1,610 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 <compiler/objectivec/objectivec_file.h>
+#include <compiler/objectivec/objectivec_enum.h>
+#include <compiler/objectivec/objectivec_extension.h>
+#include <compiler/objectivec/objectivec_message.h>
+#include <compiler/code_generator.h>
+#include <io/printer.h>
+#include <io/zero_copy_stream_impl.h>
+#include <stubs/stl_util.h>
+#include <stubs/strutil.h>
+#include <algorithm> // std::find()
+#include <iostream>
+#include <sstream>
+
+// NOTE: src/google/protobuf/compiler/plugin.cc makes use of cerr for some
+// error cases, so it seems to be ok to use as a back door for errors.
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace objectivec {
+
+namespace {
+
+// This is also found in GPBBootstrap.h, and needs to be kept in sync.
+const int32_t GOOGLE_PROTOBUF_OBJC_VERSION = 30004;
+
+const char* kHeaderExtension = ".pbobjc.h";
+
+// Checks if a message contains any enums definitions (on the message or
+// a nested message under it).
+bool MessageContainsEnums(const Descriptor* message) {
+ if (message->enum_type_count() > 0) {
+ return true;
+ }
+ for (int i = 0; i < message->nested_type_count(); i++) {
+ if (MessageContainsEnums(message->nested_type(i))) {
+ return true;
+ }
+ }
+ return false;
+}
+
+// Checks if a message contains any extension definitions (on the message or
+// a nested message under it).
+bool MessageContainsExtensions(const Descriptor* message) {
+ if (message->extension_count() > 0) {
+ return true;
+ }
+ for (int i = 0; i < message->nested_type_count(); i++) {
+ if (MessageContainsExtensions(message->nested_type(i))) {
+ return true;
+ }
+ }
+ return false;
+}
+
+// Checks if the file contains any enum definitions (at the root or
+// nested under a message).
+bool FileContainsEnums(const FileDescriptor* file) {
+ if (file->enum_type_count() > 0) {
+ return true;
+ }
+ for (int i = 0; i < file->message_type_count(); i++) {
+ if (MessageContainsEnums(file->message_type(i))) {
+ return true;
+ }
+ }
+ return false;
+}
+
+// Checks if the file contains any extensions definitions (at the root or
+// nested under a message).
+bool FileContainsExtensions(const FileDescriptor* file) {
+ if (file->extension_count() > 0) {
+ return true;
+ }
+ for (int i = 0; i < file->message_type_count(); i++) {
+ if (MessageContainsExtensions(file->message_type(i))) {
+ return true;
+ }
+ }
+ return false;
+}
+
+// Helper for CollectMinimalFileDepsContainingExtensionsWorker that marks all
+// deps as visited and prunes them from the needed files list.
+void PruneFileAndDepsMarkingAsVisited(
+ const FileDescriptor* file,
+ std::vector<const FileDescriptor*>* files,
+ std::set<const FileDescriptor*>* files_visited) {
+ std::vector<const FileDescriptor*>::iterator iter =
+ std::find(files->begin(), files->end(), file);
+ if (iter != files->end()) {
+ files->erase(iter);
+ }
+ files_visited->insert(file);
+ for (int i = 0; i < file->dependency_count(); i++) {
+ PruneFileAndDepsMarkingAsVisited(file->dependency(i), files, files_visited);
+ }
+}
+
+// Helper for CollectMinimalFileDepsContainingExtensions.
+void CollectMinimalFileDepsContainingExtensionsWorker(
+ const FileDescriptor* file,
+ std::vector<const FileDescriptor*>* files,
+ std::set<const FileDescriptor*>* files_visited) {
+ if (files_visited->find(file) != files_visited->end()) {
+ return;
+ }
+ files_visited->insert(file);
+
+ if (FileContainsExtensions(file)) {
+ files->push_back(file);
+ for (int i = 0; i < file->dependency_count(); i++) {
+ const FileDescriptor* dep = file->dependency(i);
+ PruneFileAndDepsMarkingAsVisited(dep, files, files_visited);
+ }
+ } else {
+ for (int i = 0; i < file->dependency_count(); i++) {
+ const FileDescriptor* dep = file->dependency(i);
+ CollectMinimalFileDepsContainingExtensionsWorker(dep, files,
+ files_visited);
+ }
+ }
+}
+
+// Collect the deps of the given file that contain extensions. This can be used to
+// create the chain of roots that need to be wired together.
+//
+// NOTE: If any changes are made to this and the supporting functions, you will
+// need to manually validate what the generated code is for the test files:
+// objectivec/Tests/unittest_extension_chain_*.proto
+// There are comments about what the expected code should be line and limited
+// testing objectivec/Tests/GPBUnittestProtos2.m around compilation (#imports
+// specifically).
+void CollectMinimalFileDepsContainingExtensions(
+ const FileDescriptor* file,
+ std::vector<const FileDescriptor*>* files) {
+ std::set<const FileDescriptor*> files_visited;
+ for (int i = 0; i < file->dependency_count(); i++) {
+ const FileDescriptor* dep = file->dependency(i);
+ CollectMinimalFileDepsContainingExtensionsWorker(dep, files,
+ &files_visited);
+ }
+}
+
+bool IsDirectDependency(const FileDescriptor* dep, const FileDescriptor* file) {
+ for (int i = 0; i < file->dependency_count(); i++) {
+ if (dep == file->dependency(i)) {
+ return true;
+ }
+ }
+ return false;
+}
+
+} // namespace
+
+FileGenerator::FileGenerator(const FileDescriptor* file, const Options& options)
+ : file_(file),
+ root_class_name_(FileClassName(file)),
+ is_bundled_proto_(IsProtobufLibraryBundledProtoFile(file)),
+ options_(options) {
+ for (int i = 0; i < file_->enum_type_count(); i++) {
+ EnumGenerator* generator = new EnumGenerator(file_->enum_type(i));
+ enum_generators_.emplace_back(generator);
+ }
+ for (int i = 0; i < file_->message_type_count(); i++) {
+ MessageGenerator* generator =
+ new MessageGenerator(root_class_name_, file_->message_type(i), options_);
+ message_generators_.emplace_back(generator);
+ }
+ for (int i = 0; i < file_->extension_count(); i++) {
+ ExtensionGenerator* generator =
+ new ExtensionGenerator(root_class_name_, file_->extension(i));
+ extension_generators_.emplace_back(generator);
+ }
+}
+
+FileGenerator::~FileGenerator() {}
+
+void FileGenerator::GenerateHeader(io::Printer* printer) {
+ std::vector<std::string> headers;
+ // Generated files bundled with the library get minimal imports, everything
+ // else gets the wrapper so everything is usable.
+ if (is_bundled_proto_) {
+ headers.push_back("GPBDescriptor.h");
+ headers.push_back("GPBMessage.h");
+ headers.push_back("GPBRootObject.h");
+ } else {
+ headers.push_back("GPBProtocolBuffers.h");
+ }
+ PrintFileRuntimePreamble(printer, headers);
+
+ // Add some verification that the generated code matches the source the
+ // code is being compiled with.
+ // NOTE: This captures the raw numeric values at the time the generator was
+ // compiled, since that will be the versions for the ObjC runtime at that
+ // time. The constants in the generated code will then get their values at
+ // at compile time (so checking against the headers being used to compile).
+ printer->Print(
+ "#if GOOGLE_PROTOBUF_OBJC_VERSION < $google_protobuf_objc_version$\n"
+ "#error This file was generated by a newer version of protoc which is incompatible with your Protocol Buffer library sources.\n"
+ "#endif\n"
+ "#if $google_protobuf_objc_version$ < GOOGLE_PROTOBUF_OBJC_MIN_SUPPORTED_VERSION\n"
+ "#error This file was generated by an older version of protoc which is incompatible with your Protocol Buffer library sources.\n"
+ "#endif\n"
+ "\n",
+ "google_protobuf_objc_version", StrCat(GOOGLE_PROTOBUF_OBJC_VERSION));
+
+ // #import any headers for "public imports" in the proto file.
+ {
+ ImportWriter import_writer(
+ options_.generate_for_named_framework,
+ options_.named_framework_to_proto_path_mappings_path,
+ options_.runtime_import_prefix,
+ is_bundled_proto_);
+ const std::string header_extension(kHeaderExtension);
+ for (int i = 0; i < file_->public_dependency_count(); i++) {
+ import_writer.AddFile(file_->public_dependency(i), header_extension);
+ }
+ import_writer.Print(printer);
+ }
+
+ // Note:
+ // deprecated-declarations suppression is only needed if some place in this
+ // proto file is something deprecated or if it references something from
+ // another file that is deprecated.
+ printer->Print(
+ "// @@protoc_insertion_point(imports)\n"
+ "\n"
+ "#pragma clang diagnostic push\n"
+ "#pragma clang diagnostic ignored \"-Wdeprecated-declarations\"\n"
+ "\n"
+ "CF_EXTERN_C_BEGIN\n"
+ "\n");
+
+ std::set<std::string> fwd_decls;
+ for (const auto& generator : message_generators_) {
+ generator->DetermineForwardDeclarations(&fwd_decls);
+ }
+ for (std::set<std::string>::const_iterator i(fwd_decls.begin());
+ i != fwd_decls.end(); ++i) {
+ printer->Print("$value$;\n", "value", *i);
+ }
+ if (fwd_decls.begin() != fwd_decls.end()) {
+ printer->Print("\n");
+ }
+
+ printer->Print(
+ "NS_ASSUME_NONNULL_BEGIN\n"
+ "\n");
+
+ // need to write out all enums first
+ for (const auto& generator : enum_generators_) {
+ generator->GenerateHeader(printer);
+ }
+
+ for (const auto& generator : message_generators_) {
+ generator->GenerateEnumHeader(printer);
+ }
+
+ // For extensions to chain together, the Root gets created even if there
+ // are no extensions.
+ printer->Print(
+ "#pragma mark - $root_class_name$\n"
+ "\n"
+ "/**\n"
+ " * Exposes the extension registry for this file.\n"
+ " *\n"
+ " * The base class provides:\n"
+ " * @code\n"
+ " * + (GPBExtensionRegistry *)extensionRegistry;\n"
+ " * @endcode\n"
+ " * which is a @c GPBExtensionRegistry that includes all the extensions defined by\n"
+ " * this file and all files that it depends on.\n"
+ " **/\n"
+ "GPB_FINAL @interface $root_class_name$ : GPBRootObject\n"
+ "@end\n"
+ "\n",
+ "root_class_name", root_class_name_);
+
+ if (!extension_generators_.empty()) {
+ // The dynamic methods block is only needed if there are extensions.
+ printer->Print(
+ "@interface $root_class_name$ (DynamicMethods)\n",
+ "root_class_name", root_class_name_);
+
+ for (const auto& generator : extension_generators_) {
+ generator->GenerateMembersHeader(printer);
+ }
+
+ printer->Print("@end\n\n");
+ } // !extension_generators_.empty()
+
+ for (const auto& generator : message_generators_) {
+ generator->GenerateMessageHeader(printer);
+ }
+
+ printer->Print(
+ "NS_ASSUME_NONNULL_END\n"
+ "\n"
+ "CF_EXTERN_C_END\n"
+ "\n"
+ "#pragma clang diagnostic pop\n"
+ "\n"
+ "// @@protoc_insertion_point(global_scope)\n");
+}
+
+void FileGenerator::GenerateSource(io::Printer* printer) {
+ // #import the runtime support.
+ std::vector<std::string> headers;
+ headers.push_back("GPBProtocolBuffers_RuntimeSupport.h");
+ PrintFileRuntimePreamble(printer, headers);
+
+ // Enums use atomic in the generated code, so add the system import as needed.
+ if (FileContainsEnums(file_)) {
+ printer->Print(
+ "#import <stdatomic.h>\n"
+ "\n");
+ }
+
+ std::vector<const FileDescriptor*> deps_with_extensions;
+ CollectMinimalFileDepsContainingExtensions(file_, &deps_with_extensions);
+
+ {
+ ImportWriter import_writer(
+ options_.generate_for_named_framework,
+ options_.named_framework_to_proto_path_mappings_path,
+ options_.runtime_import_prefix,
+ is_bundled_proto_);
+ const std::string header_extension(kHeaderExtension);
+
+ // #import the header for this proto file.
+ import_writer.AddFile(file_, header_extension);
+
+ // #import the headers for anything that a plain dependency of this proto
+ // file (that means they were just an include, not a "public" include).
+ std::set<std::string> public_import_names;
+ for (int i = 0; i < file_->public_dependency_count(); i++) {
+ public_import_names.insert(file_->public_dependency(i)->name());
+ }
+ for (int i = 0; i < file_->dependency_count(); i++) {
+ const FileDescriptor *dep = file_->dependency(i);
+ bool public_import = (public_import_names.count(dep->name()) != 0);
+ if (!public_import) {
+ import_writer.AddFile(dep, header_extension);
+ }
+ }
+
+ // If any indirect dependency provided extensions, it needs to be directly
+ // imported so it can get merged into the root's extensions registry.
+ // See the Note by CollectMinimalFileDepsContainingExtensions before
+ // changing this.
+ for (std::vector<const FileDescriptor*>::iterator iter =
+ deps_with_extensions.begin();
+ iter != deps_with_extensions.end(); ++iter) {
+ if (!IsDirectDependency(*iter, file_)) {
+ import_writer.AddFile(*iter, header_extension);
+ }
+ }
+
+ import_writer.Print(printer);
+ }
+
+ bool includes_oneof = false;
+ for (const auto& generator : message_generators_) {
+ if (generator->IncludesOneOfDefinition()) {
+ includes_oneof = true;
+ break;
+ }
+ }
+
+ std::set<std::string> fwd_decls;
+ for (const auto& generator : message_generators_) {
+ generator->DetermineObjectiveCClassDefinitions(&fwd_decls);
+ }
+ for (const auto& generator : extension_generators_) {
+ generator->DetermineObjectiveCClassDefinitions(&fwd_decls);
+ }
+
+ // Note:
+ // deprecated-declarations suppression is only needed if some place in this
+ // proto file is something deprecated or if it references something from
+ // another file that is deprecated.
+ // dollar-in-identifier-extension is needed because we use references to
+ // objc class names that have $ in identifiers.
+ printer->Print(
+ "// @@protoc_insertion_point(imports)\n"
+ "\n"
+ "#pragma clang diagnostic push\n"
+ "#pragma clang diagnostic ignored \"-Wdeprecated-declarations\"\n");
+ if (includes_oneof) {
+ // The generated code for oneof's uses direct ivar access, suppress the
+ // warning in case developer turn that on in the context they compile the
+ // generated code.
+ printer->Print(
+ "#pragma clang diagnostic ignored \"-Wdirect-ivar-access\"\n");
+ }
+ if (!fwd_decls.empty()) {
+ printer->Print(
+ "#pragma clang diagnostic ignored \"-Wdollar-in-identifier-extension\"\n");
+ }
+ printer->Print(
+ "\n");
+ if (!fwd_decls.empty()) {
+ printer->Print(
+ "#pragma mark - Objective C Class declarations\n"
+ "// Forward declarations of Objective C classes that we can use as\n"
+ "// static values in struct initializers.\n"
+ "// We don't use [Foo class] because it is not a static value.\n");
+ }
+ for (const auto& i : fwd_decls) {
+ printer->Print("$value$\n", "value", i);
+ }
+ if (!fwd_decls.empty()) {
+ printer->Print("\n");
+ }
+ printer->Print(
+ "#pragma mark - $root_class_name$\n"
+ "\n"
+ "@implementation $root_class_name$\n\n",
+ "root_class_name", root_class_name_);
+
+ const bool file_contains_extensions = FileContainsExtensions(file_);
+
+ // If there were any extensions or this file has any dependencies, output
+ // a registry to override to create the file specific registry.
+ if (file_contains_extensions || !deps_with_extensions.empty()) {
+ printer->Print(
+ "+ (GPBExtensionRegistry*)extensionRegistry {\n"
+ " // This is called by +initialize so there is no need to worry\n"
+ " // about thread safety and initialization of registry.\n"
+ " static GPBExtensionRegistry* registry = nil;\n"
+ " if (!registry) {\n"
+ " GPB_DEBUG_CHECK_RUNTIME_VERSIONS();\n"
+ " registry = [[GPBExtensionRegistry alloc] init];\n");
+
+ printer->Indent();
+ printer->Indent();
+
+ if (file_contains_extensions) {
+ printer->Print(
+ "static GPBExtensionDescription descriptions[] = {\n");
+ printer->Indent();
+ for (const auto& generator : extension_generators_) {
+ generator->GenerateStaticVariablesInitialization(printer);
+ }
+ for (const auto& generator : message_generators_) {
+ generator->GenerateStaticVariablesInitialization(printer);
+ }
+ printer->Outdent();
+ printer->Print(
+ "};\n"
+ "for (size_t i = 0; i < sizeof(descriptions) / sizeof(descriptions[0]); ++i) {\n"
+ " GPBExtensionDescriptor *extension =\n"
+ " [[GPBExtensionDescriptor alloc] initWithExtensionDescription:&descriptions[i]\n"
+ " usesClassRefs:YES];\n"
+ " [registry addExtension:extension];\n"
+ " [self globallyRegisterExtension:extension];\n"
+ " [extension release];\n"
+ "}\n");
+ }
+
+ if (deps_with_extensions.empty()) {
+ printer->Print(
+ "// None of the imports (direct or indirect) defined extensions, so no need to add\n"
+ "// them to this registry.\n");
+ } else {
+ printer->Print(
+ "// Merge in the imports (direct or indirect) that defined extensions.\n");
+ for (std::vector<const FileDescriptor*>::iterator iter =
+ deps_with_extensions.begin();
+ iter != deps_with_extensions.end(); ++iter) {
+ const std::string root_class_name(FileClassName((*iter)));
+ printer->Print(
+ "[registry addExtensions:[$dependency$ extensionRegistry]];\n",
+ "dependency", root_class_name);
+ }
+ }
+
+ printer->Outdent();
+ printer->Outdent();
+
+ printer->Print(
+ " }\n"
+ " return registry;\n"
+ "}\n");
+ } else {
+ if (file_->dependency_count() > 0) {
+ printer->Print(
+ "// No extensions in the file and none of the imports (direct or indirect)\n"
+ "// defined extensions, so no need to generate +extensionRegistry.\n");
+ } else {
+ printer->Print(
+ "// No extensions in the file and no imports, so no need to generate\n"
+ "// +extensionRegistry.\n");
+ }
+ }
+
+ printer->Print("\n@end\n\n");
+
+ // File descriptor only needed if there are messages to use it.
+ if (!message_generators_.empty()) {
+ std::map<std::string, std::string> vars;
+ vars["root_class_name"] = root_class_name_;
+ vars["package"] = file_->package();
+ vars["objc_prefix"] = FileClassPrefix(file_);
+ switch (file_->syntax()) {
+ case FileDescriptor::SYNTAX_UNKNOWN:
+ vars["syntax"] = "GPBFileSyntaxUnknown";
+ break;
+ case FileDescriptor::SYNTAX_PROTO2:
+ vars["syntax"] = "GPBFileSyntaxProto2";
+ break;
+ case FileDescriptor::SYNTAX_PROTO3:
+ vars["syntax"] = "GPBFileSyntaxProto3";
+ break;
+ }
+ printer->Print(vars,
+ "#pragma mark - $root_class_name$_FileDescriptor\n"
+ "\n"
+ "static GPBFileDescriptor *$root_class_name$_FileDescriptor(void) {\n"
+ " // This is called by +initialize so there is no need to worry\n"
+ " // about thread safety of the singleton.\n"
+ " static GPBFileDescriptor *descriptor = NULL;\n"
+ " if (!descriptor) {\n"
+ " GPB_DEBUG_CHECK_RUNTIME_VERSIONS();\n");
+ if (!vars["objc_prefix"].empty()) {
+ printer->Print(
+ vars,
+ " descriptor = [[GPBFileDescriptor alloc] initWithPackage:@\"$package$\"\n"
+ " objcPrefix:@\"$objc_prefix$\"\n"
+ " syntax:$syntax$];\n");
+ } else {
+ printer->Print(
+ vars,
+ " descriptor = [[GPBFileDescriptor alloc] initWithPackage:@\"$package$\"\n"
+ " syntax:$syntax$];\n");
+ }
+ printer->Print(
+ " }\n"
+ " return descriptor;\n"
+ "}\n"
+ "\n");
+ }
+
+ for (const auto& generator : enum_generators_) {
+ generator->GenerateSource(printer);
+ }
+ for (const auto& generator : message_generators_) {
+ generator->GenerateSource(printer);
+ }
+
+ printer->Print(
+ "\n"
+ "#pragma clang diagnostic pop\n"
+ "\n"
+ "// @@protoc_insertion_point(global_scope)\n");
+}
+
+// Helper to print the import of the runtime support at the top of generated
+// files. This currently only supports the runtime coming from a framework
+// as defined by the official CocoaPod.
+void FileGenerator::PrintFileRuntimePreamble(
+ io::Printer* printer,
+ const std::vector<std::string>& headers_to_import) const {
+ printer->Print(
+ "// Generated by the protocol buffer compiler. DO NOT EDIT!\n"
+ "// source: $filename$\n"
+ "\n",
+ "filename", file_->name());
+ ImportWriter::PrintRuntimeImports(
+ printer, headers_to_import, options_.runtime_import_prefix, true);
+ printer->Print("\n");
+}
+
+} // namespace objectivec
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_file.h b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_file.h
new file mode 100644
index 00000000..61572802
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_file.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_COMPILER_OBJECTIVEC_FILE_H__
+#define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_FILE_H__
+
+#include <string>
+#include <set>
+#include <vector>
+#include <compiler/objectivec/objectivec_helpers.h>
+#include <descriptor.h>
+#include <io/printer.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace objectivec {
+
+class EnumGenerator;
+class ExtensionGenerator;
+class MessageGenerator;
+
+class FileGenerator {
+ public:
+ FileGenerator(const FileDescriptor* file, const Options& options);
+ ~FileGenerator();
+
+ FileGenerator(const FileGenerator&) = delete;
+ FileGenerator& operator=(const FileGenerator&) = delete;
+
+ void GenerateSource(io::Printer* printer);
+ void GenerateHeader(io::Printer* printer);
+
+ private:
+ const FileDescriptor* file_;
+ std::string root_class_name_;
+ bool is_bundled_proto_;
+
+ std::vector<std::unique_ptr<EnumGenerator>> enum_generators_;
+ std::vector<std::unique_ptr<MessageGenerator>> message_generators_;
+ std::vector<std::unique_ptr<ExtensionGenerator>> extension_generators_;
+
+ const Options options_;
+
+ void PrintFileRuntimePreamble(
+ io::Printer* printer,
+ const std::vector<std::string>& headers_to_import) const;
+};
+
+} // namespace objectivec
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_FILE_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_generator.cc b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_generator.cc
new file mode 100644
index 00000000..3dbd1d43
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_generator.cc
@@ -0,0 +1,276 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <fstream>
+#include <iostream>
+#include <string>
+#include <unordered_set>
+#include <compiler/objectivec/objectivec_generator.h>
+#include <compiler/objectivec/objectivec_file.h>
+#include <compiler/objectivec/objectivec_helpers.h>
+#include <io/printer.h>
+#include <io/zero_copy_stream.h>
+#include <stubs/strutil.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace objectivec {
+
+namespace {
+
+// Convert a string with "yes"/"no" (case insensitive) to a boolean, returning
+// true/false for if the input string was a valid value. If the input string is
+// invalid, `result` is unchanged.
+bool StringToBool(const std::string& value, bool* result) {
+ std::string upper_value(value);
+ UpperString(&upper_value);
+ if (upper_value == "NO") {
+ *result = false;
+ return true;
+ }
+ if (upper_value == "YES") {
+ *result = true;
+ return true;
+ }
+
+ return false;
+}
+
+} // namespace
+
+ObjectiveCGenerator::ObjectiveCGenerator() {}
+
+ObjectiveCGenerator::~ObjectiveCGenerator() {}
+
+bool ObjectiveCGenerator::HasGenerateAll() const {
+ return true;
+}
+
+bool ObjectiveCGenerator::Generate(const FileDescriptor* file,
+ const std::string& parameter,
+ GeneratorContext* context,
+ std::string* error) const {
+ *error = "Unimplemented Generate() method. Call GenerateAll() instead.";
+ return false;
+}
+
+bool ObjectiveCGenerator::GenerateAll(
+ const std::vector<const FileDescriptor*>& files,
+ const std::string& parameter, GeneratorContext* context,
+ std::string* error) const {
+ // -----------------------------------------------------------------
+ // Parse generator options. These options are passed to the compiler using the
+ // --objc_opt flag. The options are passed as a comma separated list of
+ // options along with their values. If the option appears multiple times, only
+ // the last value will be considered.
+ //
+ // e.g. protoc ... --objc_opt=expected_prefixes=file.txt,generate_for_named_framework=MyFramework
+
+ Options generation_options;
+
+ std::vector<std::pair<std::string, std::string> > options;
+ ParseGeneratorParameter(parameter, &options);
+ for (int i = 0; i < options.size(); i++) {
+ if (options[i].first == "expected_prefixes_path") {
+ // Path to find a file containing the expected prefixes
+ // (objc_class_prefix "PREFIX") for proto packages (package NAME). The
+ // generator will then issue warnings/errors if in the proto files being
+ // generated the option is not listed/wrong/etc in the file.
+ //
+ // The format of the file is:
+ // - An entry is a line of "package=prefix".
+ // - Comments start with "#".
+ // - A comment can go on a line after a expected package/prefix pair.
+ // (i.e. - "package=prefix # comment")
+ //
+ // There is no validation that the prefixes are good prefixes, it is
+ // assumed that they are when you create the file.
+ generation_options.expected_prefixes_path = options[i].second;
+ } else if (options[i].first == "expected_prefixes_suppressions") {
+ // A semicolon delimited string that lists the paths of .proto files to
+ // exclude from the package prefix validations (expected_prefixes_path).
+ // This is provided as an "out", to skip some files being checked.
+ for (StringPiece split_piece : Split(
+ options[i].second, ";", true)) {
+ generation_options.expected_prefixes_suppressions.push_back(
+ std::string(split_piece));
+ }
+ } else if (options[i].first == "prefixes_must_be_registered") {
+ // If objc prefix file option value must be registered to be used. This
+ // option has no meaning if an "expected_prefixes_path" isn't set. The
+ // available options are:
+ // "no": They don't have to be registered.
+ // "yes": They must be registered and an error will be raised if a files
+ // tried to use a prefix that isn't registered.
+ // Default is "no".
+ if (!StringToBool(options[i].second,
+ &generation_options.prefixes_must_be_registered)) {
+ *error = "error: Unknown value for prefixes_must_be_registered: " + options[i].second;
+ return false;
+ }
+ } else if (options[i].first == "require_prefixes") {
+ // If every file must have an objc prefix file option to be used. The
+ // available options are:
+ // "no": Files can be generated without the prefix option.
+ // "yes": Files must have the objc prefix option, and an error will be
+ // raised if a files doesn't have one.
+ // Default is "no".
+ if (!StringToBool(options[i].second,
+ &generation_options.require_prefixes)) {
+ *error = "error: Unknown value for require_prefixes: " + options[i].second;
+ return false;
+ }
+ } else if (options[i].first == "generate_for_named_framework") {
+ // The name of the framework that protos are being generated for. This
+ // will cause the #import statements to be framework based using this
+ // name (i.e. - "#import <NAME/proto.pbobjc.h>).
+ //
+ // NOTE: If this option is used with
+ // named_framework_to_proto_path_mappings_path, then this is effectively
+ // the "default" framework name used for everything that wasn't mapped by
+ // the mapping file.
+ generation_options.generate_for_named_framework = options[i].second;
+ } else if (options[i].first == "named_framework_to_proto_path_mappings_path") {
+ // Path to find a file containing the list of framework names and proto
+ // files. The generator uses this to decide if a proto file
+ // referenced should use a framework style import vs. a user level import
+ // (#import <FRAMEWORK/file.pbobjc.h> vs #import "dir/file.pbobjc.h").
+ //
+ // The format of the file is:
+ // - An entry is a line of "frameworkName: file.proto, dir/file2.proto".
+ // - Comments start with "#".
+ // - A comment can go on a line after a expected package/prefix pair.
+ // (i.e. - "frameworkName: file.proto # comment")
+ //
+ // Any number of files can be listed for a framework, just separate them
+ // with commas.
+ //
+ // There can be multiple lines listing the same frameworkName in case it
+ // has a lot of proto files included in it; having multiple lines makes
+ // things easier to read. If a proto file is not configured in the
+ // mappings file, it will use the default framework name if one was passed
+ // with generate_for_named_framework, or the relative path to it's include
+ // path otherwise.
+ generation_options.named_framework_to_proto_path_mappings_path = options[i].second;
+ } else if (options[i].first == "runtime_import_prefix") {
+ // Path to use as a prefix on #imports of runtime provided headers in the
+ // generated files. When integrating ObjC protos into a build system,
+ // this can be used to avoid having to add the runtime directory to the
+ // header search path since the generate #import will be more complete.
+ generation_options.runtime_import_prefix =
+ StripSuffixString(options[i].second, "/");
+ } else if (options[i].first == "use_package_as_prefix") {
+ // Controls how the symbols should be prefixed to avoid symbols
+ // collisions. The objc_class_prefix file option is always honored, this
+ // is just what to do if that isn't set. The available options are:
+ // "no": Not prefixed (the existing mode).
+ // "yes": Make a prefix out of the proto package.
+ bool value = false;
+ if (StringToBool(options[i].second, &value)) {
+ SetUseProtoPackageAsDefaultPrefix(value);
+ } else {
+ *error = "error: Unknown use_package_as_prefix: " + options[i].second;
+ return false;
+ }
+ } else if (options[i].first == "proto_package_prefix_exceptions_path") {
+ // Path to find a file containing the list of proto package names that are
+ // exceptions when use_package_as_prefix is enabled. This can be used to
+ // migrate packages one at a time to use_package_as_prefix since there
+ // are likely code updates needed with each one.
+ //
+ // The format of the file is:
+ // - An entry is a line of "proto.package.name".
+ // - Comments start with "#".
+ // - A comment can go on a line after a expected package/prefix pair.
+ // (i.e. - "some.proto.package # comment")
+ SetProtoPackagePrefixExceptionList(options[i].second);
+ } else {
+ *error = "error: Unknown generator option: " + options[i].first;
+ return false;
+ }
+ }
+
+ // -----------------------------------------------------------------
+
+ // These are not official generation options and could be removed/changed in
+ // the future and doing that won't count as a breaking change.
+ bool headers_only = getenv("GPB_OBJC_HEADERS_ONLY") != NULL;
+ std::unordered_set<std::string> skip_impls;
+ if (getenv("GPB_OBJC_SKIP_IMPLS_FILE") != NULL) {
+ std::ifstream skip_file(getenv("GPB_OBJC_SKIP_IMPLS_FILE"));
+ if (skip_file.is_open()) {
+ std::string line;
+ while (std::getline(skip_file, line)) {
+ skip_impls.insert(line);
+ }
+ } else {
+ *error = "error: Failed to open GPB_OBJC_SKIP_IMPLS_FILE file";
+ return false;
+ }
+ }
+
+ // -----------------------------------------------------------------
+
+ // Validate the objc prefix/package pairings.
+ if (!ValidateObjCClassPrefixes(files, generation_options, error)) {
+ // *error will have been filled in.
+ return false;
+ }
+
+ for (int i = 0; i < files.size(); i++) {
+ const FileDescriptor* file = files[i];
+ FileGenerator file_generator(file, generation_options);
+ std::string filepath = FilePath(file);
+
+ // Generate header.
+ {
+ std::unique_ptr<io::ZeroCopyOutputStream> output(
+ context->Open(filepath + ".pbobjc.h"));
+ io::Printer printer(output.get(), '$');
+ file_generator.GenerateHeader(&printer);
+ }
+
+ // Generate m file.
+ if (!headers_only && skip_impls.count(file->name()) == 0) {
+ std::unique_ptr<io::ZeroCopyOutputStream> output(
+ context->Open(filepath + ".pbobjc.m"));
+ io::Printer printer(output.get(), '$');
+ file_generator.GenerateSource(&printer);
+ }
+ }
+
+ return true;
+}
+
+} // namespace objectivec
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_generator.h b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_generator.h
new file mode 100644
index 00000000..c7cfe8d3
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_generator.h
@@ -0,0 +1,79 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Generates ObjectiveC code for a given .proto file.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_GENERATOR_H__
+#define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_GENERATOR_H__
+
+#include <string>
+#include <compiler/code_generator.h>
+#include <descriptor.h>
+
+#include <port_def.inc>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace objectivec {
+
+// CodeGenerator implementation which generates a ObjectiveC source file and
+// header. If you create your own protocol compiler binary and you want it to
+// support ObjectiveC output, you can do so by registering an instance of this
+// CodeGenerator with the CommandLineInterface in your main() function.
+class PROTOC_EXPORT ObjectiveCGenerator : public CodeGenerator {
+ public:
+ ObjectiveCGenerator();
+ ~ObjectiveCGenerator();
+
+ ObjectiveCGenerator(const ObjectiveCGenerator&) = delete;
+ ObjectiveCGenerator& operator=(const ObjectiveCGenerator&) = delete;
+
+ // implements CodeGenerator ----------------------------------------
+ bool HasGenerateAll() const override;
+ bool Generate(const FileDescriptor* file, const std::string& parameter,
+ GeneratorContext* context, std::string* error) const override;
+ bool GenerateAll(const std::vector<const FileDescriptor*>& files,
+ const std::string& parameter, GeneratorContext* context,
+ std::string* error) const override;
+
+ uint64_t GetSupportedFeatures() const override {
+ return FEATURE_PROTO3_OPTIONAL;
+ }
+};
+
+} // namespace objectivec
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#include <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_GENERATOR_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_helpers.cc b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_helpers.cc
new file mode 100644
index 00000000..014edb9e
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_helpers.cc
@@ -0,0 +1,1960 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 _MSC_VER
+#include <unistd.h>
+#endif
+#include <climits>
+#include <errno.h>
+#include <fcntl.h>
+#include <fstream>
+#include <iostream>
+#include <sstream>
+#include <stdlib.h>
+#include <unordered_set>
+#include <vector>
+
+#include <compiler/code_generator.h>
+#include <compiler/objectivec/objectivec_helpers.h>
+#include <compiler/objectivec/objectivec_nsobject_methods.h>
+#include <descriptor.pb.h>
+#include <io/coded_stream.h>
+#include <io/printer.h>
+#include <io/zero_copy_stream_impl.h>
+#include <io/io_win32.h>
+#include <port.h>
+#include <stubs/common.h>
+#include <stubs/strutil.h>
+
+// NOTE: src/google/protobuf/compiler/plugin.cc makes use of cerr for some
+// error cases, so it seems to be ok to use as a back door for errors.
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace objectivec {
+
+// <io.h> is transitively included in this file. Import the functions explicitly
+// in this port namespace to avoid ambiguous definition.
+namespace posix {
+#ifdef _WIN32
+using ::google::protobuf::io::win32::open;
+#else
+using ::open;
+#endif
+} // namespace port
+
+namespace {
+
+class SimpleLineCollector : public LineConsumer {
+ public:
+ SimpleLineCollector(std::unordered_set<std::string>* inout_set)
+ : set_(inout_set) {}
+
+ virtual bool ConsumeLine(const StringPiece& line, std::string* out_error) override {
+ set_->insert(std::string(line));
+ return true;
+ }
+
+ private:
+ std::unordered_set<std::string>* set_;
+};
+
+class PrefixModeStorage {
+ public:
+ PrefixModeStorage();
+
+ bool use_package_name() const { return use_package_name_; }
+ void set_use_package_name(bool on_or_off) { use_package_name_ = on_or_off; }
+
+ const std::string exception_path() const { return exception_path_; }
+ void set_exception_path(const std::string& path) {
+ exception_path_ = path;
+ exceptions_.clear();
+ }
+
+ bool is_package_exempted(const std::string& package);
+
+ private:
+ bool use_package_name_;
+ std::string exception_path_;
+ std::unordered_set<std::string> exceptions_;
+};
+
+PrefixModeStorage::PrefixModeStorage() {
+ // Even thought there are generation options, have an env back door since some
+ // of these helpers could be used in other plugins.
+
+ const char* use_package_cstr = getenv("GPB_OBJC_USE_PACKAGE_AS_PREFIX");
+ use_package_name_ =
+ (use_package_cstr && (std::string("YES") == ToUpper(use_package_cstr)));
+
+ const char* exception_path = getenv("GPB_OBJC_PACKAGE_PREFIX_EXCEPTIONS_PATH");
+ if (exception_path) {
+ exception_path_ = exception_path;
+ }
+}
+
+bool PrefixModeStorage::is_package_exempted(const std::string& package) {
+ if (exceptions_.empty() && !exception_path_.empty()) {
+ std::string error_str;
+ SimpleLineCollector collector(&exceptions_);
+ if (!ParseSimpleFile(exception_path_, &collector, &error_str)) {
+ if (error_str.empty()) {
+ error_str = std::string("protoc:0: warning: Failed to parse")
+ + std::string(" package prefix exceptions file: ")
+ + exception_path_;
+ }
+ std::cerr << error_str << std::endl;
+ std::cerr.flush();
+ exceptions_.clear();
+ }
+
+ // If the file was empty put something in it so it doesn't get reloaded over
+ // and over.
+ if (exceptions_.empty()) {
+ exceptions_.insert("<not a real package>");
+ }
+ }
+
+ return exceptions_.count(package) != 0;
+}
+
+PrefixModeStorage g_prefix_mode;
+
+} // namespace
+
+bool UseProtoPackageAsDefaultPrefix() {
+ return g_prefix_mode.use_package_name();
+}
+
+void SetUseProtoPackageAsDefaultPrefix(bool on_or_off) {
+ g_prefix_mode.set_use_package_name(on_or_off);
+}
+
+std::string GetProtoPackagePrefixExceptionList() {
+ return g_prefix_mode.exception_path();
+}
+
+void SetProtoPackagePrefixExceptionList(const std::string& file_path) {
+ g_prefix_mode.set_exception_path(file_path);
+}
+
+Options::Options() {
+ // Default is the value of the env for the package prefixes.
+ const char* file_path = getenv("GPB_OBJC_EXPECTED_PACKAGE_PREFIXES");
+ if (file_path) {
+ expected_prefixes_path = file_path;
+ }
+ const char* suppressions = getenv("GPB_OBJC_EXPECTED_PACKAGE_PREFIXES_SUPPRESSIONS");
+ if (suppressions) {
+ expected_prefixes_suppressions =
+ Split(suppressions, ";", true);
+ }
+ prefixes_must_be_registered = false;
+ require_prefixes = false;
+}
+
+namespace {
+
+std::unordered_set<std::string> MakeWordsMap(const char* const words[],
+ size_t num_words) {
+ std::unordered_set<std::string> result;
+ for (int i = 0; i < num_words; i++) {
+ result.insert(words[i]);
+ }
+ return result;
+}
+
+const char* const kUpperSegmentsList[] = {"url", "http", "https"};
+
+std::unordered_set<std::string> kUpperSegments =
+ MakeWordsMap(kUpperSegmentsList, GOOGLE_ARRAYSIZE(kUpperSegmentsList));
+
+bool ascii_isnewline(char c) {
+ return c == '\n' || c == '\r';
+}
+
+// Internal helper for name handing.
+// Do not expose this outside of helpers, stick to having functions for specific
+// cases (ClassName(), FieldName()), so there is always consistent suffix rules.
+std::string UnderscoresToCamelCase(const std::string& input,
+ bool first_capitalized) {
+ std::vector<std::string> values;
+ std::string current;
+
+ bool last_char_was_number = false;
+ bool last_char_was_lower = false;
+ bool last_char_was_upper = false;
+ for (int i = 0; i < input.size(); i++) {
+ char c = input[i];
+ if (ascii_isdigit(c)) {
+ if (!last_char_was_number) {
+ values.push_back(current);
+ current = "";
+ }
+ current += c;
+ last_char_was_number = last_char_was_lower = last_char_was_upper = false;
+ last_char_was_number = true;
+ } else if (ascii_islower(c)) {
+ // lowercase letter can follow a lowercase or uppercase letter
+ if (!last_char_was_lower && !last_char_was_upper) {
+ values.push_back(current);
+ current = "";
+ }
+ current += c; // already lower
+ last_char_was_number = last_char_was_lower = last_char_was_upper = false;
+ last_char_was_lower = true;
+ } else if (ascii_isupper(c)) {
+ if (!last_char_was_upper) {
+ values.push_back(current);
+ current = "";
+ }
+ current += ascii_tolower(c);
+ last_char_was_number = last_char_was_lower = last_char_was_upper = false;
+ last_char_was_upper = true;
+ } else {
+ last_char_was_number = last_char_was_lower = last_char_was_upper = false;
+ }
+ }
+ values.push_back(current);
+
+ std::string result;
+ bool first_segment_forces_upper = false;
+ for (std::vector<std::string>::iterator i = values.begin(); i != values.end();
+ ++i) {
+ std::string value = *i;
+ bool all_upper = (kUpperSegments.count(value) > 0);
+ if (all_upper && (result.length() == 0)) {
+ first_segment_forces_upper = true;
+ }
+ for (int j = 0; j < value.length(); j++) {
+ if (j == 0 || all_upper) {
+ value[j] = ascii_toupper(value[j]);
+ } else {
+ // Nothing, already in lower.
+ }
+ }
+ result += value;
+ }
+ if ((result.length() != 0) &&
+ !first_capitalized &&
+ !first_segment_forces_upper) {
+ result[0] = ascii_tolower(result[0]);
+ }
+ return result;
+}
+
+const char* const kReservedWordList[] = {
+ // Note NSObject Methods:
+ // These are brought in from objectivec_nsobject_methods.h that is generated
+ // using method_dump.sh. See kNSObjectMethods below.
+
+ // Objective C "keywords" that aren't in C
+ // From
+ // http://stackoverflow.com/questions/1873630/reserved-keywords-in-objective-c
+ // with some others added on.
+ "id", "_cmd", "super", "in", "out", "inout", "bycopy", "byref", "oneway",
+ "self", "instancetype", "nullable", "nonnull", "nil", "Nil",
+ "YES", "NO", "weak",
+
+ // C/C++ keywords (Incl C++ 0x11)
+ // From http://en.cppreference.com/w/cpp/keywords
+ "and", "and_eq", "alignas", "alignof", "asm", "auto", "bitand", "bitor",
+ "bool", "break", "case", "catch", "char", "char16_t", "char32_t", "class",
+ "compl", "const", "constexpr", "const_cast", "continue", "decltype",
+ "default", "delete", "double", "dynamic_cast", "else", "enum", "explicit",
+ "export", "extern ", "false", "float", "for", "friend", "goto", "if",
+ "inline", "int", "long", "mutable", "namespace", "new", "noexcept", "not",
+ "not_eq", "nullptr", "operator", "or", "or_eq", "private", "protected",
+ "public", "register", "reinterpret_cast", "return", "short", "signed",
+ "sizeof", "static", "static_assert", "static_cast", "struct", "switch",
+ "template", "this", "thread_local", "throw", "true", "try", "typedef",
+ "typeid", "typename", "union", "unsigned", "using", "virtual", "void",
+ "volatile", "wchar_t", "while", "xor", "xor_eq",
+
+ // C99 keywords
+ // From
+ // http://publib.boulder.ibm.com/infocenter/lnxpcomp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8l.doc%2Flanguage%2Fref%2Fkeyw.htm
+ "restrict",
+
+ // GCC/Clang extension
+ "typeof",
+
+ // Not a keyword, but will break you
+ "NULL",
+
+ // C88+ specs call for these to be macros, so depending on what they are
+ // defined to be it can lead to odd errors for some Xcode/SDK versions.
+ "stdin", "stdout", "stderr",
+
+ // Objective-C Runtime typedefs
+ // From <obc/runtime.h>
+ "Category", "Ivar", "Method", "Protocol",
+
+ // GPBMessage Methods
+ // Only need to add instance methods that may conflict with
+ // method declared in protos. The main cases are methods
+ // that take no arguments, or setFoo:/hasFoo: type methods.
+ "clear", "data", "delimitedData", "descriptor", "extensionRegistry",
+ "extensionsCurrentlySet", "initialized", "isInitialized", "serializedSize",
+ "sortedExtensionsInUse", "unknownFields",
+
+ // MacTypes.h names
+ "Fixed", "Fract", "Size", "LogicalAddress", "PhysicalAddress", "ByteCount",
+ "ByteOffset", "Duration", "AbsoluteTime", "OptionBits", "ItemCount",
+ "PBVersion", "ScriptCode", "LangCode", "RegionCode", "OSType",
+ "ProcessSerialNumber", "Point", "Rect", "FixedPoint", "FixedRect", "Style",
+ "StyleParameter", "StyleField", "TimeScale", "TimeBase", "TimeRecord",
+};
+
+// returns true is input starts with __ or _[A-Z] which are reserved identifiers
+// in C/ C++. All calls should go through UnderscoresToCamelCase before getting here
+// but this verifies and allows for future expansion if we decide to redefine what a
+// reserved C identifier is (for example the GNU list
+// https://www.gnu.org/software/libc/manual/html_node/Reserved-Names.html )
+bool IsReservedCIdentifier(const std::string& input) {
+ if (input.length() > 2) {
+ if (input.at(0) == '_') {
+ if (isupper(input.at(1)) || input.at(1) == '_') {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+std::string SanitizeNameForObjC(const std::string& prefix,
+ const std::string& input,
+ const std::string& extension,
+ std::string* out_suffix_added) {
+ static const std::unordered_set<std::string> kReservedWords =
+ MakeWordsMap(kReservedWordList, GOOGLE_ARRAYSIZE(kReservedWordList));
+ static const std::unordered_set<std::string> kNSObjectMethods =
+ MakeWordsMap(kNSObjectMethodsList, GOOGLE_ARRAYSIZE(kNSObjectMethodsList));
+ std::string sanitized;
+ // We add the prefix in the cases where the string is missing a prefix.
+ // We define "missing a prefix" as where 'input':
+ // a) Doesn't start with the prefix or
+ // b) Isn't equivalent to the prefix or
+ // c) Has the prefix, but the letter after the prefix is lowercase
+ if (HasPrefixString(input, prefix)) {
+ if (input.length() == prefix.length() || !ascii_isupper(input[prefix.length()])) {
+ sanitized = prefix + input;
+ } else {
+ sanitized = input;
+ }
+ } else {
+ sanitized = prefix + input;
+ }
+ if (IsReservedCIdentifier(sanitized) ||
+ (kReservedWords.count(sanitized) > 0) ||
+ (kNSObjectMethods.count(sanitized) > 0)) {
+ if (out_suffix_added) *out_suffix_added = extension;
+ return sanitized + extension;
+ }
+ if (out_suffix_added) out_suffix_added->clear();
+ return sanitized;
+}
+
+std::string NameFromFieldDescriptor(const FieldDescriptor* field) {
+ if (field->type() == FieldDescriptor::TYPE_GROUP) {
+ return field->message_type()->name();
+ } else {
+ return field->name();
+ }
+}
+
+void PathSplit(const std::string& path, std::string* directory,
+ std::string* basename) {
+ std::string::size_type last_slash = path.rfind('/');
+ if (last_slash == std::string::npos) {
+ if (directory) {
+ *directory = "";
+ }
+ if (basename) {
+ *basename = path;
+ }
+ } else {
+ if (directory) {
+ *directory = path.substr(0, last_slash);
+ }
+ if (basename) {
+ *basename = path.substr(last_slash + 1);
+ }
+ }
+}
+
+bool IsSpecialName(const std::string& name, const std::string* special_names,
+ size_t count) {
+ for (size_t i = 0; i < count; ++i) {
+ size_t length = special_names[i].length();
+ if (name.compare(0, length, special_names[i]) == 0) {
+ if (name.length() > length) {
+ // If name is longer than the retained_name[i] that it matches
+ // the next character must be not lower case (newton vs newTon vs
+ // new_ton).
+ return !ascii_islower(name[length]);
+ } else {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+std::string GetZeroEnumNameForFlagType(const FlagType flag_type) {
+ switch(flag_type) {
+ case FLAGTYPE_DESCRIPTOR_INITIALIZATION:
+ return "GPBDescriptorInitializationFlag_None";
+ case FLAGTYPE_EXTENSION:
+ return "GPBExtensionNone";
+ case FLAGTYPE_FIELD:
+ return "GPBFieldNone";
+ default:
+ GOOGLE_LOG(FATAL) << "Can't get here.";
+ return "0";
+ }
+}
+
+std::string GetEnumNameForFlagType(const FlagType flag_type) {
+ switch(flag_type) {
+ case FLAGTYPE_DESCRIPTOR_INITIALIZATION:
+ return "GPBDescriptorInitializationFlags";
+ case FLAGTYPE_EXTENSION:
+ return "GPBExtensionOptions";
+ case FLAGTYPE_FIELD:
+ return "GPBFieldFlags";
+ default:
+ GOOGLE_LOG(FATAL) << "Can't get here.";
+ return std::string();
+ }
+}
+
+void MaybeUnQuote(StringPiece* input) {
+ if ((input->length() >= 2) &&
+ ((*input->data() == '\'' || *input->data() == '"')) &&
+ ((*input)[input->length() - 1] == *input->data())) {
+ input->remove_prefix(1);
+ input->remove_suffix(1);
+ }
+}
+
+} // namespace
+
+// Escape C++ trigraphs by escaping question marks to \?
+std::string EscapeTrigraphs(const std::string& to_escape) {
+ return StringReplace(to_escape, "?", "\\?", true);
+}
+
+void TrimWhitespace(StringPiece* input) {
+ while (!input->empty() && ascii_isspace(*input->data())) {
+ input->remove_prefix(1);
+ }
+ while (!input->empty() && ascii_isspace((*input)[input->length() - 1])) {
+ input->remove_suffix(1);
+ }
+}
+
+bool IsRetainedName(const std::string& name) {
+ // List of prefixes from
+ // http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmRules.html
+ static const std::string retained_names[] = {"new", "alloc", "copy",
+ "mutableCopy"};
+ return IsSpecialName(name, retained_names,
+ sizeof(retained_names) / sizeof(retained_names[0]));
+}
+
+bool IsInitName(const std::string& name) {
+ static const std::string init_names[] = {"init"};
+ return IsSpecialName(name, init_names,
+ sizeof(init_names) / sizeof(init_names[0]));
+}
+
+std::string BaseFileName(const FileDescriptor* file) {
+ std::string basename;
+ PathSplit(file->name(), NULL, &basename);
+ return basename;
+}
+
+std::string FileClassPrefix(const FileDescriptor* file) {
+ // Always honor the file option.
+ if (file->options().has_objc_class_prefix()) {
+ return file->options().objc_class_prefix();
+ }
+
+ // If package prefix isn't enabled or no package, done.
+ if (!g_prefix_mode.use_package_name() || file->package().empty()) {
+ return "";
+ }
+
+ // If the package is in the exceptions list, done.
+ if (g_prefix_mode.is_package_exempted(file->package())) {
+ return "";
+ }
+
+ // Transform the package into a prefix: use the dot segments as part,
+ // camelcase each one and then join them with underscores, and add an
+ // underscore at the end.
+ std::string result;
+ const std::vector<std::string> segments = Split(file->package(), ".", true);
+ for (const auto& segment : segments) {
+ const std::string part = UnderscoresToCamelCase(segment, true);
+ if (part.empty()) {
+ continue;
+ }
+ if (!result.empty()) {
+ result.append("_");
+ }
+ result.append(part);
+ }
+ if (!result.empty()) {
+ result.append("_");
+ }
+ return result;
+}
+
+std::string FilePath(const FileDescriptor* file) {
+ std::string output;
+ std::string basename;
+ std::string directory;
+ PathSplit(file->name(), &directory, &basename);
+ if (directory.length() > 0) {
+ output = directory + "/";
+ }
+ basename = StripProto(basename);
+
+ // CamelCase to be more ObjC friendly.
+ basename = UnderscoresToCamelCase(basename, true);
+
+ output += basename;
+ return output;
+}
+
+std::string FilePathBasename(const FileDescriptor* file) {
+ std::string output;
+ std::string basename;
+ std::string directory;
+ PathSplit(file->name(), &directory, &basename);
+ basename = StripProto(basename);
+
+ // CamelCase to be more ObjC friendly.
+ output = UnderscoresToCamelCase(basename, true);
+
+ return output;
+}
+
+std::string FileClassName(const FileDescriptor* file) {
+ const std::string prefix = FileClassPrefix(file);
+ const std::string name =
+ UnderscoresToCamelCase(StripProto(BaseFileName(file)), true) + "Root";
+ // There aren't really any reserved words that end in "Root", but playing
+ // it safe and checking.
+ return SanitizeNameForObjC(prefix, name, "_RootClass", NULL);
+}
+
+std::string ClassNameWorker(const Descriptor* descriptor) {
+ std::string name;
+ if (descriptor->containing_type() != NULL) {
+ name = ClassNameWorker(descriptor->containing_type());
+ name += "_";
+ }
+ return name + descriptor->name();
+}
+
+std::string ClassNameWorker(const EnumDescriptor* descriptor) {
+ std::string name;
+ if (descriptor->containing_type() != NULL) {
+ name = ClassNameWorker(descriptor->containing_type());
+ name += "_";
+ }
+ return name + descriptor->name();
+}
+
+std::string ClassName(const Descriptor* descriptor) {
+ return ClassName(descriptor, NULL);
+}
+
+std::string ClassName(const Descriptor* descriptor,
+ std::string* out_suffix_added) {
+ // 1. Message names are used as is (style calls for CamelCase, trust it).
+ // 2. Check for reserved word at the very end and then suffix things.
+ const std::string prefix = FileClassPrefix(descriptor->file());
+ const std::string name = ClassNameWorker(descriptor);
+ return SanitizeNameForObjC(prefix, name, "_Class", out_suffix_added);
+}
+
+std::string EnumName(const EnumDescriptor* descriptor) {
+ // 1. Enum names are used as is (style calls for CamelCase, trust it).
+ // 2. Check for reserved word at the every end and then suffix things.
+ // message Fixed {
+ // message Size {...}
+ // enum Mumble {...}
+ // ...
+ // }
+ // yields Fixed_Class, Fixed_Size.
+ const std::string prefix = FileClassPrefix(descriptor->file());
+ const std::string name = ClassNameWorker(descriptor);
+ return SanitizeNameForObjC(prefix, name, "_Enum", NULL);
+}
+
+std::string EnumValueName(const EnumValueDescriptor* descriptor) {
+ // Because of the Switch enum compatibility, the name on the enum has to have
+ // the suffix handing, so it slightly diverges from how nested classes work.
+ // enum Fixed {
+ // FOO = 1
+ // }
+ // yields Fixed_Enum and Fixed_Enum_Foo (not Fixed_Foo).
+ const std::string class_name = EnumName(descriptor->type());
+ const std::string value_str =
+ UnderscoresToCamelCase(descriptor->name(), true);
+ const std::string name = class_name + "_" + value_str;
+ // There aren't really any reserved words with an underscore and a leading
+ // capital letter, but playing it safe and checking.
+ return SanitizeNameForObjC("", name, "_Value", NULL);
+}
+
+std::string EnumValueShortName(const EnumValueDescriptor* descriptor) {
+ // Enum value names (EnumValueName above) are the enum name turned into
+ // a class name and then the value name is CamelCased and concatenated; the
+ // whole thing then gets sanitized for reserved words.
+ // The "short name" is intended to be the final leaf, the value name; but
+ // you can't simply send that off to sanitize as that could result in it
+ // getting modified when the full name didn't. For example enum
+ // "StorageModes" has a value "retain". So the full name is
+ // "StorageModes_Retain", but if we sanitize "retain" it would become
+ // "RetainValue".
+ // So the right way to get the short name is to take the full enum name
+ // and then strip off the enum name (leaving the value name and anything
+ // done by sanitize).
+ const std::string class_name = EnumName(descriptor->type());
+ const std::string long_name_prefix = class_name + "_";
+ const std::string long_name = EnumValueName(descriptor);
+ return StripPrefixString(long_name, long_name_prefix);
+}
+
+std::string UnCamelCaseEnumShortName(const std::string& name) {
+ std::string result;
+ for (int i = 0; i < name.size(); i++) {
+ char c = name[i];
+ if (i > 0 && ascii_isupper(c)) {
+ result += '_';
+ }
+ result += ascii_toupper(c);
+ }
+ return result;
+}
+
+std::string ExtensionMethodName(const FieldDescriptor* descriptor) {
+ const std::string name = NameFromFieldDescriptor(descriptor);
+ const std::string result = UnderscoresToCamelCase(name, false);
+ return SanitizeNameForObjC("", result, "_Extension", NULL);
+}
+
+std::string FieldName(const FieldDescriptor* field) {
+ const std::string name = NameFromFieldDescriptor(field);
+ std::string result = UnderscoresToCamelCase(name, false);
+ if (field->is_repeated() && !field->is_map()) {
+ // Add "Array" before do check for reserved worlds.
+ result += "Array";
+ } else {
+ // If it wasn't repeated, but ends in "Array", force on the _p suffix.
+ if (HasSuffixString(result, "Array")) {
+ result += "_p";
+ }
+ }
+ return SanitizeNameForObjC("", result, "_p", NULL);
+}
+
+std::string FieldNameCapitalized(const FieldDescriptor* field) {
+ // Want the same suffix handling, so upcase the first letter of the other
+ // name.
+ std::string result = FieldName(field);
+ if (result.length() > 0) {
+ result[0] = ascii_toupper(result[0]);
+ }
+ return result;
+}
+
+std::string OneofEnumName(const OneofDescriptor* descriptor) {
+ const Descriptor* fieldDescriptor = descriptor->containing_type();
+ std::string name = ClassName(fieldDescriptor);
+ name += "_" + UnderscoresToCamelCase(descriptor->name(), true) + "_OneOfCase";
+ // No sanitize needed because the OS never has names that end in _OneOfCase.
+ return name;
+}
+
+std::string OneofName(const OneofDescriptor* descriptor) {
+ std::string name = UnderscoresToCamelCase(descriptor->name(), false);
+ // No sanitize needed because it gets OneOfCase added and that shouldn't
+ // ever conflict.
+ return name;
+}
+
+std::string OneofNameCapitalized(const OneofDescriptor* descriptor) {
+ // Use the common handling and then up-case the first letter.
+ std::string result = OneofName(descriptor);
+ if (result.length() > 0) {
+ result[0] = ascii_toupper(result[0]);
+ }
+ return result;
+}
+
+std::string ObjCClass(const std::string& class_name) {
+ return std::string("GPBObjCClass(") + class_name + ")";
+}
+
+std::string ObjCClassDeclaration(const std::string& class_name) {
+ return std::string("GPBObjCClassDeclaration(") + class_name + ");";
+}
+
+std::string UnCamelCaseFieldName(const std::string& name, const FieldDescriptor* field) {
+ std::string worker(name);
+ if (HasSuffixString(worker, "_p")) {
+ worker = StripSuffixString(worker, "_p");
+ }
+ if (field->is_repeated() && HasSuffixString(worker, "Array")) {
+ worker = StripSuffixString(worker, "Array");
+ }
+ if (field->type() == FieldDescriptor::TYPE_GROUP) {
+ if (worker.length() > 0) {
+ if (ascii_islower(worker[0])) {
+ worker[0] = ascii_toupper(worker[0]);
+ }
+ }
+ return worker;
+ } else {
+ std::string result;
+ for (int i = 0; i < worker.size(); i++) {
+ char c = worker[i];
+ if (ascii_isupper(c)) {
+ if (i > 0) {
+ result += '_';
+ }
+ result += ascii_tolower(c);
+ } else {
+ result += c;
+ }
+ }
+ return result;
+ }
+}
+
+std::string GetCapitalizedType(const FieldDescriptor* field) {
+ switch (field->type()) {
+ case FieldDescriptor::TYPE_INT32:
+ return "Int32";
+ case FieldDescriptor::TYPE_UINT32:
+ return "UInt32";
+ case FieldDescriptor::TYPE_SINT32:
+ return "SInt32";
+ case FieldDescriptor::TYPE_FIXED32:
+ return "Fixed32";
+ case FieldDescriptor::TYPE_SFIXED32:
+ return "SFixed32";
+ case FieldDescriptor::TYPE_INT64:
+ return "Int64";
+ case FieldDescriptor::TYPE_UINT64:
+ return "UInt64";
+ case FieldDescriptor::TYPE_SINT64:
+ return "SInt64";
+ case FieldDescriptor::TYPE_FIXED64:
+ return "Fixed64";
+ case FieldDescriptor::TYPE_SFIXED64:
+ return "SFixed64";
+ case FieldDescriptor::TYPE_FLOAT:
+ return "Float";
+ case FieldDescriptor::TYPE_DOUBLE:
+ return "Double";
+ case FieldDescriptor::TYPE_BOOL:
+ return "Bool";
+ case FieldDescriptor::TYPE_STRING:
+ return "String";
+ case FieldDescriptor::TYPE_BYTES:
+ return "Bytes";
+ case FieldDescriptor::TYPE_ENUM:
+ return "Enum";
+ case FieldDescriptor::TYPE_GROUP:
+ return "Group";
+ case FieldDescriptor::TYPE_MESSAGE:
+ return "Message";
+ }
+
+ // Some compilers report reaching end of function even though all cases of
+ // the enum are handed in the switch.
+ GOOGLE_LOG(FATAL) << "Can't get here.";
+ return std::string();
+}
+
+ObjectiveCType GetObjectiveCType(FieldDescriptor::Type field_type) {
+ switch (field_type) {
+ case FieldDescriptor::TYPE_INT32:
+ case FieldDescriptor::TYPE_SINT32:
+ case FieldDescriptor::TYPE_SFIXED32:
+ return OBJECTIVECTYPE_INT32;
+
+ case FieldDescriptor::TYPE_UINT32:
+ case FieldDescriptor::TYPE_FIXED32:
+ return OBJECTIVECTYPE_UINT32;
+
+ case FieldDescriptor::TYPE_INT64:
+ case FieldDescriptor::TYPE_SINT64:
+ case FieldDescriptor::TYPE_SFIXED64:
+ return OBJECTIVECTYPE_INT64;
+
+ case FieldDescriptor::TYPE_UINT64:
+ case FieldDescriptor::TYPE_FIXED64:
+ return OBJECTIVECTYPE_UINT64;
+
+ case FieldDescriptor::TYPE_FLOAT:
+ return OBJECTIVECTYPE_FLOAT;
+
+ case FieldDescriptor::TYPE_DOUBLE:
+ return OBJECTIVECTYPE_DOUBLE;
+
+ case FieldDescriptor::TYPE_BOOL:
+ return OBJECTIVECTYPE_BOOLEAN;
+
+ case FieldDescriptor::TYPE_STRING:
+ return OBJECTIVECTYPE_STRING;
+
+ case FieldDescriptor::TYPE_BYTES:
+ return OBJECTIVECTYPE_DATA;
+
+ case FieldDescriptor::TYPE_ENUM:
+ return OBJECTIVECTYPE_ENUM;
+
+ case FieldDescriptor::TYPE_GROUP:
+ case FieldDescriptor::TYPE_MESSAGE:
+ return OBJECTIVECTYPE_MESSAGE;
+ }
+
+ // Some compilers report reaching end of function even though all cases of
+ // the enum are handed in the switch.
+ GOOGLE_LOG(FATAL) << "Can't get here.";
+ return OBJECTIVECTYPE_INT32;
+}
+
+bool IsPrimitiveType(const FieldDescriptor* field) {
+ ObjectiveCType type = GetObjectiveCType(field);
+ switch (type) {
+ case OBJECTIVECTYPE_INT32:
+ case OBJECTIVECTYPE_UINT32:
+ case OBJECTIVECTYPE_INT64:
+ case OBJECTIVECTYPE_UINT64:
+ case OBJECTIVECTYPE_FLOAT:
+ case OBJECTIVECTYPE_DOUBLE:
+ case OBJECTIVECTYPE_BOOLEAN:
+ case OBJECTIVECTYPE_ENUM:
+ return true;
+ break;
+ default:
+ return false;
+ }
+}
+
+bool IsReferenceType(const FieldDescriptor* field) {
+ return !IsPrimitiveType(field);
+}
+
+static std::string HandleExtremeFloatingPoint(std::string val,
+ bool add_float_suffix) {
+ if (val == "nan") {
+ return "NAN";
+ } else if (val == "inf") {
+ return "INFINITY";
+ } else if (val == "-inf") {
+ return "-INFINITY";
+ } else {
+ // float strings with ., e or E need to have f appended
+ if (add_float_suffix && (val.find(".") != std::string::npos ||
+ val.find("e") != std::string::npos ||
+ val.find("E") != std::string::npos)) {
+ val += "f";
+ }
+ return val;
+ }
+}
+
+std::string GPBGenericValueFieldName(const FieldDescriptor* field) {
+ // Returns the field within the GPBGenericValue union to use for the given
+ // field.
+ if (field->is_repeated()) {
+ return "valueMessage";
+ }
+ switch (field->cpp_type()) {
+ case FieldDescriptor::CPPTYPE_INT32:
+ return "valueInt32";
+ case FieldDescriptor::CPPTYPE_UINT32:
+ return "valueUInt32";
+ case FieldDescriptor::CPPTYPE_INT64:
+ return "valueInt64";
+ case FieldDescriptor::CPPTYPE_UINT64:
+ return "valueUInt64";
+ case FieldDescriptor::CPPTYPE_FLOAT:
+ return "valueFloat";
+ case FieldDescriptor::CPPTYPE_DOUBLE:
+ return "valueDouble";
+ case FieldDescriptor::CPPTYPE_BOOL:
+ return "valueBool";
+ case FieldDescriptor::CPPTYPE_STRING:
+ if (field->type() == FieldDescriptor::TYPE_BYTES) {
+ return "valueData";
+ } else {
+ return "valueString";
+ }
+ case FieldDescriptor::CPPTYPE_ENUM:
+ return "valueEnum";
+ case FieldDescriptor::CPPTYPE_MESSAGE:
+ return "valueMessage";
+ }
+
+ // Some compilers report reaching end of function even though all cases of
+ // the enum are handed in the switch.
+ GOOGLE_LOG(FATAL) << "Can't get here.";
+ return std::string();
+}
+
+
+std::string DefaultValue(const FieldDescriptor* field) {
+ // Repeated fields don't have defaults.
+ if (field->is_repeated()) {
+ return "nil";
+ }
+
+ // Switch on cpp_type since we need to know which default_value_* method
+ // of FieldDescriptor to call.
+ switch (field->cpp_type()) {
+ case FieldDescriptor::CPPTYPE_INT32:
+ // gcc and llvm reject the decimal form of kint32min and kint64min.
+ if (field->default_value_int32() == INT_MIN) {
+ return "-0x80000000";
+ }
+ return StrCat(field->default_value_int32());
+ case FieldDescriptor::CPPTYPE_UINT32:
+ return StrCat(field->default_value_uint32()) + "U";
+ case FieldDescriptor::CPPTYPE_INT64:
+ // gcc and llvm reject the decimal form of kint32min and kint64min.
+ if (field->default_value_int64() == LLONG_MIN) {
+ return "-0x8000000000000000LL";
+ }
+ return StrCat(field->default_value_int64()) + "LL";
+ case FieldDescriptor::CPPTYPE_UINT64:
+ return StrCat(field->default_value_uint64()) + "ULL";
+ case FieldDescriptor::CPPTYPE_DOUBLE:
+ return HandleExtremeFloatingPoint(
+ SimpleDtoa(field->default_value_double()), false);
+ case FieldDescriptor::CPPTYPE_FLOAT:
+ return HandleExtremeFloatingPoint(
+ SimpleFtoa(field->default_value_float()), true);
+ case FieldDescriptor::CPPTYPE_BOOL:
+ return field->default_value_bool() ? "YES" : "NO";
+ case FieldDescriptor::CPPTYPE_STRING: {
+ const bool has_default_value = field->has_default_value();
+ const std::string& default_string = field->default_value_string();
+ if (!has_default_value || default_string.length() == 0) {
+ // If the field is defined as being the empty string,
+ // then we will just assign to nil, as the empty string is the
+ // default for both strings and data.
+ return "nil";
+ }
+ if (field->type() == FieldDescriptor::TYPE_BYTES) {
+ // We want constant fields in our data structures so we can
+ // declare them as static. To achieve this we cheat and stuff
+ // a escaped c string (prefixed with a length) into the data
+ // field, and cast it to an (NSData*) so it will compile.
+ // The runtime library knows how to handle it.
+
+ // Must convert to a standard byte order for packing length into
+ // a cstring.
+ uint32_t length = ghtonl(default_string.length());
+ std::string bytes((const char*)&length, sizeof(length));
+ bytes.append(default_string);
+ return "(NSData*)\"" + EscapeTrigraphs(CEscape(bytes)) + "\"";
+ } else {
+ return "@\"" + EscapeTrigraphs(CEscape(default_string)) + "\"";
+ }
+ }
+ case FieldDescriptor::CPPTYPE_ENUM:
+ return EnumValueName(field->default_value_enum());
+ case FieldDescriptor::CPPTYPE_MESSAGE:
+ return "nil";
+ }
+
+ // Some compilers report reaching end of function even though all cases of
+ // the enum are handed in the switch.
+ GOOGLE_LOG(FATAL) << "Can't get here.";
+ return std::string();
+}
+
+bool HasNonZeroDefaultValue(const FieldDescriptor* field) {
+ // Repeated fields don't have defaults.
+ if (field->is_repeated()) {
+ return false;
+ }
+
+ // As much as checking field->has_default_value() seems useful, it isn't
+ // because of enums. proto2 syntax allows the first item in an enum (the
+ // default) to be non zero. So checking field->has_default_value() would
+ // result in missing this non zero default. See MessageWithOneBasedEnum in
+ // objectivec/Tests/unittest_objc.proto for a test Message to confirm this.
+
+ // Some proto file set the default to the zero value, so make sure the value
+ // isn't the zero case.
+ switch (field->cpp_type()) {
+ case FieldDescriptor::CPPTYPE_INT32:
+ return field->default_value_int32() != 0;
+ case FieldDescriptor::CPPTYPE_UINT32:
+ return field->default_value_uint32() != 0U;
+ case FieldDescriptor::CPPTYPE_INT64:
+ return field->default_value_int64() != 0LL;
+ case FieldDescriptor::CPPTYPE_UINT64:
+ return field->default_value_uint64() != 0ULL;
+ case FieldDescriptor::CPPTYPE_DOUBLE:
+ return field->default_value_double() != 0.0;
+ case FieldDescriptor::CPPTYPE_FLOAT:
+ return field->default_value_float() != 0.0f;
+ case FieldDescriptor::CPPTYPE_BOOL:
+ return field->default_value_bool();
+ case FieldDescriptor::CPPTYPE_STRING: {
+ const std::string& default_string = field->default_value_string();
+ return default_string.length() != 0;
+ }
+ case FieldDescriptor::CPPTYPE_ENUM:
+ return field->default_value_enum()->number() != 0;
+ case FieldDescriptor::CPPTYPE_MESSAGE:
+ return false;
+ }
+
+ // Some compilers report reaching end of function even though all cases of
+ // the enum are handed in the switch.
+ GOOGLE_LOG(FATAL) << "Can't get here.";
+ return false;
+}
+
+std::string BuildFlagsString(const FlagType flag_type,
+ const std::vector<std::string>& strings) {
+ if (strings.empty()) {
+ return GetZeroEnumNameForFlagType(flag_type);
+ } else if (strings.size() == 1) {
+ return strings[0];
+ }
+ std::string string("(" + GetEnumNameForFlagType(flag_type) + ")(");
+ for (size_t i = 0; i != strings.size(); ++i) {
+ if (i > 0) {
+ string.append(" | ");
+ }
+ string.append(strings[i]);
+ }
+ string.append(")");
+ return string;
+}
+
+std::string BuildCommentsString(const SourceLocation& location,
+ bool prefer_single_line) {
+ const std::string& comments = location.leading_comments.empty()
+ ? location.trailing_comments
+ : location.leading_comments;
+ std::vector<std::string> lines;
+ lines = Split(comments, "\n", false);
+ while (!lines.empty() && lines.back().empty()) {
+ lines.pop_back();
+ }
+ // If there are no comments, just return an empty string.
+ if (lines.empty()) {
+ return "";
+ }
+
+ std::string prefix;
+ std::string suffix;
+ std::string final_comments;
+ std::string epilogue;
+
+ bool add_leading_space = false;
+
+ if (prefer_single_line && lines.size() == 1) {
+ prefix = "/** ";
+ suffix = " */\n";
+ } else {
+ prefix = "* ";
+ suffix = "\n";
+ final_comments += "/**\n";
+ epilogue = " **/\n";
+ add_leading_space = true;
+ }
+
+ for (int i = 0; i < lines.size(); i++) {
+ std::string line = StripPrefixString(lines[i], " ");
+ // HeaderDoc and appledoc use '\' and '@' for markers; escape them.
+ line = StringReplace(line, "\\", "\\\\", true);
+ line = StringReplace(line, "@", "\\@", true);
+ // Decouple / from * to not have inline comments inside comments.
+ line = StringReplace(line, "/*", "/\\*", true);
+ line = StringReplace(line, "*/", "*\\/", true);
+ line = prefix + line;
+ StripWhitespace(&line);
+ // If not a one line, need to add the first space before *, as
+ // StripWhitespace would have removed it.
+ line = (add_leading_space ? " " : "") + line;
+ final_comments += line + suffix;
+ }
+ final_comments += epilogue;
+ return final_comments;
+}
+
+// Making these a generator option for folks that don't use CocoaPods, but do
+// want to put the library in a framework is an interesting question. The
+// problem is it means changing sources shipped with the library to actually
+// use a different value; so it isn't as simple as a option.
+const char* const ProtobufLibraryFrameworkName = "Protobuf";
+
+std::string ProtobufFrameworkImportSymbol(const std::string& framework_name) {
+ // GPB_USE_[framework_name]_FRAMEWORK_IMPORTS
+ std::string result = std::string("GPB_USE_");
+ result += ToUpper(framework_name);
+ result += "_FRAMEWORK_IMPORTS";
+ return result;
+}
+
+bool IsProtobufLibraryBundledProtoFile(const FileDescriptor* file) {
+ // We don't check the name prefix or proto package because some files
+ // (descriptor.proto), aren't shipped generated by the library, so this
+ // seems to be the safest way to only catch the ones shipped.
+ const std::string name = file->name();
+ if (name == "google/protobuf/any.proto" ||
+ name == "google/protobuf/api.proto" ||
+ name == "google/protobuf/duration.proto" ||
+ name == "google/protobuf/empty.proto" ||
+ name == "google/protobuf/field_mask.proto" ||
+ name == "google/protobuf/source_context.proto" ||
+ name == "google/protobuf/struct.proto" ||
+ name == "google/protobuf/timestamp.proto" ||
+ name == "google/protobuf/type.proto" ||
+ name == "google/protobuf/wrappers.proto") {
+ return true;
+ }
+ return false;
+}
+
+bool ReadLine(StringPiece* input, StringPiece* line) {
+ for (int len = 0; len < input->size(); ++len) {
+ if (ascii_isnewline((*input)[len])) {
+ *line = StringPiece(input->data(), len);
+ ++len; // advance over the newline
+ *input = StringPiece(input->data() + len, input->size() - len);
+ return true;
+ }
+ }
+ return false; // Ran out of input with no newline.
+}
+
+void RemoveComment(StringPiece* input) {
+ int offset = input->find('#');
+ if (offset != StringPiece::npos) {
+ input->remove_suffix(input->length() - offset);
+ }
+}
+
+namespace {
+
+class ExpectedPrefixesCollector : public LineConsumer {
+ public:
+ ExpectedPrefixesCollector(std::map<std::string, std::string>* inout_package_to_prefix_map)
+ : prefix_map_(inout_package_to_prefix_map) {}
+
+ virtual bool ConsumeLine(const StringPiece& line, std::string* out_error) override;
+
+ private:
+ std::map<std::string, std::string>* prefix_map_;
+};
+
+bool ExpectedPrefixesCollector::ConsumeLine(
+ const StringPiece& line, std::string* out_error) {
+ int offset = line.find('=');
+ if (offset == StringPiece::npos) {
+ *out_error = std::string("Expected prefixes file line without equal sign: '") +
+ std::string(line) + "'.";
+ return false;
+ }
+ StringPiece package = line.substr(0, offset);
+ StringPiece prefix = line.substr(offset + 1);
+ TrimWhitespace(&package);
+ TrimWhitespace(&prefix);
+ MaybeUnQuote(&prefix);
+ // Don't really worry about error checking the package/prefix for
+ // being valid. Assume the file is validated when it is created/edited.
+ (*prefix_map_)[std::string(package)] = std::string(prefix);
+ return true;
+}
+
+bool LoadExpectedPackagePrefixes(const Options& generation_options,
+ std::map<std::string, std::string>* prefix_map,
+ std::string* out_error) {
+ if (generation_options.expected_prefixes_path.empty()) {
+ return true;
+ }
+
+ ExpectedPrefixesCollector collector(prefix_map);
+ return ParseSimpleFile(
+ generation_options.expected_prefixes_path, &collector, out_error);
+}
+
+bool ValidateObjCClassPrefix(
+ const FileDescriptor* file, const std::string& expected_prefixes_path,
+ const std::map<std::string, std::string>& expected_package_prefixes,
+ bool prefixes_must_be_registered, bool require_prefixes,
+ std::string* out_error) {
+ // Reminder: An explicit prefix option of "" is valid in case the default
+ // prefixing is set to use the proto package and a file needs to be generated
+ // without any prefix at all (for legacy reasons).
+
+ bool has_prefix = file->options().has_objc_class_prefix();
+ bool have_expected_prefix_file = !expected_prefixes_path.empty();
+
+ const std::string prefix = file->options().objc_class_prefix();
+ const std::string package = file->package();
+
+ // NOTE: src/google/protobuf/compiler/plugin.cc makes use of cerr for some
+ // error cases, so it seems to be ok to use as a back door for warnings.
+
+ // Check: Error - See if there was an expected prefix for the package and
+ // report if it doesn't match (wrong or missing).
+ std::map<std::string, std::string>::const_iterator package_match =
+ expected_package_prefixes.find(package);
+ if (package_match != expected_package_prefixes.end()) {
+ // There was an entry, and...
+ if (has_prefix && package_match->second == prefix) {
+ // ...it matches. All good, out of here!
+ return true;
+ } else {
+ // ...it didn't match!
+ *out_error = "error: Expected 'option objc_class_prefix = \"" +
+ package_match->second + "\";' for package '" + package +
+ "' in '" + file->name() + "'";
+ if (has_prefix) {
+ *out_error += "; but found '" + prefix + "' instead";
+ }
+ *out_error += ".";
+ return false;
+ }
+ }
+
+ // If there was no prefix option, we're done at this point.
+ if (!has_prefix) {
+ if (require_prefixes) {
+ *out_error =
+ "error: '" + file->name() + "' does not have a required 'option" +
+ " objc_class_prefix'.";
+ return false;
+ }
+ return true;
+ }
+
+ // When the prefix is non empty, check it against the expected entries.
+ if (!prefix.empty() && have_expected_prefix_file) {
+ // For a non empty prefix, look for any other package that uses the prefix.
+ std::string other_package_for_prefix;
+ for (std::map<std::string, std::string>::const_iterator i =
+ expected_package_prefixes.begin();
+ i != expected_package_prefixes.end(); ++i) {
+ if (i->second == prefix) {
+ other_package_for_prefix = i->first;
+ break;
+ }
+ }
+
+ // Check: Warning - If the file does not have a package, check whether the
+ // prefix was declared is being used by another package or not. This is
+ // a special case for empty packages.
+ if (package.empty()) {
+ // The file does not have a package and ...
+ if (other_package_for_prefix.empty()) {
+ // ... no other package has declared that prefix.
+ std::cerr
+ << "protoc:0: warning: File '" << file->name() << "' has no "
+ << "package. Consider adding a new package to the proto and adding '"
+ << "new.package = " << prefix << "' to the expected prefixes file ("
+ << expected_prefixes_path << ")." << std::endl;
+ std::cerr.flush();
+ } else {
+ // ... another package has declared the same prefix.
+ std::cerr
+ << "protoc:0: warning: File '" << file->name() << "' has no package "
+ << "and package '" << other_package_for_prefix << "' already uses '"
+ << prefix << "' as its prefix. Consider either adding a new package "
+ << "to the proto, or reusing one of the packages already using this "
+ << "prefix in the expected prefixes file ("
+ << expected_prefixes_path << ")." << std::endl;
+ std::cerr.flush();
+ }
+ return true;
+ }
+
+ // Check: Error - Make sure the prefix wasn't expected for a different
+ // package (overlap is allowed, but it has to be listed as an expected
+ // overlap).
+ if (!other_package_for_prefix.empty()) {
+ *out_error =
+ "error: Found 'option objc_class_prefix = \"" + prefix +
+ "\";' in '" + file->name() +
+ "'; that prefix is already used for 'package " +
+ other_package_for_prefix + ";'. It can only be reused by listing " +
+ "it in the expected file (" +
+ expected_prefixes_path + ").";
+ return false; // Only report first usage of the prefix.
+ }
+ } // !prefix.empty()
+
+ // Check: Warning - Make sure the prefix is is a reasonable value according
+ // to Apple's rules (the checks above implicitly whitelist anything that
+ // doesn't meet these rules).
+ if (!prefix.empty() && !ascii_isupper(prefix[0])) {
+ std::cerr
+ << "protoc:0: warning: Invalid 'option objc_class_prefix = \""
+ << prefix << "\";' in '" << file->name() << "';"
+ << " it should start with a capital letter." << std::endl;
+ std::cerr.flush();
+ }
+ if (!prefix.empty() && prefix.length() < 3) {
+ // Apple reserves 2 character prefixes for themselves. They do use some
+ // 3 character prefixes, but they haven't updated the rules/docs.
+ std::cerr
+ << "protoc:0: warning: Invalid 'option objc_class_prefix = \""
+ << prefix << "\";' in '" << file->name() << "';"
+ << " Apple recommends they should be at least 3 characters long."
+ << std::endl;
+ std::cerr.flush();
+ }
+
+ // Check: Error/Warning - If the given package/prefix pair wasn't expected,
+ // issue a error/warning to added to the file.
+ if (have_expected_prefix_file) {
+ if (prefixes_must_be_registered) {
+ *out_error =
+ "error: '" + file->name() + "' has 'option objc_class_prefix = \"" +
+ prefix + "\";', but it is not registered; add it to the expected " +
+ "prefixes file (" + expected_prefixes_path + ") for the package '" +
+ package + "'.";
+ return false;
+ }
+
+ std::cerr
+ << "protoc:0: warning: Found unexpected 'option objc_class_prefix = \""
+ << prefix << "\";' in '" << file->name() << "';"
+ << " consider adding it to the expected prefixes file ("
+ << expected_prefixes_path << ")." << std::endl;
+ std::cerr.flush();
+ }
+
+ return true;
+}
+
+} // namespace
+
+bool ValidateObjCClassPrefixes(const std::vector<const FileDescriptor*>& files,
+ const Options& generation_options,
+ std::string* out_error) {
+ // Allow a '-' as the path for the expected prefixes to completely disable
+ // even the most basic of checks.
+ if (generation_options.expected_prefixes_path == "-") {
+ return true;
+ }
+
+ // Load the expected package prefixes, if available, to validate against.
+ std::map<std::string, std::string> expected_package_prefixes;
+ if (!LoadExpectedPackagePrefixes(generation_options,
+ &expected_package_prefixes,
+ out_error)) {
+ return false;
+ }
+
+ for (int i = 0; i < files.size(); i++) {
+ bool should_skip =
+ (std::find(generation_options.expected_prefixes_suppressions.begin(),
+ generation_options.expected_prefixes_suppressions.end(),
+ files[i]->name())
+ != generation_options.expected_prefixes_suppressions.end());
+ if (should_skip) {
+ continue;
+ }
+
+ bool is_valid =
+ ValidateObjCClassPrefix(files[i],
+ generation_options.expected_prefixes_path,
+ expected_package_prefixes,
+ generation_options.prefixes_must_be_registered,
+ generation_options.require_prefixes,
+ out_error);
+ if (!is_valid) {
+ return false;
+ }
+ }
+ return true;
+}
+
+TextFormatDecodeData::TextFormatDecodeData() { }
+
+TextFormatDecodeData::~TextFormatDecodeData() { }
+
+void TextFormatDecodeData::AddString(int32_t key,
+ const std::string& input_for_decode,
+ const std::string& desired_output) {
+ for (std::vector<DataEntry>::const_iterator i = entries_.begin();
+ i != entries_.end(); ++i) {
+ if (i->first == key) {
+ std::cerr << "error: duplicate key (" << key
+ << ") making TextFormat data, input: \"" << input_for_decode
+ << "\", desired: \"" << desired_output << "\"." << std::endl;
+ std::cerr.flush();
+ abort();
+ }
+ }
+
+ const std::string& data = TextFormatDecodeData::DecodeDataForString(
+ input_for_decode, desired_output);
+ entries_.push_back(DataEntry(key, data));
+}
+
+std::string TextFormatDecodeData::Data() const {
+ std::ostringstream data_stringstream;
+
+ if (num_entries() > 0) {
+ io::OstreamOutputStream data_outputstream(&data_stringstream);
+ io::CodedOutputStream output_stream(&data_outputstream);
+
+ output_stream.WriteVarint32(num_entries());
+ for (std::vector<DataEntry>::const_iterator i = entries_.begin();
+ i != entries_.end(); ++i) {
+ output_stream.WriteVarint32(i->first);
+ output_stream.WriteString(i->second);
+ }
+ }
+
+ data_stringstream.flush();
+ return data_stringstream.str();
+}
+
+namespace {
+
+// Helper to build up the decode data for a string.
+class DecodeDataBuilder {
+ public:
+ DecodeDataBuilder() { Reset(); }
+
+ bool AddCharacter(const char desired, const char input);
+ void AddUnderscore() {
+ Push();
+ need_underscore_ = true;
+ }
+ std::string Finish() {
+ Push();
+ return decode_data_;
+ }
+
+ private:
+ static constexpr uint8_t kAddUnderscore = 0x80;
+
+ static constexpr uint8_t kOpAsIs = 0x00;
+ static constexpr uint8_t kOpFirstUpper = 0x40;
+ static constexpr uint8_t kOpFirstLower = 0x20;
+ static constexpr uint8_t kOpAllUpper = 0x60;
+
+ static constexpr int kMaxSegmentLen = 0x1f;
+
+ void AddChar(const char desired) {
+ ++segment_len_;
+ is_all_upper_ &= ascii_isupper(desired);
+ }
+
+ void Push() {
+ uint8_t op = (op_ | segment_len_);
+ if (need_underscore_) op |= kAddUnderscore;
+ if (op != 0) {
+ decode_data_ += (char)op;
+ }
+ Reset();
+ }
+
+ bool AddFirst(const char desired, const char input) {
+ if (desired == input) {
+ op_ = kOpAsIs;
+ } else if (desired == ascii_toupper(input)) {
+ op_ = kOpFirstUpper;
+ } else if (desired == ascii_tolower(input)) {
+ op_ = kOpFirstLower;
+ } else {
+ // Can't be transformed to match.
+ return false;
+ }
+ AddChar(desired);
+ return true;
+ }
+
+ void Reset() {
+ need_underscore_ = false;
+ op_ = 0;
+ segment_len_ = 0;
+ is_all_upper_ = true;
+ }
+
+ bool need_underscore_;
+ bool is_all_upper_;
+ uint8_t op_;
+ int segment_len_;
+
+ std::string decode_data_;
+};
+
+bool DecodeDataBuilder::AddCharacter(const char desired, const char input) {
+ // If we've hit the max size, push to start a new segment.
+ if (segment_len_ == kMaxSegmentLen) {
+ Push();
+ }
+ if (segment_len_ == 0) {
+ return AddFirst(desired, input);
+ }
+
+ // Desired and input match...
+ if (desired == input) {
+ // If we aren't transforming it, or we're upper casing it and it is
+ // supposed to be uppercase; just add it to the segment.
+ if ((op_ != kOpAllUpper) || ascii_isupper(desired)) {
+ AddChar(desired);
+ return true;
+ }
+
+ // Add the current segment, and start the next one.
+ Push();
+ return AddFirst(desired, input);
+ }
+
+ // If we need to uppercase, and everything so far has been uppercase,
+ // promote op to AllUpper.
+ if ((desired == ascii_toupper(input)) && is_all_upper_) {
+ op_ = kOpAllUpper;
+ AddChar(desired);
+ return true;
+ }
+
+ // Give up, push and start a new segment.
+ Push();
+ return AddFirst(desired, input);
+}
+
+// If decode data can't be generated, a directive for the raw string
+// is used instead.
+std::string DirectDecodeString(const std::string& str) {
+ std::string result;
+ result += (char)'\0'; // Marker for full string.
+ result += str;
+ result += (char)'\0'; // End of string.
+ return result;
+}
+
+} // namespace
+
+// static
+std::string TextFormatDecodeData::DecodeDataForString(
+ const std::string& input_for_decode, const std::string& desired_output) {
+ if (input_for_decode.empty() || desired_output.empty()) {
+ std::cerr << "error: got empty string for making TextFormat data, input: \""
+ << input_for_decode << "\", desired: \"" << desired_output << "\"."
+ << std::endl;
+ std::cerr.flush();
+ abort();
+ }
+ if ((input_for_decode.find('\0') != std::string::npos) ||
+ (desired_output.find('\0') != std::string::npos)) {
+ std::cerr << "error: got a null char in a string for making TextFormat data,"
+ << " input: \"" << CEscape(input_for_decode) << "\", desired: \""
+ << CEscape(desired_output) << "\"." << std::endl;
+ std::cerr.flush();
+ abort();
+ }
+
+ DecodeDataBuilder builder;
+
+ // Walk the output building it from the input.
+ int x = 0;
+ for (int y = 0; y < desired_output.size(); y++) {
+ const char d = desired_output[y];
+ if (d == '_') {
+ builder.AddUnderscore();
+ continue;
+ }
+
+ if (x >= input_for_decode.size()) {
+ // Out of input, no way to encode it, just return a full decode.
+ return DirectDecodeString(desired_output);
+ }
+ if (builder.AddCharacter(d, input_for_decode[x])) {
+ ++x; // Consumed one input
+ } else {
+ // Couldn't transform for the next character, just return a full decode.
+ return DirectDecodeString(desired_output);
+ }
+ }
+
+ if (x != input_for_decode.size()) {
+ // Extra input (suffix from name sanitizing?), just return a full decode.
+ return DirectDecodeString(desired_output);
+ }
+
+ // Add the end marker.
+ return builder.Finish() + (char)'\0';
+}
+
+namespace {
+
+class Parser {
+ public:
+ Parser(LineConsumer* line_consumer)
+ : line_consumer_(line_consumer), line_(0) {}
+
+ // Feeds in some input, parse what it can, returning success/failure. Calling
+ // again after an error is undefined.
+ bool ParseChunk(StringPiece chunk, std::string* out_error);
+
+ // Should be called to finish parsing (after all input has been provided via
+ // successful calls to ParseChunk(), calling after a ParseChunk() failure is
+ // undefined). Returns success/failure.
+ bool Finish(std::string* out_error);
+
+ int last_line() const { return line_; }
+
+ private:
+ LineConsumer* line_consumer_;
+ int line_;
+ std::string leftover_;
+};
+
+bool Parser::ParseChunk(StringPiece chunk, std::string* out_error) {
+ StringPiece full_chunk;
+ if (!leftover_.empty()) {
+ leftover_ += std::string(chunk);
+ full_chunk = StringPiece(leftover_);
+ } else {
+ full_chunk = chunk;
+ }
+
+ StringPiece line;
+ while (ReadLine(&full_chunk, &line)) {
+ ++line_;
+ RemoveComment(&line);
+ TrimWhitespace(&line);
+ if (!line.empty() && !line_consumer_->ConsumeLine(line, out_error)) {
+ if (out_error->empty()) {
+ *out_error = "ConsumeLine failed without setting an error.";
+ }
+ leftover_.clear();
+ return false;
+ }
+ }
+
+ if (full_chunk.empty()) {
+ leftover_.clear();
+ } else {
+ leftover_ = std::string(full_chunk);
+ }
+ return true;
+}
+
+bool Parser::Finish(std::string* out_error) {
+ // If there is still something to go, flush it with a newline.
+ if (!leftover_.empty() && !ParseChunk("\n", out_error)) {
+ return false;
+ }
+ // This really should never fail if ParseChunk succeeded, but check to be sure.
+ if (!leftover_.empty()) {
+ *out_error = "ParseSimple Internal error: finished with pending data.";
+ return false;
+ }
+ return true;
+}
+
+std::string FullErrorString(const std::string& name, int line_num, const std::string& msg) {
+ return std::string("error: ") + name + " Line " + StrCat(line_num) + ", " + msg;
+}
+
+} // namespace
+
+LineConsumer::LineConsumer() {}
+
+LineConsumer::~LineConsumer() {}
+
+bool ParseSimpleFile(const std::string& path, LineConsumer* line_consumer,
+ std::string* out_error) {
+ int fd;
+ do {
+ fd = posix::open(path.c_str(), O_RDONLY);
+ } while (fd < 0 && errno == EINTR);
+ if (fd < 0) {
+ *out_error = std::string("error: Unable to open \"") + path + "\", " +
+ strerror(errno);
+ return false;
+ }
+ io::FileInputStream file_stream(fd);
+ file_stream.SetCloseOnDelete(true);
+
+ return ParseSimpleStream(file_stream, path, line_consumer, out_error);
+}
+
+bool ParseSimpleStream(io::ZeroCopyInputStream& input_stream,
+ const std::string& stream_name,
+ LineConsumer* line_consumer,
+ std::string* out_error) {
+ std::string local_error;
+ Parser parser(line_consumer);
+ const void* buf;
+ int buf_len;
+ while (input_stream.Next(&buf, &buf_len)) {
+ if (buf_len == 0) {
+ continue;
+ }
+
+ if (!parser.ParseChunk(StringPiece(static_cast<const char*>(buf), buf_len),
+ &local_error)) {
+ *out_error = FullErrorString(stream_name, parser.last_line(), local_error);
+ return false;
+ }
+ }
+ if (!parser.Finish(&local_error)) {
+ *out_error = FullErrorString(stream_name, parser.last_line(), local_error);
+ return false;
+ }
+ return true;
+}
+
+ImportWriter::ImportWriter(
+ const std::string& generate_for_named_framework,
+ const std::string& named_framework_to_proto_path_mappings_path,
+ const std::string& runtime_import_prefix, bool include_wkt_imports)
+ : generate_for_named_framework_(generate_for_named_framework),
+ named_framework_to_proto_path_mappings_path_(
+ named_framework_to_proto_path_mappings_path),
+ runtime_import_prefix_(runtime_import_prefix),
+ include_wkt_imports_(include_wkt_imports),
+ need_to_parse_mapping_file_(true) {}
+
+ImportWriter::~ImportWriter() {}
+
+void ImportWriter::AddFile(const FileDescriptor* file,
+ const std::string& header_extension) {
+ if (IsProtobufLibraryBundledProtoFile(file)) {
+ // The imports of the WKTs are only needed within the library itself,
+ // in other cases, they get skipped because the generated code already
+ // import GPBProtocolBuffers.h and hence proves them.
+ if (include_wkt_imports_) {
+ const std::string header_name =
+ "GPB" + FilePathBasename(file) + header_extension;
+ protobuf_imports_.push_back(header_name);
+ }
+ return;
+ }
+
+ // Lazy parse any mappings.
+ if (need_to_parse_mapping_file_) {
+ ParseFrameworkMappings();
+ }
+
+ std::map<std::string, std::string>::iterator proto_lookup =
+ proto_file_to_framework_name_.find(file->name());
+ if (proto_lookup != proto_file_to_framework_name_.end()) {
+ other_framework_imports_.push_back(
+ proto_lookup->second + "/" +
+ FilePathBasename(file) + header_extension);
+ return;
+ }
+
+ if (!generate_for_named_framework_.empty()) {
+ other_framework_imports_.push_back(
+ generate_for_named_framework_ + "/" +
+ FilePathBasename(file) + header_extension);
+ return;
+ }
+
+ other_imports_.push_back(FilePath(file) + header_extension);
+}
+
+void ImportWriter::Print(io::Printer* printer) const {
+ bool add_blank_line = false;
+
+ if (!protobuf_imports_.empty()) {
+ PrintRuntimeImports(printer, protobuf_imports_, runtime_import_prefix_);
+ add_blank_line = true;
+ }
+
+ if (!other_framework_imports_.empty()) {
+ if (add_blank_line) {
+ printer->Print("\n");
+ }
+
+ for (std::vector<std::string>::const_iterator iter =
+ other_framework_imports_.begin();
+ iter != other_framework_imports_.end(); ++iter) {
+ printer->Print(
+ "#import <$header$>\n",
+ "header", *iter);
+ }
+
+ add_blank_line = true;
+ }
+
+ if (!other_imports_.empty()) {
+ if (add_blank_line) {
+ printer->Print("\n");
+ }
+
+ for (std::vector<std::string>::const_iterator iter = other_imports_.begin();
+ iter != other_imports_.end(); ++iter) {
+ printer->Print(
+ "#import \"$header$\"\n",
+ "header", *iter);
+ }
+ }
+}
+
+void ImportWriter::PrintRuntimeImports(
+ io::Printer* printer, const std::vector<std::string>& header_to_import,
+ const std::string& runtime_import_prefix, bool default_cpp_symbol) {
+ // Given an override, use that.
+ if (!runtime_import_prefix.empty()) {
+ for (const auto& header : header_to_import) {
+ printer->Print(
+ " #import \"$import_prefix$/$header$\"\n",
+ "import_prefix", runtime_import_prefix,
+ "header", header);
+ }
+ return;
+ }
+
+ const std::string framework_name(ProtobufLibraryFrameworkName);
+ const std::string cpp_symbol(ProtobufFrameworkImportSymbol(framework_name));
+
+ if (default_cpp_symbol) {
+ printer->Print(
+ "// This CPP symbol can be defined to use imports that match up to the framework\n"
+ "// imports needed when using CocoaPods.\n"
+ "#if !defined($cpp_symbol$)\n"
+ " #define $cpp_symbol$ 0\n"
+ "#endif\n"
+ "\n",
+ "cpp_symbol", cpp_symbol);
+ }
+
+ printer->Print(
+ "#if $cpp_symbol$\n",
+ "cpp_symbol", cpp_symbol);
+ for (const auto& header : header_to_import) {
+ printer->Print(
+ " #import <$framework_name$/$header$>\n",
+ "framework_name", framework_name,
+ "header", header);
+ }
+ printer->Print(
+ "#else\n");
+ for (const auto& header : header_to_import) {
+ printer->Print(
+ " #import \"$header$\"\n",
+ "header", header);
+ }
+ printer->Print(
+ "#endif\n");
+}
+
+void ImportWriter::ParseFrameworkMappings() {
+ need_to_parse_mapping_file_ = false;
+ if (named_framework_to_proto_path_mappings_path_.empty()) {
+ return; // Nothing to do.
+ }
+
+ ProtoFrameworkCollector collector(&proto_file_to_framework_name_);
+ std::string parse_error;
+ if (!ParseSimpleFile(named_framework_to_proto_path_mappings_path_,
+ &collector, &parse_error)) {
+ std::cerr << "error parsing " << named_framework_to_proto_path_mappings_path_
+ << " : " << parse_error << std::endl;
+ std::cerr.flush();
+ }
+}
+
+bool ImportWriter::ProtoFrameworkCollector::ConsumeLine(
+ const StringPiece& line, std::string* out_error) {
+ int offset = line.find(':');
+ if (offset == StringPiece::npos) {
+ *out_error =
+ std::string("Framework/proto file mapping line without colon sign: '") +
+ std::string(line) + "'.";
+ return false;
+ }
+ StringPiece framework_name = line.substr(0, offset);
+ StringPiece proto_file_list = line.substr(offset + 1);
+ TrimWhitespace(&framework_name);
+
+ int start = 0;
+ while (start < proto_file_list.length()) {
+ offset = proto_file_list.find(',', start);
+ if (offset == StringPiece::npos) {
+ offset = proto_file_list.length();
+ }
+
+ StringPiece proto_file = proto_file_list.substr(start, offset - start);
+ TrimWhitespace(&proto_file);
+ if (!proto_file.empty()) {
+ std::map<std::string, std::string>::iterator existing_entry =
+ map_->find(std::string(proto_file));
+ if (existing_entry != map_->end()) {
+ std::cerr << "warning: duplicate proto file reference, replacing "
+ "framework entry for '"
+ << std::string(proto_file) << "' with '" << std::string(framework_name)
+ << "' (was '" << existing_entry->second << "')." << std::endl;
+ std::cerr.flush();
+ }
+
+ if (proto_file.find(' ') != StringPiece::npos) {
+ std::cerr << "note: framework mapping file had a proto file with a "
+ "space in, hopefully that isn't a missing comma: '"
+ << std::string(proto_file) << "'" << std::endl;
+ std::cerr.flush();
+ }
+
+ (*map_)[std::string(proto_file)] = std::string(framework_name);
+ }
+
+ start = offset + 1;
+ }
+
+ return true;
+}
+
+} // namespace objectivec
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_helpers.h b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_helpers.h
new file mode 100644
index 00000000..e6a3e436
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_helpers.h
@@ -0,0 +1,347 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Helper functions for generating ObjectiveC code.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_HELPERS_H__
+#define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_HELPERS_H__
+
+#include <string>
+#include <vector>
+
+#include <descriptor.h>
+#include <descriptor.pb.h>
+#include <io/zero_copy_stream.h>
+
+#include <port_def.inc>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace objectivec {
+
+// Get/Set if the proto package should be used to make the default prefix for
+// symbols. This will then impact most of the type naming apis below. It is done
+// as a global to not break any other generator reusing the methods since they
+// are exported.
+bool PROTOC_EXPORT UseProtoPackageAsDefaultPrefix();
+void PROTOC_EXPORT SetUseProtoPackageAsDefaultPrefix(bool on_or_off);
+// Get/Set the path to a file to load as exceptions when
+// `UseProtoPackageAsDefaultPrefixUseProtoPackageAsDefaultPrefix()` is `true`.
+// And empty string means there should be no exceptions loaded.
+std::string PROTOC_EXPORT GetProtoPackagePrefixExceptionList();
+void PROTOC_EXPORT SetProtoPackagePrefixExceptionList(
+ const std::string& file_path);
+
+// Generator options (see objectivec_generator.cc for a description of each):
+struct Options {
+ Options();
+ std::string expected_prefixes_path;
+ std::vector<std::string> expected_prefixes_suppressions;
+ std::string generate_for_named_framework;
+ std::string named_framework_to_proto_path_mappings_path;
+ std::string runtime_import_prefix;
+ bool prefixes_must_be_registered;
+ bool require_prefixes;
+};
+
+// Escape C++ trigraphs by escaping question marks to "\?".
+std::string PROTOC_EXPORT EscapeTrigraphs(const std::string& to_escape);
+
+// Remove white space from either end of a StringPiece.
+void PROTOC_EXPORT TrimWhitespace(StringPiece* input);
+
+// Returns true if the name requires a ns_returns_not_retained attribute applied
+// to it.
+bool PROTOC_EXPORT IsRetainedName(const std::string& name);
+
+// Returns true if the name starts with "init" and will need to have special
+// handling under ARC.
+bool PROTOC_EXPORT IsInitName(const std::string& name);
+
+// Gets the objc_class_prefix or the prefix made from the proto package.
+std::string PROTOC_EXPORT FileClassPrefix(const FileDescriptor* file);
+
+// Gets the path of the file we're going to generate (sans the .pb.h
+// extension). The path will be dependent on the objectivec package
+// declared in the proto package.
+std::string PROTOC_EXPORT FilePath(const FileDescriptor* file);
+
+// Just like FilePath(), but without the directory part.
+std::string PROTOC_EXPORT FilePathBasename(const FileDescriptor* file);
+
+// Gets the name of the root class we'll generate in the file. This class
+// is not meant for external consumption, but instead contains helpers that
+// the rest of the classes need
+std::string PROTOC_EXPORT FileClassName(const FileDescriptor* file);
+
+// These return the fully-qualified class name corresponding to the given
+// descriptor.
+std::string PROTOC_EXPORT ClassName(const Descriptor* descriptor);
+std::string PROTOC_EXPORT ClassName(const Descriptor* descriptor,
+ std::string* out_suffix_added);
+std::string PROTOC_EXPORT EnumName(const EnumDescriptor* descriptor);
+
+// Returns the fully-qualified name of the enum value corresponding to the
+// the descriptor.
+std::string PROTOC_EXPORT EnumValueName(const EnumValueDescriptor* descriptor);
+
+// Returns the name of the enum value corresponding to the descriptor.
+std::string PROTOC_EXPORT EnumValueShortName(const EnumValueDescriptor* descriptor);
+
+// Reverse what an enum does.
+std::string PROTOC_EXPORT UnCamelCaseEnumShortName(const std::string& name);
+
+// Returns the name to use for the extension (used as the method off the file's
+// Root class).
+std::string PROTOC_EXPORT ExtensionMethodName(const FieldDescriptor* descriptor);
+
+// Returns the transformed field name.
+std::string PROTOC_EXPORT FieldName(const FieldDescriptor* field);
+std::string PROTOC_EXPORT FieldNameCapitalized(const FieldDescriptor* field);
+
+// Returns the transformed oneof name.
+std::string PROTOC_EXPORT OneofEnumName(const OneofDescriptor* descriptor);
+std::string PROTOC_EXPORT OneofName(const OneofDescriptor* descriptor);
+std::string PROTOC_EXPORT OneofNameCapitalized(const OneofDescriptor* descriptor);
+
+// Returns a symbol that can be used in C code to refer to an Objective C
+// class without initializing the class.
+std::string PROTOC_EXPORT ObjCClass(const std::string& class_name);
+
+// Declares an Objective C class without initializing the class so that it can
+// be refrerred to by ObjCClass.
+std::string PROTOC_EXPORT ObjCClassDeclaration(const std::string& class_name);
+
+inline bool HasPreservingUnknownEnumSemantics(const FileDescriptor* file) {
+ return file->syntax() == FileDescriptor::SYNTAX_PROTO3;
+}
+
+inline bool IsMapEntryMessage(const Descriptor* descriptor) {
+ return descriptor->options().map_entry();
+}
+
+// Reverse of the above.
+std::string PROTOC_EXPORT UnCamelCaseFieldName(const std::string& name,
+ const FieldDescriptor* field);
+
+enum ObjectiveCType {
+ OBJECTIVECTYPE_INT32,
+ OBJECTIVECTYPE_UINT32,
+ OBJECTIVECTYPE_INT64,
+ OBJECTIVECTYPE_UINT64,
+ OBJECTIVECTYPE_FLOAT,
+ OBJECTIVECTYPE_DOUBLE,
+ OBJECTIVECTYPE_BOOLEAN,
+ OBJECTIVECTYPE_STRING,
+ OBJECTIVECTYPE_DATA,
+ OBJECTIVECTYPE_ENUM,
+ OBJECTIVECTYPE_MESSAGE
+};
+
+enum FlagType {
+ FLAGTYPE_DESCRIPTOR_INITIALIZATION,
+ FLAGTYPE_EXTENSION,
+ FLAGTYPE_FIELD
+};
+
+template <class TDescriptor>
+std::string GetOptionalDeprecatedAttribute(const TDescriptor* descriptor,
+ const FileDescriptor* file = NULL,
+ bool preSpace = true,
+ bool postNewline = false) {
+ bool isDeprecated = descriptor->options().deprecated();
+ // The file is only passed when checking Messages & Enums, so those types
+ // get tagged. At the moment, it doesn't seem to make sense to tag every
+ // field or enum value with when the file is deprecated.
+ bool isFileLevelDeprecation = false;
+ if (!isDeprecated && file) {
+ isFileLevelDeprecation = file->options().deprecated();
+ isDeprecated = isFileLevelDeprecation;
+ }
+ if (isDeprecated) {
+ std::string message;
+ const FileDescriptor* sourceFile = descriptor->file();
+ if (isFileLevelDeprecation) {
+ message = sourceFile->name() + " is deprecated.";
+ } else {
+ message = descriptor->full_name() + " is deprecated (see " +
+ sourceFile->name() + ").";
+ }
+
+ std::string result = std::string("GPB_DEPRECATED_MSG(\"") + message + "\")";
+ if (preSpace) {
+ result.insert(0, " ");
+ }
+ if (postNewline) {
+ result.append("\n");
+ }
+ return result;
+ } else {
+ return "";
+ }
+}
+
+std::string PROTOC_EXPORT GetCapitalizedType(const FieldDescriptor* field);
+
+ObjectiveCType PROTOC_EXPORT
+GetObjectiveCType(FieldDescriptor::Type field_type);
+
+inline ObjectiveCType GetObjectiveCType(const FieldDescriptor* field) {
+ return GetObjectiveCType(field->type());
+}
+
+bool PROTOC_EXPORT IsPrimitiveType(const FieldDescriptor* field);
+bool PROTOC_EXPORT IsReferenceType(const FieldDescriptor* field);
+
+std::string PROTOC_EXPORT
+GPBGenericValueFieldName(const FieldDescriptor* field);
+std::string PROTOC_EXPORT DefaultValue(const FieldDescriptor* field);
+bool PROTOC_EXPORT HasNonZeroDefaultValue(const FieldDescriptor* field);
+
+std::string PROTOC_EXPORT
+BuildFlagsString(const FlagType type, const std::vector<std::string>& strings);
+
+// Builds HeaderDoc/appledoc style comments out of the comments in the .proto
+// file.
+std::string PROTOC_EXPORT BuildCommentsString(const SourceLocation& location,
+ bool prefer_single_line);
+
+// The name the commonly used by the library when built as a framework.
+// This lines up to the name used in the CocoaPod.
+extern PROTOC_EXPORT const char* const ProtobufLibraryFrameworkName;
+// Returns the CPP symbol name to use as the gate for framework style imports
+// for the given framework name to use.
+std::string PROTOC_EXPORT
+ProtobufFrameworkImportSymbol(const std::string& framework_name);
+
+// Checks if the file is one of the proto's bundled with the library.
+bool PROTOC_EXPORT
+IsProtobufLibraryBundledProtoFile(const FileDescriptor* file);
+
+// Checks the prefix for the given files and outputs any warnings as needed. If
+// there are flat out errors, then out_error is filled in with the first error
+// and the result is false.
+bool PROTOC_EXPORT ValidateObjCClassPrefixes(
+ const std::vector<const FileDescriptor*>& files,
+ const Options& generation_options, std::string* out_error);
+
+// Generate decode data needed for ObjC's GPBDecodeTextFormatName() to transform
+// the input into the expected output.
+class PROTOC_EXPORT TextFormatDecodeData {
+ public:
+ TextFormatDecodeData();
+ ~TextFormatDecodeData();
+
+ TextFormatDecodeData(const TextFormatDecodeData&) = delete;
+ TextFormatDecodeData& operator=(const TextFormatDecodeData&) = delete;
+
+ void AddString(int32_t key, const std::string& input_for_decode,
+ const std::string& desired_output);
+ size_t num_entries() const { return entries_.size(); }
+ std::string Data() const;
+
+ static std::string DecodeDataForString(const std::string& input_for_decode,
+ const std::string& desired_output);
+
+ private:
+ typedef std::pair<int32_t, std::string> DataEntry;
+ std::vector<DataEntry> entries_;
+};
+
+// Helper for parsing simple files.
+class PROTOC_EXPORT LineConsumer {
+ public:
+ LineConsumer();
+ virtual ~LineConsumer();
+ virtual bool ConsumeLine(const StringPiece& line, std::string* out_error) = 0;
+};
+
+bool PROTOC_EXPORT ParseSimpleFile(const std::string& path,
+ LineConsumer* line_consumer,
+ std::string* out_error);
+
+bool PROTOC_EXPORT ParseSimpleStream(io::ZeroCopyInputStream& input_stream,
+ const std::string& stream_name,
+ LineConsumer* line_consumer,
+ std::string* out_error);
+
+// Helper class for parsing framework import mappings and generating
+// import statements.
+class PROTOC_EXPORT ImportWriter {
+ public:
+ ImportWriter(const std::string& generate_for_named_framework,
+ const std::string& named_framework_to_proto_path_mappings_path,
+ const std::string& runtime_import_prefix,
+ bool include_wkt_imports);
+ ~ImportWriter();
+
+ void AddFile(const FileDescriptor* file, const std::string& header_extension);
+ void Print(io::Printer* printer) const;
+
+ static void PrintRuntimeImports(io::Printer* printer,
+ const std::vector<std::string>& header_to_import,
+ const std::string& runtime_import_prefix,
+ bool default_cpp_symbol = false);
+
+ private:
+ class ProtoFrameworkCollector : public LineConsumer {
+ public:
+ ProtoFrameworkCollector(std::map<std::string, std::string>* inout_proto_file_to_framework_name)
+ : map_(inout_proto_file_to_framework_name) {}
+
+ virtual bool ConsumeLine(const StringPiece& line, std::string* out_error) override;
+
+ private:
+ std::map<std::string, std::string>* map_;
+ };
+
+ void ParseFrameworkMappings();
+
+ const std::string generate_for_named_framework_;
+ const std::string named_framework_to_proto_path_mappings_path_;
+ const std::string runtime_import_prefix_;
+ const bool include_wkt_imports_;
+ std::map<std::string, std::string> proto_file_to_framework_name_;
+ bool need_to_parse_mapping_file_;
+
+ std::vector<std::string> protobuf_imports_;
+ std::vector<std::string> other_framework_imports_;
+ std::vector<std::string> other_imports_;
+};
+
+} // namespace objectivec
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#include <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_HELPERS_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_helpers_unittest.cc b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_helpers_unittest.cc
new file mode 100644
index 00000000..85f150b9
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_helpers_unittest.cc
@@ -0,0 +1,385 @@
+// 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.
+
+#include <compiler/objectivec/objectivec_helpers.h>
+#include <io/zero_copy_stream_impl_lite.h>
+#include <testing/googletest.h>
+#include <gtest/gtest.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace objectivec {
+namespace {
+
+TEST(ObjCHelper, TextFormatDecodeData_DecodeDataForString_RawStrings) {
+ std::string input_for_decode("abcdefghIJ");
+ std::string desired_output_for_decode;
+ std::string expected;
+ std::string result;
+
+ // Different data, can't transform.
+
+ desired_output_for_decode = "zbcdefghIJ";
+ expected = std::string("\0zbcdefghIJ\0", 12);
+ result = TextFormatDecodeData::DecodeDataForString(input_for_decode,
+ desired_output_for_decode);
+ EXPECT_EQ(expected, result);
+
+ desired_output_for_decode = "abcdezghIJ";
+ expected = std::string("\0abcdezghIJ\0", 12);
+ result = TextFormatDecodeData::DecodeDataForString(input_for_decode,
+ desired_output_for_decode);
+ EXPECT_EQ(expected, result);
+
+ // Shortened data, can't transform.
+
+ desired_output_for_decode = "abcdefghI";
+ expected = std::string("\0abcdefghI\0", 11);
+ result = TextFormatDecodeData::DecodeDataForString(input_for_decode,
+ desired_output_for_decode);
+ EXPECT_EQ(expected, result);
+
+ // Extra data, can't transform.
+
+ desired_output_for_decode = "abcdefghIJz";
+ expected = std::string("\0abcdefghIJz\0", 13);
+ result = TextFormatDecodeData::DecodeDataForString(input_for_decode,
+ desired_output_for_decode);
+ EXPECT_EQ(expected, result);
+}
+
+TEST(ObjCHelper, TextFormatDecodeData_DecodeDataForString_ByteCodes) {
+ std::string input_for_decode("abcdefghIJ");
+ std::string desired_output_for_decode;
+ std::string expected;
+ std::string result;
+
+ desired_output_for_decode = "abcdefghIJ";
+ expected = std::string("\x0A\x0", 2);
+ result = TextFormatDecodeData::DecodeDataForString(input_for_decode,
+ desired_output_for_decode);
+ EXPECT_EQ(expected, result);
+
+ desired_output_for_decode = "_AbcdefghIJ";
+ expected = std::string("\xCA\x0", 2);
+ result = TextFormatDecodeData::DecodeDataForString(input_for_decode,
+ desired_output_for_decode);
+ EXPECT_EQ(expected, result);
+
+ desired_output_for_decode = "ABCD__EfghI_j";
+ expected = std::string("\x64\x80\xC5\xA1\x0", 5);
+ result = TextFormatDecodeData::DecodeDataForString(input_for_decode,
+ desired_output_for_decode);
+ EXPECT_EQ(expected, result);
+
+ // Long name so multiple decode ops are needed.
+
+ input_for_decode =
+ "longFieldNameIsLooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong1000";
+ desired_output_for_decode =
+ "long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_1000";
+ expected = std::string("\x04\xA5\xA4\xA2\xBF\x1F\x0E\x84\x0", 9);
+ result = TextFormatDecodeData::DecodeDataForString(input_for_decode,
+ desired_output_for_decode);
+ EXPECT_EQ(expected, result);
+}
+
+// Death tests do not work on Windows as of yet.
+#ifdef PROTOBUF_HAS_DEATH_TEST
+TEST(ObjCHelperDeathTest, TextFormatDecodeData_DecodeDataForString_Failures) {
+ // Empty inputs.
+
+ EXPECT_EXIT(TextFormatDecodeData::DecodeDataForString("", ""),
+ ::testing::KilledBySignal(SIGABRT),
+ "error: got empty string for making TextFormat data, input:");
+ EXPECT_EXIT(TextFormatDecodeData::DecodeDataForString("a", ""),
+ ::testing::KilledBySignal(SIGABRT),
+ "error: got empty string for making TextFormat data, input:");
+ EXPECT_EXIT(TextFormatDecodeData::DecodeDataForString("", "a"),
+ ::testing::KilledBySignal(SIGABRT),
+ "error: got empty string for making TextFormat data, input:");
+
+ // Null char in the string.
+
+ std::string str_with_null_char("ab\0c", 4);
+ EXPECT_EXIT(
+ TextFormatDecodeData::DecodeDataForString(str_with_null_char, "def"),
+ ::testing::KilledBySignal(SIGABRT),
+ "error: got a null char in a string for making TextFormat data, input:");
+ EXPECT_EXIT(
+ TextFormatDecodeData::DecodeDataForString("def", str_with_null_char),
+ ::testing::KilledBySignal(SIGABRT),
+ "error: got a null char in a string for making TextFormat data, input:");
+}
+#endif // PROTOBUF_HAS_DEATH_TEST
+
+TEST(ObjCHelper, TextFormatDecodeData_RawStrings) {
+ TextFormatDecodeData decode_data;
+
+ // Different data, can't transform.
+ decode_data.AddString(1, "abcdefghIJ", "zbcdefghIJ");
+ decode_data.AddString(3, "abcdefghIJ", "abcdezghIJ");
+ // Shortened data, can't transform.
+ decode_data.AddString(2, "abcdefghIJ", "abcdefghI");
+ // Extra data, can't transform.
+ decode_data.AddString(4, "abcdefghIJ", "abcdefghIJz");
+
+ EXPECT_EQ(4, decode_data.num_entries());
+
+ uint8 expected_data[] = {
+ 0x4,
+ 0x1, 0x0, 'z', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'I', 'J', 0x0,
+ 0x3, 0x0, 'a', 'b', 'c', 'd', 'e', 'z', 'g', 'h', 'I', 'J', 0x0,
+ 0x2, 0x0, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'I', 0x0,
+ 0x4, 0x0, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'I', 'J', 'z', 0x0,
+ };
+ std::string expected((const char*)expected_data, sizeof(expected_data));
+
+ EXPECT_EQ(expected, decode_data.Data());
+}
+
+TEST(ObjCHelper, TextFormatDecodeData_ByteCodes) {
+ TextFormatDecodeData decode_data;
+
+ decode_data.AddString(1, "abcdefghIJ", "abcdefghIJ");
+ decode_data.AddString(3, "abcdefghIJ", "_AbcdefghIJ");
+ decode_data.AddString(2, "abcdefghIJ", "Abcd_EfghIJ");
+ decode_data.AddString(4, "abcdefghIJ", "ABCD__EfghI_j");
+ decode_data.AddString(1000,
+ "longFieldNameIsLooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong1000",
+ "long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_1000");
+
+ EXPECT_EQ(5, decode_data.num_entries());
+
+ uint8 expected_data[] = {
+ 0x5,
+ // All as is (00 op)
+ 0x1, 0x0A, 0x0,
+ // Underscore, upper + 9 (10 op)
+ 0x3, 0xCA, 0x0,
+ // Upper + 3 (10 op), underscore, upper + 5 (10 op)
+ 0x2, 0x44, 0xC6, 0x0,
+ // All Upper for 4 (11 op), underscore, underscore, upper + 5 (10 op),
+ // underscore, lower + 0 (01 op)
+ 0x4, 0x64, 0x80, 0xC5, 0xA1, 0x0,
+ // 2 byte key: as is + 3 (00 op), underscore, lower + 4 (01 op),
+ // underscore, lower + 3 (01 op), underscore, lower + 1 (01 op),
+ // underscore, lower + 30 (01 op), as is + 30 (00 op), as is + 13 (00
+ // op),
+ // underscore, as is + 3 (00 op)
+ 0xE8, 0x07, 0x04, 0xA5, 0xA4, 0xA2, 0xBF, 0x1F, 0x0E, 0x84, 0x0,
+ };
+ std::string expected((const char*)expected_data, sizeof(expected_data));
+
+ EXPECT_EQ(expected, decode_data.Data());
+}
+
+
+// Death tests do not work on Windows as of yet.
+#ifdef PROTOBUF_HAS_DEATH_TEST
+TEST(ObjCHelperDeathTest, TextFormatDecodeData_Failures) {
+ TextFormatDecodeData decode_data;
+
+ // Empty inputs.
+
+ EXPECT_EXIT(decode_data.AddString(1, "", ""),
+ ::testing::KilledBySignal(SIGABRT),
+ "error: got empty string for making TextFormat data, input:");
+ EXPECT_EXIT(decode_data.AddString(1, "a", ""),
+ ::testing::KilledBySignal(SIGABRT),
+ "error: got empty string for making TextFormat data, input:");
+ EXPECT_EXIT(decode_data.AddString(1, "", "a"),
+ ::testing::KilledBySignal(SIGABRT),
+ "error: got empty string for making TextFormat data, input:");
+
+ // Null char in the string.
+
+ std::string str_with_null_char("ab\0c", 4);
+ EXPECT_EXIT(
+ decode_data.AddString(1, str_with_null_char, "def"),
+ ::testing::KilledBySignal(SIGABRT),
+ "error: got a null char in a string for making TextFormat data, input:");
+ EXPECT_EXIT(
+ decode_data.AddString(1, "def", str_with_null_char),
+ ::testing::KilledBySignal(SIGABRT),
+ "error: got a null char in a string for making TextFormat data, input:");
+
+ // Duplicate keys
+
+ decode_data.AddString(1, "abcdefghIJ", "abcdefghIJ");
+ decode_data.AddString(3, "abcdefghIJ", "_AbcdefghIJ");
+ decode_data.AddString(2, "abcdefghIJ", "Abcd_EfghIJ");
+ EXPECT_EXIT(decode_data.AddString(2, "xyz", "x_yz"),
+ ::testing::KilledBySignal(SIGABRT),
+ "error: duplicate key \\(2\\) making TextFormat data, input:");
+}
+#endif // PROTOBUF_HAS_DEATH_TEST
+
+class TestLineCollector : public LineConsumer {
+ public:
+ TestLineCollector(std::vector<std::string>* inout_lines,
+ const std::string* reject_line = nullptr,
+ bool skip_msg = false)
+ : lines_(inout_lines), reject_(reject_line), skip_msg_(skip_msg) {}
+
+ bool ConsumeLine(const StringPiece& line, std::string* out_error) override {
+ if (reject_ && *reject_ == line) {
+ if (!skip_msg_) {
+ *out_error = std::string("Rejected '") + *reject_ + "'";
+ }
+ return false;
+ }
+ if (lines_) {
+ lines_->emplace_back(line);
+ }
+ return true;
+ }
+
+ private:
+ std::vector<std::string>* lines_;
+ const std::string* reject_;
+ bool skip_msg_;
+};
+
+const int kBlockSizes[] = {-1, 1, 2, 5, 64};
+const int kBlockSizeCount = GOOGLE_ARRAYSIZE(kBlockSizes);
+
+TEST(ObjCHelper, ParseSimple_BasicsSuccess) {
+ const std::vector<std::pair<std::string, std::vector<std::string>>> tests = {
+ {"", {}},
+ {"a", {"a"}},
+ {"a c", {"a c"}},
+ {" a c ", {"a c"}},
+ {"\ta c ", {"a c"}},
+ {"abc\n", {"abc"}},
+ {"abc\nd f", {"abc", "d f"}},
+ {"\n abc \n def \n\n", {"abc", "def"}},
+ };
+
+ for (const auto& test : tests) {
+ for (int i = 0; i < kBlockSizeCount; i++) {
+ io::ArrayInputStream input(test.first.data(), test.first.size(), kBlockSizes[i]);
+ std::string err_str;
+ std::vector<std::string> lines;
+ TestLineCollector collector(&lines);
+ EXPECT_TRUE(ParseSimpleStream(input, "dummy", &collector, &err_str));
+ EXPECT_EQ(lines, test.second);
+ EXPECT_TRUE(err_str.empty());
+ }
+ }
+}
+
+TEST(ObjCHelper, ParseSimple_DropsComments) {
+ const std::vector<std::pair<std::string, std::vector<std::string>>> tests = {
+ {"# nothing", {}},
+ {"#", {}},
+ {"##", {}},
+ {"\n# nothing\n", {}},
+ {"a # same line", {"a"}},
+ {"a # same line\n", {"a"}},
+ {"a\n# line\nc", {"a", "c"}},
+ {"# n o t # h i n g #", {}},
+ {"## n o # t h i n g #", {}},
+ {"a# n o t # h i n g #", {"a"}},
+ {"a\n## n o # t h i n g #", {"a"}},
+ };
+
+ for (const auto& test : tests) {
+ for (int i = 0; i < kBlockSizeCount; i++) {
+ io::ArrayInputStream input(test.first.data(), test.first.size(), kBlockSizes[i]);
+ std::string err_str;
+ std::vector<std::string> lines;
+ TestLineCollector collector(&lines);
+ EXPECT_TRUE(ParseSimpleStream(input, "dummy", &collector, &err_str));
+ EXPECT_EQ(lines, test.second);
+ EXPECT_TRUE(err_str.empty());
+ }
+ }
+}
+
+TEST(ObjCHelper, ParseSimple_RejectLines) {
+ const std::vector<std::tuple<std::string, std::string, int>> tests = {
+ std::make_tuple("a\nb\nc", "a", 1),
+ std::make_tuple("a\nb\nc", "b", 2),
+ std::make_tuple("a\nb\nc", "c", 3),
+ std::make_tuple("a\nb\nc\n", "c", 3),
+ };
+
+ for (const auto& test : tests) {
+ for (int i = 0; i < kBlockSizeCount; i++) {
+ io::ArrayInputStream input(std::get<0>(test).data(), std::get<0>(test).size(),
+ kBlockSizes[i]);
+ std::string err_str;
+ TestLineCollector collector(nullptr, &std::get<1>(test));
+ EXPECT_FALSE(ParseSimpleStream(input, "dummy", &collector, &err_str));
+ std::string expected_err =
+ StrCat("error: dummy Line ", std::get<2>(test), ", Rejected '", std::get<1>(test), "'");
+ EXPECT_EQ(err_str, expected_err);
+ }
+ }
+}
+
+TEST(ObjCHelper, ParseSimple_RejectLinesNoMessage) {
+ const std::vector<std::tuple<std::string, std::string, int>> tests = {
+ std::make_tuple("a\nb\nc", "a", 1),
+ std::make_tuple("a\nb\nc", "b", 2),
+ std::make_tuple("a\nb\nc", "c", 3),
+ std::make_tuple("a\nb\nc\n", "c", 3),
+ };
+
+ for (const auto& test : tests) {
+ for (int i = 0; i < kBlockSizeCount; i++) {
+ io::ArrayInputStream input(std::get<0>(test).data(), std::get<0>(test).size(),
+ kBlockSizes[i]);
+ std::string err_str;
+ TestLineCollector collector(nullptr, &std::get<1>(test), true /* skip msg */);
+ EXPECT_FALSE(ParseSimpleStream(input, "dummy", &collector, &err_str));
+ std::string expected_err =
+ StrCat("error: dummy Line ", std::get<2>(test),
+ ", ConsumeLine failed without setting an error.");
+ EXPECT_EQ(err_str, expected_err);
+ }
+ }
+}
+
+// TODO(thomasvl): Should probably add some unittests for all the special cases
+// of name mangling (class name, field name, enum names). Rather than doing
+// this with an ObjC test in the objectivec directory, we should be able to
+// use src/google/protobuf/compiler/importer* (like other tests) to support a
+// virtual file system to feed in protos, once we have the Descriptor tree, the
+// tests could use the helper methods for generating names and validate the
+// right things are happening.
+
+} // namespace
+} // namespace objectivec
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_map_field.cc b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_map_field.cc
new file mode 100644
index 00000000..58681ae4
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_map_field.cc
@@ -0,0 +1,189 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2015 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 <map>
+#include <string>
+
+#include <compiler/objectivec/objectivec_map_field.h>
+#include <compiler/objectivec/objectivec_helpers.h>
+#include <io/printer.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace objectivec {
+
+// MapFieldGenerator uses RepeatedFieldGenerator as the parent because it
+// provides a bunch of things (no has* methods, comments for contained type,
+// etc.).
+
+namespace {
+
+const char* MapEntryTypeName(const FieldDescriptor* descriptor, bool isKey) {
+ ObjectiveCType type = GetObjectiveCType(descriptor);
+ switch (type) {
+ case OBJECTIVECTYPE_INT32:
+ return "Int32";
+ case OBJECTIVECTYPE_UINT32:
+ return "UInt32";
+ case OBJECTIVECTYPE_INT64:
+ return "Int64";
+ case OBJECTIVECTYPE_UINT64:
+ return "UInt64";
+ case OBJECTIVECTYPE_FLOAT:
+ return "Float";
+ case OBJECTIVECTYPE_DOUBLE:
+ return "Double";
+ case OBJECTIVECTYPE_BOOLEAN:
+ return "Bool";
+ case OBJECTIVECTYPE_STRING:
+ return (isKey ? "String" : "Object");
+ case OBJECTIVECTYPE_DATA:
+ return "Object";
+ case OBJECTIVECTYPE_ENUM:
+ return "Enum";
+ case OBJECTIVECTYPE_MESSAGE:
+ return "Object";
+ }
+
+ // Some compilers report reaching end of function even though all cases of
+ // the enum are handed in the switch.
+ GOOGLE_LOG(FATAL) << "Can't get here.";
+ return NULL;
+}
+
+} // namespace
+
+MapFieldGenerator::MapFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options)
+ : RepeatedFieldGenerator(descriptor, options) {
+ const FieldDescriptor* key_descriptor =
+ descriptor->message_type()->map_key();
+ const FieldDescriptor* value_descriptor =
+ descriptor->message_type()->map_value();
+ value_field_generator_.reset(FieldGenerator::Make(value_descriptor, options));
+
+ // Pull over some variables_ from the value.
+ variables_["field_type"] = value_field_generator_->variable("field_type");
+ variables_["default"] = value_field_generator_->variable("default");
+ variables_["default_name"] = value_field_generator_->variable("default_name");
+
+ // Build custom field flags.
+ std::vector<std::string> field_flags;
+ field_flags.push_back("GPBFieldMapKey" + GetCapitalizedType(key_descriptor));
+ // Pull over the current text format custom name values that was calculated.
+ if (variables_["fieldflags"].find("GPBFieldTextFormatNameCustom") !=
+ std::string::npos) {
+ field_flags.push_back("GPBFieldTextFormatNameCustom");
+ }
+ // Pull over some info from the value's flags.
+ const std::string& value_field_flags =
+ value_field_generator_->variable("fieldflags");
+ if (value_field_flags.find("GPBFieldHasDefaultValue") != std::string::npos) {
+ field_flags.push_back("GPBFieldHasDefaultValue");
+ }
+ if (value_field_flags.find("GPBFieldHasEnumDescriptor") !=
+ std::string::npos) {
+ field_flags.push_back("GPBFieldHasEnumDescriptor");
+ }
+
+ variables_["fieldflags"] = BuildFlagsString(FLAGTYPE_FIELD, field_flags);
+
+ ObjectiveCType value_objc_type = GetObjectiveCType(value_descriptor);
+ const bool value_is_object_type =
+ ((value_objc_type == OBJECTIVECTYPE_STRING) ||
+ (value_objc_type == OBJECTIVECTYPE_DATA) ||
+ (value_objc_type == OBJECTIVECTYPE_MESSAGE));
+ if ((GetObjectiveCType(key_descriptor) == OBJECTIVECTYPE_STRING) &&
+ value_is_object_type) {
+ variables_["array_storage_type"] = "NSMutableDictionary";
+ variables_["array_property_type"] =
+ "NSMutableDictionary<NSString*, " +
+ value_field_generator_->variable("storage_type") + "*>";
+ } else {
+ std::string class_name("GPB");
+ class_name += MapEntryTypeName(key_descriptor, true);
+ class_name += MapEntryTypeName(value_descriptor, false);
+ class_name += "Dictionary";
+ variables_["array_storage_type"] = class_name;
+ if (value_is_object_type) {
+ variables_["array_property_type"] =
+ class_name + "<" +
+ value_field_generator_->variable("storage_type") + "*>";
+ }
+ }
+
+ variables_["dataTypeSpecific_name"] =
+ value_field_generator_->variable("dataTypeSpecific_name");
+ variables_["dataTypeSpecific_value"] =
+ value_field_generator_->variable("dataTypeSpecific_value");
+}
+
+MapFieldGenerator::~MapFieldGenerator() {}
+
+void MapFieldGenerator::FinishInitialization(void) {
+ RepeatedFieldGenerator::FinishInitialization();
+ // Use the array_comment support in RepeatedFieldGenerator to output what the
+ // values in the map are.
+ const FieldDescriptor* value_descriptor =
+ descriptor_->message_type()->FindFieldByName("value");
+ if (GetObjectiveCType(value_descriptor) == OBJECTIVECTYPE_ENUM) {
+ variables_["array_comment"] =
+ "// |" + variables_["name"] + "| values are |" + value_field_generator_->variable("storage_type") + "|\n";
+ }
+}
+
+void MapFieldGenerator::DetermineForwardDeclarations(
+ std::set<std::string>* fwd_decls) const {
+ RepeatedFieldGenerator::DetermineForwardDeclarations(fwd_decls);
+ const FieldDescriptor* value_descriptor =
+ descriptor_->message_type()->FindFieldByName("value");
+ if (GetObjectiveCType(value_descriptor) == OBJECTIVECTYPE_MESSAGE) {
+ const std::string& value_storage_type =
+ value_field_generator_->variable("storage_type");
+ fwd_decls->insert("@class " + value_storage_type);
+ }
+}
+
+void MapFieldGenerator::DetermineObjectiveCClassDefinitions(
+ std::set<std::string>* fwd_decls) const {
+ // Class name is already in "storage_type".
+ const FieldDescriptor* value_descriptor =
+ descriptor_->message_type()->FindFieldByName("value");
+ if (GetObjectiveCType(value_descriptor) == OBJECTIVECTYPE_MESSAGE) {
+ fwd_decls->insert(ObjCClassDeclaration(
+ value_field_generator_->variable("storage_type")));
+ }
+}
+
+} // namespace objectivec
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_map_field.h b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_map_field.h
new file mode 100644
index 00000000..32371123
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_map_field.h
@@ -0,0 +1,71 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2015 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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_COMPILER_OBJECTIVEC_MAP_FIELD_H__
+#define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_MAP_FIELD_H__
+
+#include <map>
+#include <string>
+#include <compiler/objectivec/objectivec_field.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace objectivec {
+
+class MapFieldGenerator : public RepeatedFieldGenerator {
+ friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field,
+ const Options& options);
+
+ public:
+ virtual void FinishInitialization(void) override;
+
+ MapFieldGenerator(const MapFieldGenerator&) = delete;
+ MapFieldGenerator& operator=(const MapFieldGenerator&) = delete;
+
+ protected:
+ MapFieldGenerator(const FieldDescriptor* descriptor, const Options& options);
+ virtual ~MapFieldGenerator();
+
+ virtual void DetermineObjectiveCClassDefinitions(
+ std::set<std::string>* fwd_decls) const override;
+ virtual void DetermineForwardDeclarations(
+ std::set<std::string>* fwd_decls) const override;
+
+ private:
+ std::unique_ptr<FieldGenerator> value_field_generator_;
+};
+
+} // namespace objectivec
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_MAP_FIELD_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_message.cc b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_message.cc
new file mode 100644
index 00000000..0e8bfec9
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_message.cc
@@ -0,0 +1,636 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 <algorithm>
+#include <iostream>
+#include <sstream>
+
+#include <compiler/objectivec/objectivec_message.h>
+#include <compiler/objectivec/objectivec_enum.h>
+#include <compiler/objectivec/objectivec_extension.h>
+#include <compiler/objectivec/objectivec_helpers.h>
+#include <stubs/stl_util.h>
+#include <stubs/strutil.h>
+#include <io/printer.h>
+#include <io/coded_stream.h>
+#include <io/zero_copy_stream_impl.h>
+#include <wire_format.h>
+#include <wire_format_lite.h>
+#include <descriptor.pb.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace objectivec {
+
+namespace {
+struct FieldOrderingByNumber {
+ inline bool operator()(const FieldDescriptor* a,
+ const FieldDescriptor* b) const {
+ return a->number() < b->number();
+ }
+};
+
+int OrderGroupForFieldDescriptor(const FieldDescriptor* descriptor) {
+ // The first item in the object structure is our uint32[] for has bits.
+ // We then want to order things to make the instances as small as
+ // possible. So we follow the has bits with:
+ // 1. Anything always 4 bytes - float, *32, enums
+ // 2. Anything that is always a pointer (they will be 8 bytes on 64 bit
+ // builds and 4 bytes on 32bit builds.
+ // 3. Anything always 8 bytes - double, *64
+ //
+ // NOTE: Bools aren't listed, they were stored in the has bits.
+ //
+ // Why? Using 64bit builds as an example, this means worse case, we have
+ // enough bools that we overflow 1 byte from 4 byte alignment, so 3 bytes
+ // are wasted before the 4 byte values. Then if we have an odd number of
+ // those 4 byte values, the 8 byte values will be pushed down by 32bits to
+ // keep them aligned. But the structure will end 8 byte aligned, so no
+ // waste on the end. If you did the reverse order, you could waste 4 bytes
+ // before the first 8 byte value (after the has array), then a single
+ // bool on the end would need 7 bytes of padding to make the overall
+ // structure 8 byte aligned; so 11 bytes, wasted total.
+
+ // Anything repeated is a GPB*Array/NSArray, so pointer.
+ if (descriptor->is_repeated()) {
+ return 3;
+ }
+
+ switch (descriptor->type()) {
+ // All always 8 bytes.
+ case FieldDescriptor::TYPE_DOUBLE:
+ case FieldDescriptor::TYPE_INT64:
+ case FieldDescriptor::TYPE_SINT64:
+ case FieldDescriptor::TYPE_UINT64:
+ case FieldDescriptor::TYPE_SFIXED64:
+ case FieldDescriptor::TYPE_FIXED64:
+ return 4;
+
+ // Pointers (string and bytes are NSString and NSData); 8 or 4 bytes
+ // depending on the build architecture.
+ case FieldDescriptor::TYPE_GROUP:
+ case FieldDescriptor::TYPE_MESSAGE:
+ case FieldDescriptor::TYPE_STRING:
+ case FieldDescriptor::TYPE_BYTES:
+ return 3;
+
+ // All always 4 bytes (enums are int32s).
+ case FieldDescriptor::TYPE_FLOAT:
+ case FieldDescriptor::TYPE_INT32:
+ case FieldDescriptor::TYPE_SINT32:
+ case FieldDescriptor::TYPE_UINT32:
+ case FieldDescriptor::TYPE_SFIXED32:
+ case FieldDescriptor::TYPE_FIXED32:
+ case FieldDescriptor::TYPE_ENUM:
+ return 2;
+
+ // 0 bytes. Stored in the has bits.
+ case FieldDescriptor::TYPE_BOOL:
+ return 99; // End of the list (doesn't really matter).
+ }
+
+ // Some compilers report reaching end of function even though all cases of
+ // the enum are handed in the switch.
+ GOOGLE_LOG(FATAL) << "Can't get here.";
+ return 0;
+}
+
+struct FieldOrderingByStorageSize {
+ inline bool operator()(const FieldDescriptor* a,
+ const FieldDescriptor* b) const {
+ // Order by grouping.
+ const int order_group_a = OrderGroupForFieldDescriptor(a);
+ const int order_group_b = OrderGroupForFieldDescriptor(b);
+ if (order_group_a != order_group_b) {
+ return order_group_a < order_group_b;
+ }
+ // Within the group, order by field number (provides stable ordering).
+ return a->number() < b->number();
+ }
+};
+
+struct ExtensionRangeOrdering {
+ bool operator()(const Descriptor::ExtensionRange* a,
+ const Descriptor::ExtensionRange* b) const {
+ return a->start < b->start;
+ }
+};
+
+// Sort the fields of the given Descriptor by number into a new[]'d array
+// and return it.
+const FieldDescriptor** SortFieldsByNumber(const Descriptor* descriptor) {
+ const FieldDescriptor** fields =
+ new const FieldDescriptor* [descriptor->field_count()];
+ for (int i = 0; i < descriptor->field_count(); i++) {
+ fields[i] = descriptor->field(i);
+ }
+ std::sort(fields, fields + descriptor->field_count(), FieldOrderingByNumber());
+ return fields;
+}
+
+// Sort the fields of the given Descriptor by storage size into a new[]'d
+// array and return it.
+const FieldDescriptor** SortFieldsByStorageSize(const Descriptor* descriptor) {
+ const FieldDescriptor** fields =
+ new const FieldDescriptor* [descriptor->field_count()];
+ for (int i = 0; i < descriptor->field_count(); i++) {
+ fields[i] = descriptor->field(i);
+ }
+ std::sort(fields, fields + descriptor->field_count(),
+ FieldOrderingByStorageSize());
+ return fields;
+}
+} // namespace
+
+MessageGenerator::MessageGenerator(const std::string& root_classname,
+ const Descriptor* descriptor,
+ const Options& options)
+ : root_classname_(root_classname),
+ descriptor_(descriptor),
+ field_generators_(descriptor, options),
+ class_name_(ClassName(descriptor_)),
+ deprecated_attribute_(GetOptionalDeprecatedAttribute(
+ descriptor, descriptor->file(), false, true)) {
+ for (int i = 0; i < descriptor_->extension_count(); i++) {
+ extension_generators_.emplace_back(
+ new ExtensionGenerator(class_name_, descriptor_->extension(i)));
+ }
+
+ for (int i = 0; i < descriptor_->real_oneof_decl_count(); i++) {
+ OneofGenerator* generator = new OneofGenerator(descriptor_->oneof_decl(i));
+ oneof_generators_.emplace_back(generator);
+ }
+
+ for (int i = 0; i < descriptor_->enum_type_count(); i++) {
+ EnumGenerator* generator = new EnumGenerator(descriptor_->enum_type(i));
+ enum_generators_.emplace_back(generator);
+ }
+
+ for (int i = 0; i < descriptor_->nested_type_count(); i++) {
+ MessageGenerator* generator =
+ new MessageGenerator(root_classname_,
+ descriptor_->nested_type(i),
+ options);
+ nested_message_generators_.emplace_back(generator);
+ }
+}
+
+MessageGenerator::~MessageGenerator() {}
+
+void MessageGenerator::GenerateStaticVariablesInitialization(
+ io::Printer* printer) {
+ for (const auto& generator : extension_generators_) {
+ generator->GenerateStaticVariablesInitialization(printer);
+ }
+
+ for (const auto& generator : nested_message_generators_) {
+ generator->GenerateStaticVariablesInitialization(printer);
+ }
+}
+
+void MessageGenerator::DetermineForwardDeclarations(
+ std::set<std::string>* fwd_decls) {
+ if (!IsMapEntryMessage(descriptor_)) {
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ const FieldDescriptor* fieldDescriptor = descriptor_->field(i);
+ field_generators_.get(fieldDescriptor)
+ .DetermineForwardDeclarations(fwd_decls);
+ }
+ }
+
+ for (const auto& generator : nested_message_generators_) {
+ generator->DetermineForwardDeclarations(fwd_decls);
+ }
+}
+
+void MessageGenerator::DetermineObjectiveCClassDefinitions(
+ std::set<std::string>* fwd_decls) {
+ if (!IsMapEntryMessage(descriptor_)) {
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ const FieldDescriptor* fieldDescriptor = descriptor_->field(i);
+ field_generators_.get(fieldDescriptor)
+ .DetermineObjectiveCClassDefinitions(fwd_decls);
+ }
+ }
+
+ for (const auto& generator : extension_generators_) {
+ generator->DetermineObjectiveCClassDefinitions(fwd_decls);
+ }
+
+ for (const auto& generator : nested_message_generators_) {
+ generator->DetermineObjectiveCClassDefinitions(fwd_decls);
+ }
+
+ const Descriptor* containing_descriptor = descriptor_->containing_type();
+ if (containing_descriptor != NULL) {
+ std::string containing_class = ClassName(containing_descriptor);
+ fwd_decls->insert(ObjCClassDeclaration(containing_class));
+ }
+}
+
+bool MessageGenerator::IncludesOneOfDefinition() const {
+ if (!oneof_generators_.empty()) {
+ return true;
+ }
+
+ for (const auto& generator : nested_message_generators_) {
+ if (generator->IncludesOneOfDefinition()) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void MessageGenerator::GenerateEnumHeader(io::Printer* printer) {
+ for (const auto& generator : enum_generators_) {
+ generator->GenerateHeader(printer);
+ }
+
+ for (const auto& generator : nested_message_generators_) {
+ generator->GenerateEnumHeader(printer);
+ }
+}
+
+void MessageGenerator::GenerateExtensionRegistrationSource(
+ io::Printer* printer) {
+ for (const auto& generator : extension_generators_) {
+ generator->GenerateRegistrationSource(printer);
+ }
+
+ for (const auto& generator : nested_message_generators_) {
+ generator->GenerateExtensionRegistrationSource(printer);
+ }
+}
+
+void MessageGenerator::GenerateMessageHeader(io::Printer* printer) {
+ // This a a map entry message, just recurse and do nothing directly.
+ if (IsMapEntryMessage(descriptor_)) {
+ for (const auto& generator : nested_message_generators_) {
+ generator->GenerateMessageHeader(printer);
+ }
+ return;
+ }
+
+ printer->Print(
+ "#pragma mark - $classname$\n"
+ "\n",
+ "classname", class_name_);
+
+ if (descriptor_->field_count()) {
+ std::unique_ptr<const FieldDescriptor*[]> sorted_fields(
+ SortFieldsByNumber(descriptor_));
+
+ printer->Print("typedef GPB_ENUM($classname$_FieldNumber) {\n",
+ "classname", class_name_);
+ printer->Indent();
+
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ field_generators_.get(sorted_fields[i])
+ .GenerateFieldNumberConstant(printer);
+ }
+
+ printer->Outdent();
+ printer->Print("};\n\n");
+ }
+
+ for (const auto& generator : oneof_generators_) {
+ generator->GenerateCaseEnum(printer);
+ }
+
+ std::string message_comments;
+ SourceLocation location;
+ if (descriptor_->GetSourceLocation(&location)) {
+ message_comments = BuildCommentsString(location, false);
+ } else {
+ message_comments = "";
+ }
+
+ printer->Print(
+ "$comments$$deprecated_attribute$GPB_FINAL @interface $classname$ : GPBMessage\n\n",
+ "classname", class_name_,
+ "deprecated_attribute", deprecated_attribute_,
+ "comments", message_comments);
+
+ std::vector<char> seen_oneofs(oneof_generators_.size(), 0);
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ const FieldDescriptor* field = descriptor_->field(i);
+ const OneofDescriptor* oneof = field->real_containing_oneof();
+ if (oneof) {
+ const int oneof_index = oneof->index();
+ if (!seen_oneofs[oneof_index]) {
+ seen_oneofs[oneof_index] = 1;
+ oneof_generators_[oneof_index]->GeneratePublicCasePropertyDeclaration(
+ printer);
+ }
+ }
+ field_generators_.get(field).GeneratePropertyDeclaration(printer);
+ }
+
+ printer->Print("@end\n\n");
+
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ field_generators_.get(descriptor_->field(i))
+ .GenerateCFunctionDeclarations(printer);
+ }
+
+ if (!oneof_generators_.empty()) {
+ for (const auto& generator : oneof_generators_) {
+ generator->GenerateClearFunctionDeclaration(printer);
+ }
+ printer->Print("\n");
+ }
+
+ if (descriptor_->extension_count() > 0) {
+ printer->Print("@interface $classname$ (DynamicMethods)\n\n",
+ "classname", class_name_);
+ for (const auto& generator : extension_generators_) {
+ generator->GenerateMembersHeader(printer);
+ }
+ printer->Print("@end\n\n");
+ }
+
+ for (const auto& generator : nested_message_generators_) {
+ generator->GenerateMessageHeader(printer);
+ }
+}
+
+void MessageGenerator::GenerateSource(io::Printer* printer) {
+ if (!IsMapEntryMessage(descriptor_)) {
+ printer->Print(
+ "#pragma mark - $classname$\n"
+ "\n",
+ "classname", class_name_);
+
+ if (!deprecated_attribute_.empty()) {
+ // No warnings when compiling the impl of this deprecated class.
+ printer->Print(
+ "#pragma clang diagnostic push\n"
+ "#pragma clang diagnostic ignored \"-Wdeprecated-implementations\"\n"
+ "\n");
+ }
+
+ printer->Print("@implementation $classname$\n\n",
+ "classname", class_name_);
+
+ for (const auto& generator : oneof_generators_) {
+ generator->GeneratePropertyImplementation(printer);
+ }
+
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ field_generators_.get(descriptor_->field(i))
+ .GeneratePropertyImplementation(printer);
+ }
+
+ std::unique_ptr<const FieldDescriptor*[]> sorted_fields(
+ SortFieldsByNumber(descriptor_));
+ std::unique_ptr<const FieldDescriptor*[]> size_order_fields(
+ SortFieldsByStorageSize(descriptor_));
+
+ std::vector<const Descriptor::ExtensionRange*> sorted_extensions;
+ sorted_extensions.reserve(descriptor_->extension_range_count());
+ for (int i = 0; i < descriptor_->extension_range_count(); ++i) {
+ sorted_extensions.push_back(descriptor_->extension_range(i));
+ }
+
+ std::sort(sorted_extensions.begin(), sorted_extensions.end(),
+ ExtensionRangeOrdering());
+
+ // Assign has bits:
+ // 1. FieldGeneratorMap::CalculateHasBits() loops through the fields seeing
+ // who needs has bits and assigning them.
+ // 2. FieldGenerator::SetOneofIndexBase() overrides has_bit with a negative
+ // index that groups all the elements in the oneof.
+ size_t num_has_bits = field_generators_.CalculateHasBits();
+ size_t sizeof_has_storage = (num_has_bits + 31) / 32;
+ if (sizeof_has_storage == 0) {
+ // In the case where no field needs has bits, don't let the _has_storage_
+ // end up as zero length (zero length arrays are sort of a grey area
+ // since it has to be at the start of the struct). This also ensures a
+ // field with only oneofs keeps the required negative indices they need.
+ sizeof_has_storage = 1;
+ }
+ // Tell all the fields the oneof base.
+ for (const auto& generator : oneof_generators_) {
+ generator->SetOneofIndexBase(sizeof_has_storage);
+ }
+ field_generators_.SetOneofIndexBase(sizeof_has_storage);
+ // sizeof_has_storage needs enough bits for the single fields that aren't in
+ // any oneof, and then one int32 for each oneof (to store the field number).
+ sizeof_has_storage += oneof_generators_.size();
+
+ printer->Print(
+ "\n"
+ "typedef struct $classname$__storage_ {\n"
+ " uint32_t _has_storage_[$sizeof_has_storage$];\n",
+ "classname", class_name_,
+ "sizeof_has_storage", StrCat(sizeof_has_storage));
+ printer->Indent();
+
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ field_generators_.get(size_order_fields[i])
+ .GenerateFieldStorageDeclaration(printer);
+ }
+ printer->Outdent();
+
+ printer->Print("} $classname$__storage_;\n\n", "classname", class_name_);
+
+
+ printer->Print(
+ "// This method is threadsafe because it is initially called\n"
+ "// in +initialize for each subclass.\n"
+ "+ (GPBDescriptor *)descriptor {\n"
+ " static GPBDescriptor *descriptor = nil;\n"
+ " if (!descriptor) {\n");
+
+ TextFormatDecodeData text_format_decode_data;
+ bool has_fields = descriptor_->field_count() > 0;
+ bool need_defaults = field_generators_.DoesAnyFieldHaveNonZeroDefault();
+ std::string field_description_type;
+ if (need_defaults) {
+ field_description_type = "GPBMessageFieldDescriptionWithDefault";
+ } else {
+ field_description_type = "GPBMessageFieldDescription";
+ }
+ if (has_fields) {
+ printer->Indent();
+ printer->Indent();
+ printer->Print(
+ "static $field_description_type$ fields[] = {\n",
+ "field_description_type", field_description_type);
+ printer->Indent();
+ for (int i = 0; i < descriptor_->field_count(); ++i) {
+ const FieldGenerator& field_generator =
+ field_generators_.get(sorted_fields[i]);
+ field_generator.GenerateFieldDescription(printer, need_defaults);
+ if (field_generator.needs_textformat_name_support()) {
+ text_format_decode_data.AddString(sorted_fields[i]->number(),
+ field_generator.generated_objc_name(),
+ field_generator.raw_field_name());
+ }
+ }
+ printer->Outdent();
+ printer->Print(
+ "};\n");
+ printer->Outdent();
+ printer->Outdent();
+ }
+
+ std::map<std::string, std::string> vars;
+ vars["classname"] = class_name_;
+ vars["rootclassname"] = root_classname_;
+ vars["fields"] = has_fields ? "fields" : "NULL";
+ if (has_fields) {
+ vars["fields_count"] =
+ "(uint32_t)(sizeof(fields) / sizeof(" + field_description_type + "))";
+ } else {
+ vars["fields_count"] = "0";
+ }
+
+ std::vector<std::string> init_flags;
+ init_flags.push_back("GPBDescriptorInitializationFlag_UsesClassRefs");
+ init_flags.push_back("GPBDescriptorInitializationFlag_Proto3OptionalKnown");
+ if (need_defaults) {
+ init_flags.push_back("GPBDescriptorInitializationFlag_FieldsWithDefault");
+ }
+ if (descriptor_->options().message_set_wire_format()) {
+ init_flags.push_back("GPBDescriptorInitializationFlag_WireFormat");
+ }
+ vars["init_flags"] = BuildFlagsString(FLAGTYPE_DESCRIPTOR_INITIALIZATION,
+ init_flags);
+
+ printer->Print(
+ vars,
+ " GPBDescriptor *localDescriptor =\n"
+ " [GPBDescriptor allocDescriptorForClass:[$classname$ class]\n"
+ " rootClass:[$rootclassname$ class]\n"
+ " file:$rootclassname$_FileDescriptor()\n"
+ " fields:$fields$\n"
+ " fieldCount:$fields_count$\n"
+ " storageSize:sizeof($classname$__storage_)\n"
+ " flags:$init_flags$];\n");
+ if (!oneof_generators_.empty()) {
+ printer->Print(
+ " static const char *oneofs[] = {\n");
+ for (const auto& generator : oneof_generators_) {
+ printer->Print(" \"$name$\",\n", "name",
+ generator->DescriptorName());
+ }
+ printer->Print(
+ " };\n"
+ " [localDescriptor setupOneofs:oneofs\n"
+ " count:(uint32_t)(sizeof(oneofs) / sizeof(char*))\n"
+ " firstHasIndex:$first_has_index$];\n",
+ "first_has_index", oneof_generators_[0]->HasIndexAsString());
+ }
+ if (text_format_decode_data.num_entries() != 0) {
+ const std::string text_format_data_str(text_format_decode_data.Data());
+ printer->Print(
+ "#if !GPBOBJC_SKIP_MESSAGE_TEXTFORMAT_EXTRAS\n"
+ " static const char *extraTextFormatInfo =");
+ static const int kBytesPerLine = 40; // allow for escaping
+ for (int i = 0; i < text_format_data_str.size(); i += kBytesPerLine) {
+ printer->Print(
+ "\n \"$data$\"",
+ "data", EscapeTrigraphs(
+ CEscape(text_format_data_str.substr(i, kBytesPerLine))));
+ }
+ printer->Print(
+ ";\n"
+ " [localDescriptor setupExtraTextInfo:extraTextFormatInfo];\n"
+ "#endif // !GPBOBJC_SKIP_MESSAGE_TEXTFORMAT_EXTRAS\n");
+ }
+ if (!sorted_extensions.empty()) {
+ printer->Print(
+ " static const GPBExtensionRange ranges[] = {\n");
+ for (int i = 0; i < sorted_extensions.size(); i++) {
+ printer->Print(" { .start = $start$, .end = $end$ },\n",
+ "start", StrCat(sorted_extensions[i]->start),
+ "end", StrCat(sorted_extensions[i]->end));
+ }
+ printer->Print(
+ " };\n"
+ " [localDescriptor setupExtensionRanges:ranges\n"
+ " count:(uint32_t)(sizeof(ranges) / sizeof(GPBExtensionRange))];\n");
+ }
+ if (descriptor_->containing_type() != NULL) {
+ std::string containing_class = ClassName(descriptor_->containing_type());
+ std::string parent_class_ref = ObjCClass(containing_class);
+ printer->Print(
+ " [localDescriptor setupContainingMessageClass:$parent_class_ref$];\n",
+ "parent_class_ref", parent_class_ref);
+ }
+ std::string suffix_added;
+ ClassName(descriptor_, &suffix_added);
+ if (!suffix_added.empty()) {
+ printer->Print(
+ " [localDescriptor setupMessageClassNameSuffix:@\"$suffix$\"];\n",
+ "suffix", suffix_added);
+ }
+ printer->Print(
+ " #if defined(DEBUG) && DEBUG\n"
+ " NSAssert(descriptor == nil, @\"Startup recursed!\");\n"
+ " #endif // DEBUG\n"
+ " descriptor = localDescriptor;\n"
+ " }\n"
+ " return descriptor;\n"
+ "}\n\n"
+ "@end\n\n");
+
+ if (!deprecated_attribute_.empty()) {
+ printer->Print(
+ "#pragma clang diagnostic pop\n"
+ "\n");
+ }
+
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ field_generators_.get(descriptor_->field(i))
+ .GenerateCFunctionImplementations(printer);
+ }
+
+ for (const auto& generator : oneof_generators_) {
+ generator->GenerateClearFunctionImplementation(printer);
+ }
+ }
+
+ for (const auto& generator : enum_generators_) {
+ generator->GenerateSource(printer);
+ }
+
+ for (const auto& generator : nested_message_generators_) {
+ generator->GenerateSource(printer);
+ }
+}
+
+} // namespace objectivec
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_message.h b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_message.h
new file mode 100644
index 00000000..64c7b49f
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_message.h
@@ -0,0 +1,99 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_MESSAGE_H__
+#define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_MESSAGE_H__
+
+#include <string>
+#include <set>
+#include <vector>
+#include <compiler/objectivec/objectivec_field.h>
+#include <compiler/objectivec/objectivec_helpers.h>
+#include <compiler/objectivec/objectivec_oneof.h>
+#include <descriptor.h>
+#include <io/printer.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace objectivec {
+
+class ExtensionGenerator;
+class EnumGenerator;
+
+class MessageGenerator {
+ public:
+ MessageGenerator(const std::string& root_classname,
+ const Descriptor* descriptor, const Options& options);
+ ~MessageGenerator();
+
+ MessageGenerator(const MessageGenerator&) = delete;
+ MessageGenerator& operator=(const MessageGenerator&) = delete;
+
+ void GenerateStaticVariablesInitialization(io::Printer* printer);
+ void GenerateEnumHeader(io::Printer* printer);
+ void GenerateMessageHeader(io::Printer* printer);
+ void GenerateSource(io::Printer* printer);
+ void GenerateExtensionRegistrationSource(io::Printer* printer);
+ void DetermineObjectiveCClassDefinitions(std::set<std::string>* fwd_decls);
+ void DetermineForwardDeclarations(std::set<std::string>* fwd_decls);
+
+ // Checks if the message or a nested message includes a oneof definition.
+ bool IncludesOneOfDefinition() const;
+
+ private:
+ void GenerateParseFromMethodsHeader(io::Printer* printer);
+
+ void GenerateSerializeOneFieldSource(io::Printer* printer,
+ const FieldDescriptor* field);
+ void GenerateSerializeOneExtensionRangeSource(
+ io::Printer* printer, const Descriptor::ExtensionRange* range);
+
+ void GenerateMessageDescriptionSource(io::Printer* printer);
+ void GenerateDescriptionOneFieldSource(io::Printer* printer,
+ const FieldDescriptor* field);
+
+ const std::string root_classname_;
+ const Descriptor* descriptor_;
+ FieldGeneratorMap field_generators_;
+ const std::string class_name_;
+ const std::string deprecated_attribute_;
+ std::vector<std::unique_ptr<ExtensionGenerator>> extension_generators_;
+ std::vector<std::unique_ptr<EnumGenerator>> enum_generators_;
+ std::vector<std::unique_ptr<MessageGenerator>> nested_message_generators_;
+ std::vector<std::unique_ptr<OneofGenerator>> oneof_generators_;
+};
+
+} // namespace objectivec
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_MESSAGE_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_message_field.cc b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_message_field.cc
new file mode 100644
index 00000000..241ae0fa
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_message_field.cc
@@ -0,0 +1,107 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 <map>
+#include <string>
+
+#include <compiler/objectivec/objectivec_message_field.h>
+#include <compiler/objectivec/objectivec_helpers.h>
+#include <io/printer.h>
+#include <wire_format.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace objectivec {
+
+namespace {
+
+void SetMessageVariables(const FieldDescriptor* descriptor,
+ std::map<std::string, std::string>* variables) {
+ const std::string& message_type = ClassName(descriptor->message_type());
+ const std::string& containing_class =
+ ClassName(descriptor->containing_type());
+ (*variables)["type"] = message_type;
+ (*variables)["containing_class"] = containing_class;
+ (*variables)["storage_type"] = message_type;
+ (*variables)["group_or_message"] =
+ (descriptor->type() == FieldDescriptor::TYPE_GROUP) ? "Group" : "Message";
+ (*variables)["dataTypeSpecific_value"] = ObjCClass(message_type);
+}
+
+} // namespace
+
+MessageFieldGenerator::MessageFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options)
+ : ObjCObjFieldGenerator(descriptor, options) {
+ SetMessageVariables(descriptor, &variables_);
+}
+
+MessageFieldGenerator::~MessageFieldGenerator() {}
+
+void MessageFieldGenerator::DetermineForwardDeclarations(
+ std::set<std::string>* fwd_decls) const {
+ ObjCObjFieldGenerator::DetermineForwardDeclarations(fwd_decls);
+ // Class name is already in "storage_type".
+ fwd_decls->insert("@class " + variable("storage_type"));
+}
+
+void MessageFieldGenerator::DetermineObjectiveCClassDefinitions(
+ std::set<std::string>* fwd_decls) const {
+ fwd_decls->insert(ObjCClassDeclaration(variable("storage_type")));
+}
+
+RepeatedMessageFieldGenerator::RepeatedMessageFieldGenerator(
+ const FieldDescriptor* descriptor, const Options& options)
+ : RepeatedFieldGenerator(descriptor, options) {
+ SetMessageVariables(descriptor, &variables_);
+ variables_["array_storage_type"] = "NSMutableArray";
+ variables_["array_property_type"] =
+ "NSMutableArray<" + variables_["storage_type"] + "*>";
+}
+
+RepeatedMessageFieldGenerator::~RepeatedMessageFieldGenerator() {}
+
+void RepeatedMessageFieldGenerator::DetermineForwardDeclarations(
+ std::set<std::string>* fwd_decls) const {
+ RepeatedFieldGenerator::DetermineForwardDeclarations(fwd_decls);
+ // Class name is already in "storage_type".
+ fwd_decls->insert("@class " + variable("storage_type"));
+}
+
+void RepeatedMessageFieldGenerator::DetermineObjectiveCClassDefinitions(
+ std::set<std::string>* fwd_decls) const {
+ fwd_decls->insert(ObjCClassDeclaration(variable("storage_type")));
+}
+
+} // namespace objectivec
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_message_field.h b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_message_field.h
new file mode 100644
index 00000000..7ea99c37
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_message_field.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.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_MESSAGE_FIELD_H__
+#define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_MESSAGE_FIELD_H__
+
+#include <map>
+#include <string>
+#include <compiler/objectivec/objectivec_field.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace objectivec {
+
+class MessageFieldGenerator : public ObjCObjFieldGenerator {
+ friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field,
+ const Options& options);
+
+ protected:
+ MessageFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options);
+
+ MessageFieldGenerator(const MessageFieldGenerator&) = delete;
+ MessageFieldGenerator& operator=(const MessageFieldGenerator&) = delete;
+
+ virtual ~MessageFieldGenerator();
+
+ public:
+ virtual void DetermineForwardDeclarations(
+ std::set<std::string>* fwd_decls) const override;
+ virtual void DetermineObjectiveCClassDefinitions(
+ std::set<std::string>* fwd_decls) const override;
+};
+
+class RepeatedMessageFieldGenerator : public RepeatedFieldGenerator {
+ friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field,
+ const Options& options);
+
+ protected:
+ RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options);
+ virtual ~RepeatedMessageFieldGenerator();
+
+ RepeatedMessageFieldGenerator(const RepeatedMessageFieldGenerator&) = delete;
+ RepeatedMessageFieldGenerator operator=(const RepeatedMessageFieldGenerator&) = delete;
+
+ public:
+ virtual void DetermineForwardDeclarations(
+ std::set<std::string>* fwd_decls) const override;
+ virtual void DetermineObjectiveCClassDefinitions(
+ std::set<std::string>* fwd_decls) const override;
+};
+
+} // namespace objectivec
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_MESSAGE_FIELD_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_nsobject_methods.h b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_nsobject_methods.h
new file mode 100644
index 00000000..16330466
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_nsobject_methods.h
@@ -0,0 +1,197 @@
+// NSObject methods
+// Autogenerated by method_dump.sh. Do not edit by hand.
+// Date: Thu Nov 1 14:12:16 PDT 2018
+// macOS: MacOSX10.14.sdk
+// iOS: iPhoneSimulator12.1.sdk
+
+const char* const kNSObjectMethodsList[] = {
+ "CAMLType",
+ "CA_copyRenderValue",
+ "CA_prepareRenderValue",
+ "NS_copyCGImage",
+ "NS_tiledLayerVisibleRect",
+ "___tryRetain_OA",
+ "__autorelease_OA",
+ "__dealloc_zombie",
+ "__release_OA",
+ "__retain_OA",
+ "_accessibilityFinalize",
+ "_accessibilityIsTableViewDescendant",
+ "_accessibilityUIElementSpecifier",
+ "_accessibilityUseConvenienceAPI",
+ "_allowsDirectEncoding",
+ "_asScriptTerminologyNameArray",
+ "_asScriptTerminologyNameString",
+ "_bindingAdaptor",
+ "_cfTypeID",
+ "_copyDescription",
+ "_destroyObserverList",
+ "_didEndKeyValueObserving",
+ "_implicitObservationInfo",
+ "_internalAccessibilityAttributedHint",
+ "_internalAccessibilityAttributedLabel",
+ "_internalAccessibilityAttributedValue",
+ "_isAXConnector",
+ "_isAccessibilityContainerSectionCandidate",
+ "_isAccessibilityContentNavigatorSectionCandidate",
+ "_isAccessibilityContentSectionCandidate",
+ "_isAccessibilityTopLevelNavigatorSectionCandidate",
+ "_isDeallocating",
+ "_isKVOA",
+ "_isToManyChangeInformation",
+ "_ivarDescription",
+ "_localClassNameForClass",
+ "_methodDescription",
+ "_observerStorage",
+ "_overrideUseFastBlockObservers",
+ "_propertyDescription",
+ "_releaseBindingAdaptor",
+ "_scriptingCount",
+ "_scriptingCountNonrecursively",
+ "_scriptingDebugDescription",
+ "_scriptingExists",
+ "_scriptingShouldCheckObjectIndexes",
+ "_shortMethodDescription",
+ "_shouldSearchChildrenForSection",
+ "_traitStorageList",
+ "_tryRetain",
+ "_ui_descriptionBuilder",
+ "_uikit_variesByTraitCollections",
+ "_web_description",
+ "_webkit_invokeOnMainThread",
+ "_willBeginKeyValueObserving",
+ "accessibilityActivate",
+ "accessibilityActivationPoint",
+ "accessibilityAllowsOverriddenAttributesWhenIgnored",
+ "accessibilityAssistiveTechnologyFocusedIdentifiers",
+ "accessibilityAttributedHint",
+ "accessibilityAttributedLabel",
+ "accessibilityAttributedValue",
+ "accessibilityContainer",
+ "accessibilityContainerType",
+ "accessibilityCustomActions",
+ "accessibilityCustomRotors",
+ "accessibilityDecrement",
+ "accessibilityDragSourceDescriptors",
+ "accessibilityDropPointDescriptors",
+ "accessibilityElementCount",
+ "accessibilityElementDidBecomeFocused",
+ "accessibilityElementDidLoseFocus",
+ "accessibilityElementIsFocused",
+ "accessibilityElements",
+ "accessibilityElementsHidden",
+ "accessibilityFrame",
+ "accessibilityHeaderElements",
+ "accessibilityHint",
+ "accessibilityIdentification",
+ "accessibilityIdentifier",
+ "accessibilityIncrement",
+ "accessibilityLabel",
+ "accessibilityLanguage",
+ "accessibilityLocalizedStringKey",
+ "accessibilityNavigationStyle",
+ "accessibilityOverriddenAttributes",
+ "accessibilityParameterizedAttributeNames",
+ "accessibilityPath",
+ "accessibilityPerformEscape",
+ "accessibilityPerformMagicTap",
+ "accessibilityPresenterProcessIdentifier",
+ "accessibilityShouldUseUniqueId",
+ "accessibilitySupportsNotifications",
+ "accessibilitySupportsOverriddenAttributes",
+ "accessibilityTemporaryChildren",
+ "accessibilityTraits",
+ "accessibilityValue",
+ "accessibilityViewIsModal",
+ "accessibilityVisibleArea",
+ "allPropertyKeys",
+ "allowsWeakReference",
+ "attributeKeys",
+ "autoContentAccessingProxy",
+ "autorelease",
+ "awakeFromNib",
+ "boolValueSafe",
+ "bs_encoded",
+ "bs_isPlistableType",
+ "bs_secureEncoded",
+ "cl_json_serializeKey",
+ "class",
+ "classCode",
+ "classDescription",
+ "classForArchiver",
+ "classForCoder",
+ "classForKeyedArchiver",
+ "classForPortCoder",
+ "className",
+ "clearProperties",
+ "copy",
+ "dealloc",
+ "debugDescription",
+ "defaultAccessibilityTraits",
+ "description",
+ "doubleValueSafe",
+ "entityName",
+ "exposedBindings",
+ "finalize",
+ "finishObserving",
+ "flushKeyBindings",
+ "hash",
+ "init",
+ "int64ValueSafe",
+ "isAccessibilityElement",
+ "isAccessibilityElementByDefault",
+ "isElementAccessibilityExposedToInterfaceBuilder",
+ "isFault",
+ "isNSArray__",
+ "isNSCFConstantString__",
+ "isNSData__",
+ "isNSDate__",
+ "isNSDictionary__",
+ "isNSNumber__",
+ "isNSObject__",
+ "isNSOrderedSet__",
+ "isNSSet__",
+ "isNSString__",
+ "isNSTimeZone__",
+ "isNSValue__",
+ "isProxy",
+ "mutableCopy",
+ "nilValueForKey",
+ "objectSpecifier",
+ "observationInfo",
+ "pep_onDetachedThread",
+ "pep_onMainThread",
+ "pep_onMainThreadIfNecessary",
+ "prepareForInterfaceBuilder",
+ "release",
+ "releaseOnMainThread",
+ "retain",
+ "retainCount",
+ "retainWeakReference",
+ "scriptingProperties",
+ "self",
+ "shouldGroupAccessibilityChildren",
+ "storedAccessibilityActivationPoint",
+ "storedAccessibilityContainerType",
+ "storedAccessibilityElementsHidden",
+ "storedAccessibilityFrame",
+ "storedAccessibilityNavigationStyle",
+ "storedAccessibilityTraits",
+ "storedAccessibilityViewIsModal",
+ "storedIsAccessibilityElement",
+ "storedShouldGroupAccessibilityChildren",
+ "stringValueSafe",
+ "superclass",
+ "toManyRelationshipKeys",
+ "toOneRelationshipKeys",
+ "traitStorageList",
+ "un_safeBoolValue",
+ "userInterfaceItemIdentifier",
+ "utf8ValueSafe",
+ "valuesForKeysWithDictionary",
+ "zone",
+// Protocol: CAAnimatableValue
+// Protocol: CARenderValue
+// Protocol: NSObject
+// Protocol: ROCKRemoteInvocationInterface
+};
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_oneof.cc b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_oneof.cc
new file mode 100644
index 00000000..de00a1f4
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_oneof.cc
@@ -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.
+
+#include <map>
+#include <string>
+
+#include <compiler/objectivec/objectivec_oneof.h>
+#include <compiler/objectivec/objectivec_helpers.h>
+#include <io/printer.h>
+#include <stubs/strutil.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace objectivec {
+
+OneofGenerator::OneofGenerator(const OneofDescriptor* descriptor)
+ : descriptor_(descriptor) {
+ variables_["enum_name"] = OneofEnumName(descriptor_);
+ variables_["name"] = OneofName(descriptor_);
+ variables_["capitalized_name"] = OneofNameCapitalized(descriptor_);
+ variables_["raw_index"] = StrCat(descriptor_->index());
+ const Descriptor* msg_descriptor = descriptor_->containing_type();
+ variables_["owning_message_class"] = ClassName(msg_descriptor);
+
+ std::string comments;
+ SourceLocation location;
+ if (descriptor_->GetSourceLocation(&location)) {
+ comments = BuildCommentsString(location, true);
+ } else {
+ comments = "";
+ }
+ variables_["comments"] = comments;
+}
+
+OneofGenerator::~OneofGenerator() {}
+
+void OneofGenerator::SetOneofIndexBase(int index_base) {
+ int index = descriptor_->index() + index_base;
+ // Flip the sign to mark it as a oneof.
+ variables_["index"] = StrCat(-index);
+}
+
+void OneofGenerator::GenerateCaseEnum(io::Printer* printer) {
+ printer->Print(
+ variables_,
+ "typedef GPB_ENUM($enum_name$) {\n");
+ printer->Indent();
+ printer->Print(
+ variables_,
+ "$enum_name$_GPBUnsetOneOfCase = 0,\n");
+ std::string enum_name = variables_["enum_name"];
+ for (int j = 0; j < descriptor_->field_count(); j++) {
+ const FieldDescriptor* field = descriptor_->field(j);
+ std::string field_name = FieldNameCapitalized(field);
+ printer->Print(
+ "$enum_name$_$field_name$ = $field_number$,\n",
+ "enum_name", enum_name,
+ "field_name", field_name,
+ "field_number", StrCat(field->number()));
+ }
+ printer->Outdent();
+ printer->Print(
+ "};\n"
+ "\n");
+}
+
+void OneofGenerator::GeneratePublicCasePropertyDeclaration(
+ io::Printer* printer) {
+ printer->Print(
+ variables_,
+ "$comments$"
+ "@property(nonatomic, readonly) $enum_name$ $name$OneOfCase;\n"
+ "\n");
+}
+
+void OneofGenerator::GenerateClearFunctionDeclaration(io::Printer* printer) {
+ printer->Print(
+ variables_,
+ "/**\n"
+ " * Clears whatever value was set for the oneof '$name$'.\n"
+ " **/\n"
+ "void $owning_message_class$_Clear$capitalized_name$OneOfCase($owning_message_class$ *message);\n");
+}
+
+void OneofGenerator::GeneratePropertyImplementation(io::Printer* printer) {
+ printer->Print(
+ variables_,
+ "@dynamic $name$OneOfCase;\n");
+}
+
+void OneofGenerator::GenerateClearFunctionImplementation(io::Printer* printer) {
+ printer->Print(
+ variables_,
+ "void $owning_message_class$_Clear$capitalized_name$OneOfCase($owning_message_class$ *message) {\n"
+ " GPBDescriptor *descriptor = [$owning_message_class$ descriptor];\n"
+ " GPBOneofDescriptor *oneof = [descriptor.oneofs objectAtIndex:$raw_index$];\n"
+ " GPBClearOneof(message, oneof);\n"
+ "}\n");
+}
+
+std::string OneofGenerator::DescriptorName(void) const {
+ return variables_.find("name")->second;
+}
+
+std::string OneofGenerator::HasIndexAsString(void) const {
+ return variables_.find("index")->second;
+}
+
+} // namespace objectivec
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_oneof.h b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_oneof.h
new file mode 100644
index 00000000..3d59f4ff
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_oneof.h
@@ -0,0 +1,76 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_ONEOF_H__
+#define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_ONEOF_H__
+
+#include <string>
+#include <set>
+#include <vector>
+#include <descriptor.h>
+#include <io/printer.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace objectivec {
+
+class OneofGenerator {
+ public:
+ explicit OneofGenerator(const OneofDescriptor* descriptor);
+ ~OneofGenerator();
+
+ OneofGenerator(const OneofGenerator&) = delete;
+ OneofGenerator& operator=(const OneofGenerator&) = delete;
+
+ void SetOneofIndexBase(int index_base);
+
+ void GenerateCaseEnum(io::Printer* printer);
+
+ void GeneratePublicCasePropertyDeclaration(io::Printer* printer);
+ void GenerateClearFunctionDeclaration(io::Printer* printer);
+
+ void GeneratePropertyImplementation(io::Printer* printer);
+ void GenerateClearFunctionImplementation(io::Printer* printer);
+
+ std::string DescriptorName(void) const;
+ std::string HasIndexAsString(void) const;
+
+ private:
+ const OneofDescriptor* descriptor_;
+ std::map<std::string, std::string> variables_;
+};
+
+} // namespace objectivec
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_ONEOF_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_primitive_field.cc b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_primitive_field.cc
new file mode 100644
index 00000000..7b5eec0c
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_primitive_field.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 <map>
+#include <string>
+
+#include <compiler/objectivec/objectivec_helpers.h>
+#include <compiler/objectivec/objectivec_primitive_field.h>
+#include <io/printer.h>
+#include <stubs/strutil.h>
+#include <wire_format.h>
+#include <wire_format_lite.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace objectivec {
+
+using internal::WireFormat;
+using internal::WireFormatLite;
+
+namespace {
+
+const char* PrimitiveTypeName(const FieldDescriptor* descriptor) {
+ ObjectiveCType type = GetObjectiveCType(descriptor);
+ switch (type) {
+ case OBJECTIVECTYPE_INT32:
+ return "int32_t";
+ case OBJECTIVECTYPE_UINT32:
+ return "uint32_t";
+ case OBJECTIVECTYPE_INT64:
+ return "int64_t";
+ case OBJECTIVECTYPE_UINT64:
+ return "uint64_t";
+ case OBJECTIVECTYPE_FLOAT:
+ return "float";
+ case OBJECTIVECTYPE_DOUBLE:
+ return "double";
+ case OBJECTIVECTYPE_BOOLEAN:
+ return "BOOL";
+ case OBJECTIVECTYPE_STRING:
+ return "NSString";
+ case OBJECTIVECTYPE_DATA:
+ return "NSData";
+ case OBJECTIVECTYPE_ENUM:
+ return "int32_t";
+ case OBJECTIVECTYPE_MESSAGE:
+ return NULL; // Messages go through objectivec_message_field.cc|h.
+ }
+
+ // Some compilers report reaching end of function even though all cases of
+ // the enum are handed in the switch.
+ GOOGLE_LOG(FATAL) << "Can't get here.";
+ return NULL;
+}
+
+const char* PrimitiveArrayTypeName(const FieldDescriptor* descriptor) {
+ ObjectiveCType type = GetObjectiveCType(descriptor);
+ switch (type) {
+ case OBJECTIVECTYPE_INT32:
+ return "Int32";
+ case OBJECTIVECTYPE_UINT32:
+ return "UInt32";
+ case OBJECTIVECTYPE_INT64:
+ return "Int64";
+ case OBJECTIVECTYPE_UINT64:
+ return "UInt64";
+ case OBJECTIVECTYPE_FLOAT:
+ return "Float";
+ case OBJECTIVECTYPE_DOUBLE:
+ return "Double";
+ case OBJECTIVECTYPE_BOOLEAN:
+ return "Bool";
+ case OBJECTIVECTYPE_STRING:
+ return ""; // Want NSArray
+ case OBJECTIVECTYPE_DATA:
+ return ""; // Want NSArray
+ case OBJECTIVECTYPE_ENUM:
+ return "Enum";
+ case OBJECTIVECTYPE_MESSAGE:
+ // Want NSArray (but goes through objectivec_message_field.cc|h).
+ return "";
+ }
+
+ // Some compilers report reaching end of function even though all cases of
+ // the enum are handed in the switch.
+ GOOGLE_LOG(FATAL) << "Can't get here.";
+ return NULL;
+}
+
+void SetPrimitiveVariables(const FieldDescriptor* descriptor,
+ std::map<std::string, std::string>* variables) {
+ std::string primitive_name = PrimitiveTypeName(descriptor);
+ (*variables)["type"] = primitive_name;
+ (*variables)["storage_type"] = primitive_name;
+}
+
+} // namespace
+
+PrimitiveFieldGenerator::PrimitiveFieldGenerator(
+ const FieldDescriptor* descriptor, const Options& options)
+ : SingleFieldGenerator(descriptor, options) {
+ SetPrimitiveVariables(descriptor, &variables_);
+}
+
+PrimitiveFieldGenerator::~PrimitiveFieldGenerator() {}
+
+void PrimitiveFieldGenerator::GenerateFieldStorageDeclaration(
+ io::Printer* printer) const {
+ if (GetObjectiveCType(descriptor_) == OBJECTIVECTYPE_BOOLEAN) {
+ // Nothing, BOOLs are stored in the has bits.
+ } else {
+ SingleFieldGenerator::GenerateFieldStorageDeclaration(printer);
+ }
+}
+
+int PrimitiveFieldGenerator::ExtraRuntimeHasBitsNeeded(void) const {
+ if (GetObjectiveCType(descriptor_) == OBJECTIVECTYPE_BOOLEAN) {
+ // Reserve a bit for the storage of the boolean.
+ return 1;
+ }
+ return 0;
+}
+
+void PrimitiveFieldGenerator::SetExtraRuntimeHasBitsBase(int has_base) {
+ if (GetObjectiveCType(descriptor_) == OBJECTIVECTYPE_BOOLEAN) {
+ // Set into the offset the has bit to use for the actual value.
+ variables_["storage_offset_value"] = StrCat(has_base);
+ variables_["storage_offset_comment"] =
+ " // Stored in _has_storage_ to save space.";
+ }
+}
+
+PrimitiveObjFieldGenerator::PrimitiveObjFieldGenerator(
+ const FieldDescriptor* descriptor, const Options& options)
+ : ObjCObjFieldGenerator(descriptor, options) {
+ SetPrimitiveVariables(descriptor, &variables_);
+ variables_["property_storage_attribute"] = "copy";
+}
+
+PrimitiveObjFieldGenerator::~PrimitiveObjFieldGenerator() {}
+
+RepeatedPrimitiveFieldGenerator::RepeatedPrimitiveFieldGenerator(
+ const FieldDescriptor* descriptor, const Options& options)
+ : RepeatedFieldGenerator(descriptor, options) {
+ SetPrimitiveVariables(descriptor, &variables_);
+
+ std::string base_name = PrimitiveArrayTypeName(descriptor);
+ if (base_name.length()) {
+ variables_["array_storage_type"] = "GPB" + base_name + "Array";
+ } else {
+ variables_["array_storage_type"] = "NSMutableArray";
+ variables_["array_property_type"] =
+ "NSMutableArray<" + variables_["storage_type"] + "*>";
+ }
+}
+
+RepeatedPrimitiveFieldGenerator::~RepeatedPrimitiveFieldGenerator() {}
+
+} // namespace objectivec
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_primitive_field.h b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_primitive_field.h
new file mode 100644
index 00000000..88e91ba8
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_primitive_field.h
@@ -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.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_PRIMITIVE_FIELD_H__
+#define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_PRIMITIVE_FIELD_H__
+
+#include <map>
+#include <string>
+#include <compiler/objectivec/objectivec_field.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace objectivec {
+
+class PrimitiveFieldGenerator : public SingleFieldGenerator {
+ friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field,
+ const Options& options);
+
+ protected:
+ PrimitiveFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options);
+ virtual ~PrimitiveFieldGenerator();
+
+ PrimitiveFieldGenerator(const PrimitiveFieldGenerator&) = delete;
+ PrimitiveFieldGenerator& operator=(const PrimitiveFieldGenerator&) = delete;
+
+ virtual void GenerateFieldStorageDeclaration(io::Printer* printer) const override;
+
+ virtual int ExtraRuntimeHasBitsNeeded(void) const override;
+ virtual void SetExtraRuntimeHasBitsBase(int index_base) override;
+};
+
+class PrimitiveObjFieldGenerator : public ObjCObjFieldGenerator {
+ friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field,
+ const Options& options);
+
+ protected:
+ PrimitiveObjFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options);
+ virtual ~PrimitiveObjFieldGenerator();
+
+ PrimitiveObjFieldGenerator(const PrimitiveObjFieldGenerator&) = delete;
+ PrimitiveObjFieldGenerator& operator=(const PrimitiveObjFieldGenerator&) =
+ delete;
+};
+
+class RepeatedPrimitiveFieldGenerator : public RepeatedFieldGenerator {
+ friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field,
+ const Options& options);
+
+ protected:
+ RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options);
+ virtual ~RepeatedPrimitiveFieldGenerator();
+
+ RepeatedPrimitiveFieldGenerator(const RepeatedPrimitiveFieldGenerator&) =
+ delete;
+ RepeatedPrimitiveFieldGenerator& operator=(
+ const RepeatedPrimitiveFieldGenerator&) = delete;
+};
+
+} // namespace objectivec
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_PRIMITIVE_FIELD_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/package_info.h b/NorthstarDedicatedTest/include/protobuf/compiler/package_info.h
new file mode 100644
index 00000000..105ef601
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/package_info.h
@@ -0,0 +1,63 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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::compiler namespace.
+// It is not compiled into anything, but it may be read by an automated
+// documentation generator.
+
+namespace google {
+namespace protobuf {
+
+// Implementation of the Protocol Buffer compiler.
+//
+// This package contains code for parsing .proto files and generating code
+// based on them. There are two reasons you might be interested in this
+// package:
+// - You want to parse .proto files at runtime. In this case, you should
+// look at importer.h. Since this functionality is widely useful, it is
+// included in the libprotobuf base library; you do not have to link against
+// libprotoc.
+// - You want to write a custom protocol compiler which generates different
+// kinds of code, e.g. code in a different language which is not supported
+// by the official compiler. For this purpose, command_line_interface.h
+// provides you with a complete compiler front-end, so all you need to do
+// is write a custom implementation of CodeGenerator and a trivial main()
+// function. You can even make your compiler support the official languages
+// in addition to your own. Since this functionality is only useful to those
+// writing custom compilers, it is in a separate library called "libprotoc"
+// which you will have to link against.
+namespace compiler {}
+
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/parser.cc b/NorthstarDedicatedTest/include/protobuf/compiler/parser.cc
new file mode 100644
index 00000000..6d84ac9f
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/parser.cc
@@ -0,0 +1,2445 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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.
+//
+// Recursive descent FTW.
+
+#include <compiler/parser.h>
+
+#include <float.h>
+
+#include <cstdint>
+#include <limits>
+#include <unordered_map>
+#include <unordered_set>
+
+#include <stubs/casts.h>
+#include <stubs/logging.h>
+#include <stubs/common.h>
+#include <descriptor.pb.h>
+#include <io/tokenizer.h>
+#include <descriptor.h>
+#include <wire_format.h>
+#include <stubs/strutil.h>
+#include <stubs/map_util.h>
+#include <stubs/hash.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+
+using internal::WireFormat;
+
+namespace {
+
+typedef std::unordered_map<std::string, FieldDescriptorProto::Type> TypeNameMap;
+
+TypeNameMap MakeTypeNameTable() {
+ TypeNameMap result;
+
+ result["double"] = FieldDescriptorProto::TYPE_DOUBLE;
+ result["float"] = FieldDescriptorProto::TYPE_FLOAT;
+ result["uint64"] = FieldDescriptorProto::TYPE_UINT64;
+ result["fixed64"] = FieldDescriptorProto::TYPE_FIXED64;
+ result["fixed32"] = FieldDescriptorProto::TYPE_FIXED32;
+ result["bool"] = FieldDescriptorProto::TYPE_BOOL;
+ result["string"] = FieldDescriptorProto::TYPE_STRING;
+ result["group"] = FieldDescriptorProto::TYPE_GROUP;
+
+ result["bytes"] = FieldDescriptorProto::TYPE_BYTES;
+ result["uint32"] = FieldDescriptorProto::TYPE_UINT32;
+ result["sfixed32"] = FieldDescriptorProto::TYPE_SFIXED32;
+ result["sfixed64"] = FieldDescriptorProto::TYPE_SFIXED64;
+ result["int32"] = FieldDescriptorProto::TYPE_INT32;
+ result["int64"] = FieldDescriptorProto::TYPE_INT64;
+ result["sint32"] = FieldDescriptorProto::TYPE_SINT32;
+ result["sint64"] = FieldDescriptorProto::TYPE_SINT64;
+
+ return result;
+}
+
+const TypeNameMap kTypeNames = MakeTypeNameTable();
+
+// Camel-case the field name and append "Entry" for generated map entry name.
+// e.g. map<KeyType, ValueType> foo_map => FooMapEntry
+std::string MapEntryName(const std::string& field_name) {
+ std::string result;
+ static const char kSuffix[] = "Entry";
+ result.reserve(field_name.size() + sizeof(kSuffix));
+ bool cap_next = true;
+ for (const char field_name_char : field_name) {
+ if (field_name_char == '_') {
+ cap_next = true;
+ } else if (cap_next) {
+ // Note: Do not use ctype.h due to locales.
+ if ('a' <= field_name_char && field_name_char <= 'z') {
+ result.push_back(field_name_char - 'a' + 'A');
+ } else {
+ result.push_back(field_name_char);
+ }
+ cap_next = false;
+ } else {
+ result.push_back(field_name_char);
+ }
+ }
+ result.append(kSuffix);
+ return result;
+}
+
+bool IsUppercase(char c) { return c >= 'A' && c <= 'Z'; }
+
+bool IsLowercase(char c) { return c >= 'a' && c <= 'z'; }
+
+bool IsNumber(char c) { return c >= '0' && c <= '9'; }
+
+bool IsUpperCamelCase(const std::string& name) {
+ if (name.empty()) {
+ return true;
+ }
+ // Name must start with an upper case character.
+ if (!IsUppercase(name[0])) {
+ return false;
+ }
+ // Must not contains underscore.
+ for (const char c : name) {
+ if (c == '_') {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool IsUpperUnderscore(const std::string& name) {
+ for (const char c : name) {
+ if (!IsUppercase(c) && c != '_' && !IsNumber(c)) {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool IsLowerUnderscore(const std::string& name) {
+ for (const char c : name) {
+ if (!IsLowercase(c) && c != '_' && !IsNumber(c)) {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool IsNumberFollowUnderscore(const std::string& name) {
+ for (int i = 1; i < name.length(); i++) {
+ const char c = name[i];
+ if (IsNumber(c) && name[i - 1] == '_') {
+ return true;
+ }
+ }
+ return false;
+}
+
+} // anonymous namespace
+
+// 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.
+#define DO(STATEMENT) \
+ if (STATEMENT) { \
+ } else \
+ return false
+
+// ===================================================================
+
+Parser::Parser()
+ : input_(NULL),
+ error_collector_(NULL),
+ source_location_table_(NULL),
+ had_errors_(false),
+ require_syntax_identifier_(false),
+ stop_after_syntax_identifier_(false) {
+}
+
+Parser::~Parser() {}
+
+// ===================================================================
+
+inline bool Parser::LookingAt(const char* text) {
+ return input_->current().text == text;
+}
+
+inline bool Parser::LookingAtType(io::Tokenizer::TokenType token_type) {
+ return input_->current().type == token_type;
+}
+
+inline bool Parser::AtEnd() { return LookingAtType(io::Tokenizer::TYPE_END); }
+
+bool Parser::TryConsume(const char* text) {
+ if (LookingAt(text)) {
+ input_->Next();
+ return true;
+ } else {
+ return false;
+ }
+}
+
+bool Parser::Consume(const char* text, const char* error) {
+ if (TryConsume(text)) {
+ return true;
+ } else {
+ AddError(error);
+ return false;
+ }
+}
+
+bool Parser::Consume(const char* text) {
+ if (TryConsume(text)) {
+ return true;
+ } else {
+ AddError("Expected \"" + std::string(text) + "\".");
+ return false;
+ }
+}
+
+bool Parser::ConsumeIdentifier(std::string* output, const char* error) {
+ if (LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) {
+ *output = input_->current().text;
+ input_->Next();
+ return true;
+ } else {
+ AddError(error);
+ return false;
+ }
+}
+
+bool Parser::ConsumeInteger(int* output, const char* error) {
+ if (LookingAtType(io::Tokenizer::TYPE_INTEGER)) {
+ uint64_t value = 0;
+ if (!io::Tokenizer::ParseInteger(input_->current().text,
+ std::numeric_limits<int32_t>::max(),
+ &value)) {
+ AddError("Integer out of range.");
+ // We still return true because we did, in fact, parse an integer.
+ }
+ *output = value;
+ input_->Next();
+ return true;
+ } else {
+ AddError(error);
+ return false;
+ }
+}
+
+bool Parser::ConsumeSignedInteger(int* output, const char* error) {
+ bool is_negative = false;
+ uint64_t max_value = std::numeric_limits<int32_t>::max();
+ if (TryConsume("-")) {
+ is_negative = true;
+ max_value += 1;
+ }
+ uint64_t value = 0;
+ DO(ConsumeInteger64(max_value, &value, error));
+ if (is_negative) value *= -1;
+ *output = value;
+ return true;
+}
+
+bool Parser::ConsumeInteger64(uint64_t max_value, uint64_t* output,
+ const char* error) {
+ if (LookingAtType(io::Tokenizer::TYPE_INTEGER)) {
+ if (!io::Tokenizer::ParseInteger(input_->current().text, max_value,
+ output)) {
+ AddError("Integer out of range.");
+ // We still return true because we did, in fact, parse an integer.
+ *output = 0;
+ }
+ input_->Next();
+ return true;
+ } else {
+ AddError(error);
+ return false;
+ }
+}
+
+bool Parser::ConsumeNumber(double* output, const char* error) {
+ if (LookingAtType(io::Tokenizer::TYPE_FLOAT)) {
+ *output = io::Tokenizer::ParseFloat(input_->current().text);
+ input_->Next();
+ return true;
+ } else if (LookingAtType(io::Tokenizer::TYPE_INTEGER)) {
+ // Also accept integers.
+ uint64_t value = 0;
+ if (!io::Tokenizer::ParseInteger(input_->current().text,
+ std::numeric_limits<uint64_t>::max(),
+ &value)) {
+ AddError("Integer out of range.");
+ // We still return true because we did, in fact, parse a number.
+ }
+ *output = value;
+ input_->Next();
+ return true;
+ } else if (LookingAt("inf")) {
+ *output = std::numeric_limits<double>::infinity();
+ input_->Next();
+ return true;
+ } else if (LookingAt("nan")) {
+ *output = std::numeric_limits<double>::quiet_NaN();
+ input_->Next();
+ return true;
+ } else {
+ AddError(error);
+ return false;
+ }
+}
+
+bool Parser::ConsumeString(std::string* output, const char* error) {
+ if (LookingAtType(io::Tokenizer::TYPE_STRING)) {
+ io::Tokenizer::ParseString(input_->current().text, output);
+ input_->Next();
+ // Allow C++ like concatenation of adjacent string tokens.
+ while (LookingAtType(io::Tokenizer::TYPE_STRING)) {
+ io::Tokenizer::ParseStringAppend(input_->current().text, output);
+ input_->Next();
+ }
+ return true;
+ } else {
+ AddError(error);
+ return false;
+ }
+}
+
+bool Parser::TryConsumeEndOfDeclaration(const char* text,
+ const LocationRecorder* location) {
+ if (LookingAt(text)) {
+ std::string leading, trailing;
+ std::vector<std::string> detached;
+ input_->NextWithComments(&trailing, &detached, &leading);
+
+ // Save the leading comments for next time, and recall the leading comments
+ // from last time.
+ leading.swap(upcoming_doc_comments_);
+
+ if (location != NULL) {
+ upcoming_detached_comments_.swap(detached);
+ location->AttachComments(&leading, &trailing, &detached);
+ } else if (strcmp(text, "}") == 0) {
+ // If the current location is null and we are finishing the current scope,
+ // drop pending upcoming detached comments.
+ upcoming_detached_comments_.swap(detached);
+ } else {
+ // Otherwise, append the new detached comments to the existing upcoming
+ // detached comments.
+ upcoming_detached_comments_.insert(upcoming_detached_comments_.end(),
+ detached.begin(), detached.end());
+ }
+
+ return true;
+ } else {
+ return false;
+ }
+}
+
+bool Parser::ConsumeEndOfDeclaration(const char* text,
+ const LocationRecorder* location) {
+ if (TryConsumeEndOfDeclaration(text, location)) {
+ return true;
+ } else {
+ AddError("Expected \"" + std::string(text) + "\".");
+ return false;
+ }
+}
+
+// -------------------------------------------------------------------
+
+void Parser::AddError(int line, int column, const std::string& error) {
+ if (error_collector_ != NULL) {
+ error_collector_->AddError(line, column, error);
+ }
+ had_errors_ = true;
+}
+
+void Parser::AddError(const std::string& error) {
+ AddError(input_->current().line, input_->current().column, error);
+}
+
+void Parser::AddWarning(const std::string& warning) {
+ if (error_collector_ != nullptr) {
+ error_collector_->AddWarning(input_->current().line,
+ input_->current().column, warning);
+ }
+}
+
+// -------------------------------------------------------------------
+
+Parser::LocationRecorder::LocationRecorder(Parser* parser)
+ : parser_(parser),
+ source_code_info_(parser->source_code_info_),
+ location_(parser_->source_code_info_->add_location()) {
+ location_->add_span(parser_->input_->current().line);
+ location_->add_span(parser_->input_->current().column);
+}
+
+Parser::LocationRecorder::LocationRecorder(const LocationRecorder& parent) {
+ Init(parent, parent.source_code_info_);
+}
+
+Parser::LocationRecorder::LocationRecorder(const LocationRecorder& parent,
+ int path1,
+ SourceCodeInfo* source_code_info) {
+ Init(parent, source_code_info);
+ AddPath(path1);
+}
+
+Parser::LocationRecorder::LocationRecorder(const LocationRecorder& parent,
+ int path1) {
+ Init(parent, parent.source_code_info_);
+ AddPath(path1);
+}
+
+Parser::LocationRecorder::LocationRecorder(const LocationRecorder& parent,
+ int path1, int path2) {
+ Init(parent, parent.source_code_info_);
+ AddPath(path1);
+ AddPath(path2);
+}
+
+void Parser::LocationRecorder::Init(const LocationRecorder& parent,
+ SourceCodeInfo* source_code_info) {
+ parser_ = parent.parser_;
+ source_code_info_ = source_code_info;
+
+ location_ = source_code_info_->add_location();
+ location_->mutable_path()->CopyFrom(parent.location_->path());
+
+ location_->add_span(parser_->input_->current().line);
+ location_->add_span(parser_->input_->current().column);
+}
+
+Parser::LocationRecorder::~LocationRecorder() {
+ if (location_->span_size() <= 2) {
+ EndAt(parser_->input_->previous());
+ }
+}
+
+void Parser::LocationRecorder::AddPath(int path_component) {
+ location_->add_path(path_component);
+}
+
+void Parser::LocationRecorder::StartAt(const io::Tokenizer::Token& token) {
+ location_->set_span(0, token.line);
+ location_->set_span(1, token.column);
+}
+
+void Parser::LocationRecorder::StartAt(const LocationRecorder& other) {
+ location_->set_span(0, other.location_->span(0));
+ location_->set_span(1, other.location_->span(1));
+}
+
+void Parser::LocationRecorder::EndAt(const io::Tokenizer::Token& token) {
+ if (token.line != location_->span(0)) {
+ location_->add_span(token.line);
+ }
+ location_->add_span(token.end_column);
+}
+
+void Parser::LocationRecorder::RecordLegacyLocation(
+ const Message* descriptor,
+ DescriptorPool::ErrorCollector::ErrorLocation location) {
+ if (parser_->source_location_table_ != NULL) {
+ parser_->source_location_table_->Add(
+ descriptor, location, location_->span(0), location_->span(1));
+ }
+}
+
+void Parser::LocationRecorder::RecordLegacyImportLocation(
+ const Message* descriptor, const std::string& name) {
+ if (parser_->source_location_table_ != nullptr) {
+ parser_->source_location_table_->AddImport(
+ descriptor, name, location_->span(0), location_->span(1));
+ }
+}
+
+int Parser::LocationRecorder::CurrentPathSize() const {
+ return location_->path_size();
+}
+
+void Parser::LocationRecorder::AttachComments(
+ std::string* leading, std::string* trailing,
+ std::vector<std::string>* detached_comments) const {
+ GOOGLE_CHECK(!location_->has_leading_comments());
+ GOOGLE_CHECK(!location_->has_trailing_comments());
+
+ if (!leading->empty()) {
+ location_->mutable_leading_comments()->swap(*leading);
+ }
+ if (!trailing->empty()) {
+ location_->mutable_trailing_comments()->swap(*trailing);
+ }
+ for (int i = 0; i < detached_comments->size(); ++i) {
+ location_->add_leading_detached_comments()->swap((*detached_comments)[i]);
+ }
+ detached_comments->clear();
+}
+
+// -------------------------------------------------------------------
+
+void Parser::SkipStatement() {
+ while (true) {
+ if (AtEnd()) {
+ return;
+ } else if (LookingAtType(io::Tokenizer::TYPE_SYMBOL)) {
+ if (TryConsumeEndOfDeclaration(";", NULL)) {
+ return;
+ } else if (TryConsume("{")) {
+ SkipRestOfBlock();
+ return;
+ } else if (LookingAt("}")) {
+ return;
+ }
+ }
+ input_->Next();
+ }
+}
+
+void Parser::SkipRestOfBlock() {
+ while (true) {
+ if (AtEnd()) {
+ return;
+ } else if (LookingAtType(io::Tokenizer::TYPE_SYMBOL)) {
+ if (TryConsumeEndOfDeclaration("}", NULL)) {
+ return;
+ } else if (TryConsume("{")) {
+ SkipRestOfBlock();
+ }
+ }
+ input_->Next();
+ }
+}
+
+// ===================================================================
+
+bool Parser::ValidateEnum(const EnumDescriptorProto* proto) {
+ bool has_allow_alias = false;
+ bool allow_alias = false;
+
+ for (int i = 0; i < proto->options().uninterpreted_option_size(); i++) {
+ const UninterpretedOption option = proto->options().uninterpreted_option(i);
+ if (option.name_size() > 1) {
+ continue;
+ }
+ if (!option.name(0).is_extension() &&
+ option.name(0).name_part() == "allow_alias") {
+ has_allow_alias = true;
+ if (option.identifier_value() == "true") {
+ allow_alias = true;
+ }
+ break;
+ }
+ }
+
+ if (has_allow_alias && !allow_alias) {
+ std::string error =
+ "\"" + proto->name() +
+ "\" declares 'option allow_alias = false;' which has no effect. "
+ "Please remove the declaration.";
+ // This needlessly clutters declarations with nops.
+ AddError(error);
+ return false;
+ }
+
+ std::set<int> used_values;
+ bool has_duplicates = false;
+ for (int i = 0; i < proto->value_size(); ++i) {
+ const EnumValueDescriptorProto& enum_value = proto->value(i);
+ if (used_values.find(enum_value.number()) != used_values.end()) {
+ has_duplicates = true;
+ break;
+ } else {
+ used_values.insert(enum_value.number());
+ }
+ }
+ if (allow_alias && !has_duplicates) {
+ std::string error =
+ "\"" + proto->name() +
+ "\" declares support for enum aliases but no enum values share field "
+ "numbers. Please remove the unnecessary 'option allow_alias = true;' "
+ "declaration.";
+ // Generate an error if an enum declares support for duplicate enum values
+ // and does not use it protect future authors.
+ AddError(error);
+ return false;
+ }
+
+ // Enforce that enum constants must be UPPER_CASE except in case of
+ // enum_alias.
+ if (!allow_alias) {
+ for (const auto& enum_value : proto->value()) {
+ if (!IsUpperUnderscore(enum_value.name())) {
+ AddWarning(
+ "Enum constant should be in UPPER_CASE. Found: " +
+ enum_value.name() +
+ ". See https://developers.google.com/protocol-buffers/docs/style");
+ }
+ }
+ }
+
+ return true;
+}
+
+bool Parser::Parse(io::Tokenizer* input, FileDescriptorProto* file) {
+ input_ = input;
+ had_errors_ = false;
+ syntax_identifier_.clear();
+
+ // Note that |file| could be NULL at this point if
+ // stop_after_syntax_identifier_ is true. So, we conservatively allocate
+ // SourceCodeInfo on the stack, then swap it into the FileDescriptorProto
+ // later on.
+ SourceCodeInfo source_code_info;
+ source_code_info_ = &source_code_info;
+
+ if (LookingAtType(io::Tokenizer::TYPE_START)) {
+ // Advance to first token.
+ input_->NextWithComments(NULL, &upcoming_detached_comments_,
+ &upcoming_doc_comments_);
+ }
+
+ {
+ LocationRecorder root_location(this);
+ root_location.RecordLegacyLocation(file,
+ DescriptorPool::ErrorCollector::OTHER);
+
+ if (require_syntax_identifier_ || LookingAt("syntax")) {
+ if (!ParseSyntaxIdentifier(root_location)) {
+ // Don't attempt to parse the file if we didn't recognize the syntax
+ // identifier.
+ return false;
+ }
+ // Store the syntax into the file.
+ if (file != NULL) file->set_syntax(syntax_identifier_);
+ } else if (!stop_after_syntax_identifier_) {
+ GOOGLE_LOG(WARNING) << "No syntax specified for the proto file: " << file->name()
+ << ". Please use 'syntax = \"proto2\";' "
+ << "or 'syntax = \"proto3\";' to specify a syntax "
+ << "version. (Defaulted to proto2 syntax.)";
+ syntax_identifier_ = "proto2";
+ }
+
+ if (stop_after_syntax_identifier_) return !had_errors_;
+
+ // Repeatedly parse statements until we reach the end of the file.
+ while (!AtEnd()) {
+ if (!ParseTopLevelStatement(file, root_location)) {
+ // This statement failed to parse. Skip it, but keep looping to parse
+ // other statements.
+ SkipStatement();
+
+ if (LookingAt("}")) {
+ AddError("Unmatched \"}\".");
+ input_->NextWithComments(NULL, &upcoming_detached_comments_,
+ &upcoming_doc_comments_);
+ }
+ }
+ }
+ }
+
+ input_ = NULL;
+ source_code_info_ = NULL;
+ assert(file != NULL);
+ source_code_info.Swap(file->mutable_source_code_info());
+ return !had_errors_;
+}
+
+bool Parser::ParseSyntaxIdentifier(const LocationRecorder& parent) {
+ LocationRecorder syntax_location(parent,
+ FileDescriptorProto::kSyntaxFieldNumber);
+ DO(Consume(
+ "syntax",
+ "File must begin with a syntax statement, e.g. 'syntax = \"proto2\";'."));
+ DO(Consume("="));
+ io::Tokenizer::Token syntax_token = input_->current();
+ std::string syntax;
+ DO(ConsumeString(&syntax, "Expected syntax identifier."));
+ DO(ConsumeEndOfDeclaration(";", &syntax_location));
+
+ syntax_identifier_ = syntax;
+
+ if (syntax != "proto2" && syntax != "proto3" &&
+ !stop_after_syntax_identifier_) {
+ AddError(syntax_token.line, syntax_token.column,
+ "Unrecognized syntax identifier \"" + syntax +
+ "\". This parser "
+ "only recognizes \"proto2\" and \"proto3\".");
+ return false;
+ }
+
+ return true;
+}
+
+bool Parser::ParseTopLevelStatement(FileDescriptorProto* file,
+ const LocationRecorder& root_location) {
+ if (TryConsumeEndOfDeclaration(";", NULL)) {
+ // empty statement; ignore
+ return true;
+ } else if (LookingAt("message")) {
+ LocationRecorder location(root_location,
+ FileDescriptorProto::kMessageTypeFieldNumber,
+ file->message_type_size());
+ return ParseMessageDefinition(file->add_message_type(), location, file);
+ } else if (LookingAt("enum")) {
+ LocationRecorder location(root_location,
+ FileDescriptorProto::kEnumTypeFieldNumber,
+ file->enum_type_size());
+ return ParseEnumDefinition(file->add_enum_type(), location, file);
+ } else if (LookingAt("service")) {
+ LocationRecorder location(root_location,
+ FileDescriptorProto::kServiceFieldNumber,
+ file->service_size());
+ return ParseServiceDefinition(file->add_service(), location, file);
+ } else if (LookingAt("extend")) {
+ LocationRecorder location(root_location,
+ FileDescriptorProto::kExtensionFieldNumber);
+ return ParseExtend(
+ file->mutable_extension(), file->mutable_message_type(), root_location,
+ FileDescriptorProto::kMessageTypeFieldNumber, location, file);
+ } else if (LookingAt("import")) {
+ return ParseImport(file->mutable_dependency(),
+ file->mutable_public_dependency(),
+ file->mutable_weak_dependency(), root_location, file);
+ } else if (LookingAt("package")) {
+ return ParsePackage(file, root_location, file);
+ } else if (LookingAt("option")) {
+ LocationRecorder location(root_location,
+ FileDescriptorProto::kOptionsFieldNumber);
+ return ParseOption(file->mutable_options(), location, file,
+ OPTION_STATEMENT);
+ } else {
+ AddError("Expected top-level statement (e.g. \"message\").");
+ return false;
+ }
+}
+
+// -------------------------------------------------------------------
+// Messages
+
+bool Parser::ParseMessageDefinition(
+ DescriptorProto* message, const LocationRecorder& message_location,
+ const FileDescriptorProto* containing_file) {
+ DO(Consume("message"));
+ {
+ LocationRecorder location(message_location,
+ DescriptorProto::kNameFieldNumber);
+ location.RecordLegacyLocation(message,
+ DescriptorPool::ErrorCollector::NAME);
+ DO(ConsumeIdentifier(message->mutable_name(), "Expected message name."));
+ if (!IsUpperCamelCase(message->name())) {
+ AddWarning(
+ "Message name should be in UpperCamelCase. Found: " +
+ message->name() +
+ ". See https://developers.google.com/protocol-buffers/docs/style");
+ }
+ }
+ DO(ParseMessageBlock(message, message_location, containing_file));
+
+ if (syntax_identifier_ == "proto3") {
+ // Add synthetic one-field oneofs for optional fields, except messages which
+ // already have presence in proto3.
+ //
+ // We have to make sure the oneof names don't conflict with any other
+ // field or oneof.
+ std::unordered_set<std::string> names;
+ for (const auto& field : message->field()) {
+ names.insert(field.name());
+ }
+ for (const auto& oneof : message->oneof_decl()) {
+ names.insert(oneof.name());
+ }
+
+ for (auto& field : *message->mutable_field()) {
+ if (field.proto3_optional()) {
+ std::string oneof_name = field.name();
+
+ // Prepend 'XXXXX_' until we are no longer conflicting.
+ // Avoid prepending a double-underscore because such names are
+ // reserved in C++.
+ if (oneof_name.empty() || oneof_name[0] != '_') {
+ oneof_name = '_' + oneof_name;
+ }
+ while (names.count(oneof_name) > 0) {
+ oneof_name = 'X' + oneof_name;
+ }
+
+ names.insert(oneof_name);
+ field.set_oneof_index(message->oneof_decl_size());
+ OneofDescriptorProto* oneof = message->add_oneof_decl();
+ oneof->set_name(oneof_name);
+ }
+ }
+ }
+
+ return true;
+}
+
+namespace {
+
+const int kMaxRangeSentinel = -1;
+
+bool IsMessageSetWireFormatMessage(const DescriptorProto& message) {
+ const MessageOptions& options = message.options();
+ for (int i = 0; i < options.uninterpreted_option_size(); ++i) {
+ const UninterpretedOption& uninterpreted = options.uninterpreted_option(i);
+ if (uninterpreted.name_size() == 1 &&
+ uninterpreted.name(0).name_part() == "message_set_wire_format" &&
+ uninterpreted.identifier_value() == "true") {
+ return true;
+ }
+ }
+ return false;
+}
+
+// Modifies any extension ranges that specified 'max' as the end of the
+// extension range, and sets them to the type-specific maximum. The actual max
+// tag number can only be determined after all options have been parsed.
+void AdjustExtensionRangesWithMaxEndNumber(DescriptorProto* message) {
+ const bool is_message_set = IsMessageSetWireFormatMessage(*message);
+ const int max_extension_number = is_message_set
+ ? std::numeric_limits<int32_t>::max()
+ : FieldDescriptor::kMaxNumber + 1;
+ for (int i = 0; i < message->extension_range_size(); ++i) {
+ if (message->extension_range(i).end() == kMaxRangeSentinel) {
+ message->mutable_extension_range(i)->set_end(max_extension_number);
+ }
+ }
+}
+
+// Modifies any reserved ranges that specified 'max' as the end of the
+// reserved range, and sets them to the type-specific maximum. The actual max
+// tag number can only be determined after all options have been parsed.
+void AdjustReservedRangesWithMaxEndNumber(DescriptorProto* message) {
+ const bool is_message_set = IsMessageSetWireFormatMessage(*message);
+ const int max_field_number = is_message_set
+ ? std::numeric_limits<int32_t>::max()
+ : FieldDescriptor::kMaxNumber + 1;
+ for (int i = 0; i < message->reserved_range_size(); ++i) {
+ if (message->reserved_range(i).end() == kMaxRangeSentinel) {
+ message->mutable_reserved_range(i)->set_end(max_field_number);
+ }
+ }
+}
+
+} // namespace
+
+bool Parser::ParseMessageBlock(DescriptorProto* message,
+ const LocationRecorder& message_location,
+ const FileDescriptorProto* containing_file) {
+ DO(ConsumeEndOfDeclaration("{", &message_location));
+
+ while (!TryConsumeEndOfDeclaration("}", NULL)) {
+ if (AtEnd()) {
+ AddError("Reached end of input in message definition (missing '}').");
+ return false;
+ }
+
+ if (!ParseMessageStatement(message, message_location, containing_file)) {
+ // This statement failed to parse. Skip it, but keep looping to parse
+ // other statements.
+ SkipStatement();
+ }
+ }
+
+ if (message->extension_range_size() > 0) {
+ AdjustExtensionRangesWithMaxEndNumber(message);
+ }
+ if (message->reserved_range_size() > 0) {
+ AdjustReservedRangesWithMaxEndNumber(message);
+ }
+ return true;
+}
+
+bool Parser::ParseMessageStatement(DescriptorProto* message,
+ const LocationRecorder& message_location,
+ const FileDescriptorProto* containing_file) {
+ if (TryConsumeEndOfDeclaration(";", NULL)) {
+ // empty statement; ignore
+ return true;
+ } else if (LookingAt("message")) {
+ LocationRecorder location(message_location,
+ DescriptorProto::kNestedTypeFieldNumber,
+ message->nested_type_size());
+ return ParseMessageDefinition(message->add_nested_type(), location,
+ containing_file);
+ } else if (LookingAt("enum")) {
+ LocationRecorder location(message_location,
+ DescriptorProto::kEnumTypeFieldNumber,
+ message->enum_type_size());
+ return ParseEnumDefinition(message->add_enum_type(), location,
+ containing_file);
+ } else if (LookingAt("extensions")) {
+ LocationRecorder location(message_location,
+ DescriptorProto::kExtensionRangeFieldNumber);
+ return ParseExtensions(message, location, containing_file);
+ } else if (LookingAt("reserved")) {
+ return ParseReserved(message, message_location);
+ } else if (LookingAt("extend")) {
+ LocationRecorder location(message_location,
+ DescriptorProto::kExtensionFieldNumber);
+ return ParseExtend(message->mutable_extension(),
+ message->mutable_nested_type(), message_location,
+ DescriptorProto::kNestedTypeFieldNumber, location,
+ containing_file);
+ } else if (LookingAt("option")) {
+ LocationRecorder location(message_location,
+ DescriptorProto::kOptionsFieldNumber);
+ return ParseOption(message->mutable_options(), location, containing_file,
+ OPTION_STATEMENT);
+ } else if (LookingAt("oneof")) {
+ int oneof_index = message->oneof_decl_size();
+ LocationRecorder oneof_location(
+ message_location, DescriptorProto::kOneofDeclFieldNumber, oneof_index);
+
+ return ParseOneof(message->add_oneof_decl(), message, oneof_index,
+ oneof_location, message_location, containing_file);
+ } else {
+ LocationRecorder location(message_location,
+ DescriptorProto::kFieldFieldNumber,
+ message->field_size());
+ return ParseMessageField(
+ message->add_field(), message->mutable_nested_type(), message_location,
+ DescriptorProto::kNestedTypeFieldNumber, location, containing_file);
+ }
+}
+
+bool Parser::ParseMessageField(FieldDescriptorProto* field,
+ RepeatedPtrField<DescriptorProto>* messages,
+ const LocationRecorder& parent_location,
+ int location_field_number_for_nested_type,
+ const LocationRecorder& field_location,
+ const FileDescriptorProto* containing_file) {
+ {
+ FieldDescriptorProto::Label label;
+ if (ParseLabel(&label, field_location, containing_file)) {
+ field->set_label(label);
+ if (label == FieldDescriptorProto::LABEL_OPTIONAL &&
+ syntax_identifier_ == "proto3") {
+ field->set_proto3_optional(true);
+ }
+ }
+ }
+
+ return ParseMessageFieldNoLabel(field, messages, parent_location,
+ location_field_number_for_nested_type,
+ field_location, containing_file);
+}
+
+bool Parser::ParseMessageFieldNoLabel(
+ FieldDescriptorProto* field, RepeatedPtrField<DescriptorProto>* messages,
+ const LocationRecorder& parent_location,
+ int location_field_number_for_nested_type,
+ const LocationRecorder& field_location,
+ const FileDescriptorProto* containing_file) {
+ MapField map_field;
+ // Parse type.
+ {
+ LocationRecorder location(field_location); // add path later
+ location.RecordLegacyLocation(field, DescriptorPool::ErrorCollector::TYPE);
+
+ bool type_parsed = false;
+ FieldDescriptorProto::Type type = FieldDescriptorProto::TYPE_INT32;
+ std::string type_name;
+
+ // Special case map field. We only treat the field as a map field if the
+ // field type name starts with the word "map" with a following "<".
+ if (TryConsume("map")) {
+ if (LookingAt("<")) {
+ map_field.is_map_field = true;
+ } else {
+ // False positive
+ type_parsed = true;
+ type_name = "map";
+ }
+ }
+ if (map_field.is_map_field) {
+ if (field->has_oneof_index()) {
+ AddError("Map fields are not allowed in oneofs.");
+ return false;
+ }
+ if (field->has_label()) {
+ AddError(
+ "Field labels (required/optional/repeated) are not allowed on "
+ "map fields.");
+ return false;
+ }
+ if (field->has_extendee()) {
+ AddError("Map fields are not allowed to be extensions.");
+ return false;
+ }
+ field->set_label(FieldDescriptorProto::LABEL_REPEATED);
+ DO(Consume("<"));
+ DO(ParseType(&map_field.key_type, &map_field.key_type_name));
+ DO(Consume(","));
+ DO(ParseType(&map_field.value_type, &map_field.value_type_name));
+ DO(Consume(">"));
+ // Defer setting of the type name of the map field until the
+ // field name is parsed. Add the source location though.
+ location.AddPath(FieldDescriptorProto::kTypeNameFieldNumber);
+ } else {
+ // Handle the case where no explicit label is given for a non-map field.
+ if (!field->has_label() && DefaultToOptionalFields()) {
+ field->set_label(FieldDescriptorProto::LABEL_OPTIONAL);
+ }
+ if (!field->has_label()) {
+ AddError("Expected \"required\", \"optional\", or \"repeated\".");
+ // We can actually reasonably recover here by just assuming the user
+ // forgot the label altogether.
+ field->set_label(FieldDescriptorProto::LABEL_OPTIONAL);
+ }
+
+ // Handle the case where the actual type is a message or enum named "map",
+ // which we already consumed in the code above.
+ if (!type_parsed) {
+ DO(ParseType(&type, &type_name));
+ }
+ if (type_name.empty()) {
+ location.AddPath(FieldDescriptorProto::kTypeFieldNumber);
+ field->set_type(type);
+ } else {
+ location.AddPath(FieldDescriptorProto::kTypeNameFieldNumber);
+ field->set_type_name(type_name);
+ }
+ }
+ }
+
+ // Parse name and '='.
+ io::Tokenizer::Token name_token = input_->current();
+ {
+ LocationRecorder location(field_location,
+ FieldDescriptorProto::kNameFieldNumber);
+ location.RecordLegacyLocation(field, DescriptorPool::ErrorCollector::NAME);
+ DO(ConsumeIdentifier(field->mutable_name(), "Expected field name."));
+
+ if (!IsLowerUnderscore(field->name())) {
+ AddWarning(
+ "Field name should be lowercase. Found: " + field->name() +
+ ". See: https://developers.google.com/protocol-buffers/docs/style");
+ }
+ if (IsNumberFollowUnderscore(field->name())) {
+ AddWarning(
+ "Number should not come right after an underscore. Found: " +
+ field->name() +
+ ". See: https://developers.google.com/protocol-buffers/docs/style");
+ }
+ }
+ DO(Consume("=", "Missing field number."));
+
+ // Parse field number.
+ {
+ LocationRecorder location(field_location,
+ FieldDescriptorProto::kNumberFieldNumber);
+ location.RecordLegacyLocation(field,
+ DescriptorPool::ErrorCollector::NUMBER);
+ int number;
+ DO(ConsumeInteger(&number, "Expected field number."));
+ field->set_number(number);
+ }
+
+ // Parse options.
+ DO(ParseFieldOptions(field, field_location, containing_file));
+
+ // Deal with groups.
+ if (field->has_type() && field->type() == FieldDescriptorProto::TYPE_GROUP) {
+ // Awkward: Since a group declares both a message type and a field, we
+ // have to create overlapping locations.
+ LocationRecorder group_location(parent_location);
+ group_location.StartAt(field_location);
+ group_location.AddPath(location_field_number_for_nested_type);
+ group_location.AddPath(messages->size());
+
+ DescriptorProto* group = messages->Add();
+ group->set_name(field->name());
+
+ // Record name location to match the field name's location.
+ {
+ LocationRecorder location(group_location,
+ DescriptorProto::kNameFieldNumber);
+ location.StartAt(name_token);
+ location.EndAt(name_token);
+ location.RecordLegacyLocation(group,
+ DescriptorPool::ErrorCollector::NAME);
+ }
+
+ // The field's type_name also comes from the name. Confusing!
+ {
+ LocationRecorder location(field_location,
+ FieldDescriptorProto::kTypeNameFieldNumber);
+ location.StartAt(name_token);
+ location.EndAt(name_token);
+ }
+
+ // As a hack for backwards-compatibility, we force the group name to start
+ // with a capital letter and lower-case the field name. New code should
+ // not use groups; it should use nested messages.
+ if (group->name()[0] < 'A' || 'Z' < group->name()[0]) {
+ AddError(name_token.line, name_token.column,
+ "Group names must start with a capital letter.");
+ }
+ LowerString(field->mutable_name());
+
+ field->set_type_name(group->name());
+ if (LookingAt("{")) {
+ DO(ParseMessageBlock(group, group_location, containing_file));
+ } else {
+ AddError("Missing group body.");
+ return false;
+ }
+ } else {
+ DO(ConsumeEndOfDeclaration(";", &field_location));
+ }
+
+ // Create a map entry type if this is a map field.
+ if (map_field.is_map_field) {
+ GenerateMapEntry(map_field, field, messages);
+ }
+
+ return true;
+}
+
+void Parser::GenerateMapEntry(const MapField& map_field,
+ FieldDescriptorProto* field,
+ RepeatedPtrField<DescriptorProto>* messages) {
+ DescriptorProto* entry = messages->Add();
+ std::string entry_name = MapEntryName(field->name());
+ field->set_type_name(entry_name);
+ entry->set_name(entry_name);
+ entry->mutable_options()->set_map_entry(true);
+ FieldDescriptorProto* key_field = entry->add_field();
+ key_field->set_name("key");
+ key_field->set_label(FieldDescriptorProto::LABEL_OPTIONAL);
+ key_field->set_number(1);
+ if (map_field.key_type_name.empty()) {
+ key_field->set_type(map_field.key_type);
+ } else {
+ key_field->set_type_name(map_field.key_type_name);
+ }
+ FieldDescriptorProto* value_field = entry->add_field();
+ value_field->set_name("value");
+ value_field->set_label(FieldDescriptorProto::LABEL_OPTIONAL);
+ value_field->set_number(2);
+ if (map_field.value_type_name.empty()) {
+ value_field->set_type(map_field.value_type);
+ } else {
+ value_field->set_type_name(map_field.value_type_name);
+ }
+ // Propagate the "enforce_utf8" option to key and value fields if they
+ // are strings. This helps simplify the implementation of code generators
+ // and also reflection-based parsing code.
+ //
+ // The following definition:
+ // message Foo {
+ // map<string, string> value = 1 [enforce_utf8 = false];
+ // }
+ // will be interpreted as:
+ // message Foo {
+ // message ValueEntry {
+ // option map_entry = true;
+ // string key = 1 [enforce_utf8 = false];
+ // string value = 2 [enforce_utf8 = false];
+ // }
+ // repeated ValueEntry value = 1 [enforce_utf8 = false];
+ // }
+ //
+ // TODO(xiaofeng): Remove this when the "enforce_utf8" option is removed
+ // from protocol compiler.
+ for (int i = 0; i < field->options().uninterpreted_option_size(); ++i) {
+ const UninterpretedOption& option =
+ field->options().uninterpreted_option(i);
+ if (option.name_size() == 1 &&
+ option.name(0).name_part() == "enforce_utf8" &&
+ !option.name(0).is_extension()) {
+ if (key_field->type() == FieldDescriptorProto::TYPE_STRING) {
+ key_field->mutable_options()->add_uninterpreted_option()->CopyFrom(
+ option);
+ }
+ if (value_field->type() == FieldDescriptorProto::TYPE_STRING) {
+ value_field->mutable_options()->add_uninterpreted_option()->CopyFrom(
+ option);
+ }
+ }
+ }
+}
+
+bool Parser::ParseFieldOptions(FieldDescriptorProto* field,
+ const LocationRecorder& field_location,
+ const FileDescriptorProto* containing_file) {
+ if (!LookingAt("[")) return true;
+
+ LocationRecorder location(field_location,
+ FieldDescriptorProto::kOptionsFieldNumber);
+
+ DO(Consume("["));
+
+ // Parse field options.
+ do {
+ if (LookingAt("default")) {
+ // We intentionally pass field_location rather than location here, since
+ // the default value is not actually an option.
+ DO(ParseDefaultAssignment(field, field_location, containing_file));
+ } else if (LookingAt("json_name")) {
+ // Like default value, this "json_name" is not an actual option.
+ DO(ParseJsonName(field, field_location, containing_file));
+ } else {
+ DO(ParseOption(field->mutable_options(), location, containing_file,
+ OPTION_ASSIGNMENT));
+ }
+ } while (TryConsume(","));
+
+ DO(Consume("]"));
+ return true;
+}
+
+bool Parser::ParseDefaultAssignment(
+ FieldDescriptorProto* field, const LocationRecorder& field_location,
+ const FileDescriptorProto* containing_file) {
+ if (field->has_default_value()) {
+ AddError("Already set option \"default\".");
+ field->clear_default_value();
+ }
+
+ DO(Consume("default"));
+ DO(Consume("="));
+
+ LocationRecorder location(field_location,
+ FieldDescriptorProto::kDefaultValueFieldNumber);
+ location.RecordLegacyLocation(field,
+ DescriptorPool::ErrorCollector::DEFAULT_VALUE);
+ std::string* default_value = field->mutable_default_value();
+
+ if (!field->has_type()) {
+ // The field has a type name, but we don't know if it is a message or an
+ // enum yet. (If it were a primitive type, |field| would have a type set
+ // already.) In this case, simply take the current string as the default
+ // value; we will catch the error later if it is not a valid enum value.
+ // (N.B. that we do not check whether the current token is an identifier:
+ // doing so throws strange errors when the user mistypes a primitive
+ // typename and we assume it's an enum. E.g.: "optional int foo = 1 [default
+ // = 42]". In such a case the fundamental error is really that "int" is not
+ // a type, not that "42" is not an identifier. See b/12533582.)
+ *default_value = input_->current().text;
+ input_->Next();
+ return true;
+ }
+
+ switch (field->type()) {
+ case FieldDescriptorProto::TYPE_INT32:
+ case FieldDescriptorProto::TYPE_INT64:
+ case FieldDescriptorProto::TYPE_SINT32:
+ case FieldDescriptorProto::TYPE_SINT64:
+ case FieldDescriptorProto::TYPE_SFIXED32:
+ case FieldDescriptorProto::TYPE_SFIXED64: {
+ uint64_t max_value = std::numeric_limits<int64_t>::max();
+ if (field->type() == FieldDescriptorProto::TYPE_INT32 ||
+ field->type() == FieldDescriptorProto::TYPE_SINT32 ||
+ field->type() == FieldDescriptorProto::TYPE_SFIXED32) {
+ max_value = std::numeric_limits<int32_t>::max();
+ }
+
+ // These types can be negative.
+ if (TryConsume("-")) {
+ default_value->append("-");
+ // Two's complement always has one more negative value than positive.
+ ++max_value;
+ }
+ // Parse the integer to verify that it is not out-of-range.
+ uint64_t value;
+ DO(ConsumeInteger64(max_value, &value,
+ "Expected integer for field default value."));
+ // And stringify it again.
+ default_value->append(StrCat(value));
+ break;
+ }
+
+ case FieldDescriptorProto::TYPE_UINT32:
+ case FieldDescriptorProto::TYPE_UINT64:
+ case FieldDescriptorProto::TYPE_FIXED32:
+ case FieldDescriptorProto::TYPE_FIXED64: {
+ uint64_t max_value = std::numeric_limits<uint64_t>::max();
+ if (field->type() == FieldDescriptorProto::TYPE_UINT32 ||
+ field->type() == FieldDescriptorProto::TYPE_FIXED32) {
+ max_value = std::numeric_limits<uint32_t>::max();
+ }
+
+ // Numeric, not negative.
+ if (TryConsume("-")) {
+ AddError("Unsigned field can't have negative default value.");
+ }
+ // Parse the integer to verify that it is not out-of-range.
+ uint64_t value;
+ DO(ConsumeInteger64(max_value, &value,
+ "Expected integer for field default value."));
+ // And stringify it again.
+ default_value->append(StrCat(value));
+ break;
+ }
+
+ case FieldDescriptorProto::TYPE_FLOAT:
+ case FieldDescriptorProto::TYPE_DOUBLE:
+ // These types can be negative.
+ if (TryConsume("-")) {
+ default_value->append("-");
+ }
+ // Parse the integer because we have to convert hex integers to decimal
+ // floats.
+ double value;
+ DO(ConsumeNumber(&value, "Expected number."));
+ // And stringify it again.
+ default_value->append(SimpleDtoa(value));
+ break;
+
+ case FieldDescriptorProto::TYPE_BOOL:
+ if (TryConsume("true")) {
+ default_value->assign("true");
+ } else if (TryConsume("false")) {
+ default_value->assign("false");
+ } else {
+ AddError("Expected \"true\" or \"false\".");
+ return false;
+ }
+ break;
+
+ case FieldDescriptorProto::TYPE_STRING:
+ // Note: When file option java_string_check_utf8 is true, if a
+ // non-string representation (eg byte[]) is later supported, it must
+ // be checked for UTF-8-ness.
+ DO(ConsumeString(default_value,
+ "Expected string for field default "
+ "value."));
+ break;
+
+ case FieldDescriptorProto::TYPE_BYTES:
+ DO(ConsumeString(default_value, "Expected string."));
+ *default_value = CEscape(*default_value);
+ break;
+
+ case FieldDescriptorProto::TYPE_ENUM:
+ DO(ConsumeIdentifier(default_value,
+ "Expected enum identifier for field "
+ "default value."));
+ break;
+
+ case FieldDescriptorProto::TYPE_MESSAGE:
+ case FieldDescriptorProto::TYPE_GROUP:
+ AddError("Messages can't have default values.");
+ return false;
+ }
+
+ return true;
+}
+
+bool Parser::ParseJsonName(FieldDescriptorProto* field,
+ const LocationRecorder& field_location,
+ const FileDescriptorProto* containing_file) {
+ if (field->has_json_name()) {
+ AddError("Already set option \"json_name\".");
+ field->clear_json_name();
+ }
+
+ LocationRecorder location(field_location,
+ FieldDescriptorProto::kJsonNameFieldNumber);
+ location.RecordLegacyLocation(field,
+ DescriptorPool::ErrorCollector::OPTION_NAME);
+
+ DO(Consume("json_name"));
+ DO(Consume("="));
+
+ LocationRecorder value_location(location);
+ value_location.RecordLegacyLocation(
+ field, DescriptorPool::ErrorCollector::OPTION_VALUE);
+
+ DO(ConsumeString(field->mutable_json_name(),
+ "Expected string for JSON name."));
+ return true;
+}
+
+bool Parser::ParseOptionNamePart(UninterpretedOption* uninterpreted_option,
+ const LocationRecorder& part_location,
+ const FileDescriptorProto* containing_file) {
+ UninterpretedOption::NamePart* name = uninterpreted_option->add_name();
+ std::string identifier; // We parse identifiers into this string.
+ if (LookingAt("(")) { // This is an extension.
+ DO(Consume("("));
+
+ {
+ LocationRecorder location(
+ part_location, UninterpretedOption::NamePart::kNamePartFieldNumber);
+ // An extension name consists of dot-separated identifiers, and may begin
+ // with a dot.
+ if (LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) {
+ DO(ConsumeIdentifier(&identifier, "Expected identifier."));
+ name->mutable_name_part()->append(identifier);
+ }
+ while (LookingAt(".")) {
+ DO(Consume("."));
+ name->mutable_name_part()->append(".");
+ DO(ConsumeIdentifier(&identifier, "Expected identifier."));
+ name->mutable_name_part()->append(identifier);
+ }
+ }
+
+ DO(Consume(")"));
+ name->set_is_extension(true);
+ } else { // This is a regular field.
+ LocationRecorder location(
+ part_location, UninterpretedOption::NamePart::kNamePartFieldNumber);
+ DO(ConsumeIdentifier(&identifier, "Expected identifier."));
+ name->mutable_name_part()->append(identifier);
+ name->set_is_extension(false);
+ }
+ return true;
+}
+
+bool Parser::ParseUninterpretedBlock(std::string* value) {
+ // Note that enclosing braces are not added to *value.
+ // We do NOT use ConsumeEndOfStatement for this brace because it's delimiting
+ // an expression, not a block of statements.
+ DO(Consume("{"));
+ int brace_depth = 1;
+ while (!AtEnd()) {
+ if (LookingAt("{")) {
+ brace_depth++;
+ } else if (LookingAt("}")) {
+ brace_depth--;
+ if (brace_depth == 0) {
+ input_->Next();
+ return true;
+ }
+ }
+ // TODO(sanjay): Interpret line/column numbers to preserve formatting
+ if (!value->empty()) value->push_back(' ');
+ value->append(input_->current().text);
+ input_->Next();
+ }
+ AddError("Unexpected end of stream while parsing aggregate value.");
+ return false;
+}
+
+// We don't interpret the option here. Instead we store it in an
+// UninterpretedOption, to be interpreted later.
+bool Parser::ParseOption(Message* options,
+ const LocationRecorder& options_location,
+ const FileDescriptorProto* containing_file,
+ OptionStyle style) {
+ // Create an entry in the uninterpreted_option field.
+ const FieldDescriptor* uninterpreted_option_field =
+ options->GetDescriptor()->FindFieldByName("uninterpreted_option");
+ GOOGLE_CHECK(uninterpreted_option_field != NULL)
+ << "No field named \"uninterpreted_option\" in the Options proto.";
+
+ const Reflection* reflection = options->GetReflection();
+
+ LocationRecorder location(
+ options_location, uninterpreted_option_field->number(),
+ reflection->FieldSize(*options, uninterpreted_option_field));
+
+ if (style == OPTION_STATEMENT) {
+ DO(Consume("option"));
+ }
+
+ UninterpretedOption* uninterpreted_option =
+ down_cast<UninterpretedOption*>(options->GetReflection()->AddMessage(
+ options, uninterpreted_option_field));
+
+ // Parse dot-separated name.
+ {
+ LocationRecorder name_location(location,
+ UninterpretedOption::kNameFieldNumber);
+ name_location.RecordLegacyLocation(
+ uninterpreted_option, DescriptorPool::ErrorCollector::OPTION_NAME);
+
+ {
+ LocationRecorder part_location(name_location,
+ uninterpreted_option->name_size());
+ DO(ParseOptionNamePart(uninterpreted_option, part_location,
+ containing_file));
+ }
+
+ while (LookingAt(".")) {
+ DO(Consume("."));
+ LocationRecorder part_location(name_location,
+ uninterpreted_option->name_size());
+ DO(ParseOptionNamePart(uninterpreted_option, part_location,
+ containing_file));
+ }
+ }
+
+ DO(Consume("="));
+
+ {
+ LocationRecorder value_location(location);
+ value_location.RecordLegacyLocation(
+ uninterpreted_option, DescriptorPool::ErrorCollector::OPTION_VALUE);
+
+ // All values are a single token, except for negative numbers, which consist
+ // of a single '-' symbol, followed by a positive number.
+ bool is_negative = TryConsume("-");
+
+ switch (input_->current().type) {
+ case io::Tokenizer::TYPE_START:
+ GOOGLE_LOG(FATAL) << "Trying to read value before any tokens have been read.";
+ return false;
+
+ case io::Tokenizer::TYPE_END:
+ AddError("Unexpected end of stream while parsing option value.");
+ return false;
+
+ case io::Tokenizer::TYPE_WHITESPACE:
+ case io::Tokenizer::TYPE_NEWLINE:
+ GOOGLE_CHECK(!input_->report_whitespace() && !input_->report_newlines())
+ << "Whitespace tokens were not requested.";
+ GOOGLE_LOG(FATAL) << "Tokenizer reported whitespace.";
+ return false;
+
+ case io::Tokenizer::TYPE_IDENTIFIER: {
+ value_location.AddPath(
+ UninterpretedOption::kIdentifierValueFieldNumber);
+ if (is_negative) {
+ AddError("Invalid '-' symbol before identifier.");
+ return false;
+ }
+ std::string value;
+ DO(ConsumeIdentifier(&value, "Expected identifier."));
+ uninterpreted_option->set_identifier_value(value);
+ break;
+ }
+
+ case io::Tokenizer::TYPE_INTEGER: {
+ uint64_t value;
+ uint64_t max_value =
+ is_negative
+ ? static_cast<uint64_t>(std::numeric_limits<int64_t>::max()) + 1
+ : std::numeric_limits<uint64_t>::max();
+ DO(ConsumeInteger64(max_value, &value, "Expected integer."));
+ if (is_negative) {
+ value_location.AddPath(
+ UninterpretedOption::kNegativeIntValueFieldNumber);
+ uninterpreted_option->set_negative_int_value(
+ static_cast<int64_t>(0 - value));
+ } else {
+ value_location.AddPath(
+ UninterpretedOption::kPositiveIntValueFieldNumber);
+ uninterpreted_option->set_positive_int_value(value);
+ }
+ break;
+ }
+
+ case io::Tokenizer::TYPE_FLOAT: {
+ value_location.AddPath(UninterpretedOption::kDoubleValueFieldNumber);
+ double value;
+ DO(ConsumeNumber(&value, "Expected number."));
+ uninterpreted_option->set_double_value(is_negative ? -value : value);
+ break;
+ }
+
+ case io::Tokenizer::TYPE_STRING: {
+ value_location.AddPath(UninterpretedOption::kStringValueFieldNumber);
+ if (is_negative) {
+ AddError("Invalid '-' symbol before string.");
+ return false;
+ }
+ std::string value;
+ DO(ConsumeString(&value, "Expected string."));
+ uninterpreted_option->set_string_value(value);
+ break;
+ }
+
+ case io::Tokenizer::TYPE_SYMBOL:
+ if (LookingAt("{")) {
+ value_location.AddPath(
+ UninterpretedOption::kAggregateValueFieldNumber);
+ DO(ParseUninterpretedBlock(
+ uninterpreted_option->mutable_aggregate_value()));
+ } else {
+ AddError("Expected option value.");
+ return false;
+ }
+ break;
+ }
+ }
+
+ if (style == OPTION_STATEMENT) {
+ DO(ConsumeEndOfDeclaration(";", &location));
+ }
+
+ return true;
+}
+
+bool Parser::ParseExtensions(DescriptorProto* message,
+ const LocationRecorder& extensions_location,
+ const FileDescriptorProto* containing_file) {
+ // Parse the declaration.
+ DO(Consume("extensions"));
+
+ int old_range_size = message->extension_range_size();
+
+ do {
+ // Note that kExtensionRangeFieldNumber was already pushed by the parent.
+ LocationRecorder location(extensions_location,
+ message->extension_range_size());
+
+ DescriptorProto::ExtensionRange* range = message->add_extension_range();
+ location.RecordLegacyLocation(range,
+ DescriptorPool::ErrorCollector::NUMBER);
+
+ int start, end;
+ io::Tokenizer::Token start_token;
+
+ {
+ LocationRecorder start_location(
+ location, DescriptorProto::ExtensionRange::kStartFieldNumber);
+ start_token = input_->current();
+ DO(ConsumeInteger(&start, "Expected field number range."));
+ }
+
+ if (TryConsume("to")) {
+ LocationRecorder end_location(
+ location, DescriptorProto::ExtensionRange::kEndFieldNumber);
+ if (TryConsume("max")) {
+ // Set to the sentinel value - 1 since we increment the value below.
+ // The actual value of the end of the range should be set with
+ // AdjustExtensionRangesWithMaxEndNumber.
+ end = kMaxRangeSentinel - 1;
+ } else {
+ DO(ConsumeInteger(&end, "Expected integer."));
+ }
+ } else {
+ LocationRecorder end_location(
+ location, DescriptorProto::ExtensionRange::kEndFieldNumber);
+ end_location.StartAt(start_token);
+ end_location.EndAt(start_token);
+ end = start;
+ }
+
+ // Users like to specify inclusive ranges, but in code we like the end
+ // number to be exclusive.
+ ++end;
+
+ range->set_start(start);
+ range->set_end(end);
+ } while (TryConsume(","));
+
+ if (LookingAt("[")) {
+ int range_number_index = extensions_location.CurrentPathSize();
+ SourceCodeInfo info;
+
+ // Parse extension range options in the first range.
+ ExtensionRangeOptions* options =
+ message->mutable_extension_range(old_range_size)->mutable_options();
+
+ {
+ LocationRecorder index_location(
+ extensions_location, 0 /* we fill this in w/ actual index below */,
+ &info);
+ LocationRecorder location(
+ index_location, DescriptorProto::ExtensionRange::kOptionsFieldNumber);
+ DO(Consume("["));
+
+ do {
+ DO(ParseOption(options, location, containing_file, OPTION_ASSIGNMENT));
+ } while (TryConsume(","));
+
+ DO(Consume("]"));
+ }
+
+ // Then copy the extension range options to all of the other ranges we've
+ // parsed.
+ for (int i = old_range_size + 1; i < message->extension_range_size(); i++) {
+ message->mutable_extension_range(i)->mutable_options()->CopyFrom(
+ *options);
+ }
+ // and copy source locations to the other ranges, too
+ for (int i = old_range_size; i < message->extension_range_size(); i++) {
+ for (int j = 0; j < info.location_size(); j++) {
+ if (info.location(j).path_size() == range_number_index + 1) {
+ // this location's path is up to the extension range index, but
+ // doesn't include options; so it's redundant with location above
+ continue;
+ }
+ SourceCodeInfo_Location* dest = source_code_info_->add_location();
+ *dest = info.location(j);
+ dest->set_path(range_number_index, i);
+ }
+ }
+ }
+
+ DO(ConsumeEndOfDeclaration(";", &extensions_location));
+ return true;
+}
+
+// This is similar to extension range parsing, except that it accepts field
+// name literals.
+bool Parser::ParseReserved(DescriptorProto* message,
+ const LocationRecorder& message_location) {
+ io::Tokenizer::Token start_token = input_->current();
+ // Parse the declaration.
+ DO(Consume("reserved"));
+ if (LookingAtType(io::Tokenizer::TYPE_STRING)) {
+ LocationRecorder location(message_location,
+ DescriptorProto::kReservedNameFieldNumber);
+ location.StartAt(start_token);
+ return ParseReservedNames(message, location);
+ } else {
+ LocationRecorder location(message_location,
+ DescriptorProto::kReservedRangeFieldNumber);
+ location.StartAt(start_token);
+ return ParseReservedNumbers(message, location);
+ }
+}
+
+bool Parser::ParseReservedNames(DescriptorProto* message,
+ const LocationRecorder& parent_location) {
+ do {
+ LocationRecorder location(parent_location, message->reserved_name_size());
+ DO(ConsumeString(message->add_reserved_name(), "Expected field name."));
+ } while (TryConsume(","));
+ DO(ConsumeEndOfDeclaration(";", &parent_location));
+ return true;
+}
+
+bool Parser::ParseReservedNumbers(DescriptorProto* message,
+ const LocationRecorder& parent_location) {
+ bool first = true;
+ do {
+ LocationRecorder location(parent_location, message->reserved_range_size());
+
+ DescriptorProto::ReservedRange* range = message->add_reserved_range();
+ int start, end;
+ io::Tokenizer::Token start_token;
+ {
+ LocationRecorder start_location(
+ location, DescriptorProto::ReservedRange::kStartFieldNumber);
+ start_token = input_->current();
+ DO(ConsumeInteger(&start, (first ? "Expected field name or number range."
+ : "Expected field number range.")));
+ }
+
+ if (TryConsume("to")) {
+ LocationRecorder end_location(
+ location, DescriptorProto::ReservedRange::kEndFieldNumber);
+ if (TryConsume("max")) {
+ // Set to the sentinel value - 1 since we increment the value below.
+ // The actual value of the end of the range should be set with
+ // AdjustExtensionRangesWithMaxEndNumber.
+ end = kMaxRangeSentinel - 1;
+ } else {
+ DO(ConsumeInteger(&end, "Expected integer."));
+ }
+ } else {
+ LocationRecorder end_location(
+ location, DescriptorProto::ReservedRange::kEndFieldNumber);
+ end_location.StartAt(start_token);
+ end_location.EndAt(start_token);
+ end = start;
+ }
+
+ // Users like to specify inclusive ranges, but in code we like the end
+ // number to be exclusive.
+ ++end;
+
+ range->set_start(start);
+ range->set_end(end);
+ first = false;
+ } while (TryConsume(","));
+
+ DO(ConsumeEndOfDeclaration(";", &parent_location));
+ return true;
+}
+
+bool Parser::ParseReserved(EnumDescriptorProto* message,
+ const LocationRecorder& message_location) {
+ io::Tokenizer::Token start_token = input_->current();
+ // Parse the declaration.
+ DO(Consume("reserved"));
+ if (LookingAtType(io::Tokenizer::TYPE_STRING)) {
+ LocationRecorder location(message_location,
+ EnumDescriptorProto::kReservedNameFieldNumber);
+ location.StartAt(start_token);
+ return ParseReservedNames(message, location);
+ } else {
+ LocationRecorder location(message_location,
+ EnumDescriptorProto::kReservedRangeFieldNumber);
+ location.StartAt(start_token);
+ return ParseReservedNumbers(message, location);
+ }
+}
+
+bool Parser::ParseReservedNames(EnumDescriptorProto* message,
+ const LocationRecorder& parent_location) {
+ do {
+ LocationRecorder location(parent_location, message->reserved_name_size());
+ DO(ConsumeString(message->add_reserved_name(), "Expected enum value."));
+ } while (TryConsume(","));
+ DO(ConsumeEndOfDeclaration(";", &parent_location));
+ return true;
+}
+
+bool Parser::ParseReservedNumbers(EnumDescriptorProto* message,
+ const LocationRecorder& parent_location) {
+ bool first = true;
+ do {
+ LocationRecorder location(parent_location, message->reserved_range_size());
+
+ EnumDescriptorProto::EnumReservedRange* range =
+ message->add_reserved_range();
+ int start, end;
+ io::Tokenizer::Token start_token;
+ {
+ LocationRecorder start_location(
+ location, EnumDescriptorProto::EnumReservedRange::kStartFieldNumber);
+ start_token = input_->current();
+ DO(ConsumeSignedInteger(&start,
+ (first ? "Expected enum value or number range."
+ : "Expected enum number range.")));
+ }
+
+ if (TryConsume("to")) {
+ LocationRecorder end_location(
+ location, EnumDescriptorProto::EnumReservedRange::kEndFieldNumber);
+ if (TryConsume("max")) {
+ // This is in the enum descriptor path, which doesn't have the message
+ // set duality to fix up, so it doesn't integrate with the sentinel.
+ end = INT_MAX;
+ } else {
+ DO(ConsumeSignedInteger(&end, "Expected integer."));
+ }
+ } else {
+ LocationRecorder end_location(
+ location, EnumDescriptorProto::EnumReservedRange::kEndFieldNumber);
+ end_location.StartAt(start_token);
+ end_location.EndAt(start_token);
+ end = start;
+ }
+
+ range->set_start(start);
+ range->set_end(end);
+ first = false;
+ } while (TryConsume(","));
+
+ DO(ConsumeEndOfDeclaration(";", &parent_location));
+ return true;
+}
+
+bool Parser::ParseExtend(RepeatedPtrField<FieldDescriptorProto>* extensions,
+ RepeatedPtrField<DescriptorProto>* messages,
+ const LocationRecorder& parent_location,
+ int location_field_number_for_nested_type,
+ const LocationRecorder& extend_location,
+ const FileDescriptorProto* containing_file) {
+ DO(Consume("extend"));
+
+ // Parse the extendee type.
+ io::Tokenizer::Token extendee_start = input_->current();
+ std::string extendee;
+ DO(ParseUserDefinedType(&extendee));
+ io::Tokenizer::Token extendee_end = input_->previous();
+
+ // Parse the block.
+ DO(ConsumeEndOfDeclaration("{", &extend_location));
+
+ bool is_first = true;
+
+ do {
+ if (AtEnd()) {
+ AddError("Reached end of input in extend definition (missing '}').");
+ return false;
+ }
+
+ // Note that kExtensionFieldNumber was already pushed by the parent.
+ LocationRecorder location(extend_location, extensions->size());
+
+ FieldDescriptorProto* field = extensions->Add();
+
+ {
+ LocationRecorder extendee_location(
+ location, FieldDescriptorProto::kExtendeeFieldNumber);
+ extendee_location.StartAt(extendee_start);
+ extendee_location.EndAt(extendee_end);
+
+ if (is_first) {
+ extendee_location.RecordLegacyLocation(
+ field, DescriptorPool::ErrorCollector::EXTENDEE);
+ is_first = false;
+ }
+ }
+
+ field->set_extendee(extendee);
+
+ if (!ParseMessageField(field, messages, parent_location,
+ location_field_number_for_nested_type, location,
+ containing_file)) {
+ // This statement failed to parse. Skip it, but keep looping to parse
+ // other statements.
+ SkipStatement();
+ }
+ } while (!TryConsumeEndOfDeclaration("}", NULL));
+
+ return true;
+}
+
+bool Parser::ParseOneof(OneofDescriptorProto* oneof_decl,
+ DescriptorProto* containing_type, int oneof_index,
+ const LocationRecorder& oneof_location,
+ const LocationRecorder& containing_type_location,
+ const FileDescriptorProto* containing_file) {
+ DO(Consume("oneof"));
+
+ {
+ LocationRecorder name_location(oneof_location,
+ OneofDescriptorProto::kNameFieldNumber);
+ DO(ConsumeIdentifier(oneof_decl->mutable_name(), "Expected oneof name."));
+ }
+
+ DO(ConsumeEndOfDeclaration("{", &oneof_location));
+
+ do {
+ if (AtEnd()) {
+ AddError("Reached end of input in oneof definition (missing '}').");
+ return false;
+ }
+
+ if (LookingAt("option")) {
+ LocationRecorder option_location(
+ oneof_location, OneofDescriptorProto::kOptionsFieldNumber);
+ if (!ParseOption(oneof_decl->mutable_options(), option_location,
+ containing_file, OPTION_STATEMENT)) {
+ return false;
+ }
+ continue;
+ }
+
+ // Print a nice error if the user accidentally tries to place a label
+ // on an individual member of a oneof.
+ if (LookingAt("required") || LookingAt("optional") ||
+ LookingAt("repeated")) {
+ AddError(
+ "Fields in oneofs must not have labels (required / optional "
+ "/ repeated).");
+ // We can continue parsing here because we understand what the user
+ // meant. The error report will still make parsing fail overall.
+ input_->Next();
+ }
+
+ LocationRecorder field_location(containing_type_location,
+ DescriptorProto::kFieldFieldNumber,
+ containing_type->field_size());
+
+ FieldDescriptorProto* field = containing_type->add_field();
+ field->set_label(FieldDescriptorProto::LABEL_OPTIONAL);
+ field->set_oneof_index(oneof_index);
+
+ if (!ParseMessageFieldNoLabel(field, containing_type->mutable_nested_type(),
+ containing_type_location,
+ DescriptorProto::kNestedTypeFieldNumber,
+ field_location, containing_file)) {
+ // This statement failed to parse. Skip it, but keep looping to parse
+ // other statements.
+ SkipStatement();
+ }
+ } while (!TryConsumeEndOfDeclaration("}", NULL));
+
+ return true;
+}
+
+// -------------------------------------------------------------------
+// Enums
+
+bool Parser::ParseEnumDefinition(EnumDescriptorProto* enum_type,
+ const LocationRecorder& enum_location,
+ const FileDescriptorProto* containing_file) {
+ DO(Consume("enum"));
+
+ {
+ LocationRecorder location(enum_location,
+ EnumDescriptorProto::kNameFieldNumber);
+ location.RecordLegacyLocation(enum_type,
+ DescriptorPool::ErrorCollector::NAME);
+ DO(ConsumeIdentifier(enum_type->mutable_name(), "Expected enum name."));
+ }
+
+ DO(ParseEnumBlock(enum_type, enum_location, containing_file));
+
+ DO(ValidateEnum(enum_type));
+
+ return true;
+}
+
+bool Parser::ParseEnumBlock(EnumDescriptorProto* enum_type,
+ const LocationRecorder& enum_location,
+ const FileDescriptorProto* containing_file) {
+ DO(ConsumeEndOfDeclaration("{", &enum_location));
+
+ while (!TryConsumeEndOfDeclaration("}", NULL)) {
+ if (AtEnd()) {
+ AddError("Reached end of input in enum definition (missing '}').");
+ return false;
+ }
+
+ if (!ParseEnumStatement(enum_type, enum_location, containing_file)) {
+ // This statement failed to parse. Skip it, but keep looping to parse
+ // other statements.
+ SkipStatement();
+ }
+ }
+
+ return true;
+}
+
+bool Parser::ParseEnumStatement(EnumDescriptorProto* enum_type,
+ const LocationRecorder& enum_location,
+ const FileDescriptorProto* containing_file) {
+ if (TryConsumeEndOfDeclaration(";", NULL)) {
+ // empty statement; ignore
+ return true;
+ } else if (LookingAt("option")) {
+ LocationRecorder location(enum_location,
+ EnumDescriptorProto::kOptionsFieldNumber);
+ return ParseOption(enum_type->mutable_options(), location, containing_file,
+ OPTION_STATEMENT);
+ } else if (LookingAt("reserved")) {
+ return ParseReserved(enum_type, enum_location);
+ } else {
+ LocationRecorder location(enum_location,
+ EnumDescriptorProto::kValueFieldNumber,
+ enum_type->value_size());
+ return ParseEnumConstant(enum_type->add_value(), location, containing_file);
+ }
+}
+
+bool Parser::ParseEnumConstant(EnumValueDescriptorProto* enum_value,
+ const LocationRecorder& enum_value_location,
+ const FileDescriptorProto* containing_file) {
+ // Parse name.
+ {
+ LocationRecorder location(enum_value_location,
+ EnumValueDescriptorProto::kNameFieldNumber);
+ location.RecordLegacyLocation(enum_value,
+ DescriptorPool::ErrorCollector::NAME);
+ DO(ConsumeIdentifier(enum_value->mutable_name(),
+ "Expected enum constant name."));
+ }
+
+ DO(Consume("=", "Missing numeric value for enum constant."));
+
+ // Parse value.
+ {
+ LocationRecorder location(enum_value_location,
+ EnumValueDescriptorProto::kNumberFieldNumber);
+ location.RecordLegacyLocation(enum_value,
+ DescriptorPool::ErrorCollector::NUMBER);
+
+ int number;
+ DO(ConsumeSignedInteger(&number, "Expected integer."));
+ enum_value->set_number(number);
+ }
+
+ DO(ParseEnumConstantOptions(enum_value, enum_value_location,
+ containing_file));
+
+ DO(ConsumeEndOfDeclaration(";", &enum_value_location));
+
+ return true;
+}
+
+bool Parser::ParseEnumConstantOptions(
+ EnumValueDescriptorProto* value,
+ const LocationRecorder& enum_value_location,
+ const FileDescriptorProto* containing_file) {
+ if (!LookingAt("[")) return true;
+
+ LocationRecorder location(enum_value_location,
+ EnumValueDescriptorProto::kOptionsFieldNumber);
+
+ DO(Consume("["));
+
+ do {
+ DO(ParseOption(value->mutable_options(), location, containing_file,
+ OPTION_ASSIGNMENT));
+ } while (TryConsume(","));
+
+ DO(Consume("]"));
+ return true;
+}
+
+// -------------------------------------------------------------------
+// Services
+
+bool Parser::ParseServiceDefinition(
+ ServiceDescriptorProto* service, const LocationRecorder& service_location,
+ const FileDescriptorProto* containing_file) {
+ DO(Consume("service"));
+
+ {
+ LocationRecorder location(service_location,
+ ServiceDescriptorProto::kNameFieldNumber);
+ location.RecordLegacyLocation(service,
+ DescriptorPool::ErrorCollector::NAME);
+ DO(ConsumeIdentifier(service->mutable_name(), "Expected service name."));
+ }
+
+ DO(ParseServiceBlock(service, service_location, containing_file));
+ return true;
+}
+
+bool Parser::ParseServiceBlock(ServiceDescriptorProto* service,
+ const LocationRecorder& service_location,
+ const FileDescriptorProto* containing_file) {
+ DO(ConsumeEndOfDeclaration("{", &service_location));
+
+ while (!TryConsumeEndOfDeclaration("}", NULL)) {
+ if (AtEnd()) {
+ AddError("Reached end of input in service definition (missing '}').");
+ return false;
+ }
+
+ if (!ParseServiceStatement(service, service_location, containing_file)) {
+ // This statement failed to parse. Skip it, but keep looping to parse
+ // other statements.
+ SkipStatement();
+ }
+ }
+
+ return true;
+}
+
+bool Parser::ParseServiceStatement(ServiceDescriptorProto* service,
+ const LocationRecorder& service_location,
+ const FileDescriptorProto* containing_file) {
+ if (TryConsumeEndOfDeclaration(";", NULL)) {
+ // empty statement; ignore
+ return true;
+ } else if (LookingAt("option")) {
+ LocationRecorder location(service_location,
+ ServiceDescriptorProto::kOptionsFieldNumber);
+ return ParseOption(service->mutable_options(), location, containing_file,
+ OPTION_STATEMENT);
+ } else {
+ LocationRecorder location(service_location,
+ ServiceDescriptorProto::kMethodFieldNumber,
+ service->method_size());
+ return ParseServiceMethod(service->add_method(), location, containing_file);
+ }
+}
+
+bool Parser::ParseServiceMethod(MethodDescriptorProto* method,
+ const LocationRecorder& method_location,
+ const FileDescriptorProto* containing_file) {
+ DO(Consume("rpc"));
+
+ {
+ LocationRecorder location(method_location,
+ MethodDescriptorProto::kNameFieldNumber);
+ location.RecordLegacyLocation(method, DescriptorPool::ErrorCollector::NAME);
+ DO(ConsumeIdentifier(method->mutable_name(), "Expected method name."));
+ }
+
+ // Parse input type.
+ DO(Consume("("));
+ {
+ if (LookingAt("stream")) {
+ LocationRecorder location(
+ method_location, MethodDescriptorProto::kClientStreamingFieldNumber);
+ location.RecordLegacyLocation(method,
+ DescriptorPool::ErrorCollector::OTHER);
+ method->set_client_streaming(true);
+ DO(Consume("stream"));
+
+ }
+ LocationRecorder location(method_location,
+ MethodDescriptorProto::kInputTypeFieldNumber);
+ location.RecordLegacyLocation(method,
+ DescriptorPool::ErrorCollector::INPUT_TYPE);
+ DO(ParseUserDefinedType(method->mutable_input_type()));
+ }
+ DO(Consume(")"));
+
+ // Parse output type.
+ DO(Consume("returns"));
+ DO(Consume("("));
+ {
+ if (LookingAt("stream")) {
+ LocationRecorder location(
+ method_location, MethodDescriptorProto::kServerStreamingFieldNumber);
+ location.RecordLegacyLocation(method,
+ DescriptorPool::ErrorCollector::OTHER);
+ DO(Consume("stream"));
+ method->set_server_streaming(true);
+
+ }
+ LocationRecorder location(method_location,
+ MethodDescriptorProto::kOutputTypeFieldNumber);
+ location.RecordLegacyLocation(method,
+ DescriptorPool::ErrorCollector::OUTPUT_TYPE);
+ DO(ParseUserDefinedType(method->mutable_output_type()));
+ }
+ DO(Consume(")"));
+
+ if (LookingAt("{")) {
+ // Options!
+ DO(ParseMethodOptions(method_location, containing_file,
+ MethodDescriptorProto::kOptionsFieldNumber,
+ method->mutable_options()));
+ } else {
+ DO(ConsumeEndOfDeclaration(";", &method_location));
+ }
+
+ return true;
+}
+
+bool Parser::ParseMethodOptions(const LocationRecorder& parent_location,
+ const FileDescriptorProto* containing_file,
+ const int optionsFieldNumber,
+ Message* mutable_options) {
+ // Options!
+ ConsumeEndOfDeclaration("{", &parent_location);
+ while (!TryConsumeEndOfDeclaration("}", NULL)) {
+ if (AtEnd()) {
+ AddError("Reached end of input in method options (missing '}').");
+ return false;
+ }
+
+ if (TryConsumeEndOfDeclaration(";", NULL)) {
+ // empty statement; ignore
+ } else {
+ LocationRecorder location(parent_location, optionsFieldNumber);
+ if (!ParseOption(mutable_options, location, containing_file,
+ OPTION_STATEMENT)) {
+ // This statement failed to parse. Skip it, but keep looping to
+ // parse other statements.
+ SkipStatement();
+ }
+ }
+ }
+
+ return true;
+}
+
+// -------------------------------------------------------------------
+
+bool Parser::ParseLabel(FieldDescriptorProto::Label* label,
+ const LocationRecorder& field_location,
+ const FileDescriptorProto* containing_file) {
+ if (!LookingAt("optional") && !LookingAt("repeated") &&
+ !LookingAt("required")) {
+ return false;
+ }
+ LocationRecorder location(field_location,
+ FieldDescriptorProto::kLabelFieldNumber);
+ if (TryConsume("optional")) {
+ *label = FieldDescriptorProto::LABEL_OPTIONAL;
+ } else if (TryConsume("repeated")) {
+ *label = FieldDescriptorProto::LABEL_REPEATED;
+ } else {
+ Consume("required");
+ *label = FieldDescriptorProto::LABEL_REQUIRED;
+ }
+ return true;
+}
+
+bool Parser::ParseType(FieldDescriptorProto::Type* type,
+ std::string* type_name) {
+ TypeNameMap::const_iterator iter = kTypeNames.find(input_->current().text);
+ if (iter != kTypeNames.end()) {
+ *type = iter->second;
+ input_->Next();
+ } else {
+ DO(ParseUserDefinedType(type_name));
+ }
+ return true;
+}
+
+bool Parser::ParseUserDefinedType(std::string* type_name) {
+ type_name->clear();
+
+ TypeNameMap::const_iterator iter = kTypeNames.find(input_->current().text);
+ if (iter != kTypeNames.end()) {
+ // Note: The only place enum types are allowed is for field types, but
+ // if we are parsing a field type then we would not get here because
+ // primitives are allowed there as well. So this error message doesn't
+ // need to account for enums.
+ AddError("Expected message type.");
+
+ // Pretend to accept this type so that we can go on parsing.
+ *type_name = input_->current().text;
+ input_->Next();
+ return true;
+ }
+
+ // A leading "." means the name is fully-qualified.
+ if (TryConsume(".")) type_name->append(".");
+
+ // Consume the first part of the name.
+ std::string identifier;
+ DO(ConsumeIdentifier(&identifier, "Expected type name."));
+ type_name->append(identifier);
+
+ // Consume more parts.
+ while (TryConsume(".")) {
+ type_name->append(".");
+ DO(ConsumeIdentifier(&identifier, "Expected identifier."));
+ type_name->append(identifier);
+ }
+
+ return true;
+}
+
+// ===================================================================
+
+bool Parser::ParsePackage(FileDescriptorProto* file,
+ const LocationRecorder& root_location,
+ const FileDescriptorProto* containing_file) {
+ if (file->has_package()) {
+ AddError("Multiple package definitions.");
+ // Don't append the new package to the old one. Just replace it. Not
+ // that it really matters since this is an error anyway.
+ file->clear_package();
+ }
+
+ LocationRecorder location(root_location,
+ FileDescriptorProto::kPackageFieldNumber);
+ location.RecordLegacyLocation(file, DescriptorPool::ErrorCollector::NAME);
+
+ DO(Consume("package"));
+
+ while (true) {
+ std::string identifier;
+ DO(ConsumeIdentifier(&identifier, "Expected identifier."));
+ file->mutable_package()->append(identifier);
+ if (!TryConsume(".")) break;
+ file->mutable_package()->append(".");
+ }
+
+ DO(ConsumeEndOfDeclaration(";", &location));
+
+ return true;
+}
+
+bool Parser::ParseImport(RepeatedPtrField<std::string>* dependency,
+ RepeatedField<int32_t>* public_dependency,
+ RepeatedField<int32_t>* weak_dependency,
+ const LocationRecorder& root_location,
+ const FileDescriptorProto* containing_file) {
+ LocationRecorder location(root_location,
+ FileDescriptorProto::kDependencyFieldNumber,
+ dependency->size());
+
+ DO(Consume("import"));
+
+ if (LookingAt("public")) {
+ LocationRecorder public_location(
+ root_location, FileDescriptorProto::kPublicDependencyFieldNumber,
+ public_dependency->size());
+ DO(Consume("public"));
+ *public_dependency->Add() = dependency->size();
+ } else if (LookingAt("weak")) {
+ LocationRecorder weak_location(
+ root_location, FileDescriptorProto::kWeakDependencyFieldNumber,
+ weak_dependency->size());
+ weak_location.RecordLegacyImportLocation(containing_file, "weak");
+ DO(Consume("weak"));
+ *weak_dependency->Add() = dependency->size();
+ }
+
+ std::string import_file;
+ DO(ConsumeString(&import_file,
+ "Expected a string naming the file to import."));
+ *dependency->Add() = import_file;
+ location.RecordLegacyImportLocation(containing_file, import_file);
+
+ DO(ConsumeEndOfDeclaration(";", &location));
+
+ return true;
+}
+
+// ===================================================================
+
+SourceLocationTable::SourceLocationTable() {}
+SourceLocationTable::~SourceLocationTable() {}
+
+bool SourceLocationTable::Find(
+ const Message* descriptor,
+ DescriptorPool::ErrorCollector::ErrorLocation location, int* line,
+ int* column) const {
+ const std::pair<int, int>* result =
+ FindOrNull(location_map_, std::make_pair(descriptor, location));
+ if (result == NULL) {
+ *line = -1;
+ *column = 0;
+ return false;
+ } else {
+ *line = result->first;
+ *column = result->second;
+ return true;
+ }
+}
+
+bool SourceLocationTable::FindImport(const Message* descriptor,
+ const std::string& name, int* line,
+ int* column) const {
+ const std::pair<int, int>* result =
+ FindOrNull(import_location_map_, std::make_pair(descriptor, name));
+ if (result == nullptr) {
+ *line = -1;
+ *column = 0;
+ return false;
+ } else {
+ *line = result->first;
+ *column = result->second;
+ return true;
+ }
+}
+
+void SourceLocationTable::Add(
+ const Message* descriptor,
+ DescriptorPool::ErrorCollector::ErrorLocation location, int line,
+ int column) {
+ location_map_[std::make_pair(descriptor, location)] =
+ std::make_pair(line, column);
+}
+
+void SourceLocationTable::AddImport(const Message* descriptor,
+ const std::string& name, int line,
+ int column) {
+ import_location_map_[std::make_pair(descriptor, name)] =
+ std::make_pair(line, column);
+}
+
+void SourceLocationTable::Clear() { location_map_.clear(); }
+
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/parser.h b/NorthstarDedicatedTest/include/protobuf/compiler/parser.h
new file mode 100644
index 00000000..37055bd3
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/parser.h
@@ -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.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// Implements parsing of .proto files to FileDescriptorProtos.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_PARSER_H__
+#define GOOGLE_PROTOBUF_COMPILER_PARSER_H__
+
+#include <cstdint>
+#include <map>
+#include <string>
+#include <utility>
+
+#include <descriptor.pb.h>
+#include <io/tokenizer.h>
+#include <descriptor.h>
+#include <repeated_field.h>
+
+// Must be included last.
+#include <port_def.inc>
+
+namespace google {
+namespace protobuf {
+
+class Message;
+
+namespace compiler {
+
+// Defined in this file.
+class Parser;
+class SourceLocationTable;
+
+// Implements parsing of protocol definitions (such as .proto files).
+//
+// Note that most users will be more interested in the Importer class.
+// Parser is a lower-level class which simply converts a single .proto file
+// to a FileDescriptorProto. It does not resolve import directives or perform
+// many other kinds of validation needed to construct a complete
+// FileDescriptor.
+class PROTOBUF_EXPORT Parser {
+ public:
+ Parser();
+ ~Parser();
+
+ // Parse the entire input and construct a FileDescriptorProto representing
+ // it. Returns true if no errors occurred, false otherwise.
+ bool Parse(io::Tokenizer* input, FileDescriptorProto* file);
+
+ // Optional features:
+
+ // DEPRECATED: New code should use the SourceCodeInfo embedded in the
+ // FileDescriptorProto.
+ //
+ // Requests that locations of certain definitions be recorded to the given
+ // SourceLocationTable while parsing. This can be used to look up exact line
+ // and column numbers for errors reported by DescriptorPool during validation.
+ // Set to NULL (the default) to discard source location information.
+ void RecordSourceLocationsTo(SourceLocationTable* location_table) {
+ source_location_table_ = location_table;
+ }
+
+ // Requests that errors be recorded to the given ErrorCollector while
+ // parsing. Set to NULL (the default) to discard error messages.
+ void RecordErrorsTo(io::ErrorCollector* error_collector) {
+ error_collector_ = error_collector;
+ }
+
+ // Returns the identifier used in the "syntax = " declaration, if one was
+ // seen during the last call to Parse(), or the empty string otherwise.
+ const std::string& GetSyntaxIdentifier() { return syntax_identifier_; }
+
+ // If set true, input files will be required to begin with a syntax
+ // identifier. Otherwise, files may omit this. If a syntax identifier
+ // is provided, it must be 'syntax = "proto2";' and must appear at the
+ // top of this file regardless of whether or not it was required.
+ void SetRequireSyntaxIdentifier(bool value) {
+ require_syntax_identifier_ = value;
+ }
+
+ // Call SetStopAfterSyntaxIdentifier(true) to tell the parser to stop
+ // parsing as soon as it has seen the syntax identifier, or lack thereof.
+ // This is useful for quickly identifying the syntax of the file without
+ // parsing the whole thing. If this is enabled, no error will be recorded
+ // if the syntax identifier is something other than "proto2" (since
+ // presumably the caller intends to deal with that), but other kinds of
+ // errors (e.g. parse errors) will still be reported. When this is enabled,
+ // you may pass a NULL FileDescriptorProto to Parse().
+ void SetStopAfterSyntaxIdentifier(bool value) {
+ stop_after_syntax_identifier_ = value;
+ }
+
+ private:
+ class LocationRecorder;
+
+ // =================================================================
+ // Error recovery helpers
+
+ // Consume the rest of the current statement. This consumes tokens
+ // until it sees one of:
+ // ';' Consumes the token and returns.
+ // '{' Consumes the brace then calls SkipRestOfBlock().
+ // '}' Returns without consuming.
+ // EOF Returns (can't consume).
+ // The Parser often calls SkipStatement() after encountering a syntax
+ // error. This allows it to go on parsing the following lines, allowing
+ // it to report more than just one error in the file.
+ void SkipStatement();
+
+ // Consume the rest of the current block, including nested blocks,
+ // ending after the closing '}' is encountered and consumed, or at EOF.
+ void SkipRestOfBlock();
+
+ // -----------------------------------------------------------------
+ // Single-token consuming helpers
+ //
+ // These make parsing code more readable.
+
+ // True if the current token is TYPE_END.
+ inline bool AtEnd();
+
+ // True if the next token matches the given text.
+ inline bool LookingAt(const char* text);
+ // True if the next token is of the given type.
+ inline bool LookingAtType(io::Tokenizer::TokenType token_type);
+
+ // If the next token exactly matches the text given, consume it and return
+ // true. Otherwise, return false without logging an error.
+ bool TryConsume(const char* text);
+
+ // These attempt to read some kind of token from the input. If successful,
+ // they return true. Otherwise they return false and add the given error
+ // to the error list.
+
+ // Consume a token with the exact text given.
+ bool Consume(const char* text, const char* error);
+ // Same as above, but automatically generates the error "Expected \"text\".",
+ // where "text" is the expected token text.
+ bool Consume(const char* text);
+ // Consume a token of type IDENTIFIER and store its text in "output".
+ bool ConsumeIdentifier(std::string* output, const char* error);
+ // Consume an integer and store its value in "output".
+ bool ConsumeInteger(int* output, const char* error);
+ // Consume a signed integer and store its value in "output".
+ bool ConsumeSignedInteger(int* output, const char* error);
+ // Consume a 64-bit integer and store its value in "output". If the value
+ // is greater than max_value, an error will be reported.
+ bool ConsumeInteger64(uint64_t max_value, uint64_t* output,
+ const char* error);
+ // Consume a number and store its value in "output". This will accept
+ // tokens of either INTEGER or FLOAT type.
+ bool ConsumeNumber(double* output, const char* error);
+ // Consume a string literal and store its (unescaped) value in "output".
+ bool ConsumeString(std::string* output, const char* error);
+
+ // Consume a token representing the end of the statement. Comments between
+ // this token and the next will be harvested for documentation. The given
+ // LocationRecorder should refer to the declaration that was just parsed;
+ // it will be populated with these comments.
+ //
+ // TODO(kenton): The LocationRecorder is const because historically locations
+ // have been passed around by const reference, for no particularly good
+ // reason. We should probably go through and change them all to mutable
+ // pointer to make this more intuitive.
+ bool TryConsumeEndOfDeclaration(const char* text,
+ const LocationRecorder* location);
+ bool TryConsumeEndOfDeclarationFinishScope(const char* text,
+ const LocationRecorder* location);
+
+ bool ConsumeEndOfDeclaration(const char* text,
+ const LocationRecorder* location);
+
+ // -----------------------------------------------------------------
+ // Error logging helpers
+
+ // Invokes error_collector_->AddError(), if error_collector_ is not NULL.
+ void AddError(int line, int column, const std::string& error);
+
+ // Invokes error_collector_->AddError() with the line and column number
+ // of the current token.
+ void AddError(const std::string& error);
+
+ // Invokes error_collector_->AddWarning() with the line and column number
+ // of the current token.
+ void AddWarning(const std::string& warning);
+
+ // Records a location in the SourceCodeInfo.location table (see
+ // descriptor.proto). We use RAII to ensure that the start and end locations
+ // are recorded -- the constructor records the start location and the
+ // destructor records the end location. Since the parser is
+ // recursive-descent, this works out beautifully.
+ class PROTOBUF_EXPORT LocationRecorder {
+ public:
+ // Construct the file's "root" location.
+ LocationRecorder(Parser* parser);
+
+ // Construct a location that represents a declaration nested within the
+ // given parent. E.g. a field's location is nested within the location
+ // for a message type. The parent's path will be copied, so you should
+ // call AddPath() only to add the path components leading from the parent
+ // to the child (as opposed to leading from the root to the child).
+ LocationRecorder(const LocationRecorder& parent);
+
+ // Convenience constructors that call AddPath() one or two times.
+ LocationRecorder(const LocationRecorder& parent, int path1);
+ LocationRecorder(const LocationRecorder& parent, int path1, int path2);
+
+ // Creates a recorder that generates locations into given source code info.
+ LocationRecorder(const LocationRecorder& parent, int path1,
+ SourceCodeInfo* source_code_info);
+
+ ~LocationRecorder();
+
+ // Add a path component. See SourceCodeInfo.Location.path in
+ // descriptor.proto.
+ void AddPath(int path_component);
+
+ // By default the location is considered to start at the current token at
+ // the time the LocationRecorder is created. StartAt() sets the start
+ // location to the given token instead.
+ void StartAt(const io::Tokenizer::Token& token);
+
+ // Start at the same location as some other LocationRecorder.
+ void StartAt(const LocationRecorder& other);
+
+ // By default the location is considered to end at the previous token at
+ // the time the LocationRecorder is destroyed. EndAt() sets the end
+ // location to the given token instead.
+ void EndAt(const io::Tokenizer::Token& token);
+
+ // Records the start point of this location to the SourceLocationTable that
+ // was passed to RecordSourceLocationsTo(), if any. SourceLocationTable
+ // is an older way of keeping track of source locations which is still
+ // used in some places.
+ void RecordLegacyLocation(
+ const Message* descriptor,
+ DescriptorPool::ErrorCollector::ErrorLocation location);
+ void RecordLegacyImportLocation(const Message* descriptor,
+ const std::string& name);
+
+ // Returns the number of path components in the recorder's current location.
+ int CurrentPathSize() const;
+
+ // Attaches leading and trailing comments to the location. The two strings
+ // will be swapped into place, so after this is called *leading and
+ // *trailing will be empty.
+ //
+ // TODO(kenton): See comment on TryConsumeEndOfDeclaration(), above, for
+ // why this is const.
+ void AttachComments(std::string* leading, std::string* trailing,
+ std::vector<std::string>* detached_comments) const;
+
+ private:
+ // Indexes of parent and current location in the parent
+ // SourceCodeInfo.location repeated field. For top-level elements,
+ // parent_index_ is -1.
+ Parser* parser_;
+ SourceCodeInfo* source_code_info_;
+ SourceCodeInfo::Location* location_;
+
+ void Init(const LocationRecorder& parent, SourceCodeInfo* source_code_info);
+ };
+
+ // =================================================================
+ // Parsers for various language constructs
+
+ // Parses the "syntax = \"proto2\";" line at the top of the file. Returns
+ // false if it failed to parse or if the syntax identifier was not
+ // recognized.
+ bool ParseSyntaxIdentifier(const LocationRecorder& parent);
+
+ // These methods parse various individual bits of code. They return
+ // false if they completely fail to parse the construct. In this case,
+ // it is probably necessary to skip the rest of the statement to recover.
+ // However, if these methods return true, it does NOT mean that there
+ // were no errors; only that there were no *syntax* errors. For instance,
+ // if a service method is defined using proper syntax but uses a primitive
+ // type as its input or output, ParseMethodField() still returns true
+ // and only reports the error by calling AddError(). In practice, this
+ // makes logic much simpler for the caller.
+
+ // Parse a top-level message, enum, service, etc.
+ bool ParseTopLevelStatement(FileDescriptorProto* file,
+ const LocationRecorder& root_location);
+
+ // Parse various language high-level language construrcts.
+ bool ParseMessageDefinition(DescriptorProto* message,
+ const LocationRecorder& message_location,
+ const FileDescriptorProto* containing_file);
+ bool ParseEnumDefinition(EnumDescriptorProto* enum_type,
+ const LocationRecorder& enum_location,
+ const FileDescriptorProto* containing_file);
+ bool ParseServiceDefinition(ServiceDescriptorProto* service,
+ const LocationRecorder& service_location,
+ const FileDescriptorProto* containing_file);
+ bool ParsePackage(FileDescriptorProto* file,
+ const LocationRecorder& root_location,
+ const FileDescriptorProto* containing_file);
+ bool ParseImport(RepeatedPtrField<std::string>* dependency,
+ RepeatedField<int32_t>* public_dependency,
+ RepeatedField<int32_t>* weak_dependency,
+ const LocationRecorder& root_location,
+ const FileDescriptorProto* containing_file);
+
+ // These methods parse the contents of a message, enum, or service type and
+ // add them to the given object. They consume the entire block including
+ // the beginning and ending brace.
+ bool ParseMessageBlock(DescriptorProto* message,
+ const LocationRecorder& message_location,
+ const FileDescriptorProto* containing_file);
+ bool ParseEnumBlock(EnumDescriptorProto* enum_type,
+ const LocationRecorder& enum_location,
+ const FileDescriptorProto* containing_file);
+ bool ParseServiceBlock(ServiceDescriptorProto* service,
+ const LocationRecorder& service_location,
+ const FileDescriptorProto* containing_file);
+
+ // Parse one statement within a message, enum, or service block, including
+ // final semicolon.
+ bool ParseMessageStatement(DescriptorProto* message,
+ const LocationRecorder& message_location,
+ const FileDescriptorProto* containing_file);
+ bool ParseEnumStatement(EnumDescriptorProto* message,
+ const LocationRecorder& enum_location,
+ const FileDescriptorProto* containing_file);
+ bool ParseServiceStatement(ServiceDescriptorProto* message,
+ const LocationRecorder& service_location,
+ const FileDescriptorProto* containing_file);
+
+ // Parse a field of a message. If the field is a group, its type will be
+ // added to "messages".
+ //
+ // parent_location and location_field_number_for_nested_type are needed when
+ // parsing groups -- we need to generate a nested message type within the
+ // parent and record its location accordingly. Since the parent could be
+ // either a FileDescriptorProto or a DescriptorProto, we must pass in the
+ // correct field number to use.
+ bool ParseMessageField(FieldDescriptorProto* field,
+ RepeatedPtrField<DescriptorProto>* messages,
+ const LocationRecorder& parent_location,
+ int location_field_number_for_nested_type,
+ const LocationRecorder& field_location,
+ const FileDescriptorProto* containing_file);
+
+ // Like ParseMessageField() but expects the label has already been filled in
+ // by the caller.
+ bool ParseMessageFieldNoLabel(FieldDescriptorProto* field,
+ RepeatedPtrField<DescriptorProto>* messages,
+ const LocationRecorder& parent_location,
+ int location_field_number_for_nested_type,
+ const LocationRecorder& field_location,
+ const FileDescriptorProto* containing_file);
+
+ // Parse an "extensions" declaration.
+ bool ParseExtensions(DescriptorProto* message,
+ const LocationRecorder& extensions_location,
+ const FileDescriptorProto* containing_file);
+
+ // Parse a "reserved" declaration.
+ bool ParseReserved(DescriptorProto* message,
+ const LocationRecorder& message_location);
+ bool ParseReservedNames(DescriptorProto* message,
+ const LocationRecorder& parent_location);
+ bool ParseReservedNumbers(DescriptorProto* message,
+ const LocationRecorder& parent_location);
+ bool ParseReserved(EnumDescriptorProto* message,
+ const LocationRecorder& message_location);
+ bool ParseReservedNames(EnumDescriptorProto* message,
+ const LocationRecorder& parent_location);
+ bool ParseReservedNumbers(EnumDescriptorProto* message,
+ const LocationRecorder& parent_location);
+
+ // Parse an "extend" declaration. (See also comments for
+ // ParseMessageField().)
+ bool ParseExtend(RepeatedPtrField<FieldDescriptorProto>* extensions,
+ RepeatedPtrField<DescriptorProto>* messages,
+ const LocationRecorder& parent_location,
+ int location_field_number_for_nested_type,
+ const LocationRecorder& extend_location,
+ const FileDescriptorProto* containing_file);
+
+ // Parse a "oneof" declaration. The caller is responsible for setting
+ // oneof_decl->label() since it will have had to parse the label before it
+ // knew it was parsing a oneof.
+ bool ParseOneof(OneofDescriptorProto* oneof_decl,
+ DescriptorProto* containing_type, int oneof_index,
+ const LocationRecorder& oneof_location,
+ const LocationRecorder& containing_type_location,
+ const FileDescriptorProto* containing_file);
+
+ // Parse a single enum value within an enum block.
+ bool ParseEnumConstant(EnumValueDescriptorProto* enum_value,
+ const LocationRecorder& enum_value_location,
+ const FileDescriptorProto* containing_file);
+
+ // Parse enum constant options, i.e. the list in square brackets at the end
+ // of the enum constant value definition.
+ bool ParseEnumConstantOptions(EnumValueDescriptorProto* value,
+ const LocationRecorder& enum_value_location,
+ const FileDescriptorProto* containing_file);
+
+ // Parse a single method within a service definition.
+ bool ParseServiceMethod(MethodDescriptorProto* method,
+ const LocationRecorder& method_location,
+ const FileDescriptorProto* containing_file);
+
+
+ // Parse options of a single method or stream.
+ bool ParseMethodOptions(const LocationRecorder& parent_location,
+ const FileDescriptorProto* containing_file,
+ const int optionsFieldNumber,
+ Message* mutable_options);
+
+ // Parse "required", "optional", or "repeated" and fill in "label"
+ // with the value. Returns true if such a label is consumed.
+ bool ParseLabel(FieldDescriptorProto::Label* label,
+ const LocationRecorder& field_location,
+ const FileDescriptorProto* containing_file);
+
+ // Parse a type name and fill in "type" (if it is a primitive) or
+ // "type_name" (if it is not) with the type parsed.
+ bool ParseType(FieldDescriptorProto::Type* type, std::string* type_name);
+ // Parse a user-defined type and fill in "type_name" with the name.
+ // If a primitive type is named, it is treated as an error.
+ bool ParseUserDefinedType(std::string* type_name);
+
+ // Parses field options, i.e. the stuff in square brackets at the end
+ // of a field definition. Also parses default value.
+ bool ParseFieldOptions(FieldDescriptorProto* field,
+ const LocationRecorder& field_location,
+ const FileDescriptorProto* containing_file);
+
+ // Parse the "default" option. This needs special handling because its
+ // type is the field's type.
+ bool ParseDefaultAssignment(FieldDescriptorProto* field,
+ const LocationRecorder& field_location,
+ const FileDescriptorProto* containing_file);
+
+ bool ParseJsonName(FieldDescriptorProto* field,
+ const LocationRecorder& field_location,
+ const FileDescriptorProto* containing_file);
+
+ enum OptionStyle {
+ OPTION_ASSIGNMENT, // just "name = value"
+ OPTION_STATEMENT // "option name = value;"
+ };
+
+ // Parse a single option name/value pair, e.g. "ctype = CORD". The name
+ // identifies a field of the given Message, and the value of that field
+ // is set to the parsed value.
+ bool ParseOption(Message* options, const LocationRecorder& options_location,
+ const FileDescriptorProto* containing_file,
+ OptionStyle style);
+
+ // Parses a single part of a multipart option name. A multipart name consists
+ // of names separated by dots. Each name is either an identifier or a series
+ // of identifiers separated by dots and enclosed in parentheses. E.g.,
+ // "foo.(bar.baz).qux".
+ bool ParseOptionNamePart(UninterpretedOption* uninterpreted_option,
+ const LocationRecorder& part_location,
+ const FileDescriptorProto* containing_file);
+
+ // Parses a string surrounded by balanced braces. Strips off the outer
+ // braces and stores the enclosed string in *value.
+ // E.g.,
+ // { foo } *value gets 'foo'
+ // { foo { bar: box } } *value gets 'foo { bar: box }'
+ // {} *value gets ''
+ //
+ // REQUIRES: LookingAt("{")
+ // When finished successfully, we are looking at the first token past
+ // the ending brace.
+ bool ParseUninterpretedBlock(std::string* value);
+
+ struct MapField {
+ // Whether the field is a map field.
+ bool is_map_field;
+ // The types of the key and value if they are primitive types.
+ FieldDescriptorProto::Type key_type;
+ FieldDescriptorProto::Type value_type;
+ // Or the type names string if the types are customized types.
+ std::string key_type_name;
+ std::string value_type_name;
+
+ MapField() : is_map_field(false) {}
+ };
+ // Desugar the map syntax to generate a nested map entry message.
+ void GenerateMapEntry(const MapField& map_field, FieldDescriptorProto* field,
+ RepeatedPtrField<DescriptorProto>* messages);
+
+ // Whether fields without label default to optional fields.
+ bool DefaultToOptionalFields() const {
+ return syntax_identifier_ == "proto3";
+ }
+
+ bool ValidateEnum(const EnumDescriptorProto* proto);
+
+ // =================================================================
+
+ io::Tokenizer* input_;
+ io::ErrorCollector* error_collector_;
+ SourceCodeInfo* source_code_info_;
+ SourceLocationTable* source_location_table_; // legacy
+ bool had_errors_;
+ bool require_syntax_identifier_;
+ bool stop_after_syntax_identifier_;
+ std::string syntax_identifier_;
+
+ // Leading doc comments for the next declaration. These are not complete
+ // yet; use ConsumeEndOfDeclaration() to get the complete comments.
+ std::string upcoming_doc_comments_;
+
+ // Detached comments are not connected to any syntax entities. Elements in
+ // this vector are paragraphs of comments separated by empty lines. The
+ // detached comments will be put into the leading_detached_comments field for
+ // the next element (See SourceCodeInfo.Location in descriptor.proto), when
+ // ConsumeEndOfDeclaration() is called.
+ std::vector<std::string> upcoming_detached_comments_;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Parser);
+};
+
+// A table mapping (descriptor, ErrorLocation) pairs -- as reported by
+// DescriptorPool when validating descriptors -- to line and column numbers
+// within the original source code.
+//
+// This is semi-obsolete: FileDescriptorProto.source_code_info now contains
+// far more complete information about source locations. However, as of this
+// writing you still need to use SourceLocationTable when integrating with
+// DescriptorPool.
+class PROTOBUF_EXPORT SourceLocationTable {
+ public:
+ SourceLocationTable();
+ ~SourceLocationTable();
+
+ // Finds the precise location of the given error and fills in *line and
+ // *column with the line and column numbers. If not found, sets *line to
+ // -1 and *column to 0 (since line = -1 is used to mean "error has no exact
+ // location" in the ErrorCollector interface). Returns true if found, false
+ // otherwise.
+ bool Find(const Message* descriptor,
+ DescriptorPool::ErrorCollector::ErrorLocation location, int* line,
+ int* column) const;
+ bool FindImport(const Message* descriptor, const std::string& name, int* line,
+ int* column) const;
+
+ // Adds a location to the table.
+ void Add(const Message* descriptor,
+ DescriptorPool::ErrorCollector::ErrorLocation location, int line,
+ int column);
+ void AddImport(const Message* descriptor, const std::string& name, int line,
+ int column);
+
+ // Clears the contents of the table.
+ void Clear();
+
+ private:
+ typedef std::map<
+ std::pair<const Message*, DescriptorPool::ErrorCollector::ErrorLocation>,
+ std::pair<int, int> >
+ LocationMap;
+ LocationMap location_map_;
+ std::map<std::pair<const Message*, std::string>, std::pair<int, int> >
+ import_location_map_;
+};
+
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#include <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_COMPILER_PARSER_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/parser_unittest.cc b/NorthstarDedicatedTest/include/protobuf/compiler/parser_unittest.cc
new file mode 100644
index 00000000..0b175117
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/parser_unittest.cc
@@ -0,0 +1,3681 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 <compiler/parser.h>
+
+#include <algorithm>
+#include <map>
+#include <memory>
+#include <vector>
+
+#include <test_util2.h>
+#include <unittest.pb.h>
+#include <any.pb.h>
+#include <unittest_custom_options.pb.h>
+#include <io/tokenizer.h>
+#include <io/zero_copy_stream_impl.h>
+#include <descriptor.pb.h>
+#include <text_format.h>
+#include <wire_format.h>
+#include <testing/googletest.h>
+#include <gtest/gtest.h>
+#include <stubs/substitute.h>
+#include <stubs/map_util.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+
+namespace {
+
+class MockErrorCollector : public io::ErrorCollector {
+ public:
+ MockErrorCollector() = default;
+ ~MockErrorCollector() override = default;
+
+ std::string warning_;
+ std::string text_;
+
+ // implements ErrorCollector ---------------------------------------
+ void AddWarning(int line, int column, const std::string& message) override {
+ strings::SubstituteAndAppend(&warning_, "$0:$1: $2\n", line, column, message);
+ }
+
+ void AddError(int line, int column, const std::string& message) override {
+ strings::SubstituteAndAppend(&text_, "$0:$1: $2\n", line, column, message);
+ }
+};
+
+class MockValidationErrorCollector : public DescriptorPool::ErrorCollector {
+ public:
+ MockValidationErrorCollector(const SourceLocationTable& source_locations,
+ io::ErrorCollector* wrapped_collector)
+ : source_locations_(source_locations),
+ wrapped_collector_(wrapped_collector) {}
+ ~MockValidationErrorCollector() {}
+
+ // implements ErrorCollector ---------------------------------------
+ void AddError(const std::string& filename, const std::string& element_name,
+ const Message* descriptor, ErrorLocation location,
+ const std::string& message) override {
+ int line, column;
+ if (location == DescriptorPool::ErrorCollector::IMPORT) {
+ source_locations_.FindImport(descriptor, element_name, &line, &column);
+ } else {
+ source_locations_.Find(descriptor, location, &line, &column);
+ }
+ wrapped_collector_->AddError(line, column, message);
+ }
+
+ private:
+ const SourceLocationTable& source_locations_;
+ io::ErrorCollector* wrapped_collector_;
+};
+
+class ParserTest : public testing::Test {
+ protected:
+ ParserTest() : require_syntax_identifier_(false) {}
+
+ // Set up the parser to parse the given text.
+ void SetupParser(const char* text) {
+ raw_input_.reset(new io::ArrayInputStream(text, strlen(text)));
+ input_.reset(new io::Tokenizer(raw_input_.get(), &error_collector_));
+ parser_.reset(new Parser());
+ parser_->RecordErrorsTo(&error_collector_);
+ parser_->SetRequireSyntaxIdentifier(require_syntax_identifier_);
+ }
+
+ // Parse the input and expect that the resulting FileDescriptorProto matches
+ // the given output. The output is a FileDescriptorProto in protocol buffer
+ // text format.
+ void ExpectParsesTo(const char* input, const char* output) {
+ SetupParser(input);
+ FileDescriptorProto actual, expected;
+
+ parser_->Parse(input_.get(), &actual);
+ EXPECT_EQ(io::Tokenizer::TYPE_END, input_->current().type);
+ ASSERT_EQ("", error_collector_.text_);
+
+ // We don't cover SourceCodeInfo in these tests.
+ actual.clear_source_code_info();
+
+ // Parse the ASCII representation in order to canonicalize it. We could
+ // just compare directly to actual.DebugString(), but that would require
+ // that the caller precisely match the formatting that DebugString()
+ // produces.
+ ASSERT_TRUE(TextFormat::ParseFromString(output, &expected));
+
+ // Compare by comparing debug strings.
+ // TODO(kenton): Use differencer, once it is available.
+ EXPECT_EQ(expected.DebugString(), actual.DebugString());
+ }
+
+ // Parse the text and expect that the given errors are reported.
+ void ExpectHasErrors(const char* text, const char* expected_errors) {
+ ExpectHasEarlyExitErrors(text, expected_errors);
+ EXPECT_EQ(io::Tokenizer::TYPE_END, input_->current().type);
+ }
+
+ // Same as above but does not expect that the parser parses the complete
+ // input.
+ void ExpectHasEarlyExitErrors(const char* text, const char* expected_errors) {
+ SetupParser(text);
+ FileDescriptorProto file;
+ parser_->Parse(input_.get(), &file);
+ EXPECT_EQ(expected_errors, error_collector_.text_);
+ }
+
+ // Parse the text as a file and validate it (with a DescriptorPool), and
+ // expect that the validation step reports the given errors.
+ void ExpectHasValidationErrors(const char* text,
+ const char* expected_errors) {
+ SetupParser(text);
+ SourceLocationTable source_locations;
+ parser_->RecordSourceLocationsTo(&source_locations);
+
+ FileDescriptorProto file;
+ file.set_name("foo.proto");
+ parser_->Parse(input_.get(), &file);
+ EXPECT_EQ(io::Tokenizer::TYPE_END, input_->current().type);
+ ASSERT_EQ("", error_collector_.text_);
+
+ MockValidationErrorCollector validation_error_collector(source_locations,
+ &error_collector_);
+ EXPECT_TRUE(pool_.BuildFileCollectingErrors(
+ file, &validation_error_collector) == NULL);
+ EXPECT_EQ(expected_errors, error_collector_.text_);
+ }
+
+ MockErrorCollector error_collector_;
+ DescriptorPool pool_;
+
+ std::unique_ptr<io::ZeroCopyInputStream> raw_input_;
+ std::unique_ptr<io::Tokenizer> input_;
+ std::unique_ptr<Parser> parser_;
+ bool require_syntax_identifier_;
+};
+
+// ===================================================================
+
+TEST_F(ParserTest, StopAfterSyntaxIdentifier) {
+ SetupParser(
+ "// blah\n"
+ "syntax = \"foobar\";\n"
+ "this line will not be parsed\n");
+ parser_->SetStopAfterSyntaxIdentifier(true);
+ EXPECT_TRUE(parser_->Parse(input_.get(), NULL));
+ EXPECT_EQ("", error_collector_.text_);
+ EXPECT_EQ("foobar", parser_->GetSyntaxIdentifier());
+}
+
+TEST_F(ParserTest, StopAfterOmittedSyntaxIdentifier) {
+ SetupParser(
+ "// blah\n"
+ "this line will not be parsed\n");
+ parser_->SetStopAfterSyntaxIdentifier(true);
+ EXPECT_TRUE(parser_->Parse(input_.get(), NULL));
+ EXPECT_EQ("", error_collector_.text_);
+ EXPECT_EQ("", parser_->GetSyntaxIdentifier());
+}
+
+TEST_F(ParserTest, StopAfterSyntaxIdentifierWithErrors) {
+ SetupParser(
+ "// blah\n"
+ "syntax = error;\n");
+ parser_->SetStopAfterSyntaxIdentifier(true);
+ EXPECT_FALSE(parser_->Parse(input_.get(), NULL));
+ EXPECT_EQ("1:9: Expected syntax identifier.\n", error_collector_.text_);
+}
+
+TEST_F(ParserTest, WarnIfSyntaxIdentifierOmmitted) {
+ SetupParser("message A {}");
+ FileDescriptorProto file;
+ CaptureTestStderr();
+ EXPECT_TRUE(parser_->Parse(input_.get(), &file));
+ EXPECT_TRUE(GetCapturedTestStderr().find("No syntax specified") !=
+ std::string::npos);
+}
+
+TEST_F(ParserTest, WarnIfFieldNameIsNotUpperCamel) {
+ SetupParser(
+ "syntax = \"proto2\";"
+ "message abc {}");
+ FileDescriptorProto file;
+ EXPECT_TRUE(parser_->Parse(input_.get(), &file));
+ EXPECT_TRUE(error_collector_.warning_.find(
+ "Message name should be in UpperCamelCase. Found: abc.") !=
+ std::string::npos);
+}
+
+TEST_F(ParserTest, WarnIfFieldNameIsNotLowerUnderscore) {
+ SetupParser(
+ "syntax = \"proto2\";"
+ "message A {"
+ " optional string SongName = 1;"
+ "}");
+ FileDescriptorProto file;
+ EXPECT_TRUE(parser_->Parse(input_.get(), &file));
+ EXPECT_TRUE(error_collector_.warning_.find(
+ "Field name should be lowercase. Found: SongName") !=
+ std::string::npos);
+}
+
+TEST_F(ParserTest, WarnIfFieldNameContainsNumberImmediatelyFollowUnderscore) {
+ SetupParser(
+ "syntax = \"proto2\";"
+ "message A {"
+ " optional string song_name_1 = 1;"
+ "}");
+ FileDescriptorProto file;
+ EXPECT_TRUE(parser_->Parse(input_.get(), &file));
+ EXPECT_TRUE(error_collector_.warning_.find(
+ "Number should not come right after an underscore. Found: "
+ "song_name_1.") != std::string::npos);
+}
+
+// ===================================================================
+
+typedef ParserTest ParseMessageTest;
+
+TEST_F(ParseMessageTest, IgnoreBOM) {
+ char input[] =
+ " message TestMessage {\n"
+ " required int32 foo = 1;\n"
+ "}\n";
+ // Set UTF-8 BOM.
+ input[0] = (char)0xEF;
+ input[1] = (char)0xBB;
+ input[2] = (char)0xBF;
+ ExpectParsesTo(
+ input,
+ "message_type {"
+ " name: \"TestMessage\""
+ " field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_INT32 number:1 }"
+ "}");
+}
+
+TEST_F(ParseMessageTest, BOMError) {
+ char input[] =
+ " message TestMessage {\n"
+ " required int32 foo = 1;\n"
+ "}\n";
+ input[0] = (char)0xEF;
+ ExpectHasErrors(input,
+ "0:1: Proto file starts with 0xEF but not UTF-8 BOM. "
+ "Only UTF-8 is accepted for proto file.\n"
+ "0:0: Expected top-level statement (e.g. \"message\").\n");
+}
+
+TEST_F(ParseMessageTest, SimpleMessage) {
+ ExpectParsesTo(
+ "message TestMessage {\n"
+ " required int32 foo = 1;\n"
+ "}\n",
+
+ "message_type {"
+ " name: \"TestMessage\""
+ " field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_INT32 number:1 }"
+ "}");
+}
+
+TEST_F(ParseMessageTest, ImplicitSyntaxIdentifier) {
+ require_syntax_identifier_ = false;
+ ExpectParsesTo(
+ "message TestMessage {\n"
+ " required int32 foo = 1;\n"
+ "}\n",
+
+ "message_type {"
+ " name: \"TestMessage\""
+ " field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_INT32 number:1 }"
+ "}");
+ EXPECT_EQ("proto2", parser_->GetSyntaxIdentifier());
+}
+
+TEST_F(ParseMessageTest, ExplicitSyntaxIdentifier) {
+ ExpectParsesTo(
+ "syntax = \"proto2\";\n"
+ "message TestMessage {\n"
+ " required int32 foo = 1;\n"
+ "}\n",
+
+ "syntax: 'proto2' "
+ "message_type {"
+ " name: \"TestMessage\""
+ " field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_INT32 number:1 }"
+ "}");
+ EXPECT_EQ("proto2", parser_->GetSyntaxIdentifier());
+}
+
+TEST_F(ParseMessageTest, ExplicitRequiredSyntaxIdentifier) {
+ require_syntax_identifier_ = true;
+ ExpectParsesTo(
+ "syntax = \"proto2\";\n"
+ "message TestMessage {\n"
+ " required int32 foo = 1;\n"
+ "}\n",
+
+ "syntax: 'proto2' "
+ "message_type {"
+ " name: \"TestMessage\""
+ " field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_INT32 number:1 }"
+ "}");
+ EXPECT_EQ("proto2", parser_->GetSyntaxIdentifier());
+}
+
+TEST_F(ParseMessageTest, SimpleFields) {
+ ExpectParsesTo(
+ "message TestMessage {\n"
+ " required int32 foo = 15;\n"
+ " optional int32 bar = 34;\n"
+ " repeated int32 baz = 3;\n"
+ "}\n",
+
+ "message_type {"
+ " name: \"TestMessage\""
+ " field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_INT32 number:15 }"
+ " field { name:\"bar\" label:LABEL_OPTIONAL type:TYPE_INT32 number:34 }"
+ " field { name:\"baz\" label:LABEL_REPEATED type:TYPE_INT32 number:3 }"
+ "}");
+}
+
+TEST_F(ParseMessageTest, PrimitiveFieldTypes) {
+ ExpectParsesTo(
+ "message TestMessage {\n"
+ " required int32 foo = 1;\n"
+ " required int64 foo = 1;\n"
+ " required uint32 foo = 1;\n"
+ " required uint64 foo = 1;\n"
+ " required sint32 foo = 1;\n"
+ " required sint64 foo = 1;\n"
+ " required fixed32 foo = 1;\n"
+ " required fixed64 foo = 1;\n"
+ " required sfixed32 foo = 1;\n"
+ " required sfixed64 foo = 1;\n"
+ " required float foo = 1;\n"
+ " required double foo = 1;\n"
+ " required string foo = 1;\n"
+ " required bytes foo = 1;\n"
+ " required bool foo = 1;\n"
+ "}\n",
+
+ "message_type {"
+ " name: \"TestMessage\""
+ " field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_INT32 number:1 "
+ "}"
+ " field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_INT64 number:1 "
+ "}"
+ " field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_UINT32 number:1 "
+ "}"
+ " field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_UINT64 number:1 "
+ "}"
+ " field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_SINT32 number:1 "
+ "}"
+ " field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_SINT64 number:1 "
+ "}"
+ " field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_FIXED32 number:1 "
+ "}"
+ " field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_FIXED64 number:1 "
+ "}"
+ " field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_SFIXED32 number:1 "
+ "}"
+ " field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_SFIXED64 number:1 "
+ "}"
+ " field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_FLOAT number:1 "
+ "}"
+ " field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_DOUBLE number:1 "
+ "}"
+ " field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_STRING number:1 "
+ "}"
+ " field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_BYTES number:1 "
+ "}"
+ " field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_BOOL number:1 "
+ "}"
+ "}");
+}
+
+TEST_F(ParseMessageTest, FieldDefaults) {
+ ExpectParsesTo(
+ "message TestMessage {\n"
+ " required int32 foo = 1 [default= 1 ];\n"
+ " required int32 foo = 1 [default= -2 ];\n"
+ " required int64 foo = 1 [default= 3 ];\n"
+ " required int64 foo = 1 [default= -4 ];\n"
+ " required uint32 foo = 1 [default= 5 ];\n"
+ " required uint64 foo = 1 [default= 6 ];\n"
+ " required float foo = 1 [default= 7.5];\n"
+ " required float foo = 1 [default= -8.5];\n"
+ " required float foo = 1 [default= 9 ];\n"
+ " required double foo = 1 [default= 10.5];\n"
+ " required double foo = 1 [default=-11.5];\n"
+ " required double foo = 1 [default= 12 ];\n"
+ " required double foo = 1 [default= inf ];\n"
+ " required double foo = 1 [default=-inf ];\n"
+ " required double foo = 1 [default= nan ];\n"
+ " required string foo = 1 [default='13\\001'];\n"
+ " required string foo = 1 [default='a' \"b\" \n \"c\"];\n"
+ " required bytes foo = 1 [default='14\\002'];\n"
+ " required bytes foo = 1 [default='a' \"b\" \n 'c'];\n"
+ " required bool foo = 1 [default=true ];\n"
+ " required Foo foo = 1 [default=FOO ];\n"
+
+ " required int32 foo = 1 [default= 0x7FFFFFFF];\n"
+ " required int32 foo = 1 [default=-0x80000000];\n"
+ " required uint32 foo = 1 [default= 0xFFFFFFFF];\n"
+ " required int64 foo = 1 [default= 0x7FFFFFFFFFFFFFFF];\n"
+ " required int64 foo = 1 [default=-0x8000000000000000];\n"
+ " required uint64 foo = 1 [default= 0xFFFFFFFFFFFFFFFF];\n"
+ " required double foo = 1 [default= 0xabcd];\n"
+ "}\n",
+
+#define ETC "name:\"foo\" label:LABEL_REQUIRED number:1"
+ "message_type {"
+ " name: \"TestMessage\""
+ " field { type:TYPE_INT32 default_value:\"1\" " ETC
+ " }"
+ " field { type:TYPE_INT32 default_value:\"-2\" " ETC
+ " }"
+ " field { type:TYPE_INT64 default_value:\"3\" " ETC
+ " }"
+ " field { type:TYPE_INT64 default_value:\"-4\" " ETC
+ " }"
+ " field { type:TYPE_UINT32 default_value:\"5\" " ETC
+ " }"
+ " field { type:TYPE_UINT64 default_value:\"6\" " ETC
+ " }"
+ " field { type:TYPE_FLOAT default_value:\"7.5\" " ETC
+ " }"
+ " field { type:TYPE_FLOAT default_value:\"-8.5\" " ETC
+ " }"
+ " field { type:TYPE_FLOAT default_value:\"9\" " ETC
+ " }"
+ " field { type:TYPE_DOUBLE default_value:\"10.5\" " ETC
+ " }"
+ " field { type:TYPE_DOUBLE default_value:\"-11.5\" " ETC
+ " }"
+ " field { type:TYPE_DOUBLE default_value:\"12\" " ETC
+ " }"
+ " field { type:TYPE_DOUBLE default_value:\"inf\" " ETC
+ " }"
+ " field { type:TYPE_DOUBLE default_value:\"-inf\" " ETC
+ " }"
+ " field { type:TYPE_DOUBLE default_value:\"nan\" " ETC
+ " }"
+ " field { type:TYPE_STRING default_value:\"13\\001\" " ETC
+ " }"
+ " field { type:TYPE_STRING default_value:\"abc\" " ETC
+ " }"
+ " field { type:TYPE_BYTES default_value:\"14\\\\002\" " ETC
+ " }"
+ " field { type:TYPE_BYTES default_value:\"abc\" " ETC
+ " }"
+ " field { type:TYPE_BOOL default_value:\"true\" " ETC
+ " }"
+ " field { type_name:\"Foo\" default_value:\"FOO\" " ETC
+ " }"
+
+ " field {"
+ " type:TYPE_INT32 default_value:\"2147483647\" " ETC
+ " }"
+ " field {"
+ " type:TYPE_INT32 default_value:\"-2147483648\" " ETC
+ " }"
+ " field {"
+ " type:TYPE_UINT32 default_value:\"4294967295\" " ETC
+ " }"
+ " field {"
+ " type:TYPE_INT64 default_value:\"9223372036854775807\" " ETC
+ " }"
+ " field {"
+ " type:TYPE_INT64 default_value:\"-9223372036854775808\" " ETC
+ " }"
+ " field {"
+ " type:TYPE_UINT64 default_value:\"18446744073709551615\" " ETC
+ " }"
+ " field {"
+ " type:TYPE_DOUBLE default_value:\"43981\" " ETC
+ " }"
+ "}");
+#undef ETC
+}
+
+TEST_F(ParseMessageTest, FieldJsonName) {
+ ExpectParsesTo(
+ "message TestMessage {\n"
+ " optional string foo = 1 [json_name = \"@type\"];\n"
+ "}\n",
+ "message_type {"
+ " name: \"TestMessage\""
+ " field {\n"
+ " name: \"foo\" label: LABEL_OPTIONAL type: TYPE_STRING number: 1"
+ " json_name: \"@type\"\n"
+ " }\n"
+ "}\n");
+}
+
+TEST_F(ParseMessageTest, FieldOptions) {
+ ExpectParsesTo(
+ "message TestMessage {\n"
+ " optional string foo = 1\n"
+ " [ctype=CORD, (foo)=7, foo.(.bar.baz).qux.quux.(corge)=-33, \n"
+ " (quux)=\"x\040y\", (baz.qux)=hey];\n"
+ "}\n",
+
+ "message_type {"
+ " name: \"TestMessage\""
+ " field { name: \"foo\" label: LABEL_OPTIONAL type: TYPE_STRING number: "
+ "1"
+ " options { uninterpreted_option: { name { name_part: \"ctype\" "
+ " is_extension: false "
+ "} "
+ " identifier_value: \"CORD\" "
+ "}"
+ " uninterpreted_option: { name { name_part: \"foo\" "
+ " is_extension: true } "
+ " positive_int_value: 7 }"
+ " uninterpreted_option: { name { name_part: \"foo\" "
+ " is_extension: false "
+ "} "
+ " name { name_part: "
+ "\".bar.baz\""
+ " is_extension: true } "
+ " name { name_part: \"qux\" "
+ " is_extension: false "
+ "} "
+ " name { name_part: \"quux\" "
+ " is_extension: false "
+ "} "
+ " name { name_part: \"corge\" "
+ " is_extension: true } "
+ " negative_int_value: -33 }"
+ " uninterpreted_option: { name { name_part: \"quux\" "
+ " is_extension: true } "
+ " string_value: \"x y\" }"
+ " uninterpreted_option: { name { name_part: "
+ "\"baz.qux\" "
+ " is_extension: true } "
+ " identifier_value: \"hey\" }"
+ " }"
+ " }"
+ "}");
+}
+
+TEST_F(ParseMessageTest, Oneof) {
+ ExpectParsesTo(
+ "message TestMessage {\n"
+ " oneof foo {\n"
+ " int32 a = 1;\n"
+ " string b = 2;\n"
+ " TestMessage c = 3;\n"
+ " group D = 4 { optional int32 i = 5; }\n"
+ " }\n"
+ "}\n",
+
+ "message_type {"
+ " name: \"TestMessage\""
+ " field { name:\"a\" label:LABEL_OPTIONAL type:TYPE_INT32 number:1 "
+ " oneof_index:0 }"
+ " field { name:\"b\" label:LABEL_OPTIONAL type:TYPE_STRING number:2 "
+ " oneof_index:0 }"
+ " field { name:\"c\" label:LABEL_OPTIONAL type_name:\"TestMessage\" "
+ " number:3 oneof_index:0 }"
+ " field { name:\"d\" label:LABEL_OPTIONAL type:TYPE_GROUP "
+ " type_name:\"D\" number:4 oneof_index:0 }"
+ " oneof_decl {"
+ " name: \"foo\""
+ " }"
+ " nested_type {"
+ " name: \"D\""
+ " field { name:\"i\" label:LABEL_OPTIONAL type:TYPE_INT32 number:5 }"
+ " }"
+ "}");
+}
+
+TEST_F(ParseMessageTest, MultipleOneofs) {
+ ExpectParsesTo(
+ "message TestMessage {\n"
+ " oneof foo {\n"
+ " int32 a = 1;\n"
+ " string b = 2;\n"
+ " }\n"
+ " oneof bar {\n"
+ " int32 c = 3;\n"
+ " string d = 4;\n"
+ " }\n"
+ "}\n",
+
+ "message_type {"
+ " name: \"TestMessage\""
+ " field { name:\"a\" label:LABEL_OPTIONAL type:TYPE_INT32 number:1 "
+ " oneof_index:0 }"
+ " field { name:\"b\" label:LABEL_OPTIONAL type:TYPE_STRING number:2 "
+ " oneof_index:0 }"
+ " field { name:\"c\" label:LABEL_OPTIONAL type:TYPE_INT32 number:3 "
+ " oneof_index:1 }"
+ " field { name:\"d\" label:LABEL_OPTIONAL type:TYPE_STRING number:4 "
+ " oneof_index:1 }"
+ " oneof_decl {"
+ " name: \"foo\""
+ " }"
+ " oneof_decl {"
+ " name: \"bar\""
+ " }"
+ "}");
+}
+
+TEST_F(ParseMessageTest, Maps) {
+ ExpectParsesTo(
+ "message TestMessage {\n"
+ " map<int32, string> primitive_type_map = 1;\n"
+ " map<KeyType, ValueType> composite_type_map = 2;\n"
+ "}\n",
+
+ "message_type {"
+ " name: \"TestMessage\""
+ " nested_type {"
+ " name: \"PrimitiveTypeMapEntry\""
+ " field { "
+ " name: \"key\" number: 1 label:LABEL_OPTIONAL"
+ " type:TYPE_INT32"
+ " }"
+ " field { "
+ " name: \"value\" number: 2 label:LABEL_OPTIONAL"
+ " type:TYPE_STRING"
+ " }"
+ " options { map_entry: true }"
+ " }"
+ " nested_type {"
+ " name: \"CompositeTypeMapEntry\""
+ " field { "
+ " name: \"key\" number: 1 label:LABEL_OPTIONAL"
+ " type_name: \"KeyType\""
+ " }"
+ " field { "
+ " name: \"value\" number: 2 label:LABEL_OPTIONAL"
+ " type_name: \"ValueType\""
+ " }"
+ " options { map_entry: true }"
+ " }"
+ " field {"
+ " name: \"primitive_type_map\""
+ " label: LABEL_REPEATED"
+ " type_name: \"PrimitiveTypeMapEntry\""
+ " number: 1"
+ " }"
+ " field {"
+ " name: \"composite_type_map\""
+ " label: LABEL_REPEATED"
+ " type_name: \"CompositeTypeMapEntry\""
+ " number: 2"
+ " }"
+ "}");
+}
+
+TEST_F(ParseMessageTest, Group) {
+ ExpectParsesTo(
+ "message TestMessage {\n"
+ " optional group TestGroup = 1 {};\n"
+ "}\n",
+
+ "message_type {"
+ " name: \"TestMessage\""
+ " nested_type { name: \"TestGroup\" }"
+ " field { name:\"testgroup\" label:LABEL_OPTIONAL number:1"
+ " type:TYPE_GROUP type_name: \"TestGroup\" }"
+ "}");
+}
+
+TEST_F(ParseMessageTest, NestedMessage) {
+ ExpectParsesTo(
+ "message TestMessage {\n"
+ " message Nested {}\n"
+ " optional Nested test_nested = 1;\n"
+ "}\n",
+
+ "message_type {"
+ " name: \"TestMessage\""
+ " nested_type { name: \"Nested\" }"
+ " field { name:\"test_nested\" label:LABEL_OPTIONAL number:1"
+ " type_name: \"Nested\" }"
+ "}");
+}
+
+TEST_F(ParseMessageTest, NestedEnum) {
+ ExpectParsesTo(
+ "message TestMessage {\n"
+ " enum NestedEnum {}\n"
+ " optional NestedEnum test_enum = 1;\n"
+ "}\n",
+
+ "message_type {"
+ " name: \"TestMessage\""
+ " enum_type { name: \"NestedEnum\" }"
+ " field { name:\"test_enum\" label:LABEL_OPTIONAL number:1"
+ " type_name: \"NestedEnum\" }"
+ "}");
+}
+
+TEST_F(ParseMessageTest, ReservedRange) {
+ ExpectParsesTo(
+ "message TestMessage {\n"
+ " required int32 foo = 1;\n"
+ " reserved 2, 15, 9 to 11, 3, 20 to max;\n"
+ "}\n",
+
+ "message_type {"
+ " name: \"TestMessage\""
+ " field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_INT32 number:1 }"
+ " reserved_range { start:2 end:3 }"
+ " reserved_range { start:15 end:16 }"
+ " reserved_range { start:9 end:12 }"
+ " reserved_range { start:3 end:4 }"
+ " reserved_range { start:20 end:536870912 }"
+ "}");
+}
+
+TEST_F(ParseMessageTest, ReservedRangeOnMessageSet) {
+ ExpectParsesTo(
+ "message TestMessage {\n"
+ " option message_set_wire_format = true;\n"
+ " reserved 20 to max;\n"
+ "}\n",
+
+ "message_type {"
+ " name: \"TestMessage\""
+ " options {"
+ " uninterpreted_option {"
+ " name {"
+ " name_part: \"message_set_wire_format\""
+ " is_extension: false"
+ " }"
+ " identifier_value: \"true\""
+ " }"
+ " }"
+ " reserved_range { start:20 end:2147483647 }"
+ "}");
+}
+
+TEST_F(ParseMessageTest, ReservedNames) {
+ ExpectParsesTo(
+ "message TestMessage {\n"
+ " reserved \"foo\", \"bar\";\n"
+ "}\n",
+
+ "message_type {"
+ " name: \"TestMessage\""
+ " reserved_name: \"foo\""
+ " reserved_name: \"bar\""
+ "}");
+}
+
+TEST_F(ParseMessageTest, ExtensionRange) {
+ ExpectParsesTo(
+ "message TestMessage {\n"
+ " extensions 10 to 19;\n"
+ " extensions 30 to max;\n"
+ "}\n",
+
+ "message_type {"
+ " name: \"TestMessage\""
+ " extension_range { start:10 end:20 }"
+ " extension_range { start:30 end:536870912 }"
+ "}");
+}
+
+TEST_F(ParseMessageTest, ExtensionRangeWithOptions) {
+ ExpectParsesTo(
+ "message TestMessage {\n"
+ " extensions 10 to 19 [(i) = 5];\n"
+ "}\n",
+
+ "message_type {"
+ " name: \"TestMessage\""
+ " extension_range {"
+ " start:10"
+ " end:20"
+ " options {"
+ " uninterpreted_option {"
+ " name {"
+ " name_part: \"i\""
+ " is_extension: true"
+ " }"
+ " positive_int_value: 5"
+ " }"
+ " }"
+ " }"
+ "}");
+}
+
+TEST_F(ParseMessageTest, CompoundExtensionRange) {
+ ExpectParsesTo(
+ "message TestMessage {\n"
+ " extensions 2, 15, 9 to 11, 100 to max, 3;\n"
+ "}\n",
+
+ "message_type {"
+ " name: \"TestMessage\""
+ " extension_range { start:2 end:3 }"
+ " extension_range { start:15 end:16 }"
+ " extension_range { start:9 end:12 }"
+ " extension_range { start:100 end:536870912 }"
+ " extension_range { start:3 end:4 }"
+ "}");
+}
+
+TEST_F(ParseMessageTest, CompoundExtensionRangeWithOptions) {
+ ExpectParsesTo(
+ "message TestMessage {\n"
+ " extensions 2, 15, 9 to 11, 100 to max, 3 [(i) = 5];\n"
+ "}\n",
+
+ "message_type {"
+ " name: \"TestMessage\""
+ " extension_range {"
+ " start:2"
+ " end:3"
+ " options {"
+ " uninterpreted_option {"
+ " name {"
+ " name_part: \"i\""
+ " is_extension: true"
+ " }"
+ " positive_int_value: 5"
+ " }"
+ " }"
+ " }"
+ " extension_range {"
+ " start:15"
+ " end:16"
+ " options {"
+ " uninterpreted_option {"
+ " name {"
+ " name_part: \"i\""
+ " is_extension: true"
+ " }"
+ " positive_int_value: 5"
+ " }"
+ " }"
+ " }"
+ " extension_range {"
+ " start:9"
+ " end:12"
+ " options {"
+ " uninterpreted_option {"
+ " name {"
+ " name_part: \"i\""
+ " is_extension: true"
+ " }"
+ " positive_int_value: 5"
+ " }"
+ " }"
+ " }"
+ " extension_range {"
+ " start:100"
+ " end:536870912"
+ " options {"
+ " uninterpreted_option {"
+ " name {"
+ " name_part: \"i\""
+ " is_extension: true"
+ " }"
+ " positive_int_value: 5"
+ " }"
+ " }"
+ " }"
+ " extension_range {"
+ " start:3"
+ " end:4"
+ " options {"
+ " uninterpreted_option {"
+ " name {"
+ " name_part: \"i\""
+ " is_extension: true"
+ " }"
+ " positive_int_value: 5"
+ " }"
+ " }"
+ " }"
+ "}");
+}
+
+TEST_F(ParseMessageTest, LargerMaxForMessageSetWireFormatMessages) {
+ // Messages using the message_set_wire_format option can accept larger
+ // extension numbers, as the numbers are not encoded as int32 field values
+ // rather than tags.
+ ExpectParsesTo(
+ "message TestMessage {\n"
+ " extensions 4 to max;\n"
+ " option message_set_wire_format = true;\n"
+ "}\n",
+
+ "message_type {"
+ " name: \"TestMessage\""
+ " extension_range { start:4 end: 0x7fffffff }"
+ " options {\n"
+ " uninterpreted_option { \n"
+ " name {\n"
+ " name_part: \"message_set_wire_format\"\n"
+ " is_extension: false\n"
+ " }\n"
+ " identifier_value: \"true\"\n"
+ " }\n"
+ " }\n"
+ "}");
+}
+
+TEST_F(ParseMessageTest, Extensions) {
+ ExpectParsesTo(
+ "extend Extendee1 { optional int32 foo = 12; }\n"
+ "extend Extendee2 { repeated TestMessage bar = 22; }\n",
+
+ "extension { name:\"foo\" label:LABEL_OPTIONAL type:TYPE_INT32 number:12"
+ " extendee: \"Extendee1\" } "
+ "extension { name:\"bar\" label:LABEL_REPEATED number:22"
+ " type_name:\"TestMessage\" extendee: \"Extendee2\" }");
+}
+
+TEST_F(ParseMessageTest, ExtensionsInMessageScope) {
+ ExpectParsesTo(
+ "message TestMessage {\n"
+ " extend Extendee1 { optional int32 foo = 12; }\n"
+ " extend Extendee2 { repeated TestMessage bar = 22; }\n"
+ "}\n",
+
+ "message_type {"
+ " name: \"TestMessage\""
+ " extension { name:\"foo\" label:LABEL_OPTIONAL type:TYPE_INT32 "
+ "number:12"
+ " extendee: \"Extendee1\" }"
+ " extension { name:\"bar\" label:LABEL_REPEATED number:22"
+ " type_name:\"TestMessage\" extendee: \"Extendee2\" }"
+ "}");
+}
+
+TEST_F(ParseMessageTest, MultipleExtensionsOneExtendee) {
+ ExpectParsesTo(
+ "extend Extendee1 {\n"
+ " optional int32 foo = 12;\n"
+ " repeated TestMessage bar = 22;\n"
+ "}\n",
+
+ "extension { name:\"foo\" label:LABEL_OPTIONAL type:TYPE_INT32 number:12"
+ " extendee: \"Extendee1\" } "
+ "extension { name:\"bar\" label:LABEL_REPEATED number:22"
+ " type_name:\"TestMessage\" extendee: \"Extendee1\" }");
+}
+
+TEST_F(ParseMessageTest, OptionalLabelProto3) {
+ ExpectParsesTo(
+ "syntax = \"proto3\";\n"
+ "message TestMessage {\n"
+ " int32 foo = 1;\n"
+ "}\n",
+
+ "syntax: \"proto3\" "
+ "message_type {"
+ " name: \"TestMessage\""
+ " field { name:\"foo\" label:LABEL_OPTIONAL type:TYPE_INT32 number:1 } "
+ "}");
+}
+
+TEST_F(ParseMessageTest, ExplicitOptionalLabelProto3) {
+ ExpectParsesTo(
+ "syntax = 'proto3';\n"
+ "message TestMessage {\n"
+ " optional int32 foo = 1;\n"
+ "}\n",
+
+ "syntax: \"proto3\" "
+ "message_type {"
+ " name: \"TestMessage\""
+ " field { name:\"foo\" label:LABEL_OPTIONAL type:TYPE_INT32 number:1 "
+ " proto3_optional: true oneof_index: 0 } "
+ " oneof_decl { name:\"_foo\" } "
+ "}");
+
+ // Handle collisions in the synthetic oneof name.
+ ExpectParsesTo(
+ "syntax = 'proto3';\n"
+ "message TestMessage {\n"
+ " optional int32 foo = 1;\n"
+ " oneof _foo {\n"
+ " int32 __foo = 2;\n"
+ " }\n"
+ "}\n",
+
+ "syntax: \"proto3\" "
+ "message_type {"
+ " name: \"TestMessage\""
+ " field { name:\"foo\" label:LABEL_OPTIONAL type:TYPE_INT32 number:1 "
+ " proto3_optional: true oneof_index: 1 } "
+ " field { name:\"__foo\" label:LABEL_OPTIONAL type:TYPE_INT32 number:2 "
+ " oneof_index: 0 } "
+ " oneof_decl { name:\"_foo\" } "
+ " oneof_decl { name:\"X_foo\" } "
+ "}");
+}
+
+// ===================================================================
+
+typedef ParserTest ParseEnumTest;
+
+TEST_F(ParseEnumTest, SimpleEnum) {
+ ExpectParsesTo(
+ "enum TestEnum {\n"
+ " FOO = 0;\n"
+ "}\n",
+
+ "enum_type {"
+ " name: \"TestEnum\""
+ " value { name:\"FOO\" number:0 }"
+ "}");
+}
+
+TEST_F(ParseEnumTest, Values) {
+ ExpectParsesTo(
+ "enum TestEnum {\n"
+ " FOO = 13;\n"
+ " BAR = -10;\n"
+ " BAZ = 500;\n"
+ " HEX_MAX = 0x7FFFFFFF;\n"
+ " HEX_MIN = -0x80000000;\n"
+ " INT_MAX = 2147483647;\n"
+ " INT_MIN = -2147483648;\n"
+ "}\n",
+
+ "enum_type {"
+ " name: \"TestEnum\""
+ " value { name:\"FOO\" number:13 }"
+ " value { name:\"BAR\" number:-10 }"
+ " value { name:\"BAZ\" number:500 }"
+ " value { name:\"HEX_MAX\" number:2147483647 }"
+ " value { name:\"HEX_MIN\" number:-2147483648 }"
+ " value { name:\"INT_MAX\" number:2147483647 }"
+ " value { name:\"INT_MIN\" number:-2147483648 }"
+ "}");
+}
+
+TEST_F(ParseEnumTest, ValueOptions) {
+ ExpectParsesTo(
+ "enum TestEnum {\n"
+ " FOO = 13;\n"
+ " BAR = -10 [ (something.text) = 'abc' ];\n"
+ " BAZ = 500 [ (something.text) = 'def', other = 1 ];\n"
+ "}\n",
+
+ "enum_type {"
+ " name: \"TestEnum\""
+ " value { name: \"FOO\" number: 13 }"
+ " value { name: \"BAR\" number: -10 "
+ " options { "
+ " uninterpreted_option { "
+ " name { name_part: \"something.text\" is_extension: true } "
+ " string_value: \"abc\" "
+ " } "
+ " } "
+ " } "
+ " value { name: \"BAZ\" number: 500 "
+ " options { "
+ " uninterpreted_option { "
+ " name { name_part: \"something.text\" is_extension: true } "
+ " string_value: \"def\" "
+ " } "
+ " uninterpreted_option { "
+ " name { name_part: \"other\" is_extension: false } "
+ " positive_int_value: 1 "
+ " } "
+ " } "
+ " } "
+ "}");
+}
+
+TEST_F(ParseEnumTest, ReservedRange) {
+ ExpectParsesTo(
+ "enum TestEnum {\n"
+ " FOO = 0;\n"
+ " reserved -2147483648, -6 to -4, -1 to 1, 2, 15, 9 to 11, 3, 20 to "
+ "max;\n"
+ "}\n",
+
+ "enum_type {"
+ " name: \"TestEnum\""
+ " value { name:\"FOO\" number:0 }"
+ " reserved_range { start:-2147483648 end:-2147483648 }"
+ " reserved_range { start:-6 end:-4 }"
+ " reserved_range { start:-1 end:1 }"
+ " reserved_range { start:2 end:2 }"
+ " reserved_range { start:15 end:15 }"
+ " reserved_range { start:9 end:11 }"
+ " reserved_range { start:3 end:3 }"
+ " reserved_range { start:20 end:2147483647 }"
+ "}");
+}
+
+TEST_F(ParseEnumTest, ReservedNames) {
+ ExpectParsesTo(
+ "enum TestEnum {\n"
+ " FOO = 0;\n"
+ " reserved \"foo\", \"bar\";\n"
+ "}\n",
+
+ "enum_type {"
+ " name: \"TestEnum\""
+ " value { name:\"FOO\" number:0 }"
+ " reserved_name: \"foo\""
+ " reserved_name: \"bar\""
+ "}");
+}
+
+// ===================================================================
+
+typedef ParserTest ParseServiceTest;
+
+TEST_F(ParseServiceTest, SimpleService) {
+ ExpectParsesTo(
+ "service TestService {\n"
+ " rpc Foo(In) returns (Out);\n"
+ "}\n",
+
+ "service {"
+ " name: \"TestService\""
+ " method { name:\"Foo\" input_type:\"In\" output_type:\"Out\" }"
+ "}");
+}
+
+TEST_F(ParseServiceTest, MethodsAndStreams) {
+ ExpectParsesTo(
+ "service TestService {\n"
+ " rpc Foo(In1) returns (Out1);\n"
+ " rpc Bar(In2) returns (Out2);\n"
+ " rpc Baz(In3) returns (Out3);\n"
+ "}\n",
+
+ "service {"
+ " name: \"TestService\""
+ " method { name:\"Foo\" input_type:\"In1\" output_type:\"Out1\" }"
+ " method { name:\"Bar\" input_type:\"In2\" output_type:\"Out2\" }"
+ " method { name:\"Baz\" input_type:\"In3\" output_type:\"Out3\" }"
+ "}");
+}
+
+
+// ===================================================================
+// imports and packages
+
+typedef ParserTest ParseMiscTest;
+
+TEST_F(ParseMiscTest, ParseImport) {
+ ExpectParsesTo("import \"foo/bar/baz.proto\";\n",
+ "dependency: \"foo/bar/baz.proto\"");
+}
+
+TEST_F(ParseMiscTest, ParseMultipleImports) {
+ ExpectParsesTo(
+ "import \"foo.proto\";\n"
+ "import \"bar.proto\";\n"
+ "import \"baz.proto\";\n",
+ "dependency: \"foo.proto\""
+ "dependency: \"bar.proto\""
+ "dependency: \"baz.proto\"");
+}
+
+TEST_F(ParseMiscTest, ParsePublicImports) {
+ ExpectParsesTo(
+ "import \"foo.proto\";\n"
+ "import public \"bar.proto\";\n"
+ "import \"baz.proto\";\n"
+ "import public \"qux.proto\";\n",
+ "dependency: \"foo.proto\""
+ "dependency: \"bar.proto\""
+ "dependency: \"baz.proto\""
+ "dependency: \"qux.proto\""
+ "public_dependency: 1 "
+ "public_dependency: 3 ");
+}
+
+TEST_F(ParseMiscTest, ParsePackage) {
+ ExpectParsesTo("package foo.bar.baz;\n", "package: \"foo.bar.baz\"");
+}
+
+TEST_F(ParseMiscTest, ParsePackageWithSpaces) {
+ ExpectParsesTo(
+ "package foo . bar. \n"
+ " baz;\n",
+ "package: \"foo.bar.baz\"");
+}
+
+// ===================================================================
+// options
+
+TEST_F(ParseMiscTest, ParseFileOptions) {
+ ExpectParsesTo(
+ "option java_package = \"com.google.foo\";\n"
+ "option optimize_for = CODE_SIZE;",
+
+ "options {"
+ "uninterpreted_option { name { name_part: \"java_package\" "
+ " is_extension: false }"
+ " string_value: \"com.google.foo\"} "
+ "uninterpreted_option { name { name_part: \"optimize_for\" "
+ " is_extension: false }"
+ " identifier_value: \"CODE_SIZE\" } "
+ "}");
+}
+
+// ===================================================================
+// Error tests
+//
+// There are a very large number of possible errors that the parser could
+// report, so it's infeasible to test every single one of them. Instead,
+// we test each unique call to AddError() in parser.h. This does not mean
+// we are testing every possible error that Parser can generate because
+// each variant of the Consume() helper only counts as one unique call to
+// AddError().
+
+typedef ParserTest ParseErrorTest;
+
+TEST_F(ParseErrorTest, MissingSyntaxIdentifier) {
+ require_syntax_identifier_ = true;
+ ExpectHasEarlyExitErrors("message TestMessage {}",
+ "0:0: File must begin with a syntax statement, e.g. "
+ "'syntax = \"proto2\";'.\n");
+ EXPECT_EQ("", parser_->GetSyntaxIdentifier());
+}
+
+TEST_F(ParseErrorTest, UnknownSyntaxIdentifier) {
+ ExpectHasEarlyExitErrors(
+ "syntax = \"no_such_syntax\";",
+ "0:9: Unrecognized syntax identifier \"no_such_syntax\". This parser "
+ "only recognizes \"proto2\" and \"proto3\".\n");
+ EXPECT_EQ("no_such_syntax", parser_->GetSyntaxIdentifier());
+}
+
+TEST_F(ParseErrorTest, SimpleSyntaxError) {
+ ExpectHasErrors("message TestMessage @#$ { blah }",
+ "0:20: Expected \"{\".\n");
+ EXPECT_EQ("proto2", parser_->GetSyntaxIdentifier());
+}
+
+TEST_F(ParseErrorTest, ExpectedTopLevel) {
+ ExpectHasErrors("blah;",
+ "0:0: Expected top-level statement (e.g. \"message\").\n");
+}
+
+TEST_F(ParseErrorTest, UnmatchedCloseBrace) {
+ // This used to cause an infinite loop. Doh.
+ ExpectHasErrors("}",
+ "0:0: Expected top-level statement (e.g. \"message\").\n"
+ "0:0: Unmatched \"}\".\n");
+}
+
+// -------------------------------------------------------------------
+// Message errors
+
+TEST_F(ParseErrorTest, MessageMissingName) {
+ ExpectHasErrors("message {}", "0:8: Expected message name.\n");
+}
+
+TEST_F(ParseErrorTest, MessageMissingBody) {
+ ExpectHasErrors("message TestMessage;", "0:19: Expected \"{\".\n");
+}
+
+TEST_F(ParseErrorTest, EofInMessage) {
+ ExpectHasErrors(
+ "message TestMessage {",
+ "0:21: Reached end of input in message definition (missing '}').\n");
+}
+
+TEST_F(ParseErrorTest, MissingFieldNumber) {
+ ExpectHasErrors(
+ "message TestMessage {\n"
+ " optional int32 foo;\n"
+ "}\n",
+ "1:20: Missing field number.\n");
+}
+
+TEST_F(ParseErrorTest, ExpectedFieldNumber) {
+ ExpectHasErrors(
+ "message TestMessage {\n"
+ " optional int32 foo = ;\n"
+ "}\n",
+ "1:23: Expected field number.\n");
+}
+
+TEST_F(ParseErrorTest, FieldNumberOutOfRange) {
+ ExpectHasErrors(
+ "message TestMessage {\n"
+ " optional int32 foo = 0x100000000;\n"
+ "}\n",
+ "1:23: Integer out of range.\n");
+}
+
+TEST_F(ParseErrorTest, MissingLabel) {
+ ExpectHasErrors(
+ "message TestMessage {\n"
+ " int32 foo = 1;\n"
+ "}\n",
+ "1:2: Expected \"required\", \"optional\", or \"repeated\".\n");
+}
+
+TEST_F(ParseErrorTest, ExpectedOptionName) {
+ ExpectHasErrors(
+ "message TestMessage {\n"
+ " optional uint32 foo = 1 [];\n"
+ "}\n",
+ "1:27: Expected identifier.\n");
+}
+
+TEST_F(ParseErrorTest, NonExtensionOptionNameBeginningWithDot) {
+ ExpectHasErrors(
+ "message TestMessage {\n"
+ " optional uint32 foo = 1 [.foo=1];\n"
+ "}\n",
+ "1:27: Expected identifier.\n");
+}
+
+TEST_F(ParseErrorTest, DefaultValueTypeMismatch) {
+ ExpectHasErrors(
+ "message TestMessage {\n"
+ " optional uint32 foo = 1 [default=true];\n"
+ "}\n",
+ "1:35: Expected integer for field default value.\n");
+}
+
+TEST_F(ParseErrorTest, DefaultValueNotBoolean) {
+ ExpectHasErrors(
+ "message TestMessage {\n"
+ " optional bool foo = 1 [default=blah];\n"
+ "}\n",
+ "1:33: Expected \"true\" or \"false\".\n");
+}
+
+TEST_F(ParseErrorTest, DefaultValueNotString) {
+ ExpectHasErrors(
+ "message TestMessage {\n"
+ " optional string foo = 1 [default=1];\n"
+ "}\n",
+ "1:35: Expected string for field default value.\n");
+}
+
+TEST_F(ParseErrorTest, DefaultValueUnsignedNegative) {
+ ExpectHasErrors(
+ "message TestMessage {\n"
+ " optional uint32 foo = 1 [default=-1];\n"
+ "}\n",
+ "1:36: Unsigned field can't have negative default value.\n");
+}
+
+TEST_F(ParseErrorTest, DefaultValueTooLarge) {
+ ExpectHasErrors(
+ "message TestMessage {\n"
+ " optional int32 foo = 1 [default= 0x80000000];\n"
+ " optional int32 foo = 1 [default=-0x80000001];\n"
+ " optional uint32 foo = 1 [default= 0x100000000];\n"
+ " optional int64 foo = 1 [default= 0x80000000000000000];\n"
+ " optional int64 foo = 1 [default=-0x80000000000000001];\n"
+ " optional uint64 foo = 1 [default= 0x100000000000000000];\n"
+ "}\n",
+ "1:36: Integer out of range.\n"
+ "2:36: Integer out of range.\n"
+ "3:36: Integer out of range.\n"
+ "4:36: Integer out of range.\n"
+ "5:36: Integer out of range.\n"
+ "6:36: Integer out of range.\n");
+}
+
+TEST_F(ParseErrorTest, JsonNameNotString) {
+ ExpectHasErrors(
+ "message TestMessage {\n"
+ " optional string foo = 1 [json_name=1];\n"
+ "}\n",
+ "1:37: Expected string for JSON name.\n");
+}
+
+TEST_F(ParseErrorTest, DuplicateJsonName) {
+ ExpectHasErrors(
+ "message TestMessage {\n"
+ " optional uint32 foo = 1 [json_name=\"a\",json_name=\"b\"];\n"
+ "}\n",
+ "1:41: Already set option \"json_name\".\n");
+}
+
+TEST_F(ParseErrorTest, EnumValueOutOfRange) {
+ ExpectHasErrors(
+ "enum TestEnum {\n"
+ " HEX_TOO_BIG = 0x80000000;\n"
+ " HEX_TOO_SMALL = -0x80000001;\n"
+ " INT_TOO_BIG = 2147483648;\n"
+ " INT_TOO_SMALL = -2147483649;\n"
+ "}\n",
+ "1:19: Integer out of range.\n"
+ "2:19: Integer out of range.\n"
+ "3:19: Integer out of range.\n"
+ "4:19: Integer out of range.\n");
+}
+
+TEST_F(ParseErrorTest, EnumAllowAliasFalse) {
+ ExpectHasErrors(
+ "enum Foo {\n"
+ " option allow_alias = false;\n"
+ " BAR = 1;\n"
+ " BAZ = 2;\n"
+ "}\n",
+ "5:0: \"Foo\" declares 'option allow_alias = false;' which has no "
+ "effect. "
+ "Please remove the declaration.\n");
+}
+
+TEST_F(ParseErrorTest, UnnecessaryEnumAllowAlias) {
+ ExpectHasErrors(
+ "enum Foo {\n"
+ " option allow_alias = true;\n"
+ " BAR = 1;\n"
+ " BAZ = 2;\n"
+ "}\n",
+ "5:0: \"Foo\" declares support for enum aliases but no enum values share "
+ "field numbers. Please remove the unnecessary 'option allow_alias = "
+ "true;' "
+ "declaration.\n");
+}
+
+TEST_F(ParseErrorTest, DefaultValueMissing) {
+ ExpectHasErrors(
+ "message TestMessage {\n"
+ " optional uint32 foo = 1 [default=];\n"
+ "}\n",
+ "1:35: Expected integer for field default value.\n");
+}
+
+TEST_F(ParseErrorTest, DefaultValueForGroup) {
+ ExpectHasErrors(
+ "message TestMessage {\n"
+ " optional group Foo = 1 [default=blah] {}\n"
+ "}\n",
+ "1:34: Messages can't have default values.\n");
+}
+
+TEST_F(ParseErrorTest, DuplicateDefaultValue) {
+ ExpectHasErrors(
+ "message TestMessage {\n"
+ " optional uint32 foo = 1 [default=1,default=2];\n"
+ "}\n",
+ "1:37: Already set option \"default\".\n");
+}
+
+TEST_F(ParseErrorTest, MissingOneofName) {
+ ExpectHasErrors(
+ "message TestMessage {\n"
+ " oneof {\n"
+ " int32 bar = 1;\n"
+ " }\n"
+ "}\n",
+ "1:8: Expected oneof name.\n");
+}
+
+TEST_F(ParseErrorTest, LabelInOneof) {
+ ExpectHasErrors(
+ "message TestMessage {\n"
+ " oneof foo {\n"
+ " optional int32 bar = 1;\n"
+ " }\n"
+ "}\n",
+ "2:4: Fields in oneofs must not have labels (required / optional "
+ "/ repeated).\n");
+}
+
+TEST_F(ParseErrorTest, MapInOneof) {
+ ExpectHasErrors(
+ "message TestMessage {\n"
+ " oneof foo {\n"
+ " map<int32, int32> foo_map = 1;\n"
+ " map message_field = 2;\n" // a normal message field is OK
+ " }\n"
+ "}\n",
+ "2:7: Map fields are not allowed in oneofs.\n");
+}
+
+TEST_F(ParseErrorTest, LabelForMap) {
+ ExpectHasErrors(
+ "message TestMessage {\n"
+ " optional map<int32, int32> int_map = 1;\n"
+ " required map<int32, int32> int_map2 = 2;\n"
+ " repeated map<int32, int32> int_map3 = 3;\n"
+ " optional map map_message = 4;\n" // a normal message field is OK
+ "}\n",
+ "1:14: Field labels (required/optional/repeated) are not allowed on map "
+ "fields.\n"
+ "2:14: Field labels (required/optional/repeated) are not allowed on map "
+ "fields.\n"
+ "3:14: Field labels (required/optional/repeated) are not allowed on map "
+ "fields.\n");
+}
+
+TEST_F(ParseErrorTest, MalformedMaps) {
+ ExpectHasErrors(
+ "message TestMessage {\n"
+ " map map_message = 1;\n" // a normal message field lacking label
+ " map<string> str_map = 2;\n"
+ " map<string,> str_map2 = 3;\n"
+ " map<,string> str_map3 = 4;\n"
+ " map<> empty_map = 5;\n"
+ " map<string,string str_map6 = 6;\n"
+ "}"
+ "extend SomeMessage {\n"
+ " map<int32, int32> int_map = 1;\n"
+ "}",
+ "1:6: Expected \"required\", \"optional\", or \"repeated\".\n"
+ "2:12: Expected \",\".\n"
+ "3:13: Expected type name.\n"
+ "4:6: Expected type name.\n"
+ "5:6: Expected type name.\n"
+ "6:20: Expected \">\".\n"
+ "8:5: Map fields are not allowed to be extensions.\n");
+}
+
+TEST_F(ParseErrorTest, GroupNotCapitalized) {
+ ExpectHasErrors(
+ "message TestMessage {\n"
+ " optional group foo = 1 {}\n"
+ "}\n",
+ "1:17: Group names must start with a capital letter.\n");
+}
+
+TEST_F(ParseErrorTest, GroupMissingBody) {
+ ExpectHasErrors(
+ "message TestMessage {\n"
+ " optional group Foo = 1;\n"
+ "}\n",
+ "1:24: Missing group body.\n");
+}
+
+TEST_F(ParseErrorTest, ExtendingPrimitive) {
+ ExpectHasErrors("extend int32 { optional string foo = 4; }\n",
+ "0:7: Expected message type.\n");
+}
+
+TEST_F(ParseErrorTest, ErrorInExtension) {
+ ExpectHasErrors(
+ "message Foo { extensions 100 to 199; }\n"
+ "extend Foo { optional string foo; }\n",
+ "1:32: Missing field number.\n");
+}
+
+TEST_F(ParseErrorTest, MultipleParseErrors) {
+ // When a statement has a parse error, the parser should be able to continue
+ // parsing at the next statement.
+ ExpectHasErrors(
+ "message TestMessage {\n"
+ " optional int32 foo;\n"
+ " !invalid statement ending in a block { blah blah { blah } blah }\n"
+ " optional int32 bar = 3 {}\n"
+ "}\n",
+ "1:20: Missing field number.\n"
+ "2:2: Expected \"required\", \"optional\", or \"repeated\".\n"
+ "2:2: Expected type name.\n"
+ "3:25: Expected \";\".\n");
+}
+
+TEST_F(ParseErrorTest, EofInAggregateValue) {
+ ExpectHasErrors(
+ "option (fileopt) = { i:100\n",
+ "1:0: Unexpected end of stream while parsing aggregate value.\n");
+}
+
+// -------------------------------------------------------------------
+// Enum errors
+
+TEST_F(ParseErrorTest, EofInEnum) {
+ ExpectHasErrors(
+ "enum TestEnum {",
+ "0:15: Reached end of input in enum definition (missing '}').\n");
+}
+
+TEST_F(ParseErrorTest, EnumValueMissingNumber) {
+ ExpectHasErrors(
+ "enum TestEnum {\n"
+ " FOO;\n"
+ "}\n",
+ "1:5: Missing numeric value for enum constant.\n");
+}
+
+TEST_F(ParseErrorTest, EnumReservedStandaloneMaxNotAllowed) {
+ ExpectHasErrors(
+ "enum TestEnum {\n"
+ " FOO = 1;\n"
+ " reserved max;\n"
+ "}\n",
+ "2:11: Expected enum value or number range.\n");
+}
+
+TEST_F(ParseErrorTest, EnumReservedMixNameAndNumber) {
+ ExpectHasErrors(
+ "enum TestEnum {\n"
+ " FOO = 1;\n"
+ " reserved 10, \"foo\";\n"
+ "}\n",
+ "2:15: Expected enum number range.\n");
+}
+
+TEST_F(ParseErrorTest, EnumReservedPositiveNumberOutOfRange) {
+ ExpectHasErrors(
+ "enum TestEnum {\n"
+ "FOO = 1;\n"
+ " reserved 2147483648;\n"
+ "}\n",
+ "2:11: Integer out of range.\n");
+}
+
+TEST_F(ParseErrorTest, EnumReservedNegativeNumberOutOfRange) {
+ ExpectHasErrors(
+ "enum TestEnum {\n"
+ "FOO = 1;\n"
+ " reserved -2147483649;\n"
+ "}\n",
+ "2:12: Integer out of range.\n");
+}
+
+TEST_F(ParseErrorTest, EnumReservedMissingQuotes) {
+ ExpectHasErrors(
+ "enum TestEnum {\n"
+ " FOO = 1;\n"
+ " reserved foo;\n"
+ "}\n",
+ "2:11: Expected enum value or number range.\n");
+}
+
+// -------------------------------------------------------------------
+// Reserved field number errors
+
+TEST_F(ParseErrorTest, ReservedStandaloneMaxNotAllowed) {
+ ExpectHasErrors(
+ "message Foo {\n"
+ " reserved max;\n"
+ "}\n",
+ "1:11: Expected field name or number range.\n");
+}
+
+TEST_F(ParseErrorTest, ReservedMixNameAndNumber) {
+ ExpectHasErrors(
+ "message Foo {\n"
+ " reserved 10, \"foo\";\n"
+ "}\n",
+ "1:15: Expected field number range.\n");
+}
+
+TEST_F(ParseErrorTest, ReservedMissingQuotes) {
+ ExpectHasErrors(
+ "message Foo {\n"
+ " reserved foo;\n"
+ "}\n",
+ "1:11: Expected field name or number range.\n");
+}
+
+TEST_F(ParseErrorTest, ReservedNegativeNumber) {
+ ExpectHasErrors(
+ "message Foo {\n"
+ " reserved -10;\n"
+ "}\n",
+ "1:11: Expected field name or number range.\n");
+}
+
+TEST_F(ParseErrorTest, ReservedNumberOutOfRange) {
+ ExpectHasErrors(
+ "message Foo {\n"
+ " reserved 2147483648;\n"
+ "}\n",
+ "1:11: Integer out of range.\n");
+}
+
+// -------------------------------------------------------------------
+// Service errors
+
+TEST_F(ParseErrorTest, EofInService) {
+ ExpectHasErrors(
+ "service TestService {",
+ "0:21: Reached end of input in service definition (missing '}').\n");
+}
+
+TEST_F(ParseErrorTest, ServiceMethodPrimitiveParams) {
+ ExpectHasErrors(
+ "service TestService {\n"
+ " rpc Foo(int32) returns (string);\n"
+ "}\n",
+ "1:10: Expected message type.\n"
+ "1:26: Expected message type.\n");
+}
+
+
+TEST_F(ParseErrorTest, EofInMethodOptions) {
+ ExpectHasErrors(
+ "service TestService {\n"
+ " rpc Foo(Bar) returns(Bar) {",
+ "1:29: Reached end of input in method options (missing '}').\n"
+ "1:29: Reached end of input in service definition (missing '}').\n");
+}
+
+
+TEST_F(ParseErrorTest, PrimitiveMethodInput) {
+ ExpectHasErrors(
+ "service TestService {\n"
+ " rpc Foo(int32) returns(Bar);\n"
+ "}\n",
+ "1:10: Expected message type.\n");
+}
+
+
+TEST_F(ParseErrorTest, MethodOptionTypeError) {
+ // This used to cause an infinite loop.
+ ExpectHasErrors(
+ "message Baz {}\n"
+ "service Foo {\n"
+ " rpc Bar(Baz) returns(Baz) { option invalid syntax; }\n"
+ "}\n",
+ "2:45: Expected \"=\".\n");
+}
+
+
+// -------------------------------------------------------------------
+// Import and package errors
+
+TEST_F(ParseErrorTest, ImportNotQuoted) {
+ ExpectHasErrors("import foo;\n",
+ "0:7: Expected a string naming the file to import.\n");
+}
+
+TEST_F(ParseErrorTest, MultiplePackagesInFile) {
+ ExpectHasErrors(
+ "package foo;\n"
+ "package bar;\n",
+ "1:0: Multiple package definitions.\n");
+}
+
+// ===================================================================
+// Test that errors detected by DescriptorPool correctly report line and
+// column numbers. We have one test for every call to RecordLocation() in
+// parser.cc.
+
+typedef ParserTest ParserValidationErrorTest;
+
+TEST_F(ParserValidationErrorTest, PackageNameError) {
+ // Create another file which defines symbol "foo".
+ FileDescriptorProto other_file;
+ other_file.set_name("bar.proto");
+ other_file.add_message_type()->set_name("foo");
+ EXPECT_TRUE(pool_.BuildFile(other_file) != NULL);
+
+ // Now try to define it as a package.
+ ExpectHasValidationErrors(
+ "package foo.bar;",
+ "0:0: \"foo\" is already defined (as something other than a package) "
+ "in file \"bar.proto\".\n");
+}
+
+TEST_F(ParserValidationErrorTest, ImportUnloadedError) {
+ ExpectHasValidationErrors(
+ "package test;\n"
+ "\n"
+ "import \"unloaded.proto\";",
+ "2:0: Import \"unloaded.proto\" has not been loaded.\n");
+}
+
+TEST_F(ParserValidationErrorTest, ImportTwice) {
+ FileDescriptorProto other_file;
+ other_file.set_name("bar.proto");
+ other_file.add_message_type()->set_name("foo");
+ EXPECT_TRUE(pool_.BuildFile(other_file) != nullptr);
+
+ ExpectHasValidationErrors(
+ "package test;\n"
+ "\n"
+ "import \"bar.proto\";\n"
+ " import \"bar.proto\";",
+ "3:2: Import \"bar.proto\" was listed twice.\n");
+}
+
+TEST_F(ParserValidationErrorTest, DuplicateFileError) {
+ FileDescriptorProto other_file;
+ other_file.set_name("foo.proto");
+ EXPECT_TRUE(pool_.BuildFile(other_file) != nullptr);
+
+ ExpectHasValidationErrors(
+ "package test;", "0:0: A file with this name is already in the pool.\n");
+}
+
+TEST_F(ParserValidationErrorTest, MessageNameError) {
+ ExpectHasValidationErrors(
+ "message Foo {}\n"
+ "message Foo {}\n",
+ "1:8: \"Foo\" is already defined.\n");
+}
+
+TEST_F(ParserValidationErrorTest, FieldNameError) {
+ ExpectHasValidationErrors(
+ "message Foo {\n"
+ " optional int32 bar = 1;\n"
+ " optional int32 bar = 2;\n"
+ "}\n",
+ "2:17: \"bar\" is already defined in \"Foo\".\n");
+}
+
+TEST_F(ParserValidationErrorTest, FieldTypeError) {
+ ExpectHasValidationErrors(
+ "message Foo {\n"
+ " optional Baz bar = 1;\n"
+ "}\n",
+ "1:11: \"Baz\" is not defined.\n");
+}
+
+TEST_F(ParserValidationErrorTest, FieldNumberError) {
+ ExpectHasValidationErrors(
+ "message Foo {\n"
+ " optional int32 bar = 0;\n"
+ "}\n",
+ "1:23: Field numbers must be positive integers.\n");
+}
+
+TEST_F(ParserValidationErrorTest, FieldExtendeeError) {
+ ExpectHasValidationErrors("extend Baz { optional int32 bar = 1; }\n",
+ "0:7: \"Baz\" is not defined.\n");
+}
+
+TEST_F(ParserValidationErrorTest, ExtensionJsonNameError) {
+ ExpectHasValidationErrors(
+ "message TestMessage {\n"
+ " extensions 1 to 100;\n"
+ "}\n"
+ "extend TestMessage {\n"
+ " optional int32 foo = 12 [json_name = \"bar\"];\n"
+ "}",
+ "4:27: option json_name is not allowed on extension fields.\n");
+}
+
+TEST_F(ParserValidationErrorTest, FieldDefaultValueError) {
+ ExpectHasValidationErrors(
+ "enum Baz { QUX = 1; }\n"
+ "message Foo {\n"
+ " optional Baz bar = 1 [default=NO_SUCH_VALUE];\n"
+ "}\n",
+ "2:32: Enum type \"Baz\" has no value named \"NO_SUCH_VALUE\".\n");
+}
+
+TEST_F(ParserValidationErrorTest, FileOptionNameError) {
+ ExpectHasValidationErrors(
+ "option foo = 5;",
+ "0:7: Option \"foo\" unknown. Ensure that your proto definition file "
+ "imports the proto which defines the option.\n");
+}
+
+TEST_F(ParserValidationErrorTest, FileOptionValueError) {
+ ExpectHasValidationErrors(
+ "option java_outer_classname = 5;",
+ "0:30: Value must be quoted string for string option "
+ "\"google.protobuf.FileOptions.java_outer_classname\".\n");
+}
+
+TEST_F(ParserValidationErrorTest, FieldOptionNameError) {
+ ExpectHasValidationErrors(
+ "message Foo {\n"
+ " optional bool bar = 1 [foo=1];\n"
+ "}\n",
+ "1:25: Option \"foo\" unknown. Ensure that your proto definition file "
+ "imports the proto which defines the option.\n");
+}
+
+TEST_F(ParserValidationErrorTest, FieldOptionValueError) {
+ ExpectHasValidationErrors(
+ "message Foo {\n"
+ " optional int32 bar = 1 [ctype=1];\n"
+ "}\n",
+ "1:32: Value must be identifier for enum-valued option "
+ "\"google.protobuf.FieldOptions.ctype\".\n");
+}
+
+TEST_F(ParserValidationErrorTest, ExtensionRangeNumberError) {
+ ExpectHasValidationErrors(
+ "message Foo {\n"
+ " extensions 0;\n"
+ "}\n",
+ "1:13: Extension numbers must be positive integers.\n");
+}
+
+TEST_F(ParserValidationErrorTest, Proto3ExtensionError) {
+ ExpectHasValidationErrors(
+ "syntax = 'proto3';\n"
+ "message Foo { \n"
+ " extensions 100 to 199;\n"
+ "}\n"
+ "extend Foo { string foo = 101; }\n",
+ "4:7: Extensions in proto3 are only allowed for defining options.\n"
+ "2:13: Extension ranges are not allowed in proto3.\n");
+}
+
+TEST_F(ParserValidationErrorTest, Proto3MessageSet) {
+ ExpectHasValidationErrors(
+ "syntax = 'proto3';\n"
+ "message Foo { \n"
+ " option message_set_wire_format = true;\n"
+ "}\n",
+ "1:8: MessageSet is not supported in proto3.\n");
+}
+
+TEST_F(ParserValidationErrorTest, Proto3Required) {
+ ExpectHasValidationErrors(
+ "syntax = 'proto3';\n"
+ "message Foo { \n"
+ " required int32 field = 1;"
+ "}\n",
+ "2:11: Required fields are not allowed in proto3.\n");
+}
+
+TEST_F(ParserValidationErrorTest, Proto3Default) {
+ ExpectHasValidationErrors(
+ "syntax = 'proto3';\n"
+ "message Foo { \n"
+ " int32 field = 1 [default = 12];"
+ "}\n",
+ "2:29: Explicit default values are not allowed in proto3.\n");
+}
+
+TEST_F(ParserValidationErrorTest, Proto3JsonConflictError) {
+ ExpectHasValidationErrors(
+ "syntax = 'proto3';\n"
+ "message TestMessage {\n"
+ " uint32 foo = 1;\n"
+ " uint32 Foo = 2;\n"
+ "}\n",
+ "3:9: The JSON camel-case name of field \"Foo\" conflicts with field "
+ "\"foo\". This is not allowed in proto3.\n");
+}
+
+TEST_F(ParserValidationErrorTest, EnumNameError) {
+ ExpectHasValidationErrors(
+ "enum Foo {A = 1;}\n"
+ "enum Foo {B = 1;}\n",
+ "1:5: \"Foo\" is already defined.\n");
+}
+
+TEST_F(ParserValidationErrorTest, Proto3EnumError) {
+ ExpectHasValidationErrors(
+ "syntax = 'proto3';\n"
+ "enum Foo {A = 1;}\n",
+ "1:14: The first enum value must be zero in proto3.\n");
+}
+
+TEST_F(ParserValidationErrorTest, EnumValueNameError) {
+ ExpectHasValidationErrors(
+ "enum Foo {\n"
+ " BAR = 1;\n"
+ " BAR = 1;\n"
+ "}\n",
+ "2:2: \"BAR\" is already defined.\n");
+}
+
+TEST_F(ParserValidationErrorTest, EnumValueAliasError) {
+ ExpectHasValidationErrors(
+ "enum Foo {\n"
+ " BAR = 1;\n"
+ " BAZ = 1;\n"
+ "}\n",
+ "2:8: \"BAZ\" uses the same enum value as \"BAR\". If this is "
+ "intended, set 'option allow_alias = true;' to the enum "
+ "definition.\n");
+}
+
+TEST_F(ParserValidationErrorTest, ExplicitlyMapEntryError) {
+ ExpectHasValidationErrors(
+ "message Foo {\n"
+ " message ValueEntry {\n"
+ " option map_entry = true;\n"
+ " optional int32 key = 1;\n"
+ " optional int32 value = 2;\n"
+ " extensions 99 to 999;\n"
+ " }\n"
+ " repeated ValueEntry value = 1;\n"
+ "}",
+ "7:11: map_entry should not be set explicitly. Use "
+ "map<KeyType, ValueType> instead.\n");
+}
+
+TEST_F(ParserValidationErrorTest, ServiceNameError) {
+ ExpectHasValidationErrors(
+ "service Foo {}\n"
+ "service Foo {}\n",
+ "1:8: \"Foo\" is already defined.\n");
+}
+
+TEST_F(ParserValidationErrorTest, MethodNameError) {
+ ExpectHasValidationErrors(
+ "message Baz {}\n"
+ "service Foo {\n"
+ " rpc Bar(Baz) returns(Baz);\n"
+ " rpc Bar(Baz) returns(Baz);\n"
+ "}\n",
+ "3:6: \"Bar\" is already defined in \"Foo\".\n");
+}
+
+
+TEST_F(ParserValidationErrorTest, MethodInputTypeError) {
+ ExpectHasValidationErrors(
+ "message Baz {}\n"
+ "service Foo {\n"
+ " rpc Bar(Qux) returns(Baz);\n"
+ "}\n",
+ "2:10: \"Qux\" is not defined.\n");
+}
+
+
+TEST_F(ParserValidationErrorTest, MethodOutputTypeError) {
+ ExpectHasValidationErrors(
+ "message Baz {}\n"
+ "service Foo {\n"
+ " rpc Bar(Baz) returns(Qux);\n"
+ "}\n",
+ "2:23: \"Qux\" is not defined.\n");
+}
+
+
+TEST_F(ParserValidationErrorTest, ResolvedUndefinedError) {
+ // Create another file which defines symbol ".base.bar".
+ FileDescriptorProto other_file;
+ other_file.set_name("base.proto");
+ other_file.set_package("base");
+ other_file.add_message_type()->set_name("bar");
+ EXPECT_TRUE(pool_.BuildFile(other_file) != NULL);
+
+ // Define "foo.base" and try "base.bar".
+ // "base.bar" is resolved to "foo.base.bar" which is not defined.
+ ExpectHasValidationErrors(
+ "package foo.base;\n"
+ "import \"base.proto\";\n"
+ "message qux {\n"
+ " optional base.bar baz = 1;\n"
+ " optional .base.bar quz = 2;\n"
+ "}\n",
+ "3:11: \"base.bar\" is resolved to \"foo.base.bar\","
+ " which is not defined. The innermost scope is searched first "
+ "in name resolution. Consider using a leading '.'(i.e., \".base.bar\")"
+ " to start from the outermost scope.\n");
+}
+
+TEST_F(ParserValidationErrorTest, ResovledUndefinedOptionError) {
+ // Build descriptor message in test pool
+ FileDescriptorProto descriptor_proto;
+ DescriptorProto::descriptor()->file()->CopyTo(&descriptor_proto);
+ ASSERT_TRUE(pool_.BuildFile(descriptor_proto) != NULL);
+
+ // base2.proto:
+ // package baz
+ // import net/proto2/proto/descriptor.proto
+ // message Bar { optional int32 foo = 1; }
+ // extend FileOptions { optional Bar bar = 7672757; }
+ FileDescriptorProto other_file;
+ other_file.set_name("base2.proto");
+ other_file.set_package("baz");
+ other_file.add_dependency();
+ other_file.set_dependency(0, descriptor_proto.name());
+
+ DescriptorProto* message(other_file.add_message_type());
+ message->set_name("Bar");
+ FieldDescriptorProto* field(message->add_field());
+ field->set_name("foo");
+ field->set_number(1);
+ field->set_label(FieldDescriptorProto::LABEL_OPTIONAL);
+ field->set_type(FieldDescriptorProto::TYPE_INT32);
+
+ FieldDescriptorProto* extension(other_file.add_extension());
+ extension->set_name("bar");
+ extension->set_number(7672757);
+ extension->set_label(FieldDescriptorProto::LABEL_OPTIONAL);
+ extension->set_type(FieldDescriptorProto::TYPE_MESSAGE);
+ extension->set_type_name("Bar");
+ extension->set_extendee("google.protobuf.FileOptions");
+
+ EXPECT_TRUE(pool_.BuildFile(other_file) != NULL);
+
+ // qux.proto:
+ // package qux.baz
+ // option (baz.bar).foo = 1;
+ //
+ // Although "baz.bar" is already defined, the lookup code will try
+ // "qux.baz.bar", since it's the match from the innermost scope,
+ // which will cause a symbol not defined error.
+ ExpectHasValidationErrors(
+ "package qux.baz;\n"
+ "import \"base2.proto\";\n"
+ "option (baz.bar).foo = 1;\n",
+ "2:7: Option \"(baz.bar)\" is resolved to \"(qux.baz.bar)\","
+ " which is not defined. The innermost scope is searched first "
+ "in name resolution. Consider using a leading '.'(i.e., \"(.baz.bar)\")"
+ " to start from the outermost scope.\n");
+}
+
+// ===================================================================
+// Test that the output from FileDescriptor::DebugString() (and all other
+// descriptor types) is parseable, and results in the same Descriptor
+// definitions again afoter parsing (note, however, that the order of messages
+// cannot be guaranteed to be the same)
+
+typedef ParserTest ParseDescriptorDebugTest;
+
+class CompareDescriptorNames {
+ public:
+ bool operator()(const DescriptorProto* left,
+ const DescriptorProto* right) const {
+ return left->name() < right->name();
+ }
+};
+
+// Sorts nested DescriptorProtos of a DescriptoProto, by name.
+void SortMessages(DescriptorProto* descriptor_proto) {
+ int size = descriptor_proto->nested_type_size();
+ // recursively sort; we can't guarantee the order of nested messages either
+ for (int i = 0; i < size; ++i) {
+ SortMessages(descriptor_proto->mutable_nested_type(i));
+ }
+ DescriptorProto** data =
+ descriptor_proto->mutable_nested_type()->mutable_data();
+ std::sort(data, data + size, CompareDescriptorNames());
+}
+
+// Sorts DescriptorProtos belonging to a FileDescriptorProto, by name.
+void SortMessages(FileDescriptorProto* file_descriptor_proto) {
+ int size = file_descriptor_proto->message_type_size();
+ // recursively sort; we can't guarantee the order of nested messages either
+ for (int i = 0; i < size; ++i) {
+ SortMessages(file_descriptor_proto->mutable_message_type(i));
+ }
+ DescriptorProto** data =
+ file_descriptor_proto->mutable_message_type()->mutable_data();
+ std::sort(data, data + size, CompareDescriptorNames());
+}
+
+// Strips the message and enum field type names for comparison purpose only.
+void StripFieldTypeName(DescriptorProto* proto) {
+ for (int i = 0; i < proto->field_size(); ++i) {
+ std::string type_name = proto->field(i).type_name();
+ std::string::size_type pos = type_name.find_last_of('.');
+ if (pos != std::string::npos) {
+ proto->mutable_field(i)->mutable_type_name()->assign(
+ type_name.begin() + pos + 1, type_name.end());
+ }
+ }
+ for (int i = 0; i < proto->nested_type_size(); ++i) {
+ StripFieldTypeName(proto->mutable_nested_type(i));
+ }
+}
+
+void StripFieldTypeName(FileDescriptorProto* file_proto) {
+ for (int i = 0; i < file_proto->message_type_size(); ++i) {
+ StripFieldTypeName(file_proto->mutable_message_type(i));
+ }
+}
+
+TEST_F(ParseDescriptorDebugTest, TestAllDescriptorTypes) {
+ const FileDescriptor* original_file =
+ protobuf_unittest::TestAllTypes::descriptor()->file();
+ FileDescriptorProto expected;
+ original_file->CopyTo(&expected);
+
+ // Get the DebugString of the unittest.proto FileDecriptor, which includes
+ // all other descriptor types
+ std::string debug_string = original_file->DebugString();
+
+ // Parse the debug string
+ SetupParser(debug_string.c_str());
+ FileDescriptorProto parsed;
+ parser_->Parse(input_.get(), &parsed);
+ EXPECT_EQ(io::Tokenizer::TYPE_END, input_->current().type);
+ ASSERT_EQ("", error_collector_.text_) << "Failed to parse:\n" << debug_string;
+
+ // We now have a FileDescriptorProto, but to compare with the expected we
+ // need to link to a FileDecriptor, then output back to a proto. We'll
+ // also need to give it the same name as the original.
+ parsed.set_name(
+ TestUtil::MaybeTranslatePath("net/proto2/internal/unittest.proto"));
+ // We need the imported dependency before we can build our parsed proto
+ const FileDescriptor* public_import =
+ protobuf_unittest_import::PublicImportMessage::descriptor()->file();
+ FileDescriptorProto public_import_proto;
+ public_import->CopyTo(&public_import_proto);
+ ASSERT_TRUE(pool_.BuildFile(public_import_proto) != NULL);
+ const FileDescriptor* import =
+ protobuf_unittest_import::ImportMessage::descriptor()->file();
+ FileDescriptorProto import_proto;
+ import->CopyTo(&import_proto);
+ ASSERT_TRUE(pool_.BuildFile(import_proto) != NULL);
+ const FileDescriptor* actual = pool_.BuildFile(parsed);
+ parsed.Clear();
+ ASSERT_TRUE(actual != NULL) << "Failed to validate:\n" << debug_string;
+ actual->CopyTo(&parsed);
+ ASSERT_TRUE(actual != NULL);
+
+ // The messages might be in different orders, making them hard to compare.
+ // So, sort the messages in the descriptor protos (including nested messages,
+ // recursively).
+ SortMessages(&expected);
+ SortMessages(&parsed);
+
+ // I really wanted to use StringDiff here for the debug output on fail,
+ // but the strings are too long for it, and if I increase its max size,
+ // we get a memory allocation failure :(
+ EXPECT_EQ(expected.DebugString(), parsed.DebugString());
+}
+
+TEST_F(ParseDescriptorDebugTest, TestCustomOptions) {
+ const FileDescriptor* original_file =
+ protobuf_unittest::AggregateMessage::descriptor()->file();
+ FileDescriptorProto expected;
+ original_file->CopyTo(&expected);
+
+ std::string debug_string = original_file->DebugString();
+
+ // Parse the debug string
+ SetupParser(debug_string.c_str());
+ FileDescriptorProto parsed;
+ parser_->Parse(input_.get(), &parsed);
+ EXPECT_EQ(io::Tokenizer::TYPE_END, input_->current().type);
+ ASSERT_EQ("", error_collector_.text_);
+
+ // We now have a FileDescriptorProto, but to compare with the expected we
+ // need to link to a FileDecriptor, then output back to a proto. We'll
+ // also need to give it the same name as the original.
+ parsed.set_name(original_file->name());
+
+ // unittest_custom_options.proto depends on descriptor.proto.
+ const FileDescriptor* import = FileDescriptorProto::descriptor()->file();
+ FileDescriptorProto import_proto;
+ import->CopyTo(&import_proto);
+ ASSERT_TRUE(pool_.BuildFile(import_proto) != NULL);
+
+ FileDescriptorProto any_import;
+ google::protobuf::Any::descriptor()->file()->CopyTo(&any_import);
+ ASSERT_TRUE(pool_.BuildFile(any_import) != nullptr);
+
+ const FileDescriptor* actual = pool_.BuildFile(parsed);
+ ASSERT_TRUE(actual != NULL);
+ parsed.Clear();
+ actual->CopyTo(&parsed);
+
+ // The messages might be in different orders, making them hard to compare.
+ // So, sort the messages in the descriptor protos (including nested messages,
+ // recursively).
+ SortMessages(&expected);
+ SortMessages(&parsed);
+
+ EXPECT_EQ(expected.DebugString(), parsed.DebugString());
+}
+
+// Ensure that DebugStringWithOptions(), with |include_comments| set to true,
+// includes comments from the original parser input in all of the appropriate
+// places.
+TEST_F(ParseDescriptorDebugTest, TestCommentsInDebugString) {
+ SetupParser(
+ "// Detached comment before syntax.\n"
+ "\n"
+ "// Syntax comment.\n"
+ "syntax = \"proto2\";\n"
+ "\n"
+ "// Detached comment before package.\n"
+ "\n"
+ "// Package comment.\n"
+ "package comment_test;\n"
+ "\n"
+ "// Detached comment before TestMessage1.\n"
+ "\n"
+ "// Message comment.\n"
+ "//\n"
+ "// More detail in message comment.\n"
+ "message TestMessage1 {\n"
+ "\n"
+ " // Detached comment before foo.\n"
+ "\n"
+ " // Field comment.\n"
+ " optional int32 foo = 1;\n"
+ "\n"
+ " // Detached comment before NestedMessage.\n"
+ "\n"
+ " // Nested-message comment.\n"
+ " message NestedMessage {\n"
+ " optional int32 bar = 1;\n"
+ " }\n"
+ "}\n"
+ "\n"
+ "// Detached comment before MyEnumType.\n"
+ "\n"
+ "// Enum comment.\n"
+ "enum MyEnumType {\n"
+ "\n"
+ " // Detached comment before ASDF.\n"
+ "\n"
+ " // Enum-value comment.\n"
+ " ASDF = 1;\n"
+ "}\n"
+ "\n"
+ "// Detached comment before MyService.\n"
+ "\n"
+ "// Service comment.\n"
+ "service MyService {\n"
+ "\n"
+ " // Detached comment before MyRPCCall.\n"
+ "\n"
+ " // RPC comment.\n"
+ " rpc MyRPCCall(TestMessage1) returns (TestMessage1) { }\n"
+ "}\n");
+
+ FileDescriptorProto parsed_desc;
+ parsed_desc.set_name("foo.proto");
+ SourceLocationTable source_locations;
+ parser_->RecordSourceLocationsTo(&source_locations);
+ parser_->Parse(input_.get(), &parsed_desc);
+ EXPECT_EQ(io::Tokenizer::TYPE_END, input_->current().type);
+ ASSERT_EQ("", error_collector_.text_);
+
+ // We need to import the FileDescriptorProto to get a FileDescriptor.
+ MockValidationErrorCollector collector(source_locations, &error_collector_);
+ const FileDescriptor* descriptor =
+ pool_.BuildFileCollectingErrors(parsed_desc, &collector);
+ ASSERT_TRUE(descriptor != NULL);
+
+ // Ensure that each of the comments appears somewhere in the DebugString().
+ // We don't test the exact comment placement or formatting, because we do not
+ // want to be too fragile here.
+ const char* expected_comments[] = {
+ "Detached comment before syntax.",
+ "Syntax comment.",
+ "Detached comment before package.",
+ "Package comment.",
+ "Detached comment before TestMessage1.",
+ "Message comment.",
+ "More detail in message comment.",
+ "Detached comment before foo.",
+ "Field comment",
+ "Detached comment before NestedMessage.",
+ "Nested-message comment",
+ "Detached comment before MyEnumType.",
+ "Enum comment",
+ "Detached comment before ASDF.",
+ "Enum-value comment",
+ "Detached comment before MyService.",
+ "Service comment",
+ "Detached comment before MyRPCCall.",
+ "RPC comment",
+ };
+
+ DebugStringOptions debug_string_options;
+ debug_string_options.include_comments = true;
+
+ {
+ const std::string debug_string =
+ descriptor->DebugStringWithOptions(debug_string_options);
+
+ for (int i = 0; i < GOOGLE_ARRAYSIZE(expected_comments); ++i) {
+ std::string::size_type found_pos =
+ debug_string.find(expected_comments[i]);
+ EXPECT_TRUE(found_pos != std::string::npos)
+ << "\"" << expected_comments[i] << "\" not found.";
+ }
+
+ // Result of DebugStringWithOptions should be parseable.
+ SetupParser(debug_string.c_str());
+ FileDescriptorProto parsed;
+ parser_->Parse(input_.get(), &parsed);
+ EXPECT_EQ(io::Tokenizer::TYPE_END, input_->current().type);
+ ASSERT_EQ("", error_collector_.text_) << "Failed to parse:\n"
+ << debug_string;
+ }
+
+}
+
+TEST_F(ParseDescriptorDebugTest, TestMaps) {
+ SetupParser(
+ "syntax = \"proto3\"; "
+ "message Foo { "
+ " message Bar { } "
+ " map<int32, Bar> enum_message_map = 1; "
+ " map<string, float> primitive_map = 2; "
+ "} ");
+ FileDescriptorProto original;
+ EXPECT_TRUE(parser_->Parse(input_.get(), &original));
+ original.set_name("foo.proto");
+ const FileDescriptor* file = pool_.BuildFile(original);
+ ASSERT_TRUE(file != NULL);
+
+ // Make sure the debug string uses map syntax and does not have the auto
+ // generated entry.
+ std::string debug_string = file->DebugString();
+ EXPECT_TRUE(debug_string.find("map<") != std::string::npos);
+ EXPECT_TRUE(debug_string.find("option map_entry") == std::string::npos);
+ EXPECT_TRUE(debug_string.find("MapEntry") == std::string::npos);
+
+ // Make sure the descriptor debug string is parsable.
+ FileDescriptorProto parsed;
+ SetupParser(debug_string.c_str());
+ parsed.set_name("foo.proto");
+ ASSERT_TRUE(parser_->Parse(input_.get(), &parsed));
+
+ original.clear_source_code_info();
+ parsed.clear_source_code_info();
+ StripFieldTypeName(&original);
+ StripFieldTypeName(&parsed);
+ EXPECT_EQ(original.DebugString(), parsed.DebugString());
+}
+
+// ===================================================================
+// SourceCodeInfo tests.
+
+// Follows a path -- as defined by SourceCodeInfo.Location.path -- from a
+// message to a particular sub-field.
+// * If the target is itself a message, sets *output_message to point at it,
+// *output_field to NULL, and *output_index to -1.
+// * Otherwise, if the target is an element of a repeated field, sets
+// *output_message to the containing message, *output_field to the descriptor
+// of the field, and *output_index to the index of the element.
+// * Otherwise, the target is a field (possibly a repeated field, but not any
+// one element). Sets *output_message to the containing message,
+// *output_field to the descriptor of the field, and *output_index to -1.
+// Returns true if the path was valid, false otherwise. A gTest failure is
+// recorded before returning false.
+bool FollowPath(const Message& root, const int* path_begin, const int* path_end,
+ const Message** output_message,
+ const FieldDescriptor** output_field, int* output_index) {
+ if (path_begin == path_end) {
+ // Path refers to this whole message.
+ *output_message = &root;
+ *output_field = NULL;
+ *output_index = -1;
+ return true;
+ }
+
+ const Descriptor* descriptor = root.GetDescriptor();
+ const Reflection* reflection = root.GetReflection();
+
+ const FieldDescriptor* field = descriptor->FindFieldByNumber(*path_begin);
+
+ if (field == NULL) {
+ ADD_FAILURE() << descriptor->name()
+ << " has no field number: " << *path_begin;
+ return false;
+ }
+
+ ++path_begin;
+
+ if (field->is_repeated()) {
+ if (path_begin == path_end) {
+ // Path refers to the whole repeated field.
+ *output_message = &root;
+ *output_field = field;
+ *output_index = -1;
+ return true;
+ }
+
+ int index = *path_begin++;
+ int size = reflection->FieldSize(root, field);
+
+ if (index >= size) {
+ ADD_FAILURE() << descriptor->name() << "." << field->name()
+ << " has size " << size
+ << ", but path contained index: " << index;
+ return false;
+ }
+
+ if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+ // Descend into child message.
+ const Message& child = reflection->GetRepeatedMessage(root, field, index);
+ return FollowPath(child, path_begin, path_end, output_message,
+ output_field, output_index);
+ } else if (path_begin == path_end) {
+ // Path refers to this element.
+ *output_message = &root;
+ *output_field = field;
+ *output_index = index;
+ return true;
+ } else {
+ ADD_FAILURE() << descriptor->name() << "." << field->name()
+ << " is not a message; cannot descend into it.";
+ return false;
+ }
+ } else {
+ if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+ const Message& child = reflection->GetMessage(root, field);
+ return FollowPath(child, path_begin, path_end, output_message,
+ output_field, output_index);
+ } else if (path_begin == path_end) {
+ // Path refers to this field.
+ *output_message = &root;
+ *output_field = field;
+ *output_index = -1;
+ return true;
+ } else {
+ ADD_FAILURE() << descriptor->name() << "." << field->name()
+ << " is not a message; cannot descend into it.";
+ return false;
+ }
+ }
+}
+
+// Check if two spans are equal.
+bool CompareSpans(const RepeatedField<int>& span1,
+ const RepeatedField<int>& span2) {
+ if (span1.size() != span2.size()) return false;
+ for (int i = 0; i < span1.size(); i++) {
+ if (span1.Get(i) != span2.Get(i)) return false;
+ }
+ return true;
+}
+
+// Test fixture for source info tests, which check that source locations are
+// recorded correctly in FileDescriptorProto.source_code_info.location.
+class SourceInfoTest : public ParserTest {
+ protected:
+ // The parsed file (initialized by Parse()).
+ FileDescriptorProto file_;
+
+ // Parse the given text as a .proto file and populate the spans_ map with
+ // all the source location spans in its SourceCodeInfo table.
+ bool Parse(const char* text) {
+ ExtractMarkers(text);
+ SetupParser(text_without_markers_.c_str());
+ if (!parser_->Parse(input_.get(), &file_)) {
+ return false;
+ }
+
+ const SourceCodeInfo& source_info = file_.source_code_info();
+ for (int i = 0; i < source_info.location_size(); i++) {
+ const SourceCodeInfo::Location& location = source_info.location(i);
+ const Message* descriptor_proto = NULL;
+ const FieldDescriptor* field = NULL;
+ int index = 0;
+ if (!FollowPath(file_, location.path().begin(), location.path().end(),
+ &descriptor_proto, &field, &index)) {
+ return false;
+ }
+
+ spans_.insert(
+ std::make_pair(SpanKey(*descriptor_proto, field, index), &location));
+ }
+
+ return true;
+ }
+
+ void TearDown() override {
+ EXPECT_TRUE(spans_.empty()) << "Forgot to call HasSpan() for:\n"
+ << spans_.begin()->second->DebugString();
+ }
+
+ // -----------------------------------------------------------------
+ // HasSpan() checks that the span of source code delimited by the given
+ // tags (comments) correspond via the SourceCodeInfo table to the given
+ // part of the FileDescriptorProto. (If unclear, look at the actual tests;
+ // it should quickly become obvious.)
+
+ bool HasSpan(char start_marker, char end_marker,
+ const Message& descriptor_proto) {
+ return HasSpanWithComment(start_marker, end_marker, descriptor_proto, NULL,
+ -1, NULL, NULL, NULL);
+ }
+
+ bool HasSpanWithComment(char start_marker, char end_marker,
+ const Message& descriptor_proto,
+ const char* expected_leading_comments,
+ const char* expected_trailing_comments,
+ const char* expected_leading_detached_comments) {
+ return HasSpanWithComment(start_marker, end_marker, descriptor_proto, NULL,
+ -1, expected_leading_comments,
+ expected_trailing_comments,
+ expected_leading_detached_comments);
+ }
+
+ bool HasSpan(char start_marker, char end_marker,
+ const Message& descriptor_proto, const std::string& field_name) {
+ return HasSpan(start_marker, end_marker, descriptor_proto, field_name, -1);
+ }
+
+ bool HasSpan(char start_marker, char end_marker,
+ const Message& descriptor_proto, const std::string& field_name,
+ int index) {
+ return HasSpan(start_marker, end_marker, descriptor_proto, field_name,
+ index, NULL, NULL, NULL);
+ }
+
+ bool HasSpan(char start_marker, char end_marker,
+ const Message& descriptor_proto, const std::string& field_name,
+ int index, const char* expected_leading_comments,
+ const char* expected_trailing_comments,
+ const char* expected_leading_detached_comments) {
+ const FieldDescriptor* field =
+ descriptor_proto.GetDescriptor()->FindFieldByName(field_name);
+ if (field == NULL) {
+ ADD_FAILURE() << descriptor_proto.GetDescriptor()->name()
+ << " has no such field: " << field_name;
+ return false;
+ }
+
+ return HasSpanWithComment(start_marker, end_marker, descriptor_proto, field,
+ index, expected_leading_comments,
+ expected_trailing_comments,
+ expected_leading_detached_comments);
+ }
+
+ bool HasSpan(const Message& descriptor_proto) {
+ return HasSpanWithComment('\0', '\0', descriptor_proto, NULL, -1, NULL,
+ NULL, NULL);
+ }
+
+ bool HasSpan(const Message& descriptor_proto, const std::string& field_name) {
+ return HasSpan('\0', '\0', descriptor_proto, field_name, -1);
+ }
+
+ bool HasSpanWithComment(char start_marker, char end_marker,
+ const Message& descriptor_proto,
+ const FieldDescriptor* field, int index,
+ const char* expected_leading_comments,
+ const char* expected_trailing_comments,
+ const char* expected_leading_detached_comments) {
+ std::pair<SpanMap::iterator, SpanMap::iterator> range =
+ spans_.equal_range(SpanKey(descriptor_proto, field, index));
+
+ if (start_marker == '\0') {
+ if (range.first == range.second) {
+ return false;
+ } else {
+ spans_.erase(range.first);
+ return true;
+ }
+ } else {
+ std::pair<int, int> start_pos = FindOrDie(markers_, start_marker);
+ std::pair<int, int> end_pos = FindOrDie(markers_, end_marker);
+
+ RepeatedField<int> expected_span;
+ expected_span.Add(start_pos.first);
+ expected_span.Add(start_pos.second);
+ if (end_pos.first != start_pos.first) {
+ expected_span.Add(end_pos.first);
+ }
+ expected_span.Add(end_pos.second);
+
+ for (SpanMap::iterator iter = range.first; iter != range.second; ++iter) {
+ if (CompareSpans(expected_span, iter->second->span())) {
+ if (expected_leading_comments == NULL) {
+ EXPECT_FALSE(iter->second->has_leading_comments());
+ } else {
+ EXPECT_TRUE(iter->second->has_leading_comments());
+ EXPECT_EQ(expected_leading_comments,
+ iter->second->leading_comments());
+ }
+ if (expected_trailing_comments == NULL) {
+ EXPECT_FALSE(iter->second->has_trailing_comments());
+ } else {
+ EXPECT_TRUE(iter->second->has_trailing_comments());
+ EXPECT_EQ(expected_trailing_comments,
+ iter->second->trailing_comments());
+ }
+ if (expected_leading_detached_comments == NULL) {
+ EXPECT_EQ(0, iter->second->leading_detached_comments_size());
+ } else {
+ EXPECT_EQ(
+ expected_leading_detached_comments,
+ Join(iter->second->leading_detached_comments(), "\n"));
+ }
+
+ spans_.erase(iter);
+ return true;
+ }
+ }
+
+ return false;
+ }
+ }
+
+ private:
+ struct SpanKey {
+ const Message* descriptor_proto;
+ const FieldDescriptor* field;
+ int index;
+
+ inline SpanKey() {}
+ inline SpanKey(const Message& descriptor_proto_param,
+ const FieldDescriptor* field_param, int index_param)
+ : descriptor_proto(&descriptor_proto_param),
+ field(field_param),
+ index(index_param) {}
+
+ inline bool operator<(const SpanKey& other) const {
+ if (descriptor_proto < other.descriptor_proto) return true;
+ if (descriptor_proto > other.descriptor_proto) return false;
+ if (field < other.field) return true;
+ if (field > other.field) return false;
+ return index < other.index;
+ }
+ };
+
+ typedef std::multimap<SpanKey, const SourceCodeInfo::Location*> SpanMap;
+ SpanMap spans_;
+ std::map<char, std::pair<int, int> > markers_;
+ std::string text_without_markers_;
+
+ void ExtractMarkers(const char* text) {
+ markers_.clear();
+ text_without_markers_.clear();
+ int line = 0;
+ int column = 0;
+ while (*text != '\0') {
+ if (*text == '$') {
+ ++text;
+ GOOGLE_CHECK_NE('\0', *text);
+ if (*text == '$') {
+ text_without_markers_ += '$';
+ ++column;
+ } else {
+ markers_[*text] = std::make_pair(line, column);
+ ++text;
+ GOOGLE_CHECK_EQ('$', *text);
+ }
+ } else if (*text == '\n') {
+ ++line;
+ column = 0;
+ text_without_markers_ += *text;
+ } else {
+ text_without_markers_ += *text;
+ ++column;
+ }
+ ++text;
+ }
+ }
+};
+
+TEST_F(SourceInfoTest, BasicFileDecls) {
+ EXPECT_TRUE(
+ Parse("$a$syntax = \"proto2\";$i$\n"
+ "$b$package foo.bar;$c$\n"
+ "$d$import \"baz.proto\";$e$\n"
+ "$f$import\"qux.proto\";$h$\n"
+ "$j$import $k$public$l$ \"bar.proto\";$m$\n"
+ "$n$import $o$weak$p$ \"bar.proto\";$q$\n"
+ "\n"
+ "// comment ignored\n"));
+
+ EXPECT_TRUE(HasSpan('a', 'q', file_));
+ EXPECT_TRUE(HasSpan('b', 'c', file_, "package"));
+ EXPECT_TRUE(HasSpan('d', 'e', file_, "dependency", 0));
+ EXPECT_TRUE(HasSpan('f', 'h', file_, "dependency", 1));
+ EXPECT_TRUE(HasSpan('j', 'm', file_, "dependency", 2));
+ EXPECT_TRUE(HasSpan('k', 'l', file_, "public_dependency", 0));
+ EXPECT_TRUE(HasSpan('n', 'q', file_, "dependency", 3));
+ EXPECT_TRUE(HasSpan('o', 'p', file_, "weak_dependency", 0));
+ EXPECT_TRUE(HasSpan('a', 'i', file_, "syntax"));
+}
+
+TEST_F(SourceInfoTest, Messages) {
+ EXPECT_TRUE(
+ Parse("$a$message $b$Foo$c$ {}$d$\n"
+ "$e$message $f$Bar$g$ {}$h$\n"));
+
+ EXPECT_TRUE(HasSpan('a', 'd', file_.message_type(0)));
+ EXPECT_TRUE(HasSpan('b', 'c', file_.message_type(0), "name"));
+ EXPECT_TRUE(HasSpan('e', 'h', file_.message_type(1)));
+ EXPECT_TRUE(HasSpan('f', 'g', file_.message_type(1), "name"));
+
+ // Ignore these.
+ EXPECT_TRUE(HasSpan(file_));
+}
+
+TEST_F(SourceInfoTest, Fields) {
+ EXPECT_TRUE(
+ Parse("message Foo {\n"
+ " $a$optional$b$ $c$int32$d$ $e$bar$f$ = $g$1$h$;$i$\n"
+ " $j$repeated$k$ $l$X.Y$m$ $n$baz$o$ = $p$2$q$;$r$\n"
+ "}\n"));
+
+ const FieldDescriptorProto& field1 = file_.message_type(0).field(0);
+ const FieldDescriptorProto& field2 = file_.message_type(0).field(1);
+
+ EXPECT_TRUE(HasSpan('a', 'i', field1));
+ EXPECT_TRUE(HasSpan('a', 'b', field1, "label"));
+ EXPECT_TRUE(HasSpan('c', 'd', field1, "type"));
+ EXPECT_TRUE(HasSpan('e', 'f', field1, "name"));
+ EXPECT_TRUE(HasSpan('g', 'h', field1, "number"));
+
+ EXPECT_TRUE(HasSpan('j', 'r', field2));
+ EXPECT_TRUE(HasSpan('j', 'k', field2, "label"));
+ EXPECT_TRUE(HasSpan('l', 'm', field2, "type_name"));
+ EXPECT_TRUE(HasSpan('n', 'o', field2, "name"));
+ EXPECT_TRUE(HasSpan('p', 'q', field2, "number"));
+
+ // Ignore these.
+ EXPECT_TRUE(HasSpan(file_));
+ EXPECT_TRUE(HasSpan(file_.message_type(0)));
+ EXPECT_TRUE(HasSpan(file_.message_type(0), "name"));
+}
+
+TEST_F(SourceInfoTest, Proto3Fields) {
+ EXPECT_TRUE(
+ Parse("syntax = \"proto3\";\n"
+ "message Foo {\n"
+ " $a$int32$b$ $c$bar$d$ = $e$1$f$;$g$\n"
+ " $h$repeated$i$ $j$X.Y$k$ $l$baz$m$ = $n$2$o$;$p$\n"
+ "}\n"));
+
+ const FieldDescriptorProto& field1 = file_.message_type(0).field(0);
+ const FieldDescriptorProto& field2 = file_.message_type(0).field(1);
+
+ EXPECT_TRUE(HasSpan('a', 'g', field1));
+ EXPECT_TRUE(HasSpan('a', 'b', field1, "type"));
+ EXPECT_TRUE(HasSpan('c', 'd', field1, "name"));
+ EXPECT_TRUE(HasSpan('e', 'f', field1, "number"));
+
+ EXPECT_TRUE(HasSpan('h', 'p', field2));
+ EXPECT_TRUE(HasSpan('h', 'i', field2, "label"));
+ EXPECT_TRUE(HasSpan('j', 'k', field2, "type_name"));
+ EXPECT_TRUE(HasSpan('l', 'm', field2, "name"));
+ EXPECT_TRUE(HasSpan('n', 'o', field2, "number"));
+
+ // Ignore these.
+ EXPECT_TRUE(HasSpan(file_));
+ EXPECT_TRUE(HasSpan(file_, "syntax"));
+ EXPECT_TRUE(HasSpan(file_.message_type(0)));
+ EXPECT_TRUE(HasSpan(file_.message_type(0), "name"));
+}
+
+TEST_F(SourceInfoTest, Extensions) {
+ EXPECT_TRUE(
+ Parse("$a$extend $b$Foo$c$ {\n"
+ " $d$optional$e$ int32 bar = 1;$f$\n"
+ " $g$repeated$h$ X.Y baz = 2;$i$\n"
+ "}$j$\n"
+ "$k$extend $l$Bar$m$ {\n"
+ " $n$optional int32 qux = 1;$o$\n"
+ "}$p$\n"));
+
+ const FieldDescriptorProto& field1 = file_.extension(0);
+ const FieldDescriptorProto& field2 = file_.extension(1);
+ const FieldDescriptorProto& field3 = file_.extension(2);
+
+ EXPECT_TRUE(HasSpan('a', 'j', file_, "extension"));
+ EXPECT_TRUE(HasSpan('k', 'p', file_, "extension"));
+
+ EXPECT_TRUE(HasSpan('d', 'f', field1));
+ EXPECT_TRUE(HasSpan('d', 'e', field1, "label"));
+ EXPECT_TRUE(HasSpan('b', 'c', field1, "extendee"));
+
+ EXPECT_TRUE(HasSpan('g', 'i', field2));
+ EXPECT_TRUE(HasSpan('g', 'h', field2, "label"));
+ EXPECT_TRUE(HasSpan('b', 'c', field2, "extendee"));
+
+ EXPECT_TRUE(HasSpan('n', 'o', field3));
+ EXPECT_TRUE(HasSpan('l', 'm', field3, "extendee"));
+
+ // Ignore these.
+ EXPECT_TRUE(HasSpan(file_));
+ EXPECT_TRUE(HasSpan(field1, "type"));
+ EXPECT_TRUE(HasSpan(field1, "name"));
+ EXPECT_TRUE(HasSpan(field1, "number"));
+ EXPECT_TRUE(HasSpan(field2, "type_name"));
+ EXPECT_TRUE(HasSpan(field2, "name"));
+ EXPECT_TRUE(HasSpan(field2, "number"));
+ EXPECT_TRUE(HasSpan(field3, "label"));
+ EXPECT_TRUE(HasSpan(field3, "type"));
+ EXPECT_TRUE(HasSpan(field3, "name"));
+ EXPECT_TRUE(HasSpan(field3, "number"));
+}
+
+TEST_F(SourceInfoTest, NestedExtensions) {
+ EXPECT_TRUE(
+ Parse("message Message {\n"
+ " $a$extend $b$Foo$c$ {\n"
+ " $d$optional$e$ int32 bar = 1;$f$\n"
+ " $g$repeated$h$ X.Y baz = 2;$i$\n"
+ " }$j$\n"
+ " $k$extend $l$Bar$m$ {\n"
+ " $n$optional int32 qux = 1;$o$\n"
+ " }$p$\n"
+ "}\n"));
+
+ const FieldDescriptorProto& field1 = file_.message_type(0).extension(0);
+ const FieldDescriptorProto& field2 = file_.message_type(0).extension(1);
+ const FieldDescriptorProto& field3 = file_.message_type(0).extension(2);
+
+ EXPECT_TRUE(HasSpan('a', 'j', file_.message_type(0), "extension"));
+ EXPECT_TRUE(HasSpan('k', 'p', file_.message_type(0), "extension"));
+
+ EXPECT_TRUE(HasSpan('d', 'f', field1));
+ EXPECT_TRUE(HasSpan('d', 'e', field1, "label"));
+ EXPECT_TRUE(HasSpan('b', 'c', field1, "extendee"));
+
+ EXPECT_TRUE(HasSpan('g', 'i', field2));
+ EXPECT_TRUE(HasSpan('g', 'h', field2, "label"));
+ EXPECT_TRUE(HasSpan('b', 'c', field2, "extendee"));
+
+ EXPECT_TRUE(HasSpan('n', 'o', field3));
+ EXPECT_TRUE(HasSpan('l', 'm', field3, "extendee"));
+
+ // Ignore these.
+ EXPECT_TRUE(HasSpan(file_));
+ EXPECT_TRUE(HasSpan(file_.message_type(0)));
+ EXPECT_TRUE(HasSpan(file_.message_type(0), "name"));
+ EXPECT_TRUE(HasSpan(field1, "type"));
+ EXPECT_TRUE(HasSpan(field1, "name"));
+ EXPECT_TRUE(HasSpan(field1, "number"));
+ EXPECT_TRUE(HasSpan(field2, "type_name"));
+ EXPECT_TRUE(HasSpan(field2, "name"));
+ EXPECT_TRUE(HasSpan(field2, "number"));
+ EXPECT_TRUE(HasSpan(field3, "label"));
+ EXPECT_TRUE(HasSpan(field3, "type"));
+ EXPECT_TRUE(HasSpan(field3, "name"));
+ EXPECT_TRUE(HasSpan(field3, "number"));
+}
+
+TEST_F(SourceInfoTest, ExtensionRanges) {
+ EXPECT_TRUE(
+ Parse("message Message {\n"
+ " $a$extensions $b$1$c$ to $d$4$e$, $f$6$g$;$h$\n"
+ " $i$extensions $j$8$k$ to $l$max$m$;$n$\n"
+ "}\n"));
+
+ const DescriptorProto::ExtensionRange& range1 =
+ file_.message_type(0).extension_range(0);
+ const DescriptorProto::ExtensionRange& range2 =
+ file_.message_type(0).extension_range(1);
+ const DescriptorProto::ExtensionRange& range3 =
+ file_.message_type(0).extension_range(2);
+
+ EXPECT_TRUE(HasSpan('a', 'h', file_.message_type(0), "extension_range"));
+ EXPECT_TRUE(HasSpan('i', 'n', file_.message_type(0), "extension_range"));
+
+ EXPECT_TRUE(HasSpan('b', 'e', range1));
+ EXPECT_TRUE(HasSpan('b', 'c', range1, "start"));
+ EXPECT_TRUE(HasSpan('d', 'e', range1, "end"));
+
+ EXPECT_TRUE(HasSpan('f', 'g', range2));
+ EXPECT_TRUE(HasSpan('f', 'g', range2, "start"));
+ EXPECT_TRUE(HasSpan('f', 'g', range2, "end"));
+
+ EXPECT_TRUE(HasSpan('j', 'm', range3));
+ EXPECT_TRUE(HasSpan('j', 'k', range3, "start"));
+ EXPECT_TRUE(HasSpan('l', 'm', range3, "end"));
+
+ // Ignore these.
+ EXPECT_TRUE(HasSpan(file_));
+ EXPECT_TRUE(HasSpan(file_.message_type(0)));
+ EXPECT_TRUE(HasSpan(file_.message_type(0), "name"));
+}
+
+TEST_F(SourceInfoTest, ReservedRanges) {
+ EXPECT_TRUE(
+ Parse("message Message {\n"
+ " $a$reserved $b$1$c$ to $d$4$e$, $f$6$g$;$h$\n"
+ "}\n"));
+
+ const DescriptorProto::ReservedRange& range1 =
+ file_.message_type(0).reserved_range(0);
+ const DescriptorProto::ReservedRange& range2 =
+ file_.message_type(0).reserved_range(1);
+
+ EXPECT_TRUE(HasSpan('a', 'h', file_.message_type(0), "reserved_range"));
+
+ EXPECT_TRUE(HasSpan('b', 'e', range1));
+ EXPECT_TRUE(HasSpan('b', 'c', range1, "start"));
+ EXPECT_TRUE(HasSpan('d', 'e', range1, "end"));
+
+ EXPECT_TRUE(HasSpan('f', 'g', range2));
+ EXPECT_TRUE(HasSpan('f', 'g', range2, "start"));
+ EXPECT_TRUE(HasSpan('f', 'g', range2, "end"));
+
+ // Ignore these.
+ EXPECT_TRUE(HasSpan(file_));
+ EXPECT_TRUE(HasSpan(file_.message_type(0)));
+ EXPECT_TRUE(HasSpan(file_.message_type(0), "name"));
+}
+
+TEST_F(SourceInfoTest, Oneofs) {
+ EXPECT_TRUE(
+ Parse("message Foo {\n"
+ " $a$oneof $c$foo$d$ {\n"
+ " $e$int32$f$ $g$a$h$ = $i$1$j$;$k$\n"
+ " }$r$\n"
+ "}\n"));
+
+ const OneofDescriptorProto& oneof_decl = file_.message_type(0).oneof_decl(0);
+ const FieldDescriptorProto& field = file_.message_type(0).field(0);
+
+ EXPECT_TRUE(HasSpan('a', 'r', oneof_decl));
+ EXPECT_TRUE(HasSpan('c', 'd', oneof_decl, "name"));
+
+ EXPECT_TRUE(HasSpan('e', 'k', field));
+ EXPECT_TRUE(HasSpan('e', 'f', field, "type"));
+ EXPECT_TRUE(HasSpan('g', 'h', field, "name"));
+ EXPECT_TRUE(HasSpan('i', 'j', field, "number"));
+
+ // Ignore these.
+ EXPECT_TRUE(HasSpan(file_));
+ EXPECT_TRUE(HasSpan(file_.message_type(0)));
+ EXPECT_TRUE(HasSpan(file_.message_type(0), "name"));
+}
+
+TEST_F(SourceInfoTest, NestedMessages) {
+ EXPECT_TRUE(
+ Parse("message Foo {\n"
+ " $a$message $b$Bar$c$ {\n"
+ " $d$message $e$Baz$f$ {}$g$\n"
+ " }$h$\n"
+ " $i$message $j$Qux$k$ {}$l$\n"
+ "}\n"));
+
+ const DescriptorProto& bar = file_.message_type(0).nested_type(0);
+ const DescriptorProto& baz = bar.nested_type(0);
+ const DescriptorProto& qux = file_.message_type(0).nested_type(1);
+
+ EXPECT_TRUE(HasSpan('a', 'h', bar));
+ EXPECT_TRUE(HasSpan('b', 'c', bar, "name"));
+ EXPECT_TRUE(HasSpan('d', 'g', baz));
+ EXPECT_TRUE(HasSpan('e', 'f', baz, "name"));
+ EXPECT_TRUE(HasSpan('i', 'l', qux));
+ EXPECT_TRUE(HasSpan('j', 'k', qux, "name"));
+
+ // Ignore these.
+ EXPECT_TRUE(HasSpan(file_));
+ EXPECT_TRUE(HasSpan(file_.message_type(0)));
+ EXPECT_TRUE(HasSpan(file_.message_type(0), "name"));
+}
+
+TEST_F(SourceInfoTest, Groups) {
+ EXPECT_TRUE(
+ Parse("message Foo {\n"
+ " message Bar {}\n"
+ " $a$optional$b$ $c$group$d$ $e$Baz$f$ = $g$1$h$ {\n"
+ " $i$message Qux {}$j$\n"
+ " }$k$\n"
+ "}\n"));
+
+ const DescriptorProto& bar = file_.message_type(0).nested_type(0);
+ const DescriptorProto& baz = file_.message_type(0).nested_type(1);
+ const DescriptorProto& qux = baz.nested_type(0);
+ const FieldDescriptorProto& field = file_.message_type(0).field(0);
+
+ EXPECT_TRUE(HasSpan('a', 'k', field));
+ EXPECT_TRUE(HasSpan('a', 'b', field, "label"));
+ EXPECT_TRUE(HasSpan('c', 'd', field, "type"));
+ EXPECT_TRUE(HasSpan('e', 'f', field, "name"));
+ EXPECT_TRUE(HasSpan('e', 'f', field, "type_name"));
+ EXPECT_TRUE(HasSpan('g', 'h', field, "number"));
+
+ EXPECT_TRUE(HasSpan('a', 'k', baz));
+ EXPECT_TRUE(HasSpan('e', 'f', baz, "name"));
+ EXPECT_TRUE(HasSpan('i', 'j', qux));
+
+ // Ignore these.
+ EXPECT_TRUE(HasSpan(file_));
+ EXPECT_TRUE(HasSpan(file_.message_type(0)));
+ EXPECT_TRUE(HasSpan(file_.message_type(0), "name"));
+ EXPECT_TRUE(HasSpan(bar));
+ EXPECT_TRUE(HasSpan(bar, "name"));
+ EXPECT_TRUE(HasSpan(qux, "name"));
+}
+
+TEST_F(SourceInfoTest, Enums) {
+ EXPECT_TRUE(
+ Parse("$a$enum $b$Foo$c$ {}$d$\n"
+ "$e$enum $f$Bar$g$ {}$h$\n"));
+
+ EXPECT_TRUE(HasSpan('a', 'd', file_.enum_type(0)));
+ EXPECT_TRUE(HasSpan('b', 'c', file_.enum_type(0), "name"));
+ EXPECT_TRUE(HasSpan('e', 'h', file_.enum_type(1)));
+ EXPECT_TRUE(HasSpan('f', 'g', file_.enum_type(1), "name"));
+
+ // Ignore these.
+ EXPECT_TRUE(HasSpan(file_));
+}
+
+TEST_F(SourceInfoTest, EnumValues) {
+ EXPECT_TRUE(
+ Parse("enum Foo {\n"
+ " $a$BAR$b$ = $c$1$d$;$e$\n"
+ " $f$BAZ$g$ = $h$2$i$;$j$\n"
+ "}"));
+
+ const EnumValueDescriptorProto& bar = file_.enum_type(0).value(0);
+ const EnumValueDescriptorProto& baz = file_.enum_type(0).value(1);
+
+ EXPECT_TRUE(HasSpan('a', 'e', bar));
+ EXPECT_TRUE(HasSpan('a', 'b', bar, "name"));
+ EXPECT_TRUE(HasSpan('c', 'd', bar, "number"));
+ EXPECT_TRUE(HasSpan('f', 'j', baz));
+ EXPECT_TRUE(HasSpan('f', 'g', baz, "name"));
+ EXPECT_TRUE(HasSpan('h', 'i', baz, "number"));
+
+ // Ignore these.
+ EXPECT_TRUE(HasSpan(file_));
+ EXPECT_TRUE(HasSpan(file_.enum_type(0)));
+ EXPECT_TRUE(HasSpan(file_.enum_type(0), "name"));
+}
+
+TEST_F(SourceInfoTest, EnumReservedRange) {
+ EXPECT_TRUE(
+ Parse("enum TestEnum {\n"
+ " $a$reserved $b$1$c$ to $d$10$e$;$f$\n"
+ "}"));
+
+ const EnumDescriptorProto::EnumReservedRange& bar =
+ file_.enum_type(0).reserved_range(0);
+
+ EXPECT_TRUE(HasSpan('a', 'f', file_.enum_type(0), "reserved_range"));
+ EXPECT_TRUE(HasSpan('b', 'e', bar));
+ EXPECT_TRUE(HasSpan('b', 'c', bar, "start"));
+ EXPECT_TRUE(HasSpan('d', 'e', bar, "end"));
+
+ // Ignore these.
+ EXPECT_TRUE(HasSpan(file_));
+ EXPECT_TRUE(HasSpan(file_.enum_type(0)));
+ EXPECT_TRUE(HasSpan(file_.enum_type(0), "name"));
+}
+
+TEST_F(SourceInfoTest, EnumReservedName) {
+ EXPECT_TRUE(
+ Parse("enum TestEnum {\n"
+ " $a$reserved $b$'foo'$c$;$d$\n"
+ "}"));
+
+ const EnumDescriptorProto& bar = file_.enum_type(0);
+
+ EXPECT_TRUE(HasSpan('a', 'd', bar, "reserved_name"));
+ EXPECT_TRUE(HasSpan('b', 'c', bar, "reserved_name", 0));
+
+ // Ignore these.
+ EXPECT_TRUE(HasSpan(file_));
+ EXPECT_TRUE(HasSpan(file_.enum_type(0)));
+ EXPECT_TRUE(HasSpan(file_.enum_type(0), "name"));
+}
+
+TEST_F(SourceInfoTest, NestedEnums) {
+ EXPECT_TRUE(
+ Parse("message Foo {\n"
+ " $a$enum $b$Bar$c$ {}$d$\n"
+ " $e$enum $f$Baz$g$ {}$h$\n"
+ "}\n"));
+
+ const EnumDescriptorProto& bar = file_.message_type(0).enum_type(0);
+ const EnumDescriptorProto& baz = file_.message_type(0).enum_type(1);
+
+ EXPECT_TRUE(HasSpan('a', 'd', bar));
+ EXPECT_TRUE(HasSpan('b', 'c', bar, "name"));
+ EXPECT_TRUE(HasSpan('e', 'h', baz));
+ EXPECT_TRUE(HasSpan('f', 'g', baz, "name"));
+
+ // Ignore these.
+ EXPECT_TRUE(HasSpan(file_));
+ EXPECT_TRUE(HasSpan(file_.message_type(0)));
+ EXPECT_TRUE(HasSpan(file_.message_type(0), "name"));
+}
+
+TEST_F(SourceInfoTest, Services) {
+ EXPECT_TRUE(
+ Parse("$a$service $b$Foo$c$ {}$d$\n"
+ "$e$service $f$Bar$g$ {}$h$\n"));
+
+ EXPECT_TRUE(HasSpan('a', 'd', file_.service(0)));
+ EXPECT_TRUE(HasSpan('b', 'c', file_.service(0), "name"));
+ EXPECT_TRUE(HasSpan('e', 'h', file_.service(1)));
+ EXPECT_TRUE(HasSpan('f', 'g', file_.service(1), "name"));
+
+ // Ignore these.
+ EXPECT_TRUE(HasSpan(file_));
+}
+
+TEST_F(SourceInfoTest, MethodsAndStreams) {
+ EXPECT_TRUE(
+ Parse("service Foo {\n"
+ " $a$rpc $b$Bar$c$($d$X$e$) returns($f$Y$g$);$h$"
+ " $i$rpc $j$Baz$k$($l$Z$m$) returns($n$W$o$);$p$"
+ "}"));
+
+ const MethodDescriptorProto& bar = file_.service(0).method(0);
+ const MethodDescriptorProto& baz = file_.service(0).method(1);
+
+ EXPECT_TRUE(HasSpan('a', 'h', bar));
+ EXPECT_TRUE(HasSpan('b', 'c', bar, "name"));
+ EXPECT_TRUE(HasSpan('d', 'e', bar, "input_type"));
+ EXPECT_TRUE(HasSpan('f', 'g', bar, "output_type"));
+
+ EXPECT_TRUE(HasSpan('i', 'p', baz));
+ EXPECT_TRUE(HasSpan('j', 'k', baz, "name"));
+ EXPECT_TRUE(HasSpan('l', 'm', baz, "input_type"));
+ EXPECT_TRUE(HasSpan('n', 'o', baz, "output_type"));
+
+ // Ignore these.
+ EXPECT_TRUE(HasSpan(file_));
+ EXPECT_TRUE(HasSpan(file_.service(0)));
+ EXPECT_TRUE(HasSpan(file_.service(0), "name"));
+}
+
+
+TEST_F(SourceInfoTest, Options) {
+ EXPECT_TRUE(
+ Parse("$a$option $b$foo$c$.$d$($e$bar.baz$f$)$g$ = "
+ "$h$123$i$;$j$\n"
+ "$k$option qux = $l$-123$m$;$n$\n"
+ "$o$option corge = $p$abc$q$;$r$\n"
+ "$s$option grault = $t$'blah'$u$;$v$\n"
+ "$w$option garply = $x${ yadda yadda }$y$;$z$\n"
+ "$0$option waldo = $1$123.0$2$;$3$\n"));
+
+ const UninterpretedOption& option1 = file_.options().uninterpreted_option(0);
+ const UninterpretedOption& option2 = file_.options().uninterpreted_option(1);
+ const UninterpretedOption& option3 = file_.options().uninterpreted_option(2);
+ const UninterpretedOption& option4 = file_.options().uninterpreted_option(3);
+ const UninterpretedOption& option5 = file_.options().uninterpreted_option(4);
+ const UninterpretedOption& option6 = file_.options().uninterpreted_option(5);
+
+ EXPECT_TRUE(HasSpan('a', 'j', file_.options()));
+ EXPECT_TRUE(HasSpan('a', 'j', option1));
+ EXPECT_TRUE(HasSpan('b', 'g', option1, "name"));
+ EXPECT_TRUE(HasSpan('b', 'c', option1.name(0)));
+ EXPECT_TRUE(HasSpan('b', 'c', option1.name(0), "name_part"));
+ EXPECT_TRUE(HasSpan('d', 'g', option1.name(1)));
+ EXPECT_TRUE(HasSpan('e', 'f', option1.name(1), "name_part"));
+ EXPECT_TRUE(HasSpan('h', 'i', option1, "positive_int_value"));
+
+ EXPECT_TRUE(HasSpan('k', 'n', file_.options()));
+ EXPECT_TRUE(HasSpan('l', 'm', option2, "negative_int_value"));
+
+ EXPECT_TRUE(HasSpan('o', 'r', file_.options()));
+ EXPECT_TRUE(HasSpan('p', 'q', option3, "identifier_value"));
+
+ EXPECT_TRUE(HasSpan('s', 'v', file_.options()));
+ EXPECT_TRUE(HasSpan('t', 'u', option4, "string_value"));
+
+ EXPECT_TRUE(HasSpan('w', 'z', file_.options()));
+ EXPECT_TRUE(HasSpan('x', 'y', option5, "aggregate_value"));
+
+ EXPECT_TRUE(HasSpan('0', '3', file_.options()));
+ EXPECT_TRUE(HasSpan('1', '2', option6, "double_value"));
+
+ // Ignore these.
+ EXPECT_TRUE(HasSpan(file_));
+ EXPECT_TRUE(HasSpan(option2));
+ EXPECT_TRUE(HasSpan(option3));
+ EXPECT_TRUE(HasSpan(option4));
+ EXPECT_TRUE(HasSpan(option5));
+ EXPECT_TRUE(HasSpan(option6));
+ EXPECT_TRUE(HasSpan(option2, "name"));
+ EXPECT_TRUE(HasSpan(option3, "name"));
+ EXPECT_TRUE(HasSpan(option4, "name"));
+ EXPECT_TRUE(HasSpan(option5, "name"));
+ EXPECT_TRUE(HasSpan(option6, "name"));
+ EXPECT_TRUE(HasSpan(option2.name(0)));
+ EXPECT_TRUE(HasSpan(option3.name(0)));
+ EXPECT_TRUE(HasSpan(option4.name(0)));
+ EXPECT_TRUE(HasSpan(option5.name(0)));
+ EXPECT_TRUE(HasSpan(option6.name(0)));
+ EXPECT_TRUE(HasSpan(option2.name(0), "name_part"));
+ EXPECT_TRUE(HasSpan(option3.name(0), "name_part"));
+ EXPECT_TRUE(HasSpan(option4.name(0), "name_part"));
+ EXPECT_TRUE(HasSpan(option5.name(0), "name_part"));
+ EXPECT_TRUE(HasSpan(option6.name(0), "name_part"));
+}
+
+TEST_F(SourceInfoTest, ScopedOptions) {
+ EXPECT_TRUE(
+ Parse("message Foo {\n"
+ " $a$option mopt = 1;$b$\n"
+ "}\n"
+ "enum Bar {\n"
+ " $c$option eopt = 1;$d$\n"
+ "}\n"
+ "service Baz {\n"
+ " $e$option sopt = 1;$f$\n"
+ " rpc M(X) returns(Y) {\n"
+ " $g$option mopt = 1;$h$\n"
+ " }\n"
+ " rpc MS4($1$stream$2$ X) returns($3$stream$4$ Y) {\n"
+ " $k$option mopt = 1;$l$\n"
+ " }\n"
+ "}\n"));
+
+ EXPECT_TRUE(HasSpan('a', 'b', file_.message_type(0).options()));
+ EXPECT_TRUE(HasSpan('c', 'd', file_.enum_type(0).options()));
+ EXPECT_TRUE(HasSpan('e', 'f', file_.service(0).options()));
+ EXPECT_TRUE(HasSpan('g', 'h', file_.service(0).method(0).options()));
+
+ // Ignore these.
+ EXPECT_TRUE(HasSpan(file_));
+ EXPECT_TRUE(HasSpan(file_.message_type(0)));
+ EXPECT_TRUE(HasSpan(file_.message_type(0), "name"));
+ EXPECT_TRUE(HasSpan(file_.message_type(0).options().uninterpreted_option(0)));
+ EXPECT_TRUE(
+ HasSpan(file_.message_type(0).options().uninterpreted_option(0), "name"));
+ EXPECT_TRUE(
+ HasSpan(file_.message_type(0).options().uninterpreted_option(0).name(0)));
+ EXPECT_TRUE(
+ HasSpan(file_.message_type(0).options().uninterpreted_option(0).name(0),
+ "name_part"));
+ EXPECT_TRUE(HasSpan(file_.message_type(0).options().uninterpreted_option(0),
+ "positive_int_value"));
+ EXPECT_TRUE(HasSpan(file_.enum_type(0)));
+ EXPECT_TRUE(HasSpan(file_.enum_type(0), "name"));
+ EXPECT_TRUE(HasSpan(file_.enum_type(0).options().uninterpreted_option(0)));
+ EXPECT_TRUE(
+ HasSpan(file_.enum_type(0).options().uninterpreted_option(0), "name"));
+ EXPECT_TRUE(
+ HasSpan(file_.enum_type(0).options().uninterpreted_option(0).name(0)));
+ EXPECT_TRUE(
+ HasSpan(file_.enum_type(0).options().uninterpreted_option(0).name(0),
+ "name_part"));
+ EXPECT_TRUE(HasSpan(file_.enum_type(0).options().uninterpreted_option(0),
+ "positive_int_value"));
+ EXPECT_TRUE(HasSpan(file_.service(0)));
+ EXPECT_TRUE(HasSpan(file_.service(0), "name"));
+ EXPECT_TRUE(HasSpan(file_.service(0).method(0)));
+ EXPECT_TRUE(HasSpan(file_.service(0).options().uninterpreted_option(0)));
+ EXPECT_TRUE(
+ HasSpan(file_.service(0).options().uninterpreted_option(0), "name"));
+ EXPECT_TRUE(
+ HasSpan(file_.service(0).options().uninterpreted_option(0).name(0)));
+ EXPECT_TRUE(HasSpan(
+ file_.service(0).options().uninterpreted_option(0).name(0), "name_part"));
+ EXPECT_TRUE(HasSpan(file_.service(0).options().uninterpreted_option(0),
+ "positive_int_value"));
+ EXPECT_TRUE(HasSpan(file_.service(0).method(0), "name"));
+ EXPECT_TRUE(HasSpan(file_.service(0).method(0), "input_type"));
+ EXPECT_TRUE(HasSpan(file_.service(0).method(0), "output_type"));
+ EXPECT_TRUE(
+ HasSpan(file_.service(0).method(0).options().uninterpreted_option(0)));
+ EXPECT_TRUE(HasSpan(
+ file_.service(0).method(0).options().uninterpreted_option(0), "name"));
+ EXPECT_TRUE(HasSpan(
+ file_.service(0).method(0).options().uninterpreted_option(0).name(0)));
+ EXPECT_TRUE(HasSpan(
+ file_.service(0).method(0).options().uninterpreted_option(0).name(0),
+ "name_part"));
+ EXPECT_TRUE(
+ HasSpan(file_.service(0).method(0).options().uninterpreted_option(0),
+ "positive_int_value"));
+
+ EXPECT_TRUE(HasSpan('k', 'l', file_.service(0).method(1).options()));
+ EXPECT_TRUE(HasSpan(file_.service(0).method(1)));
+ EXPECT_TRUE(HasSpan(file_.service(0).method(1), "name"));
+ EXPECT_TRUE(HasSpan(file_.service(0).method(1), "input_type"));
+ EXPECT_TRUE(HasSpan(file_.service(0).method(1), "output_type"));
+ EXPECT_TRUE(
+ HasSpan(file_.service(0).method(1).options().uninterpreted_option(0)));
+ EXPECT_TRUE(HasSpan(
+ file_.service(0).method(1).options().uninterpreted_option(0), "name"));
+ EXPECT_TRUE(HasSpan(
+ file_.service(0).method(1).options().uninterpreted_option(0).name(0)));
+ EXPECT_TRUE(HasSpan(
+ file_.service(0).method(1).options().uninterpreted_option(0).name(0),
+ "name_part"));
+ EXPECT_TRUE(
+ HasSpan(file_.service(0).method(1).options().uninterpreted_option(0),
+ "positive_int_value"));
+ EXPECT_TRUE(
+ HasSpan('1', '2', file_.service(0).method(1), "client_streaming"));
+ EXPECT_TRUE(
+ HasSpan('3', '4', file_.service(0).method(1), "server_streaming"));
+}
+
+TEST_F(SourceInfoTest, FieldOptions) {
+ // The actual "name = value" pairs are parsed by the same code as for
+ // top-level options so we won't re-test that -- just make sure that the
+ // syntax used for field options is understood.
+ EXPECT_TRUE(
+ Parse("message Foo {"
+ " optional int32 bar = 1 "
+ "$a$[default=$b$123$c$,$d$opt1=123$e$,"
+ "$f$opt2='hi'$g$]$h$;"
+ "}\n"));
+
+ const FieldDescriptorProto& field = file_.message_type(0).field(0);
+ const UninterpretedOption& option1 = field.options().uninterpreted_option(0);
+ const UninterpretedOption& option2 = field.options().uninterpreted_option(1);
+
+ EXPECT_TRUE(HasSpan('a', 'h', field.options()));
+ EXPECT_TRUE(HasSpan('b', 'c', field, "default_value"));
+ EXPECT_TRUE(HasSpan('d', 'e', option1));
+ EXPECT_TRUE(HasSpan('f', 'g', option2));
+
+ // Ignore these.
+ EXPECT_TRUE(HasSpan(file_));
+ EXPECT_TRUE(HasSpan(file_.message_type(0)));
+ EXPECT_TRUE(HasSpan(file_.message_type(0), "name"));
+ EXPECT_TRUE(HasSpan(field));
+ EXPECT_TRUE(HasSpan(field, "label"));
+ EXPECT_TRUE(HasSpan(field, "type"));
+ EXPECT_TRUE(HasSpan(field, "name"));
+ EXPECT_TRUE(HasSpan(field, "number"));
+ EXPECT_TRUE(HasSpan(option1, "name"));
+ EXPECT_TRUE(HasSpan(option2, "name"));
+ EXPECT_TRUE(HasSpan(option1.name(0)));
+ EXPECT_TRUE(HasSpan(option2.name(0)));
+ EXPECT_TRUE(HasSpan(option1.name(0), "name_part"));
+ EXPECT_TRUE(HasSpan(option2.name(0), "name_part"));
+ EXPECT_TRUE(HasSpan(option1, "positive_int_value"));
+ EXPECT_TRUE(HasSpan(option2, "string_value"));
+}
+
+TEST_F(SourceInfoTest, EnumValueOptions) {
+ // The actual "name = value" pairs are parsed by the same code as for
+ // top-level options so we won't re-test that -- just make sure that the
+ // syntax used for enum options is understood.
+ EXPECT_TRUE(
+ Parse("enum Foo {"
+ " BAR = 1 $a$[$b$opt1=123$c$,$d$opt2='hi'$e$]$f$;"
+ "}\n"));
+
+ const EnumValueDescriptorProto& value = file_.enum_type(0).value(0);
+ const UninterpretedOption& option1 = value.options().uninterpreted_option(0);
+ const UninterpretedOption& option2 = value.options().uninterpreted_option(1);
+
+ EXPECT_TRUE(HasSpan('a', 'f', value.options()));
+ EXPECT_TRUE(HasSpan('b', 'c', option1));
+ EXPECT_TRUE(HasSpan('d', 'e', option2));
+
+ // Ignore these.
+ EXPECT_TRUE(HasSpan(file_));
+ EXPECT_TRUE(HasSpan(file_.enum_type(0)));
+ EXPECT_TRUE(HasSpan(file_.enum_type(0), "name"));
+ EXPECT_TRUE(HasSpan(value));
+ EXPECT_TRUE(HasSpan(value, "name"));
+ EXPECT_TRUE(HasSpan(value, "number"));
+ EXPECT_TRUE(HasSpan(option1, "name"));
+ EXPECT_TRUE(HasSpan(option2, "name"));
+ EXPECT_TRUE(HasSpan(option1.name(0)));
+ EXPECT_TRUE(HasSpan(option2.name(0)));
+ EXPECT_TRUE(HasSpan(option1.name(0), "name_part"));
+ EXPECT_TRUE(HasSpan(option2.name(0), "name_part"));
+ EXPECT_TRUE(HasSpan(option1, "positive_int_value"));
+ EXPECT_TRUE(HasSpan(option2, "string_value"));
+}
+
+TEST_F(SourceInfoTest, DocComments) {
+ EXPECT_TRUE(
+ Parse("// Foo leading\n"
+ "// line 2\n"
+ "$a$message Foo {\n"
+ " // Foo trailing\n"
+ " // line 2\n"
+ "\n"
+ " // detached\n"
+ "\n"
+ " // bar leading\n"
+ " $b$optional int32 bar = 1;$c$\n"
+ " // bar trailing\n"
+ "}$d$\n"
+ "// ignored\n"));
+
+ const DescriptorProto& foo = file_.message_type(0);
+ const FieldDescriptorProto& bar = foo.field(0);
+
+ EXPECT_TRUE(HasSpanWithComment('a', 'd', foo, " Foo leading\n line 2\n",
+ " Foo trailing\n line 2\n", NULL));
+ EXPECT_TRUE(HasSpanWithComment('b', 'c', bar, " bar leading\n",
+ " bar trailing\n", " detached\n"));
+
+ // Ignore these.
+ EXPECT_TRUE(HasSpan(file_));
+ EXPECT_TRUE(HasSpan(foo, "name"));
+ EXPECT_TRUE(HasSpan(bar, "label"));
+ EXPECT_TRUE(HasSpan(bar, "type"));
+ EXPECT_TRUE(HasSpan(bar, "name"));
+ EXPECT_TRUE(HasSpan(bar, "number"));
+}
+
+TEST_F(SourceInfoTest, DocComments2) {
+ EXPECT_TRUE(
+ Parse("// detached before message.\n"
+ "\n"
+ "// Foo leading\n"
+ "// line 2\n"
+ "$a$message Foo {\n"
+ " /* Foo trailing\n"
+ " * line 2 */\n"
+ " // detached\n"
+ " /* bar leading\n"
+ " */"
+ " $b$optional int32 bar = 1;$c$ // bar trailing\n"
+ " // ignored detached\n"
+ "}$d$\n"
+ "// ignored\n"
+ "\n"
+ "// detached before option\n"
+ "\n"
+ "// option leading\n"
+ "$e$option baz = 123;$f$\n"
+ "// option trailing\n"));
+
+ const DescriptorProto& foo = file_.message_type(0);
+ const FieldDescriptorProto& bar = foo.field(0);
+ const UninterpretedOption& baz = file_.options().uninterpreted_option(0);
+
+ EXPECT_TRUE(HasSpanWithComment('a', 'd', foo, " Foo leading\n line 2\n",
+ " Foo trailing\n line 2 ",
+ " detached before message.\n"));
+ EXPECT_TRUE(HasSpanWithComment('b', 'c', bar, " bar leading\n",
+ " bar trailing\n", " detached\n"));
+ EXPECT_TRUE(HasSpanWithComment('e', 'f', baz, " option leading\n",
+ " option trailing\n",
+ " detached before option\n"));
+
+ // Ignore these.
+ EXPECT_TRUE(HasSpan(file_));
+ EXPECT_TRUE(HasSpan(foo, "name"));
+ EXPECT_TRUE(HasSpan(bar, "label"));
+ EXPECT_TRUE(HasSpan(bar, "type"));
+ EXPECT_TRUE(HasSpan(bar, "name"));
+ EXPECT_TRUE(HasSpan(bar, "number"));
+ EXPECT_TRUE(HasSpan(file_.options()));
+ EXPECT_TRUE(HasSpan(baz, "name"));
+ EXPECT_TRUE(HasSpan(baz.name(0)));
+ EXPECT_TRUE(HasSpan(baz.name(0), "name_part"));
+ EXPECT_TRUE(HasSpan(baz, "positive_int_value"));
+}
+
+TEST_F(SourceInfoTest, DocComments3) {
+ EXPECT_TRUE(
+ Parse("$a$message Foo {\n"
+ " // bar leading\n"
+ " $b$optional int32 bar = 1 [(baz.qux) = {}];$c$\n"
+ " // bar trailing\n"
+ "}$d$\n"
+ "// ignored\n"));
+
+ const DescriptorProto& foo = file_.message_type(0);
+ const FieldDescriptorProto& bar = foo.field(0);
+
+ EXPECT_TRUE(HasSpanWithComment('b', 'c', bar, " bar leading\n",
+ " bar trailing\n", NULL));
+
+ // Ignore these.
+ EXPECT_TRUE(HasSpan(file_));
+ EXPECT_TRUE(HasSpan(foo));
+ EXPECT_TRUE(HasSpan(foo, "name"));
+ EXPECT_TRUE(HasSpan(bar, "label"));
+ EXPECT_TRUE(HasSpan(bar, "type"));
+ EXPECT_TRUE(HasSpan(bar, "name"));
+ EXPECT_TRUE(HasSpan(bar, "number"));
+ EXPECT_TRUE(HasSpan(bar.options()));
+ EXPECT_TRUE(HasSpan(bar.options().uninterpreted_option(0)));
+ EXPECT_TRUE(HasSpan(bar.options().uninterpreted_option(0), "name"));
+ EXPECT_TRUE(HasSpan(bar.options().uninterpreted_option(0).name(0)));
+ EXPECT_TRUE(
+ HasSpan(bar.options().uninterpreted_option(0).name(0), "name_part"));
+ EXPECT_TRUE(
+ HasSpan(bar.options().uninterpreted_option(0), "aggregate_value"));
+}
+
+TEST_F(SourceInfoTest, DocCommentsTopLevel) {
+ EXPECT_TRUE(
+ Parse("// detached before syntax paragraph 1\n"
+ "\n"
+ "// detached before syntax paragraph 2\n"
+ "\n"
+ "// syntax leading\n"
+ "$a$syntax = \"proto2\";$b$\n"
+ "// syntax trailing\n"
+ "\n"
+ "// syntax-package detached comments\n"
+ "\n"
+ ";\n"
+ "\n"
+ "// detached after empty before package\n"
+ "\n"
+ "// package leading\n"
+ "$c$package foo;$d$\n"
+ "// package trailing\n"
+ "\n"
+ "// ignored detach\n"
+ "\n"));
+
+ EXPECT_TRUE(HasSpan('a', 'b', file_, "syntax", -1, " syntax leading\n",
+ " syntax trailing\n",
+ " detached before syntax paragraph 1\n"
+ "\n"
+ " detached before syntax paragraph 2\n"));
+ EXPECT_TRUE(HasSpan('c', 'd', file_, "package", -1, " package leading\n",
+ " package trailing\n",
+ " syntax-package detached comments\n"
+ "\n"
+ " detached after empty before package\n"));
+
+ // ignore these.
+ EXPECT_TRUE(HasSpan(file_));
+}
+
+TEST_F(SourceInfoTest, DocCommentsOneof) {
+ EXPECT_TRUE(
+ Parse("// Foo leading\n"
+ "$a$message Foo {\n"
+ " /* Foo trailing\n"
+ " */\n"
+ " // detached before oneof\n"
+ " /* bar leading\n"
+ " * line 2 */\n"
+ " $b$oneof bar {\n"
+ " /* bar trailing\n"
+ " * line 2 */\n"
+ " // detached before bar_int\n"
+ " /* bar_int leading\n"
+ " */\n"
+ " $c$int32 bar_int = 1;$d$ // bar_int trailing\n"
+ " // detach comment ignored\n"
+ " }$e$\n"
+ "}$f$\n"));
+
+ const DescriptorProto& foo = file_.message_type(0);
+ const OneofDescriptorProto& bar = foo.oneof_decl(0);
+ const FieldDescriptorProto& bar_int = foo.field(0);
+
+ EXPECT_TRUE(HasSpanWithComment('a', 'f', foo, " Foo leading\n",
+ " Foo trailing\n", NULL));
+ EXPECT_TRUE(HasSpanWithComment('b', 'e', bar, " bar leading\n line 2 ",
+ " bar trailing\n line 2 ",
+ " detached before oneof\n"));
+ EXPECT_TRUE(HasSpanWithComment('c', 'd', bar_int, " bar_int leading\n",
+ " bar_int trailing\n",
+ " detached before bar_int\n"));
+
+ // Ignore these.
+ EXPECT_TRUE(HasSpan(file_));
+ EXPECT_TRUE(HasSpan(foo, "name"));
+ EXPECT_TRUE(HasSpan(bar, "name"));
+ EXPECT_TRUE(HasSpan(bar_int, "type"));
+ EXPECT_TRUE(HasSpan(bar_int, "name"));
+ EXPECT_TRUE(HasSpan(bar_int, "number"));
+}
+
+// ===================================================================
+
+} // anonymous namespace
+
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/php/php_generator.cc b/NorthstarDedicatedTest/include/protobuf/compiler/php/php_generator.cc
new file mode 100644
index 00000000..31914f38
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/php/php_generator.cc
@@ -0,0 +1,2325 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 <compiler/php/php_generator.h>
+
+#include <compiler/code_generator.h>
+#include <compiler/plugin.h>
+#include <descriptor.h>
+#include <descriptor.pb.h>
+#include <io/printer.h>
+#include <io/zero_copy_stream.h>
+#include <stubs/strutil.h>
+
+#include <sstream>
+
+const std::string kDescriptorFile = "google/protobuf/descriptor.proto";
+const std::string kEmptyFile = "google/protobuf/empty.proto";
+const std::string kEmptyMetadataFile = "GPBMetadata/Google/Protobuf/GPBEmpty.php";
+const std::string kDescriptorMetadataFile =
+ "GPBMetadata/Google/Protobuf/Internal/Descriptor.php";
+const std::string kDescriptorDirName = "Google/Protobuf/Internal";
+const std::string kDescriptorPackageName = "Google\\Protobuf\\Internal";
+const char* const kReservedNames[] = {
+ "abstract", "and", "array", "as", "break",
+ "callable", "case", "catch", "class", "clone",
+ "const", "continue", "declare", "default", "die",
+ "do", "echo", "else", "elseif", "empty",
+ "enddeclare", "endfor", "endforeach", "endif", "endswitch",
+ "endwhile", "eval", "exit", "extends", "final",
+ "finally", "fn", "for", "foreach", "function",
+ "global", "goto", "if", "implements", "include",
+ "include_once", "instanceof", "insteadof", "interface", "isset",
+ "list", "match", "namespace", "new", "or",
+ "print", "private", "protected", "public", "require",
+ "require_once", "return", "static", "switch", "throw",
+ "trait", "try", "unset", "use", "var",
+ "while", "xor", "yield", "int", "float",
+ "bool", "string", "true", "false", "null",
+ "void", "iterable"};
+const char* const kValidConstantNames[] = {
+ "int", "float", "bool", "string", "true",
+ "false", "null", "void", "iterable",
+};
+const int kReservedNamesSize = 77;
+const int kValidConstantNamesSize = 9;
+const int kFieldSetter = 1;
+const int kFieldGetter = 2;
+const int kFieldProperty = 3;
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace php {
+
+struct Options {
+ bool is_descriptor = false;
+ bool aggregate_metadata = false;
+ bool gen_c_wkt = false;
+ std::set<string> aggregate_metadata_prefixes;
+};
+
+namespace {
+
+// Forward decls.
+std::string PhpName(const std::string& full_name, const Options& options);
+std::string IntToString(int32 value);
+std::string FilenameToClassname(const std::string& filename);
+std::string GeneratedMetadataFileName(const FileDescriptor* file,
+ const Options& options);
+std::string UnderscoresToCamelCase(const std::string& name,
+ bool cap_first_letter);
+void Indent(io::Printer* printer);
+void Outdent(io::Printer* printer);
+void GenerateAddFilesToPool(const FileDescriptor* file, const Options& options,
+ io::Printer* printer);
+void GenerateMessageDocComment(io::Printer* printer, const Descriptor* message,
+ const Options& options);
+void GenerateMessageConstructorDocComment(io::Printer* printer,
+ const Descriptor* message,
+ const Options& options);
+void GenerateFieldDocComment(io::Printer* printer, const FieldDescriptor* field,
+ const Options& options, int function_type);
+void GenerateWrapperFieldGetterDocComment(io::Printer* printer,
+ const FieldDescriptor* field);
+void GenerateWrapperFieldSetterDocComment(io::Printer* printer,
+ const FieldDescriptor* field);
+void GenerateEnumDocComment(io::Printer* printer, const EnumDescriptor* enum_,
+ const Options& options);
+void GenerateEnumValueDocComment(io::Printer* printer,
+ const EnumValueDescriptor* value);
+void GenerateServiceDocComment(io::Printer* printer,
+ const ServiceDescriptor* service);
+void GenerateServiceMethodDocComment(io::Printer* printer,
+ const MethodDescriptor* method);
+
+std::string ReservedNamePrefix(const std::string& classname,
+ const FileDescriptor* file) {
+ bool is_reserved = false;
+
+ std::string lower = classname;
+ std::transform(lower.begin(), lower.end(), lower.begin(), ::tolower);
+
+ for (int i = 0; i < kReservedNamesSize; i++) {
+ if (lower == kReservedNames[i]) {
+ is_reserved = true;
+ break;
+ }
+ }
+
+ if (is_reserved) {
+ if (file->package() == "google.protobuf") {
+ return "GPB";
+ } else {
+ return "PB";
+ }
+ }
+
+ return "";
+}
+
+template <typename DescriptorType>
+std::string DescriptorFullName(const DescriptorType* desc, bool is_internal) {
+ if (is_internal) {
+ return StringReplace(desc->full_name(),
+ "google.protobuf",
+ "google.protobuf.internal", false);
+ } else {
+ return desc->full_name();
+ }
+}
+
+template <typename DescriptorType>
+std::string ClassNamePrefix(const std::string& classname,
+ const DescriptorType* desc) {
+ const std::string& prefix = (desc->file()->options()).php_class_prefix();
+ if (!prefix.empty()) {
+ return prefix;
+ }
+
+ return ReservedNamePrefix(classname, desc->file());
+}
+
+template <typename DescriptorType>
+std::string GeneratedClassNameImpl(const DescriptorType* desc) {
+ std::string classname = ClassNamePrefix(desc->name(), desc) + desc->name();
+ const Descriptor* containing = desc->containing_type();
+ while (containing != NULL) {
+ classname = ClassNamePrefix(containing->name(), desc) + containing->name()
+ + '\\' + classname;
+ containing = containing->containing_type();
+ }
+ return classname;
+}
+
+std::string GeneratedClassNameImpl(const ServiceDescriptor* desc) {
+ std::string classname = desc->name();
+ return ClassNamePrefix(classname, desc) + classname;
+}
+
+template <typename DescriptorType>
+std::string LegacyGeneratedClassName(const DescriptorType* desc) {
+ std::string classname = desc->name();
+ const Descriptor* containing = desc->containing_type();
+ while (containing != NULL) {
+ classname = containing->name() + '_' + classname;
+ containing = containing->containing_type();
+ }
+ return ClassNamePrefix(classname, desc) + classname;
+}
+
+std::string ClassNamePrefix(const std::string& classname) {
+ std::string lower = classname;
+ std::transform(lower.begin(), lower.end(), lower.begin(), ::tolower);
+
+ for (int i = 0; i < kReservedNamesSize; i++) {
+ if (lower == kReservedNames[i]) {
+ return "PB";
+ }
+ }
+
+ return "";
+}
+
+std::string ConstantNamePrefix(const std::string& classname) {
+ bool is_reserved = false;
+
+ std::string lower = classname;
+ std::transform(lower.begin(), lower.end(), lower.begin(), ::tolower);
+
+ for (int i = 0; i < kReservedNamesSize; i++) {
+ if (lower == kReservedNames[i]) {
+ is_reserved = true;
+ break;
+ }
+ }
+
+ for (int i = 0; i < kValidConstantNamesSize; i++) {
+ if (lower == kValidConstantNames[i]) {
+ is_reserved = false;
+ break;
+ }
+ }
+
+ if (is_reserved) {
+ return "PB";
+ }
+
+ return "";
+}
+
+template <typename DescriptorType>
+std::string RootPhpNamespace(const DescriptorType* desc,
+ const Options& options) {
+ if (desc->file()->options().has_php_namespace()) {
+ const std::string& php_namespace = desc->file()->options().php_namespace();
+ if (!php_namespace.empty()) {
+ return php_namespace;
+ }
+ return "";
+ }
+
+ if (!desc->file()->package().empty()) {
+ return PhpName(desc->file()->package(), options);
+ }
+ return "";
+}
+
+template <typename DescriptorType>
+std::string FullClassName(const DescriptorType* desc, const Options& options) {
+ std::string classname = GeneratedClassNameImpl(desc);
+ std::string php_namespace = RootPhpNamespace(desc, options);
+ if (!php_namespace.empty()) {
+ return php_namespace + "\\" + classname;
+ }
+ return classname;
+}
+
+template <typename DescriptorType>
+std::string FullClassName(const DescriptorType* desc, bool is_descriptor) {
+ Options options;
+ options.is_descriptor = is_descriptor;
+ return FullClassName(desc, options);
+}
+
+template <typename DescriptorType>
+std::string LegacyFullClassName(const DescriptorType* desc,
+ const Options& options) {
+ std::string classname = LegacyGeneratedClassName(desc);
+ std::string php_namespace = RootPhpNamespace(desc, options);
+ if (!php_namespace.empty()) {
+ return php_namespace + "\\" + classname;
+ }
+ return classname;
+}
+
+std::string PhpName(const std::string& full_name, const Options& options) {
+ if (options.is_descriptor) {
+ return kDescriptorPackageName;
+ }
+
+ std::string segment;
+ std::string result;
+ bool cap_next_letter = true;
+ for (int i = 0; i < full_name.size(); i++) {
+ if ('a' <= full_name[i] && full_name[i] <= 'z' && cap_next_letter) {
+ segment += full_name[i] + ('A' - 'a');
+ cap_next_letter = false;
+ } else if (full_name[i] == '.') {
+ result += ClassNamePrefix(segment) + segment + '\\';
+ segment = "";
+ cap_next_letter = true;
+ } else {
+ segment += full_name[i];
+ cap_next_letter = false;
+ }
+ }
+ result += ClassNamePrefix(segment) + segment;
+ return result;
+}
+
+std::string DefaultForField(const FieldDescriptor* field) {
+ switch (field->type()) {
+ case FieldDescriptor::TYPE_INT32:
+ case FieldDescriptor::TYPE_INT64:
+ case FieldDescriptor::TYPE_UINT32:
+ case FieldDescriptor::TYPE_UINT64:
+ case FieldDescriptor::TYPE_SINT32:
+ case FieldDescriptor::TYPE_SINT64:
+ case FieldDescriptor::TYPE_FIXED32:
+ case FieldDescriptor::TYPE_FIXED64:
+ case FieldDescriptor::TYPE_SFIXED32:
+ case FieldDescriptor::TYPE_SFIXED64:
+ case FieldDescriptor::TYPE_ENUM: return "0";
+ case FieldDescriptor::TYPE_DOUBLE:
+ case FieldDescriptor::TYPE_FLOAT: return "0.0";
+ case FieldDescriptor::TYPE_BOOL: return "false";
+ case FieldDescriptor::TYPE_STRING:
+ case FieldDescriptor::TYPE_BYTES: return "''";
+ case FieldDescriptor::TYPE_MESSAGE:
+ case FieldDescriptor::TYPE_GROUP: return "null";
+ default: assert(false); return "";
+ }
+}
+
+std::string GeneratedMetadataFileName(const FileDescriptor* file,
+ const Options& options) {
+ const std::string& proto_file = file->name();
+ int start_index = 0;
+ int first_index = proto_file.find_first_of("/", start_index);
+ std::string result = "";
+ std::string segment = "";
+
+ if (proto_file == kEmptyFile) {
+ return kEmptyMetadataFile;
+ }
+ if (options.is_descriptor) {
+ return kDescriptorMetadataFile;
+ }
+
+ // Append directory name.
+ std::string file_no_suffix;
+ int lastindex = proto_file.find_last_of(".");
+ if (proto_file == kEmptyFile) {
+ return kEmptyMetadataFile;
+ } else {
+ file_no_suffix = proto_file.substr(0, lastindex);
+ }
+
+ if (file->options().has_php_metadata_namespace()) {
+ const std::string& php_metadata_namespace =
+ file->options().php_metadata_namespace();
+ if (!php_metadata_namespace.empty() && php_metadata_namespace != "\\") {
+ result += php_metadata_namespace;
+ std::replace(result.begin(), result.end(), '\\', '/');
+ if (result.at(result.size() - 1) != '/') {
+ result += "/";
+ }
+ }
+ } else {
+ result += "GPBMetadata/";
+ while (first_index != std::string::npos) {
+ segment = UnderscoresToCamelCase(
+ file_no_suffix.substr(start_index, first_index - start_index), true);
+ result += ReservedNamePrefix(segment, file) + segment + "/";
+ start_index = first_index + 1;
+ first_index = file_no_suffix.find_first_of("/", start_index);
+ }
+ }
+
+ // Append file name.
+ int file_name_start = file_no_suffix.find_last_of("/");
+ if (file_name_start == std::string::npos) {
+ file_name_start = 0;
+ } else {
+ file_name_start += 1;
+ }
+ segment = UnderscoresToCamelCase(
+ file_no_suffix.substr(file_name_start, first_index - file_name_start), true);
+
+ return result + ReservedNamePrefix(segment, file) + segment + ".php";
+}
+
+std::string GeneratedMetadataFileName(const FileDescriptor* file,
+ bool is_descriptor) {
+ Options options;
+ options.is_descriptor = is_descriptor;
+ return GeneratedMetadataFileName(file, options);
+}
+
+template <typename DescriptorType>
+std::string GeneratedClassFileName(const DescriptorType* desc,
+ const Options& options) {
+ std::string result = FullClassName(desc, options);
+ for (int i = 0; i < result.size(); i++) {
+ if (result[i] == '\\') {
+ result[i] = '/';
+ }
+ }
+ return result + ".php";
+}
+
+template <typename DescriptorType>
+std::string LegacyGeneratedClassFileName(const DescriptorType* desc,
+ const Options& options) {
+ std::string result = LegacyFullClassName(desc, options);
+
+ for (int i = 0; i < result.size(); i++) {
+ if (result[i] == '\\') {
+ result[i] = '/';
+ }
+ }
+ return result + ".php";
+}
+
+std::string GeneratedServiceFileName(const ServiceDescriptor* service,
+ const Options& options) {
+ std::string result = FullClassName(service, options) + "Interface";
+ for (int i = 0; i < result.size(); i++) {
+ if (result[i] == '\\') {
+ result[i] = '/';
+ }
+ }
+ return result + ".php";
+}
+
+std::string IntToString(int32 value) {
+ std::ostringstream os;
+ os << value;
+ return os.str();
+}
+
+std::string LabelForField(const FieldDescriptor* field) {
+ switch (field->label()) {
+ case FieldDescriptor::LABEL_OPTIONAL: return "optional";
+ case FieldDescriptor::LABEL_REQUIRED: return "required";
+ case FieldDescriptor::LABEL_REPEATED: return "repeated";
+ default: assert(false); return "";
+ }
+}
+
+std::string PhpSetterTypeName(const FieldDescriptor* field,
+ const Options& options) {
+ if (field->is_map()) {
+ return "array|\\Google\\Protobuf\\Internal\\MapField";
+ }
+ std::string type;
+ switch (field->type()) {
+ case FieldDescriptor::TYPE_INT32:
+ case FieldDescriptor::TYPE_UINT32:
+ case FieldDescriptor::TYPE_SINT32:
+ case FieldDescriptor::TYPE_FIXED32:
+ case FieldDescriptor::TYPE_SFIXED32:
+ case FieldDescriptor::TYPE_ENUM:
+ type = "int";
+ break;
+ case FieldDescriptor::TYPE_INT64:
+ case FieldDescriptor::TYPE_UINT64:
+ case FieldDescriptor::TYPE_SINT64:
+ case FieldDescriptor::TYPE_FIXED64:
+ case FieldDescriptor::TYPE_SFIXED64:
+ type = "int|string";
+ break;
+ case FieldDescriptor::TYPE_DOUBLE:
+ case FieldDescriptor::TYPE_FLOAT:
+ type = "float";
+ break;
+ case FieldDescriptor::TYPE_BOOL:
+ type = "bool";
+ break;
+ case FieldDescriptor::TYPE_STRING:
+ case FieldDescriptor::TYPE_BYTES:
+ type = "string";
+ break;
+ case FieldDescriptor::TYPE_MESSAGE:
+ type = "\\" + FullClassName(field->message_type(), options);
+ break;
+ case FieldDescriptor::TYPE_GROUP:
+ return "null";
+ default: assert(false); return "";
+ }
+ if (field->is_repeated()) {
+ // accommodate for edge case with multiple types.
+ size_t start_pos = type.find("|");
+ if (start_pos != std::string::npos) {
+ type.replace(start_pos, 1, "[]|");
+ }
+ type += "[]|\\Google\\Protobuf\\Internal\\RepeatedField";
+ }
+ return type;
+}
+
+std::string PhpSetterTypeName(const FieldDescriptor* field,
+ bool is_descriptor) {
+ Options options;
+ options.is_descriptor = is_descriptor;
+ return PhpSetterTypeName(field, options);
+}
+
+std::string PhpGetterTypeName(const FieldDescriptor* field,
+ const Options& options) {
+ if (field->is_map()) {
+ return "\\Google\\Protobuf\\Internal\\MapField";
+ }
+ if (field->is_repeated()) {
+ return "\\Google\\Protobuf\\Internal\\RepeatedField";
+ }
+ switch (field->type()) {
+ case FieldDescriptor::TYPE_INT32:
+ case FieldDescriptor::TYPE_UINT32:
+ case FieldDescriptor::TYPE_SINT32:
+ case FieldDescriptor::TYPE_FIXED32:
+ case FieldDescriptor::TYPE_SFIXED32:
+ case FieldDescriptor::TYPE_ENUM: return "int";
+ case FieldDescriptor::TYPE_INT64:
+ case FieldDescriptor::TYPE_UINT64:
+ case FieldDescriptor::TYPE_SINT64:
+ case FieldDescriptor::TYPE_FIXED64:
+ case FieldDescriptor::TYPE_SFIXED64: return "int|string";
+ case FieldDescriptor::TYPE_DOUBLE:
+ case FieldDescriptor::TYPE_FLOAT: return "float";
+ case FieldDescriptor::TYPE_BOOL: return "bool";
+ case FieldDescriptor::TYPE_STRING:
+ case FieldDescriptor::TYPE_BYTES: return "string";
+ case FieldDescriptor::TYPE_MESSAGE:
+ return "\\" + FullClassName(field->message_type(), options);
+ case FieldDescriptor::TYPE_GROUP: return "null";
+ default: assert(false); return "";
+ }
+}
+
+std::string PhpGetterTypeName(const FieldDescriptor* field,
+ bool is_descriptor) {
+ Options options;
+ options.is_descriptor = is_descriptor;
+ return PhpGetterTypeName(field, options);
+}
+
+std::string EnumOrMessageSuffix(const FieldDescriptor* field,
+ const Options& options) {
+ if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+ return ", '" +
+ DescriptorFullName(field->message_type(), options.is_descriptor) +
+ "'";
+ }
+ if (field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) {
+ return ", '" +
+ DescriptorFullName(field->enum_type(), options.is_descriptor) + "'";
+ }
+ return "";
+}
+
+std::string EnumOrMessageSuffix(const FieldDescriptor* field,
+ bool is_descriptor) {
+ Options options;
+ options.is_descriptor = is_descriptor;
+ return EnumOrMessageSuffix(field, options);
+}
+
+// Converts a name to camel-case. If cap_first_letter is true, capitalize the
+// first letter.
+std::string UnderscoresToCamelCase(const std::string& name,
+ bool cap_first_letter) {
+ std::string result;
+ for (int i = 0; i < name.size(); i++) {
+ if ('a' <= name[i] && name[i] <= 'z') {
+ if (cap_first_letter) {
+ result += name[i] + ('A' - 'a');
+ } else {
+ result += name[i];
+ }
+ cap_first_letter = false;
+ } else if ('A' <= name[i] && name[i] <= 'Z') {
+ if (i == 0 && !cap_first_letter) {
+ // Force first letter to lower-case unless explicitly told to
+ // capitalize it.
+ result += name[i] + ('a' - 'A');
+ } else {
+ // Capital letters after the first are left as-is.
+ result += name[i];
+ }
+ cap_first_letter = false;
+ } else if ('0' <= name[i] && name[i] <= '9') {
+ result += name[i];
+ cap_first_letter = true;
+ } else {
+ cap_first_letter = true;
+ }
+ }
+ // Add a trailing "_" if the name should be altered.
+ if (name[name.size() - 1] == '#') {
+ result += '_';
+ }
+ return result;
+}
+
+void Indent(io::Printer* printer) {
+ printer->Indent();
+ printer->Indent();
+}
+void Outdent(io::Printer* printer) {
+ printer->Outdent();
+ printer->Outdent();
+}
+
+void GenerateField(const FieldDescriptor* field, io::Printer* printer,
+ const Options& options) {
+ if (field->is_repeated()) {
+ GenerateFieldDocComment(printer, field, options, kFieldProperty);
+ printer->Print(
+ "private $^name^;\n",
+ "name", field->name());
+ } else if (field->real_containing_oneof()) {
+ // Oneof fields are handled by GenerateOneofField.
+ return;
+ } else {
+ std::string initial_value =
+ field->has_presence() ? "null" : DefaultForField(field);
+ GenerateFieldDocComment(printer, field, options, kFieldProperty);
+ printer->Print(
+ "protected $^name^ = ^initial_value^;\n",
+ "name", field->name(),
+ "initial_value", initial_value);
+ }
+}
+
+void GenerateOneofField(const OneofDescriptor* oneof, io::Printer* printer) {
+ // Oneof property needs to be protected in order to be accessed by parent
+ // class in implementation.
+ printer->Print(
+ "protected $^name^;\n",
+ "name", oneof->name());
+}
+
+void GenerateFieldAccessor(const FieldDescriptor* field, const Options& options,
+ io::Printer* printer) {
+ const OneofDescriptor* oneof = field->real_containing_oneof();
+
+ // Generate getter.
+ GenerateFieldDocComment(printer, field, options, kFieldGetter);
+
+ // deprecation
+ std::string deprecation_trigger = (field->options().deprecated()) ? "@trigger_error('" +
+ field->name() + " is deprecated.', E_USER_DEPRECATED);\n " : "";
+
+ // Emit getter.
+ if (oneof != NULL) {
+ printer->Print(
+ "public function get^camel_name^()\n"
+ "{\n"
+ " ^deprecation_trigger^return $this->readOneof(^number^);\n"
+ "}\n\n",
+ "camel_name", UnderscoresToCamelCase(field->name(), true),
+ "number", IntToString(field->number()),
+ "deprecation_trigger", deprecation_trigger);
+ } else if (field->has_presence() && !field->message_type()) {
+ printer->Print(
+ "public function get^camel_name^()\n"
+ "{\n"
+ " ^deprecation_trigger^return isset($this->^name^) ? $this->^name^ : ^default_value^;\n"
+ "}\n\n",
+ "camel_name", UnderscoresToCamelCase(field->name(), true),
+ "name", field->name(),
+ "default_value", DefaultForField(field),
+ "deprecation_trigger", deprecation_trigger);
+ } else {
+ printer->Print(
+ "public function get^camel_name^()\n"
+ "{\n"
+ " ^deprecation_trigger^return $this->^name^;\n"
+ "}\n\n",
+ "camel_name", UnderscoresToCamelCase(field->name(), true),
+ "name", field->name(),
+ "deprecation_trigger", deprecation_trigger);
+ }
+
+ // Emit hazzers/clear.
+ if (oneof) {
+ printer->Print(
+ "public function has^camel_name^()\n"
+ "{\n"
+ " ^deprecation_trigger^return $this->hasOneof(^number^);\n"
+ "}\n\n",
+ "camel_name", UnderscoresToCamelCase(field->name(), true),
+ "number", IntToString(field->number()),
+ "deprecation_trigger", deprecation_trigger);
+ } else if (field->has_presence()) {
+ printer->Print(
+ "public function has^camel_name^()\n"
+ "{\n"
+ " ^deprecation_trigger^return isset($this->^name^);\n"
+ "}\n\n"
+ "public function clear^camel_name^()\n"
+ "{\n"
+ " ^deprecation_trigger^unset($this->^name^);\n"
+ "}\n\n",
+ "camel_name", UnderscoresToCamelCase(field->name(), true),
+ "name", field->name(),
+ "default_value", DefaultForField(field),
+ "deprecation_trigger", deprecation_trigger);
+ }
+
+ // For wrapper types, generate an additional getXXXUnwrapped getter
+ if (!field->is_map() &&
+ !field->is_repeated() &&
+ field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
+ IsWrapperType(field)) {
+ GenerateWrapperFieldGetterDocComment(printer, field);
+ printer->Print(
+ "public function get^camel_name^Unwrapped()\n"
+ "{\n"
+ " ^deprecation_trigger^return $this->readWrapperValue(\"^field_name^\");\n"
+ "}\n\n",
+ "camel_name", UnderscoresToCamelCase(field->name(), true),
+ "field_name", field->name(),
+ "deprecation_trigger", deprecation_trigger);
+ }
+
+ // Generate setter.
+ GenerateFieldDocComment(printer, field, options, kFieldSetter);
+ printer->Print(
+ "public function set^camel_name^($var)\n"
+ "{\n",
+ "camel_name", UnderscoresToCamelCase(field->name(), true));
+
+ Indent(printer);
+
+ if (field->options().deprecated()) {
+ printer->Print(
+ "^deprecation_trigger^",
+ "deprecation_trigger", deprecation_trigger
+ );
+ }
+
+ // Type check.
+ if (field->is_map()) {
+ const Descriptor* map_entry = field->message_type();
+ const FieldDescriptor* key = map_entry->FindFieldByName("key");
+ const FieldDescriptor* value = map_entry->FindFieldByName("value");
+ printer->Print(
+ "$arr = GPBUtil::checkMapField($var, "
+ "\\Google\\Protobuf\\Internal\\GPBType::^key_type^, "
+ "\\Google\\Protobuf\\Internal\\GPBType::^value_type^",
+ "key_type", ToUpper(key->type_name()),
+ "value_type", ToUpper(value->type_name()));
+ if (value->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+ printer->Print(
+ ", \\^class_name^);\n",
+ "class_name",
+ FullClassName(value->message_type(), options) + "::class");
+ } else if (value->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) {
+ printer->Print(
+ ", \\^class_name^);\n",
+ "class_name",
+ FullClassName(value->enum_type(), options) + "::class");
+ } else {
+ printer->Print(");\n");
+ }
+ } else if (field->is_repeated()) {
+ printer->Print(
+ "$arr = GPBUtil::checkRepeatedField($var, "
+ "\\Google\\Protobuf\\Internal\\GPBType::^type^",
+ "type", ToUpper(field->type_name()));
+ if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+ printer->Print(
+ ", \\^class_name^);\n",
+ "class_name",
+ FullClassName(field->message_type(), options) + "::class");
+ } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) {
+ printer->Print(
+ ", \\^class_name^);\n",
+ "class_name",
+ FullClassName(field->enum_type(), options) + "::class");
+ } else {
+ printer->Print(");\n");
+ }
+ } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+ printer->Print(
+ "GPBUtil::checkMessage($var, \\^class_name^::class);\n",
+ "class_name", FullClassName(field->message_type(), options));
+ } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) {
+ printer->Print(
+ "GPBUtil::checkEnum($var, \\^class_name^::class);\n",
+ "class_name", FullClassName(field->enum_type(), options));
+ } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING) {
+ printer->Print(
+ "GPBUtil::checkString($var, ^utf8^);\n",
+ "utf8",
+ field->type() == FieldDescriptor::TYPE_STRING ? "True": "False");
+ } else {
+ printer->Print(
+ "GPBUtil::check^type^($var);\n",
+ "type", UnderscoresToCamelCase(field->cpp_type_name(), true));
+ }
+
+ if (oneof != NULL) {
+ printer->Print(
+ "$this->writeOneof(^number^, $var);\n",
+ "number", IntToString(field->number()));
+ } else if (field->is_repeated()) {
+ printer->Print(
+ "$this->^name^ = $arr;\n",
+ "name", field->name());
+ } else {
+ printer->Print(
+ "$this->^name^ = $var;\n",
+ "name", field->name());
+ }
+
+ printer->Print("\nreturn $this;\n");
+
+ Outdent(printer);
+
+ printer->Print(
+ "}\n\n");
+
+ // For wrapper types, generate an additional setXXXValue getter
+ if (!field->is_map() &&
+ !field->is_repeated() &&
+ field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
+ IsWrapperType(field)) {
+ GenerateWrapperFieldSetterDocComment(printer, field);
+ printer->Print(
+ "public function set^camel_name^Unwrapped($var)\n"
+ "{\n"
+ " $this->writeWrapperValue(\"^field_name^\", $var);\n"
+ " return $this;"
+ "}\n\n",
+ "camel_name", UnderscoresToCamelCase(field->name(), true),
+ "field_name", field->name());
+ }
+}
+
+void GenerateEnumToPool(const EnumDescriptor* en, io::Printer* printer) {
+ printer->Print(
+ "$pool->addEnum('^name^', "
+ "\\Google\\Protobuf\\Internal\\^class_name^::class)\n",
+ "name", DescriptorFullName(en, true),
+ "class_name", en->name());
+ Indent(printer);
+
+ for (int i = 0; i < en->value_count(); i++) {
+ const EnumValueDescriptor* value = en->value(i);
+ printer->Print(
+ "->value(\"^name^\", ^number^)\n",
+ "name", ConstantNamePrefix(value->name()) + value->name(),
+ "number", IntToString(value->number()));
+ }
+ printer->Print("->finalizeToPool();\n\n");
+ Outdent(printer);
+}
+
+void GenerateServiceMethod(const MethodDescriptor* method,
+ io::Printer* printer) {
+ printer->Print(
+ "public function ^camel_name^(\\^request_name^ $request);\n\n",
+ "camel_name", UnderscoresToCamelCase(method->name(), false),
+ "request_name", FullClassName(
+ method->input_type(), false)
+ );
+}
+
+void GenerateMessageToPool(const std::string& name_prefix,
+ const Descriptor* message, io::Printer* printer) {
+ // Don't generate MapEntry messages -- we use the PHP extension's native
+ // support for map fields instead.
+ if (message->options().map_entry()) {
+ return;
+ }
+ std::string class_name =
+ (name_prefix.empty() ? "" : name_prefix + "\\") +
+ ReservedNamePrefix(message->name(), message->file()) + message->name();
+
+ printer->Print(
+ "$pool->addMessage('^message^', "
+ "\\Google\\Protobuf\\Internal\\^class_name^::class)\n",
+ "message", DescriptorFullName(message, true),
+ "class_name", class_name);
+
+ Indent(printer);
+
+ for (int i = 0; i < message->field_count(); i++) {
+ const FieldDescriptor* field = message->field(i);
+ if (field->is_map()) {
+ const FieldDescriptor* key =
+ field->message_type()->FindFieldByName("key");
+ const FieldDescriptor* val =
+ field->message_type()->FindFieldByName("value");
+ printer->Print(
+ "->map('^field^', \\Google\\Protobuf\\Internal\\GPBType::^key^, "
+ "\\Google\\Protobuf\\Internal\\GPBType::^value^, ^number^^other^)\n",
+ "field", field->name(),
+ "key", ToUpper(key->type_name()),
+ "value", ToUpper(val->type_name()),
+ "number", StrCat(field->number()),
+ "other", EnumOrMessageSuffix(val, true));
+ } else if (!field->real_containing_oneof()) {
+ printer->Print(
+ "->^label^('^field^', "
+ "\\Google\\Protobuf\\Internal\\GPBType::^type^, ^number^^other^)\n",
+ "field", field->name(),
+ "label", LabelForField(field),
+ "type", ToUpper(field->type_name()),
+ "number", StrCat(field->number()),
+ "other", EnumOrMessageSuffix(field, true));
+ }
+ }
+
+ // oneofs.
+ for (int i = 0; i < message->real_oneof_decl_count(); i++) {
+ const OneofDescriptor* oneof = message->oneof_decl(i);
+ printer->Print("->oneof(^name^)\n",
+ "name", oneof->name());
+ Indent(printer);
+ for (int index = 0; index < oneof->field_count(); index++) {
+ const FieldDescriptor* field = oneof->field(index);
+ printer->Print(
+ "->value('^field^', "
+ "\\Google\\Protobuf\\Internal\\GPBType::^type^, ^number^^other^)\n",
+ "field", field->name(),
+ "type", ToUpper(field->type_name()),
+ "number", StrCat(field->number()),
+ "other", EnumOrMessageSuffix(field, true));
+ }
+ printer->Print("->finish()\n");
+ Outdent(printer);
+ }
+
+ printer->Print(
+ "->finalizeToPool();\n");
+
+ Outdent(printer);
+
+ printer->Print(
+ "\n");
+
+ for (int i = 0; i < message->nested_type_count(); i++) {
+ GenerateMessageToPool(class_name, message->nested_type(i), printer);
+ }
+ for (int i = 0; i < message->enum_type_count(); i++) {
+ GenerateEnumToPool(message->enum_type(i), printer);
+ }
+}
+
+void GenerateAddFileToPool(const FileDescriptor* file, const Options& options,
+ io::Printer* printer) {
+ printer->Print(
+ "public static $is_initialized = false;\n\n"
+ "public static function initOnce() {\n");
+ Indent(printer);
+
+ if (options.aggregate_metadata) {
+ GenerateAddFilesToPool(file, options, printer);
+ } else {
+ printer->Print(
+ "$pool = \\Google\\Protobuf\\Internal\\"
+ "DescriptorPool::getGeneratedPool();\n\n"
+ "if (static::$is_initialized == true) {\n"
+ " return;\n"
+ "}\n");
+
+ if (options.is_descriptor) {
+ for (int i = 0; i < file->message_type_count(); i++) {
+ GenerateMessageToPool("", file->message_type(i), printer);
+ }
+ for (int i = 0; i < file->enum_type_count(); i++) {
+ GenerateEnumToPool(file->enum_type(i), printer);
+ }
+
+ printer->Print(
+ "$pool->finish();\n");
+ } else {
+ for (int i = 0; i < file->dependency_count(); i++) {
+ const std::string& name = file->dependency(i)->name();
+ // Currently, descriptor.proto is not ready for external usage. Skip to
+ // import it for now, so that its dependencies can still work as long as
+ // they don't use protos defined in descriptor.proto.
+ if (name == kDescriptorFile) {
+ continue;
+ }
+ std::string dependency_filename =
+ GeneratedMetadataFileName(file->dependency(i), options);
+ printer->Print(
+ "\\^name^::initOnce();\n",
+ "name", FilenameToClassname(dependency_filename));
+ }
+
+ // Add messages and enums to descriptor pool.
+ FileDescriptorSet files;
+ FileDescriptorProto* file_proto = files.add_file();
+ file->CopyTo(file_proto);
+
+ // Filter out descriptor.proto as it cannot be depended on for now.
+ RepeatedPtrField<std::string>* dependency =
+ file_proto->mutable_dependency();
+ for (RepeatedPtrField<std::string>::iterator it = dependency->begin();
+ it != dependency->end(); ++it) {
+ if (*it != kDescriptorFile) {
+ dependency->erase(it);
+ break;
+ }
+ }
+
+ // Filter out all extensions, since we do not support extension yet.
+ file_proto->clear_extension();
+ RepeatedPtrField<DescriptorProto>* message_type =
+ file_proto->mutable_message_type();
+ for (RepeatedPtrField<DescriptorProto>::iterator it = message_type->begin();
+ it != message_type->end(); ++it) {
+ it->clear_extension();
+ }
+
+ std::string files_data;
+ files.SerializeToString(&files_data);
+
+ printer->Print("$pool->internalAddGeneratedFile(\n");
+ Indent(printer);
+ printer->Print("'");
+
+ for (auto ch : files_data) {
+ switch (ch) {
+ case '\\':
+ printer->Print(R"(\\)");
+ break;
+ case '\'':
+ printer->Print(R"(\')");
+ break;
+ default:
+ printer->Print("^char^", "char", std::string(1, ch));
+ break;
+ }
+ }
+
+ printer->Print("'\n");
+ Outdent(printer);
+ printer->Print(
+ ", true);\n\n");
+ }
+ printer->Print(
+ "static::$is_initialized = true;\n");
+ }
+
+ Outdent(printer);
+ printer->Print("}\n");
+}
+
+static void AnalyzeDependencyForFile(
+ const FileDescriptor* file,
+ std::set<const FileDescriptor*>* nodes_without_dependency,
+ std::map<const FileDescriptor*, std::set<const FileDescriptor*>>* deps,
+ std::map<const FileDescriptor*, int>* dependency_count) {
+ int count = file->dependency_count();
+ for (int i = 0; i < file->dependency_count(); i++) {
+ const FileDescriptor* dependency = file->dependency(i);
+ if (dependency->name() == kDescriptorFile) {
+ count--;
+ break;
+ }
+ }
+
+ if (count == 0) {
+ nodes_without_dependency->insert(file);
+ } else {
+ (*dependency_count)[file] = count;
+ for (int i = 0; i < file->dependency_count(); i++) {
+ const FileDescriptor* dependency = file->dependency(i);
+ if (dependency->name() == kDescriptorFile) {
+ continue;
+ }
+ if (deps->find(dependency) == deps->end()) {
+ (*deps)[dependency] = std::set<const FileDescriptor*>();
+ }
+ (*deps)[dependency].insert(file);
+ AnalyzeDependencyForFile(
+ dependency, nodes_without_dependency, deps, dependency_count);
+ }
+ }
+}
+
+static bool NeedsUnwrapping(const FileDescriptor* file,
+ const Options& options) {
+ bool has_aggregate_metadata_prefix = false;
+ if (options.aggregate_metadata_prefixes.empty()) {
+ has_aggregate_metadata_prefix = true;
+ } else {
+ for (const auto& prefix : options.aggregate_metadata_prefixes) {
+ if (HasPrefixString(file->package(), prefix)) {
+ has_aggregate_metadata_prefix = true;
+ break;
+ }
+ }
+ }
+
+ return has_aggregate_metadata_prefix;
+}
+
+void GenerateAddFilesToPool(const FileDescriptor* file, const Options& options,
+ io::Printer* printer) {
+ printer->Print(
+ "$pool = \\Google\\Protobuf\\Internal\\"
+ "DescriptorPool::getGeneratedPool();\n"
+ "if (static::$is_initialized == true) {\n"
+ " return;\n"
+ "}\n");
+
+ // Sort files according to dependency
+ std::map<const FileDescriptor*, std::set<const FileDescriptor*>> deps;
+ std::map<const FileDescriptor*, int> dependency_count;
+ std::set<const FileDescriptor*> nodes_without_dependency;
+ FileDescriptorSet sorted_file_set;
+
+ AnalyzeDependencyForFile(
+ file, &nodes_without_dependency, &deps, &dependency_count);
+
+ while (!nodes_without_dependency.empty()) {
+ auto file_node = *nodes_without_dependency.begin();
+ nodes_without_dependency.erase(file_node);
+ for (auto dependent : deps[file_node]) {
+ if (dependency_count[dependent] == 1) {
+ dependency_count.erase(dependent);
+ nodes_without_dependency.insert(dependent);
+ } else {
+ dependency_count[dependent] -= 1;
+ }
+ }
+
+ bool needs_aggregate = NeedsUnwrapping(file_node, options);
+
+ if (needs_aggregate) {
+ auto file_proto = sorted_file_set.add_file();
+ file_node->CopyTo(file_proto);
+
+ // Filter out descriptor.proto as it cannot be depended on for now.
+ RepeatedPtrField<std::string>* dependency =
+ file_proto->mutable_dependency();
+ for (RepeatedPtrField<std::string>::iterator it = dependency->begin();
+ it != dependency->end(); ++it) {
+ if (*it != kDescriptorFile) {
+ dependency->erase(it);
+ break;
+ }
+ }
+
+ // Filter out all extensions, since we do not support extension yet.
+ file_proto->clear_extension();
+ RepeatedPtrField<DescriptorProto>* message_type =
+ file_proto->mutable_message_type();
+ for (RepeatedPtrField<DescriptorProto>::iterator it = message_type->begin();
+ it != message_type->end(); ++it) {
+ it->clear_extension();
+ }
+ } else {
+ std::string dependency_filename = GeneratedMetadataFileName(file_node, false);
+ printer->Print(
+ "\\^name^::initOnce();\n",
+ "name", FilenameToClassname(dependency_filename));
+ }
+ }
+
+ std::string files_data;
+ sorted_file_set.SerializeToString(&files_data);
+
+ printer->Print("$pool->internalAddGeneratedFile(\n");
+ Indent(printer);
+ printer->Print("'");
+
+ for (auto ch : files_data) {
+ switch (ch) {
+ case '\\':
+ printer->Print(R"(\\)");
+ break;
+ case '\'':
+ printer->Print(R"(\')");
+ break;
+ default:
+ printer->Print("^char^", "char", std::string(1, ch));
+ break;
+ }
+ }
+
+ printer->Print("'\n");
+ Outdent(printer);
+ printer->Print(
+ ", true);\n");
+
+ printer->Print(
+ "static::$is_initialized = true;\n");
+}
+
+void GenerateUseDeclaration(const Options& options, io::Printer* printer) {
+ if (!options.is_descriptor) {
+ printer->Print(
+ "use Google\\Protobuf\\Internal\\GPBType;\n"
+ "use Google\\Protobuf\\Internal\\RepeatedField;\n"
+ "use Google\\Protobuf\\Internal\\GPBUtil;\n\n");
+ } else {
+ printer->Print(
+ "use Google\\Protobuf\\Internal\\GPBType;\n"
+ "use Google\\Protobuf\\Internal\\GPBWire;\n"
+ "use Google\\Protobuf\\Internal\\RepeatedField;\n"
+ "use Google\\Protobuf\\Internal\\InputStream;\n"
+ "use Google\\Protobuf\\Internal\\GPBUtil;\n\n");
+ }
+}
+
+void GenerateHead(const FileDescriptor* file, io::Printer* printer) {
+ printer->Print(
+ "<?php\n"
+ "# Generated by the protocol buffer compiler. DO NOT EDIT!\n"
+ "# source: ^filename^\n"
+ "\n",
+ "filename", file->name());
+}
+
+std::string FilenameToClassname(const std::string& filename) {
+ int lastindex = filename.find_last_of(".");
+ std::string result = filename.substr(0, lastindex);
+ for (int i = 0; i < result.size(); i++) {
+ if (result[i] == '/') {
+ result[i] = '\\';
+ }
+ }
+ return result;
+}
+
+void GenerateMetadataFile(const FileDescriptor* file, const Options& options,
+ GeneratorContext* generator_context) {
+ std::string filename = GeneratedMetadataFileName(file, options);
+ std::unique_ptr<io::ZeroCopyOutputStream> output(
+ generator_context->Open(filename));
+ io::Printer printer(output.get(), '^');
+
+ GenerateHead(file, &printer);
+
+ std::string fullname = FilenameToClassname(filename);
+ int lastindex = fullname.find_last_of("\\");
+
+ if (lastindex != std::string::npos) {
+ printer.Print(
+ "namespace ^name^;\n\n",
+ "name", fullname.substr(0, lastindex));
+
+ printer.Print(
+ "class ^name^\n"
+ "{\n",
+ "name", fullname.substr(lastindex + 1));
+ } else {
+ printer.Print(
+ "class ^name^\n"
+ "{\n",
+ "name", fullname);
+ }
+ Indent(&printer);
+
+ GenerateAddFileToPool(file, options, &printer);
+
+ Outdent(&printer);
+ printer.Print("}\n\n");
+}
+
+template <typename DescriptorType>
+void LegacyGenerateClassFile(const FileDescriptor* file,
+ const DescriptorType* desc, const Options& options,
+ GeneratorContext* generator_context) {
+ std::string filename = LegacyGeneratedClassFileName(desc, options);
+ std::unique_ptr<io::ZeroCopyOutputStream> output(
+ generator_context->Open(filename));
+ io::Printer printer(output.get(), '^');
+
+ GenerateHead(file, &printer);
+
+ std::string php_namespace = RootPhpNamespace(desc, options);
+ if (!php_namespace.empty()) {
+ printer.Print(
+ "namespace ^name^;\n\n",
+ "name", php_namespace);
+ }
+ std::string newname = FullClassName(desc, options);
+ printer.Print("if (false) {\n");
+ Indent(&printer);
+ printer.Print("/**\n");
+ printer.Print(" * This class is deprecated. Use ^new^ instead.\n",
+ "new", newname);
+ printer.Print(" * @deprecated\n");
+ printer.Print(" */\n");
+ printer.Print("class ^old^ {}\n",
+ "old", LegacyGeneratedClassName(desc));
+ Outdent(&printer);
+ printer.Print("}\n");
+ printer.Print("class_exists(^new^::class);\n",
+ "new", GeneratedClassNameImpl(desc));
+ printer.Print("@trigger_error('^old^ is deprecated and will be removed in "
+ "the next major release. Use ^fullname^ instead', E_USER_DEPRECATED);\n\n",
+ "old", LegacyFullClassName(desc, options),
+ "fullname", newname);
+}
+
+void GenerateEnumFile(const FileDescriptor* file, const EnumDescriptor* en,
+ const Options& options,
+ GeneratorContext* generator_context) {
+ std::string filename = GeneratedClassFileName(en, options);
+ std::unique_ptr<io::ZeroCopyOutputStream> output(
+ generator_context->Open(filename));
+ io::Printer printer(output.get(), '^');
+
+ GenerateHead(file, &printer);
+
+ std::string fullname = FilenameToClassname(filename);
+ int lastindex = fullname.find_last_of("\\");
+
+ if (lastindex != std::string::npos) {
+ printer.Print(
+ "namespace ^name^;\n\n",
+ "name", fullname.substr(0, lastindex));
+
+ // We only need this 'use' statement if the enum has a namespace.
+ // Otherwise, we get a warning that the use statement has no effect.
+ printer.Print("use UnexpectedValueException;\n\n");
+ }
+
+ GenerateEnumDocComment(&printer, en, options);
+
+ if (lastindex != std::string::npos) {
+ fullname = fullname.substr(lastindex + 1);
+ }
+
+ printer.Print(
+ "class ^name^\n"
+ "{\n",
+ "name", fullname);
+ Indent(&printer);
+
+ for (int i = 0; i < en->value_count(); i++) {
+ const EnumValueDescriptor* value = en->value(i);
+ GenerateEnumValueDocComment(&printer, value);
+ printer.Print("const ^name^ = ^number^;\n",
+ "name", ConstantNamePrefix(value->name()) + value->name(),
+ "number", IntToString(value->number()));
+ }
+
+ printer.Print("\nprivate static $valueToName = [\n");
+ Indent(&printer);
+ for (int i = 0; i < en->value_count(); i++) {
+ const EnumValueDescriptor* value = en->value(i);
+ printer.Print("self::^name^ => '^name^',\n",
+ "name", ConstantNamePrefix(value->name()) + value->name());
+ }
+ Outdent(&printer);
+ printer.Print("];\n");
+
+ printer.Print(
+ "\npublic static function name($value)\n"
+ "{\n");
+ Indent(&printer);
+ printer.Print("if (!isset(self::$valueToName[$value])) {\n");
+ Indent(&printer);
+ printer.Print("throw new UnexpectedValueException(sprintf(\n");
+ Indent(&printer);
+ Indent(&printer);
+ printer.Print("'Enum %s has no name defined for value %s', __CLASS__, $value));\n");
+ Outdent(&printer);
+ Outdent(&printer);
+ Outdent(&printer);
+ printer.Print("}\n"
+ "return self::$valueToName[$value];\n");
+ Outdent(&printer);
+ printer.Print("}\n\n");
+
+ printer.Print(
+ "\npublic static function value($name)\n"
+ "{\n");
+ Indent(&printer);
+ printer.Print("$const = __CLASS__ . '::' . strtoupper($name);\n"
+ "if (!defined($const)) {\n");
+ Indent(&printer);
+ printer.Print("throw new UnexpectedValueException(sprintf(\n");
+ Indent(&printer);
+ Indent(&printer);
+ printer.Print("'Enum %s has no value defined for name %s', __CLASS__, $name));\n");
+ Outdent(&printer);
+ Outdent(&printer);
+ Outdent(&printer);
+ printer.Print("}\n"
+ "return constant($const);\n");
+ Outdent(&printer);
+ printer.Print("}\n");
+
+ Outdent(&printer);
+ printer.Print("}\n\n");
+
+ // write legacy file for backwards compatibility with nested messages and enums
+ if (en->containing_type() != NULL) {
+ printer.Print(
+ "// Adding a class alias for backwards compatibility with the previous class name.\n");
+ printer.Print(
+ "class_alias(^new^::class, \\^old^::class);\n\n",
+ "new", fullname,
+ "old", LegacyFullClassName(en, options));
+ LegacyGenerateClassFile(file, en, options, generator_context);
+ }
+}
+
+void GenerateMessageFile(const FileDescriptor* file, const Descriptor* message,
+ const Options& options,
+ GeneratorContext* generator_context) {
+ // Don't generate MapEntry messages -- we use the PHP extension's native
+ // support for map fields instead.
+ if (message->options().map_entry()) {
+ return;
+ }
+
+ std::string filename = GeneratedClassFileName(message, options);
+ std::unique_ptr<io::ZeroCopyOutputStream> output(
+ generator_context->Open(filename));
+ io::Printer printer(output.get(), '^');
+
+ GenerateHead(file, &printer);
+
+ std::string fullname = FilenameToClassname(filename);
+ int lastindex = fullname.find_last_of("\\");
+
+ if (lastindex != std::string::npos) {
+ printer.Print(
+ "namespace ^name^;\n\n",
+ "name", fullname.substr(0, lastindex));
+ }
+
+ GenerateUseDeclaration(options, &printer);
+
+ GenerateMessageDocComment(&printer, message, options);
+ if (lastindex != std::string::npos) {
+ fullname = fullname.substr(lastindex + 1);
+ }
+
+ std::string base;
+
+ switch (message->well_known_type()) {
+ case Descriptor::WELLKNOWNTYPE_ANY:
+ base = "\\Google\\Protobuf\\Internal\\AnyBase";
+ break;
+ case Descriptor::WELLKNOWNTYPE_TIMESTAMP:
+ base = "\\Google\\Protobuf\\Internal\\TimestampBase";
+ break;
+ default:
+ base = "\\Google\\Protobuf\\Internal\\Message";
+ break;
+ }
+
+ printer.Print(
+ "class ^name^ extends ^base^\n"
+ "{\n",
+ "base", base,
+ "name", fullname);
+ Indent(&printer);
+
+ // Field and oneof definitions.
+ for (int i = 0; i < message->field_count(); i++) {
+ const FieldDescriptor* field = message->field(i);
+ GenerateField(field, &printer, options);
+ }
+ for (int i = 0; i < message->real_oneof_decl_count(); i++) {
+ const OneofDescriptor* oneof = message->oneof_decl(i);
+ GenerateOneofField(oneof, &printer);
+ }
+ printer.Print("\n");
+
+ GenerateMessageConstructorDocComment(&printer, message, options);
+ printer.Print(
+ "public function __construct($data = NULL) {\n");
+ Indent(&printer);
+
+ std::string metadata_filename = GeneratedMetadataFileName(file, options);
+ std::string metadata_fullname = FilenameToClassname(metadata_filename);
+ printer.Print(
+ "\\^fullname^::initOnce();\n",
+ "fullname", metadata_fullname);
+
+ printer.Print(
+ "parent::__construct($data);\n");
+
+ Outdent(&printer);
+ printer.Print("}\n\n");
+
+ // Field and oneof accessors.
+ for (int i = 0; i < message->field_count(); i++) {
+ const FieldDescriptor* field = message->field(i);
+ GenerateFieldAccessor(field, options, &printer);
+ }
+ for (int i = 0; i < message->real_oneof_decl_count(); i++) {
+ const OneofDescriptor* oneof = message->oneof_decl(i);
+ printer.Print(
+ "/**\n"
+ " * @return string\n"
+ " */\n"
+ "public function get^camel_name^()\n"
+ "{\n"
+ " return $this->whichOneof(\"^name^\");\n"
+ "}\n\n",
+ "camel_name", UnderscoresToCamelCase(oneof->name(), true), "name",
+ oneof->name());
+ }
+
+ Outdent(&printer);
+ printer.Print("}\n\n");
+
+ // write legacy file for backwards compatibility with nested messages and enums
+ if (message->containing_type() != NULL) {
+ printer.Print(
+ "// Adding a class alias for backwards compatibility with the previous class name.\n");
+ printer.Print(
+ "class_alias(^new^::class, \\^old^::class);\n\n",
+ "new", fullname,
+ "old", LegacyFullClassName(message, options));
+ LegacyGenerateClassFile(file, message, options, generator_context);
+ }
+
+ // Nested messages and enums.
+ for (int i = 0; i < message->nested_type_count(); i++) {
+ GenerateMessageFile(file, message->nested_type(i), options,
+ generator_context);
+ }
+ for (int i = 0; i < message->enum_type_count(); i++) {
+ GenerateEnumFile(file, message->enum_type(i), options, generator_context);
+ }
+}
+
+void GenerateServiceFile(
+ const FileDescriptor* file, const ServiceDescriptor* service,
+ const Options& options, GeneratorContext* generator_context) {
+ std::string filename = GeneratedServiceFileName(service, options);
+ std::unique_ptr<io::ZeroCopyOutputStream> output(
+ generator_context->Open(filename));
+ io::Printer printer(output.get(), '^');
+
+ GenerateHead(file, &printer);
+
+ std::string fullname = FilenameToClassname(filename);
+ int lastindex = fullname.find_last_of("\\");
+
+ if (!file->options().php_namespace().empty() ||
+ (!file->options().has_php_namespace() && !file->package().empty()) ||
+ lastindex != std::string::npos) {
+ printer.Print(
+ "namespace ^name^;\n\n",
+ "name", fullname.substr(0, lastindex));
+ }
+
+ GenerateServiceDocComment(&printer, service);
+
+ if (lastindex != std::string::npos) {
+ printer.Print(
+ "interface ^name^\n"
+ "{\n",
+ "name", fullname.substr(lastindex + 1));
+ } else {
+ printer.Print(
+ "interface ^name^\n"
+ "{\n",
+ "name", fullname);
+ }
+
+ Indent(&printer);
+
+ for (int i = 0; i < service->method_count(); i++) {
+ const MethodDescriptor* method = service->method(i);
+ GenerateServiceMethodDocComment(&printer, method);
+ GenerateServiceMethod(method, &printer);
+ }
+
+ Outdent(&printer);
+ printer.Print("}\n\n");
+}
+
+void GenerateFile(const FileDescriptor* file, const Options& options,
+ GeneratorContext* generator_context) {
+ GenerateMetadataFile(file, options, generator_context);
+
+ for (int i = 0; i < file->message_type_count(); i++) {
+ GenerateMessageFile(file, file->message_type(i), options,
+ generator_context);
+ }
+ for (int i = 0; i < file->enum_type_count(); i++) {
+ GenerateEnumFile(file, file->enum_type(i), options, generator_context);
+ }
+ if (file->options().php_generic_services()) {
+ for (int i = 0; i < file->service_count(); i++) {
+ GenerateServiceFile(file, file->service(i), options, generator_context);
+ }
+ }
+}
+
+static std::string EscapePhpdoc(const std::string& input) {
+ std::string result;
+ result.reserve(input.size() * 2);
+
+ char prev = '*';
+
+ for (std::string::size_type i = 0; i < input.size(); i++) {
+ char c = input[i];
+ switch (c) {
+ case '*':
+ // Avoid "/*".
+ if (prev == '/') {
+ result.append("&#42;");
+ } else {
+ result.push_back(c);
+ }
+ break;
+ case '/':
+ // Avoid "*/".
+ if (prev == '*') {
+ result.append("&#47;");
+ } else {
+ result.push_back(c);
+ }
+ break;
+ case '@':
+ // '@' starts phpdoc tags including the @deprecated tag, which will
+ // cause a compile-time error if inserted before a declaration that
+ // does not have a corresponding @Deprecated annotation.
+ result.append("&#64;");
+ break;
+ default:
+ result.push_back(c);
+ break;
+ }
+
+ prev = c;
+ }
+
+ return result;
+}
+
+static void GenerateDocCommentBodyForLocation(
+ io::Printer* printer, const SourceLocation& location, bool trailingNewline,
+ int indentCount) {
+ std::string comments = location.leading_comments.empty()
+ ? location.trailing_comments
+ : location.leading_comments;
+ if (!comments.empty()) {
+ // TODO(teboring): Ideally we should parse the comment text as Markdown and
+ // write it back as HTML, but this requires a Markdown parser. For now
+ // we just use the proto comments unchanged.
+
+ // If the comment itself contains block comment start or end markers,
+ // HTML-escape them so that they don't accidentally close the doc comment.
+ comments = EscapePhpdoc(comments);
+
+ std::vector<std::string> lines = Split(comments, "\n", true);
+ while (!lines.empty() && lines.back().empty()) {
+ lines.pop_back();
+ }
+
+ for (int i = 0; i < lines.size(); i++) {
+ // Most lines should start with a space. Watch out for lines that start
+ // with a /, since putting that right after the leading asterisk will
+ // close the comment.
+ if (indentCount == 0 && !lines[i].empty() && lines[i][0] == '/') {
+ printer->Print(" * ^line^\n", "line", lines[i]);
+ } else {
+ std::string indent = std::string(indentCount, ' ');
+ printer->Print(" *^ind^^line^\n", "ind", indent, "line", lines[i]);
+ }
+ }
+ if (trailingNewline) {
+ printer->Print(" *\n");
+ }
+ }
+}
+
+template <typename DescriptorType>
+static void GenerateDocCommentBody(
+ io::Printer* printer, const DescriptorType* descriptor) {
+ SourceLocation location;
+ if (descriptor->GetSourceLocation(&location)) {
+ GenerateDocCommentBodyForLocation(printer, location, true, 0);
+ }
+}
+
+static std::string FirstLineOf(const std::string& value) {
+ std::string result = value;
+
+ std::string::size_type pos = result.find_first_of('\n');
+ if (pos != std::string::npos) {
+ result.erase(pos);
+ }
+
+ return result;
+}
+
+void GenerateMessageDocComment(io::Printer* printer, const Descriptor* message,
+ const Options& options) {
+ printer->Print("/**\n");
+ GenerateDocCommentBody(printer, message);
+ printer->Print(
+ " * Generated from protobuf message <code>^messagename^</code>\n"
+ " */\n",
+ "fullname", EscapePhpdoc(FullClassName(message, options)),
+ "messagename", EscapePhpdoc(message->full_name()));
+}
+
+void GenerateMessageConstructorDocComment(io::Printer* printer,
+ const Descriptor* message,
+ const Options& options) {
+ // In theory we should have slightly different comments for setters, getters,
+ // etc., but in practice everyone already knows the difference between these
+ // so it's redundant information.
+
+ // We start the comment with the main body based on the comments from the
+ // .proto file (if present). We then end with the field declaration, e.g.:
+ // optional string foo = 5;
+ // If the field is a group, the debug string might end with {.
+ printer->Print("/**\n");
+ printer->Print(" * Constructor.\n");
+ printer->Print(" *\n");
+ printer->Print(" * @param array $data {\n");
+ printer->Print(" * Optional. Data for populating the Message object.\n");
+ printer->Print(" *\n");
+ for (int i = 0; i < message->field_count(); i++) {
+ const FieldDescriptor* field = message->field(i);
+ printer->Print(" * @type ^php_type^ $^var^\n",
+ "php_type", PhpSetterTypeName(field, options),
+ "var", field->name());
+ SourceLocation location;
+ if (field->GetSourceLocation(&location)) {
+ GenerateDocCommentBodyForLocation(printer, location, false, 10);
+ }
+ }
+ printer->Print(" * }\n");
+ printer->Print(" */\n");
+}
+
+void GenerateServiceDocComment(io::Printer* printer,
+ const ServiceDescriptor* service) {
+ printer->Print("/**\n");
+ GenerateDocCommentBody(printer, service);
+ printer->Print(
+ " * Protobuf type <code>^fullname^</code>\n"
+ " */\n",
+ "fullname", EscapePhpdoc(service->full_name()));
+}
+
+void GenerateFieldDocComment(io::Printer* printer, const FieldDescriptor* field,
+ const Options& options, int function_type) {
+ // In theory we should have slightly different comments for setters, getters,
+ // etc., but in practice everyone already knows the difference between these
+ // so it's redundant information.
+
+ // We start the comment with the main body based on the comments from the
+ // .proto file (if present). We then end with the field declaration, e.g.:
+ // optional string foo = 5;
+ // If the field is a group, the debug string might end with {.
+ printer->Print("/**\n");
+ GenerateDocCommentBody(printer, field);
+ printer->Print(
+ " * Generated from protobuf field <code>^def^</code>\n",
+ "def", EscapePhpdoc(FirstLineOf(field->DebugString())));
+ if (function_type == kFieldSetter) {
+ printer->Print(" * @param ^php_type^ $var\n",
+ "php_type", PhpSetterTypeName(field, options));
+ printer->Print(" * @return $this\n");
+ } else if (function_type == kFieldGetter) {
+ bool can_return_null = field->has_presence() &&
+ field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE;
+ printer->Print(" * @return ^php_type^^maybe_null^\n",
+ "php_type", PhpGetterTypeName(field, options),
+ "maybe_null", can_return_null ? "|null" : "");
+ }
+ if (field->options().deprecated()) {
+ printer->Print(" * @deprecated\n");
+ }
+ printer->Print(" */\n");
+}
+
+void GenerateWrapperFieldGetterDocComment(io::Printer* printer, const FieldDescriptor* field) {
+ // Generate a doc comment for the special getXXXValue methods that are
+ // generated for wrapper types.
+ const FieldDescriptor* primitiveField = field->message_type()->FindFieldByName("value");
+ printer->Print("/**\n");
+ printer->Print(
+ " * Returns the unboxed value from <code>get^camel_name^()</code>\n\n",
+ "camel_name", UnderscoresToCamelCase(field->name(), true));
+ GenerateDocCommentBody(printer, field);
+ printer->Print(
+ " * Generated from protobuf field <code>^def^</code>\n",
+ "def", EscapePhpdoc(FirstLineOf(field->DebugString())));
+ printer->Print(" * @return ^php_type^|null\n",
+ "php_type", PhpGetterTypeName(primitiveField, false));
+ printer->Print(" */\n");
+}
+
+void GenerateWrapperFieldSetterDocComment(io::Printer* printer, const FieldDescriptor* field) {
+ // Generate a doc comment for the special setXXXValue methods that are
+ // generated for wrapper types.
+ const FieldDescriptor* primitiveField = field->message_type()->FindFieldByName("value");
+ printer->Print("/**\n");
+ printer->Print(
+ " * Sets the field by wrapping a primitive type in a ^message_name^ object.\n\n",
+ "message_name", FullClassName(field->message_type(), false));
+ GenerateDocCommentBody(printer, field);
+ printer->Print(
+ " * Generated from protobuf field <code>^def^</code>\n",
+ "def", EscapePhpdoc(FirstLineOf(field->DebugString())));
+ printer->Print(" * @param ^php_type^|null $var\n",
+ "php_type", PhpSetterTypeName(primitiveField, false));
+ printer->Print(" * @return $this\n");
+ printer->Print(" */\n");
+}
+
+void GenerateEnumDocComment(io::Printer* printer, const EnumDescriptor* enum_,
+ const Options& options) {
+ printer->Print("/**\n");
+ GenerateDocCommentBody(printer, enum_);
+ printer->Print(
+ " * Protobuf type <code>^fullname^</code>\n"
+ " */\n",
+ "fullname", EscapePhpdoc(enum_->full_name()));
+}
+
+void GenerateEnumValueDocComment(io::Printer* printer,
+ const EnumValueDescriptor* value) {
+ printer->Print("/**\n");
+ GenerateDocCommentBody(printer, value);
+ printer->Print(
+ " * Generated from protobuf enum <code>^def^</code>\n"
+ " */\n",
+ "def", EscapePhpdoc(FirstLineOf(value->DebugString())));
+}
+
+void GenerateServiceMethodDocComment(io::Printer* printer,
+ const MethodDescriptor* method) {
+ printer->Print("/**\n");
+ GenerateDocCommentBody(printer, method);
+ printer->Print(
+ " * Method <code>^method_name^</code>\n"
+ " *\n",
+ "method_name", EscapePhpdoc(UnderscoresToCamelCase(method->name(), false)));
+ printer->Print(
+ " * @param \\^input_type^ $request\n",
+ "input_type", EscapePhpdoc(FullClassName(method->input_type(), false)));
+ printer->Print(
+ " * @return \\^return_type^\n"
+ " */\n",
+ "return_type", EscapePhpdoc(FullClassName(method->output_type(), false)));
+}
+
+std::string FilenameCName(const FileDescriptor* file) {
+ std::string c_name = file->name();
+ c_name = StringReplace(c_name, ".", "_", true);
+ c_name = StringReplace(c_name, "/", "_", true);
+ return c_name;
+}
+
+void GenerateCEnum(const EnumDescriptor* desc, io::Printer* printer) {
+ std::string c_name = desc->full_name();
+ c_name = StringReplace(c_name, ".", "_", true);
+ std::string php_name = FullClassName(desc, Options());
+ php_name = StringReplace(php_name, "\\", "\\\\", true);
+ printer->Print(
+ "/* $c_name$ */\n"
+ "\n"
+ "zend_class_entry* $c_name$_ce;\n"
+ "\n"
+ "PHP_METHOD($c_name$, name) {\n"
+ " $file_c_name$_AddDescriptor();\n"
+ " const upb_symtab *symtab = DescriptorPool_GetSymbolTable();\n"
+ " const upb_enumdef *e = upb_symtab_lookupenum(symtab, \"$name$\");\n"
+ " const char *name;\n"
+ " zend_long value;\n"
+ " if (zend_parse_parameters(ZEND_NUM_ARGS(), \"l\", &value) ==\n"
+ " FAILURE) {\n"
+ " return;\n"
+ " }\n"
+ " name = upb_enumdef_iton(e, value);\n"
+ " if (!name) {\n"
+ " zend_throw_exception_ex(NULL, 0,\n"
+ " \"$php_name$ has no name \"\n"
+ " \"defined for value \" ZEND_LONG_FMT \".\",\n"
+ " value);\n"
+ " return;\n"
+ " }\n"
+ " RETURN_STRING(name);\n"
+ "}\n"
+ "\n"
+ "PHP_METHOD($c_name$, value) {\n"
+ " $file_c_name$_AddDescriptor();\n"
+ " const upb_symtab *symtab = DescriptorPool_GetSymbolTable();\n"
+ " const upb_enumdef *e = upb_symtab_lookupenum(symtab, \"$name$\");\n"
+ " char *name = NULL;\n"
+ " size_t name_len;\n"
+ " int32_t num;\n"
+ " if (zend_parse_parameters(ZEND_NUM_ARGS(), \"s\", &name,\n"
+ " &name_len) == FAILURE) {\n"
+ " return;\n"
+ " }\n"
+ " if (!upb_enumdef_ntoi(e, name, name_len, &num)) {\n"
+ " zend_throw_exception_ex(NULL, 0,\n"
+ " \"$php_name$ has no value \"\n"
+ " \"defined for name %s.\",\n"
+ " name);\n"
+ " return;\n"
+ " }\n"
+ " RETURN_LONG(num);\n"
+ "}\n"
+ "\n"
+ "static zend_function_entry $c_name$_phpmethods[] = {\n"
+ " PHP_ME($c_name$, name, arginfo_lookup, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)\n"
+ " PHP_ME($c_name$, value, arginfo_lookup, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)\n"
+ " ZEND_FE_END\n"
+ "};\n"
+ "\n"
+ "static void $c_name$_ModuleInit() {\n"
+ " zend_class_entry tmp_ce;\n"
+ "\n"
+ " INIT_CLASS_ENTRY(tmp_ce, \"$php_name$\",\n"
+ " $c_name$_phpmethods);\n"
+ "\n"
+ " $c_name$_ce = zend_register_internal_class(&tmp_ce);\n",
+ "name", desc->full_name(),
+ "file_c_name", FilenameCName(desc->file()),
+ "c_name", c_name,
+ "php_name", php_name);
+
+ for (int i = 0; i < desc->value_count(); i++) {
+ const EnumValueDescriptor* value = desc->value(i);
+ printer->Print(
+ " zend_declare_class_constant_long($c_name$_ce, \"$name$\",\n"
+ " strlen(\"$name$\"), $num$);\n",
+ "c_name", c_name,
+ "name", value->name(),
+ "num", std::to_string(value->number()));
+ }
+
+ printer->Print(
+ "}\n"
+ "\n");
+}
+
+void GenerateCMessage(const Descriptor* message, io::Printer* printer) {
+ std::string c_name = message->full_name();
+ c_name = StringReplace(c_name, ".", "_", true);
+ std::string php_name = FullClassName(message, Options());
+ php_name = StringReplace(php_name, "\\", "\\\\", true);
+ printer->Print(
+ "/* $c_name$ */\n"
+ "\n"
+ "zend_class_entry* $c_name$_ce;\n"
+ "\n"
+ "static PHP_METHOD($c_name$, __construct) {\n"
+ " $file_c_name$_AddDescriptor();\n"
+ " zim_Message___construct(INTERNAL_FUNCTION_PARAM_PASSTHRU);\n"
+ "}\n"
+ "\n",
+ "file_c_name", FilenameCName(message->file()),
+ "c_name", c_name);
+
+ for (int i = 0; i < message->field_count(); i++) {
+ auto field = message->field(i);
+ printer->Print(
+ "static PHP_METHOD($c_name$, get$camel_name$) {\n"
+ " Message* intern = (Message*)Z_OBJ_P(getThis());\n"
+ " const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef,\n"
+ " \"$name$\");\n"
+ " zval ret;\n"
+ " Message_get(intern, f, &ret);\n"
+ " RETURN_COPY_VALUE(&ret);\n"
+ "}\n"
+ "\n"
+ "static PHP_METHOD($c_name$, set$camel_name$) {\n"
+ " Message* intern = (Message*)Z_OBJ_P(getThis());\n"
+ " const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef,\n"
+ " \"$name$\");\n"
+ " zval *val;\n"
+ " if (zend_parse_parameters(ZEND_NUM_ARGS(), \"z\", &val)\n"
+ " == FAILURE) {\n"
+ " return;\n"
+ " }\n"
+ " Message_set(intern, f, val);\n"
+ " RETURN_COPY(getThis());\n"
+ "}\n"
+ "\n",
+ "c_name", c_name,
+ "name", field->name(),
+ "camel_name", UnderscoresToCamelCase(field->name(), true));
+ }
+
+ for (int i = 0; i < message->real_oneof_decl_count(); i++) {
+ auto oneof = message->oneof_decl(i);
+ printer->Print(
+ "static PHP_METHOD($c_name$, get$camel_name$) {\n"
+ " Message* intern = (Message*)Z_OBJ_P(getThis());\n"
+ " const upb_oneofdef *oneof = upb_msgdef_ntooz(intern->desc->msgdef,\n"
+ " \"$name$\");\n"
+ " const upb_fielddef *field = upb_msg_whichoneof(intern->msg, oneof);\n"
+ " RETURN_STRING(field ? upb_fielddef_name(field) : \"\");\n"
+ "}\n",
+ "c_name", c_name,
+ "name", oneof->name(),
+ "camel_name", UnderscoresToCamelCase(oneof->name(), true));
+ }
+
+ switch (message->well_known_type()) {
+ case Descriptor::WELLKNOWNTYPE_ANY:
+ printer->Print(
+ "ZEND_BEGIN_ARG_INFO_EX(arginfo_is, 0, 0, 1)\n"
+ " ZEND_ARG_INFO(0, proto)\n"
+ "ZEND_END_ARG_INFO()\n"
+ "\n"
+ );
+ break;
+ case Descriptor::WELLKNOWNTYPE_TIMESTAMP:
+ printer->Print(
+ "ZEND_BEGIN_ARG_INFO_EX(arginfo_timestamp_fromdatetime, 0, 0, 1)\n"
+ " ZEND_ARG_INFO(0, datetime)\n"
+ "ZEND_END_ARG_INFO()\n"
+ "\n"
+ );
+ break;
+ default:
+ break;
+ }
+
+ printer->Print(
+ "static zend_function_entry $c_name$_phpmethods[] = {\n"
+ " PHP_ME($c_name$, __construct, arginfo_construct, ZEND_ACC_PUBLIC)\n",
+ "c_name", c_name);
+
+ for (int i = 0; i < message->field_count(); i++) {
+ auto field = message->field(i);
+ printer->Print(
+ " PHP_ME($c_name$, get$camel_name$, arginfo_void, ZEND_ACC_PUBLIC)\n"
+ " PHP_ME($c_name$, set$camel_name$, arginfo_setter, ZEND_ACC_PUBLIC)\n",
+ "c_name", c_name,
+ "camel_name", UnderscoresToCamelCase(field->name(), true));
+ }
+
+ for (int i = 0; i < message->real_oneof_decl_count(); i++) {
+ auto oneof = message->oneof_decl(i);
+ printer->Print(
+ " PHP_ME($c_name$, get$camel_name$, arginfo_void, ZEND_ACC_PUBLIC)\n",
+ "c_name", c_name,
+ "camel_name", UnderscoresToCamelCase(oneof->name(), true));
+ }
+
+ // Extra hand-written functions added to the well-known types.
+ switch (message->well_known_type()) {
+ case Descriptor::WELLKNOWNTYPE_ANY:
+ printer->Print(
+ " PHP_ME($c_name$, is, arginfo_is, ZEND_ACC_PUBLIC)\n"
+ " PHP_ME($c_name$, pack, arginfo_setter, ZEND_ACC_PUBLIC)\n"
+ " PHP_ME($c_name$, unpack, arginfo_void, ZEND_ACC_PUBLIC)\n",
+ "c_name", c_name);
+ break;
+ case Descriptor::WELLKNOWNTYPE_TIMESTAMP:
+ printer->Print(
+ " PHP_ME($c_name$, fromDateTime, arginfo_timestamp_fromdatetime, ZEND_ACC_PUBLIC)\n"
+ " PHP_ME($c_name$, toDateTime, arginfo_void, ZEND_ACC_PUBLIC)\n",
+ "c_name", c_name);
+ break;
+ default:
+ break;
+ }
+
+ printer->Print(
+ " ZEND_FE_END\n"
+ "};\n"
+ "\n"
+ "static void $c_name$_ModuleInit() {\n"
+ " zend_class_entry tmp_ce;\n"
+ "\n"
+ " INIT_CLASS_ENTRY(tmp_ce, \"$php_name$\",\n"
+ " $c_name$_phpmethods);\n"
+ "\n"
+ " $c_name$_ce = zend_register_internal_class(&tmp_ce);\n"
+ " $c_name$_ce->ce_flags |= ZEND_ACC_FINAL;\n"
+ " $c_name$_ce->create_object = Message_create;\n"
+ " zend_do_inheritance($c_name$_ce, message_ce);\n"
+ "}\n"
+ "\n",
+ "c_name", c_name,
+ "php_name", php_name);
+
+ for (int i = 0; i < message->nested_type_count(); i++) {
+ GenerateCMessage(message->nested_type(i), printer);
+ }
+ for (int i = 0; i < message->enum_type_count(); i++) {
+ GenerateCEnum(message->enum_type(i), printer);
+ }
+}
+
+void GenerateEnumCInit(const EnumDescriptor* desc, io::Printer* printer) {
+ std::string c_name = desc->full_name();
+ c_name = StringReplace(c_name, ".", "_", true);
+
+ printer->Print(
+ " $c_name$_ModuleInit();\n",
+ "c_name", c_name);
+}
+
+void GenerateCInit(const Descriptor* message, io::Printer* printer) {
+ std::string c_name = message->full_name();
+ c_name = StringReplace(c_name, ".", "_", true);
+
+ printer->Print(
+ " $c_name$_ModuleInit();\n",
+ "c_name", c_name);
+
+ for (int i = 0; i < message->nested_type_count(); i++) {
+ GenerateCInit(message->nested_type(i), printer);
+ }
+ for (int i = 0; i < message->enum_type_count(); i++) {
+ GenerateEnumCInit(message->enum_type(i), printer);
+ }
+}
+
+void GenerateCWellKnownTypes(const std::vector<const FileDescriptor*>& files,
+ GeneratorContext* context) {
+ std::unique_ptr<io::ZeroCopyOutputStream> output(
+ context->Open("../ext/google/protobuf/wkt.inc"));
+ io::Printer printer(output.get(), '$');
+
+ printer.Print(
+ "// This file is generated from the .proto files for the well-known\n"
+ "// types. Do not edit!\n\n");
+
+ printer.Print(
+ "ZEND_BEGIN_ARG_INFO_EX(arginfo_lookup, 0, 0, 1)\n"
+ " ZEND_ARG_INFO(0, key)\n"
+ "ZEND_END_ARG_INFO()\n"
+ "\n"
+ );
+
+ for (auto file : files) {
+ printer.Print(
+ "static void $c_name$_AddDescriptor();\n",
+ "c_name", FilenameCName(file));
+ }
+
+ for (auto file : files) {
+ std::string c_name = FilenameCName(file);
+ std::string metadata_filename = GeneratedMetadataFileName(file, Options());
+ std::string metadata_classname = FilenameToClassname(metadata_filename);
+ std::string metadata_c_name =
+ StringReplace(metadata_classname, "\\", "_", true);
+ metadata_classname = StringReplace(metadata_classname, "\\", "\\\\", true);
+ FileDescriptorProto file_proto;
+ file->CopyTo(&file_proto);
+ std::string serialized;
+ file_proto.SerializeToString(&serialized);
+ printer.Print(
+ "/* $filename$ */\n"
+ "\n"
+ "zend_class_entry* $metadata_c_name$_ce;\n"
+ "\n"
+ "const char $c_name$_descriptor [$size$] = {\n",
+ "filename", file->name(),
+ "c_name", c_name,
+ "metadata_c_name", metadata_c_name,
+ "size", std::to_string(serialized.size()));
+
+ for (size_t i = 0; i < serialized.size();) {
+ for (size_t j = 0; j < 25 && i < serialized.size(); ++i, ++j) {
+ printer.Print("'$ch$', ", "ch", CEscape(serialized.substr(i, 1)));
+ }
+ printer.Print("\n");
+ }
+
+ printer.Print(
+ "};\n"
+ "\n"
+ "static void $c_name$_AddDescriptor() {\n"
+ " if (DescriptorPool_HasFile(\"$filename$\")) return;\n",
+ "filename", file->name(),
+ "c_name", c_name,
+ "metadata_c_name", metadata_c_name);
+
+ for (int i = 0; i < file->dependency_count(); i++) {
+ std::string dep_c_name = FilenameCName(file->dependency(i));
+ printer.Print(
+ " $dep_c_name$_AddDescriptor();\n",
+ "dep_c_name", dep_c_name);
+ }
+
+ printer.Print(
+ " DescriptorPool_AddDescriptor(\"$filename$\", $c_name$_descriptor,\n"
+ " sizeof($c_name$_descriptor));\n"
+ "}\n"
+ "\n"
+ "static PHP_METHOD($metadata_c_name$, initOnce) {\n"
+ " $c_name$_AddDescriptor();\n"
+ "}\n"
+ "\n"
+ "static zend_function_entry $metadata_c_name$_methods[] = {\n"
+ " PHP_ME($metadata_c_name$, initOnce, arginfo_void, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)\n"
+ " ZEND_FE_END\n"
+ "};\n"
+ "\n"
+ "static void $metadata_c_name$_ModuleInit() {\n"
+ " zend_class_entry tmp_ce;\n"
+ "\n"
+ " INIT_CLASS_ENTRY(tmp_ce, \"$metadata_classname$\",\n"
+ " $metadata_c_name$_methods);\n"
+ "\n"
+ " $metadata_c_name$_ce = zend_register_internal_class(&tmp_ce);\n"
+ "}\n"
+ "\n",
+ "filename", file->name(),
+ "c_name", c_name,
+ "metadata_c_name", metadata_c_name,
+ "metadata_classname", metadata_classname);
+ for (int i = 0; i < file->message_type_count(); i++) {
+ GenerateCMessage(file->message_type(i), &printer);
+ }
+ for (int i = 0; i < file->enum_type_count(); i++) {
+ GenerateCEnum(file->enum_type(i), &printer);
+ }
+ }
+
+ printer.Print(
+ "static void WellKnownTypes_ModuleInit() {\n");
+
+ for (auto file : files) {
+ std::string metadata_filename = GeneratedMetadataFileName(file, Options());
+ std::string metadata_classname = FilenameToClassname(metadata_filename);
+ std::string metadata_c_name =
+ StringReplace(metadata_classname, "\\", "_", true);
+ printer.Print(
+ " $metadata_c_name$_ModuleInit();\n",
+ "metadata_c_name", metadata_c_name);
+ for (int i = 0; i < file->message_type_count(); i++) {
+ GenerateCInit(file->message_type(i), &printer);
+ }
+ for (int i = 0; i < file->enum_type_count(); i++) {
+ GenerateEnumCInit(file->enum_type(i), &printer);
+ }
+ }
+
+ printer.Print(
+ "}\n");
+}
+
+} // namespace
+
+std::string GeneratedClassName(const Descriptor* desc) {
+ return GeneratedClassNameImpl(desc);
+}
+
+std::string GeneratedClassName(const EnumDescriptor* desc) {
+ return GeneratedClassNameImpl(desc);
+}
+
+std::string GeneratedClassName(const ServiceDescriptor* desc) {
+ return GeneratedClassNameImpl(desc);
+}
+
+bool Generator::Generate(const FileDescriptor* file,
+ const std::string& parameter,
+ GeneratorContext* generator_context,
+ std::string* error) const {
+ return Generate(file, Options(), generator_context, error);
+}
+
+bool Generator::Generate(const FileDescriptor* file, const Options& options,
+ GeneratorContext* generator_context,
+ std::string* error) const {
+ if (options.is_descriptor && file->name() != kDescriptorFile) {
+ *error =
+ "Can only generate PHP code for google/protobuf/descriptor.proto.\n";
+ return false;
+ }
+
+ if (!options.is_descriptor && file->syntax() != FileDescriptor::SYNTAX_PROTO3) {
+ *error =
+ "Can only generate PHP code for proto3 .proto files.\n"
+ "Please add 'syntax = \"proto3\";' to the top of your .proto file.\n";
+ return false;
+ }
+
+ GenerateFile(file, options, generator_context);
+
+ return true;
+}
+
+bool Generator::GenerateAll(const std::vector<const FileDescriptor*>& files,
+ const std::string& parameter,
+ GeneratorContext* generator_context,
+ std::string* error) const {
+ Options options;
+
+ for (const auto& option : Split(parameter, ",", true)) {
+ const std::vector<std::string> option_pair = Split(option, "=", true);
+ if (HasPrefixString(option_pair[0], "aggregate_metadata")) {
+ options.aggregate_metadata = true;
+ for (const auto& prefix : Split(option_pair[1], "#", false)) {
+ options.aggregate_metadata_prefixes.emplace(prefix);
+ GOOGLE_LOG(INFO) << prefix;
+ }
+ } else if (option_pair[0] == "internal") {
+ options.is_descriptor = true;
+ } else if (option_pair[0] == "internal_generate_c_wkt") {
+ GenerateCWellKnownTypes(files, generator_context);
+ } else {
+ GOOGLE_LOG(FATAL) << "Unknown codegen option: " << option_pair[0];
+ }
+ }
+
+ for (auto file : files) {
+ if (!Generate(file, options, generator_context, error)) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+} // namespace php
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/php/php_generator.h b/NorthstarDedicatedTest/include/protobuf/compiler/php/php_generator.h
new file mode 100644
index 00000000..d3a977aa
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/php/php_generator.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.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_PHP_GENERATOR_H__
+#define GOOGLE_PROTOBUF_COMPILER_PHP_GENERATOR_H__
+
+#include <compiler/code_generator.h>
+#include <descriptor.h>
+
+#include <string>
+
+#include <port_def.inc>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace php {
+
+struct Options;
+
+class PROTOC_EXPORT Generator : public CodeGenerator {
+ public:
+ virtual bool Generate(
+ const FileDescriptor* file,
+ const std::string& parameter,
+ GeneratorContext* generator_context,
+ std::string* error) const override;
+
+ bool GenerateAll(const std::vector<const FileDescriptor*>& files,
+ const std::string& parameter,
+ GeneratorContext* generator_context,
+ std::string* error) const override;
+
+ uint64_t GetSupportedFeatures() const override {
+ return FEATURE_PROTO3_OPTIONAL;
+ }
+
+ private:
+ bool Generate(
+ const FileDescriptor* file,
+ const Options& options,
+ GeneratorContext* generator_context,
+ std::string* error) const;
+};
+
+// To skip reserved keywords in php, some generated classname are prefixed.
+// Other code generators may need following API to figure out the actual
+// classname.
+PROTOC_EXPORT std::string GeneratedClassName(const Descriptor* desc);
+PROTOC_EXPORT std::string GeneratedClassName(const EnumDescriptor* desc);
+PROTOC_EXPORT std::string GeneratedClassName(const ServiceDescriptor* desc);
+
+inline bool IsWrapperType(const FieldDescriptor* descriptor) {
+ return descriptor->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
+ descriptor->message_type()->file()->name() == "google/protobuf/wrappers.proto";
+}
+
+} // namespace php
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#include <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_COMPILER_PHP_GENERATOR_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/plugin.cc b/NorthstarDedicatedTest/include/protobuf/compiler/plugin.cc
new file mode 100644
index 00000000..8ab8dfc8
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/plugin.cc
@@ -0,0 +1,200 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 <compiler/plugin.h>
+
+#include <iostream>
+#include <set>
+
+#ifdef _WIN32
+#include <fcntl.h>
+#else
+#include <unistd.h>
+#endif
+
+#include <stubs/logging.h>
+#include <stubs/common.h>
+#include <compiler/plugin.pb.h>
+#include <compiler/code_generator.h>
+#include <io/zero_copy_stream_impl.h>
+#include <descriptor.h>
+#include <io/io_win32.h>
+
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+
+#if defined(_WIN32)
+// 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::setmode;
+#endif
+
+class GeneratorResponseContext : public GeneratorContext {
+ public:
+ GeneratorResponseContext(
+ const Version& compiler_version, CodeGeneratorResponse* response,
+ const std::vector<const FileDescriptor*>& parsed_files)
+ : compiler_version_(compiler_version),
+ response_(response),
+ parsed_files_(parsed_files) {}
+ virtual ~GeneratorResponseContext() {}
+
+ // implements GeneratorContext --------------------------------------
+
+ io::ZeroCopyOutputStream* Open(const std::string& filename) override {
+ CodeGeneratorResponse::File* file = response_->add_file();
+ file->set_name(filename);
+ return new io::StringOutputStream(file->mutable_content());
+ }
+
+ io::ZeroCopyOutputStream* OpenForInsert(
+ const std::string& filename,
+ const std::string& insertion_point) override {
+ CodeGeneratorResponse::File* file = response_->add_file();
+ file->set_name(filename);
+ file->set_insertion_point(insertion_point);
+ return new io::StringOutputStream(file->mutable_content());
+ }
+
+ io::ZeroCopyOutputStream* OpenForInsertWithGeneratedCodeInfo(
+ const std::string& filename, const std::string& insertion_point,
+ const google::protobuf::GeneratedCodeInfo& info) override {
+ CodeGeneratorResponse::File* file = response_->add_file();
+ file->set_name(filename);
+ file->set_insertion_point(insertion_point);
+ *file->mutable_generated_code_info() = info;
+ return new io::StringOutputStream(file->mutable_content());
+ }
+
+ void ListParsedFiles(std::vector<const FileDescriptor*>* output) override {
+ *output = parsed_files_;
+ }
+
+ void GetCompilerVersion(Version* version) const override {
+ *version = compiler_version_;
+ }
+
+ private:
+ Version compiler_version_;
+ CodeGeneratorResponse* response_;
+ const std::vector<const FileDescriptor*>& parsed_files_;
+};
+
+bool GenerateCode(const CodeGeneratorRequest& request,
+ const CodeGenerator& generator,
+ CodeGeneratorResponse* response, std::string* error_msg) {
+ DescriptorPool pool;
+ for (int i = 0; i < request.proto_file_size(); i++) {
+ const FileDescriptor* file = pool.BuildFile(request.proto_file(i));
+ if (file == NULL) {
+ // BuildFile() already wrote an error message.
+ return false;
+ }
+ }
+
+ std::vector<const FileDescriptor*> parsed_files;
+ for (int i = 0; i < request.file_to_generate_size(); i++) {
+ parsed_files.push_back(pool.FindFileByName(request.file_to_generate(i)));
+ if (parsed_files.back() == NULL) {
+ *error_msg =
+ "protoc asked plugin to generate a file but "
+ "did not provide a descriptor for the file: " +
+ request.file_to_generate(i);
+ return false;
+ }
+ }
+
+ GeneratorResponseContext context(request.compiler_version(), response,
+ parsed_files);
+
+
+ std::string error;
+ bool succeeded = generator.GenerateAll(parsed_files, request.parameter(),
+ &context, &error);
+
+ response->set_supported_features(generator.GetSupportedFeatures());
+
+ if (!succeeded && error.empty()) {
+ error =
+ "Code generator returned false but provided no error "
+ "description.";
+ }
+ if (!error.empty()) {
+ response->set_error(error);
+ }
+
+ return true;
+}
+
+int PluginMain(int argc, char* argv[], const CodeGenerator* generator) {
+
+ if (argc > 1) {
+ std::cerr << argv[0] << ": Unknown option: " << argv[1] << std::endl;
+ return 1;
+ }
+
+#ifdef _WIN32
+ setmode(STDIN_FILENO, _O_BINARY);
+ setmode(STDOUT_FILENO, _O_BINARY);
+#endif
+
+ CodeGeneratorRequest request;
+ if (!request.ParseFromFileDescriptor(STDIN_FILENO)) {
+ std::cerr << argv[0] << ": protoc sent unparseable request to plugin."
+ << std::endl;
+ return 1;
+ }
+
+
+ std::string error_msg;
+ CodeGeneratorResponse response;
+
+ if (GenerateCode(request, *generator, &response, &error_msg)) {
+ if (!response.SerializeToFileDescriptor(STDOUT_FILENO)) {
+ std::cerr << argv[0] << ": Error writing to stdout." << std::endl;
+ return 1;
+ }
+ } else {
+ if (!error_msg.empty()) {
+ std::cerr << argv[0] << ": " << error_msg << std::endl;
+ }
+ return 1;
+ }
+
+ return 0;
+}
+
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/plugin.h b/NorthstarDedicatedTest/include/protobuf/compiler/plugin.h
new file mode 100644
index 00000000..24af7aa1
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/plugin.h
@@ -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.
+
+// Author: kenton@google.com (Kenton Varda)
+//
+// Front-end for protoc code generator plugins written in C++.
+//
+// To implement a protoc plugin in C++, simply write an implementation of
+// CodeGenerator, then create a main() function like:
+// int main(int argc, char* argv[]) {
+// MyCodeGenerator generator;
+// return google::protobuf::compiler::PluginMain(argc, argv, &generator);
+// }
+// You must link your plugin against libprotobuf and libprotoc.
+//
+// The core part of PluginMain is to invoke the given CodeGenerator on a
+// CodeGeneratorRequest to generate a CodeGeneratorResponse. This part is
+// abstracted out and made into function GenerateCode so that it can be reused,
+// for example, to implement a variant of PluginMain that does some
+// preprocessing on the input CodeGeneratorRequest before feeding the request
+// to the given code generator.
+//
+// To get protoc to use the plugin, do one of the following:
+// * Place the plugin binary somewhere in the PATH and give it the name
+// "protoc-gen-NAME" (replacing "NAME" with the name of your plugin). If you
+// then invoke protoc with the parameter --NAME_out=OUT_DIR (again, replace
+// "NAME" with your plugin's name), protoc will invoke your plugin to generate
+// the output, which will be placed in OUT_DIR.
+// * Place the plugin binary anywhere, with any name, and pass the --plugin
+// parameter to protoc to direct it to your plugin like so:
+// protoc --plugin=protoc-gen-NAME=path/to/mybinary --NAME_out=OUT_DIR
+// On Windows, make sure to include the .exe suffix:
+// protoc --plugin=protoc-gen-NAME=path/to/mybinary.exe --NAME_out=OUT_DIR
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_PLUGIN_H__
+#define GOOGLE_PROTOBUF_COMPILER_PLUGIN_H__
+
+#include <string>
+
+#include <port_def.inc>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+
+class CodeGenerator; // code_generator.h
+class CodeGeneratorRequest;
+class CodeGeneratorResponse;
+
+// Implements main() for a protoc plugin exposing the given code generator.
+PROTOC_EXPORT int PluginMain(int argc, char* argv[],
+ const CodeGenerator* generator);
+
+
+// Generates code using the given code generator. Returns true if the code
+// generation is successful. If the code generation fails, error_msg may be
+// populated to describe the failure cause.
+bool GenerateCode(const CodeGeneratorRequest& request,
+ const CodeGenerator& generator,
+ CodeGeneratorResponse* response, std::string* error_msg);
+
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#include <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_COMPILER_PLUGIN_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/plugin.pb.cc b/NorthstarDedicatedTest/include/protobuf/compiler/plugin.pb.cc
new file mode 100644
index 00000000..28a197d1
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/plugin.pb.cc
@@ -0,0 +1,1584 @@
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+// source: google/protobuf/compiler/plugin.proto
+
+#include <compiler/plugin.pb.h>
+
+#include <algorithm>
+
+#include <io/coded_stream.h>
+#include <extension_set.h>
+#include <wire_format_lite.h>
+#include <descriptor.h>
+#include <generated_message_reflection.h>
+#include <reflection_ops.h>
+#include <wire_format.h>
+// @@protoc_insertion_point(includes)
+#include <port_def.inc>
+
+PROTOBUF_PRAGMA_INIT_SEG
+PROTOBUF_NAMESPACE_OPEN
+namespace compiler {
+constexpr Version::Version(
+ ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized)
+ : suffix_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string)
+ , major_(0)
+ , minor_(0)
+ , patch_(0){}
+struct VersionDefaultTypeInternal {
+ constexpr VersionDefaultTypeInternal()
+ : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {}
+ ~VersionDefaultTypeInternal() {}
+ union {
+ Version _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT VersionDefaultTypeInternal _Version_default_instance_;
+constexpr CodeGeneratorRequest::CodeGeneratorRequest(
+ ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized)
+ : file_to_generate_()
+ , proto_file_()
+ , parameter_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string)
+ , compiler_version_(nullptr){}
+struct CodeGeneratorRequestDefaultTypeInternal {
+ constexpr CodeGeneratorRequestDefaultTypeInternal()
+ : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {}
+ ~CodeGeneratorRequestDefaultTypeInternal() {}
+ union {
+ CodeGeneratorRequest _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT CodeGeneratorRequestDefaultTypeInternal _CodeGeneratorRequest_default_instance_;
+constexpr CodeGeneratorResponse_File::CodeGeneratorResponse_File(
+ ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized)
+ : name_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string)
+ , insertion_point_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string)
+ , content_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string)
+ , generated_code_info_(nullptr){}
+struct CodeGeneratorResponse_FileDefaultTypeInternal {
+ constexpr CodeGeneratorResponse_FileDefaultTypeInternal()
+ : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {}
+ ~CodeGeneratorResponse_FileDefaultTypeInternal() {}
+ union {
+ CodeGeneratorResponse_File _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT CodeGeneratorResponse_FileDefaultTypeInternal _CodeGeneratorResponse_File_default_instance_;
+constexpr CodeGeneratorResponse::CodeGeneratorResponse(
+ ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized)
+ : file_()
+ , error_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string)
+ , supported_features_(uint64_t{0u}){}
+struct CodeGeneratorResponseDefaultTypeInternal {
+ constexpr CodeGeneratorResponseDefaultTypeInternal()
+ : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {}
+ ~CodeGeneratorResponseDefaultTypeInternal() {}
+ union {
+ CodeGeneratorResponse _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT CodeGeneratorResponseDefaultTypeInternal _CodeGeneratorResponse_default_instance_;
+} // namespace compiler
+PROTOBUF_NAMESPACE_CLOSE
+static ::PROTOBUF_NAMESPACE_ID::Metadata file_level_metadata_google_2fprotobuf_2fcompiler_2fplugin_2eproto[4];
+static const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* file_level_enum_descriptors_google_2fprotobuf_2fcompiler_2fplugin_2eproto[1];
+static constexpr ::PROTOBUF_NAMESPACE_ID::ServiceDescriptor const** file_level_service_descriptors_google_2fprotobuf_2fcompiler_2fplugin_2eproto = nullptr;
+
+const uint32_t TableStruct_google_2fprotobuf_2fcompiler_2fplugin_2eproto::offsets[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = {
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::compiler::Version, _has_bits_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::compiler::Version, _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::compiler::Version, major_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::compiler::Version, minor_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::compiler::Version, patch_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::compiler::Version, suffix_),
+ 1,
+ 2,
+ 3,
+ 0,
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorRequest, _has_bits_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorRequest, _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::compiler::CodeGeneratorRequest, file_to_generate_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorRequest, parameter_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorRequest, proto_file_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorRequest, compiler_version_),
+ ~0u,
+ 0,
+ ~0u,
+ 1,
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File, _has_bits_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File, _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::compiler::CodeGeneratorResponse_File, name_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File, insertion_point_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File, content_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File, generated_code_info_),
+ 0,
+ 1,
+ 2,
+ 3,
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse, _has_bits_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse, _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::compiler::CodeGeneratorResponse, error_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse, supported_features_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse, file_),
+ 0,
+ 1,
+ ~0u,
+};
+static const ::PROTOBUF_NAMESPACE_ID::internal::MigrationSchema schemas[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = {
+ { 0, 10, -1, sizeof(::PROTOBUF_NAMESPACE_ID::compiler::Version)},
+ { 14, 24, -1, sizeof(::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorRequest)},
+ { 28, 38, -1, sizeof(::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File)},
+ { 42, 51, -1, sizeof(::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse)},
+};
+
+static ::PROTOBUF_NAMESPACE_ID::Message const * const file_default_instances[] = {
+ reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::compiler::_Version_default_instance_),
+ reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::compiler::_CodeGeneratorRequest_default_instance_),
+ reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::compiler::_CodeGeneratorResponse_File_default_instance_),
+ reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::compiler::_CodeGeneratorResponse_default_instance_),
+};
+
+const char descriptor_table_protodef_google_2fprotobuf_2fcompiler_2fplugin_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) =
+ "\n%google/protobuf/compiler/plugin.proto\022"
+ "\030google.protobuf.compiler\032 google/protob"
+ "uf/descriptor.proto\"F\n\007Version\022\r\n\005major\030"
+ "\001 \001(\005\022\r\n\005minor\030\002 \001(\005\022\r\n\005patch\030\003 \001(\005\022\016\n\006s"
+ "uffix\030\004 \001(\t\"\272\001\n\024CodeGeneratorRequest\022\030\n\020"
+ "file_to_generate\030\001 \003(\t\022\021\n\tparameter\030\002 \001("
+ "\t\0228\n\nproto_file\030\017 \003(\0132$.google.protobuf."
+ "FileDescriptorProto\022;\n\020compiler_version\030"
+ "\003 \001(\0132!.google.protobuf.compiler.Version"
+ "\"\301\002\n\025CodeGeneratorResponse\022\r\n\005error\030\001 \001("
+ "\t\022\032\n\022supported_features\030\002 \001(\004\022B\n\004file\030\017 "
+ "\003(\01324.google.protobuf.compiler.CodeGener"
+ "atorResponse.File\032\177\n\004File\022\014\n\004name\030\001 \001(\t\022"
+ "\027\n\017insertion_point\030\002 \001(\t\022\017\n\007content\030\017 \001("
+ "\t\022\?\n\023generated_code_info\030\020 \001(\0132\".google."
+ "protobuf.GeneratedCodeInfo\"8\n\007Feature\022\020\n"
+ "\014FEATURE_NONE\020\000\022\033\n\027FEATURE_PROTO3_OPTION"
+ "AL\020\001BW\n\034com.google.protobuf.compilerB\014Pl"
+ "uginProtosZ)google.golang.org/protobuf/t"
+ "ypes/pluginpb"
+ ;
+static const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable*const descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_deps[1] = {
+ &::descriptor_table_google_2fprotobuf_2fdescriptor_2eproto,
+};
+static ::PROTOBUF_NAMESPACE_ID::internal::once_flag descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_once;
+const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto = {
+ false, false, 773, descriptor_table_protodef_google_2fprotobuf_2fcompiler_2fplugin_2eproto, "google/protobuf/compiler/plugin.proto",
+ &descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_once, descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_deps, 1, 4,
+ schemas, file_default_instances, TableStruct_google_2fprotobuf_2fcompiler_2fplugin_2eproto::offsets,
+ file_level_metadata_google_2fprotobuf_2fcompiler_2fplugin_2eproto, file_level_enum_descriptors_google_2fprotobuf_2fcompiler_2fplugin_2eproto, file_level_service_descriptors_google_2fprotobuf_2fcompiler_2fplugin_2eproto,
+};
+PROTOBUF_ATTRIBUTE_WEAK const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable* descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_getter() {
+ return &descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto;
+}
+
+// Force running AddDescriptors() at dynamic initialization time.
+PROTOBUF_ATTRIBUTE_INIT_PRIORITY static ::PROTOBUF_NAMESPACE_ID::internal::AddDescriptorsRunner dynamic_init_dummy_google_2fprotobuf_2fcompiler_2fplugin_2eproto(&descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto);
+PROTOBUF_NAMESPACE_OPEN
+namespace compiler {
+const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* CodeGeneratorResponse_Feature_descriptor() {
+ ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto);
+ return file_level_enum_descriptors_google_2fprotobuf_2fcompiler_2fplugin_2eproto[0];
+}
+bool CodeGeneratorResponse_Feature_IsValid(int value) {
+ switch (value) {
+ case 0:
+ case 1:
+ return true;
+ default:
+ return false;
+ }
+}
+
+#if (__cplusplus < 201703) && (!defined(_MSC_VER) || (_MSC_VER >= 1900 && _MSC_VER < 1912))
+constexpr CodeGeneratorResponse_Feature CodeGeneratorResponse::FEATURE_NONE;
+constexpr CodeGeneratorResponse_Feature CodeGeneratorResponse::FEATURE_PROTO3_OPTIONAL;
+constexpr CodeGeneratorResponse_Feature CodeGeneratorResponse::Feature_MIN;
+constexpr CodeGeneratorResponse_Feature CodeGeneratorResponse::Feature_MAX;
+constexpr int CodeGeneratorResponse::Feature_ARRAYSIZE;
+#endif // (__cplusplus < 201703) && (!defined(_MSC_VER) || (_MSC_VER >= 1900 && _MSC_VER < 1912))
+
+// ===================================================================
+
+class Version::_Internal {
+ public:
+ using HasBits = decltype(std::declval<Version>()._has_bits_);
+ static void set_has_major(HasBits* has_bits) {
+ (*has_bits)[0] |= 2u;
+ }
+ static void set_has_minor(HasBits* has_bits) {
+ (*has_bits)[0] |= 4u;
+ }
+ static void set_has_patch(HasBits* has_bits) {
+ (*has_bits)[0] |= 8u;
+ }
+ static void set_has_suffix(HasBits* has_bits) {
+ (*has_bits)[0] |= 1u;
+ }
+};
+
+Version::Version(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned)
+ : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) {
+ SharedCtor();
+ if (!is_message_owned) {
+ RegisterArenaDtor(arena);
+ }
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.compiler.Version)
+}
+Version::Version(const Version& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message(),
+ _has_bits_(from._has_bits_) {
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ suffix_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ suffix_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (from._internal_has_suffix()) {
+ suffix_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_suffix(),
+ GetArenaForAllocation());
+ }
+ ::memcpy(&major_, &from.major_,
+ static_cast<size_t>(reinterpret_cast<char*>(&patch_) -
+ reinterpret_cast<char*>(&major_)) + sizeof(patch_));
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.compiler.Version)
+}
+
+inline void Version::SharedCtor() {
+suffix_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ suffix_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+::memset(reinterpret_cast<char*>(this) + static_cast<size_t>(
+ reinterpret_cast<char*>(&major_) - reinterpret_cast<char*>(this)),
+ 0, static_cast<size_t>(reinterpret_cast<char*>(&patch_) -
+ reinterpret_cast<char*>(&major_)) + sizeof(patch_));
+}
+
+Version::~Version() {
+ // @@protoc_insertion_point(destructor:google.protobuf.compiler.Version)
+ if (GetArenaForAllocation() != nullptr) return;
+ SharedDtor();
+ _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+inline void Version::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+ suffix_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+}
+
+void Version::ArenaDtor(void* object) {
+ Version* _this = reinterpret_cast< Version* >(object);
+ (void)_this;
+}
+void Version::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) {
+}
+void Version::SetCachedSize(int size) const {
+ _cached_size_.Set(size);
+}
+
+void Version::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.compiler.Version)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ cached_has_bits = _has_bits_[0];
+ if (cached_has_bits & 0x00000001u) {
+ suffix_.ClearNonDefaultToEmpty();
+ }
+ if (cached_has_bits & 0x0000000eu) {
+ ::memset(&major_, 0, static_cast<size_t>(
+ reinterpret_cast<char*>(&patch_) -
+ reinterpret_cast<char*>(&major_)) + sizeof(patch_));
+ }
+ _has_bits_.Clear();
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* Version::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ _Internal::HasBits has_bits{};
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag);
+ switch (tag >> 3) {
+ // optional int32 major = 1;
+ case 1:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 8)) {
+ _Internal::set_has_major(&has_bits);
+ major_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint32(&ptr);
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // optional int32 minor = 2;
+ case 2:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 16)) {
+ _Internal::set_has_minor(&has_bits);
+ minor_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint32(&ptr);
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // optional int32 patch = 3;
+ case 3:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 24)) {
+ _Internal::set_has_patch(&has_bits);
+ patch_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint32(&ptr);
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // optional string suffix = 4;
+ case 4:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 34)) {
+ auto str = _internal_mutable_suffix();
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx);
+ #ifndef NDEBUG
+ ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.compiler.Version.suffix");
+ #endif // !NDEBUG
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ default:
+ goto handle_unusual;
+ } // switch
+ handle_unusual:
+ if ((tag == 0) || ((tag & 7) == 4)) {
+ CHK_(ptr);
+ ctx->SetLastTag(tag);
+ goto message_done;
+ }
+ ptr = UnknownFieldParse(
+ tag,
+ _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(),
+ ptr, ctx);
+ CHK_(ptr != nullptr);
+ } // while
+message_done:
+ _has_bits_.Or(has_bits);
+ return ptr;
+failure:
+ ptr = nullptr;
+ goto message_done;
+#undef CHK_
+}
+
+uint8_t* Version::_InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const {
+ // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.compiler.Version)
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ cached_has_bits = _has_bits_[0];
+ // optional int32 major = 1;
+ if (cached_has_bits & 0x00000002u) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32ToArray(1, this->_internal_major(), target);
+ }
+
+ // optional int32 minor = 2;
+ if (cached_has_bits & 0x00000004u) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32ToArray(2, this->_internal_minor(), target);
+ }
+
+ // optional int32 patch = 3;
+ if (cached_has_bits & 0x00000008u) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32ToArray(3, this->_internal_patch(), target);
+ }
+
+ // optional string suffix = 4;
+ if (cached_has_bits & 0x00000001u) {
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField(
+ this->_internal_suffix().data(), static_cast<int>(this->_internal_suffix().length()),
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE,
+ "google.protobuf.compiler.Version.suffix");
+ target = stream->WriteStringMaybeAliased(
+ 4, this->_internal_suffix(), target);
+ }
+
+ if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray(
+ _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.compiler.Version)
+ return target;
+}
+
+size_t Version::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.compiler.Version)
+ 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 = _has_bits_[0];
+ if (cached_has_bits & 0x0000000fu) {
+ // optional string suffix = 4;
+ if (cached_has_bits & 0x00000001u) {
+ total_size += 1 +
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
+ this->_internal_suffix());
+ }
+
+ // optional int32 major = 1;
+ if (cached_has_bits & 0x00000002u) {
+ total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32SizePlusOne(this->_internal_major());
+ }
+
+ // optional int32 minor = 2;
+ if (cached_has_bits & 0x00000004u) {
+ total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32SizePlusOne(this->_internal_minor());
+ }
+
+ // optional int32 patch = 3;
+ if (cached_has_bits & 0x00000008u) {
+ total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32SizePlusOne(this->_internal_patch());
+ }
+
+ }
+ return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData Version::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck,
+ Version::MergeImpl
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*Version::GetClassData() const { return &_class_data_; }
+
+void Version::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to,
+ const ::PROTOBUF_NAMESPACE_ID::Message& from) {
+ static_cast<Version *>(to)->MergeFrom(
+ static_cast<const Version &>(from));
+}
+
+
+void Version::MergeFrom(const Version& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.compiler.Version)
+ GOOGLE_DCHECK_NE(&from, this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ cached_has_bits = from._has_bits_[0];
+ if (cached_has_bits & 0x0000000fu) {
+ if (cached_has_bits & 0x00000001u) {
+ _internal_set_suffix(from._internal_suffix());
+ }
+ if (cached_has_bits & 0x00000002u) {
+ major_ = from.major_;
+ }
+ if (cached_has_bits & 0x00000004u) {
+ minor_ = from.minor_;
+ }
+ if (cached_has_bits & 0x00000008u) {
+ patch_ = from.patch_;
+ }
+ _has_bits_[0] |= cached_has_bits;
+ }
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+}
+
+void Version::CopyFrom(const Version& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.compiler.Version)
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+bool Version::IsInitialized() const {
+ return true;
+}
+
+void Version::InternalSwap(Version* other) {
+ using std::swap;
+ auto* lhs_arena = GetArenaForAllocation();
+ auto* rhs_arena = other->GetArenaForAllocation();
+ _internal_metadata_.InternalSwap(&other->_internal_metadata_);
+ swap(_has_bits_[0], other->_has_bits_[0]);
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(),
+ &suffix_, lhs_arena,
+ &other->suffix_, rhs_arena
+ );
+ ::PROTOBUF_NAMESPACE_ID::internal::memswap<
+ PROTOBUF_FIELD_OFFSET(Version, patch_)
+ + sizeof(Version::patch_)
+ - PROTOBUF_FIELD_OFFSET(Version, major_)>(
+ reinterpret_cast<char*>(&major_),
+ reinterpret_cast<char*>(&other->major_));
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata Version::GetMetadata() const {
+ return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(
+ &descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_getter, &descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_once,
+ file_level_metadata_google_2fprotobuf_2fcompiler_2fplugin_2eproto[0]);
+}
+
+// ===================================================================
+
+class CodeGeneratorRequest::_Internal {
+ public:
+ using HasBits = decltype(std::declval<CodeGeneratorRequest>()._has_bits_);
+ static void set_has_parameter(HasBits* has_bits) {
+ (*has_bits)[0] |= 1u;
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::compiler::Version& compiler_version(const CodeGeneratorRequest* msg);
+ static void set_has_compiler_version(HasBits* has_bits) {
+ (*has_bits)[0] |= 2u;
+ }
+};
+
+const ::PROTOBUF_NAMESPACE_ID::compiler::Version&
+CodeGeneratorRequest::_Internal::compiler_version(const CodeGeneratorRequest* msg) {
+ return *msg->compiler_version_;
+}
+void CodeGeneratorRequest::clear_proto_file() {
+ proto_file_.Clear();
+}
+CodeGeneratorRequest::CodeGeneratorRequest(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned)
+ : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned),
+ file_to_generate_(arena),
+ proto_file_(arena) {
+ SharedCtor();
+ if (!is_message_owned) {
+ RegisterArenaDtor(arena);
+ }
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.compiler.CodeGeneratorRequest)
+}
+CodeGeneratorRequest::CodeGeneratorRequest(const CodeGeneratorRequest& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message(),
+ _has_bits_(from._has_bits_),
+ file_to_generate_(from.file_to_generate_),
+ proto_file_(from.proto_file_) {
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ parameter_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ parameter_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (from._internal_has_parameter()) {
+ parameter_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_parameter(),
+ GetArenaForAllocation());
+ }
+ if (from._internal_has_compiler_version()) {
+ compiler_version_ = new ::PROTOBUF_NAMESPACE_ID::compiler::Version(*from.compiler_version_);
+ } else {
+ compiler_version_ = nullptr;
+ }
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.compiler.CodeGeneratorRequest)
+}
+
+inline void CodeGeneratorRequest::SharedCtor() {
+parameter_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ parameter_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+compiler_version_ = nullptr;
+}
+
+CodeGeneratorRequest::~CodeGeneratorRequest() {
+ // @@protoc_insertion_point(destructor:google.protobuf.compiler.CodeGeneratorRequest)
+ if (GetArenaForAllocation() != nullptr) return;
+ SharedDtor();
+ _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+inline void CodeGeneratorRequest::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+ parameter_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ if (this != internal_default_instance()) delete compiler_version_;
+}
+
+void CodeGeneratorRequest::ArenaDtor(void* object) {
+ CodeGeneratorRequest* _this = reinterpret_cast< CodeGeneratorRequest* >(object);
+ (void)_this;
+}
+void CodeGeneratorRequest::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) {
+}
+void CodeGeneratorRequest::SetCachedSize(int size) const {
+ _cached_size_.Set(size);
+}
+
+void CodeGeneratorRequest::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.compiler.CodeGeneratorRequest)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ file_to_generate_.Clear();
+ proto_file_.Clear();
+ cached_has_bits = _has_bits_[0];
+ if (cached_has_bits & 0x00000003u) {
+ if (cached_has_bits & 0x00000001u) {
+ parameter_.ClearNonDefaultToEmpty();
+ }
+ if (cached_has_bits & 0x00000002u) {
+ GOOGLE_DCHECK(compiler_version_ != nullptr);
+ compiler_version_->Clear();
+ }
+ }
+ _has_bits_.Clear();
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* CodeGeneratorRequest::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ _Internal::HasBits has_bits{};
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag);
+ switch (tag >> 3) {
+ // repeated string file_to_generate = 1;
+ case 1:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 10)) {
+ ptr -= 1;
+ do {
+ ptr += 1;
+ auto str = _internal_add_file_to_generate();
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx);
+ #ifndef NDEBUG
+ ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.compiler.CodeGeneratorRequest.file_to_generate");
+ #endif // !NDEBUG
+ CHK_(ptr);
+ if (!ctx->DataAvailable(ptr)) break;
+ } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<10>(ptr));
+ } else
+ goto handle_unusual;
+ continue;
+ // optional string parameter = 2;
+ case 2:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 18)) {
+ auto str = _internal_mutable_parameter();
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx);
+ #ifndef NDEBUG
+ ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.compiler.CodeGeneratorRequest.parameter");
+ #endif // !NDEBUG
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // optional .google.protobuf.compiler.Version compiler_version = 3;
+ case 3:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 26)) {
+ ptr = ctx->ParseMessage(_internal_mutable_compiler_version(), ptr);
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // repeated .google.protobuf.FileDescriptorProto proto_file = 15;
+ case 15:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 122)) {
+ ptr -= 1;
+ do {
+ ptr += 1;
+ ptr = ctx->ParseMessage(_internal_add_proto_file(), ptr);
+ CHK_(ptr);
+ if (!ctx->DataAvailable(ptr)) break;
+ } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<122>(ptr));
+ } else
+ goto handle_unusual;
+ continue;
+ default:
+ goto handle_unusual;
+ } // switch
+ handle_unusual:
+ if ((tag == 0) || ((tag & 7) == 4)) {
+ CHK_(ptr);
+ ctx->SetLastTag(tag);
+ goto message_done;
+ }
+ ptr = UnknownFieldParse(
+ tag,
+ _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(),
+ ptr, ctx);
+ CHK_(ptr != nullptr);
+ } // while
+message_done:
+ _has_bits_.Or(has_bits);
+ return ptr;
+failure:
+ ptr = nullptr;
+ goto message_done;
+#undef CHK_
+}
+
+uint8_t* CodeGeneratorRequest::_InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const {
+ // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.compiler.CodeGeneratorRequest)
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ // repeated string file_to_generate = 1;
+ for (int i = 0, n = this->_internal_file_to_generate_size(); i < n; i++) {
+ const auto& s = this->_internal_file_to_generate(i);
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField(
+ s.data(), static_cast<int>(s.length()),
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE,
+ "google.protobuf.compiler.CodeGeneratorRequest.file_to_generate");
+ target = stream->WriteString(1, s, target);
+ }
+
+ cached_has_bits = _has_bits_[0];
+ // optional string parameter = 2;
+ if (cached_has_bits & 0x00000001u) {
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField(
+ this->_internal_parameter().data(), static_cast<int>(this->_internal_parameter().length()),
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE,
+ "google.protobuf.compiler.CodeGeneratorRequest.parameter");
+ target = stream->WriteStringMaybeAliased(
+ 2, this->_internal_parameter(), target);
+ }
+
+ // optional .google.protobuf.compiler.Version compiler_version = 3;
+ if (cached_has_bits & 0x00000002u) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(
+ 3, _Internal::compiler_version(this), target, stream);
+ }
+
+ // repeated .google.protobuf.FileDescriptorProto proto_file = 15;
+ for (unsigned int i = 0,
+ n = static_cast<unsigned int>(this->_internal_proto_file_size()); i < n; i++) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(15, this->_internal_proto_file(i), target, stream);
+ }
+
+ if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray(
+ _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.compiler.CodeGeneratorRequest)
+ return target;
+}
+
+size_t CodeGeneratorRequest::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.compiler.CodeGeneratorRequest)
+ 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 file_to_generate = 1;
+ total_size += 1 *
+ ::PROTOBUF_NAMESPACE_ID::internal::FromIntSize(file_to_generate_.size());
+ for (int i = 0, n = file_to_generate_.size(); i < n; i++) {
+ total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
+ file_to_generate_.Get(i));
+ }
+
+ // repeated .google.protobuf.FileDescriptorProto proto_file = 15;
+ total_size += 1UL * this->_internal_proto_file_size();
+ for (const auto& msg : this->proto_file_) {
+ total_size +=
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg);
+ }
+
+ cached_has_bits = _has_bits_[0];
+ if (cached_has_bits & 0x00000003u) {
+ // optional string parameter = 2;
+ if (cached_has_bits & 0x00000001u) {
+ total_size += 1 +
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
+ this->_internal_parameter());
+ }
+
+ // optional .google.protobuf.compiler.Version compiler_version = 3;
+ if (cached_has_bits & 0x00000002u) {
+ total_size += 1 +
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(
+ *compiler_version_);
+ }
+
+ }
+ return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData CodeGeneratorRequest::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck,
+ CodeGeneratorRequest::MergeImpl
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*CodeGeneratorRequest::GetClassData() const { return &_class_data_; }
+
+void CodeGeneratorRequest::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to,
+ const ::PROTOBUF_NAMESPACE_ID::Message& from) {
+ static_cast<CodeGeneratorRequest *>(to)->MergeFrom(
+ static_cast<const CodeGeneratorRequest &>(from));
+}
+
+
+void CodeGeneratorRequest::MergeFrom(const CodeGeneratorRequest& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.compiler.CodeGeneratorRequest)
+ GOOGLE_DCHECK_NE(&from, this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ file_to_generate_.MergeFrom(from.file_to_generate_);
+ proto_file_.MergeFrom(from.proto_file_);
+ cached_has_bits = from._has_bits_[0];
+ if (cached_has_bits & 0x00000003u) {
+ if (cached_has_bits & 0x00000001u) {
+ _internal_set_parameter(from._internal_parameter());
+ }
+ if (cached_has_bits & 0x00000002u) {
+ _internal_mutable_compiler_version()->::PROTOBUF_NAMESPACE_ID::compiler::Version::MergeFrom(from._internal_compiler_version());
+ }
+ }
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+}
+
+void CodeGeneratorRequest::CopyFrom(const CodeGeneratorRequest& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.compiler.CodeGeneratorRequest)
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+bool CodeGeneratorRequest::IsInitialized() const {
+ if (!::PROTOBUF_NAMESPACE_ID::internal::AllAreInitialized(proto_file_))
+ return false;
+ return true;
+}
+
+void CodeGeneratorRequest::InternalSwap(CodeGeneratorRequest* other) {
+ using std::swap;
+ auto* lhs_arena = GetArenaForAllocation();
+ auto* rhs_arena = other->GetArenaForAllocation();
+ _internal_metadata_.InternalSwap(&other->_internal_metadata_);
+ swap(_has_bits_[0], other->_has_bits_[0]);
+ file_to_generate_.InternalSwap(&other->file_to_generate_);
+ proto_file_.InternalSwap(&other->proto_file_);
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(),
+ &parameter_, lhs_arena,
+ &other->parameter_, rhs_arena
+ );
+ swap(compiler_version_, other->compiler_version_);
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata CodeGeneratorRequest::GetMetadata() const {
+ return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(
+ &descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_getter, &descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_once,
+ file_level_metadata_google_2fprotobuf_2fcompiler_2fplugin_2eproto[1]);
+}
+
+// ===================================================================
+
+class CodeGeneratorResponse_File::_Internal {
+ public:
+ using HasBits = decltype(std::declval<CodeGeneratorResponse_File>()._has_bits_);
+ static void set_has_name(HasBits* has_bits) {
+ (*has_bits)[0] |= 1u;
+ }
+ static void set_has_insertion_point(HasBits* has_bits) {
+ (*has_bits)[0] |= 2u;
+ }
+ static void set_has_content(HasBits* has_bits) {
+ (*has_bits)[0] |= 4u;
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo& generated_code_info(const CodeGeneratorResponse_File* msg);
+ static void set_has_generated_code_info(HasBits* has_bits) {
+ (*has_bits)[0] |= 8u;
+ }
+};
+
+const ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo&
+CodeGeneratorResponse_File::_Internal::generated_code_info(const CodeGeneratorResponse_File* msg) {
+ return *msg->generated_code_info_;
+}
+void CodeGeneratorResponse_File::clear_generated_code_info() {
+ if (generated_code_info_ != nullptr) generated_code_info_->Clear();
+ _has_bits_[0] &= ~0x00000008u;
+}
+CodeGeneratorResponse_File::CodeGeneratorResponse_File(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned)
+ : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) {
+ SharedCtor();
+ if (!is_message_owned) {
+ RegisterArenaDtor(arena);
+ }
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.compiler.CodeGeneratorResponse.File)
+}
+CodeGeneratorResponse_File::CodeGeneratorResponse_File(const CodeGeneratorResponse_File& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message(),
+ _has_bits_(from._has_bits_) {
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (from._internal_has_name()) {
+ name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_name(),
+ GetArenaForAllocation());
+ }
+ insertion_point_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ insertion_point_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (from._internal_has_insertion_point()) {
+ insertion_point_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_insertion_point(),
+ GetArenaForAllocation());
+ }
+ content_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ content_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (from._internal_has_content()) {
+ content_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_content(),
+ GetArenaForAllocation());
+ }
+ if (from._internal_has_generated_code_info()) {
+ generated_code_info_ = new ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo(*from.generated_code_info_);
+ } else {
+ generated_code_info_ = nullptr;
+ }
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.compiler.CodeGeneratorResponse.File)
+}
+
+inline void CodeGeneratorResponse_File::SharedCtor() {
+name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+insertion_point_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ insertion_point_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+content_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ content_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+generated_code_info_ = nullptr;
+}
+
+CodeGeneratorResponse_File::~CodeGeneratorResponse_File() {
+ // @@protoc_insertion_point(destructor:google.protobuf.compiler.CodeGeneratorResponse.File)
+ if (GetArenaForAllocation() != nullptr) return;
+ SharedDtor();
+ _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+inline void CodeGeneratorResponse_File::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+ name_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ insertion_point_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ content_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ if (this != internal_default_instance()) delete generated_code_info_;
+}
+
+void CodeGeneratorResponse_File::ArenaDtor(void* object) {
+ CodeGeneratorResponse_File* _this = reinterpret_cast< CodeGeneratorResponse_File* >(object);
+ (void)_this;
+}
+void CodeGeneratorResponse_File::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) {
+}
+void CodeGeneratorResponse_File::SetCachedSize(int size) const {
+ _cached_size_.Set(size);
+}
+
+void CodeGeneratorResponse_File::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.compiler.CodeGeneratorResponse.File)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ cached_has_bits = _has_bits_[0];
+ if (cached_has_bits & 0x0000000fu) {
+ if (cached_has_bits & 0x00000001u) {
+ name_.ClearNonDefaultToEmpty();
+ }
+ if (cached_has_bits & 0x00000002u) {
+ insertion_point_.ClearNonDefaultToEmpty();
+ }
+ if (cached_has_bits & 0x00000004u) {
+ content_.ClearNonDefaultToEmpty();
+ }
+ if (cached_has_bits & 0x00000008u) {
+ GOOGLE_DCHECK(generated_code_info_ != nullptr);
+ generated_code_info_->Clear();
+ }
+ }
+ _has_bits_.Clear();
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* CodeGeneratorResponse_File::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ _Internal::HasBits has_bits{};
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag);
+ switch (tag >> 3) {
+ // optional string name = 1;
+ case 1:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 10)) {
+ auto str = _internal_mutable_name();
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx);
+ #ifndef NDEBUG
+ ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.compiler.CodeGeneratorResponse.File.name");
+ #endif // !NDEBUG
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // optional string insertion_point = 2;
+ case 2:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 18)) {
+ auto str = _internal_mutable_insertion_point();
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx);
+ #ifndef NDEBUG
+ ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point");
+ #endif // !NDEBUG
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // optional string content = 15;
+ case 15:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 122)) {
+ auto str = _internal_mutable_content();
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx);
+ #ifndef NDEBUG
+ ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.compiler.CodeGeneratorResponse.File.content");
+ #endif // !NDEBUG
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // optional .google.protobuf.GeneratedCodeInfo generated_code_info = 16;
+ case 16:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 130)) {
+ ptr = ctx->ParseMessage(_internal_mutable_generated_code_info(), ptr);
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ default:
+ goto handle_unusual;
+ } // switch
+ handle_unusual:
+ if ((tag == 0) || ((tag & 7) == 4)) {
+ CHK_(ptr);
+ ctx->SetLastTag(tag);
+ goto message_done;
+ }
+ ptr = UnknownFieldParse(
+ tag,
+ _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(),
+ ptr, ctx);
+ CHK_(ptr != nullptr);
+ } // while
+message_done:
+ _has_bits_.Or(has_bits);
+ return ptr;
+failure:
+ ptr = nullptr;
+ goto message_done;
+#undef CHK_
+}
+
+uint8_t* CodeGeneratorResponse_File::_InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const {
+ // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.compiler.CodeGeneratorResponse.File)
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ cached_has_bits = _has_bits_[0];
+ // optional string name = 1;
+ if (cached_has_bits & 0x00000001u) {
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField(
+ this->_internal_name().data(), static_cast<int>(this->_internal_name().length()),
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE,
+ "google.protobuf.compiler.CodeGeneratorResponse.File.name");
+ target = stream->WriteStringMaybeAliased(
+ 1, this->_internal_name(), target);
+ }
+
+ // optional string insertion_point = 2;
+ if (cached_has_bits & 0x00000002u) {
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField(
+ this->_internal_insertion_point().data(), static_cast<int>(this->_internal_insertion_point().length()),
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE,
+ "google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point");
+ target = stream->WriteStringMaybeAliased(
+ 2, this->_internal_insertion_point(), target);
+ }
+
+ // optional string content = 15;
+ if (cached_has_bits & 0x00000004u) {
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField(
+ this->_internal_content().data(), static_cast<int>(this->_internal_content().length()),
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE,
+ "google.protobuf.compiler.CodeGeneratorResponse.File.content");
+ target = stream->WriteStringMaybeAliased(
+ 15, this->_internal_content(), target);
+ }
+
+ // optional .google.protobuf.GeneratedCodeInfo generated_code_info = 16;
+ if (cached_has_bits & 0x00000008u) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(
+ 16, _Internal::generated_code_info(this), target, stream);
+ }
+
+ if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray(
+ _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.compiler.CodeGeneratorResponse.File)
+ return target;
+}
+
+size_t CodeGeneratorResponse_File::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.compiler.CodeGeneratorResponse.File)
+ 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 = _has_bits_[0];
+ if (cached_has_bits & 0x0000000fu) {
+ // optional string name = 1;
+ if (cached_has_bits & 0x00000001u) {
+ total_size += 1 +
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
+ this->_internal_name());
+ }
+
+ // optional string insertion_point = 2;
+ if (cached_has_bits & 0x00000002u) {
+ total_size += 1 +
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
+ this->_internal_insertion_point());
+ }
+
+ // optional string content = 15;
+ if (cached_has_bits & 0x00000004u) {
+ total_size += 1 +
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
+ this->_internal_content());
+ }
+
+ // optional .google.protobuf.GeneratedCodeInfo generated_code_info = 16;
+ if (cached_has_bits & 0x00000008u) {
+ total_size += 2 +
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(
+ *generated_code_info_);
+ }
+
+ }
+ return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData CodeGeneratorResponse_File::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck,
+ CodeGeneratorResponse_File::MergeImpl
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*CodeGeneratorResponse_File::GetClassData() const { return &_class_data_; }
+
+void CodeGeneratorResponse_File::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to,
+ const ::PROTOBUF_NAMESPACE_ID::Message& from) {
+ static_cast<CodeGeneratorResponse_File *>(to)->MergeFrom(
+ static_cast<const CodeGeneratorResponse_File &>(from));
+}
+
+
+void CodeGeneratorResponse_File::MergeFrom(const CodeGeneratorResponse_File& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.compiler.CodeGeneratorResponse.File)
+ GOOGLE_DCHECK_NE(&from, this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ cached_has_bits = from._has_bits_[0];
+ if (cached_has_bits & 0x0000000fu) {
+ if (cached_has_bits & 0x00000001u) {
+ _internal_set_name(from._internal_name());
+ }
+ if (cached_has_bits & 0x00000002u) {
+ _internal_set_insertion_point(from._internal_insertion_point());
+ }
+ if (cached_has_bits & 0x00000004u) {
+ _internal_set_content(from._internal_content());
+ }
+ if (cached_has_bits & 0x00000008u) {
+ _internal_mutable_generated_code_info()->::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo::MergeFrom(from._internal_generated_code_info());
+ }
+ }
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+}
+
+void CodeGeneratorResponse_File::CopyFrom(const CodeGeneratorResponse_File& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.compiler.CodeGeneratorResponse.File)
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+bool CodeGeneratorResponse_File::IsInitialized() const {
+ return true;
+}
+
+void CodeGeneratorResponse_File::InternalSwap(CodeGeneratorResponse_File* other) {
+ using std::swap;
+ auto* lhs_arena = GetArenaForAllocation();
+ auto* rhs_arena = other->GetArenaForAllocation();
+ _internal_metadata_.InternalSwap(&other->_internal_metadata_);
+ swap(_has_bits_[0], other->_has_bits_[0]);
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(),
+ &name_, lhs_arena,
+ &other->name_, rhs_arena
+ );
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(),
+ &insertion_point_, lhs_arena,
+ &other->insertion_point_, rhs_arena
+ );
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(),
+ &content_, lhs_arena,
+ &other->content_, rhs_arena
+ );
+ swap(generated_code_info_, other->generated_code_info_);
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata CodeGeneratorResponse_File::GetMetadata() const {
+ return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(
+ &descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_getter, &descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_once,
+ file_level_metadata_google_2fprotobuf_2fcompiler_2fplugin_2eproto[2]);
+}
+
+// ===================================================================
+
+class CodeGeneratorResponse::_Internal {
+ public:
+ using HasBits = decltype(std::declval<CodeGeneratorResponse>()._has_bits_);
+ static void set_has_error(HasBits* has_bits) {
+ (*has_bits)[0] |= 1u;
+ }
+ static void set_has_supported_features(HasBits* has_bits) {
+ (*has_bits)[0] |= 2u;
+ }
+};
+
+CodeGeneratorResponse::CodeGeneratorResponse(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned)
+ : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned),
+ file_(arena) {
+ SharedCtor();
+ if (!is_message_owned) {
+ RegisterArenaDtor(arena);
+ }
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.compiler.CodeGeneratorResponse)
+}
+CodeGeneratorResponse::CodeGeneratorResponse(const CodeGeneratorResponse& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message(),
+ _has_bits_(from._has_bits_),
+ file_(from.file_) {
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ error_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ error_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (from._internal_has_error()) {
+ error_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_error(),
+ GetArenaForAllocation());
+ }
+ supported_features_ = from.supported_features_;
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.compiler.CodeGeneratorResponse)
+}
+
+inline void CodeGeneratorResponse::SharedCtor() {
+error_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ error_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+supported_features_ = uint64_t{0u};
+}
+
+CodeGeneratorResponse::~CodeGeneratorResponse() {
+ // @@protoc_insertion_point(destructor:google.protobuf.compiler.CodeGeneratorResponse)
+ if (GetArenaForAllocation() != nullptr) return;
+ SharedDtor();
+ _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+inline void CodeGeneratorResponse::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+ error_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+}
+
+void CodeGeneratorResponse::ArenaDtor(void* object) {
+ CodeGeneratorResponse* _this = reinterpret_cast< CodeGeneratorResponse* >(object);
+ (void)_this;
+}
+void CodeGeneratorResponse::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) {
+}
+void CodeGeneratorResponse::SetCachedSize(int size) const {
+ _cached_size_.Set(size);
+}
+
+void CodeGeneratorResponse::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.compiler.CodeGeneratorResponse)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ file_.Clear();
+ cached_has_bits = _has_bits_[0];
+ if (cached_has_bits & 0x00000001u) {
+ error_.ClearNonDefaultToEmpty();
+ }
+ supported_features_ = uint64_t{0u};
+ _has_bits_.Clear();
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* CodeGeneratorResponse::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ _Internal::HasBits has_bits{};
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag);
+ switch (tag >> 3) {
+ // optional string error = 1;
+ case 1:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 10)) {
+ auto str = _internal_mutable_error();
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx);
+ #ifndef NDEBUG
+ ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.compiler.CodeGeneratorResponse.error");
+ #endif // !NDEBUG
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // optional uint64 supported_features = 2;
+ case 2:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 16)) {
+ _Internal::set_has_supported_features(&has_bits);
+ supported_features_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr);
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15;
+ case 15:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 122)) {
+ 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<122>(ptr));
+ } else
+ goto handle_unusual;
+ continue;
+ default:
+ goto handle_unusual;
+ } // switch
+ handle_unusual:
+ if ((tag == 0) || ((tag & 7) == 4)) {
+ CHK_(ptr);
+ ctx->SetLastTag(tag);
+ goto message_done;
+ }
+ ptr = UnknownFieldParse(
+ tag,
+ _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(),
+ ptr, ctx);
+ CHK_(ptr != nullptr);
+ } // while
+message_done:
+ _has_bits_.Or(has_bits);
+ return ptr;
+failure:
+ ptr = nullptr;
+ goto message_done;
+#undef CHK_
+}
+
+uint8_t* CodeGeneratorResponse::_InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const {
+ // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.compiler.CodeGeneratorResponse)
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ cached_has_bits = _has_bits_[0];
+ // optional string error = 1;
+ if (cached_has_bits & 0x00000001u) {
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField(
+ this->_internal_error().data(), static_cast<int>(this->_internal_error().length()),
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE,
+ "google.protobuf.compiler.CodeGeneratorResponse.error");
+ target = stream->WriteStringMaybeAliased(
+ 1, this->_internal_error(), target);
+ }
+
+ // optional uint64 supported_features = 2;
+ if (cached_has_bits & 0x00000002u) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteUInt64ToArray(2, this->_internal_supported_features(), target);
+ }
+
+ // repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15;
+ for (unsigned int i = 0,
+ n = static_cast<unsigned int>(this->_internal_file_size()); i < n; i++) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(15, this->_internal_file(i), target, stream);
+ }
+
+ if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray(
+ _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.compiler.CodeGeneratorResponse)
+ return target;
+}
+
+size_t CodeGeneratorResponse::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.compiler.CodeGeneratorResponse)
+ 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.compiler.CodeGeneratorResponse.File file = 15;
+ total_size += 1UL * this->_internal_file_size();
+ for (const auto& msg : this->file_) {
+ total_size +=
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg);
+ }
+
+ cached_has_bits = _has_bits_[0];
+ if (cached_has_bits & 0x00000003u) {
+ // optional string error = 1;
+ if (cached_has_bits & 0x00000001u) {
+ total_size += 1 +
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
+ this->_internal_error());
+ }
+
+ // optional uint64 supported_features = 2;
+ if (cached_has_bits & 0x00000002u) {
+ total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::UInt64SizePlusOne(this->_internal_supported_features());
+ }
+
+ }
+ return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData CodeGeneratorResponse::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck,
+ CodeGeneratorResponse::MergeImpl
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*CodeGeneratorResponse::GetClassData() const { return &_class_data_; }
+
+void CodeGeneratorResponse::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to,
+ const ::PROTOBUF_NAMESPACE_ID::Message& from) {
+ static_cast<CodeGeneratorResponse *>(to)->MergeFrom(
+ static_cast<const CodeGeneratorResponse &>(from));
+}
+
+
+void CodeGeneratorResponse::MergeFrom(const CodeGeneratorResponse& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.compiler.CodeGeneratorResponse)
+ GOOGLE_DCHECK_NE(&from, this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ file_.MergeFrom(from.file_);
+ cached_has_bits = from._has_bits_[0];
+ if (cached_has_bits & 0x00000003u) {
+ if (cached_has_bits & 0x00000001u) {
+ _internal_set_error(from._internal_error());
+ }
+ if (cached_has_bits & 0x00000002u) {
+ supported_features_ = from.supported_features_;
+ }
+ _has_bits_[0] |= cached_has_bits;
+ }
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+}
+
+void CodeGeneratorResponse::CopyFrom(const CodeGeneratorResponse& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.compiler.CodeGeneratorResponse)
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+bool CodeGeneratorResponse::IsInitialized() const {
+ return true;
+}
+
+void CodeGeneratorResponse::InternalSwap(CodeGeneratorResponse* other) {
+ using std::swap;
+ auto* lhs_arena = GetArenaForAllocation();
+ auto* rhs_arena = other->GetArenaForAllocation();
+ _internal_metadata_.InternalSwap(&other->_internal_metadata_);
+ swap(_has_bits_[0], other->_has_bits_[0]);
+ file_.InternalSwap(&other->file_);
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(),
+ &error_, lhs_arena,
+ &other->error_, rhs_arena
+ );
+ swap(supported_features_, other->supported_features_);
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata CodeGeneratorResponse::GetMetadata() const {
+ return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(
+ &descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_getter, &descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_once,
+ file_level_metadata_google_2fprotobuf_2fcompiler_2fplugin_2eproto[3]);
+}
+
+// @@protoc_insertion_point(namespace_scope)
+} // namespace compiler
+PROTOBUF_NAMESPACE_CLOSE
+PROTOBUF_NAMESPACE_OPEN
+template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::compiler::Version* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::compiler::Version >(Arena* arena) {
+ return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::compiler::Version >(arena);
+}
+template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorRequest* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorRequest >(Arena* arena) {
+ return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorRequest >(arena);
+}
+template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File >(Arena* arena) {
+ return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File >(arena);
+}
+template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse >(Arena* arena) {
+ return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse >(arena);
+}
+PROTOBUF_NAMESPACE_CLOSE
+
+// @@protoc_insertion_point(global_scope)
+#include <port_undef.inc>
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/plugin.pb.h b/NorthstarDedicatedTest/include/protobuf/compiler/plugin.pb.h
new file mode 100644
index 00000000..a3ed430b
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/plugin.pb.h
@@ -0,0 +1,1909 @@
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+// source: google/protobuf/compiler/plugin.proto
+
+#ifndef GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fcompiler_2fplugin_2eproto
+#define GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fcompiler_2fplugin_2eproto
+
+#include <limits>
+#include <string>
+
+#include <port_def.inc>
+#if PROTOBUF_VERSION < 3019000
+#error This file was generated by a newer version of protoc which is
+#error incompatible with your Protocol Buffer headers. Please update
+#error your headers.
+#endif
+#if 3019004 < 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 <port_undef.inc>
+#include <io/coded_stream.h>
+#include <arena.h>
+#include <arenastring.h>
+#include <generated_message_table_driven.h>
+#include <generated_message_util.h>
+#include <metadata_lite.h>
+#include <generated_message_reflection.h>
+#include <message.h>
+#include <repeated_field.h> // IWYU pragma: export
+#include <extension_set.h> // IWYU pragma: export
+#include <generated_enum_reflection.h>
+#include <unknown_field_set.h>
+#include <descriptor.pb.h>
+// @@protoc_insertion_point(includes)
+#include <port_def.inc>
+#define PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fcompiler_2fplugin_2eproto PROTOC_EXPORT
+#ifdef major
+#undef major
+#endif
+#ifdef minor
+#undef minor
+#endif
+PROTOBUF_NAMESPACE_OPEN
+namespace internal {
+class AnyMetadata;
+} // namespace internal
+PROTOBUF_NAMESPACE_CLOSE
+
+// Internal implementation detail -- do not use these members.
+struct PROTOC_EXPORT TableStruct_google_2fprotobuf_2fcompiler_2fplugin_2eproto {
+ static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTableField entries[]
+ PROTOBUF_SECTION_VARIABLE(protodesc_cold);
+ static const ::PROTOBUF_NAMESPACE_ID::internal::AuxiliaryParseTableField aux[]
+ PROTOBUF_SECTION_VARIABLE(protodesc_cold);
+ static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTable schema[4]
+ PROTOBUF_SECTION_VARIABLE(protodesc_cold);
+ static const ::PROTOBUF_NAMESPACE_ID::internal::FieldMetadata field_metadata[];
+ static const ::PROTOBUF_NAMESPACE_ID::internal::SerializationTable serialization_table[];
+ static const uint32_t offsets[];
+};
+PROTOC_EXPORT extern const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto;
+PROTOBUF_NAMESPACE_OPEN
+namespace compiler {
+class CodeGeneratorRequest;
+struct CodeGeneratorRequestDefaultTypeInternal;
+PROTOC_EXPORT extern CodeGeneratorRequestDefaultTypeInternal _CodeGeneratorRequest_default_instance_;
+class CodeGeneratorResponse;
+struct CodeGeneratorResponseDefaultTypeInternal;
+PROTOC_EXPORT extern CodeGeneratorResponseDefaultTypeInternal _CodeGeneratorResponse_default_instance_;
+class CodeGeneratorResponse_File;
+struct CodeGeneratorResponse_FileDefaultTypeInternal;
+PROTOC_EXPORT extern CodeGeneratorResponse_FileDefaultTypeInternal _CodeGeneratorResponse_File_default_instance_;
+class Version;
+struct VersionDefaultTypeInternal;
+PROTOC_EXPORT extern VersionDefaultTypeInternal _Version_default_instance_;
+} // namespace compiler
+PROTOBUF_NAMESPACE_CLOSE
+PROTOBUF_NAMESPACE_OPEN
+template<> PROTOC_EXPORT ::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorRequest* Arena::CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorRequest>(Arena*);
+template<> PROTOC_EXPORT ::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse* Arena::CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse>(Arena*);
+template<> PROTOC_EXPORT ::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File* Arena::CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File>(Arena*);
+template<> PROTOC_EXPORT ::PROTOBUF_NAMESPACE_ID::compiler::Version* Arena::CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::compiler::Version>(Arena*);
+PROTOBUF_NAMESPACE_CLOSE
+PROTOBUF_NAMESPACE_OPEN
+namespace compiler {
+
+enum CodeGeneratorResponse_Feature : int {
+ CodeGeneratorResponse_Feature_FEATURE_NONE = 0,
+ CodeGeneratorResponse_Feature_FEATURE_PROTO3_OPTIONAL = 1
+};
+PROTOC_EXPORT bool CodeGeneratorResponse_Feature_IsValid(int value);
+constexpr CodeGeneratorResponse_Feature CodeGeneratorResponse_Feature_Feature_MIN = CodeGeneratorResponse_Feature_FEATURE_NONE;
+constexpr CodeGeneratorResponse_Feature CodeGeneratorResponse_Feature_Feature_MAX = CodeGeneratorResponse_Feature_FEATURE_PROTO3_OPTIONAL;
+constexpr int CodeGeneratorResponse_Feature_Feature_ARRAYSIZE = CodeGeneratorResponse_Feature_Feature_MAX + 1;
+
+PROTOC_EXPORT const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* CodeGeneratorResponse_Feature_descriptor();
+template<typename T>
+inline const std::string& CodeGeneratorResponse_Feature_Name(T enum_t_value) {
+ static_assert(::std::is_same<T, CodeGeneratorResponse_Feature>::value ||
+ ::std::is_integral<T>::value,
+ "Incorrect type passed to function CodeGeneratorResponse_Feature_Name.");
+ return ::PROTOBUF_NAMESPACE_ID::internal::NameOfEnum(
+ CodeGeneratorResponse_Feature_descriptor(), enum_t_value);
+}
+inline bool CodeGeneratorResponse_Feature_Parse(
+ ::PROTOBUF_NAMESPACE_ID::ConstStringParam name, CodeGeneratorResponse_Feature* value) {
+ return ::PROTOBUF_NAMESPACE_ID::internal::ParseNamedEnum<CodeGeneratorResponse_Feature>(
+ CodeGeneratorResponse_Feature_descriptor(), name, value);
+}
+// ===================================================================
+
+class PROTOC_EXPORT Version final :
+ public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.compiler.Version) */ {
+ public:
+ inline Version() : Version(nullptr) {}
+ ~Version() override;
+ explicit constexpr Version(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
+
+ Version(const Version& from);
+ Version(Version&& from) noexcept
+ : Version() {
+ *this = ::std::move(from);
+ }
+
+ inline Version& operator=(const Version& from) {
+ CopyFrom(from);
+ return *this;
+ }
+ inline Version& operator=(Version&& 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 Version& default_instance() {
+ return *internal_default_instance();
+ }
+ static inline const Version* internal_default_instance() {
+ return reinterpret_cast<const Version*>(
+ &_Version_default_instance_);
+ }
+ static constexpr int kIndexInFileMessages =
+ 0;
+
+ friend void swap(Version& a, Version& b) {
+ a.Swap(&b);
+ }
+ inline void Swap(Version* 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(Version* other) {
+ if (other == this) return;
+ GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena());
+ InternalSwap(other);
+ }
+
+ // implements Message ----------------------------------------------
+
+ Version* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
+ return CreateMaybeMessage<Version>(arena);
+ }
+ using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
+ void CopyFrom(const Version& from);
+ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
+ void MergeFrom(const Version& from);
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from);
+ public:
+ PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+ bool IsInitialized() const final;
+
+ size_t ByteSizeLong() const final;
+ const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
+ uint8_t* _InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
+ int GetCachedSize() const final { return _cached_size_.Get(); }
+
+ private:
+ void SharedCtor();
+ void SharedDtor();
+ void SetCachedSize(int size) const final;
+ void InternalSwap(Version* other);
+
+ private:
+ friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
+ static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
+ return "google.protobuf.compiler.Version";
+ }
+ protected:
+ explicit Version(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned = false);
+ private:
+ static void ArenaDtor(void* object);
+ inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
+ public:
+
+ static const ClassData _class_data_;
+ const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;
+
+ ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;
+
+ // nested types ----------------------------------------------------
+
+ // accessors -------------------------------------------------------
+
+ enum : int {
+ kSuffixFieldNumber = 4,
+ kMajorFieldNumber = 1,
+ kMinorFieldNumber = 2,
+ kPatchFieldNumber = 3,
+ };
+ // optional string suffix = 4;
+ bool has_suffix() const;
+ private:
+ bool _internal_has_suffix() const;
+ public:
+ void clear_suffix();
+ const std::string& suffix() const;
+ template <typename ArgT0 = const std::string&, typename... ArgT>
+ void set_suffix(ArgT0&& arg0, ArgT... args);
+ std::string* mutable_suffix();
+ PROTOBUF_NODISCARD std::string* release_suffix();
+ void set_allocated_suffix(std::string* suffix);
+ private:
+ const std::string& _internal_suffix() const;
+ inline PROTOBUF_ALWAYS_INLINE void _internal_set_suffix(const std::string& value);
+ std::string* _internal_mutable_suffix();
+ public:
+
+ // optional int32 major = 1;
+ bool has_major() const;
+ private:
+ bool _internal_has_major() const;
+ public:
+ void clear_major();
+ int32_t major() const;
+ void set_major(int32_t value);
+ private:
+ int32_t _internal_major() const;
+ void _internal_set_major(int32_t value);
+ public:
+
+ // optional int32 minor = 2;
+ bool has_minor() const;
+ private:
+ bool _internal_has_minor() const;
+ public:
+ void clear_minor();
+ int32_t minor() const;
+ void set_minor(int32_t value);
+ private:
+ int32_t _internal_minor() const;
+ void _internal_set_minor(int32_t value);
+ public:
+
+ // optional int32 patch = 3;
+ bool has_patch() const;
+ private:
+ bool _internal_has_patch() const;
+ public:
+ void clear_patch();
+ int32_t patch() const;
+ void set_patch(int32_t value);
+ private:
+ int32_t _internal_patch() const;
+ void _internal_set_patch(int32_t value);
+ public:
+
+ // @@protoc_insertion_point(class_scope:google.protobuf.compiler.Version)
+ private:
+ class _Internal;
+
+ template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
+ typedef void InternalArenaConstructable_;
+ typedef void DestructorSkippable_;
+ ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_;
+ mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr suffix_;
+ int32_t major_;
+ int32_t minor_;
+ int32_t patch_;
+ friend struct ::TableStruct_google_2fprotobuf_2fcompiler_2fplugin_2eproto;
+};
+// -------------------------------------------------------------------
+
+class PROTOC_EXPORT CodeGeneratorRequest final :
+ public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.compiler.CodeGeneratorRequest) */ {
+ public:
+ inline CodeGeneratorRequest() : CodeGeneratorRequest(nullptr) {}
+ ~CodeGeneratorRequest() override;
+ explicit constexpr CodeGeneratorRequest(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
+
+ CodeGeneratorRequest(const CodeGeneratorRequest& from);
+ CodeGeneratorRequest(CodeGeneratorRequest&& from) noexcept
+ : CodeGeneratorRequest() {
+ *this = ::std::move(from);
+ }
+
+ inline CodeGeneratorRequest& operator=(const CodeGeneratorRequest& from) {
+ CopyFrom(from);
+ return *this;
+ }
+ inline CodeGeneratorRequest& operator=(CodeGeneratorRequest&& 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 CodeGeneratorRequest& default_instance() {
+ return *internal_default_instance();
+ }
+ static inline const CodeGeneratorRequest* internal_default_instance() {
+ return reinterpret_cast<const CodeGeneratorRequest*>(
+ &_CodeGeneratorRequest_default_instance_);
+ }
+ static constexpr int kIndexInFileMessages =
+ 1;
+
+ friend void swap(CodeGeneratorRequest& a, CodeGeneratorRequest& b) {
+ a.Swap(&b);
+ }
+ inline void Swap(CodeGeneratorRequest* 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(CodeGeneratorRequest* other) {
+ if (other == this) return;
+ GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena());
+ InternalSwap(other);
+ }
+
+ // implements Message ----------------------------------------------
+
+ CodeGeneratorRequest* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
+ return CreateMaybeMessage<CodeGeneratorRequest>(arena);
+ }
+ using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
+ void CopyFrom(const CodeGeneratorRequest& from);
+ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
+ void MergeFrom(const CodeGeneratorRequest& from);
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from);
+ public:
+ PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+ bool IsInitialized() const final;
+
+ size_t ByteSizeLong() const final;
+ const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
+ uint8_t* _InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
+ int GetCachedSize() const final { return _cached_size_.Get(); }
+
+ private:
+ void SharedCtor();
+ void SharedDtor();
+ void SetCachedSize(int size) const final;
+ void InternalSwap(CodeGeneratorRequest* other);
+
+ private:
+ friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
+ static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
+ return "google.protobuf.compiler.CodeGeneratorRequest";
+ }
+ protected:
+ explicit CodeGeneratorRequest(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned = false);
+ private:
+ static void ArenaDtor(void* object);
+ inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
+ public:
+
+ static const ClassData _class_data_;
+ const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;
+
+ ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;
+
+ // nested types ----------------------------------------------------
+
+ // accessors -------------------------------------------------------
+
+ enum : int {
+ kFileToGenerateFieldNumber = 1,
+ kProtoFileFieldNumber = 15,
+ kParameterFieldNumber = 2,
+ kCompilerVersionFieldNumber = 3,
+ };
+ // repeated string file_to_generate = 1;
+ int file_to_generate_size() const;
+ private:
+ int _internal_file_to_generate_size() const;
+ public:
+ void clear_file_to_generate();
+ const std::string& file_to_generate(int index) const;
+ std::string* mutable_file_to_generate(int index);
+ void set_file_to_generate(int index, const std::string& value);
+ void set_file_to_generate(int index, std::string&& value);
+ void set_file_to_generate(int index, const char* value);
+ void set_file_to_generate(int index, const char* value, size_t size);
+ std::string* add_file_to_generate();
+ void add_file_to_generate(const std::string& value);
+ void add_file_to_generate(std::string&& value);
+ void add_file_to_generate(const char* value);
+ void add_file_to_generate(const char* value, size_t size);
+ const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string>& file_to_generate() const;
+ ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string>* mutable_file_to_generate();
+ private:
+ const std::string& _internal_file_to_generate(int index) const;
+ std::string* _internal_add_file_to_generate();
+ public:
+
+ // repeated .google.protobuf.FileDescriptorProto proto_file = 15;
+ int proto_file_size() const;
+ private:
+ int _internal_proto_file_size() const;
+ public:
+ void clear_proto_file();
+ ::PROTOBUF_NAMESPACE_ID::FileDescriptorProto* mutable_proto_file(int index);
+ ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::FileDescriptorProto >*
+ mutable_proto_file();
+ private:
+ const ::PROTOBUF_NAMESPACE_ID::FileDescriptorProto& _internal_proto_file(int index) const;
+ ::PROTOBUF_NAMESPACE_ID::FileDescriptorProto* _internal_add_proto_file();
+ public:
+ const ::PROTOBUF_NAMESPACE_ID::FileDescriptorProto& proto_file(int index) const;
+ ::PROTOBUF_NAMESPACE_ID::FileDescriptorProto* add_proto_file();
+ const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::FileDescriptorProto >&
+ proto_file() const;
+
+ // optional string parameter = 2;
+ bool has_parameter() const;
+ private:
+ bool _internal_has_parameter() const;
+ public:
+ void clear_parameter();
+ const std::string& parameter() const;
+ template <typename ArgT0 = const std::string&, typename... ArgT>
+ void set_parameter(ArgT0&& arg0, ArgT... args);
+ std::string* mutable_parameter();
+ PROTOBUF_NODISCARD std::string* release_parameter();
+ void set_allocated_parameter(std::string* parameter);
+ private:
+ const std::string& _internal_parameter() const;
+ inline PROTOBUF_ALWAYS_INLINE void _internal_set_parameter(const std::string& value);
+ std::string* _internal_mutable_parameter();
+ public:
+
+ // optional .google.protobuf.compiler.Version compiler_version = 3;
+ bool has_compiler_version() const;
+ private:
+ bool _internal_has_compiler_version() const;
+ public:
+ void clear_compiler_version();
+ const ::PROTOBUF_NAMESPACE_ID::compiler::Version& compiler_version() const;
+ PROTOBUF_NODISCARD ::PROTOBUF_NAMESPACE_ID::compiler::Version* release_compiler_version();
+ ::PROTOBUF_NAMESPACE_ID::compiler::Version* mutable_compiler_version();
+ void set_allocated_compiler_version(::PROTOBUF_NAMESPACE_ID::compiler::Version* compiler_version);
+ private:
+ const ::PROTOBUF_NAMESPACE_ID::compiler::Version& _internal_compiler_version() const;
+ ::PROTOBUF_NAMESPACE_ID::compiler::Version* _internal_mutable_compiler_version();
+ public:
+ void unsafe_arena_set_allocated_compiler_version(
+ ::PROTOBUF_NAMESPACE_ID::compiler::Version* compiler_version);
+ ::PROTOBUF_NAMESPACE_ID::compiler::Version* unsafe_arena_release_compiler_version();
+
+ // @@protoc_insertion_point(class_scope:google.protobuf.compiler.CodeGeneratorRequest)
+ private:
+ class _Internal;
+
+ template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
+ typedef void InternalArenaConstructable_;
+ typedef void DestructorSkippable_;
+ ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_;
+ mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
+ ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string> file_to_generate_;
+ ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::FileDescriptorProto > proto_file_;
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr parameter_;
+ ::PROTOBUF_NAMESPACE_ID::compiler::Version* compiler_version_;
+ friend struct ::TableStruct_google_2fprotobuf_2fcompiler_2fplugin_2eproto;
+};
+// -------------------------------------------------------------------
+
+class PROTOC_EXPORT CodeGeneratorResponse_File final :
+ public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.compiler.CodeGeneratorResponse.File) */ {
+ public:
+ inline CodeGeneratorResponse_File() : CodeGeneratorResponse_File(nullptr) {}
+ ~CodeGeneratorResponse_File() override;
+ explicit constexpr CodeGeneratorResponse_File(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
+
+ CodeGeneratorResponse_File(const CodeGeneratorResponse_File& from);
+ CodeGeneratorResponse_File(CodeGeneratorResponse_File&& from) noexcept
+ : CodeGeneratorResponse_File() {
+ *this = ::std::move(from);
+ }
+
+ inline CodeGeneratorResponse_File& operator=(const CodeGeneratorResponse_File& from) {
+ CopyFrom(from);
+ return *this;
+ }
+ inline CodeGeneratorResponse_File& operator=(CodeGeneratorResponse_File&& 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 CodeGeneratorResponse_File& default_instance() {
+ return *internal_default_instance();
+ }
+ static inline const CodeGeneratorResponse_File* internal_default_instance() {
+ return reinterpret_cast<const CodeGeneratorResponse_File*>(
+ &_CodeGeneratorResponse_File_default_instance_);
+ }
+ static constexpr int kIndexInFileMessages =
+ 2;
+
+ friend void swap(CodeGeneratorResponse_File& a, CodeGeneratorResponse_File& b) {
+ a.Swap(&b);
+ }
+ inline void Swap(CodeGeneratorResponse_File* 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(CodeGeneratorResponse_File* other) {
+ if (other == this) return;
+ GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena());
+ InternalSwap(other);
+ }
+
+ // implements Message ----------------------------------------------
+
+ CodeGeneratorResponse_File* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
+ return CreateMaybeMessage<CodeGeneratorResponse_File>(arena);
+ }
+ using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
+ void CopyFrom(const CodeGeneratorResponse_File& from);
+ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
+ void MergeFrom(const CodeGeneratorResponse_File& from);
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from);
+ public:
+ PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+ bool IsInitialized() const final;
+
+ size_t ByteSizeLong() const final;
+ const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
+ uint8_t* _InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
+ int GetCachedSize() const final { return _cached_size_.Get(); }
+
+ private:
+ void SharedCtor();
+ void SharedDtor();
+ void SetCachedSize(int size) const final;
+ void InternalSwap(CodeGeneratorResponse_File* other);
+
+ private:
+ friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
+ static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
+ return "google.protobuf.compiler.CodeGeneratorResponse.File";
+ }
+ protected:
+ explicit CodeGeneratorResponse_File(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned = false);
+ private:
+ static void ArenaDtor(void* object);
+ inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
+ public:
+
+ static const ClassData _class_data_;
+ const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;
+
+ ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;
+
+ // nested types ----------------------------------------------------
+
+ // accessors -------------------------------------------------------
+
+ enum : int {
+ kNameFieldNumber = 1,
+ kInsertionPointFieldNumber = 2,
+ kContentFieldNumber = 15,
+ kGeneratedCodeInfoFieldNumber = 16,
+ };
+ // 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 insertion_point = 2;
+ bool has_insertion_point() const;
+ private:
+ bool _internal_has_insertion_point() const;
+ public:
+ void clear_insertion_point();
+ const std::string& insertion_point() const;
+ template <typename ArgT0 = const std::string&, typename... ArgT>
+ void set_insertion_point(ArgT0&& arg0, ArgT... args);
+ std::string* mutable_insertion_point();
+ PROTOBUF_NODISCARD std::string* release_insertion_point();
+ void set_allocated_insertion_point(std::string* insertion_point);
+ private:
+ const std::string& _internal_insertion_point() const;
+ inline PROTOBUF_ALWAYS_INLINE void _internal_set_insertion_point(const std::string& value);
+ std::string* _internal_mutable_insertion_point();
+ public:
+
+ // optional string content = 15;
+ bool has_content() const;
+ private:
+ bool _internal_has_content() const;
+ public:
+ void clear_content();
+ const std::string& content() const;
+ template <typename ArgT0 = const std::string&, typename... ArgT>
+ void set_content(ArgT0&& arg0, ArgT... args);
+ std::string* mutable_content();
+ PROTOBUF_NODISCARD std::string* release_content();
+ void set_allocated_content(std::string* content);
+ private:
+ const std::string& _internal_content() const;
+ inline PROTOBUF_ALWAYS_INLINE void _internal_set_content(const std::string& value);
+ std::string* _internal_mutable_content();
+ public:
+
+ // optional .google.protobuf.GeneratedCodeInfo generated_code_info = 16;
+ bool has_generated_code_info() const;
+ private:
+ bool _internal_has_generated_code_info() const;
+ public:
+ void clear_generated_code_info();
+ const ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo& generated_code_info() const;
+ PROTOBUF_NODISCARD ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* release_generated_code_info();
+ ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* mutable_generated_code_info();
+ void set_allocated_generated_code_info(::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* generated_code_info);
+ private:
+ const ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo& _internal_generated_code_info() const;
+ ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* _internal_mutable_generated_code_info();
+ public:
+ void unsafe_arena_set_allocated_generated_code_info(
+ ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* generated_code_info);
+ ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* unsafe_arena_release_generated_code_info();
+
+ // @@protoc_insertion_point(class_scope:google.protobuf.compiler.CodeGeneratorResponse.File)
+ private:
+ class _Internal;
+
+ template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
+ typedef void InternalArenaConstructable_;
+ typedef void DestructorSkippable_;
+ ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_;
+ mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr name_;
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr insertion_point_;
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr content_;
+ ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* generated_code_info_;
+ friend struct ::TableStruct_google_2fprotobuf_2fcompiler_2fplugin_2eproto;
+};
+// -------------------------------------------------------------------
+
+class PROTOC_EXPORT CodeGeneratorResponse final :
+ public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.compiler.CodeGeneratorResponse) */ {
+ public:
+ inline CodeGeneratorResponse() : CodeGeneratorResponse(nullptr) {}
+ ~CodeGeneratorResponse() override;
+ explicit constexpr CodeGeneratorResponse(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
+
+ CodeGeneratorResponse(const CodeGeneratorResponse& from);
+ CodeGeneratorResponse(CodeGeneratorResponse&& from) noexcept
+ : CodeGeneratorResponse() {
+ *this = ::std::move(from);
+ }
+
+ inline CodeGeneratorResponse& operator=(const CodeGeneratorResponse& from) {
+ CopyFrom(from);
+ return *this;
+ }
+ inline CodeGeneratorResponse& operator=(CodeGeneratorResponse&& 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 CodeGeneratorResponse& default_instance() {
+ return *internal_default_instance();
+ }
+ static inline const CodeGeneratorResponse* internal_default_instance() {
+ return reinterpret_cast<const CodeGeneratorResponse*>(
+ &_CodeGeneratorResponse_default_instance_);
+ }
+ static constexpr int kIndexInFileMessages =
+ 3;
+
+ friend void swap(CodeGeneratorResponse& a, CodeGeneratorResponse& b) {
+ a.Swap(&b);
+ }
+ inline void Swap(CodeGeneratorResponse* 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(CodeGeneratorResponse* other) {
+ if (other == this) return;
+ GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena());
+ InternalSwap(other);
+ }
+
+ // implements Message ----------------------------------------------
+
+ CodeGeneratorResponse* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
+ return CreateMaybeMessage<CodeGeneratorResponse>(arena);
+ }
+ using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
+ void CopyFrom(const CodeGeneratorResponse& from);
+ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
+ void MergeFrom(const CodeGeneratorResponse& from);
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from);
+ public:
+ PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+ bool IsInitialized() const final;
+
+ size_t ByteSizeLong() const final;
+ const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
+ uint8_t* _InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
+ int GetCachedSize() const final { return _cached_size_.Get(); }
+
+ private:
+ void SharedCtor();
+ void SharedDtor();
+ void SetCachedSize(int size) const final;
+ void InternalSwap(CodeGeneratorResponse* other);
+
+ private:
+ friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
+ static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
+ return "google.protobuf.compiler.CodeGeneratorResponse";
+ }
+ protected:
+ explicit CodeGeneratorResponse(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned = false);
+ private:
+ static void ArenaDtor(void* object);
+ inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
+ public:
+
+ static const ClassData _class_data_;
+ const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;
+
+ ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;
+
+ // nested types ----------------------------------------------------
+
+ typedef CodeGeneratorResponse_File File;
+
+ typedef CodeGeneratorResponse_Feature Feature;
+ static constexpr Feature FEATURE_NONE =
+ CodeGeneratorResponse_Feature_FEATURE_NONE;
+ static constexpr Feature FEATURE_PROTO3_OPTIONAL =
+ CodeGeneratorResponse_Feature_FEATURE_PROTO3_OPTIONAL;
+ static inline bool Feature_IsValid(int value) {
+ return CodeGeneratorResponse_Feature_IsValid(value);
+ }
+ static constexpr Feature Feature_MIN =
+ CodeGeneratorResponse_Feature_Feature_MIN;
+ static constexpr Feature Feature_MAX =
+ CodeGeneratorResponse_Feature_Feature_MAX;
+ static constexpr int Feature_ARRAYSIZE =
+ CodeGeneratorResponse_Feature_Feature_ARRAYSIZE;
+ static inline const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor*
+ Feature_descriptor() {
+ return CodeGeneratorResponse_Feature_descriptor();
+ }
+ template<typename T>
+ static inline const std::string& Feature_Name(T enum_t_value) {
+ static_assert(::std::is_same<T, Feature>::value ||
+ ::std::is_integral<T>::value,
+ "Incorrect type passed to function Feature_Name.");
+ return CodeGeneratorResponse_Feature_Name(enum_t_value);
+ }
+ static inline bool Feature_Parse(::PROTOBUF_NAMESPACE_ID::ConstStringParam name,
+ Feature* value) {
+ return CodeGeneratorResponse_Feature_Parse(name, value);
+ }
+
+ // accessors -------------------------------------------------------
+
+ enum : int {
+ kFileFieldNumber = 15,
+ kErrorFieldNumber = 1,
+ kSupportedFeaturesFieldNumber = 2,
+ };
+ // repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15;
+ int file_size() const;
+ private:
+ int _internal_file_size() const;
+ public:
+ void clear_file();
+ ::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File* mutable_file(int index);
+ ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File >*
+ mutable_file();
+ private:
+ const ::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File& _internal_file(int index) const;
+ ::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File* _internal_add_file();
+ public:
+ const ::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File& file(int index) const;
+ ::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File* add_file();
+ const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File >&
+ file() const;
+
+ // optional string error = 1;
+ bool has_error() const;
+ private:
+ bool _internal_has_error() const;
+ public:
+ void clear_error();
+ const std::string& error() const;
+ template <typename ArgT0 = const std::string&, typename... ArgT>
+ void set_error(ArgT0&& arg0, ArgT... args);
+ std::string* mutable_error();
+ PROTOBUF_NODISCARD std::string* release_error();
+ void set_allocated_error(std::string* error);
+ private:
+ const std::string& _internal_error() const;
+ inline PROTOBUF_ALWAYS_INLINE void _internal_set_error(const std::string& value);
+ std::string* _internal_mutable_error();
+ public:
+
+ // optional uint64 supported_features = 2;
+ bool has_supported_features() const;
+ private:
+ bool _internal_has_supported_features() const;
+ public:
+ void clear_supported_features();
+ uint64_t supported_features() const;
+ void set_supported_features(uint64_t value);
+ private:
+ uint64_t _internal_supported_features() const;
+ void _internal_set_supported_features(uint64_t value);
+ public:
+
+ // @@protoc_insertion_point(class_scope:google.protobuf.compiler.CodeGeneratorResponse)
+ private:
+ class _Internal;
+
+ template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
+ typedef void InternalArenaConstructable_;
+ typedef void DestructorSkippable_;
+ ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_;
+ mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
+ ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File > file_;
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr error_;
+ uint64_t supported_features_;
+ friend struct ::TableStruct_google_2fprotobuf_2fcompiler_2fplugin_2eproto;
+};
+// ===================================================================
+
+
+// ===================================================================
+
+#ifdef __GNUC__
+ #pragma GCC diagnostic push
+ #pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#endif // __GNUC__
+// Version
+
+// optional int32 major = 1;
+inline bool Version::_internal_has_major() const {
+ bool value = (_has_bits_[0] & 0x00000002u) != 0;
+ return value;
+}
+inline bool Version::has_major() const {
+ return _internal_has_major();
+}
+inline void Version::clear_major() {
+ major_ = 0;
+ _has_bits_[0] &= ~0x00000002u;
+}
+inline int32_t Version::_internal_major() const {
+ return major_;
+}
+inline int32_t Version::major() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.compiler.Version.major)
+ return _internal_major();
+}
+inline void Version::_internal_set_major(int32_t value) {
+ _has_bits_[0] |= 0x00000002u;
+ major_ = value;
+}
+inline void Version::set_major(int32_t value) {
+ _internal_set_major(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.compiler.Version.major)
+}
+
+// optional int32 minor = 2;
+inline bool Version::_internal_has_minor() const {
+ bool value = (_has_bits_[0] & 0x00000004u) != 0;
+ return value;
+}
+inline bool Version::has_minor() const {
+ return _internal_has_minor();
+}
+inline void Version::clear_minor() {
+ minor_ = 0;
+ _has_bits_[0] &= ~0x00000004u;
+}
+inline int32_t Version::_internal_minor() const {
+ return minor_;
+}
+inline int32_t Version::minor() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.compiler.Version.minor)
+ return _internal_minor();
+}
+inline void Version::_internal_set_minor(int32_t value) {
+ _has_bits_[0] |= 0x00000004u;
+ minor_ = value;
+}
+inline void Version::set_minor(int32_t value) {
+ _internal_set_minor(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.compiler.Version.minor)
+}
+
+// optional int32 patch = 3;
+inline bool Version::_internal_has_patch() const {
+ bool value = (_has_bits_[0] & 0x00000008u) != 0;
+ return value;
+}
+inline bool Version::has_patch() const {
+ return _internal_has_patch();
+}
+inline void Version::clear_patch() {
+ patch_ = 0;
+ _has_bits_[0] &= ~0x00000008u;
+}
+inline int32_t Version::_internal_patch() const {
+ return patch_;
+}
+inline int32_t Version::patch() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.compiler.Version.patch)
+ return _internal_patch();
+}
+inline void Version::_internal_set_patch(int32_t value) {
+ _has_bits_[0] |= 0x00000008u;
+ patch_ = value;
+}
+inline void Version::set_patch(int32_t value) {
+ _internal_set_patch(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.compiler.Version.patch)
+}
+
+// optional string suffix = 4;
+inline bool Version::_internal_has_suffix() const {
+ bool value = (_has_bits_[0] & 0x00000001u) != 0;
+ return value;
+}
+inline bool Version::has_suffix() const {
+ return _internal_has_suffix();
+}
+inline void Version::clear_suffix() {
+ suffix_.ClearToEmpty();
+ _has_bits_[0] &= ~0x00000001u;
+}
+inline const std::string& Version::suffix() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.compiler.Version.suffix)
+ return _internal_suffix();
+}
+template <typename ArgT0, typename... ArgT>
+inline PROTOBUF_ALWAYS_INLINE
+void Version::set_suffix(ArgT0&& arg0, ArgT... args) {
+ _has_bits_[0] |= 0x00000001u;
+ suffix_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
+ // @@protoc_insertion_point(field_set:google.protobuf.compiler.Version.suffix)
+}
+inline std::string* Version::mutable_suffix() {
+ std::string* _s = _internal_mutable_suffix();
+ // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.Version.suffix)
+ return _s;
+}
+inline const std::string& Version::_internal_suffix() const {
+ return suffix_.Get();
+}
+inline void Version::_internal_set_suffix(const std::string& value) {
+ _has_bits_[0] |= 0x00000001u;
+ suffix_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation());
+}
+inline std::string* Version::_internal_mutable_suffix() {
+ _has_bits_[0] |= 0x00000001u;
+ return suffix_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation());
+}
+inline std::string* Version::release_suffix() {
+ // @@protoc_insertion_point(field_release:google.protobuf.compiler.Version.suffix)
+ if (!_internal_has_suffix()) {
+ return nullptr;
+ }
+ _has_bits_[0] &= ~0x00000001u;
+ auto* p = suffix_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (suffix_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
+ suffix_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ return p;
+}
+inline void Version::set_allocated_suffix(std::string* suffix) {
+ if (suffix != nullptr) {
+ _has_bits_[0] |= 0x00000001u;
+ } else {
+ _has_bits_[0] &= ~0x00000001u;
+ }
+ suffix_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), suffix,
+ GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (suffix_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
+ suffix_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.compiler.Version.suffix)
+}
+
+// -------------------------------------------------------------------
+
+// CodeGeneratorRequest
+
+// repeated string file_to_generate = 1;
+inline int CodeGeneratorRequest::_internal_file_to_generate_size() const {
+ return file_to_generate_.size();
+}
+inline int CodeGeneratorRequest::file_to_generate_size() const {
+ return _internal_file_to_generate_size();
+}
+inline void CodeGeneratorRequest::clear_file_to_generate() {
+ file_to_generate_.Clear();
+}
+inline std::string* CodeGeneratorRequest::add_file_to_generate() {
+ std::string* _s = _internal_add_file_to_generate();
+ // @@protoc_insertion_point(field_add_mutable:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate)
+ return _s;
+}
+inline const std::string& CodeGeneratorRequest::_internal_file_to_generate(int index) const {
+ return file_to_generate_.Get(index);
+}
+inline const std::string& CodeGeneratorRequest::file_to_generate(int index) const {
+ // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate)
+ return _internal_file_to_generate(index);
+}
+inline std::string* CodeGeneratorRequest::mutable_file_to_generate(int index) {
+ // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate)
+ return file_to_generate_.Mutable(index);
+}
+inline void CodeGeneratorRequest::set_file_to_generate(int index, const std::string& value) {
+ file_to_generate_.Mutable(index)->assign(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate)
+}
+inline void CodeGeneratorRequest::set_file_to_generate(int index, std::string&& value) {
+ file_to_generate_.Mutable(index)->assign(std::move(value));
+ // @@protoc_insertion_point(field_set:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate)
+}
+inline void CodeGeneratorRequest::set_file_to_generate(int index, const char* value) {
+ GOOGLE_DCHECK(value != nullptr);
+ file_to_generate_.Mutable(index)->assign(value);
+ // @@protoc_insertion_point(field_set_char:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate)
+}
+inline void CodeGeneratorRequest::set_file_to_generate(int index, const char* value, size_t size) {
+ file_to_generate_.Mutable(index)->assign(
+ reinterpret_cast<const char*>(value), size);
+ // @@protoc_insertion_point(field_set_pointer:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate)
+}
+inline std::string* CodeGeneratorRequest::_internal_add_file_to_generate() {
+ return file_to_generate_.Add();
+}
+inline void CodeGeneratorRequest::add_file_to_generate(const std::string& value) {
+ file_to_generate_.Add()->assign(value);
+ // @@protoc_insertion_point(field_add:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate)
+}
+inline void CodeGeneratorRequest::add_file_to_generate(std::string&& value) {
+ file_to_generate_.Add(std::move(value));
+ // @@protoc_insertion_point(field_add:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate)
+}
+inline void CodeGeneratorRequest::add_file_to_generate(const char* value) {
+ GOOGLE_DCHECK(value != nullptr);
+ file_to_generate_.Add()->assign(value);
+ // @@protoc_insertion_point(field_add_char:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate)
+}
+inline void CodeGeneratorRequest::add_file_to_generate(const char* value, size_t size) {
+ file_to_generate_.Add()->assign(reinterpret_cast<const char*>(value), size);
+ // @@protoc_insertion_point(field_add_pointer:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate)
+}
+inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string>&
+CodeGeneratorRequest::file_to_generate() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate)
+ return file_to_generate_;
+}
+inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string>*
+CodeGeneratorRequest::mutable_file_to_generate() {
+ // @@protoc_insertion_point(field_mutable_list:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate)
+ return &file_to_generate_;
+}
+
+// optional string parameter = 2;
+inline bool CodeGeneratorRequest::_internal_has_parameter() const {
+ bool value = (_has_bits_[0] & 0x00000001u) != 0;
+ return value;
+}
+inline bool CodeGeneratorRequest::has_parameter() const {
+ return _internal_has_parameter();
+}
+inline void CodeGeneratorRequest::clear_parameter() {
+ parameter_.ClearToEmpty();
+ _has_bits_[0] &= ~0x00000001u;
+}
+inline const std::string& CodeGeneratorRequest::parameter() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorRequest.parameter)
+ return _internal_parameter();
+}
+template <typename ArgT0, typename... ArgT>
+inline PROTOBUF_ALWAYS_INLINE
+void CodeGeneratorRequest::set_parameter(ArgT0&& arg0, ArgT... args) {
+ _has_bits_[0] |= 0x00000001u;
+ parameter_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
+ // @@protoc_insertion_point(field_set:google.protobuf.compiler.CodeGeneratorRequest.parameter)
+}
+inline std::string* CodeGeneratorRequest::mutable_parameter() {
+ std::string* _s = _internal_mutable_parameter();
+ // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.CodeGeneratorRequest.parameter)
+ return _s;
+}
+inline const std::string& CodeGeneratorRequest::_internal_parameter() const {
+ return parameter_.Get();
+}
+inline void CodeGeneratorRequest::_internal_set_parameter(const std::string& value) {
+ _has_bits_[0] |= 0x00000001u;
+ parameter_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation());
+}
+inline std::string* CodeGeneratorRequest::_internal_mutable_parameter() {
+ _has_bits_[0] |= 0x00000001u;
+ return parameter_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation());
+}
+inline std::string* CodeGeneratorRequest::release_parameter() {
+ // @@protoc_insertion_point(field_release:google.protobuf.compiler.CodeGeneratorRequest.parameter)
+ if (!_internal_has_parameter()) {
+ return nullptr;
+ }
+ _has_bits_[0] &= ~0x00000001u;
+ auto* p = parameter_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (parameter_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
+ parameter_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ return p;
+}
+inline void CodeGeneratorRequest::set_allocated_parameter(std::string* parameter) {
+ if (parameter != nullptr) {
+ _has_bits_[0] |= 0x00000001u;
+ } else {
+ _has_bits_[0] &= ~0x00000001u;
+ }
+ parameter_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), parameter,
+ GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (parameter_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
+ parameter_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.compiler.CodeGeneratorRequest.parameter)
+}
+
+// repeated .google.protobuf.FileDescriptorProto proto_file = 15;
+inline int CodeGeneratorRequest::_internal_proto_file_size() const {
+ return proto_file_.size();
+}
+inline int CodeGeneratorRequest::proto_file_size() const {
+ return _internal_proto_file_size();
+}
+inline ::PROTOBUF_NAMESPACE_ID::FileDescriptorProto* CodeGeneratorRequest::mutable_proto_file(int index) {
+ // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.CodeGeneratorRequest.proto_file)
+ return proto_file_.Mutable(index);
+}
+inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::FileDescriptorProto >*
+CodeGeneratorRequest::mutable_proto_file() {
+ // @@protoc_insertion_point(field_mutable_list:google.protobuf.compiler.CodeGeneratorRequest.proto_file)
+ return &proto_file_;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::FileDescriptorProto& CodeGeneratorRequest::_internal_proto_file(int index) const {
+ return proto_file_.Get(index);
+}
+inline const ::PROTOBUF_NAMESPACE_ID::FileDescriptorProto& CodeGeneratorRequest::proto_file(int index) const {
+ // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorRequest.proto_file)
+ return _internal_proto_file(index);
+}
+inline ::PROTOBUF_NAMESPACE_ID::FileDescriptorProto* CodeGeneratorRequest::_internal_add_proto_file() {
+ return proto_file_.Add();
+}
+inline ::PROTOBUF_NAMESPACE_ID::FileDescriptorProto* CodeGeneratorRequest::add_proto_file() {
+ ::PROTOBUF_NAMESPACE_ID::FileDescriptorProto* _add = _internal_add_proto_file();
+ // @@protoc_insertion_point(field_add:google.protobuf.compiler.CodeGeneratorRequest.proto_file)
+ return _add;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::FileDescriptorProto >&
+CodeGeneratorRequest::proto_file() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.compiler.CodeGeneratorRequest.proto_file)
+ return proto_file_;
+}
+
+// optional .google.protobuf.compiler.Version compiler_version = 3;
+inline bool CodeGeneratorRequest::_internal_has_compiler_version() const {
+ bool value = (_has_bits_[0] & 0x00000002u) != 0;
+ PROTOBUF_ASSUME(!value || compiler_version_ != nullptr);
+ return value;
+}
+inline bool CodeGeneratorRequest::has_compiler_version() const {
+ return _internal_has_compiler_version();
+}
+inline void CodeGeneratorRequest::clear_compiler_version() {
+ if (compiler_version_ != nullptr) compiler_version_->Clear();
+ _has_bits_[0] &= ~0x00000002u;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::compiler::Version& CodeGeneratorRequest::_internal_compiler_version() const {
+ const ::PROTOBUF_NAMESPACE_ID::compiler::Version* p = compiler_version_;
+ return p != nullptr ? *p : reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::compiler::Version&>(
+ ::PROTOBUF_NAMESPACE_ID::compiler::_Version_default_instance_);
+}
+inline const ::PROTOBUF_NAMESPACE_ID::compiler::Version& CodeGeneratorRequest::compiler_version() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorRequest.compiler_version)
+ return _internal_compiler_version();
+}
+inline void CodeGeneratorRequest::unsafe_arena_set_allocated_compiler_version(
+ ::PROTOBUF_NAMESPACE_ID::compiler::Version* compiler_version) {
+ if (GetArenaForAllocation() == nullptr) {
+ delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(compiler_version_);
+ }
+ compiler_version_ = compiler_version;
+ if (compiler_version) {
+ _has_bits_[0] |= 0x00000002u;
+ } else {
+ _has_bits_[0] &= ~0x00000002u;
+ }
+ // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.compiler.CodeGeneratorRequest.compiler_version)
+}
+inline ::PROTOBUF_NAMESPACE_ID::compiler::Version* CodeGeneratorRequest::release_compiler_version() {
+ _has_bits_[0] &= ~0x00000002u;
+ ::PROTOBUF_NAMESPACE_ID::compiler::Version* temp = compiler_version_;
+ compiler_version_ = 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::compiler::Version* CodeGeneratorRequest::unsafe_arena_release_compiler_version() {
+ // @@protoc_insertion_point(field_release:google.protobuf.compiler.CodeGeneratorRequest.compiler_version)
+ _has_bits_[0] &= ~0x00000002u;
+ ::PROTOBUF_NAMESPACE_ID::compiler::Version* temp = compiler_version_;
+ compiler_version_ = nullptr;
+ return temp;
+}
+inline ::PROTOBUF_NAMESPACE_ID::compiler::Version* CodeGeneratorRequest::_internal_mutable_compiler_version() {
+ _has_bits_[0] |= 0x00000002u;
+ if (compiler_version_ == nullptr) {
+ auto* p = CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::compiler::Version>(GetArenaForAllocation());
+ compiler_version_ = p;
+ }
+ return compiler_version_;
+}
+inline ::PROTOBUF_NAMESPACE_ID::compiler::Version* CodeGeneratorRequest::mutable_compiler_version() {
+ ::PROTOBUF_NAMESPACE_ID::compiler::Version* _msg = _internal_mutable_compiler_version();
+ // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.CodeGeneratorRequest.compiler_version)
+ return _msg;
+}
+inline void CodeGeneratorRequest::set_allocated_compiler_version(::PROTOBUF_NAMESPACE_ID::compiler::Version* compiler_version) {
+ ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaForAllocation();
+ if (message_arena == nullptr) {
+ delete compiler_version_;
+ }
+ if (compiler_version) {
+ ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
+ ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper<::PROTOBUF_NAMESPACE_ID::compiler::Version>::GetOwningArena(compiler_version);
+ if (message_arena != submessage_arena) {
+ compiler_version = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
+ message_arena, compiler_version, submessage_arena);
+ }
+ _has_bits_[0] |= 0x00000002u;
+ } else {
+ _has_bits_[0] &= ~0x00000002u;
+ }
+ compiler_version_ = compiler_version;
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.compiler.CodeGeneratorRequest.compiler_version)
+}
+
+// -------------------------------------------------------------------
+
+// CodeGeneratorResponse_File
+
+// optional string name = 1;
+inline bool CodeGeneratorResponse_File::_internal_has_name() const {
+ bool value = (_has_bits_[0] & 0x00000001u) != 0;
+ return value;
+}
+inline bool CodeGeneratorResponse_File::has_name() const {
+ return _internal_has_name();
+}
+inline void CodeGeneratorResponse_File::clear_name() {
+ name_.ClearToEmpty();
+ _has_bits_[0] &= ~0x00000001u;
+}
+inline const std::string& CodeGeneratorResponse_File::name() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorResponse.File.name)
+ return _internal_name();
+}
+template <typename ArgT0, typename... ArgT>
+inline PROTOBUF_ALWAYS_INLINE
+void CodeGeneratorResponse_File::set_name(ArgT0&& arg0, ArgT... args) {
+ _has_bits_[0] |= 0x00000001u;
+ name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
+ // @@protoc_insertion_point(field_set:google.protobuf.compiler.CodeGeneratorResponse.File.name)
+}
+inline std::string* CodeGeneratorResponse_File::mutable_name() {
+ std::string* _s = _internal_mutable_name();
+ // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.CodeGeneratorResponse.File.name)
+ return _s;
+}
+inline const std::string& CodeGeneratorResponse_File::_internal_name() const {
+ return name_.Get();
+}
+inline void CodeGeneratorResponse_File::_internal_set_name(const std::string& value) {
+ _has_bits_[0] |= 0x00000001u;
+ name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation());
+}
+inline std::string* CodeGeneratorResponse_File::_internal_mutable_name() {
+ _has_bits_[0] |= 0x00000001u;
+ return name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation());
+}
+inline std::string* CodeGeneratorResponse_File::release_name() {
+ // @@protoc_insertion_point(field_release:google.protobuf.compiler.CodeGeneratorResponse.File.name)
+ if (!_internal_has_name()) {
+ return nullptr;
+ }
+ _has_bits_[0] &= ~0x00000001u;
+ auto* p = name_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (name_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
+ name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ return p;
+}
+inline void CodeGeneratorResponse_File::set_allocated_name(std::string* name) {
+ if (name != nullptr) {
+ _has_bits_[0] |= 0x00000001u;
+ } else {
+ _has_bits_[0] &= ~0x00000001u;
+ }
+ name_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), name,
+ GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (name_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
+ name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.compiler.CodeGeneratorResponse.File.name)
+}
+
+// optional string insertion_point = 2;
+inline bool CodeGeneratorResponse_File::_internal_has_insertion_point() const {
+ bool value = (_has_bits_[0] & 0x00000002u) != 0;
+ return value;
+}
+inline bool CodeGeneratorResponse_File::has_insertion_point() const {
+ return _internal_has_insertion_point();
+}
+inline void CodeGeneratorResponse_File::clear_insertion_point() {
+ insertion_point_.ClearToEmpty();
+ _has_bits_[0] &= ~0x00000002u;
+}
+inline const std::string& CodeGeneratorResponse_File::insertion_point() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point)
+ return _internal_insertion_point();
+}
+template <typename ArgT0, typename... ArgT>
+inline PROTOBUF_ALWAYS_INLINE
+void CodeGeneratorResponse_File::set_insertion_point(ArgT0&& arg0, ArgT... args) {
+ _has_bits_[0] |= 0x00000002u;
+ insertion_point_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
+ // @@protoc_insertion_point(field_set:google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point)
+}
+inline std::string* CodeGeneratorResponse_File::mutable_insertion_point() {
+ std::string* _s = _internal_mutable_insertion_point();
+ // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point)
+ return _s;
+}
+inline const std::string& CodeGeneratorResponse_File::_internal_insertion_point() const {
+ return insertion_point_.Get();
+}
+inline void CodeGeneratorResponse_File::_internal_set_insertion_point(const std::string& value) {
+ _has_bits_[0] |= 0x00000002u;
+ insertion_point_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation());
+}
+inline std::string* CodeGeneratorResponse_File::_internal_mutable_insertion_point() {
+ _has_bits_[0] |= 0x00000002u;
+ return insertion_point_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation());
+}
+inline std::string* CodeGeneratorResponse_File::release_insertion_point() {
+ // @@protoc_insertion_point(field_release:google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point)
+ if (!_internal_has_insertion_point()) {
+ return nullptr;
+ }
+ _has_bits_[0] &= ~0x00000002u;
+ auto* p = insertion_point_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (insertion_point_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
+ insertion_point_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ return p;
+}
+inline void CodeGeneratorResponse_File::set_allocated_insertion_point(std::string* insertion_point) {
+ if (insertion_point != nullptr) {
+ _has_bits_[0] |= 0x00000002u;
+ } else {
+ _has_bits_[0] &= ~0x00000002u;
+ }
+ insertion_point_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), insertion_point,
+ GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (insertion_point_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
+ insertion_point_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point)
+}
+
+// optional string content = 15;
+inline bool CodeGeneratorResponse_File::_internal_has_content() const {
+ bool value = (_has_bits_[0] & 0x00000004u) != 0;
+ return value;
+}
+inline bool CodeGeneratorResponse_File::has_content() const {
+ return _internal_has_content();
+}
+inline void CodeGeneratorResponse_File::clear_content() {
+ content_.ClearToEmpty();
+ _has_bits_[0] &= ~0x00000004u;
+}
+inline const std::string& CodeGeneratorResponse_File::content() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorResponse.File.content)
+ return _internal_content();
+}
+template <typename ArgT0, typename... ArgT>
+inline PROTOBUF_ALWAYS_INLINE
+void CodeGeneratorResponse_File::set_content(ArgT0&& arg0, ArgT... args) {
+ _has_bits_[0] |= 0x00000004u;
+ content_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
+ // @@protoc_insertion_point(field_set:google.protobuf.compiler.CodeGeneratorResponse.File.content)
+}
+inline std::string* CodeGeneratorResponse_File::mutable_content() {
+ std::string* _s = _internal_mutable_content();
+ // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.CodeGeneratorResponse.File.content)
+ return _s;
+}
+inline const std::string& CodeGeneratorResponse_File::_internal_content() const {
+ return content_.Get();
+}
+inline void CodeGeneratorResponse_File::_internal_set_content(const std::string& value) {
+ _has_bits_[0] |= 0x00000004u;
+ content_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation());
+}
+inline std::string* CodeGeneratorResponse_File::_internal_mutable_content() {
+ _has_bits_[0] |= 0x00000004u;
+ return content_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation());
+}
+inline std::string* CodeGeneratorResponse_File::release_content() {
+ // @@protoc_insertion_point(field_release:google.protobuf.compiler.CodeGeneratorResponse.File.content)
+ if (!_internal_has_content()) {
+ return nullptr;
+ }
+ _has_bits_[0] &= ~0x00000004u;
+ auto* p = content_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (content_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
+ content_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ return p;
+}
+inline void CodeGeneratorResponse_File::set_allocated_content(std::string* content) {
+ if (content != nullptr) {
+ _has_bits_[0] |= 0x00000004u;
+ } else {
+ _has_bits_[0] &= ~0x00000004u;
+ }
+ content_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), content,
+ GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (content_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
+ content_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.compiler.CodeGeneratorResponse.File.content)
+}
+
+// optional .google.protobuf.GeneratedCodeInfo generated_code_info = 16;
+inline bool CodeGeneratorResponse_File::_internal_has_generated_code_info() const {
+ bool value = (_has_bits_[0] & 0x00000008u) != 0;
+ PROTOBUF_ASSUME(!value || generated_code_info_ != nullptr);
+ return value;
+}
+inline bool CodeGeneratorResponse_File::has_generated_code_info() const {
+ return _internal_has_generated_code_info();
+}
+inline const ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo& CodeGeneratorResponse_File::_internal_generated_code_info() const {
+ const ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* p = generated_code_info_;
+ return p != nullptr ? *p : reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo&>(
+ ::PROTOBUF_NAMESPACE_ID::_GeneratedCodeInfo_default_instance_);
+}
+inline const ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo& CodeGeneratorResponse_File::generated_code_info() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorResponse.File.generated_code_info)
+ return _internal_generated_code_info();
+}
+inline void CodeGeneratorResponse_File::unsafe_arena_set_allocated_generated_code_info(
+ ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* generated_code_info) {
+ if (GetArenaForAllocation() == nullptr) {
+ delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(generated_code_info_);
+ }
+ generated_code_info_ = generated_code_info;
+ if (generated_code_info) {
+ _has_bits_[0] |= 0x00000008u;
+ } else {
+ _has_bits_[0] &= ~0x00000008u;
+ }
+ // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.compiler.CodeGeneratorResponse.File.generated_code_info)
+}
+inline ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* CodeGeneratorResponse_File::release_generated_code_info() {
+ _has_bits_[0] &= ~0x00000008u;
+ ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* temp = generated_code_info_;
+ generated_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::GeneratedCodeInfo* CodeGeneratorResponse_File::unsafe_arena_release_generated_code_info() {
+ // @@protoc_insertion_point(field_release:google.protobuf.compiler.CodeGeneratorResponse.File.generated_code_info)
+ _has_bits_[0] &= ~0x00000008u;
+ ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* temp = generated_code_info_;
+ generated_code_info_ = nullptr;
+ return temp;
+}
+inline ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* CodeGeneratorResponse_File::_internal_mutable_generated_code_info() {
+ _has_bits_[0] |= 0x00000008u;
+ if (generated_code_info_ == nullptr) {
+ auto* p = CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo>(GetArenaForAllocation());
+ generated_code_info_ = p;
+ }
+ return generated_code_info_;
+}
+inline ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* CodeGeneratorResponse_File::mutable_generated_code_info() {
+ ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* _msg = _internal_mutable_generated_code_info();
+ // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.CodeGeneratorResponse.File.generated_code_info)
+ return _msg;
+}
+inline void CodeGeneratorResponse_File::set_allocated_generated_code_info(::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* generated_code_info) {
+ ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaForAllocation();
+ if (message_arena == nullptr) {
+ delete reinterpret_cast< ::PROTOBUF_NAMESPACE_ID::MessageLite*>(generated_code_info_);
+ }
+ if (generated_code_info) {
+ ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
+ ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper<
+ ::PROTOBUF_NAMESPACE_ID::MessageLite>::GetOwningArena(
+ reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(generated_code_info));
+ if (message_arena != submessage_arena) {
+ generated_code_info = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
+ message_arena, generated_code_info, submessage_arena);
+ }
+ _has_bits_[0] |= 0x00000008u;
+ } else {
+ _has_bits_[0] &= ~0x00000008u;
+ }
+ generated_code_info_ = generated_code_info;
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.compiler.CodeGeneratorResponse.File.generated_code_info)
+}
+
+// -------------------------------------------------------------------
+
+// CodeGeneratorResponse
+
+// optional string error = 1;
+inline bool CodeGeneratorResponse::_internal_has_error() const {
+ bool value = (_has_bits_[0] & 0x00000001u) != 0;
+ return value;
+}
+inline bool CodeGeneratorResponse::has_error() const {
+ return _internal_has_error();
+}
+inline void CodeGeneratorResponse::clear_error() {
+ error_.ClearToEmpty();
+ _has_bits_[0] &= ~0x00000001u;
+}
+inline const std::string& CodeGeneratorResponse::error() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorResponse.error)
+ return _internal_error();
+}
+template <typename ArgT0, typename... ArgT>
+inline PROTOBUF_ALWAYS_INLINE
+void CodeGeneratorResponse::set_error(ArgT0&& arg0, ArgT... args) {
+ _has_bits_[0] |= 0x00000001u;
+ error_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
+ // @@protoc_insertion_point(field_set:google.protobuf.compiler.CodeGeneratorResponse.error)
+}
+inline std::string* CodeGeneratorResponse::mutable_error() {
+ std::string* _s = _internal_mutable_error();
+ // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.CodeGeneratorResponse.error)
+ return _s;
+}
+inline const std::string& CodeGeneratorResponse::_internal_error() const {
+ return error_.Get();
+}
+inline void CodeGeneratorResponse::_internal_set_error(const std::string& value) {
+ _has_bits_[0] |= 0x00000001u;
+ error_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation());
+}
+inline std::string* CodeGeneratorResponse::_internal_mutable_error() {
+ _has_bits_[0] |= 0x00000001u;
+ return error_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation());
+}
+inline std::string* CodeGeneratorResponse::release_error() {
+ // @@protoc_insertion_point(field_release:google.protobuf.compiler.CodeGeneratorResponse.error)
+ if (!_internal_has_error()) {
+ return nullptr;
+ }
+ _has_bits_[0] &= ~0x00000001u;
+ auto* p = error_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (error_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
+ error_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ return p;
+}
+inline void CodeGeneratorResponse::set_allocated_error(std::string* error) {
+ if (error != nullptr) {
+ _has_bits_[0] |= 0x00000001u;
+ } else {
+ _has_bits_[0] &= ~0x00000001u;
+ }
+ error_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), error,
+ GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (error_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
+ error_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.compiler.CodeGeneratorResponse.error)
+}
+
+// optional uint64 supported_features = 2;
+inline bool CodeGeneratorResponse::_internal_has_supported_features() const {
+ bool value = (_has_bits_[0] & 0x00000002u) != 0;
+ return value;
+}
+inline bool CodeGeneratorResponse::has_supported_features() const {
+ return _internal_has_supported_features();
+}
+inline void CodeGeneratorResponse::clear_supported_features() {
+ supported_features_ = uint64_t{0u};
+ _has_bits_[0] &= ~0x00000002u;
+}
+inline uint64_t CodeGeneratorResponse::_internal_supported_features() const {
+ return supported_features_;
+}
+inline uint64_t CodeGeneratorResponse::supported_features() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorResponse.supported_features)
+ return _internal_supported_features();
+}
+inline void CodeGeneratorResponse::_internal_set_supported_features(uint64_t value) {
+ _has_bits_[0] |= 0x00000002u;
+ supported_features_ = value;
+}
+inline void CodeGeneratorResponse::set_supported_features(uint64_t value) {
+ _internal_set_supported_features(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.compiler.CodeGeneratorResponse.supported_features)
+}
+
+// repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15;
+inline int CodeGeneratorResponse::_internal_file_size() const {
+ return file_.size();
+}
+inline int CodeGeneratorResponse::file_size() const {
+ return _internal_file_size();
+}
+inline void CodeGeneratorResponse::clear_file() {
+ file_.Clear();
+}
+inline ::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File* CodeGeneratorResponse::mutable_file(int index) {
+ // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.CodeGeneratorResponse.file)
+ return file_.Mutable(index);
+}
+inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File >*
+CodeGeneratorResponse::mutable_file() {
+ // @@protoc_insertion_point(field_mutable_list:google.protobuf.compiler.CodeGeneratorResponse.file)
+ return &file_;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File& CodeGeneratorResponse::_internal_file(int index) const {
+ return file_.Get(index);
+}
+inline const ::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File& CodeGeneratorResponse::file(int index) const {
+ // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorResponse.file)
+ return _internal_file(index);
+}
+inline ::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File* CodeGeneratorResponse::_internal_add_file() {
+ return file_.Add();
+}
+inline ::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File* CodeGeneratorResponse::add_file() {
+ ::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File* _add = _internal_add_file();
+ // @@protoc_insertion_point(field_add:google.protobuf.compiler.CodeGeneratorResponse.file)
+ return _add;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File >&
+CodeGeneratorResponse::file() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.compiler.CodeGeneratorResponse.file)
+ return file_;
+}
+
+#ifdef __GNUC__
+ #pragma GCC diagnostic pop
+#endif // __GNUC__
+// -------------------------------------------------------------------
+
+// -------------------------------------------------------------------
+
+// -------------------------------------------------------------------
+
+
+// @@protoc_insertion_point(namespace_scope)
+
+} // namespace compiler
+PROTOBUF_NAMESPACE_CLOSE
+
+PROTOBUF_NAMESPACE_OPEN
+
+template <> struct is_proto_enum< ::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_Feature> : ::std::true_type {};
+template <>
+inline const EnumDescriptor* GetEnumDescriptor< ::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_Feature>() {
+ return ::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_Feature_descriptor();
+}
+
+PROTOBUF_NAMESPACE_CLOSE
+
+// @@protoc_insertion_point(global_scope)
+
+#include <port_undef.inc>
+#endif // GOOGLE_PROTOBUF_INCLUDED_GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fcompiler_2fplugin_2eproto
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/plugin.proto b/NorthstarDedicatedTest/include/protobuf/compiler/plugin.proto
new file mode 100644
index 00000000..9242aacc
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/plugin.proto
@@ -0,0 +1,183 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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)
+//
+// WARNING: The plugin interface is currently EXPERIMENTAL and is subject to
+// change.
+//
+// protoc (aka the Protocol Compiler) can be extended via plugins. A plugin is
+// just a program that reads a CodeGeneratorRequest from stdin and writes a
+// CodeGeneratorResponse to stdout.
+//
+// Plugins written using C++ can use google/protobuf/compiler/plugin.h instead
+// of dealing with the raw protocol defined here.
+//
+// A plugin executable needs only to be placed somewhere in the path. The
+// plugin should be named "protoc-gen-$NAME", and will then be used when the
+// flag "--${NAME}_out" is passed to protoc.
+
+syntax = "proto2";
+
+package google.protobuf.compiler;
+option java_package = "com.google.protobuf.compiler";
+option java_outer_classname = "PluginProtos";
+
+option go_package = "google.golang.org/protobuf/types/pluginpb";
+
+import "google/protobuf/descriptor.proto";
+
+// The version number of protocol compiler.
+message Version {
+ optional int32 major = 1;
+ optional int32 minor = 2;
+ optional int32 patch = 3;
+ // A suffix for alpha, beta or rc release, e.g., "alpha-1", "rc2". It should
+ // be empty for mainline stable releases.
+ optional string suffix = 4;
+}
+
+// An encoded CodeGeneratorRequest is written to the plugin's stdin.
+message CodeGeneratorRequest {
+ // The .proto files that were explicitly listed on the command-line. The
+ // code generator should generate code only for these files. Each file's
+ // descriptor will be included in proto_file, below.
+ repeated string file_to_generate = 1;
+
+ // The generator parameter passed on the command-line.
+ optional string parameter = 2;
+
+ // FileDescriptorProtos for all files in files_to_generate and everything
+ // they import. The files will appear in topological order, so each file
+ // appears before any file that imports it.
+ //
+ // protoc guarantees that all proto_files will be written after
+ // the fields above, even though this is not technically guaranteed by the
+ // protobuf wire format. This theoretically could allow a plugin to stream
+ // in the FileDescriptorProtos and handle them one by one rather than read
+ // the entire set into memory at once. However, as of this writing, this
+ // is not similarly optimized on protoc's end -- it will store all fields in
+ // memory at once before sending them to the plugin.
+ //
+ // Type names of fields and extensions in the FileDescriptorProto are always
+ // fully qualified.
+ repeated FileDescriptorProto proto_file = 15;
+
+ // The version number of protocol compiler.
+ optional Version compiler_version = 3;
+
+}
+
+// The plugin writes an encoded CodeGeneratorResponse to stdout.
+message CodeGeneratorResponse {
+ // Error message. If non-empty, code generation failed. The plugin process
+ // should exit with status code zero even if it reports an error in this way.
+ //
+ // This should be used to indicate errors in .proto files which prevent the
+ // code generator from generating correct code. Errors which indicate a
+ // problem in protoc itself -- such as the input CodeGeneratorRequest being
+ // unparseable -- should be reported by writing a message to stderr and
+ // exiting with a non-zero status code.
+ optional string error = 1;
+
+ // A bitmask of supported features that the code generator supports.
+ // This is a bitwise "or" of values from the Feature enum.
+ optional uint64 supported_features = 2;
+
+ // Sync with code_generator.h.
+ enum Feature {
+ FEATURE_NONE = 0;
+ FEATURE_PROTO3_OPTIONAL = 1;
+ }
+
+ // Represents a single generated file.
+ message File {
+ // The file name, relative to the output directory. The name must not
+ // contain "." or ".." components and must be relative, not be absolute (so,
+ // the file cannot lie outside the output directory). "/" must be used as
+ // the path separator, not "\".
+ //
+ // If the name is omitted, the content will be appended to the previous
+ // file. This allows the generator to break large files into small chunks,
+ // and allows the generated text to be streamed back to protoc so that large
+ // files need not reside completely in memory at one time. Note that as of
+ // this writing protoc does not optimize for this -- it will read the entire
+ // CodeGeneratorResponse before writing files to disk.
+ optional string name = 1;
+
+ // If non-empty, indicates that the named file should already exist, and the
+ // content here is to be inserted into that file at a defined insertion
+ // point. This feature allows a code generator to extend the output
+ // produced by another code generator. The original generator may provide
+ // insertion points by placing special annotations in the file that look
+ // like:
+ // @@protoc_insertion_point(NAME)
+ // The annotation can have arbitrary text before and after it on the line,
+ // which allows it to be placed in a comment. NAME should be replaced with
+ // an identifier naming the point -- this is what other generators will use
+ // as the insertion_point. Code inserted at this point will be placed
+ // immediately above the line containing the insertion point (thus multiple
+ // insertions to the same point will come out in the order they were added).
+ // The double-@ is intended to make it unlikely that the generated code
+ // could contain things that look like insertion points by accident.
+ //
+ // For example, the C++ code generator places the following line in the
+ // .pb.h files that it generates:
+ // // @@protoc_insertion_point(namespace_scope)
+ // This line appears within the scope of the file's package namespace, but
+ // outside of any particular class. Another plugin can then specify the
+ // insertion_point "namespace_scope" to generate additional classes or
+ // other declarations that should be placed in this scope.
+ //
+ // Note that if the line containing the insertion point begins with
+ // whitespace, the same whitespace will be added to every line of the
+ // inserted text. This is useful for languages like Python, where
+ // indentation matters. In these languages, the insertion point comment
+ // should be indented the same amount as any inserted code will need to be
+ // in order to work correctly in that context.
+ //
+ // The code generator that generates the initial file and the one which
+ // inserts into it must both run as part of a single invocation of protoc.
+ // Code generators are executed in the order in which they appear on the
+ // command line.
+ //
+ // If |insertion_point| is present, |name| must also be present.
+ optional string insertion_point = 2;
+
+ // The file contents.
+ optional string content = 15;
+
+ // Information describing the file content being inserted. If an insertion
+ // point is used, this information will be appropriately offset and inserted
+ // into the code generation metadata for the generated files.
+ optional GeneratedCodeInfo generated_code_info = 16;
+ }
+ repeated File file = 15;
+}
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/python/python_generator.cc b/NorthstarDedicatedTest/include/protobuf/compiler/python/python_generator.cc
new file mode 100644
index 00000000..96b52990
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/python/python_generator.cc
@@ -0,0 +1,1577 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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: robinson@google.com (Will Robinson)
+//
+// This module outputs pure-Python protocol message classes that will
+// largely be constructed at runtime via the metaclass in reflection.py.
+// In other words, our job is basically to output a Python equivalent
+// of the C++ *Descriptor objects, and fix up all circular references
+// within these objects.
+//
+// Note that the runtime performance of protocol message classes created in
+// this way is expected to be lousy. The plan is to create an alternate
+// generator that outputs a Python/C extension module that lets
+// performance-minded Python code leverage the fast C++ implementation
+// directly.
+
+#include <compiler/python/python_generator.h>
+
+#include <algorithm>
+#include <limits>
+#include <map>
+#include <memory>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include <stubs/logging.h>
+#include <stubs/common.h>
+#include <stubs/stringprintf.h>
+#include <descriptor.pb.h>
+#include <io/printer.h>
+#include <io/zero_copy_stream.h>
+#include <descriptor.h>
+#include <stubs/strutil.h>
+#include <stubs/substitute.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace python {
+
+namespace {
+
+
+// Returns the Python module name expected for a given .proto filename.
+std::string ModuleName(const std::string& filename) {
+ std::string basename = StripProto(filename);
+ ReplaceCharacters(&basename, "-", '_');
+ ReplaceCharacters(&basename, "/", '.');
+ return basename + "_pb2";
+}
+
+// Returns the alias we assign to the module of the given .proto filename
+// when importing. See testPackageInitializationImport in
+// net/proto2/python/internal/reflection_test.py
+// to see why we need the alias.
+std::string ModuleAlias(const std::string& filename) {
+ std::string module_name = ModuleName(filename);
+ // We can't have dots in the module name, so we replace each with _dot_.
+ // But that could lead to a collision between a.b and a_dot_b, so we also
+ // duplicate each underscore.
+ GlobalReplaceSubstring("_", "__", &module_name);
+ GlobalReplaceSubstring(".", "_dot_", &module_name);
+ return module_name;
+}
+
+// Keywords reserved by the Python language.
+const char* const kKeywords[] = {
+ "False", "None", "True", "and", "as", "assert",
+ "async", "await", "break", "class", "continue", "def",
+ "del", "elif", "else", "except", "finally", "for",
+ "from", "global", "if", "import", "in", "is",
+ "lambda", "nonlocal", "not", "or", "pass", "raise",
+ "return", "try", "while", "with", "yield", "print",
+};
+const char* const* kKeywordsEnd =
+ kKeywords + (sizeof(kKeywords) / sizeof(kKeywords[0]));
+
+bool ContainsPythonKeyword(const std::string& module_name) {
+ std::vector<std::string> tokens = Split(module_name, ".");
+ for (int i = 0; i < tokens.size(); ++i) {
+ if (std::find(kKeywords, kKeywordsEnd, tokens[i]) != kKeywordsEnd) {
+ return true;
+ }
+ }
+ return false;
+}
+
+inline bool IsPythonKeyword(const std::string& name) {
+ return (std::find(kKeywords, kKeywordsEnd, name) != kKeywordsEnd);
+}
+
+std::string ResolveKeyword(const std::string& name) {
+ if (IsPythonKeyword(name)) {
+ return "globals()['" + name + "']";
+ }
+ return name;
+}
+
+// Returns the name of all containing types for descriptor,
+// in order from outermost to innermost, followed by descriptor's
+// own name. Each name is separated by |separator|.
+template <typename DescriptorT>
+std::string NamePrefixedWithNestedTypes(const DescriptorT& descriptor,
+ const std::string& separator) {
+ std::string name = descriptor.name();
+ const Descriptor* parent = descriptor.containing_type();
+ if (parent != nullptr) {
+ std::string prefix = NamePrefixedWithNestedTypes(*parent, separator);
+ if (separator == "." && IsPythonKeyword(name)) {
+ return "getattr(" + prefix + ", '" + name + "')";
+ } else {
+ return prefix + separator + name;
+ }
+ }
+ if (separator == ".") {
+ name = ResolveKeyword(name);
+ }
+ return name;
+}
+
+// Name of the class attribute where we store the Python
+// descriptor.Descriptor instance for the generated class.
+// Must stay consistent with the _DESCRIPTOR_KEY constant
+// in proto2/public/reflection.py.
+const char kDescriptorKey[] = "DESCRIPTOR";
+
+// Does the file have top-level enums?
+inline bool HasTopLevelEnums(const FileDescriptor* file) {
+ return file->enum_type_count() > 0;
+}
+
+// Should we generate generic services for this file?
+inline bool HasGenericServices(const FileDescriptor* file) {
+ return file->service_count() > 0 && file->options().py_generic_services();
+}
+
+// Prints the common boilerplate needed at the top of every .py
+// file output by this generator.
+void PrintTopBoilerplate(io::Printer* printer, const FileDescriptor* file,
+ bool descriptor_proto) {
+ // TODO(robinson): Allow parameterization of Python version?
+ printer->Print(
+ "# -*- coding: utf-8 -*-\n"
+ "# Generated by the protocol buffer compiler. DO NOT EDIT!\n"
+ "# source: $filename$\n"
+ "\"\"\"Generated protocol buffer code.\"\"\"\n",
+ "filename", file->name());
+ if (HasTopLevelEnums(file)) {
+ printer->Print(
+ "from google.protobuf.internal import enum_type_wrapper\n");
+ }
+ printer->Print(
+ "from google.protobuf import descriptor as _descriptor\n"
+ "from google.protobuf import descriptor_pool as "
+ "_descriptor_pool\n"
+ "from google.protobuf import message as _message\n"
+ "from google.protobuf import reflection as _reflection\n"
+ "from google.protobuf import symbol_database as "
+ "_symbol_database\n");
+ if (HasGenericServices(file)) {
+ printer->Print(
+ "from google.protobuf import service as _service\n"
+ "from google.protobuf import service_reflection\n");
+ }
+
+ printer->Print(
+ "# @@protoc_insertion_point(imports)\n\n"
+ "_sym_db = _symbol_database.Default()\n");
+ printer->Print("\n\n");
+}
+
+// Returns a Python literal giving the default value for a field.
+// If the field specifies no explicit default value, we'll return
+// the default default value for the field type (zero for numbers,
+// empty string for strings, empty list for repeated fields, and
+// None for non-repeated, composite fields).
+//
+// TODO(robinson): Unify with code from
+// //compiler/cpp/internal/primitive_field.cc
+// //compiler/cpp/internal/enum_field.cc
+// //compiler/cpp/internal/string_field.cc
+std::string StringifyDefaultValue(const FieldDescriptor& field) {
+ if (field.is_repeated()) {
+ return "[]";
+ }
+
+ switch (field.cpp_type()) {
+ case FieldDescriptor::CPPTYPE_INT32:
+ return StrCat(field.default_value_int32());
+ case FieldDescriptor::CPPTYPE_UINT32:
+ return StrCat(field.default_value_uint32());
+ case FieldDescriptor::CPPTYPE_INT64:
+ return StrCat(field.default_value_int64());
+ case FieldDescriptor::CPPTYPE_UINT64:
+ return StrCat(field.default_value_uint64());
+ case FieldDescriptor::CPPTYPE_DOUBLE: {
+ double value = field.default_value_double();
+ if (value == std::numeric_limits<double>::infinity()) {
+ // Python pre-2.6 on Windows does not parse "inf" correctly. However,
+ // a numeric literal that is too big for a double will become infinity.
+ return "1e10000";
+ } else if (value == -std::numeric_limits<double>::infinity()) {
+ // See above.
+ return "-1e10000";
+ } else if (value != value) {
+ // infinity * 0 = nan
+ return "(1e10000 * 0)";
+ } else {
+ return "float(" + SimpleDtoa(value) + ")";
+ }
+ }
+ case FieldDescriptor::CPPTYPE_FLOAT: {
+ float value = field.default_value_float();
+ if (value == std::numeric_limits<float>::infinity()) {
+ // Python pre-2.6 on Windows does not parse "inf" correctly. However,
+ // a numeric literal that is too big for a double will become infinity.
+ return "1e10000";
+ } else if (value == -std::numeric_limits<float>::infinity()) {
+ // See above.
+ return "-1e10000";
+ } else if (value != value) {
+ // infinity - infinity = nan
+ return "(1e10000 * 0)";
+ } else {
+ return "float(" + SimpleFtoa(value) + ")";
+ }
+ }
+ case FieldDescriptor::CPPTYPE_BOOL:
+ return field.default_value_bool() ? "True" : "False";
+ case FieldDescriptor::CPPTYPE_ENUM:
+ return StrCat(field.default_value_enum()->number());
+ case FieldDescriptor::CPPTYPE_STRING:
+ return "b\"" + CEscape(field.default_value_string()) +
+ (field.type() != FieldDescriptor::TYPE_STRING
+ ? "\""
+ : "\".decode('utf-8')");
+ case FieldDescriptor::CPPTYPE_MESSAGE:
+ return "None";
+ }
+ // (We could add a default case above but then we wouldn't get the nice
+ // compiler warning when a new type is added.)
+ GOOGLE_LOG(FATAL) << "Not reached.";
+ return "";
+}
+
+std::string StringifySyntax(FileDescriptor::Syntax syntax) {
+ switch (syntax) {
+ case FileDescriptor::SYNTAX_PROTO2:
+ return "proto2";
+ case FileDescriptor::SYNTAX_PROTO3:
+ return "proto3";
+ case FileDescriptor::SYNTAX_UNKNOWN:
+ default:
+ GOOGLE_LOG(FATAL) << "Unsupported syntax; this generator only supports proto2 "
+ "and proto3 syntax.";
+ return "";
+ }
+}
+
+} // namespace
+
+Generator::Generator() : file_(nullptr) {}
+
+Generator::~Generator() {}
+
+uint64_t Generator::GetSupportedFeatures() const {
+ return CodeGenerator::Feature::FEATURE_PROTO3_OPTIONAL;
+}
+
+bool Generator::Generate(const FileDescriptor* file,
+ const std::string& parameter,
+ GeneratorContext* context, std::string* error) const {
+ // -----------------------------------------------------------------
+ // parse generator options
+ bool cpp_generated_lib_linked = false;
+
+ std::vector<std::pair<std::string, std::string> > options;
+ ParseGeneratorParameter(parameter, &options);
+
+ for (int i = 0; i < options.size(); i++) {
+ if (options[i].first == "cpp_generated_lib_linked") {
+ cpp_generated_lib_linked = true;
+ } else {
+ *error = "Unknown generator option: " + options[i].first;
+ return false;
+ }
+ }
+
+ // Completely serialize all Generate() calls on this instance. The
+ // thread-safety constraints of the CodeGenerator interface aren't clear so
+ // just be as conservative as possible. It's easier to relax this later if
+ // we need to, but I doubt it will be an issue.
+ // TODO(kenton): The proper thing to do would be to allocate any state on
+ // the stack and use that, so that the Generator class itself does not need
+ // to have any mutable members. Then it is implicitly thread-safe.
+ MutexLock lock(&mutex_);
+ file_ = file;
+ std::string module_name = ModuleName(file->name());
+ std::string filename = module_name;
+ ReplaceCharacters(&filename, ".", '/');
+ filename += ".py";
+
+ pure_python_workable_ = !cpp_generated_lib_linked;
+ if (HasPrefixString(file->name(), "google/protobuf/")) {
+ pure_python_workable_ = true;
+ }
+
+ FileDescriptorProto fdp;
+ file_->CopyTo(&fdp);
+ fdp.SerializeToString(&file_descriptor_serialized_);
+
+
+ std::unique_ptr<io::ZeroCopyOutputStream> output(context->Open(filename));
+ GOOGLE_CHECK(output.get());
+ io::Printer printer(output.get(), '$');
+ printer_ = &printer;
+
+ PrintTopBoilerplate(printer_, file_, GeneratingDescriptorProto());
+ if (pure_python_workable_) {
+ PrintImports();
+ }
+ PrintFileDescriptor();
+ PrintTopLevelEnums();
+ PrintTopLevelExtensions();
+ if (pure_python_workable_) {
+ if (GeneratingDescriptorProto()) {
+ printer_->Print("if _descriptor._USE_C_DESCRIPTORS == False:\n");
+ printer_->Indent();
+ // Create enums before message descriptors
+ PrintAllNestedEnumsInFile(StripPrintDescriptor::kCreate);
+ PrintMessageDescriptors(StripPrintDescriptor::kCreate);
+ FixForeignFieldsInDescriptors();
+ printer_->Outdent();
+ printer_->Print("else:\n");
+ printer_->Indent();
+ }
+ // Find the message descriptors first and then use the message
+ // descriptor to find enums.
+ PrintMessageDescriptors(StripPrintDescriptor::kFind);
+ PrintAllNestedEnumsInFile(StripPrintDescriptor::kFind);
+ if (GeneratingDescriptorProto()) {
+ printer_->Outdent();
+ }
+ }
+ PrintMessages();
+ if (pure_python_workable_) {
+ PrintServiceDescriptors();
+
+ printer.Print("if _descriptor._USE_C_DESCRIPTORS == False:\n");
+ printer_->Indent();
+
+ // We have to fix up the extensions after the message classes themselves,
+ // since they need to call static RegisterExtension() methods on these
+ // classes.
+ FixForeignFieldsInExtensions();
+ // Descriptor options may have custom extensions. These custom options
+ // can only be successfully parsed after we register corresponding
+ // extensions. Therefore we parse all options again here to recognize
+ // custom options that may be unknown when we define the descriptors.
+ // This does not apply to services because they are not used by extensions.
+ FixAllDescriptorOptions();
+
+ // Set serialized_start and serialized_end.
+ SetSerializedPbInterval();
+
+ printer_->Outdent();
+ }
+ if (HasGenericServices(file)) {
+ PrintServices();
+ }
+
+ printer.Print("# @@protoc_insertion_point(module_scope)\n");
+
+ return !printer.failed();
+}
+
+
+// Prints Python imports for all modules imported by |file|.
+void Generator::PrintImports() const {
+ for (int i = 0; i < file_->dependency_count(); ++i) {
+ const std::string& filename = file_->dependency(i)->name();
+
+ std::string module_name = ModuleName(filename);
+ std::string module_alias = ModuleAlias(filename);
+ if (ContainsPythonKeyword(module_name)) {
+ // If the module path contains a Python keyword, we have to quote the
+ // module name and import it using importlib. Otherwise the usual kind of
+ // import statement would result in a syntax error from the presence of
+ // the keyword.
+ printer_->Print("import importlib\n");
+ printer_->Print("$alias$ = importlib.import_module('$name$')\n", "alias",
+ module_alias, "name", module_name);
+ } else {
+ int last_dot_pos = module_name.rfind('.');
+ std::string import_statement;
+ if (last_dot_pos == std::string::npos) {
+ // NOTE(petya): this is not tested as it would require a protocol buffer
+ // outside of any package, and I don't think that is easily achievable.
+ import_statement = "import " + module_name;
+ } else {
+ import_statement = "from " + module_name.substr(0, last_dot_pos) +
+ " import " + module_name.substr(last_dot_pos + 1);
+ }
+ printer_->Print("$statement$ as $alias$\n", "statement", import_statement,
+ "alias", module_alias);
+ }
+
+ CopyPublicDependenciesAliases(module_alias, file_->dependency(i));
+ }
+ printer_->Print("\n");
+
+ // Print public imports.
+ for (int i = 0; i < file_->public_dependency_count(); ++i) {
+ std::string module_name = ModuleName(file_->public_dependency(i)->name());
+ printer_->Print("from $module$ import *\n", "module", module_name);
+ }
+ printer_->Print("\n");
+}
+
+// Prints the single file descriptor for this file.
+void Generator::PrintFileDescriptor() const {
+ std::map<std::string, std::string> m;
+ m["descriptor_name"] = kDescriptorKey;
+ m["name"] = file_->name();
+ m["package"] = file_->package();
+ m["syntax"] = StringifySyntax(file_->syntax());
+ m["options"] = OptionsValue(file_->options().SerializeAsString());
+ m["serialized_descriptor"] = strings::CHexEscape(file_descriptor_serialized_);
+ if (GeneratingDescriptorProto()) {
+ printer_->Print("if _descriptor._USE_C_DESCRIPTORS == False:\n");
+ printer_->Indent();
+ // Pure python's AddSerializedFile() depend on the generated
+ // descriptor_pb2.py thus we can not use AddSerializedFile() when
+ // generated descriptor.proto for pure python.
+ const char file_descriptor_template[] =
+ "$descriptor_name$ = _descriptor.FileDescriptor(\n"
+ " name='$name$',\n"
+ " package='$package$',\n"
+ " syntax='$syntax$',\n"
+ " serialized_options=$options$,\n"
+ " create_key=_descriptor._internal_create_key,\n";
+ printer_->Print(m, file_descriptor_template);
+ printer_->Indent();
+ if (pure_python_workable_) {
+ printer_->Print("serialized_pb=b'$value$'\n", "value",
+ strings::CHexEscape(file_descriptor_serialized_));
+ if (file_->dependency_count() != 0) {
+ printer_->Print(",\ndependencies=[");
+ for (int i = 0; i < file_->dependency_count(); ++i) {
+ std::string module_alias = ModuleAlias(file_->dependency(i)->name());
+ printer_->Print("$module_alias$.DESCRIPTOR,", "module_alias",
+ module_alias);
+ }
+ printer_->Print("]");
+ }
+ if (file_->public_dependency_count() > 0) {
+ printer_->Print(",\npublic_dependencies=[");
+ for (int i = 0; i < file_->public_dependency_count(); ++i) {
+ std::string module_alias =
+ ModuleAlias(file_->public_dependency(i)->name());
+ printer_->Print("$module_alias$.DESCRIPTOR,", "module_alias",
+ module_alias);
+ }
+ printer_->Print("]");
+ }
+ } else {
+ printer_->Print("serialized_pb=''\n");
+ }
+
+ // TODO(falk): Also print options and fix the message_type, enum_type,
+ // service and extension later in the generation.
+
+ printer_->Outdent();
+ printer_->Print(")\n");
+
+ printer_->Outdent();
+ printer_->Print("else:\n");
+ printer_->Indent();
+ }
+ printer_->Print(m,
+ "$descriptor_name$ = "
+ "_descriptor_pool.Default().AddSerializedFile(b'$serialized_"
+ "descriptor$')\n");
+ if (GeneratingDescriptorProto()) {
+ printer_->Outdent();
+ }
+ printer_->Print("\n");
+}
+
+// Prints descriptors and module-level constants for all top-level
+// enums defined in |file|.
+void Generator::PrintTopLevelEnums() const {
+ std::vector<std::pair<std::string, int> > top_level_enum_values;
+ for (int i = 0; i < file_->enum_type_count(); ++i) {
+ const EnumDescriptor& enum_descriptor = *file_->enum_type(i);
+ PrintFindEnum(enum_descriptor);
+ printer_->Print(
+ "$name$ = "
+ "enum_type_wrapper.EnumTypeWrapper($descriptor_name$)",
+ "name", ResolveKeyword(enum_descriptor.name()), "descriptor_name",
+ ModuleLevelDescriptorName(enum_descriptor));
+ printer_->Print("\n");
+
+ for (int j = 0; j < enum_descriptor.value_count(); ++j) {
+ const EnumValueDescriptor& value_descriptor = *enum_descriptor.value(j);
+ top_level_enum_values.push_back(
+ std::make_pair(value_descriptor.name(), value_descriptor.number()));
+ }
+ }
+
+ for (int i = 0; i < top_level_enum_values.size(); ++i) {
+ printer_->Print("$name$ = $value$\n", "name",
+ ResolveKeyword(top_level_enum_values[i].first), "value",
+ StrCat(top_level_enum_values[i].second));
+ }
+ printer_->Print("\n");
+}
+
+// Prints all enums contained in all message types in |file|.
+void Generator::PrintAllNestedEnumsInFile(
+ StripPrintDescriptor print_mode) const {
+ for (int i = 0; i < file_->message_type_count(); ++i) {
+ PrintNestedEnums(*file_->message_type(i), print_mode);
+ }
+}
+
+// Prints a Python statement assigning the appropriate module-level
+// enum name to a Python EnumDescriptor object equivalent to
+// enum_descriptor.
+void Generator::PrintCreateEnum(const EnumDescriptor& enum_descriptor) const {
+ std::map<std::string, std::string> m;
+ std::string module_level_descriptor_name =
+ ModuleLevelDescriptorName(enum_descriptor);
+ m["descriptor_name"] = module_level_descriptor_name;
+ m["name"] = enum_descriptor.name();
+ m["full_name"] = enum_descriptor.full_name();
+ m["file"] = kDescriptorKey;
+ const char enum_descriptor_template[] =
+ "$descriptor_name$ = _descriptor.EnumDescriptor(\n"
+ " name='$name$',\n"
+ " full_name='$full_name$',\n"
+ " filename=None,\n"
+ " file=$file$,\n"
+ " create_key=_descriptor._internal_create_key,\n"
+ " values=[\n";
+ std::string options_string;
+ enum_descriptor.options().SerializeToString(&options_string);
+ printer_->Print(m, enum_descriptor_template);
+ printer_->Indent();
+ printer_->Indent();
+
+ if (pure_python_workable_) {
+ for (int i = 0; i < enum_descriptor.value_count(); ++i) {
+ PrintEnumValueDescriptor(*enum_descriptor.value(i));
+ printer_->Print(",\n");
+ }
+ }
+
+ printer_->Outdent();
+ printer_->Print("],\n");
+ printer_->Print("containing_type=None,\n");
+ printer_->Print("serialized_options=$options_value$,\n", "options_value",
+ OptionsValue(options_string));
+ EnumDescriptorProto edp;
+ printer_->Outdent();
+ printer_->Print(")\n");
+ if (pure_python_workable_) {
+ printer_->Print("_sym_db.RegisterEnumDescriptor($name$)\n", "name",
+ module_level_descriptor_name);
+ }
+ printer_->Print("\n");
+}
+
+void Generator::PrintFindEnum(const EnumDescriptor& enum_descriptor) const {
+ std::map<std::string, std::string> m;
+ m["descriptor_name"] = ModuleLevelDescriptorName(enum_descriptor);
+ m["name"] = enum_descriptor.name();
+ m["file"] = kDescriptorKey;
+ if (enum_descriptor.containing_type()) {
+ m["containing_type"] =
+ ModuleLevelDescriptorName(*enum_descriptor.containing_type());
+ printer_->Print(m,
+ "$descriptor_name$ = "
+ "$containing_type$.enum_types_by_name['$name$']\n");
+ } else {
+ printer_->Print(
+ m, "$descriptor_name$ = $file$.enum_types_by_name['$name$']\n");
+ }
+}
+
+// Recursively prints enums in nested types within descriptor, then
+// prints enums contained at the top level in descriptor.
+void Generator::PrintNestedEnums(const Descriptor& descriptor,
+ StripPrintDescriptor print_mode) const {
+ for (int i = 0; i < descriptor.nested_type_count(); ++i) {
+ PrintNestedEnums(*descriptor.nested_type(i), print_mode);
+ }
+
+ for (int i = 0; i < descriptor.enum_type_count(); ++i) {
+ if (print_mode == StripPrintDescriptor::kCreate) {
+ PrintCreateEnum(*descriptor.enum_type(i));
+ } else {
+ PrintFindEnum(*descriptor.enum_type(i));
+ }
+ }
+}
+
+void Generator::PrintTopLevelExtensions() const {
+ for (int i = 0; i < file_->extension_count(); ++i) {
+ const FieldDescriptor& extension_field = *file_->extension(i);
+ std::string constant_name = extension_field.name() + "_FIELD_NUMBER";
+ ToUpper(&constant_name);
+ printer_->Print("$constant_name$ = $number$\n", "constant_name",
+ constant_name, "number",
+ StrCat(extension_field.number()));
+ printer_->Print(
+ "$resolved_name$ = "
+ "$file$.extensions_by_name['$name$']\n",
+ "resolved_name", ResolveKeyword(extension_field.name()), "file",
+ kDescriptorKey, "name", extension_field.name());
+ }
+ printer_->Print("\n");
+}
+
+// Prints Python equivalents of all Descriptors in |file|.
+void Generator::PrintMessageDescriptors(StripPrintDescriptor print_mode) const {
+ if (print_mode == StripPrintDescriptor::kCreate) {
+ for (int i = 0; i < file_->message_type_count(); ++i) {
+ PrintCreateDescriptor(*file_->message_type(i));
+ printer_->Print("\n");
+ }
+ } else {
+ for (int i = 0; i < file_->message_type_count(); ++i) {
+ PrintFindDescriptor(*file_->message_type(i));
+ }
+ }
+}
+
+void Generator::PrintServiceDescriptors() const {
+ for (int i = 0; i < file_->service_count(); ++i) {
+ PrintServiceDescriptor(*file_->service(i));
+ }
+}
+
+void Generator::PrintServices() const {
+ for (int i = 0; i < file_->service_count(); ++i) {
+ PrintServiceClass(*file_->service(i));
+ PrintServiceStub(*file_->service(i));
+ printer_->Print("\n");
+ }
+}
+
+void Generator::PrintServiceDescriptor(
+ const ServiceDescriptor& descriptor) const {
+ std::map<std::string, std::string> m;
+ m["service_name"] = ModuleLevelServiceDescriptorName(descriptor);
+ m["name"] = descriptor.name();
+ m["file"] = kDescriptorKey;
+ printer_->Print(m, "$service_name$ = $file$.services_by_name['$name$']\n");
+}
+
+void Generator::PrintDescriptorKeyAndModuleName(
+ const ServiceDescriptor& descriptor) const {
+ std::string name = ModuleLevelServiceDescriptorName(descriptor);
+ if (!pure_python_workable_) {
+ name = "_descriptor.ServiceDescriptor(full_name='" +
+ descriptor.full_name() + "')";
+ }
+ printer_->Print("$descriptor_key$ = $descriptor_name$,\n", "descriptor_key",
+ kDescriptorKey, "descriptor_name", name);
+ std::string module_name = ModuleName(file_->name());
+ printer_->Print("__module__ = '$module_name$'\n", "module_name", module_name);
+}
+
+void Generator::PrintServiceClass(const ServiceDescriptor& descriptor) const {
+ // Print the service.
+ printer_->Print(
+ "$class_name$ = service_reflection.GeneratedServiceType("
+ "'$class_name$', (_service.Service,), dict(\n",
+ "class_name", descriptor.name());
+ printer_->Indent();
+ Generator::PrintDescriptorKeyAndModuleName(descriptor);
+ printer_->Print("))\n\n");
+ printer_->Outdent();
+}
+
+void Generator::PrintServiceStub(const ServiceDescriptor& descriptor) const {
+ // Print the service stub.
+ printer_->Print(
+ "$class_name$_Stub = "
+ "service_reflection.GeneratedServiceStubType("
+ "'$class_name$_Stub', ($class_name$,), dict(\n",
+ "class_name", descriptor.name());
+ printer_->Indent();
+ Generator::PrintDescriptorKeyAndModuleName(descriptor);
+ printer_->Print("))\n\n");
+ printer_->Outdent();
+}
+
+// Prints statement assigning ModuleLevelDescriptorName(message_descriptor)
+// to a Python Descriptor object for message_descriptor.
+//
+// Mutually recursive with PrintNestedDescriptors().
+void Generator::PrintCreateDescriptor(
+ const Descriptor& message_descriptor) const {
+ std::map<std::string, std::string> m;
+ m["name"] = message_descriptor.name();
+ m["full_name"] = message_descriptor.full_name();
+ m["file"] = kDescriptorKey;
+
+ PrintNestedDescriptors(message_descriptor, StripPrintDescriptor::kCreate);
+
+ printer_->Print("\n");
+ printer_->Print("$descriptor_name$ = _descriptor.Descriptor(\n",
+ "descriptor_name",
+ ModuleLevelDescriptorName(message_descriptor));
+ printer_->Indent();
+ const char required_function_arguments[] =
+ "name='$name$',\n"
+ "full_name='$full_name$',\n"
+ "filename=None,\n"
+ "file=$file$,\n"
+ "containing_type=None,\n"
+ "create_key=_descriptor._internal_create_key,\n";
+ printer_->Print(m, required_function_arguments);
+ PrintFieldsInDescriptor(message_descriptor);
+ PrintExtensionsInDescriptor(message_descriptor);
+
+ // Nested types
+ printer_->Print("nested_types=[");
+ for (int i = 0; i < message_descriptor.nested_type_count(); ++i) {
+ const std::string nested_name =
+ ModuleLevelDescriptorName(*message_descriptor.nested_type(i));
+ printer_->Print("$name$, ", "name", nested_name);
+ }
+ printer_->Print("],\n");
+
+ // Enum types
+ printer_->Print("enum_types=[\n");
+ printer_->Indent();
+ for (int i = 0; i < message_descriptor.enum_type_count(); ++i) {
+ const std::string descriptor_name =
+ ModuleLevelDescriptorName(*message_descriptor.enum_type(i));
+ printer_->Print(descriptor_name.c_str());
+ printer_->Print(",\n");
+ }
+ printer_->Outdent();
+ printer_->Print("],\n");
+ std::string options_string;
+ message_descriptor.options().SerializeToString(&options_string);
+ printer_->Print(
+ "serialized_options=$options_value$,\n"
+ "is_extendable=$extendable$,\n"
+ "syntax='$syntax$'",
+ "options_value", OptionsValue(options_string), "extendable",
+ message_descriptor.extension_range_count() > 0 ? "True" : "False",
+ "syntax", StringifySyntax(message_descriptor.file()->syntax()));
+ printer_->Print(",\n");
+
+ // Extension ranges
+ printer_->Print("extension_ranges=[");
+ for (int i = 0; i < message_descriptor.extension_range_count(); ++i) {
+ const Descriptor::ExtensionRange* range =
+ message_descriptor.extension_range(i);
+ printer_->Print("($start$, $end$), ", "start", StrCat(range->start),
+ "end", StrCat(range->end));
+ }
+ printer_->Print("],\n");
+ printer_->Print("oneofs=[\n");
+ printer_->Indent();
+ for (int i = 0; i < message_descriptor.oneof_decl_count(); ++i) {
+ const OneofDescriptor* desc = message_descriptor.oneof_decl(i);
+ m.clear();
+ m["name"] = desc->name();
+ m["full_name"] = desc->full_name();
+ m["index"] = StrCat(desc->index());
+ options_string = OptionsValue(desc->options().SerializeAsString());
+ if (options_string == "None") {
+ m["serialized_options"] = "";
+ } else {
+ m["serialized_options"] = ", serialized_options=" + options_string;
+ }
+ printer_->Print(m,
+ "_descriptor.OneofDescriptor(\n"
+ " name='$name$', full_name='$full_name$',\n"
+ " index=$index$, containing_type=None,\n"
+ " create_key=_descriptor._internal_create_key,\n"
+ "fields=[]$serialized_options$),\n");
+ }
+ printer_->Outdent();
+ printer_->Print("],\n");
+
+ printer_->Outdent();
+ printer_->Print(")\n");
+}
+
+void Generator::PrintFindDescriptor(
+ const Descriptor& message_descriptor) const {
+ std::map<std::string, std::string> m;
+ m["descriptor_name"] = ModuleLevelDescriptorName(message_descriptor);
+ m["name"] = message_descriptor.name();
+
+ if (message_descriptor.containing_type()) {
+ m["containing_type"] =
+ ModuleLevelDescriptorName(*message_descriptor.containing_type());
+ printer_->Print(m,
+ "$descriptor_name$ = "
+ "$containing_type$.nested_types_by_name['$name$']\n");
+ } else {
+ m["file"] = kDescriptorKey;
+ printer_->Print(
+ m, "$descriptor_name$ = $file$.message_types_by_name['$name$']\n");
+ }
+
+ PrintNestedDescriptors(message_descriptor, StripPrintDescriptor::kFind);
+}
+
+// Prints Python Descriptor objects for all nested types contained in
+// message_descriptor.
+//
+// Mutually recursive with PrintDescriptor().
+void Generator::PrintNestedDescriptors(const Descriptor& containing_descriptor,
+ StripPrintDescriptor print_mode) const {
+ if (print_mode == StripPrintDescriptor::kCreate) {
+ for (int i = 0; i < containing_descriptor.nested_type_count(); ++i) {
+ PrintCreateDescriptor(*containing_descriptor.nested_type(i));
+ }
+ } else {
+ for (int i = 0; i < containing_descriptor.nested_type_count(); ++i) {
+ PrintFindDescriptor(*containing_descriptor.nested_type(i));
+ }
+ }
+}
+
+// Prints all messages in |file|.
+void Generator::PrintMessages() const {
+ for (int i = 0; i < file_->message_type_count(); ++i) {
+ std::vector<std::string> to_register;
+ PrintMessage(*file_->message_type(i), "", &to_register, false);
+ for (int j = 0; j < to_register.size(); ++j) {
+ printer_->Print("_sym_db.RegisterMessage($name$)\n", "name",
+ ResolveKeyword(to_register[j]));
+ }
+ printer_->Print("\n");
+ }
+}
+
+// Prints a Python class for the given message descriptor. We defer to the
+// metaclass to do almost all of the work of actually creating a useful class.
+// The purpose of this function and its many helper functions above is merely
+// to output a Python version of the descriptors, which the metaclass in
+// reflection.py will use to construct the meat of the class itself.
+//
+// Mutually recursive with PrintNestedMessages().
+// Collect nested message names to_register for the symbol_database.
+void Generator::PrintMessage(const Descriptor& message_descriptor,
+ const std::string& prefix,
+ std::vector<std::string>* to_register,
+ bool is_nested) const {
+ std::string qualified_name;
+ if (is_nested) {
+ if (IsPythonKeyword(message_descriptor.name())) {
+ qualified_name =
+ "getattr(" + prefix + ", '" + message_descriptor.name() + "')";
+ } else {
+ qualified_name = prefix + "." + message_descriptor.name();
+ }
+ printer_->Print(
+ "'$name$' : _reflection.GeneratedProtocolMessageType('$name$', "
+ "(_message.Message,), {\n",
+ "name", message_descriptor.name());
+ } else {
+ qualified_name = ResolveKeyword(message_descriptor.name());
+ printer_->Print(
+ "$qualified_name$ = _reflection.GeneratedProtocolMessageType('$name$', "
+ "(_message.Message,), {\n",
+ "qualified_name", qualified_name, "name", message_descriptor.name());
+ }
+ printer_->Indent();
+
+ to_register->push_back(qualified_name);
+
+ PrintNestedMessages(message_descriptor, qualified_name, to_register);
+ std::map<std::string, std::string> m;
+ m["descriptor_key"] = kDescriptorKey;
+ if (pure_python_workable_) {
+ m["descriptor_name"] = ModuleLevelDescriptorName(message_descriptor);
+ } else {
+ m["descriptor_name"] = "_descriptor.Descriptor(full_name='" +
+ message_descriptor.full_name() + "')";
+ }
+ printer_->Print(m, "'$descriptor_key$' : $descriptor_name$,\n");
+ std::string module_name = ModuleName(file_->name());
+ printer_->Print("'__module__' : '$module_name$'\n", "module_name",
+ module_name);
+ printer_->Print("# @@protoc_insertion_point(class_scope:$full_name$)\n",
+ "full_name", message_descriptor.full_name());
+ printer_->Print("})\n");
+ printer_->Outdent();
+}
+
+// Prints all nested messages within |containing_descriptor|.
+// Mutually recursive with PrintMessage().
+void Generator::PrintNestedMessages(
+ const Descriptor& containing_descriptor, const std::string& prefix,
+ std::vector<std::string>* to_register) const {
+ for (int i = 0; i < containing_descriptor.nested_type_count(); ++i) {
+ printer_->Print("\n");
+ PrintMessage(*containing_descriptor.nested_type(i), prefix, to_register,
+ true);
+ printer_->Print(",\n");
+ }
+}
+
+// Recursively fixes foreign fields in all nested types in |descriptor|, then
+// sets the message_type and enum_type of all message and enum fields to point
+// to their respective descriptors.
+// Args:
+// descriptor: descriptor to print fields for.
+// containing_descriptor: if descriptor is a nested type, this is its
+// containing type, or NULL if this is a root/top-level type.
+void Generator::FixForeignFieldsInDescriptor(
+ const Descriptor& descriptor,
+ const Descriptor* containing_descriptor) const {
+ for (int i = 0; i < descriptor.nested_type_count(); ++i) {
+ FixForeignFieldsInDescriptor(*descriptor.nested_type(i), &descriptor);
+ }
+
+ for (int i = 0; i < descriptor.field_count(); ++i) {
+ const FieldDescriptor& field_descriptor = *descriptor.field(i);
+ FixForeignFieldsInField(&descriptor, field_descriptor, "fields_by_name");
+ }
+
+ FixContainingTypeInDescriptor(descriptor, containing_descriptor);
+ for (int i = 0; i < descriptor.enum_type_count(); ++i) {
+ const EnumDescriptor& enum_descriptor = *descriptor.enum_type(i);
+ FixContainingTypeInDescriptor(enum_descriptor, &descriptor);
+ }
+ for (int i = 0; i < descriptor.oneof_decl_count(); ++i) {
+ std::map<std::string, std::string> m;
+ const OneofDescriptor* oneof = descriptor.oneof_decl(i);
+ m["descriptor_name"] = ModuleLevelDescriptorName(descriptor);
+ m["oneof_name"] = oneof->name();
+ for (int j = 0; j < oneof->field_count(); ++j) {
+ m["field_name"] = oneof->field(j)->name();
+ printer_->Print(
+ m,
+ "$descriptor_name$.oneofs_by_name['$oneof_name$'].fields.append(\n"
+ " $descriptor_name$.fields_by_name['$field_name$'])\n");
+ printer_->Print(
+ m,
+ "$descriptor_name$.fields_by_name['$field_name$'].containing_oneof = "
+ "$descriptor_name$.oneofs_by_name['$oneof_name$']\n");
+ }
+ }
+}
+
+void Generator::AddMessageToFileDescriptor(const Descriptor& descriptor) const {
+ std::map<std::string, std::string> m;
+ m["descriptor_name"] = kDescriptorKey;
+ m["message_name"] = descriptor.name();
+ m["message_descriptor_name"] = ModuleLevelDescriptorName(descriptor);
+ const char file_descriptor_template[] =
+ "$descriptor_name$.message_types_by_name['$message_name$'] = "
+ "$message_descriptor_name$\n";
+ printer_->Print(m, file_descriptor_template);
+}
+
+void Generator::AddServiceToFileDescriptor(
+ const ServiceDescriptor& descriptor) const {
+ std::map<std::string, std::string> m;
+ m["descriptor_name"] = kDescriptorKey;
+ m["service_name"] = descriptor.name();
+ m["service_descriptor_name"] = ModuleLevelServiceDescriptorName(descriptor);
+ const char file_descriptor_template[] =
+ "$descriptor_name$.services_by_name['$service_name$'] = "
+ "$service_descriptor_name$\n";
+ printer_->Print(m, file_descriptor_template);
+}
+
+void Generator::AddEnumToFileDescriptor(
+ const EnumDescriptor& descriptor) const {
+ std::map<std::string, std::string> m;
+ m["descriptor_name"] = kDescriptorKey;
+ m["enum_name"] = descriptor.name();
+ m["enum_descriptor_name"] = ModuleLevelDescriptorName(descriptor);
+ const char file_descriptor_template[] =
+ "$descriptor_name$.enum_types_by_name['$enum_name$'] = "
+ "$enum_descriptor_name$\n";
+ printer_->Print(m, file_descriptor_template);
+}
+
+void Generator::AddExtensionToFileDescriptor(
+ const FieldDescriptor& descriptor) const {
+ std::map<std::string, std::string> m;
+ m["descriptor_name"] = kDescriptorKey;
+ m["field_name"] = descriptor.name();
+ m["resolved_name"] = ResolveKeyword(descriptor.name());
+ const char file_descriptor_template[] =
+ "$descriptor_name$.extensions_by_name['$field_name$'] = "
+ "$resolved_name$\n";
+ printer_->Print(m, file_descriptor_template);
+}
+
+// Sets any necessary message_type and enum_type attributes
+// for the Python version of |field|.
+//
+// containing_type may be NULL, in which case this is a module-level field.
+//
+// python_dict_name is the name of the Python dict where we should
+// look the field up in the containing type. (e.g., fields_by_name
+// or extensions_by_name). We ignore python_dict_name if containing_type
+// is NULL.
+void Generator::FixForeignFieldsInField(
+ const Descriptor* containing_type, const FieldDescriptor& field,
+ const std::string& python_dict_name) const {
+ const std::string field_referencing_expression =
+ FieldReferencingExpression(containing_type, field, python_dict_name);
+ std::map<std::string, std::string> m;
+ m["field_ref"] = field_referencing_expression;
+ const Descriptor* foreign_message_type = field.message_type();
+ if (foreign_message_type) {
+ m["foreign_type"] = ModuleLevelDescriptorName(*foreign_message_type);
+ printer_->Print(m, "$field_ref$.message_type = $foreign_type$\n");
+ }
+ const EnumDescriptor* enum_type = field.enum_type();
+ if (enum_type) {
+ m["enum_type"] = ModuleLevelDescriptorName(*enum_type);
+ printer_->Print(m, "$field_ref$.enum_type = $enum_type$\n");
+ }
+}
+
+// Returns the module-level expression for the given FieldDescriptor.
+// Only works for fields in the .proto file this Generator is generating for.
+//
+// containing_type may be NULL, in which case this is a module-level field.
+//
+// python_dict_name is the name of the Python dict where we should
+// look the field up in the containing type. (e.g., fields_by_name
+// or extensions_by_name). We ignore python_dict_name if containing_type
+// is NULL.
+std::string Generator::FieldReferencingExpression(
+ const Descriptor* containing_type, const FieldDescriptor& field,
+ const std::string& python_dict_name) const {
+ // We should only ever be looking up fields in the current file.
+ // The only things we refer to from other files are message descriptors.
+ GOOGLE_CHECK_EQ(field.file(), file_)
+ << field.file()->name() << " vs. " << file_->name();
+ if (!containing_type) {
+ return ResolveKeyword(field.name());
+ }
+ return strings::Substitute("$0.$1['$2']",
+ ModuleLevelDescriptorName(*containing_type),
+ python_dict_name, field.name());
+}
+
+// Prints containing_type for nested descriptors or enum descriptors.
+template <typename DescriptorT>
+void Generator::FixContainingTypeInDescriptor(
+ const DescriptorT& descriptor,
+ const Descriptor* containing_descriptor) const {
+ if (containing_descriptor != nullptr) {
+ const std::string nested_name = ModuleLevelDescriptorName(descriptor);
+ const std::string parent_name =
+ ModuleLevelDescriptorName(*containing_descriptor);
+ printer_->Print("$nested_name$.containing_type = $parent_name$\n",
+ "nested_name", nested_name, "parent_name", parent_name);
+ }
+}
+
+// Prints statements setting the message_type and enum_type fields in the
+// Python descriptor objects we've already output in the file. We must
+// do this in a separate step due to circular references (otherwise, we'd
+// just set everything in the initial assignment statements).
+void Generator::FixForeignFieldsInDescriptors() const {
+ for (int i = 0; i < file_->message_type_count(); ++i) {
+ FixForeignFieldsInDescriptor(*file_->message_type(i), nullptr);
+ }
+ for (int i = 0; i < file_->message_type_count(); ++i) {
+ AddMessageToFileDescriptor(*file_->message_type(i));
+ }
+ for (int i = 0; i < file_->enum_type_count(); ++i) {
+ AddEnumToFileDescriptor(*file_->enum_type(i));
+ }
+ for (int i = 0; i < file_->extension_count(); ++i) {
+ AddExtensionToFileDescriptor(*file_->extension(i));
+ }
+
+ // TODO(jieluo): Move this register to PrintFileDescriptor() when
+ // FieldDescriptor.file is added in generated file.
+ printer_->Print("_sym_db.RegisterFileDescriptor($name$)\n", "name",
+ kDescriptorKey);
+ printer_->Print("\n");
+}
+
+// We need to not only set any necessary message_type fields, but
+// also need to call RegisterExtension() on each message we're
+// extending.
+void Generator::FixForeignFieldsInExtensions() const {
+ // Top-level extensions.
+ for (int i = 0; i < file_->extension_count(); ++i) {
+ FixForeignFieldsInExtension(*file_->extension(i));
+ }
+ // Nested extensions.
+ for (int i = 0; i < file_->message_type_count(); ++i) {
+ FixForeignFieldsInNestedExtensions(*file_->message_type(i));
+ }
+ printer_->Print("\n");
+}
+
+void Generator::FixForeignFieldsInExtension(
+ const FieldDescriptor& extension_field) const {
+ GOOGLE_CHECK(extension_field.is_extension());
+
+ std::map<std::string, std::string> m;
+ // Confusingly, for FieldDescriptors that happen to be extensions,
+ // containing_type() means "extended type."
+ // On the other hand, extension_scope() will give us what we normally
+ // mean by containing_type().
+ m["extended_message_class"] =
+ ModuleLevelMessageName(*extension_field.containing_type());
+ m["field"] = FieldReferencingExpression(
+ extension_field.extension_scope(), extension_field, "extensions_by_name");
+ printer_->Print(m, "$extended_message_class$.RegisterExtension($field$)\n");
+}
+
+void Generator::FixForeignFieldsInNestedExtensions(
+ const Descriptor& descriptor) const {
+ // Recursively fix up extensions in all nested types.
+ for (int i = 0; i < descriptor.nested_type_count(); ++i) {
+ FixForeignFieldsInNestedExtensions(*descriptor.nested_type(i));
+ }
+ // Fix up extensions directly contained within this type.
+ for (int i = 0; i < descriptor.extension_count(); ++i) {
+ FixForeignFieldsInExtension(*descriptor.extension(i));
+ }
+}
+
+// Returns a Python expression that instantiates a Python EnumValueDescriptor
+// object for the given C++ descriptor.
+void Generator::PrintEnumValueDescriptor(
+ const EnumValueDescriptor& descriptor) const {
+ // TODO(robinson): Fix up EnumValueDescriptor "type" fields.
+ // More circular references. ::sigh::
+ std::string options_string;
+ descriptor.options().SerializeToString(&options_string);
+ std::map<std::string, std::string> m;
+ m["name"] = descriptor.name();
+ m["index"] = StrCat(descriptor.index());
+ m["number"] = StrCat(descriptor.number());
+ m["options"] = OptionsValue(options_string);
+ printer_->Print(m,
+ "_descriptor.EnumValueDescriptor(\n"
+ " name='$name$', index=$index$, number=$number$,\n"
+ " serialized_options=$options$,\n"
+ " type=None,\n"
+ " create_key=_descriptor._internal_create_key)");
+}
+
+// Returns a CEscaped string of serialized_options.
+std::string Generator::OptionsValue(
+ const std::string& serialized_options) const {
+ if (serialized_options.length() == 0 || GeneratingDescriptorProto()) {
+ return "None";
+ } else {
+ return "b'" + CEscape(serialized_options) + "'";
+ }
+}
+
+// Prints an expression for a Python FieldDescriptor for |field|.
+void Generator::PrintFieldDescriptor(const FieldDescriptor& field,
+ bool is_extension) const {
+ std::string options_string;
+ field.options().SerializeToString(&options_string);
+ std::map<std::string, std::string> m;
+ m["name"] = field.name();
+ m["full_name"] = field.full_name();
+ m["index"] = StrCat(field.index());
+ m["number"] = StrCat(field.number());
+ m["type"] = StrCat(field.type());
+ m["cpp_type"] = StrCat(field.cpp_type());
+ m["label"] = StrCat(field.label());
+ m["has_default_value"] = field.has_default_value() ? "True" : "False";
+ m["default_value"] = StringifyDefaultValue(field);
+ m["is_extension"] = is_extension ? "True" : "False";
+ m["serialized_options"] = OptionsValue(options_string);
+ m["json_name"] =
+ field.has_json_name() ? ", json_name='" + field.json_name() + "'" : "";
+ // We always set message_type and enum_type to None at this point, and then
+ // these fields in correctly after all referenced descriptors have been
+ // defined and/or imported (see FixForeignFieldsInDescriptors()).
+ const char field_descriptor_decl[] =
+ "_descriptor.FieldDescriptor(\n"
+ " name='$name$', full_name='$full_name$', index=$index$,\n"
+ " number=$number$, type=$type$, cpp_type=$cpp_type$, label=$label$,\n"
+ " has_default_value=$has_default_value$, "
+ "default_value=$default_value$,\n"
+ " message_type=None, enum_type=None, containing_type=None,\n"
+ " is_extension=$is_extension$, extension_scope=None,\n"
+ " serialized_options=$serialized_options$$json_name$, file=DESCRIPTOR,"
+ " create_key=_descriptor._internal_create_key)";
+ printer_->Print(m, field_descriptor_decl);
+}
+
+// Helper for Print{Fields,Extensions}InDescriptor().
+void Generator::PrintFieldDescriptorsInDescriptor(
+ const Descriptor& message_descriptor, bool is_extension,
+ const std::string& list_variable_name, int (Descriptor::*CountFn)() const,
+ const FieldDescriptor* (Descriptor::*GetterFn)(int)const) const {
+ printer_->Print("$list$=[\n", "list", list_variable_name);
+ printer_->Indent();
+ for (int i = 0; i < (message_descriptor.*CountFn)(); ++i) {
+ PrintFieldDescriptor(*(message_descriptor.*GetterFn)(i), is_extension);
+ printer_->Print(",\n");
+ }
+ printer_->Outdent();
+ printer_->Print("],\n");
+}
+
+// Prints a statement assigning "fields" to a list of Python FieldDescriptors,
+// one for each field present in message_descriptor.
+void Generator::PrintFieldsInDescriptor(
+ const Descriptor& message_descriptor) const {
+ const bool is_extension = false;
+ PrintFieldDescriptorsInDescriptor(message_descriptor, is_extension, "fields",
+ &Descriptor::field_count,
+ &Descriptor::field);
+}
+
+// Prints a statement assigning "extensions" to a list of Python
+// FieldDescriptors, one for each extension present in message_descriptor.
+void Generator::PrintExtensionsInDescriptor(
+ const Descriptor& message_descriptor) const {
+ const bool is_extension = true;
+ PrintFieldDescriptorsInDescriptor(message_descriptor, is_extension,
+ "extensions", &Descriptor::extension_count,
+ &Descriptor::extension);
+}
+
+bool Generator::GeneratingDescriptorProto() const {
+ return file_->name() == "net/proto2/proto/descriptor.proto" ||
+ file_->name() == "google/protobuf/descriptor.proto";
+}
+
+// Returns the unique Python module-level identifier given to a descriptor.
+// This name is module-qualified iff the given descriptor describes an
+// entity that doesn't come from the current file.
+template <typename DescriptorT>
+std::string Generator::ModuleLevelDescriptorName(
+ const DescriptorT& descriptor) const {
+ // FIXME(robinson):
+ // We currently don't worry about collisions with underscores in the type
+ // names, so these would collide in nasty ways if found in the same file:
+ // OuterProto.ProtoA.ProtoB
+ // OuterProto_ProtoA.ProtoB # Underscore instead of period.
+ // As would these:
+ // OuterProto.ProtoA_.ProtoB
+ // OuterProto.ProtoA._ProtoB # Leading vs. trailing underscore.
+ // (Contrived, but certainly possible).
+ //
+ // The C++ implementation doesn't guard against this either. Leaving
+ // it for now...
+ std::string name = NamePrefixedWithNestedTypes(descriptor, "_");
+ ToUpper(&name);
+ // Module-private for now. Easy to make public later; almost impossible
+ // to make private later.
+ name = "_" + name;
+ // We now have the name relative to its own module. Also qualify with
+ // the module name iff this descriptor is from a different .proto file.
+ if (descriptor.file() != file_) {
+ name = ModuleAlias(descriptor.file()->name()) + "." + name;
+ }
+ return name;
+}
+
+// Returns the name of the message class itself, not the descriptor.
+// Like ModuleLevelDescriptorName(), module-qualifies the name iff
+// the given descriptor describes an entity that doesn't come from
+// the current file.
+std::string Generator::ModuleLevelMessageName(
+ const Descriptor& descriptor) const {
+ std::string name = NamePrefixedWithNestedTypes(descriptor, ".");
+ if (descriptor.file() != file_) {
+ name = ModuleAlias(descriptor.file()->name()) + "." + name;
+ }
+ return name;
+}
+
+// Returns the unique Python module-level identifier given to a service
+// descriptor.
+std::string Generator::ModuleLevelServiceDescriptorName(
+ const ServiceDescriptor& descriptor) const {
+ std::string name = descriptor.name();
+ ToUpper(&name);
+ name = "_" + name;
+ if (descriptor.file() != file_) {
+ name = ModuleAlias(descriptor.file()->name()) + "." + name;
+ }
+ return name;
+}
+
+// Prints standard constructor arguments serialized_start and serialized_end.
+// Args:
+// descriptor: The cpp descriptor to have a serialized reference.
+// proto: A proto
+// Example printer output:
+// serialized_start=41,
+// serialized_end=43,
+//
+template <typename DescriptorT, typename DescriptorProtoT>
+void Generator::PrintSerializedPbInterval(const DescriptorT& descriptor,
+ DescriptorProtoT& proto,
+ const std::string& name) const {
+ descriptor.CopyTo(&proto);
+ std::string sp;
+ proto.SerializeToString(&sp);
+ int offset = file_descriptor_serialized_.find(sp);
+ GOOGLE_CHECK_GE(offset, 0);
+
+ printer_->Print(
+ "$name$._serialized_start=$serialized_start$\n"
+ "$name$._serialized_end=$serialized_end$\n",
+ "name", name, "serialized_start", StrCat(offset), "serialized_end",
+ StrCat(offset + sp.size()));
+}
+
+namespace {
+void PrintDescriptorOptionsFixingCode(const std::string& descriptor,
+ const std::string& options,
+ io::Printer* printer) {
+ // Reset the _options to None thus DescriptorBase.GetOptions() can
+ // parse _options again after extensions are registered.
+ printer->Print(
+ "$descriptor$._options = None\n"
+ "$descriptor$._serialized_options = $serialized_value$\n",
+ "descriptor", descriptor, "serialized_value", options);
+}
+} // namespace
+
+void Generator::SetSerializedPbInterval() const {
+ // Top level enums.
+ for (int i = 0; i < file_->enum_type_count(); ++i) {
+ EnumDescriptorProto proto;
+ const EnumDescriptor& descriptor = *file_->enum_type(i);
+ PrintSerializedPbInterval(descriptor, proto,
+ ModuleLevelDescriptorName(descriptor));
+ }
+
+ // Messages.
+ for (int i = 0; i < file_->message_type_count(); ++i) {
+ SetMessagePbInterval(*file_->message_type(i));
+ }
+
+ // Services.
+ for (int i = 0; i < file_->service_count(); ++i) {
+ ServiceDescriptorProto proto;
+ const ServiceDescriptor& service = *file_->service(i);
+ PrintSerializedPbInterval(service, proto,
+ ModuleLevelServiceDescriptorName(service));
+ }
+}
+
+void Generator::SetMessagePbInterval(const Descriptor& descriptor) const {
+ DescriptorProto message_proto;
+ PrintSerializedPbInterval(descriptor, message_proto,
+ ModuleLevelDescriptorName(descriptor));
+
+ // Nested messages.
+ for (int i = 0; i < descriptor.nested_type_count(); ++i) {
+ SetMessagePbInterval(*descriptor.nested_type(i));
+ }
+
+ for (int i = 0; i < descriptor.enum_type_count(); ++i) {
+ EnumDescriptorProto proto;
+ const EnumDescriptor& enum_des = *descriptor.enum_type(i);
+ PrintSerializedPbInterval(enum_des, proto,
+ ModuleLevelDescriptorName(enum_des));
+ }
+}
+
+// Prints expressions that set the options field of all descriptors.
+void Generator::FixAllDescriptorOptions() const {
+ // Prints an expression that sets the file descriptor's options.
+ std::string file_options = OptionsValue(file_->options().SerializeAsString());
+ if (file_options != "None") {
+ PrintDescriptorOptionsFixingCode(kDescriptorKey, file_options, printer_);
+ } else {
+ printer_->Print("DESCRIPTOR._options = None\n");
+ }
+ // Prints expressions that set the options for all top level enums.
+ for (int i = 0; i < file_->enum_type_count(); ++i) {
+ const EnumDescriptor& enum_descriptor = *file_->enum_type(i);
+ FixOptionsForEnum(enum_descriptor);
+ }
+ // Prints expressions that set the options for all top level extensions.
+ for (int i = 0; i < file_->extension_count(); ++i) {
+ const FieldDescriptor& field = *file_->extension(i);
+ FixOptionsForField(field);
+ }
+ // Prints expressions that set the options for all messages, nested enums,
+ // nested extensions and message fields.
+ for (int i = 0; i < file_->message_type_count(); ++i) {
+ FixOptionsForMessage(*file_->message_type(i));
+ }
+
+ for (int i = 0; i < file_->service_count(); ++i) {
+ FixOptionsForService(*file_->service(i));
+ }
+}
+
+void Generator::FixOptionsForOneof(const OneofDescriptor& oneof) const {
+ std::string oneof_options = OptionsValue(oneof.options().SerializeAsString());
+ if (oneof_options != "None") {
+ std::string oneof_name = strings::Substitute(
+ "$0.$1['$2']", ModuleLevelDescriptorName(*oneof.containing_type()),
+ "oneofs_by_name", oneof.name());
+ PrintDescriptorOptionsFixingCode(oneof_name, oneof_options, printer_);
+ }
+}
+
+// Prints expressions that set the options for an enum descriptor and its
+// value descriptors.
+void Generator::FixOptionsForEnum(const EnumDescriptor& enum_descriptor) const {
+ std::string descriptor_name = ModuleLevelDescriptorName(enum_descriptor);
+ std::string enum_options =
+ OptionsValue(enum_descriptor.options().SerializeAsString());
+ if (enum_options != "None") {
+ PrintDescriptorOptionsFixingCode(descriptor_name, enum_options, printer_);
+ }
+ for (int i = 0; i < enum_descriptor.value_count(); ++i) {
+ const EnumValueDescriptor& value_descriptor = *enum_descriptor.value(i);
+ std::string value_options =
+ OptionsValue(value_descriptor.options().SerializeAsString());
+ if (value_options != "None") {
+ PrintDescriptorOptionsFixingCode(
+ StringPrintf("%s.values_by_name[\"%s\"]", descriptor_name.c_str(),
+ value_descriptor.name().c_str()),
+ value_options, printer_);
+ }
+ }
+}
+
+// Prints expressions that set the options for an service descriptor and its
+// value descriptors.
+void Generator::FixOptionsForService(
+ const ServiceDescriptor& service_descriptor) const {
+ std::string descriptor_name =
+ ModuleLevelServiceDescriptorName(service_descriptor);
+ std::string service_options =
+ OptionsValue(service_descriptor.options().SerializeAsString());
+ if (service_options != "None") {
+ PrintDescriptorOptionsFixingCode(descriptor_name, service_options,
+ printer_);
+ }
+
+ for (int i = 0; i < service_descriptor.method_count(); ++i) {
+ const MethodDescriptor* method = service_descriptor.method(i);
+ std::string method_options =
+ OptionsValue(method->options().SerializeAsString());
+ if (method_options != "None") {
+ std::string method_name =
+ descriptor_name + ".methods_by_name['" + method->name() + "']";
+ PrintDescriptorOptionsFixingCode(method_name, method_options, printer_);
+ }
+ }
+}
+
+// Prints expressions that set the options for field descriptors (including
+// extensions).
+void Generator::FixOptionsForField(const FieldDescriptor& field) const {
+ std::string field_options = OptionsValue(field.options().SerializeAsString());
+ if (field_options != "None") {
+ std::string field_name;
+ if (field.is_extension()) {
+ if (field.extension_scope() == nullptr) {
+ // Top level extensions.
+ field_name = field.name();
+ } else {
+ field_name = FieldReferencingExpression(field.extension_scope(), field,
+ "extensions_by_name");
+ }
+ } else {
+ field_name = FieldReferencingExpression(field.containing_type(), field,
+ "fields_by_name");
+ }
+ PrintDescriptorOptionsFixingCode(field_name, field_options, printer_);
+ }
+}
+
+// Prints expressions that set the options for a message and all its inner
+// types (nested messages, nested enums, extensions, fields).
+void Generator::FixOptionsForMessage(const Descriptor& descriptor) const {
+ // Nested messages.
+ for (int i = 0; i < descriptor.nested_type_count(); ++i) {
+ FixOptionsForMessage(*descriptor.nested_type(i));
+ }
+ // Oneofs.
+ for (int i = 0; i < descriptor.oneof_decl_count(); ++i) {
+ FixOptionsForOneof(*descriptor.oneof_decl(i));
+ }
+ // Enums.
+ for (int i = 0; i < descriptor.enum_type_count(); ++i) {
+ FixOptionsForEnum(*descriptor.enum_type(i));
+ }
+ // Fields.
+ for (int i = 0; i < descriptor.field_count(); ++i) {
+ const FieldDescriptor& field = *descriptor.field(i);
+ FixOptionsForField(field);
+ }
+ // Extensions.
+ for (int i = 0; i < descriptor.extension_count(); ++i) {
+ const FieldDescriptor& field = *descriptor.extension(i);
+ FixOptionsForField(field);
+ }
+ // Message option for this message.
+ std::string message_options =
+ OptionsValue(descriptor.options().SerializeAsString());
+ if (message_options != "None") {
+ std::string descriptor_name = ModuleLevelDescriptorName(descriptor);
+ PrintDescriptorOptionsFixingCode(descriptor_name, message_options,
+ printer_);
+ }
+}
+
+// If a dependency forwards other files through public dependencies, let's
+// copy over the corresponding module aliases.
+void Generator::CopyPublicDependenciesAliases(
+ const std::string& copy_from, const FileDescriptor* file) const {
+ for (int i = 0; i < file->public_dependency_count(); ++i) {
+ std::string module_name = ModuleName(file->public_dependency(i)->name());
+ std::string module_alias = ModuleAlias(file->public_dependency(i)->name());
+ // There's no module alias in the dependent file if it was generated by
+ // an old protoc (less than 3.0.0-alpha-1). Use module name in this
+ // situation.
+ printer_->Print(
+ "try:\n"
+ " $alias$ = $copy_from$.$alias$\n"
+ "except AttributeError:\n"
+ " $alias$ = $copy_from$.$module$\n",
+ "alias", module_alias, "module", module_name, "copy_from", copy_from);
+ CopyPublicDependenciesAliases(copy_from, file->public_dependency(i));
+ }
+}
+
+} // namespace python
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/python/python_generator.h b/NorthstarDedicatedTest/include/protobuf/compiler/python/python_generator.h
new file mode 100644
index 00000000..6bcfdda9
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/python/python_generator.h
@@ -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.
+
+// Author: robinson@google.com (Will Robinson)
+//
+// Generates Python code for a given .proto file.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_PYTHON_GENERATOR_H__
+#define GOOGLE_PROTOBUF_COMPILER_PYTHON_GENERATOR_H__
+
+#include <string>
+
+#include <compiler/code_generator.h>
+#include <stubs/mutex.h>
+
+#include <port_def.inc>
+
+namespace google {
+namespace protobuf {
+
+class Descriptor;
+class EnumDescriptor;
+class EnumValueDescriptor;
+class FieldDescriptor;
+class OneofDescriptor;
+class ServiceDescriptor;
+
+namespace io {
+class Printer;
+}
+
+namespace compiler {
+namespace python {
+
+enum class StripPrintDescriptor { kCreate, kFind };
+
+// CodeGenerator implementation for generated Python protocol buffer classes.
+// If you create your own protocol compiler binary and you want it to support
+// Python output, you can do so by registering an instance of this
+// CodeGenerator with the CommandLineInterface in your main() function.
+class PROTOC_EXPORT Generator : public CodeGenerator {
+ public:
+ Generator();
+ virtual ~Generator();
+
+ // CodeGenerator methods.
+ bool Generate(const FileDescriptor* file, const std::string& parameter,
+ GeneratorContext* generator_context,
+ std::string* error) const override;
+
+ uint64_t GetSupportedFeatures() const override;
+
+ private:
+ void PrintImports() const;
+ void PrintFileDescriptor() const;
+ void PrintTopLevelEnums() const;
+ void PrintAllNestedEnumsInFile(StripPrintDescriptor print_mode) const;
+ void PrintNestedEnums(const Descriptor& descriptor,
+ StripPrintDescriptor print_mode) const;
+ void PrintCreateEnum(const EnumDescriptor& enum_descriptor) const;
+ void PrintFindEnum(const EnumDescriptor& enum_descriptor) const;
+
+ void PrintTopLevelExtensions() const;
+
+ void PrintFieldDescriptor(const FieldDescriptor& field,
+ bool is_extension) const;
+ void PrintFieldDescriptorsInDescriptor(
+ const Descriptor& message_descriptor, bool is_extension,
+ const std::string& list_variable_name, int (Descriptor::*CountFn)() const,
+ const FieldDescriptor* (Descriptor::*GetterFn)(int)const) const;
+ void PrintFieldsInDescriptor(const Descriptor& message_descriptor) const;
+ void PrintExtensionsInDescriptor(const Descriptor& message_descriptor) const;
+ void PrintMessageDescriptors(StripPrintDescriptor print_mode) const;
+ void PrintCreateDescriptor(const Descriptor& message_descriptor) const;
+ void PrintFindDescriptor(const Descriptor& message_descriptor) const;
+ void PrintNestedDescriptors(const Descriptor& containing_descriptor,
+ StripPrintDescriptor print_mode) const;
+
+ void PrintMessages() const;
+ void PrintMessage(const Descriptor& message_descriptor,
+ const std::string& prefix,
+ std::vector<std::string>* to_register,
+ bool is_nested) const;
+ void PrintNestedMessages(const Descriptor& containing_descriptor,
+ const std::string& prefix,
+ std::vector<std::string>* to_register) const;
+
+ void FixForeignFieldsInDescriptors() const;
+ void FixForeignFieldsInDescriptor(
+ const Descriptor& descriptor,
+ const Descriptor* containing_descriptor) const;
+ void FixForeignFieldsInField(const Descriptor* containing_type,
+ const FieldDescriptor& field,
+ const std::string& python_dict_name) const;
+ void AddMessageToFileDescriptor(const Descriptor& descriptor) const;
+ void AddEnumToFileDescriptor(const EnumDescriptor& descriptor) const;
+ void AddExtensionToFileDescriptor(const FieldDescriptor& descriptor) const;
+ void AddServiceToFileDescriptor(const ServiceDescriptor& descriptor) const;
+ std::string FieldReferencingExpression(
+ const Descriptor* containing_type, const FieldDescriptor& field,
+ const std::string& python_dict_name) const;
+ template <typename DescriptorT>
+ void FixContainingTypeInDescriptor(
+ const DescriptorT& descriptor,
+ const Descriptor* containing_descriptor) const;
+
+ void FixForeignFieldsInExtensions() const;
+ void FixForeignFieldsInExtension(
+ const FieldDescriptor& extension_field) const;
+ void FixForeignFieldsInNestedExtensions(const Descriptor& descriptor) const;
+
+ void PrintServices() const;
+ void PrintServiceDescriptors() const;
+ void PrintServiceDescriptor(const ServiceDescriptor& descriptor) const;
+ void PrintServiceClass(const ServiceDescriptor& descriptor) const;
+ void PrintServiceStub(const ServiceDescriptor& descriptor) const;
+ void PrintDescriptorKeyAndModuleName(
+ const ServiceDescriptor& descriptor) const;
+
+ void PrintEnumValueDescriptor(const EnumValueDescriptor& descriptor) const;
+ std::string OptionsValue(const std::string& serialized_options) const;
+ bool GeneratingDescriptorProto() const;
+
+ template <typename DescriptorT>
+ std::string ModuleLevelDescriptorName(const DescriptorT& descriptor) const;
+ std::string ModuleLevelMessageName(const Descriptor& descriptor) const;
+ std::string ModuleLevelServiceDescriptorName(
+ const ServiceDescriptor& descriptor) const;
+
+ template <typename DescriptorT, typename DescriptorProtoT>
+ void PrintSerializedPbInterval(const DescriptorT& descriptor,
+ DescriptorProtoT& proto,
+ const std::string& name) const;
+
+ void FixAllDescriptorOptions() const;
+ void FixOptionsForField(const FieldDescriptor& field) const;
+ void FixOptionsForOneof(const OneofDescriptor& oneof) const;
+ void FixOptionsForEnum(const EnumDescriptor& descriptor) const;
+ void FixOptionsForService(const ServiceDescriptor& descriptor) const;
+ void FixOptionsForMessage(const Descriptor& descriptor) const;
+
+ void SetSerializedPbInterval() const;
+ void SetMessagePbInterval(const Descriptor& descriptor) const;
+
+ void CopyPublicDependenciesAliases(const std::string& copy_from,
+ const FileDescriptor* file) const;
+
+ // Very coarse-grained lock to ensure that Generate() is reentrant.
+ // Guards file_, printer_ and file_descriptor_serialized_.
+ mutable Mutex mutex_;
+ mutable const FileDescriptor* file_; // Set in Generate(). Under mutex_.
+ mutable std::string file_descriptor_serialized_;
+ mutable io::Printer* printer_; // Set in Generate(). Under mutex_.
+ mutable bool pure_python_workable_;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Generator);
+};
+
+} // namespace python
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#include <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_COMPILER_PYTHON_GENERATOR_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/python/python_plugin_unittest.cc b/NorthstarDedicatedTest/include/protobuf/compiler/python/python_plugin_unittest.cc
new file mode 100644
index 00000000..78b02e92
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/python/python_plugin_unittest.cc
@@ -0,0 +1,161 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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)
+//
+// TODO(kenton): Share code with the versions of this test in other languages?
+// It seemed like parameterizing it would add more complexity than it is
+// worth.
+
+#include <memory>
+
+#include <testing/file.h>
+#include <testing/file.h>
+#include <compiler/command_line_interface.h>
+#include <compiler/python/python_generator.h>
+#include <io/printer.h>
+#include <io/zero_copy_stream.h>
+#include <stubs/strutil.h>
+#include <testing/googletest.h>
+#include <gtest/gtest.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace python {
+namespace {
+
+class TestGenerator : public CodeGenerator {
+ public:
+ TestGenerator() {}
+ ~TestGenerator() {}
+
+ virtual bool Generate(const FileDescriptor* file,
+ const std::string& parameter, GeneratorContext* context,
+ std::string* error) const {
+ TryInsert("test_pb2.py", "imports", context);
+ TryInsert("test_pb2.py", "module_scope", context);
+ TryInsert("test_pb2.py", "class_scope:foo.Bar", context);
+ TryInsert("test_pb2.py", "class_scope:foo.Bar.Baz", context);
+ return true;
+ }
+
+ void TryInsert(const std::string& filename,
+ const std::string& insertion_point,
+ GeneratorContext* context) const {
+ std::unique_ptr<io::ZeroCopyOutputStream> output(
+ context->OpenForInsert(filename, insertion_point));
+ io::Printer printer(output.get(), '$');
+ printer.Print("// inserted $name$\n", "name", insertion_point);
+ }
+};
+
+// This test verifies that all the expected insertion points exist. It does
+// not verify that they are correctly-placed; that would require actually
+// compiling the output which is a bit more than I care to do for this test.
+TEST(PythonPluginTest, PluginTest) {
+ GOOGLE_CHECK_OK(File::SetContents(TestTempDir() + "/test.proto",
+ "syntax = \"proto2\";\n"
+ "package foo;\n"
+ "message Bar {\n"
+ " message Baz {}\n"
+ "}\n",
+ true));
+
+ compiler::CommandLineInterface cli;
+ cli.SetInputsAreProtoPathRelative(true);
+
+ python::Generator python_generator;
+ TestGenerator test_generator;
+ cli.RegisterGenerator("--python_out", &python_generator, "");
+ cli.RegisterGenerator("--test_out", &test_generator, "");
+
+ std::string proto_path = "-I" + TestTempDir();
+ std::string python_out = "--python_out=" + TestTempDir();
+ std::string test_out = "--test_out=" + TestTempDir();
+
+ const char* argv[] = {"protoc", proto_path.c_str(), python_out.c_str(),
+ test_out.c_str(), "test.proto"};
+
+ EXPECT_EQ(0, cli.Run(5, argv));
+}
+
+// This test verifies that the generated Python output uses regular imports (as
+// opposed to importlib) in the usual case where the .proto file paths do not
+// not contain any Python keywords.
+TEST(PythonPluginTest, ImportTest) {
+ // Create files test1.proto and test2.proto with the former importing the
+ // latter.
+ GOOGLE_CHECK_OK(File::SetContents(TestTempDir() + "/test1.proto",
+ "syntax = \"proto3\";\n"
+ "package foo;\n"
+ "import \"test2.proto\";"
+ "message Message1 {\n"
+ " Message2 message_2 = 1;\n"
+ "}\n",
+ true));
+ GOOGLE_CHECK_OK(File::SetContents(TestTempDir() + "/test2.proto",
+ "syntax = \"proto3\";\n"
+ "package foo;\n"
+ "message Message2 {}\n",
+ true));
+
+ compiler::CommandLineInterface cli;
+ cli.SetInputsAreProtoPathRelative(true);
+ python::Generator python_generator;
+ cli.RegisterGenerator("--python_out", &python_generator, "");
+ std::string proto_path = "-I" + TestTempDir();
+ std::string python_out = "--python_out=" + TestTempDir();
+ const char* argv[] = {"protoc", proto_path.c_str(), "-I.", python_out.c_str(),
+ "test1.proto"};
+ ASSERT_EQ(0, cli.Run(5, argv));
+
+ // Loop over the lines of the generated code and verify that we find an
+ // ordinary Python import but do not find the string "importlib".
+ std::string output;
+ GOOGLE_CHECK_OK(File::GetContents(TestTempDir() + "/test1_pb2.py", &output,
+ true));
+ std::vector<std::string> lines = Split(output, "\n");
+ std::string expected_import = "import test2_pb2";
+ bool found_expected_import = false;
+ for (int i = 0; i < lines.size(); ++i) {
+ if (lines[i].find(expected_import) != std::string::npos) {
+ found_expected_import = true;
+ }
+ EXPECT_EQ(std::string::npos, lines[i].find("importlib"));
+ }
+ EXPECT_TRUE(found_expected_import);
+}
+
+} // namespace
+} // namespace python
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generated_code.proto b/NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generated_code.proto
new file mode 100644
index 00000000..70ec9f17
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generated_code.proto
@@ -0,0 +1,70 @@
+syntax = "proto3";
+
+package A.B.C;
+
+import "ruby_generated_code_proto2_import.proto";
+
+message TestMessage {
+ int32 optional_int32 = 1;
+ int64 optional_int64 = 2;
+ uint32 optional_uint32 = 3;
+ uint64 optional_uint64 = 4;
+ bool optional_bool = 5;
+ double optional_double = 6;
+ float optional_float = 7;
+ string optional_string = 8;
+ bytes optional_bytes = 9;
+ TestEnum optional_enum = 10;
+ TestMessage optional_msg = 11;
+ TestImportedMessage optional_proto2_submessage = 12;
+
+ repeated int32 repeated_int32 = 21;
+ repeated int64 repeated_int64 = 22;
+ repeated uint32 repeated_uint32 = 23;
+ repeated uint64 repeated_uint64 = 24;
+ repeated bool repeated_bool = 25;
+ repeated double repeated_double = 26;
+ repeated float repeated_float = 27;
+ repeated string repeated_string = 28;
+ repeated bytes repeated_bytes = 29;
+ repeated TestEnum repeated_enum = 30;
+ repeated TestMessage repeated_msg = 31;
+
+ oneof my_oneof {
+ int32 oneof_int32 = 41;
+ int64 oneof_int64 = 42;
+ uint32 oneof_uint32 = 43;
+ uint64 oneof_uint64 = 44;
+ bool oneof_bool = 45;
+ double oneof_double = 46;
+ float oneof_float = 47;
+ string oneof_string = 48;
+ bytes oneof_bytes = 49;
+ TestEnum oneof_enum = 50;
+ TestMessage oneof_msg = 51;
+ }
+
+ map<int32, string> map_int32_string = 61;
+ map<int64, string> map_int64_string = 62;
+ map<uint32, string> map_uint32_string = 63;
+ map<uint64, string> map_uint64_string = 64;
+ map<bool, string> map_bool_string = 65;
+ map<string, string> map_string_string = 66;
+ map<string, TestMessage> map_string_msg = 67;
+ map<string, TestEnum> map_string_enum = 68;
+ map<string, int32> map_string_int32 = 69;
+ map<string, bool> map_string_bool = 70;
+
+ message NestedMessage {
+ int32 foo = 1;
+ }
+
+ NestedMessage nested_message = 80;
+}
+
+enum TestEnum {
+ Default = 0;
+ A = 1;
+ B = 2;
+ C = 3;
+}
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generated_code_pb.rb b/NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generated_code_pb.rb
new file mode 100644
index 00000000..256ac7c1
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generated_code_pb.rb
@@ -0,0 +1,79 @@
+# Generated by the protocol buffer compiler. DO NOT EDIT!
+# source: ruby_generated_code.proto
+
+require 'google/protobuf'
+
+require 'ruby_generated_code_proto2_import_pb'
+
+Google::Protobuf::DescriptorPool.generated_pool.build do
+ add_file("ruby_generated_code.proto", :syntax => :proto3) do
+ add_message "A.B.C.TestMessage" do
+ optional :optional_int32, :int32, 1
+ optional :optional_int64, :int64, 2
+ optional :optional_uint32, :uint32, 3
+ optional :optional_uint64, :uint64, 4
+ optional :optional_bool, :bool, 5
+ optional :optional_double, :double, 6
+ optional :optional_float, :float, 7
+ optional :optional_string, :string, 8
+ optional :optional_bytes, :bytes, 9
+ optional :optional_enum, :enum, 10, "A.B.C.TestEnum"
+ optional :optional_msg, :message, 11, "A.B.C.TestMessage"
+ optional :optional_proto2_submessage, :message, 12, "A.B.C.TestImportedMessage"
+ repeated :repeated_int32, :int32, 21
+ repeated :repeated_int64, :int64, 22
+ repeated :repeated_uint32, :uint32, 23
+ repeated :repeated_uint64, :uint64, 24
+ repeated :repeated_bool, :bool, 25
+ repeated :repeated_double, :double, 26
+ repeated :repeated_float, :float, 27
+ repeated :repeated_string, :string, 28
+ repeated :repeated_bytes, :bytes, 29
+ repeated :repeated_enum, :enum, 30, "A.B.C.TestEnum"
+ repeated :repeated_msg, :message, 31, "A.B.C.TestMessage"
+ map :map_int32_string, :int32, :string, 61
+ map :map_int64_string, :int64, :string, 62
+ map :map_uint32_string, :uint32, :string, 63
+ map :map_uint64_string, :uint64, :string, 64
+ map :map_bool_string, :bool, :string, 65
+ map :map_string_string, :string, :string, 66
+ map :map_string_msg, :string, :message, 67, "A.B.C.TestMessage"
+ map :map_string_enum, :string, :enum, 68, "A.B.C.TestEnum"
+ map :map_string_int32, :string, :int32, 69
+ map :map_string_bool, :string, :bool, 70
+ optional :nested_message, :message, 80, "A.B.C.TestMessage.NestedMessage"
+ oneof :my_oneof do
+ optional :oneof_int32, :int32, 41
+ optional :oneof_int64, :int64, 42
+ optional :oneof_uint32, :uint32, 43
+ optional :oneof_uint64, :uint64, 44
+ optional :oneof_bool, :bool, 45
+ optional :oneof_double, :double, 46
+ optional :oneof_float, :float, 47
+ optional :oneof_string, :string, 48
+ optional :oneof_bytes, :bytes, 49
+ optional :oneof_enum, :enum, 50, "A.B.C.TestEnum"
+ optional :oneof_msg, :message, 51, "A.B.C.TestMessage"
+ end
+ end
+ add_message "A.B.C.TestMessage.NestedMessage" do
+ optional :foo, :int32, 1
+ end
+ add_enum "A.B.C.TestEnum" do
+ value :Default, 0
+ value :A, 1
+ value :B, 2
+ value :C, 3
+ end
+ end
+end
+
+module A
+ module B
+ module C
+ TestMessage = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("A.B.C.TestMessage").msgclass
+ TestMessage::NestedMessage = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("A.B.C.TestMessage.NestedMessage").msgclass
+ TestEnum = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("A.B.C.TestEnum").enummodule
+ end
+ end
+end
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generated_code_proto2.proto b/NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generated_code_proto2.proto
new file mode 100644
index 00000000..ea7f7836
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generated_code_proto2.proto
@@ -0,0 +1,71 @@
+syntax = "proto2";
+
+package A.B.C;
+
+import "ruby_generated_code_proto2_import.proto";
+
+message TestMessage {
+ optional int32 optional_int32 = 1 [default = 1];
+ optional int64 optional_int64 = 2 [default = 2];
+ optional uint32 optional_uint32 = 3 [default = 3];
+ optional uint64 optional_uint64 = 4 [default = 4];
+ optional bool optional_bool = 5 [default = true];
+ optional double optional_double = 6 [default = 6.0];
+ optional float optional_float = 7 [default = 7.0];
+ optional string optional_string = 8 [default = "default str"];
+ optional bytes optional_bytes = 9 [default = "\0\1\2\100fubar"];
+ optional TestEnum optional_enum = 10 [default = A];
+ optional TestMessage optional_msg = 11;
+ optional TestImportedMessage optional_proto2_submessage = 12;
+
+ repeated int32 repeated_int32 = 21;
+ repeated int64 repeated_int64 = 22;
+ repeated uint32 repeated_uint32 = 23;
+ repeated uint64 repeated_uint64 = 24;
+ repeated bool repeated_bool = 25;
+ repeated double repeated_double = 26;
+ repeated float repeated_float = 27;
+ repeated string repeated_string = 28;
+ repeated bytes repeated_bytes = 29;
+ repeated TestEnum repeated_enum = 30;
+ repeated TestMessage repeated_msg = 31;
+
+ required int32 required_int32 = 41;
+ required int64 required_int64 = 42;
+ required uint32 required_uint32 = 43;
+ required uint64 required_uint64 = 44;
+ required bool required_bool = 45;
+ required double required_double = 46;
+ required float required_float = 47;
+ required string required_string = 48;
+ required bytes required_bytes = 49;
+ required TestEnum required_enum = 50;
+ required TestMessage required_msg = 51;
+
+ oneof my_oneof {
+ int32 oneof_int32 = 61;
+ int64 oneof_int64 = 62;
+ uint32 oneof_uint32 = 63;
+ uint64 oneof_uint64 = 64;
+ bool oneof_bool = 65;
+ double oneof_double = 66;
+ float oneof_float = 67;
+ string oneof_string = 68;
+ bytes oneof_bytes = 69;
+ TestEnum oneof_enum = 70;
+ TestMessage oneof_msg = 71;
+ }
+
+ message NestedMessage {
+ optional int32 foo = 1;
+ }
+
+ optional NestedMessage nested_message = 80;
+}
+
+enum TestEnum {
+ Default = 0;
+ A = 1;
+ B = 2;
+ C = 3;
+}
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generated_code_proto2_import.proto b/NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generated_code_proto2_import.proto
new file mode 100644
index 00000000..9ec07381
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generated_code_proto2_import.proto
@@ -0,0 +1,5 @@
+syntax = "proto2";
+
+package A.B.C;
+
+message TestImportedMessage {}
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generated_code_proto2_pb.rb b/NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generated_code_proto2_pb.rb
new file mode 100644
index 00000000..44d31969
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generated_code_proto2_pb.rb
@@ -0,0 +1,80 @@
+# Generated by the protocol buffer compiler. DO NOT EDIT!
+# source: ruby_generated_code_proto2.proto
+
+require 'google/protobuf'
+
+require 'ruby_generated_code_proto2_import_pb'
+
+Google::Protobuf::DescriptorPool.generated_pool.build do
+ add_file("ruby_generated_code_proto2.proto", :syntax => :proto2) do
+ add_message "A.B.C.TestMessage" do
+ optional :optional_int32, :int32, 1, default: 1
+ optional :optional_int64, :int64, 2, default: 2
+ optional :optional_uint32, :uint32, 3, default: 3
+ optional :optional_uint64, :uint64, 4, default: 4
+ optional :optional_bool, :bool, 5, default: true
+ optional :optional_double, :double, 6, default: 6
+ optional :optional_float, :float, 7, default: 7
+ optional :optional_string, :string, 8, default: "default str"
+ optional :optional_bytes, :bytes, 9, default: "\x00\x01\x02\x40\x66\x75\x62\x61\x72".force_encoding("ASCII-8BIT")
+ optional :optional_enum, :enum, 10, "A.B.C.TestEnum", default: 1
+ optional :optional_msg, :message, 11, "A.B.C.TestMessage"
+ optional :optional_proto2_submessage, :message, 12, "A.B.C.TestImportedMessage"
+ repeated :repeated_int32, :int32, 21
+ repeated :repeated_int64, :int64, 22
+ repeated :repeated_uint32, :uint32, 23
+ repeated :repeated_uint64, :uint64, 24
+ repeated :repeated_bool, :bool, 25
+ repeated :repeated_double, :double, 26
+ repeated :repeated_float, :float, 27
+ repeated :repeated_string, :string, 28
+ repeated :repeated_bytes, :bytes, 29
+ repeated :repeated_enum, :enum, 30, "A.B.C.TestEnum"
+ repeated :repeated_msg, :message, 31, "A.B.C.TestMessage"
+ required :required_int32, :int32, 41
+ required :required_int64, :int64, 42
+ required :required_uint32, :uint32, 43
+ required :required_uint64, :uint64, 44
+ required :required_bool, :bool, 45
+ required :required_double, :double, 46
+ required :required_float, :float, 47
+ required :required_string, :string, 48
+ required :required_bytes, :bytes, 49
+ required :required_enum, :enum, 50, "A.B.C.TestEnum"
+ required :required_msg, :message, 51, "A.B.C.TestMessage"
+ optional :nested_message, :message, 80, "A.B.C.TestMessage.NestedMessage"
+ oneof :my_oneof do
+ optional :oneof_int32, :int32, 61
+ optional :oneof_int64, :int64, 62
+ optional :oneof_uint32, :uint32, 63
+ optional :oneof_uint64, :uint64, 64
+ optional :oneof_bool, :bool, 65
+ optional :oneof_double, :double, 66
+ optional :oneof_float, :float, 67
+ optional :oneof_string, :string, 68
+ optional :oneof_bytes, :bytes, 69
+ optional :oneof_enum, :enum, 70, "A.B.C.TestEnum"
+ optional :oneof_msg, :message, 71, "A.B.C.TestMessage"
+ end
+ end
+ add_message "A.B.C.TestMessage.NestedMessage" do
+ optional :foo, :int32, 1
+ end
+ add_enum "A.B.C.TestEnum" do
+ value :Default, 0
+ value :A, 1
+ value :B, 2
+ value :C, 3
+ end
+ end
+end
+
+module A
+ module B
+ module C
+ TestMessage = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("A.B.C.TestMessage").msgclass
+ TestMessage::NestedMessage = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("A.B.C.TestMessage.NestedMessage").msgclass
+ TestEnum = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("A.B.C.TestEnum").enummodule
+ end
+ end
+end
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generated_pkg_explicit.proto b/NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generated_pkg_explicit.proto
new file mode 100644
index 00000000..8d7c948a
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generated_pkg_explicit.proto
@@ -0,0 +1,9 @@
+syntax = "proto3";
+
+package one.two.a_three;
+
+option ruby_package = "A::B::C";
+
+message Four {
+ string a_string = 1;
+}
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generated_pkg_explicit_legacy.proto b/NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generated_pkg_explicit_legacy.proto
new file mode 100644
index 00000000..7a0d2608
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generated_pkg_explicit_legacy.proto
@@ -0,0 +1,9 @@
+syntax = "proto3";
+
+package one.two.a_three.and;
+
+option ruby_package = "AA.BB.CC";
+
+message Four {
+ string another_string = 1;
+}
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generated_pkg_explicit_legacy_pb.rb b/NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generated_pkg_explicit_legacy_pb.rb
new file mode 100644
index 00000000..cdbbe891
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generated_pkg_explicit_legacy_pb.rb
@@ -0,0 +1,20 @@
+# Generated by the protocol buffer compiler. DO NOT EDIT!
+# source: ruby_generated_pkg_explicit_legacy.proto
+
+require 'google/protobuf'
+
+Google::Protobuf::DescriptorPool.generated_pool.build do
+ add_file("ruby_generated_pkg_explicit_legacy.proto", :syntax => :proto3) do
+ add_message "one.two.a_three.and.Four" do
+ optional :another_string, :string, 1
+ end
+ end
+end
+
+module AA
+ module BB
+ module CC
+ Four = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("one.two.a_three.and.Four").msgclass
+ end
+ end
+end
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generated_pkg_explicit_pb.rb b/NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generated_pkg_explicit_pb.rb
new file mode 100644
index 00000000..e6d47011
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generated_pkg_explicit_pb.rb
@@ -0,0 +1,20 @@
+# Generated by the protocol buffer compiler. DO NOT EDIT!
+# source: ruby_generated_pkg_explicit.proto
+
+require 'google/protobuf'
+
+Google::Protobuf::DescriptorPool.generated_pool.build do
+ add_file("ruby_generated_pkg_explicit.proto", :syntax => :proto3) do
+ add_message "one.two.a_three.Four" do
+ optional :a_string, :string, 1
+ end
+ end
+end
+
+module A
+ module B
+ module C
+ Four = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("one.two.a_three.Four").msgclass
+ end
+ end
+end
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generated_pkg_implicit.proto b/NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generated_pkg_implicit.proto
new file mode 100644
index 00000000..544db64d
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generated_pkg_implicit.proto
@@ -0,0 +1,7 @@
+syntax = "proto3";
+
+package one.two.a_three;
+
+message Four {
+ string a_string = 1;
+}
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generated_pkg_implicit_pb.rb b/NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generated_pkg_implicit_pb.rb
new file mode 100644
index 00000000..1ac0ef7a
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generated_pkg_implicit_pb.rb
@@ -0,0 +1,20 @@
+# Generated by the protocol buffer compiler. DO NOT EDIT!
+# source: ruby_generated_pkg_implicit.proto
+
+require 'google/protobuf'
+
+Google::Protobuf::DescriptorPool.generated_pool.build do
+ add_file("ruby_generated_pkg_implicit.proto", :syntax => :proto3) do
+ add_message "one.two.a_three.Four" do
+ optional :a_string, :string, 1
+ end
+ end
+end
+
+module One
+ module Two
+ module AThree
+ Four = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("one.two.a_three.Four").msgclass
+ end
+ end
+end
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generator.cc b/NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generator.cc
new file mode 100644
index 00000000..7d6d5032
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generator.cc
@@ -0,0 +1,575 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 <iomanip>
+#include <sstream>
+
+#include <compiler/code_generator.h>
+#include <compiler/plugin.h>
+#include <descriptor.h>
+#include <descriptor.pb.h>
+#include <io/printer.h>
+#include <io/zero_copy_stream.h>
+
+#include <compiler/ruby/ruby_generator.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace ruby {
+
+// Forward decls.
+template <class numeric_type>
+std::string NumberToString(numeric_type value);
+std::string GetRequireName(const std::string& proto_file);
+std::string LabelForField(FieldDescriptor* field);
+std::string TypeName(FieldDescriptor* field);
+bool GenerateMessage(const Descriptor* message, io::Printer* printer,
+ std::string* error);
+void GenerateEnum(const EnumDescriptor* en, io::Printer* printer);
+void GenerateMessageAssignment(const std::string& prefix,
+ const Descriptor* message, io::Printer* printer);
+void GenerateEnumAssignment(const std::string& prefix, const EnumDescriptor* en,
+ io::Printer* printer);
+std::string DefaultValueForField(const FieldDescriptor* field);
+
+template<class numeric_type>
+std::string NumberToString(numeric_type value) {
+ std::ostringstream os;
+ os << value;
+ return os.str();
+}
+
+std::string GetRequireName(const std::string& proto_file) {
+ int lastindex = proto_file.find_last_of(".");
+ return proto_file.substr(0, lastindex) + "_pb";
+}
+
+std::string GetOutputFilename(const std::string& proto_file) {
+ return GetRequireName(proto_file) + ".rb";
+}
+
+std::string LabelForField(const FieldDescriptor* field) {
+ if (field->has_optional_keyword() &&
+ field->file()->syntax() == FileDescriptor::SYNTAX_PROTO3) {
+ return "proto3_optional";
+ }
+ switch (field->label()) {
+ case FieldDescriptor::LABEL_OPTIONAL: return "optional";
+ case FieldDescriptor::LABEL_REQUIRED: return "required";
+ case FieldDescriptor::LABEL_REPEATED: return "repeated";
+ default: assert(false); return "";
+ }
+}
+
+std::string TypeName(const FieldDescriptor* field) {
+ switch (field->type()) {
+ case FieldDescriptor::TYPE_INT32: return "int32";
+ case FieldDescriptor::TYPE_INT64: return "int64";
+ case FieldDescriptor::TYPE_UINT32: return "uint32";
+ case FieldDescriptor::TYPE_UINT64: return "uint64";
+ case FieldDescriptor::TYPE_SINT32: return "sint32";
+ case FieldDescriptor::TYPE_SINT64: return "sint64";
+ case FieldDescriptor::TYPE_FIXED32: return "fixed32";
+ case FieldDescriptor::TYPE_FIXED64: return "fixed64";
+ case FieldDescriptor::TYPE_SFIXED32: return "sfixed32";
+ case FieldDescriptor::TYPE_SFIXED64: return "sfixed64";
+ case FieldDescriptor::TYPE_DOUBLE: return "double";
+ case FieldDescriptor::TYPE_FLOAT: return "float";
+ case FieldDescriptor::TYPE_BOOL: return "bool";
+ case FieldDescriptor::TYPE_ENUM: return "enum";
+ case FieldDescriptor::TYPE_STRING: return "string";
+ case FieldDescriptor::TYPE_BYTES: return "bytes";
+ case FieldDescriptor::TYPE_MESSAGE: return "message";
+ case FieldDescriptor::TYPE_GROUP: return "group";
+ default: assert(false); return "";
+ }
+}
+
+std::string StringifySyntax(FileDescriptor::Syntax syntax) {
+ switch (syntax) {
+ case FileDescriptor::SYNTAX_PROTO2:
+ return "proto2";
+ case FileDescriptor::SYNTAX_PROTO3:
+ return "proto3";
+ case FileDescriptor::SYNTAX_UNKNOWN:
+ default:
+ GOOGLE_LOG(FATAL) << "Unsupported syntax; this generator only supports "
+ "proto2 and proto3 syntax.";
+ return "";
+ }
+}
+
+std::string DefaultValueForField(const FieldDescriptor* field) {
+ switch(field->cpp_type()) {
+ case FieldDescriptor::CPPTYPE_INT32:
+ return NumberToString(field->default_value_int32());
+ case FieldDescriptor::CPPTYPE_INT64:
+ return NumberToString(field->default_value_int64());
+ case FieldDescriptor::CPPTYPE_UINT32:
+ return NumberToString(field->default_value_uint32());
+ case FieldDescriptor::CPPTYPE_UINT64:
+ return NumberToString(field->default_value_uint64());
+ case FieldDescriptor::CPPTYPE_FLOAT:
+ return NumberToString(field->default_value_float());
+ case FieldDescriptor::CPPTYPE_DOUBLE:
+ return NumberToString(field->default_value_double());
+ case FieldDescriptor::CPPTYPE_BOOL:
+ return field->default_value_bool() ? "true" : "false";
+ case FieldDescriptor::CPPTYPE_ENUM:
+ return NumberToString(field->default_value_enum()->number());
+ case FieldDescriptor::CPPTYPE_STRING: {
+ std::ostringstream os;
+ std::string default_str = field->default_value_string();
+
+ if (field->type() == FieldDescriptor::TYPE_STRING) {
+ os << "\"" << default_str << "\"";
+ } else if (field->type() == FieldDescriptor::TYPE_BYTES) {
+ os << "\"";
+
+ os.fill('0');
+ for (int i = 0; i < default_str.length(); ++i) {
+ // Write the hex form of each byte.
+ os << "\\x" << std::hex << std::setw(2)
+ << ((uint16)((unsigned char)default_str.at(i)));
+ }
+ os << "\".force_encoding(\"ASCII-8BIT\")";
+ }
+
+ return os.str();
+ }
+ default: assert(false); return "";
+ }
+}
+
+void GenerateField(const FieldDescriptor* field, io::Printer* printer) {
+ if (field->is_map()) {
+ const FieldDescriptor* key_field =
+ field->message_type()->FindFieldByNumber(1);
+ const FieldDescriptor* value_field =
+ field->message_type()->FindFieldByNumber(2);
+
+ printer->Print(
+ "map :$name$, :$key_type$, :$value_type$, $number$",
+ "name", field->name(),
+ "key_type", TypeName(key_field),
+ "value_type", TypeName(value_field),
+ "number", NumberToString(field->number()));
+
+ if (value_field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+ printer->Print(
+ ", \"$subtype$\"\n",
+ "subtype", value_field->message_type()->full_name());
+ } else if (value_field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) {
+ printer->Print(
+ ", \"$subtype$\"\n",
+ "subtype", value_field->enum_type()->full_name());
+ } else {
+ printer->Print("\n");
+ }
+ } else {
+
+ printer->Print(
+ "$label$ :$name$, ",
+ "label", LabelForField(field),
+ "name", field->name());
+ printer->Print(
+ ":$type$, $number$",
+ "type", TypeName(field),
+ "number", NumberToString(field->number()));
+
+ if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+ printer->Print(
+ ", \"$subtype$\"",
+ "subtype", field->message_type()->full_name());
+ } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) {
+ printer->Print(
+ ", \"$subtype$\"",
+ "subtype", field->enum_type()->full_name());
+ }
+
+ if (field->has_default_value()) {
+ printer->Print(", default: $default$", "default",
+ DefaultValueForField(field));
+ }
+
+ if (field->has_json_name()) {
+ printer->Print(", json_name: \"$json_name$\"", "json_name",
+ field->json_name());
+ }
+
+ printer->Print("\n");
+ }
+}
+
+void GenerateOneof(const OneofDescriptor* oneof, io::Printer* printer) {
+ printer->Print(
+ "oneof :$name$ do\n",
+ "name", oneof->name());
+ printer->Indent();
+
+ for (int i = 0; i < oneof->field_count(); i++) {
+ const FieldDescriptor* field = oneof->field(i);
+ GenerateField(field, printer);
+ }
+
+ printer->Outdent();
+ printer->Print("end\n");
+}
+
+bool GenerateMessage(const Descriptor* message, io::Printer* printer,
+ std::string* error) {
+ if (message->extension_range_count() > 0 || message->extension_count() > 0) {
+ GOOGLE_LOG(WARNING) << "Extensions are not yet supported for proto2 .proto files.";
+ }
+
+ // Don't generate MapEntry messages -- we use the Ruby extension's native
+ // support for map fields instead.
+ if (message->options().map_entry()) {
+ return true;
+ }
+
+ printer->Print(
+ "add_message \"$name$\" do\n",
+ "name", message->full_name());
+ printer->Indent();
+
+ for (int i = 0; i < message->field_count(); i++) {
+ const FieldDescriptor* field = message->field(i);
+ if (!field->real_containing_oneof()) {
+ GenerateField(field, printer);
+ }
+ }
+
+ for (int i = 0; i < message->real_oneof_decl_count(); i++) {
+ const OneofDescriptor* oneof = message->oneof_decl(i);
+ GenerateOneof(oneof, printer);
+ }
+
+ printer->Outdent();
+ printer->Print("end\n");
+
+ for (int i = 0; i < message->nested_type_count(); i++) {
+ if (!GenerateMessage(message->nested_type(i), printer, error)) {
+ return false;
+ }
+ }
+ for (int i = 0; i < message->enum_type_count(); i++) {
+ GenerateEnum(message->enum_type(i), printer);
+ }
+
+ return true;
+}
+
+void GenerateEnum(const EnumDescriptor* en, io::Printer* printer) {
+ printer->Print(
+ "add_enum \"$name$\" do\n",
+ "name", en->full_name());
+ printer->Indent();
+
+ for (int i = 0; i < en->value_count(); i++) {
+ const EnumValueDescriptor* value = en->value(i);
+ printer->Print(
+ "value :$name$, $number$\n",
+ "name", value->name(),
+ "number", NumberToString(value->number()));
+ }
+
+ printer->Outdent();
+ printer->Print(
+ "end\n");
+}
+
+// Locale-agnostic utility functions.
+bool IsLower(char ch) { return ch >= 'a' && ch <= 'z'; }
+
+bool IsUpper(char ch) { return ch >= 'A' && ch <= 'Z'; }
+
+bool IsAlpha(char ch) { return IsLower(ch) || IsUpper(ch); }
+
+char UpperChar(char ch) { return IsLower(ch) ? (ch - 'a' + 'A') : ch; }
+
+
+// Package names in protobuf are snake_case by convention, but Ruby module
+// names must be PascalCased.
+//
+// foo_bar_baz -> FooBarBaz
+std::string PackageToModule(const std::string& name) {
+ bool next_upper = true;
+ std::string result;
+ result.reserve(name.size());
+
+ for (int i = 0; i < name.size(); i++) {
+ if (name[i] == '_') {
+ next_upper = true;
+ } else {
+ if (next_upper) {
+ result.push_back(UpperChar(name[i]));
+ } else {
+ result.push_back(name[i]);
+ }
+ next_upper = false;
+ }
+ }
+
+ return result;
+}
+
+// Class and enum names in protobuf should be PascalCased by convention, but
+// since there is nothing enforcing this we need to ensure that they are valid
+// Ruby constants. That mainly means making sure that the first character is
+// an upper-case letter.
+std::string RubifyConstant(const std::string& name) {
+ std::string ret = name;
+ if (!ret.empty()) {
+ if (IsLower(ret[0])) {
+ // If it starts with a lowercase letter, capitalize it.
+ ret[0] = UpperChar(ret[0]);
+ } else if (!IsAlpha(ret[0])) {
+ // Otherwise (e.g. if it begins with an underscore), we need to come up
+ // with some prefix that starts with a capital letter. We could be smarter
+ // here, e.g. try to strip leading underscores, but this may cause other
+ // problems if the user really intended the name. So let's just prepend a
+ // well-known suffix.
+ ret = "PB_" + ret;
+ }
+ }
+
+ return ret;
+}
+
+void GenerateMessageAssignment(const std::string& prefix,
+ const Descriptor* message,
+ io::Printer* printer) {
+ // Don't generate MapEntry messages -- we use the Ruby extension's native
+ // support for map fields instead.
+ if (message->options().map_entry()) {
+ return;
+ }
+
+ printer->Print(
+ "$prefix$$name$ = ",
+ "prefix", prefix,
+ "name", RubifyConstant(message->name()));
+ printer->Print(
+ "::Google::Protobuf::DescriptorPool.generated_pool."
+ "lookup(\"$full_name$\").msgclass\n",
+ "full_name", message->full_name());
+
+ std::string nested_prefix = prefix + RubifyConstant(message->name()) + "::";
+ for (int i = 0; i < message->nested_type_count(); i++) {
+ GenerateMessageAssignment(nested_prefix, message->nested_type(i), printer);
+ }
+ for (int i = 0; i < message->enum_type_count(); i++) {
+ GenerateEnumAssignment(nested_prefix, message->enum_type(i), printer);
+ }
+}
+
+void GenerateEnumAssignment(const std::string& prefix, const EnumDescriptor* en,
+ io::Printer* printer) {
+ printer->Print(
+ "$prefix$$name$ = ",
+ "prefix", prefix,
+ "name", RubifyConstant(en->name()));
+ printer->Print(
+ "::Google::Protobuf::DescriptorPool.generated_pool."
+ "lookup(\"$full_name$\").enummodule\n",
+ "full_name", en->full_name());
+}
+
+int GeneratePackageModules(const FileDescriptor* file, io::Printer* printer) {
+ int levels = 0;
+ bool need_change_to_module = true;
+ std::string package_name;
+
+ // Determine the name to use in either format:
+ // proto package: one.two.three
+ // option ruby_package: One::Two::Three
+ if (file->options().has_ruby_package()) {
+ package_name = file->options().ruby_package();
+
+ // If :: is in the package use the Ruby formatted name as-is
+ // -> A::B::C
+ // otherwise, use the dot separator
+ // -> A.B.C
+ if (package_name.find("::") != std::string::npos) {
+ need_change_to_module = false;
+ } else {
+ GOOGLE_LOG(WARNING) << "ruby_package option should be in the form of:"
+ << " 'A::B::C' and not 'A.B.C'";
+ }
+ } else {
+ package_name = file->package();
+ }
+
+ // Use the appropriate delimiter
+ std::string delimiter = need_change_to_module ? "." : "::";
+ int delimiter_size = need_change_to_module ? 1 : 2;
+
+ // Extract each module name and indent
+ while (!package_name.empty()) {
+ size_t dot_index = package_name.find(delimiter);
+ std::string component;
+ if (dot_index == std::string::npos) {
+ component = package_name;
+ package_name = "";
+ } else {
+ component = package_name.substr(0, dot_index);
+ package_name = package_name.substr(dot_index + delimiter_size);
+ }
+ if (need_change_to_module) {
+ component = PackageToModule(component);
+ }
+ printer->Print(
+ "module $name$\n",
+ "name", component);
+ printer->Indent();
+ levels++;
+ }
+ return levels;
+}
+
+void EndPackageModules(int levels, io::Printer* printer) {
+ while (levels > 0) {
+ levels--;
+ printer->Outdent();
+ printer->Print(
+ "end\n");
+ }
+}
+
+bool GenerateDslDescriptor(const FileDescriptor* file, io::Printer* printer,
+ std::string* error) {
+ printer->Print("Google::Protobuf::DescriptorPool.generated_pool.build do\n");
+ printer->Indent();
+ printer->Print("add_file(\"$filename$\", :syntax => :$syntax$) do\n",
+ "filename", file->name(), "syntax",
+ StringifySyntax(file->syntax()));
+ printer->Indent();
+ for (int i = 0; i < file->message_type_count(); i++) {
+ if (!GenerateMessage(file->message_type(i), printer, error)) {
+ return false;
+ }
+ }
+ for (int i = 0; i < file->enum_type_count(); i++) {
+ GenerateEnum(file->enum_type(i), printer);
+ }
+ printer->Outdent();
+ printer->Print("end\n");
+ printer->Outdent();
+ printer->Print(
+ "end\n\n");
+ return true;
+}
+
+bool GenerateBinaryDescriptor(const FileDescriptor* file, io::Printer* printer,
+ std::string* error) {
+ printer->Print(
+ R"(descriptor_data = File.binread(__FILE__).split("\n__END__\n", 2)[1])");
+ printer->Print(
+ "\nGoogle::Protobuf::DescriptorPool.generated_pool.add_serialized_file("
+ "descriptor_data)\n\n");
+ return true;
+}
+
+bool GenerateFile(const FileDescriptor* file, io::Printer* printer,
+ std::string* error) {
+ printer->Print(
+ "# Generated by the protocol buffer compiler. DO NOT EDIT!\n"
+ "# source: $filename$\n"
+ "\n",
+ "filename", file->name());
+
+ printer->Print("require 'google/protobuf'\n\n");
+
+ if (file->dependency_count() != 0) {
+ for (int i = 0; i < file->dependency_count(); i++) {
+ printer->Print("require '$name$'\n", "name", GetRequireName(file->dependency(i)->name()));
+ }
+ printer->Print("\n");
+ }
+
+ // TODO: Remove this when ruby supports extensions for proto2 syntax.
+ if (file->syntax() == FileDescriptor::SYNTAX_PROTO2 &&
+ file->extension_count() > 0) {
+ GOOGLE_LOG(WARNING) << "Extensions are not yet supported for proto2 .proto files.";
+ }
+
+ bool use_raw_descriptor = file->name() == "google/protobuf/descriptor.proto";
+
+ if (use_raw_descriptor) {
+ GenerateBinaryDescriptor(file, printer, error);
+ } else {
+ GenerateDslDescriptor(file, printer, error);
+ }
+
+ int levels = GeneratePackageModules(file, printer);
+ for (int i = 0; i < file->message_type_count(); i++) {
+ GenerateMessageAssignment("", file->message_type(i), printer);
+ }
+ for (int i = 0; i < file->enum_type_count(); i++) {
+ GenerateEnumAssignment("", file->enum_type(i), printer);
+ }
+ EndPackageModules(levels, printer);
+
+ if (use_raw_descriptor) {
+ printer->Print("\n__END__\n");
+ FileDescriptorProto file_proto;
+ file->CopyTo(&file_proto);
+ std::string file_data;
+ file_proto.SerializeToString(&file_data);
+ printer->Print("$raw_descriptor$", "raw_descriptor", file_data);
+ }
+ return true;
+}
+
+bool Generator::Generate(
+ const FileDescriptor* file,
+ const std::string& parameter,
+ GeneratorContext* generator_context,
+ std::string* error) const {
+
+ if (file->syntax() != FileDescriptor::SYNTAX_PROTO3 &&
+ file->syntax() != FileDescriptor::SYNTAX_PROTO2) {
+ *error = "Invalid or unsupported proto syntax";
+ return false;
+ }
+
+ std::unique_ptr<io::ZeroCopyOutputStream> output(
+ generator_context->Open(GetOutputFilename(file->name())));
+ io::Printer printer(output.get(), '$');
+
+ return GenerateFile(file, &printer, error);
+}
+
+} // namespace ruby
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generator.h b/NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generator.h
new file mode 100644
index 00000000..e8e6e566
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generator.h
@@ -0,0 +1,67 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Generates Ruby code for a given .proto file.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_RUBY_GENERATOR_H__
+#define GOOGLE_PROTOBUF_COMPILER_RUBY_GENERATOR_H__
+
+#include <string>
+
+#include <compiler/code_generator.h>
+
+#include <port_def.inc>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace ruby {
+
+// CodeGenerator implementation for generated Ruby protocol buffer classes.
+// If you create your own protocol compiler binary and you want it to support
+// Ruby output, you can do so by registering an instance of this
+// CodeGenerator with the CommandLineInterface in your main() function.
+class PROTOC_EXPORT Generator : public CodeGenerator {
+ bool Generate(const FileDescriptor* file, const std::string& parameter,
+ GeneratorContext* generator_context,
+ std::string* error) const override;
+ uint64_t GetSupportedFeatures() const override {
+ return FEATURE_PROTO3_OPTIONAL;
+ }
+};
+
+} // namespace ruby
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#include <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_COMPILER_RUBY_GENERATOR_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generator_unittest.cc b/NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generator_unittest.cc
new file mode 100644
index 00000000..cc72c1e6
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generator_unittest.cc
@@ -0,0 +1,145 @@
+// 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.
+
+#include <memory>
+#include <list>
+
+#include <compiler/ruby/ruby_generator.h>
+#include <compiler/command_line_interface.h>
+#include <io/zero_copy_stream.h>
+#include <io/printer.h>
+
+#include <testing/googletest.h>
+#include <gtest/gtest.h>
+#include <testing/file.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace ruby {
+namespace {
+
+std::string FindRubyTestDir() {
+ return TestSourceDir() + "/google/protobuf/compiler/ruby";
+}
+
+// This test is a simple golden-file test over the output of the Ruby code
+// generator. When we make changes to the Ruby extension and alter the Ruby code
+// generator to use those changes, we should (i) manually test the output of the
+// code generator with the extension, and (ii) update the golden output above.
+// Some day, we may integrate build systems between protoc and the language
+// extensions to the point where we can do this test in a more automated way.
+
+void RubyTest(string proto_file, string import_proto_file = "") {
+ std::string ruby_tests = FindRubyTestDir();
+
+ google::protobuf::compiler::CommandLineInterface cli;
+ cli.SetInputsAreProtoPathRelative(true);
+
+ ruby::Generator ruby_generator;
+ cli.RegisterGenerator("--ruby_out", &ruby_generator, "");
+
+ // Copy generated_code.proto to the temporary test directory.
+ std::string test_input;
+ GOOGLE_CHECK_OK(File::GetContents(
+ ruby_tests + proto_file + ".proto",
+ &test_input,
+ true));
+ GOOGLE_CHECK_OK(File::SetContents(
+ TestTempDir() + proto_file + ".proto",
+ test_input,
+ true));
+
+ // Copy generated_code_import.proto to the temporary test directory.
+ std::string test_import;
+ if (!import_proto_file.empty()) {
+ GOOGLE_CHECK_OK(File::GetContents(
+ ruby_tests + import_proto_file + ".proto",
+ &test_import,
+ true));
+ GOOGLE_CHECK_OK(File::SetContents(
+ TestTempDir() + import_proto_file + ".proto",
+ test_import,
+ true));
+ }
+
+ // Invoke the proto compiler (we will be inside TestTempDir() at this point).
+ std::string ruby_out = "--ruby_out=" + TestTempDir();
+ std::string proto_path = "--proto_path=" + TestTempDir();
+
+ std::string proto_target = TestTempDir() + proto_file + ".proto";
+ const char* argv[] = {
+ "protoc",
+ ruby_out.c_str(),
+ proto_path.c_str(),
+ proto_target.c_str(),
+ };
+
+ EXPECT_EQ(0, cli.Run(4, argv));
+
+ // Load the generated output and compare to the expected result.
+ std::string output;
+ GOOGLE_CHECK_OK(File::GetContentsAsText(
+ TestTempDir() + proto_file + "_pb.rb",
+ &output,
+ true));
+ std::string expected_output;
+ GOOGLE_CHECK_OK(File::GetContentsAsText(
+ ruby_tests + proto_file + "_pb.rb",
+ &expected_output,
+ true));
+ EXPECT_EQ(expected_output, output);
+}
+
+TEST(RubyGeneratorTest, Proto3GeneratorTest) {
+ RubyTest("/ruby_generated_code", "/ruby_generated_code_proto2_import");
+}
+
+TEST(RubyGeneratorTest, Proto2GeneratorTest) {
+ RubyTest("/ruby_generated_code_proto2", "/ruby_generated_code_proto2_import");
+}
+
+TEST(RubyGeneratorTest, Proto3ImplicitPackageTest) {
+ RubyTest("/ruby_generated_pkg_implicit");
+}
+
+TEST(RubyGeneratorTest, Proto3ExplictPackageTest) {
+ RubyTest("/ruby_generated_pkg_explicit");
+}
+
+TEST(RubyGeneratorTest, Proto3ExplictLegacyPackageTest) {
+ RubyTest("/ruby_generated_pkg_explicit_legacy");
+}
+
+} // namespace
+} // namespace ruby
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/scc.h b/NorthstarDedicatedTest/include/protobuf/compiler/scc.h
new file mode 100644
index 00000000..93088bf9
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/scc.h
@@ -0,0 +1,164 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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_COMPILER_SCC_H__
+#define GOOGLE_PROTOBUF_COMPILER_SCC_H__
+
+#include <map>
+
+#include <stubs/logging.h>
+#include <stubs/common.h>
+#include <descriptor.h>
+
+#include <port_def.inc>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+
+// Description of each strongly connected component. Note that the order
+// of both the descriptors in this SCC and the order of children is
+// deterministic.
+struct SCC {
+ std::vector<const Descriptor*> descriptors;
+ std::vector<const SCC*> children;
+
+ const Descriptor* GetRepresentative() const { return descriptors[0]; }
+
+ // All messages must necessarily be in the same file.
+ const FileDescriptor* GetFile() const { return descriptors[0]->file(); }
+};
+
+// This class is used for analyzing the SCC for each message, to ensure linear
+// instead of quadratic performance, if we do this per message we would get
+// O(V*(V+E)).
+template <class DepsGenerator>
+class PROTOC_EXPORT SCCAnalyzer {
+ public:
+ explicit SCCAnalyzer() : index_(0) {}
+
+ const SCC* GetSCC(const Descriptor* descriptor) {
+ if (cache_.count(descriptor)) return cache_[descriptor].scc;
+ return DFS(descriptor).scc;
+ }
+
+ private:
+ struct NodeData {
+ const SCC* scc; // if null it means its still on the stack
+ int index;
+ int lowlink;
+ };
+
+ std::map<const Descriptor*, NodeData> cache_;
+ std::vector<const Descriptor*> stack_;
+ int index_;
+ std::vector<std::unique_ptr<SCC>> garbage_bin_;
+
+ SCC* CreateSCC() {
+ garbage_bin_.emplace_back(new SCC());
+ return garbage_bin_.back().get();
+ }
+
+ // Tarjan's Strongly Connected Components algo
+ NodeData DFS(const Descriptor* descriptor) {
+ // Must not have visited already.
+ GOOGLE_DCHECK_EQ(cache_.count(descriptor), 0);
+
+ // Mark visited by inserting in map.
+ NodeData& result = cache_[descriptor];
+ // Initialize data structures.
+ result.index = result.lowlink = index_++;
+ stack_.push_back(descriptor);
+
+ // Recurse the fields / nodes in graph
+ for (auto dep : DepsGenerator()(descriptor)) {
+ GOOGLE_CHECK(dep);
+ if (cache_.count(dep) == 0) {
+ // unexplored node
+ NodeData child_data = DFS(dep);
+ result.lowlink = std::min(result.lowlink, child_data.lowlink);
+ } else {
+ NodeData child_data = cache_[dep];
+ if (child_data.scc == nullptr) {
+ // Still in the stack_ so we found a back edge
+ result.lowlink = std::min(result.lowlink, child_data.index);
+ }
+ }
+ }
+ if (result.index == result.lowlink) {
+ // This is the root of a strongly connected component
+ SCC* scc = CreateSCC();
+ while (true) {
+ const Descriptor* scc_desc = stack_.back();
+ scc->descriptors.push_back(scc_desc);
+ // Remove from stack
+ stack_.pop_back();
+ cache_[scc_desc].scc = scc;
+
+ if (scc_desc == descriptor) break;
+ }
+
+ // The order of descriptors is random and depends how this SCC was
+ // discovered. In-order to ensure maximum stability we sort it by name.
+ std::sort(scc->descriptors.begin(), scc->descriptors.end(),
+ [](const Descriptor* a, const Descriptor* b) {
+ return a->full_name() < b->full_name();
+ });
+ AddChildren(scc);
+ }
+ return result;
+ }
+
+ // Add the SCC's that are children of this SCC to its children.
+ void AddChildren(SCC* scc) {
+ std::set<const SCC*> seen;
+ for (auto descriptor : scc->descriptors) {
+ for (auto child_msg : DepsGenerator()(descriptor)) {
+ GOOGLE_CHECK(child_msg);
+ const SCC* child = GetSCC(child_msg);
+ if (child == scc) continue;
+ if (seen.insert(child).second) {
+ scc->children.push_back(child);
+ }
+ }
+ }
+ }
+
+ // This is necessary for compiler bug in msvc2015.
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(SCCAnalyzer);
+};
+
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#include <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_COMPILER_SCC_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/subprocess.cc b/NorthstarDedicatedTest/include/protobuf/compiler/subprocess.cc
new file mode 100644
index 00000000..84e432cc
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/subprocess.cc
@@ -0,0 +1,475 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 <compiler/subprocess.h>
+
+#include <algorithm>
+#include <cstring>
+#include <iostream>
+
+#ifndef _WIN32
+#include <errno.h>
+#include <signal.h>
+#include <sys/select.h>
+#include <sys/wait.h>
+#endif
+
+#include <stubs/logging.h>
+#include <stubs/common.h>
+#include <message.h>
+#include <stubs/substitute.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+
+namespace {
+char* portable_strdup(const char* s) {
+ char* ns = (char*)malloc(strlen(s) + 1);
+ if (ns != NULL) {
+ strcpy(ns, s);
+ }
+ return ns;
+}
+} // namespace
+
+#ifdef _WIN32
+
+static void CloseHandleOrDie(HANDLE handle) {
+ if (!CloseHandle(handle)) {
+ GOOGLE_LOG(FATAL) << "CloseHandle: "
+ << Subprocess::Win32ErrorMessage(GetLastError());
+ }
+}
+
+Subprocess::Subprocess()
+ : process_start_error_(ERROR_SUCCESS),
+ child_handle_(NULL),
+ child_stdin_(NULL),
+ child_stdout_(NULL) {}
+
+Subprocess::~Subprocess() {
+ if (child_stdin_ != NULL) {
+ CloseHandleOrDie(child_stdin_);
+ }
+ if (child_stdout_ != NULL) {
+ CloseHandleOrDie(child_stdout_);
+ }
+}
+
+void Subprocess::Start(const std::string& program, SearchMode search_mode) {
+ // Create the pipes.
+ HANDLE stdin_pipe_read;
+ HANDLE stdin_pipe_write;
+ HANDLE stdout_pipe_read;
+ HANDLE stdout_pipe_write;
+
+ if (!CreatePipe(&stdin_pipe_read, &stdin_pipe_write, NULL, 0)) {
+ GOOGLE_LOG(FATAL) << "CreatePipe: " << Win32ErrorMessage(GetLastError());
+ }
+ if (!CreatePipe(&stdout_pipe_read, &stdout_pipe_write, NULL, 0)) {
+ GOOGLE_LOG(FATAL) << "CreatePipe: " << Win32ErrorMessage(GetLastError());
+ }
+
+ // Make child side of the pipes inheritable.
+ if (!SetHandleInformation(stdin_pipe_read, HANDLE_FLAG_INHERIT,
+ HANDLE_FLAG_INHERIT)) {
+ GOOGLE_LOG(FATAL) << "SetHandleInformation: "
+ << Win32ErrorMessage(GetLastError());
+ }
+ if (!SetHandleInformation(stdout_pipe_write, HANDLE_FLAG_INHERIT,
+ HANDLE_FLAG_INHERIT)) {
+ GOOGLE_LOG(FATAL) << "SetHandleInformation: "
+ << Win32ErrorMessage(GetLastError());
+ }
+
+ // Setup STARTUPINFO to redirect handles.
+ STARTUPINFOA startup_info;
+ ZeroMemory(&startup_info, sizeof(startup_info));
+ startup_info.cb = sizeof(startup_info);
+ startup_info.dwFlags = STARTF_USESTDHANDLES;
+ startup_info.hStdInput = stdin_pipe_read;
+ startup_info.hStdOutput = stdout_pipe_write;
+ startup_info.hStdError = GetStdHandle(STD_ERROR_HANDLE);
+
+ if (startup_info.hStdError == INVALID_HANDLE_VALUE) {
+ GOOGLE_LOG(FATAL) << "GetStdHandle: " << Win32ErrorMessage(GetLastError());
+ }
+
+ // Invoking cmd.exe allows for '.bat' files from the path as well as '.exe'.
+ // Using a malloc'ed string because CreateProcess() can mutate its second
+ // parameter.
+ char* command_line =
+ portable_strdup(("cmd.exe /c \"" + program + "\"").c_str());
+
+ // Create the process.
+ PROCESS_INFORMATION process_info;
+
+ if (CreateProcessA((search_mode == SEARCH_PATH) ? NULL : program.c_str(),
+ (search_mode == SEARCH_PATH) ? command_line : NULL,
+ NULL, // process security attributes
+ NULL, // thread security attributes
+ TRUE, // inherit handles?
+ 0, // obscure creation flags
+ NULL, // environment (inherit from parent)
+ NULL, // current directory (inherit from parent)
+ &startup_info, &process_info)) {
+ child_handle_ = process_info.hProcess;
+ CloseHandleOrDie(process_info.hThread);
+ child_stdin_ = stdin_pipe_write;
+ child_stdout_ = stdout_pipe_read;
+ } else {
+ process_start_error_ = GetLastError();
+ CloseHandleOrDie(stdin_pipe_write);
+ CloseHandleOrDie(stdout_pipe_read);
+ }
+
+ CloseHandleOrDie(stdin_pipe_read);
+ CloseHandleOrDie(stdout_pipe_write);
+ free(command_line);
+}
+
+bool Subprocess::Communicate(const Message& input, Message* output,
+ std::string* error) {
+ if (process_start_error_ != ERROR_SUCCESS) {
+ *error = Win32ErrorMessage(process_start_error_);
+ return false;
+ }
+
+ GOOGLE_CHECK(child_handle_ != NULL) << "Must call Start() first.";
+
+ std::string input_data = input.SerializeAsString();
+ std::string output_data;
+
+ int input_pos = 0;
+
+ while (child_stdout_ != NULL) {
+ HANDLE handles[2];
+ int handle_count = 0;
+
+ if (child_stdin_ != NULL) {
+ handles[handle_count++] = child_stdin_;
+ }
+ if (child_stdout_ != NULL) {
+ handles[handle_count++] = child_stdout_;
+ }
+
+ DWORD wait_result =
+ WaitForMultipleObjects(handle_count, handles, FALSE, INFINITE);
+
+ HANDLE signaled_handle = NULL;
+ if (wait_result >= WAIT_OBJECT_0 &&
+ wait_result < WAIT_OBJECT_0 + handle_count) {
+ signaled_handle = handles[wait_result - WAIT_OBJECT_0];
+ } else if (wait_result == WAIT_FAILED) {
+ GOOGLE_LOG(FATAL) << "WaitForMultipleObjects: "
+ << Win32ErrorMessage(GetLastError());
+ } else {
+ GOOGLE_LOG(FATAL) << "WaitForMultipleObjects: Unexpected return code: "
+ << wait_result;
+ }
+
+ if (signaled_handle == child_stdin_) {
+ DWORD n;
+ if (!WriteFile(child_stdin_, input_data.data() + input_pos,
+ input_data.size() - input_pos, &n, NULL)) {
+ // Child closed pipe. Presumably it will report an error later.
+ // Pretend we're done for now.
+ input_pos = input_data.size();
+ } else {
+ input_pos += n;
+ }
+
+ if (input_pos == input_data.size()) {
+ // We're done writing. Close.
+ CloseHandleOrDie(child_stdin_);
+ child_stdin_ = NULL;
+ }
+ } else if (signaled_handle == child_stdout_) {
+ char buffer[4096];
+ DWORD n;
+
+ if (!ReadFile(child_stdout_, buffer, sizeof(buffer), &n, NULL)) {
+ // We're done reading. Close.
+ CloseHandleOrDie(child_stdout_);
+ child_stdout_ = NULL;
+ } else {
+ output_data.append(buffer, n);
+ }
+ }
+ }
+
+ if (child_stdin_ != NULL) {
+ // Child did not finish reading input before it closed the output.
+ // Presumably it exited with an error.
+ CloseHandleOrDie(child_stdin_);
+ child_stdin_ = NULL;
+ }
+
+ DWORD wait_result = WaitForSingleObject(child_handle_, INFINITE);
+
+ if (wait_result == WAIT_FAILED) {
+ GOOGLE_LOG(FATAL) << "WaitForSingleObject: "
+ << Win32ErrorMessage(GetLastError());
+ } else if (wait_result != WAIT_OBJECT_0) {
+ GOOGLE_LOG(FATAL) << "WaitForSingleObject: Unexpected return code: "
+ << wait_result;
+ }
+
+ DWORD exit_code;
+ if (!GetExitCodeProcess(child_handle_, &exit_code)) {
+ GOOGLE_LOG(FATAL) << "GetExitCodeProcess: "
+ << Win32ErrorMessage(GetLastError());
+ }
+
+ CloseHandleOrDie(child_handle_);
+ child_handle_ = NULL;
+
+ if (exit_code != 0) {
+ *error = strings::Substitute("Plugin failed with status code $0.", exit_code);
+ return false;
+ }
+
+ if (!output->ParseFromString(output_data)) {
+ *error = "Plugin output is unparseable: " + CEscape(output_data);
+ return false;
+ }
+
+ return true;
+}
+
+std::string Subprocess::Win32ErrorMessage(DWORD error_code) {
+ char* message;
+
+ // WTF?
+ FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL, error_code, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
+ (LPSTR)&message, // NOT A BUG!
+ 0, NULL);
+
+ std::string result = message;
+ LocalFree(message);
+ return result;
+}
+
+// ===================================================================
+
+#else // _WIN32
+
+Subprocess::Subprocess()
+ : child_pid_(-1), child_stdin_(-1), child_stdout_(-1) {}
+
+Subprocess::~Subprocess() {
+ if (child_stdin_ != -1) {
+ close(child_stdin_);
+ }
+ if (child_stdout_ != -1) {
+ close(child_stdout_);
+ }
+}
+
+void Subprocess::Start(const std::string& program, SearchMode search_mode) {
+ // Note that we assume that there are no other threads, thus we don't have to
+ // do crazy stuff like using socket pairs or avoiding libc locks.
+
+ // [0] is read end, [1] is write end.
+ int stdin_pipe[2];
+ int stdout_pipe[2];
+
+ GOOGLE_CHECK(pipe(stdin_pipe) != -1);
+ GOOGLE_CHECK(pipe(stdout_pipe) != -1);
+
+ char* argv[2] = {portable_strdup(program.c_str()), NULL};
+
+ child_pid_ = fork();
+ if (child_pid_ == -1) {
+ GOOGLE_LOG(FATAL) << "fork: " << strerror(errno);
+ } else if (child_pid_ == 0) {
+ // We are the child.
+ dup2(stdin_pipe[0], STDIN_FILENO);
+ dup2(stdout_pipe[1], STDOUT_FILENO);
+
+ close(stdin_pipe[0]);
+ close(stdin_pipe[1]);
+ close(stdout_pipe[0]);
+ close(stdout_pipe[1]);
+
+ switch (search_mode) {
+ case SEARCH_PATH:
+ execvp(argv[0], argv);
+ break;
+ case EXACT_NAME:
+ execv(argv[0], argv);
+ break;
+ }
+
+ // Write directly to STDERR_FILENO to avoid stdio code paths that may do
+ // stuff that is unsafe here.
+ int ignored;
+ ignored = write(STDERR_FILENO, argv[0], strlen(argv[0]));
+ const char* message =
+ ": program not found or is not executable\n"
+ "Please specify a program using absolute path or make sure "
+ "the program is available in your PATH system variable\n";
+ ignored = write(STDERR_FILENO, message, strlen(message));
+ (void)ignored;
+
+ // Must use _exit() rather than exit() to avoid flushing output buffers
+ // that will also be flushed by the parent.
+ _exit(1);
+ } else {
+ free(argv[0]);
+
+ close(stdin_pipe[0]);
+ close(stdout_pipe[1]);
+
+ child_stdin_ = stdin_pipe[1];
+ child_stdout_ = stdout_pipe[0];
+ }
+}
+
+bool Subprocess::Communicate(const Message& input, Message* output,
+ std::string* error) {
+ GOOGLE_CHECK_NE(child_stdin_, -1) << "Must call Start() first.";
+
+ // The "sighandler_t" typedef is GNU-specific, so define our own.
+ typedef void SignalHandler(int);
+
+ // Make sure SIGPIPE is disabled so that if the child dies it doesn't kill us.
+ SignalHandler* old_pipe_handler = signal(SIGPIPE, SIG_IGN);
+
+ std::string input_data = input.SerializeAsString();
+ std::string output_data;
+
+ int input_pos = 0;
+ int max_fd = std::max(child_stdin_, child_stdout_);
+
+ while (child_stdout_ != -1) {
+ fd_set read_fds;
+ fd_set write_fds;
+ FD_ZERO(&read_fds);
+ FD_ZERO(&write_fds);
+ if (child_stdout_ != -1) {
+ FD_SET(child_stdout_, &read_fds);
+ }
+ if (child_stdin_ != -1) {
+ FD_SET(child_stdin_, &write_fds);
+ }
+
+ if (select(max_fd + 1, &read_fds, &write_fds, NULL, NULL) < 0) {
+ if (errno == EINTR) {
+ // Interrupted by signal. Try again.
+ continue;
+ } else {
+ GOOGLE_LOG(FATAL) << "select: " << strerror(errno);
+ }
+ }
+
+ if (child_stdin_ != -1 && FD_ISSET(child_stdin_, &write_fds)) {
+ int n = write(child_stdin_, input_data.data() + input_pos,
+ input_data.size() - input_pos);
+ if (n < 0) {
+ // Child closed pipe. Presumably it will report an error later.
+ // Pretend we're done for now.
+ input_pos = input_data.size();
+ } else {
+ input_pos += n;
+ }
+
+ if (input_pos == input_data.size()) {
+ // We're done writing. Close.
+ close(child_stdin_);
+ child_stdin_ = -1;
+ }
+ }
+
+ if (child_stdout_ != -1 && FD_ISSET(child_stdout_, &read_fds)) {
+ char buffer[4096];
+ int n = read(child_stdout_, buffer, sizeof(buffer));
+
+ if (n > 0) {
+ output_data.append(buffer, n);
+ } else {
+ // We're done reading. Close.
+ close(child_stdout_);
+ child_stdout_ = -1;
+ }
+ }
+ }
+
+ if (child_stdin_ != -1) {
+ // Child did not finish reading input before it closed the output.
+ // Presumably it exited with an error.
+ close(child_stdin_);
+ child_stdin_ = -1;
+ }
+
+ int status;
+ while (waitpid(child_pid_, &status, 0) == -1) {
+ if (errno != EINTR) {
+ GOOGLE_LOG(FATAL) << "waitpid: " << strerror(errno);
+ }
+ }
+
+ // Restore SIGPIPE handling.
+ signal(SIGPIPE, old_pipe_handler);
+
+ if (WIFEXITED(status)) {
+ if (WEXITSTATUS(status) != 0) {
+ int error_code = WEXITSTATUS(status);
+ *error =
+ strings::Substitute("Plugin failed with status code $0.", error_code);
+ return false;
+ }
+ } else if (WIFSIGNALED(status)) {
+ int signal = WTERMSIG(status);
+ *error = strings::Substitute("Plugin killed by signal $0.", signal);
+ return false;
+ } else {
+ *error = "Neither WEXITSTATUS nor WTERMSIG is true?";
+ return false;
+ }
+
+ if (!output->ParseFromString(output_data)) {
+ *error = "Plugin output is unparseable: " + CEscape(output_data);
+ return false;
+ }
+
+ return true;
+}
+
+#endif // !_WIN32
+
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/subprocess.h b/NorthstarDedicatedTest/include/protobuf/compiler/subprocess.h
new file mode 100644
index 00000000..dfad84e1
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/subprocess.h
@@ -0,0 +1,113 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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_COMPILER_SUBPROCESS_H__
+#define GOOGLE_PROTOBUF_COMPILER_SUBPROCESS_H__
+
+#ifdef _WIN32
+#ifndef WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN // right...
+#endif
+#include <windows.h>
+#else // _WIN32
+#include <sys/types.h>
+#include <unistd.h>
+#endif // !_WIN32
+#include <stubs/common.h>
+
+#include <string>
+
+#include <port_def.inc>
+
+namespace google {
+namespace protobuf {
+
+class Message;
+
+namespace compiler {
+
+// Utility class for launching sub-processes.
+class PROTOC_EXPORT Subprocess {
+ public:
+ Subprocess();
+ ~Subprocess();
+
+ enum SearchMode {
+ SEARCH_PATH, // Use PATH environment variable.
+ EXACT_NAME // Program is an exact file name; don't use the PATH.
+ };
+
+ // Start the subprocess. Currently we don't provide a way to specify
+ // arguments as protoc plugins don't have any.
+ void Start(const std::string& program, SearchMode search_mode);
+
+ // Serialize the input message and pipe it to the subprocess's stdin, then
+ // close the pipe. Meanwhile, read from the subprocess's stdout and parse
+ // the data into *output. All this is done carefully to avoid deadlocks.
+ // Returns true if successful. On any sort of error, returns false and sets
+ // *error to a description of the problem.
+ bool Communicate(const Message& input, Message* output, std::string* error);
+
+#ifdef _WIN32
+ // Given an error code, returns a human-readable error message. This is
+ // defined here so that CommandLineInterface can share it.
+ static std::string Win32ErrorMessage(DWORD error_code);
+#endif
+
+ private:
+#ifdef _WIN32
+ DWORD process_start_error_;
+ HANDLE child_handle_;
+
+ // The file handles for our end of the child's pipes. We close each and
+ // set it to NULL when no longer needed.
+ HANDLE child_stdin_;
+ HANDLE child_stdout_;
+
+#else // _WIN32
+ pid_t child_pid_;
+
+ // The file descriptors for our end of the child's pipes. We close each and
+ // set it to -1 when no longer needed.
+ int child_stdin_;
+ int child_stdout_;
+
+#endif // !_WIN32
+};
+
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#include <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_COMPILER_SUBPROCESS_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/test_plugin.cc b/NorthstarDedicatedTest/include/protobuf/compiler/test_plugin.cc
new file mode 100644
index 00000000..bca1f068
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/test_plugin.cc
@@ -0,0 +1,61 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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)
+//
+// This is a dummy code generator plugin used by
+// command_line_interface_unittest.
+
+#include <stdlib.h>
+#include <string>
+#include <compiler/mock_code_generator.h>
+#include <compiler/plugin.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+
+int ProtobufMain(int argc, char* argv[]) {
+ MockCodeGenerator generator("test_plugin");
+ return PluginMain(argc, argv, &generator);
+}
+
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+int main(int argc, char* argv[]) {
+#ifdef _MSC_VER
+ // Don't print a silly message or stick a modal dialog box in my face,
+ // please.
+ _set_abort_behavior(0, ~0);
+#endif // !_MSC_VER
+ return google::protobuf::compiler::ProtobufMain(argc, argv);
+}
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/zip_output_unittest.sh b/NorthstarDedicatedTest/include/protobuf/compiler/zip_output_unittest.sh
new file mode 100644
index 00000000..f8597912
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/zip_output_unittest.sh
@@ -0,0 +1,100 @@
+#!/bin/sh
+#
+# Protocol Buffers - Google's data interchange format
+# Copyright 2009 Google Inc. All rights reserved.
+# https://developers.google.com/protocol-buffers/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (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)
+#
+# Test protoc's zip output mode.
+
+fail() {
+ echo "$@" >&2
+ exit 1
+}
+
+TEST_TMPDIR=.
+PROTOC=./protoc
+JAR=jar
+UNZIP=unzip
+
+echo '
+ syntax = "proto2";
+ option java_multiple_files = true;
+ option java_package = "test.jar";
+ option java_outer_classname = "Outer";
+ message Foo {}
+ message Bar {}
+' > $TEST_TMPDIR/testzip.proto
+
+$PROTOC \
+ --cpp_out=$TEST_TMPDIR/testzip.zip --python_out=$TEST_TMPDIR/testzip.zip \
+ --java_out=$TEST_TMPDIR/testzip.jar -I$TEST_TMPDIR testzip.proto \
+ || fail 'protoc failed.'
+
+echo "Testing output to zip..."
+if $UNZIP -h > /dev/null; then
+ $UNZIP -t $TEST_TMPDIR/testzip.zip > $TEST_TMPDIR/testzip.list \
+ || fail 'unzip failed.'
+
+ grep 'testing: testzip\.pb\.cc *OK$' $TEST_TMPDIR/testzip.list > /dev/null \
+ || fail 'testzip.pb.cc not found in output zip.'
+ grep 'testing: testzip\.pb\.h *OK$' $TEST_TMPDIR/testzip.list > /dev/null \
+ || fail 'testzip.pb.h not found in output zip.'
+ grep 'testing: testzip_pb2\.py *OK$' $TEST_TMPDIR/testzip.list > /dev/null \
+ || fail 'testzip_pb2.py not found in output zip.'
+ grep -i 'manifest' $TEST_TMPDIR/testzip.list > /dev/null \
+ && fail 'Zip file contained manifest.'
+else
+ echo "Warning: 'unzip' command not available. Skipping test."
+fi
+
+echo "Testing output to jar..."
+if $JAR c $TEST_TMPDIR/testzip.proto > /dev/null; then
+ $JAR tf $TEST_TMPDIR/testzip.jar > $TEST_TMPDIR/testzip.list \
+ || fail 'jar failed.'
+
+ # Check that -interface.jar timestamps are normalized:
+ if [[ "$(TZ=UTC $JAR tvf $TEST_TMPDIR/testzip.jar)" != *'Tue Jan 01 00:00:00 UTC 1980'* ]]; then
+ fail 'Zip did not contain normalized timestamps'
+ fi
+
+ grep '^test/jar/Foo\.java$' $TEST_TMPDIR/testzip.list > /dev/null \
+ || fail 'Foo.java not found in output jar.'
+ grep '^test/jar/Bar\.java$' $TEST_TMPDIR/testzip.list > /dev/null \
+ || fail 'Bar.java not found in output jar.'
+ grep '^test/jar/Outer\.java$' $TEST_TMPDIR/testzip.list > /dev/null \
+ || fail 'Outer.java not found in output jar.'
+ grep '^META-INF/MANIFEST\.MF$' $TEST_TMPDIR/testzip.list > /dev/null \
+ || fail 'Manifest not found in output jar.'
+else
+ echo "Warning: 'jar' command not available. Skipping test."
+fi
+
+echo PASS
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/zip_writer.cc b/NorthstarDedicatedTest/include/protobuf/compiler/zip_writer.cc
new file mode 100644
index 00000000..b2361dae
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/zip_writer.cc
@@ -0,0 +1,195 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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: ambrose@google.com (Ambrose Feinstein),
+// kenton@google.com (Kenton Varda)
+//
+// Based on http://www.pkware.com/documents/casestudies/APPNOTE.TXT
+
+#include <compiler/zip_writer.h>
+
+#include <cstdint>
+
+#include <io/coded_stream.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+
+// January 1, 1980 as a DOS date.
+// see https://msdn.microsoft.com/en-us/library/9kkf9tah.aspx
+static const uint16_t kDosEpoch = 1 << 5 | 1;
+
+static const uint32_t kCRC32Table[256] = {
+ 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
+ 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
+ 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
+ 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
+ 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
+ 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
+ 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
+ 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
+ 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
+ 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
+ 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
+ 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
+ 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
+ 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
+ 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
+ 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
+ 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
+ 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
+ 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
+ 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
+ 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
+ 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
+ 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
+ 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
+ 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
+ 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
+ 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
+ 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
+ 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
+ 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
+ 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
+ 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
+ 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
+ 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
+ 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
+ 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
+ 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
+ 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
+ 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
+ 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
+ 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
+ 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
+ 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d};
+
+static uint32_t ComputeCRC32(const std::string& buf) {
+ uint32_t x = ~0U;
+ for (int i = 0; i < buf.size(); ++i) {
+ unsigned char c = buf[i];
+ x = kCRC32Table[(x ^ c) & 0xff] ^ (x >> 8);
+ }
+ return ~x;
+}
+
+static void WriteShort(io::CodedOutputStream* out, uint16_t val) {
+ uint8_t p[2];
+ p[0] = static_cast<uint8_t>(val);
+ p[1] = static_cast<uint8_t>(val >> 8);
+ out->WriteRaw(p, 2);
+}
+
+ZipWriter::ZipWriter(io::ZeroCopyOutputStream* raw_output)
+ : raw_output_(raw_output) {}
+ZipWriter::~ZipWriter() {}
+
+bool ZipWriter::Write(const std::string& filename,
+ const std::string& contents) {
+ FileInfo info;
+
+ info.name = filename;
+ uint16_t filename_size = filename.size();
+ info.offset = raw_output_->ByteCount();
+ info.size = contents.size();
+ info.crc32 = ComputeCRC32(contents);
+
+ files_.push_back(info);
+
+ // write file header
+ io::CodedOutputStream output(raw_output_);
+ output.WriteLittleEndian32(0x04034b50); // magic
+ WriteShort(&output, 10); // version needed to extract
+ WriteShort(&output, 0); // flags
+ WriteShort(&output, 0); // compression method: stored
+ WriteShort(&output, 0); // last modified time
+ WriteShort(&output, kDosEpoch); // last modified date
+ output.WriteLittleEndian32(info.crc32); // crc-32
+ output.WriteLittleEndian32(info.size); // compressed size
+ output.WriteLittleEndian32(info.size); // uncompressed size
+ WriteShort(&output, filename_size); // file name length
+ WriteShort(&output, 0); // extra field length
+ output.WriteString(filename); // file name
+ output.WriteString(contents); // file data
+
+ return !output.HadError();
+}
+
+bool ZipWriter::WriteDirectory() {
+ uint16_t num_entries = files_.size();
+ uint32_t dir_ofs = raw_output_->ByteCount();
+
+ // write central directory
+ io::CodedOutputStream output(raw_output_);
+ for (int i = 0; i < num_entries; ++i) {
+ const std::string& filename = files_[i].name;
+ uint16_t filename_size = filename.size();
+ uint32_t crc32 = files_[i].crc32;
+ uint32_t size = files_[i].size;
+ uint32_t offset = files_[i].offset;
+
+ output.WriteLittleEndian32(0x02014b50); // magic
+ WriteShort(&output, 10); // version made by
+ WriteShort(&output, 10); // version needed to extract
+ WriteShort(&output, 0); // flags
+ WriteShort(&output, 0); // compression method: stored
+ WriteShort(&output, 0); // last modified time
+ WriteShort(&output, kDosEpoch); // last modified date
+ output.WriteLittleEndian32(crc32); // crc-32
+ output.WriteLittleEndian32(size); // compressed size
+ output.WriteLittleEndian32(size); // uncompressed size
+ WriteShort(&output, filename_size); // file name length
+ WriteShort(&output, 0); // extra field length
+ WriteShort(&output, 0); // file comment length
+ WriteShort(&output, 0); // starting disk number
+ WriteShort(&output, 0); // internal file attributes
+ output.WriteLittleEndian32(0); // external file attributes
+ output.WriteLittleEndian32(offset); // local header offset
+ output.WriteString(filename); // file name
+ }
+ uint32_t dir_len = output.ByteCount();
+
+ // write end of central directory marker
+ output.WriteLittleEndian32(0x06054b50); // magic
+ WriteShort(&output, 0); // disk number
+ WriteShort(&output, 0); // disk with start of central directory
+ WriteShort(&output, num_entries); // central directory entries (this disk)
+ WriteShort(&output, num_entries); // central directory entries (total)
+ output.WriteLittleEndian32(dir_len); // central directory byte size
+ output.WriteLittleEndian32(dir_ofs); // central directory offset
+ WriteShort(&output, 0); // comment length
+
+ return output.HadError();
+}
+
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/zip_writer.h b/NorthstarDedicatedTest/include/protobuf/compiler/zip_writer.h
new file mode 100644
index 00000000..243bbf1d
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/zip_writer.h
@@ -0,0 +1,65 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 <cstdint>
+#include <vector>
+
+#include <stubs/common.h>
+#include <io/zero_copy_stream.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+
+class ZipWriter {
+ public:
+ ZipWriter(io::ZeroCopyOutputStream* raw_output);
+ ~ZipWriter();
+
+ bool Write(const std::string& filename, const std::string& contents);
+ bool WriteDirectory();
+
+ private:
+ struct FileInfo {
+ std::string name;
+ uint32_t offset;
+ uint32_t size;
+ uint32_t crc32;
+ };
+
+ io::ZeroCopyOutputStream* raw_output_;
+ std::vector<FileInfo> files_;
+};
+
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/descriptor.cc b/NorthstarDedicatedTest/include/protobuf/descriptor.cc
new file mode 100644
index 00000000..38db1f60
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/descriptor.cc
@@ -0,0 +1,8025 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 <descriptor.h>
+
+#include <algorithm>
+#include <array>
+#include <functional>
+#include <limits>
+#include <map>
+#include <memory>
+#include <set>
+#include <string>
+#include <unordered_map>
+#include <unordered_set>
+#include <vector>
+
+#include <stubs/common.h>
+#include <stubs/logging.h>
+#include <stubs/stringprintf.h>
+#include <stubs/strutil.h>
+#include <any.h>
+#include <descriptor.pb.h>
+#include <stubs/once.h>
+#include <io/coded_stream.h>
+#include <io/tokenizer.h>
+#include <io/zero_copy_stream_impl.h>
+#include <descriptor_database.h>
+#include <dynamic_message.h>
+#include <generated_message_util.h>
+#include <text_format.h>
+#include <unknown_field_set.h>
+#include <wire_format.h>
+#include <stubs/casts.h>
+#include <stubs/substitute.h>
+#include <io/strtod.h>
+#include <stubs/map_util.h>
+#include <stubs/stl_util.h>
+#include <stubs/hash.h>
+
+#undef PACKAGE // autoheader #defines this. :(
+
+
+#include <port_def.inc>
+
+namespace google {
+namespace protobuf {
+
+class Symbol {
+ public:
+ enum Type {
+ NULL_SYMBOL,
+ MESSAGE,
+ FIELD,
+ ONEOF,
+ ENUM,
+ ENUM_VALUE,
+ ENUM_VALUE_OTHER_PARENT,
+ SERVICE,
+ METHOD,
+ PACKAGE,
+ QUERY_KEY
+ };
+
+ Symbol() : ptr_(nullptr) {}
+
+ // Every object we store derives from internal::SymbolBase, where we store the
+ // symbol type enum.
+ // Storing in the object can be done without using more space in most cases,
+ // while storing it in the Symbol type would require 8 bytes.
+#define DEFINE_MEMBERS(TYPE, TYPE_CONSTANT, FIELD) \
+ explicit Symbol(TYPE* value) : ptr_(value) { \
+ value->symbol_type_ = TYPE_CONSTANT; \
+ } \
+ const TYPE* FIELD() const { \
+ return type() == TYPE_CONSTANT ? static_cast<const TYPE*>(ptr_) : nullptr; \
+ }
+
+ DEFINE_MEMBERS(Descriptor, MESSAGE, descriptor)
+ DEFINE_MEMBERS(FieldDescriptor, FIELD, field_descriptor)
+ DEFINE_MEMBERS(OneofDescriptor, ONEOF, oneof_descriptor)
+ DEFINE_MEMBERS(EnumDescriptor, ENUM, enum_descriptor)
+ DEFINE_MEMBERS(ServiceDescriptor, SERVICE, service_descriptor)
+ DEFINE_MEMBERS(MethodDescriptor, METHOD, method_descriptor)
+
+ // We use a special node for FileDescriptor.
+ // It is potentially added to the table with multiple different names, so we
+ // need a separate place to put the name.
+ struct Package : internal::SymbolBase {
+ const std::string* name;
+ const FileDescriptor* file;
+ };
+ DEFINE_MEMBERS(Package, PACKAGE, package_file_descriptor)
+
+ // Enum values have two different parents.
+ // We use two different identitied for the same object to determine the two
+ // different insertions in the map.
+ static Symbol EnumValue(EnumValueDescriptor* value, int n) {
+ Symbol s;
+ internal::SymbolBase* ptr;
+ if (n == 0) {
+ ptr = static_cast<internal::SymbolBaseN<0>*>(value);
+ ptr->symbol_type_ = ENUM_VALUE;
+ } else {
+ ptr = static_cast<internal::SymbolBaseN<1>*>(value);
+ ptr->symbol_type_ = ENUM_VALUE_OTHER_PARENT;
+ }
+ s.ptr_ = ptr;
+ return s;
+ }
+
+ const EnumValueDescriptor* enum_value_descriptor() const {
+ return type() == ENUM_VALUE
+ ? static_cast<const EnumValueDescriptor*>(
+ static_cast<const internal::SymbolBaseN<0>*>(ptr_))
+ : type() == ENUM_VALUE_OTHER_PARENT
+ ? static_cast<const EnumValueDescriptor*>(
+ static_cast<const internal::SymbolBaseN<1>*>(ptr_))
+ : nullptr;
+ }
+
+ // Not a real symbol.
+ // Only used for heterogeneous lookups and never actually inserted in the
+ // tables.
+ struct QueryKey : internal::SymbolBase {
+ StringPiece name;
+ const void* parent;
+ int field_number;
+ };
+ DEFINE_MEMBERS(QueryKey, QUERY_KEY, query_key);
+#undef DEFINE_MEMBERS
+
+ Type type() const {
+ return ptr_ == nullptr ? NULL_SYMBOL
+ : static_cast<Type>(ptr_->symbol_type_);
+ }
+ bool IsNull() const { return type() == NULL_SYMBOL; }
+ bool IsType() const { return type() == MESSAGE || type() == ENUM; }
+ bool IsAggregate() const {
+ return type() == MESSAGE || type() == PACKAGE || type() == ENUM ||
+ type() == SERVICE;
+ }
+
+ const FileDescriptor* GetFile() const {
+ switch (type()) {
+ case MESSAGE:
+ return descriptor()->file();
+ case FIELD:
+ return field_descriptor()->file();
+ case ONEOF:
+ return oneof_descriptor()->containing_type()->file();
+ case ENUM:
+ return enum_descriptor()->file();
+ case ENUM_VALUE:
+ return enum_value_descriptor()->type()->file();
+ case SERVICE:
+ return service_descriptor()->file();
+ case METHOD:
+ return method_descriptor()->service()->file();
+ case PACKAGE:
+ return package_file_descriptor()->file;
+ default:
+ return nullptr;
+ }
+ }
+
+ StringPiece full_name() const {
+ switch (type()) {
+ case MESSAGE:
+ return descriptor()->full_name();
+ case FIELD:
+ return field_descriptor()->full_name();
+ case ONEOF:
+ return oneof_descriptor()->full_name();
+ case ENUM:
+ return enum_descriptor()->full_name();
+ case ENUM_VALUE:
+ return enum_value_descriptor()->full_name();
+ case SERVICE:
+ return service_descriptor()->full_name();
+ case METHOD:
+ return method_descriptor()->full_name();
+ case PACKAGE:
+ return *package_file_descriptor()->name;
+ case QUERY_KEY:
+ return query_key()->name;
+ default:
+ GOOGLE_CHECK(false);
+ }
+ return "";
+ }
+
+ std::pair<const void*, StringPiece> parent_name_key() const {
+ const auto or_file = [&](const void* p) { return p ? p : GetFile(); };
+ switch (type()) {
+ case MESSAGE:
+ return {or_file(descriptor()->containing_type()), descriptor()->name()};
+ case FIELD: {
+ auto* field = field_descriptor();
+ return {or_file(field->is_extension() ? field->extension_scope()
+ : field->containing_type()),
+ field->name()};
+ }
+ case ONEOF:
+ return {oneof_descriptor()->containing_type(),
+ oneof_descriptor()->name()};
+ case ENUM:
+ return {or_file(enum_descriptor()->containing_type()),
+ enum_descriptor()->name()};
+ case ENUM_VALUE:
+ return {or_file(enum_value_descriptor()->type()->containing_type()),
+ enum_value_descriptor()->name()};
+ case ENUM_VALUE_OTHER_PARENT:
+ return {enum_value_descriptor()->type(),
+ enum_value_descriptor()->name()};
+ case SERVICE:
+ return {GetFile(), service_descriptor()->name()};
+ case METHOD:
+ return {method_descriptor()->service(), method_descriptor()->name()};
+ case QUERY_KEY:
+ return {query_key()->parent, query_key()->name};
+ default:
+ GOOGLE_CHECK(false);
+ }
+ return {};
+ }
+
+ std::pair<const void*, int> parent_number_key() const {
+ switch (type()) {
+ case FIELD:
+ return {field_descriptor()->containing_type(),
+ field_descriptor()->number()};
+ case ENUM_VALUE:
+ return {enum_value_descriptor()->type(),
+ enum_value_descriptor()->number()};
+ case QUERY_KEY:
+ return {query_key()->parent, query_key()->field_number};
+ default:
+ GOOGLE_CHECK(false);
+ }
+ return {};
+ }
+
+ private:
+ const internal::SymbolBase* ptr_;
+};
+
+const FieldDescriptor::CppType
+ FieldDescriptor::kTypeToCppTypeMap[MAX_TYPE + 1] = {
+ static_cast<CppType>(0), // 0 is reserved for errors
+
+ CPPTYPE_DOUBLE, // TYPE_DOUBLE
+ CPPTYPE_FLOAT, // TYPE_FLOAT
+ CPPTYPE_INT64, // TYPE_INT64
+ CPPTYPE_UINT64, // TYPE_UINT64
+ CPPTYPE_INT32, // TYPE_INT32
+ CPPTYPE_UINT64, // TYPE_FIXED64
+ CPPTYPE_UINT32, // TYPE_FIXED32
+ CPPTYPE_BOOL, // TYPE_BOOL
+ CPPTYPE_STRING, // TYPE_STRING
+ CPPTYPE_MESSAGE, // TYPE_GROUP
+ CPPTYPE_MESSAGE, // TYPE_MESSAGE
+ CPPTYPE_STRING, // TYPE_BYTES
+ CPPTYPE_UINT32, // TYPE_UINT32
+ CPPTYPE_ENUM, // TYPE_ENUM
+ CPPTYPE_INT32, // TYPE_SFIXED32
+ CPPTYPE_INT64, // TYPE_SFIXED64
+ CPPTYPE_INT32, // TYPE_SINT32
+ CPPTYPE_INT64, // TYPE_SINT64
+};
+
+const char* const FieldDescriptor::kTypeToName[MAX_TYPE + 1] = {
+ "ERROR", // 0 is reserved for errors
+
+ "double", // TYPE_DOUBLE
+ "float", // TYPE_FLOAT
+ "int64", // TYPE_INT64
+ "uint64", // TYPE_UINT64
+ "int32", // TYPE_INT32
+ "fixed64", // TYPE_FIXED64
+ "fixed32", // TYPE_FIXED32
+ "bool", // TYPE_BOOL
+ "string", // TYPE_STRING
+ "group", // TYPE_GROUP
+ "message", // TYPE_MESSAGE
+ "bytes", // TYPE_BYTES
+ "uint32", // TYPE_UINT32
+ "enum", // TYPE_ENUM
+ "sfixed32", // TYPE_SFIXED32
+ "sfixed64", // TYPE_SFIXED64
+ "sint32", // TYPE_SINT32
+ "sint64", // TYPE_SINT64
+};
+
+const char* const FieldDescriptor::kCppTypeToName[MAX_CPPTYPE + 1] = {
+ "ERROR", // 0 is reserved for errors
+
+ "int32", // CPPTYPE_INT32
+ "int64", // CPPTYPE_INT64
+ "uint32", // CPPTYPE_UINT32
+ "uint64", // CPPTYPE_UINT64
+ "double", // CPPTYPE_DOUBLE
+ "float", // CPPTYPE_FLOAT
+ "bool", // CPPTYPE_BOOL
+ "enum", // CPPTYPE_ENUM
+ "string", // CPPTYPE_STRING
+ "message", // CPPTYPE_MESSAGE
+};
+
+const char* const FieldDescriptor::kLabelToName[MAX_LABEL + 1] = {
+ "ERROR", // 0 is reserved for errors
+
+ "optional", // LABEL_OPTIONAL
+ "required", // LABEL_REQUIRED
+ "repeated", // LABEL_REPEATED
+};
+
+const char* FileDescriptor::SyntaxName(FileDescriptor::Syntax syntax) {
+ switch (syntax) {
+ case SYNTAX_PROTO2:
+ return "proto2";
+ case SYNTAX_PROTO3:
+ return "proto3";
+ case SYNTAX_UNKNOWN:
+ return "unknown";
+ }
+ GOOGLE_LOG(FATAL) << "can't reach here.";
+ return nullptr;
+}
+
+static const char* const kNonLinkedWeakMessageReplacementName = "google.protobuf.Empty";
+
+#if !defined(_MSC_VER) || (_MSC_VER >= 1900 && _MSC_VER < 1912)
+const int FieldDescriptor::kMaxNumber;
+const int FieldDescriptor::kFirstReservedNumber;
+const int FieldDescriptor::kLastReservedNumber;
+#endif
+
+namespace {
+
+// Note: I distrust ctype.h due to locales.
+char ToUpper(char ch) {
+ return (ch >= 'a' && ch <= 'z') ? (ch - 'a' + 'A') : ch;
+}
+
+char ToLower(char ch) {
+ return (ch >= 'A' && ch <= 'Z') ? (ch - 'A' + 'a') : ch;
+}
+
+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;
+}
+
+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;
+ }
+};
+
+
+const Symbol kNullSymbol;
+
+struct SymbolByFullNameHash {
+ size_t operator()(Symbol s) const {
+ return HASH_FXN<StringPiece>{}(s.full_name());
+ }
+};
+struct SymbolByFullNameEq {
+ bool operator()(Symbol a, Symbol b) const {
+ return a.full_name() == b.full_name();
+ }
+};
+using SymbolsByNameSet =
+ HASH_SET<Symbol, SymbolByFullNameHash, SymbolByFullNameEq>;
+
+struct SymbolByParentHash {
+ size_t operator()(Symbol s) const {
+ return PointerStringPairHash{}(s.parent_name_key());
+ }
+};
+struct SymbolByParentEq {
+ bool operator()(Symbol a, Symbol b) const {
+ return a.parent_name_key() == b.parent_name_key();
+ }
+};
+using SymbolsByParentSet =
+ HASH_SET<Symbol, SymbolByParentHash, SymbolByParentEq>;
+
+typedef HASH_MAP<StringPiece, const FileDescriptor*,
+ HASH_FXN<StringPiece>>
+ FilesByNameMap;
+
+typedef HASH_MAP<PointerStringPair, const FieldDescriptor*,
+ PointerStringPairHash>
+ FieldsByNameMap;
+
+struct FieldsByNumberHash {
+ size_t operator()(Symbol s) const {
+ return PointerIntegerPairHash<std::pair<const void*, int>>{}(
+ s.parent_number_key());
+ }
+};
+struct FieldsByNumberEq {
+ bool operator()(Symbol a, Symbol b) const {
+ return a.parent_number_key() == b.parent_number_key();
+ }
+};
+using FieldsByNumberSet =
+ HASH_SET<Symbol, FieldsByNumberHash, FieldsByNumberEq>;
+using EnumValuesByNumberSet = FieldsByNumberSet;
+
+// This is a map rather than a hash-map, since we use it to iterate
+// through all the extensions that extend a given Descriptor, and an
+// ordered data structure that implements lower_bound is convenient
+// for that.
+typedef std::map<DescriptorIntPair, const FieldDescriptor*>
+ ExtensionsGroupedByDescriptorMap;
+typedef HASH_MAP<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"};
+ 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();
+}
+
+// This bump allocator arena is optimized for the use case of this file. It is
+// mostly optimized for memory usage, since these objects are expected to live
+// for the entirety of the program.
+//
+// Some differences from other arenas:
+// - It has a fixed number of non-trivial types it can hold. This allows
+// tracking the allocations with a single byte. In contrast, google::protobuf::Arena
+// uses 16 bytes per non-trivial object created.
+// - It has some extra metadata for rollbacks. This is necessary for
+// implementing the API below. This metadata is flushed at the end and would
+// not cause persistent memory usage.
+// - It tries to squeeze every byte of out the blocks. If an allocation is too
+// large for the current block we move the block to a secondary area where we
+// can still use it for smaller objects. This complicates rollback logic but
+// makes it much more memory efficient.
+//
+// The allocation strategy is as follows:
+// - Memory is allocated from the front, with a forced 8 byte alignment.
+// - Metadata is allocated from the back, one byte per element.
+// - The metadata encodes one of two things:
+// * For types we want to track, the index into KnownTypes.
+// * For raw memory blocks, the size of the block (in 8 byte increments
+// to allow for a larger limit).
+// - When the raw data is too large to represent in the metadata byte, we
+// allocate this memory separately in the heap and store an OutOfLineAlloc
+// object instead. These come from large array allocations and alike.
+//
+// Blocks are kept in 3 areas:
+// - `current_` is the one we are currently allocating from. When we need to
+// allocate a block that doesn't fit there, we make a new block and move the
+// old `current_` to one of the areas below.
+// - Blocks that have no more usable space left (ie less than 9 bytes) are
+// stored in `full_blocks_`.
+// - Blocks that have some usable space are categorized in
+// `small_size_blocks_` depending on how much space they have left.
+// See `kSmallSizes` to see which sizes we track.
+//
+class TableArena {
+ public:
+ // Allocate a block on `n` bytes, with no destructor information saved.
+ void* AllocateMemory(uint32_t n) {
+ uint32_t tag = SizeToRawTag(n) + kFirstRawTag;
+ if (tag > 255) {
+ // We can't fit the size, use an OutOfLineAlloc.
+ return Create<OutOfLineAlloc>(OutOfLineAlloc{::operator new(n), n})->ptr;
+ }
+
+ return AllocRawInternal(n, static_cast<Tag>(tag));
+ }
+
+ // Allocate and construct an element of type `T` as if by
+ // `T(std::forward<Args>(args...))`.
+ // The object is registered for destruction, if its destructor is not trivial.
+ template <typename T, typename... Args>
+ T* Create(Args&&... args) {
+ static_assert(alignof(T) <= 8, "");
+ return ::new (AllocRawInternal(sizeof(T), TypeTag<T>(KnownTypes{})))
+ T(std::forward<Args>(args)...);
+ }
+
+ TableArena() {}
+
+ TableArena(const TableArena&) = delete;
+ TableArena& operator=(const TableArena&) = delete;
+
+ ~TableArena() {
+ // Uncomment this to debug usage statistics of the arena blocks.
+ // PrintUsageInfo();
+
+ for (Block* list : GetLists()) {
+ while (list != nullptr) {
+ Block* b = list;
+ list = list->next;
+ b->VisitBlock(DestroyVisitor{});
+ b->Destroy();
+ }
+ }
+ }
+
+
+ // This function exists for debugging only.
+ // It can be called from the destructor to dump some info in the tests to
+ // inspect the usage of the arena.
+ void PrintUsageInfo() const {
+ const auto print_histogram = [](Block* b, int size) {
+ std::map<uint32_t, uint32_t> unused_space_count;
+ int count = 0;
+ for (; b != nullptr; b = b->next) {
+ ++unused_space_count[b->space_left()];
+ ++count;
+ }
+ if (size > 0) {
+ fprintf(stderr, " Blocks `At least %d`", size);
+ } else {
+ fprintf(stderr, " Blocks `full`");
+ }
+ fprintf(stderr, ": %d blocks.\n", count);
+ for (auto p : unused_space_count) {
+ fprintf(stderr, " space=%4u, count=%3u\n", p.first, p.second);
+ }
+ };
+
+ fprintf(stderr, "TableArena unused space histogram:\n");
+ fprintf(stderr, " Current: %u\n",
+ current_ != nullptr ? current_->space_left() : 0);
+ print_histogram(full_blocks_, 0);
+ for (size_t i = 0; i < kSmallSizes.size(); ++i) {
+ print_histogram(small_size_blocks_[i], kSmallSizes[i]);
+ }
+ }
+
+ // Current allocation count.
+ // This can be used for checkpointing.
+ size_t num_allocations() const { return num_allocations_; }
+
+ // Rollback the latest allocations until we reach back to `checkpoint`
+ // num_allocations.
+ void RollbackTo(size_t checkpoint) {
+ while (num_allocations_ > checkpoint) {
+ GOOGLE_DCHECK(!rollback_info_.empty());
+ auto& info = rollback_info_.back();
+ Block* b = info.block;
+
+ VisitAlloc(b->data(), &b->start_offset, &b->end_offset, DestroyVisitor{},
+ KnownTypes{});
+ if (--info.count == 0) {
+ rollback_info_.pop_back();
+ }
+ --num_allocations_;
+ }
+
+ // Reconstruct the lists and destroy empty blocks.
+ auto lists = GetLists();
+ current_ = full_blocks_ = nullptr;
+ small_size_blocks_.fill(nullptr);
+
+ for (Block* list : lists) {
+ while (list != nullptr) {
+ Block* b = list;
+ list = list->next;
+
+ if (b->start_offset == 0) {
+ // This is empty, free it.
+ b->Destroy();
+ } else {
+ RelocateToUsedList(b);
+ }
+ }
+ }
+ }
+
+ // Clear all rollback information. Reduces memory usage.
+ // Trying to rollback past num_allocations() is now impossible.
+ void ClearRollbackData() {
+ rollback_info_.clear();
+ rollback_info_.shrink_to_fit();
+ }
+
+ private:
+ static constexpr size_t RoundUp(size_t n) { return (n + 7) & ~7; }
+
+ using Tag = unsigned char;
+
+ void* AllocRawInternal(uint32_t size, Tag tag) {
+ GOOGLE_DCHECK_GT(size, 0);
+ size = RoundUp(size);
+
+ Block* to_relocate = nullptr;
+ Block* to_use = nullptr;
+
+ for (size_t i = 0; i < kSmallSizes.size(); ++i) {
+ if (small_size_blocks_[i] != nullptr && size <= kSmallSizes[i]) {
+ to_use = to_relocate = PopBlock(small_size_blocks_[i]);
+ break;
+ }
+ }
+
+ if (to_relocate != nullptr) {
+ // We found one in the loop.
+ } else if (current_ != nullptr && size + 1 <= current_->space_left()) {
+ to_use = current_;
+ } else {
+ // No space left anywhere, make a new block.
+ to_relocate = current_;
+ // For now we hardcode the size to one page. Note that the maximum we can
+ // allocate in the block according to the limits of Tag is less than 2k,
+ // so this can fit anything that Tag can represent.
+ constexpr size_t kBlockSize = 4096;
+ to_use = current_ = ::new (::operator new(kBlockSize)) Block(kBlockSize);
+ GOOGLE_DCHECK_GE(current_->space_left(), size + 1);
+ }
+
+ ++num_allocations_;
+ if (!rollback_info_.empty() && rollback_info_.back().block == to_use) {
+ ++rollback_info_.back().count;
+ } else {
+ rollback_info_.push_back({to_use, 1});
+ }
+
+ void* p = to_use->Allocate(size, tag);
+ if (to_relocate != nullptr) {
+ RelocateToUsedList(to_relocate);
+ }
+ return p;
+ }
+
+ static void OperatorDelete(void* p, size_t s) {
+#if defined(__GXX_DELETE_WITH_SIZE__) || defined(__cpp_sized_deallocation)
+ ::operator delete(p, s);
+#else
+ ::operator delete(p);
+#endif
+ }
+
+ struct OutOfLineAlloc {
+ void* ptr;
+ uint32_t size;
+ };
+
+ template <typename... T>
+ struct TypeList {
+ static constexpr Tag kSize = static_cast<Tag>(sizeof...(T));
+ };
+
+ template <typename T, typename Visitor>
+ static void RunVisitor(char* p, uint16_t* start, Visitor visit) {
+ *start -= RoundUp(sizeof(T));
+ visit(reinterpret_cast<T*>(p + *start));
+ }
+
+ // Visit the allocation at the passed location.
+ // It updates start/end to be after the visited object.
+ // This allows visiting a whole block by calling the function in a loop.
+ template <typename Visitor, typename... T>
+ static void VisitAlloc(char* p, uint16_t* start, uint16_t* end, Visitor visit,
+ TypeList<T...>) {
+ const Tag tag = static_cast<Tag>(p[*end]);
+ if (tag >= kFirstRawTag) {
+ // Raw memory. Skip it.
+ *start -= TagToSize(tag);
+ } else {
+ using F = void (*)(char*, uint16_t*, Visitor);
+ static constexpr F kFuncs[] = {&RunVisitor<T, Visitor>...};
+ kFuncs[tag](p, start, visit);
+ }
+ ++*end;
+ }
+
+ template <typename U, typename... Ts>
+ static constexpr Tag TypeTag(TypeList<U, Ts...>) {
+ return 0;
+ }
+
+ template <
+ typename U, typename T, typename... Ts,
+ typename = typename std::enable_if<!std::is_same<U, T>::value>::type>
+ static constexpr Tag TypeTag(TypeList<T, Ts...>) {
+ return 1 + TypeTag<U>(TypeList<Ts...>{});
+ }
+
+ template <typename U>
+ static constexpr Tag TypeTag(TypeList<>) {
+ static_assert(std::is_trivially_destructible<U>::value, "");
+ return SizeToRawTag(sizeof(U));
+ }
+
+ using KnownTypes =
+ TypeList<OutOfLineAlloc, std::string,
+ // For name arrays
+ std::array<std::string, 2>, std::array<std::string, 3>,
+ std::array<std::string, 4>, std::array<std::string, 5>,
+ FileDescriptorTables, SourceCodeInfo, FileOptions,
+ MessageOptions, FieldOptions, ExtensionRangeOptions,
+ OneofOptions, EnumOptions, EnumValueOptions, ServiceOptions,
+ MethodOptions>;
+ static constexpr Tag kFirstRawTag = KnownTypes::kSize;
+
+
+ struct DestroyVisitor {
+ template <typename T>
+ void operator()(T* p) {
+ p->~T();
+ }
+ void operator()(OutOfLineAlloc* p) { OperatorDelete(p->ptr, p->size); }
+ };
+
+ static uint32_t SizeToRawTag(size_t n) { return (RoundUp(n) / 8) - 1; }
+
+ static uint32_t TagToSize(Tag tag) {
+ GOOGLE_DCHECK_GE(tag, kFirstRawTag);
+ return static_cast<uint32_t>(tag - kFirstRawTag + 1) * 8;
+ }
+
+ struct Block {
+ uint16_t start_offset;
+ uint16_t end_offset;
+ uint16_t capacity;
+ Block* next;
+
+ // `allocated_size` is the total size of the memory block allocated.
+ // The `Block` structure is constructed at the start and the rest of the
+ // memory is used as the payload of the `Block`.
+ explicit Block(uint32_t allocated_size) {
+ start_offset = 0;
+ end_offset = capacity =
+ reinterpret_cast<char*>(this) + allocated_size - data();
+ next = nullptr;
+ }
+
+ char* data() {
+ return reinterpret_cast<char*>(this) + RoundUp(sizeof(Block));
+ }
+
+ uint32_t memory_used() {
+ return data() + capacity - reinterpret_cast<char*>(this);
+ }
+ uint32_t space_left() const { return end_offset - start_offset; }
+
+ void* Allocate(uint32_t n, Tag tag) {
+ GOOGLE_DCHECK_LE(n + 1, space_left());
+ void* p = data() + start_offset;
+ start_offset += n;
+ data()[--end_offset] = tag;
+ return p;
+ }
+
+ void Destroy() { OperatorDelete(this, memory_used()); }
+
+ void PrependTo(Block*& list) {
+ next = list;
+ list = this;
+ }
+
+ template <typename Visitor>
+ void VisitBlock(Visitor visit) {
+ for (uint16_t s = start_offset, e = end_offset; s != 0;) {
+ VisitAlloc(data(), &s, &e, visit, KnownTypes{});
+ }
+ }
+ };
+
+ Block* PopBlock(Block*& list) {
+ Block* res = list;
+ list = list->next;
+ return res;
+ }
+
+ void RelocateToUsedList(Block* to_relocate) {
+ if (current_ == nullptr) {
+ current_ = to_relocate;
+ current_->next = nullptr;
+ return;
+ } else if (current_->space_left() < to_relocate->space_left()) {
+ std::swap(current_, to_relocate);
+ current_->next = nullptr;
+ }
+
+ for (int i = kSmallSizes.size(); --i >= 0;) {
+ if (to_relocate->space_left() >= 1 + kSmallSizes[i]) {
+ to_relocate->PrependTo(small_size_blocks_[i]);
+ return;
+ }
+ }
+
+ to_relocate->PrependTo(full_blocks_);
+ }
+
+ static constexpr std::array<uint8_t, 6> kSmallSizes = {
+ {// Sizes for pointer arrays.
+ 8, 16, 24, 32,
+ // Sizes for string arrays (for descriptor names).
+ // The most common array sizes are 2 and 3.
+ 2 * sizeof(std::string), 3 * sizeof(std::string)}};
+
+ // Helper function to iterate all lists.
+ std::array<Block*, 2 + kSmallSizes.size()> GetLists() const {
+ std::array<Block*, 2 + kSmallSizes.size()> res;
+ res[0] = current_;
+ res[1] = full_blocks_;
+ std::copy(small_size_blocks_.begin(), small_size_blocks_.end(), &res[2]);
+ return res;
+ }
+
+ Block* current_ = nullptr;
+ std::array<Block*, kSmallSizes.size()> small_size_blocks_ = {{}};
+ Block* full_blocks_ = nullptr;
+
+ size_t num_allocations_ = 0;
+ struct RollbackInfo {
+ Block* block;
+ size_t count;
+ };
+ std::vector<RollbackInfo> rollback_info_;
+};
+
+constexpr std::array<uint8_t, 6> TableArena::kSmallSizes;
+
+} // anonymous namespace
+
+// ===================================================================
+// DescriptorPool::Tables
+
+class DescriptorPool::Tables {
+ public:
+ Tables();
+ ~Tables();
+
+ // Record the current state of the tables to the stack of checkpoints.
+ // Each call to AddCheckpoint() must be paired with exactly one call to either
+ // ClearLastCheckpoint() or RollbackToLastCheckpoint().
+ //
+ // This is used when building files, since some kinds of validation errors
+ // cannot be detected until the file's descriptors have already been added to
+ // the tables.
+ //
+ // This supports recursive checkpoints, since building a file may trigger
+ // recursive building of other files. Note that recursive checkpoints are not
+ // normally necessary; explicit dependencies are built prior to checkpointing.
+ // So although we recursively build transitive imports, there is at most one
+ // checkpoint in the stack during dependency building.
+ //
+ // Recursive checkpoints only arise during cross-linking of the descriptors.
+ // Symbol references must be resolved, via DescriptorBuilder::FindSymbol and
+ // friends. If the pending file references an unknown symbol
+ // (e.g., it is not defined in the pending file's explicit dependencies), and
+ // the pool is using a fallback database, and that database contains a file
+ // defining that symbol, and that file has not yet been built by the pool,
+ // the pool builds the file during cross-linking, leading to another
+ // checkpoint.
+ void AddCheckpoint();
+
+ // Mark the last checkpoint as having cleared successfully, removing it from
+ // the stack. If the stack is empty, all pending symbols will be committed.
+ //
+ // Note that this does not guarantee that the symbols added since the last
+ // checkpoint won't be rolled back: if a checkpoint gets rolled back,
+ // everything past that point gets rolled back, including symbols added after
+ // checkpoints that were pushed onto the stack after it and marked as cleared.
+ void ClearLastCheckpoint();
+
+ // Roll back the Tables to the state of the checkpoint at the top of the
+ // stack, removing everything that was added after that point.
+ void RollbackToLastCheckpoint();
+
+ // The stack of files which are currently being built. Used to detect
+ // cyclic dependencies when loading files from a DescriptorDatabase. Not
+ // used when fallback_database_ == nullptr.
+ std::vector<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 an array of objects which will be reclaimed when the
+ // pool in destroyed. Again, destructors are never called.
+ template <typename Type>
+ Type* AllocateArray(int count);
+
+ // Allocate a string which will be destroyed when the pool is destroyed.
+ // The string is initialized to the given value for convenience.
+ const std::string* AllocateString(StringPiece value);
+
+ // Copy the input into a NUL terminated string whose lifetime is managed by
+ // the pool.
+ const char* Strdup(StringPiece value);
+
+ // Allocates an array of strings which will be destroyed when the pool is
+ // destroyed. The array is initialized with the input values.
+ template <typename... In>
+ const std::string* AllocateStringArray(In&&... values);
+
+ struct FieldNamesResult {
+ std::string* array;
+ int lowercase_index;
+ int camelcase_index;
+ int json_index;
+ };
+ // Allocate all 5 names of the field:
+ // name, full name, lowercase, camelcase and json.
+ // This function will dedup the strings when possible.
+ // The resulting array contains `name` at index 0, `full_name` at index 1 and
+ // the other 3 indices are specified in the result.
+ FieldNamesResult AllocateFieldNames(const std::string& name,
+ const std::string& scope,
+ const std::string* opt_json_name);
+
+ // Create an object that will be deleted when the pool is destroyed.
+ // The object is value initialized, and its destructor will be called if
+ // non-trivial.
+ template <typename Type>
+ Type* Create();
+
+ // Allocate a protocol message object. Some older versions of GCC have
+ // trouble understanding explicit template instantiations in some cases, so
+ // in those cases we have to pass a dummy pointer of the right type as the
+ // parameter instead of specifying the type explicitly.
+ template <typename Type>
+ Type* AllocateMessage(Type* dummy = nullptr);
+
+ // Allocate a FileDescriptorTables object.
+ FileDescriptorTables* AllocateFileTables();
+
+ private:
+ // All other memory allocated in the pool. Must be first as other objects can
+ // point into these.
+ TableArena arena_;
+
+ SymbolsByNameSet symbols_by_name_;
+ FilesByNameMap files_by_name_;
+ ExtensionsGroupedByDescriptorMap extensions_;
+
+ struct CheckPoint {
+ explicit CheckPoint(const Tables* tables)
+ : arena_before_checkpoint(tables->arena_.num_allocations()),
+ pending_symbols_before_checkpoint(
+ tables->symbols_after_checkpoint_.size()),
+ pending_files_before_checkpoint(
+ tables->files_after_checkpoint_.size()),
+ pending_extensions_before_checkpoint(
+ tables->extensions_after_checkpoint_.size()) {}
+ int arena_before_checkpoint;
+ int pending_symbols_before_checkpoint;
+ int pending_files_before_checkpoint;
+ int pending_extensions_before_checkpoint;
+ };
+ std::vector<CheckPoint> checkpoints_;
+ std::vector<const char*> symbols_after_checkpoint_;
+ std::vector<const char*> files_after_checkpoint_;
+ std::vector<DescriptorIntPair> extensions_after_checkpoint_;
+
+ // Allocate some bytes which will be reclaimed when the pool is
+ // destroyed.
+ void* AllocateBytes(int size);
+};
+
+// Contains tables specific to a particular file. These tables are not
+// modified once the file has been constructed, so they need not be
+// protected by a mutex. This makes operations that depend only on the
+// contents of a single file -- e.g. Descriptor::FindFieldByName() --
+// lock-free.
+//
+// For historical reasons, the definitions of the methods of
+// FileDescriptorTables and DescriptorPool::Tables are interleaved below.
+// These used to be a single class.
+class FileDescriptorTables {
+ public:
+ FileDescriptorTables();
+ ~FileDescriptorTables();
+
+ // Empty table, used with placeholder files.
+ inline static const FileDescriptorTables& GetEmptyInstance();
+
+ // -----------------------------------------------------------------
+ // Finding items.
+
+ // Returns a null Symbol (symbol.IsNull() is true) if not found.
+ inline Symbol FindNestedSymbol(const void* parent,
+ StringPiece name) const;
+
+ // These return nullptr if not found.
+ inline const FieldDescriptor* FindFieldByNumber(const Descriptor* parent,
+ int number) const;
+ inline const FieldDescriptor* FindFieldByLowercaseName(
+ const void* parent, StringPiece lowercase_name) const;
+ inline const FieldDescriptor* FindFieldByCamelcaseName(
+ const void* parent, StringPiece camelcase_name) const;
+ inline const EnumValueDescriptor* FindEnumValueByNumber(
+ const EnumDescriptor* parent, int number) const;
+ // This creates a new EnumValueDescriptor if not found, in a thread-safe way.
+ inline const EnumValueDescriptor* FindEnumValueByNumberCreatingIfUnknown(
+ const EnumDescriptor* parent, int number) const;
+
+ // -----------------------------------------------------------------
+ // Adding items.
+
+ // These add items to the corresponding tables. They return false if
+ // the key already exists in the table. For AddAliasUnderParent(), the
+ // string passed in must be one that was constructed using AllocateString(),
+ // as it will be used as a key in the symbols_by_parent_ map without copying.
+ bool AddAliasUnderParent(const void* parent, const std::string& name,
+ Symbol symbol);
+ bool AddFieldByNumber(FieldDescriptor* field);
+ bool AddEnumValueByNumber(EnumValueDescriptor* value);
+
+ // Adds the field to the lowercase_name and camelcase_name maps. Never
+ // fails because we allow duplicates; the first field by the name wins.
+ void AddFieldByStylizedNames(const FieldDescriptor* field);
+
+ // Populates p->first->locations_by_path_ from p->second.
+ // Unusual signature dictated by internal::call_once.
+ static void BuildLocationsByPath(
+ std::pair<const FileDescriptorTables*, const SourceCodeInfo*>* p);
+
+ // Returns the location denoted by the specified path through info,
+ // or nullptr if not found.
+ // The value of info must be that of the corresponding FileDescriptor.
+ // (Conceptually a pure function, but stateful as an optimisation.)
+ const SourceCodeInfo_Location* GetSourceLocation(
+ const std::vector<int>& path, const SourceCodeInfo* info) const;
+
+ // Must be called after BuildFileImpl(), even if the build failed and
+ // we are going to roll back to the last checkpoint.
+ void FinalizeTables();
+
+ private:
+ const void* FindParentForFieldsByMap(const FieldDescriptor* field) const;
+ static void FieldsByLowercaseNamesLazyInitStatic(
+ const FileDescriptorTables* tables);
+ void FieldsByLowercaseNamesLazyInitInternal() const;
+ static void FieldsByCamelcaseNamesLazyInitStatic(
+ const FileDescriptorTables* tables);
+ void FieldsByCamelcaseNamesLazyInitInternal() const;
+
+ SymbolsByParentSet symbols_by_parent_;
+ mutable FieldsByNameMap fields_by_lowercase_name_;
+ std::unique_ptr<FieldsByNameMap> fields_by_lowercase_name_tmp_;
+ mutable internal::once_flag fields_by_lowercase_name_once_;
+ mutable FieldsByNameMap fields_by_camelcase_name_;
+ std::unique_ptr<FieldsByNameMap> fields_by_camelcase_name_tmp_;
+ mutable internal::once_flag fields_by_camelcase_name_once_;
+ FieldsByNumberSet fields_by_number_; // Not including extensions.
+ EnumValuesByNumberSet enum_values_by_number_;
+ mutable EnumValuesByNumberSet unknown_enum_values_by_number_
+ PROTOBUF_GUARDED_BY(unknown_enum_values_mu_);
+
+ // Populated on first request to save space, hence constness games.
+ mutable internal::once_flag locations_by_path_once_;
+ mutable LocationsByPathMap locations_by_path_;
+
+ // Mutex to protect the unknown-enum-value map due to dynamic
+ // EnumValueDescriptor creation on unknown values.
+ mutable internal::WrappedMutex unknown_enum_values_mu_;
+};
+
+DescriptorPool::Tables::Tables() {
+ well_known_types_.insert({
+ {"google.protobuf.DoubleValue", Descriptor::WELLKNOWNTYPE_DOUBLEVALUE},
+ {"google.protobuf.FloatValue", Descriptor::WELLKNOWNTYPE_FLOATVALUE},
+ {"google.protobuf.Int64Value", Descriptor::WELLKNOWNTYPE_INT64VALUE},
+ {"google.protobuf.UInt64Value", Descriptor::WELLKNOWNTYPE_UINT64VALUE},
+ {"google.protobuf.Int32Value", Descriptor::WELLKNOWNTYPE_INT32VALUE},
+ {"google.protobuf.UInt32Value", Descriptor::WELLKNOWNTYPE_UINT32VALUE},
+ {"google.protobuf.StringValue", Descriptor::WELLKNOWNTYPE_STRINGVALUE},
+ {"google.protobuf.BytesValue", Descriptor::WELLKNOWNTYPE_BYTESVALUE},
+ {"google.protobuf.BoolValue", Descriptor::WELLKNOWNTYPE_BOOLVALUE},
+ {"google.protobuf.Any", Descriptor::WELLKNOWNTYPE_ANY},
+ {"google.protobuf.FieldMask", Descriptor::WELLKNOWNTYPE_FIELDMASK},
+ {"google.protobuf.Duration", Descriptor::WELLKNOWNTYPE_DURATION},
+ {"google.protobuf.Timestamp", Descriptor::WELLKNOWNTYPE_TIMESTAMP},
+ {"google.protobuf.Value", Descriptor::WELLKNOWNTYPE_VALUE},
+ {"google.protobuf.ListValue", Descriptor::WELLKNOWNTYPE_LISTVALUE},
+ {"google.protobuf.Struct", Descriptor::WELLKNOWNTYPE_STRUCT},
+ });
+}
+
+DescriptorPool::Tables::~Tables() { GOOGLE_DCHECK(checkpoints_.empty()); }
+
+FileDescriptorTables::FileDescriptorTables()
+ : fields_by_lowercase_name_tmp_(new FieldsByNameMap()),
+ fields_by_camelcase_name_tmp_(new FieldsByNameMap()) {}
+
+FileDescriptorTables::~FileDescriptorTables() {}
+
+inline const FileDescriptorTables& FileDescriptorTables::GetEmptyInstance() {
+ static auto file_descriptor_tables =
+ internal::OnShutdownDelete(new FileDescriptorTables());
+ return *file_descriptor_tables;
+}
+
+void DescriptorPool::Tables::AddCheckpoint() {
+ checkpoints_.push_back(CheckPoint(this));
+}
+
+void DescriptorPool::Tables::ClearLastCheckpoint() {
+ GOOGLE_DCHECK(!checkpoints_.empty());
+ checkpoints_.pop_back();
+ if (checkpoints_.empty()) {
+ // All checkpoints have been cleared: we can now commit all of the pending
+ // data.
+ symbols_after_checkpoint_.clear();
+ files_after_checkpoint_.clear();
+ extensions_after_checkpoint_.clear();
+ arena_.ClearRollbackData();
+ }
+}
+
+void DescriptorPool::Tables::RollbackToLastCheckpoint() {
+ GOOGLE_DCHECK(!checkpoints_.empty());
+ const CheckPoint& checkpoint = checkpoints_.back();
+
+ for (size_t i = checkpoint.pending_symbols_before_checkpoint;
+ i < symbols_after_checkpoint_.size(); i++) {
+ Symbol::QueryKey name;
+ name.name = symbols_after_checkpoint_[i];
+ symbols_by_name_.erase(Symbol(&name));
+ }
+ for (size_t i = checkpoint.pending_files_before_checkpoint;
+ i < files_after_checkpoint_.size(); i++) {
+ files_by_name_.erase(files_after_checkpoint_[i]);
+ }
+ for (size_t i = checkpoint.pending_extensions_before_checkpoint;
+ i < extensions_after_checkpoint_.size(); i++) {
+ extensions_.erase(extensions_after_checkpoint_[i]);
+ }
+
+ symbols_after_checkpoint_.resize(
+ checkpoint.pending_symbols_before_checkpoint);
+ files_after_checkpoint_.resize(checkpoint.pending_files_before_checkpoint);
+ extensions_after_checkpoint_.resize(
+ checkpoint.pending_extensions_before_checkpoint);
+
+ arena_.RollbackTo(checkpoint.arena_before_checkpoint);
+ checkpoints_.pop_back();
+}
+
+// -------------------------------------------------------------------
+
+inline Symbol DescriptorPool::Tables::FindSymbol(StringPiece key) const {
+ Symbol::QueryKey name;
+ name.name = key;
+ auto it = symbols_by_name_.find(Symbol(&name));
+ return it == symbols_by_name_.end() ? kNullSymbol : *it;
+}
+
+inline Symbol FileDescriptorTables::FindNestedSymbol(
+ const void* parent, StringPiece name) const {
+ Symbol::QueryKey query;
+ query.name = name;
+ query.parent = parent;
+ auto it = symbols_by_parent_.find(Symbol(&query));
+ return it == symbols_by_parent_.end() ? kNullSymbol : *it;
+}
+
+Symbol DescriptorPool::Tables::FindByNameHelper(const DescriptorPool* pool,
+ StringPiece name) {
+ if (pool->mutex_ != nullptr) {
+ // Fast path: the Symbol is already cached. This is just a hash lookup.
+ ReaderMutexLock lock(pool->mutex_);
+ if (known_bad_symbols_.empty() && known_bad_files_.empty()) {
+ Symbol result = FindSymbol(name);
+ if (!result.IsNull()) return result;
+ }
+ }
+ MutexLockMaybe lock(pool->mutex_);
+ if (pool->fallback_database_ != nullptr) {
+ known_bad_symbols_.clear();
+ known_bad_files_.clear();
+ }
+ Symbol result = FindSymbol(name);
+
+ if (result.IsNull() && pool->underlay_ != nullptr) {
+ // Symbol not found; check the underlay.
+ result = pool->underlay_->tables_->FindByNameHelper(pool->underlay_, name);
+ }
+
+ if (result.IsNull()) {
+ // Symbol still not found, so check fallback database.
+ if (pool->TryFindSymbolInFallbackDatabase(name)) {
+ result = FindSymbol(name);
+ }
+ }
+
+ return result;
+}
+
+inline const FileDescriptor* DescriptorPool::Tables::FindFile(
+ StringPiece key) const {
+ return FindPtrOrNull(files_by_name_, key);
+}
+
+inline const FieldDescriptor* FileDescriptorTables::FindFieldByNumber(
+ const Descriptor* parent, int number) const {
+ // If `number` is within the sequential range, just index into the parent
+ // without doing a table lookup.
+ if (parent != nullptr && //
+ 1 <= number && number <= parent->sequential_field_limit_) {
+ return parent->field(number - 1);
+ }
+
+ Symbol::QueryKey query;
+ query.parent = parent;
+ query.field_number = number;
+
+ auto it = fields_by_number_.find(Symbol(&query));
+ return it == fields_by_number_.end() ? nullptr : it->field_descriptor();
+}
+
+const void* FileDescriptorTables::FindParentForFieldsByMap(
+ const FieldDescriptor* field) const {
+ if (field->is_extension()) {
+ if (field->extension_scope() == nullptr) {
+ return field->file();
+ } else {
+ return field->extension_scope();
+ }
+ } else {
+ return field->containing_type();
+ }
+}
+
+void FileDescriptorTables::FieldsByLowercaseNamesLazyInitStatic(
+ const FileDescriptorTables* tables) {
+ tables->FieldsByLowercaseNamesLazyInitInternal();
+}
+
+void FileDescriptorTables::FieldsByLowercaseNamesLazyInitInternal() const {
+ for (Symbol symbol : symbols_by_parent_) {
+ const FieldDescriptor* field = symbol.field_descriptor();
+ if (!field) continue;
+ PointerStringPair lowercase_key(FindParentForFieldsByMap(field),
+ field->lowercase_name().c_str());
+ InsertIfNotPresent(&fields_by_lowercase_name_, lowercase_key, field);
+ }
+}
+
+inline const FieldDescriptor* FileDescriptorTables::FindFieldByLowercaseName(
+ const void* parent, StringPiece lowercase_name) const {
+ internal::call_once(
+ fields_by_lowercase_name_once_,
+ &FileDescriptorTables::FieldsByLowercaseNamesLazyInitStatic, this);
+ return FindPtrOrNull(fields_by_lowercase_name_,
+ PointerStringPair(parent, lowercase_name));
+}
+
+void FileDescriptorTables::FieldsByCamelcaseNamesLazyInitStatic(
+ const FileDescriptorTables* tables) {
+ tables->FieldsByCamelcaseNamesLazyInitInternal();
+}
+
+void FileDescriptorTables::FieldsByCamelcaseNamesLazyInitInternal() const {
+ for (Symbol symbol : symbols_by_parent_) {
+ const FieldDescriptor* field = symbol.field_descriptor();
+ if (!field) continue;
+ PointerStringPair camelcase_key(FindParentForFieldsByMap(field),
+ field->camelcase_name().c_str());
+ InsertIfNotPresent(&fields_by_camelcase_name_, camelcase_key, field);
+ }
+}
+
+inline const FieldDescriptor* FileDescriptorTables::FindFieldByCamelcaseName(
+ const void* parent, StringPiece camelcase_name) const {
+ internal::call_once(
+ fields_by_camelcase_name_once_,
+ FileDescriptorTables::FieldsByCamelcaseNamesLazyInitStatic, this);
+ return FindPtrOrNull(fields_by_camelcase_name_,
+ PointerStringPair(parent, camelcase_name));
+}
+
+inline const EnumValueDescriptor* FileDescriptorTables::FindEnumValueByNumber(
+ const EnumDescriptor* parent, int number) const {
+ // If `number` is within the sequential range, just index into the parent
+ // without doing a table lookup.
+ const int base = parent->value(0)->number();
+ if (base <= number &&
+ number <= static_cast<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(Symbol(&query));
+ return it == enum_values_by_number_.end() ? nullptr
+ : it->enum_value_descriptor();
+}
+
+inline const EnumValueDescriptor*
+FileDescriptorTables::FindEnumValueByNumberCreatingIfUnknown(
+ const EnumDescriptor* parent, int number) const {
+ // First try, with map of compiled-in values.
+ {
+ const auto* value = FindEnumValueByNumber(parent, number);
+ if (value != nullptr) {
+ return value;
+ }
+ }
+
+ Symbol::QueryKey query;
+ query.parent = parent;
+ query.field_number = number;
+
+ // Second try, with reader lock held on unknown enum values: common case.
+ {
+ ReaderMutexLock l(&unknown_enum_values_mu_);
+ auto it = unknown_enum_values_by_number_.find(Symbol(&query));
+ if (it != unknown_enum_values_by_number_.end() &&
+ it->enum_value_descriptor() != nullptr) {
+ return it->enum_value_descriptor();
+ }
+ }
+ // If not found, try again with writer lock held, and create new descriptor if
+ // necessary.
+ {
+ WriterMutexLock l(&unknown_enum_values_mu_);
+ auto it = unknown_enum_values_by_number_.find(Symbol(&query));
+ if (it != unknown_enum_values_by_number_.end() &&
+ it->enum_value_descriptor() != nullptr) {
+ return it->enum_value_descriptor();
+ }
+
+ // Create an EnumValueDescriptor dynamically. We don't insert it into the
+ // EnumDescriptor (it's not a part of the enum as originally defined), but
+ // we do insert it into the table so that we can return the same pointer
+ // later.
+ 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());
+ EnumValueDescriptor* result;
+ {
+ // Must lock the pool because we will do allocations in the shared arena.
+ MutexLockMaybe l2(pool->mutex_);
+ result = tables->Allocate<EnumValueDescriptor>();
+ result->all_names_ = tables->AllocateStringArray(
+ enum_value_name,
+ StrCat(parent->full_name(), ".", enum_value_name));
+ }
+ result->number_ = number;
+ result->type_ = parent;
+ result->options_ = &EnumValueOptions::default_instance();
+ unknown_enum_values_by_number_.insert(Symbol::EnumValue(result, 0));
+ return result;
+ }
+}
+
+inline const FieldDescriptor* DescriptorPool::Tables::FindExtension(
+ const Descriptor* extendee, int number) const {
+ return FindPtrOrNull(extensions_, std::make_pair(extendee, number));
+}
+
+inline void DescriptorPool::Tables::FindAllExtensions(
+ const Descriptor* extendee,
+ std::vector<const FieldDescriptor*>* out) const {
+ ExtensionsGroupedByDescriptorMap::const_iterator it =
+ extensions_.lower_bound(std::make_pair(extendee, 0));
+ for (; it != extensions_.end() && it->first.first == extendee; ++it) {
+ out->push_back(it->second);
+ }
+}
+
+// -------------------------------------------------------------------
+
+bool DescriptorPool::Tables::AddSymbol(const 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(full_name.c_str());
+ 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->name().c_str());
+ return true;
+ } else {
+ return false;
+ }
+}
+
+void FileDescriptorTables::FinalizeTables() {
+ // Clean up the temporary maps used by AddFieldByStylizedNames().
+ fields_by_lowercase_name_tmp_ = nullptr;
+ fields_by_camelcase_name_tmp_ = nullptr;
+}
+
+void FileDescriptorTables::AddFieldByStylizedNames(
+ const FieldDescriptor* field) {
+ const void* parent = FindParentForFieldsByMap(field);
+
+ // We want fields_by_{lower,camel}case_name_ to be lazily built, but
+ // cross-link order determines which entry will be present in the case of a
+ // conflict. So we use the temporary maps that get destroyed after
+ // BuildFileImpl() to detect the conflicts, and only store the conflicts in
+ // the map that will persist. We will then lazily populate the rest of the
+ // entries from fields_by_number_.
+
+ PointerStringPair lowercase_key(parent, field->lowercase_name().c_str());
+ if (!InsertIfNotPresent(fields_by_lowercase_name_tmp_.get(),
+ lowercase_key, field)) {
+ InsertIfNotPresent(
+ &fields_by_lowercase_name_, lowercase_key,
+ FindPtrOrNull(*fields_by_lowercase_name_tmp_, lowercase_key));
+ }
+
+ PointerStringPair camelcase_key(parent, field->camelcase_name().c_str());
+ if (!InsertIfNotPresent(fields_by_camelcase_name_tmp_.get(),
+ camelcase_key, field)) {
+ InsertIfNotPresent(
+ &fields_by_camelcase_name_, camelcase_key,
+ FindPtrOrNull(*fields_by_camelcase_name_tmp_, camelcase_key));
+ }
+}
+
+bool FileDescriptorTables::AddFieldByNumber(FieldDescriptor* field) {
+ // Skip fields that are at the start of the sequence.
+ if (field->containing_type() != nullptr && field->number() >= 1 &&
+ field->number() <= field->containing_type()->sequential_field_limit_) {
+ if (field->is_extension()) {
+ // Conflicts with the field that already exists in the sequential range.
+ return false;
+ }
+ // Only return true if the field at that index matches. Otherwise it
+ // conflicts with the existing field in the sequential range.
+ return field->containing_type()->field(field->number() - 1) == field;
+ }
+
+ return fields_by_number_.insert(Symbol(field)).second;
+}
+
+bool FileDescriptorTables::AddEnumValueByNumber(EnumValueDescriptor* value) {
+ // Skip values that are at the start of the sequence.
+ const int base = value->type()->value(0)->number();
+ if (base <= value->number() &&
+ value->number() <=
+ static_cast<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() {
+ return reinterpret_cast<Type*>(AllocateBytes(sizeof(Type)));
+}
+
+template <typename Type>
+Type* DescriptorPool::Tables::AllocateArray(int count) {
+ return reinterpret_cast<Type*>(AllocateBytes(sizeof(Type) * count));
+}
+
+const std::string* DescriptorPool::Tables::AllocateString(
+ StringPiece value) {
+ return arena_.Create<std::string>(value);
+}
+
+const char* DescriptorPool::Tables::Strdup(StringPiece value) {
+ char* p = AllocateArray<char>(static_cast<int>(value.size() + 1));
+ memcpy(p, value.data(), value.size());
+ p[value.size()] = 0;
+ return p;
+}
+
+template <typename... In>
+const std::string* DescriptorPool::Tables::AllocateStringArray(In&&... values) {
+ auto& array = *arena_.Create<std::array<std::string, sizeof...(In)>>();
+ array = {{std::string(std::forward<In>(values))...}};
+ return array.data();
+}
+
+DescriptorPool::Tables::FieldNamesResult
+DescriptorPool::Tables::AllocateFieldNames(const std::string& name,
+ const std::string& scope,
+ const std::string* opt_json_name) {
+ std::string lowercase_name = name;
+ LowerString(&lowercase_name);
+
+ std::string camelcase_name = ToCamelCase(name, /* lower_first = */ true);
+ std::string json_name;
+ if (opt_json_name != nullptr) {
+ json_name = *opt_json_name;
+ } else {
+ json_name = ToJsonName(name);
+ }
+
+ const bool lower_eq_name = lowercase_name == name;
+ const bool camel_eq_name = camelcase_name == name;
+ const bool json_eq_name = json_name == name;
+ const bool json_eq_camel = json_name == camelcase_name;
+
+ const int total_count = 2 + (lower_eq_name ? 0 : 1) +
+ (camel_eq_name ? 0 : 1) +
+ (json_eq_name || json_eq_camel ? 0 : 1);
+ FieldNamesResult result{nullptr, 0, 0, 0};
+ // We use std::array to allow handling of the destruction of the strings.
+ switch (total_count) {
+ case 2:
+ result.array = arena_.Create<std::array<std::string, 2>>()->data();
+ break;
+ case 3:
+ result.array = arena_.Create<std::array<std::string, 3>>()->data();
+ break;
+ case 4:
+ result.array = arena_.Create<std::array<std::string, 4>>()->data();
+ break;
+ case 5:
+ result.array = arena_.Create<std::array<std::string, 5>>()->data();
+ break;
+ }
+
+ result.array[0] = name;
+ if (scope.empty()) {
+ result.array[1] = name;
+ } else {
+ result.array[1] = StrCat(scope, ".", name);
+ }
+ int index = 2;
+ if (lower_eq_name) {
+ result.lowercase_index = 0;
+ } else {
+ result.lowercase_index = index;
+ result.array[index++] = std::move(lowercase_name);
+ }
+
+ if (camel_eq_name) {
+ result.camelcase_index = 0;
+ } else {
+ result.camelcase_index = index;
+ result.array[index++] = std::move(camelcase_name);
+ }
+
+ if (json_eq_name) {
+ result.json_index = 0;
+ } else if (json_eq_camel) {
+ result.json_index = result.camelcase_index;
+ } else {
+ result.json_index = index;
+ result.array[index] = std::move(json_name);
+ }
+
+ return result;
+}
+
+template <typename Type>
+Type* DescriptorPool::Tables::Create() {
+ return arena_.Create<Type>();
+}
+
+template <typename Type>
+Type* DescriptorPool::Tables::AllocateMessage(Type* /* dummy */) {
+ return arena_.Create<Type>();
+}
+
+FileDescriptorTables* DescriptorPool::Tables::AllocateFileTables() {
+ return arena_.Create<FileDescriptorTables>();
+}
+
+void* DescriptorPool::Tables::AllocateBytes(int size) {
+ if (size == 0) return nullptr;
+ return arena_.AllocateMemory(size);
+}
+
+void FileDescriptorTables::BuildLocationsByPath(
+ std::pair<const FileDescriptorTables*, const SourceCodeInfo*>* p) {
+ for (int i = 0, len = p->second->location_size(); i < len; ++i) {
+ const SourceCodeInfo_Location* loc = &p->second->location().Get(i);
+ p->first->locations_by_path_[Join(loc->path(), ",")] = loc;
+ }
+}
+
+const SourceCodeInfo_Location* FileDescriptorTables::GetSourceLocation(
+ const std::vector<int>& path, const SourceCodeInfo* info) const {
+ std::pair<const FileDescriptorTables*, const SourceCodeInfo*> p(
+ std::make_pair(this, info));
+ internal::call_once(locations_by_path_once_,
+ FileDescriptorTables::BuildLocationsByPath, &p);
+ return FindPtrOrNull(locations_by_path_, Join(path, ","));
+}
+
+// ===================================================================
+// DescriptorPool
+
+DescriptorPool::ErrorCollector::~ErrorCollector() {}
+
+DescriptorPool::DescriptorPool()
+ : mutex_(nullptr),
+ fallback_database_(nullptr),
+ default_error_collector_(nullptr),
+ underlay_(nullptr),
+ tables_(new Tables),
+ enforce_dependencies_(true),
+ lazily_build_dependencies_(false),
+ allow_unknown_(false),
+ enforce_weak_(false),
+ disallow_enforce_utf8_(false) {}
+
+DescriptorPool::DescriptorPool(DescriptorDatabase* fallback_database,
+ ErrorCollector* error_collector)
+ : mutex_(new internal::WrappedMutex),
+ fallback_database_(fallback_database),
+ default_error_collector_(error_collector),
+ underlay_(nullptr),
+ tables_(new Tables),
+ enforce_dependencies_(true),
+ lazily_build_dependencies_(false),
+ allow_unknown_(false),
+ enforce_weak_(false),
+ disallow_enforce_utf8_(false) {}
+
+DescriptorPool::DescriptorPool(const DescriptorPool* underlay)
+ : mutex_(nullptr),
+ fallback_database_(nullptr),
+ default_error_collector_(nullptr),
+ underlay_(underlay),
+ tables_(new Tables),
+ enforce_dependencies_(true),
+ lazily_build_dependencies_(false),
+ allow_unknown_(false),
+ enforce_weak_(false),
+ disallow_enforce_utf8_(false) {}
+
+DescriptorPool::~DescriptorPool() {
+ if (mutex_ != nullptr) delete mutex_;
+}
+
+// DescriptorPool::BuildFile() defined later.
+// DescriptorPool::BuildFileCollectingErrors() defined later.
+
+void DescriptorPool::InternalDontEnforceDependencies() {
+ enforce_dependencies_ = false;
+}
+
+void DescriptorPool::AddUnusedImportTrackFile(ConstStringParam file_name,
+ bool is_error) {
+ unused_import_track_files_[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.type() != Symbol::PACKAGE) {
+ return true;
+ }
+ }
+ if (underlay_ != nullptr) {
+ // Check to see if any prefix of this symbol exists in the underlay.
+ return underlay_->IsSubSymbolOfBuiltType(name);
+ }
+ return false;
+}
+
+bool DescriptorPool::TryFindSymbolInFallbackDatabase(
+ StringPiece name) const {
+ if (fallback_database_ == nullptr) return false;
+
+ auto name_string = 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);
+
+ 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_;
+
+ // 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_;
+
+ 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.qux.corge") makes
+ // the following calls, returning the first non-null result:
+ // FindSymbol("baz.qux.foo.bar"), FindSymbol("baz.foo.bar"),
+ // FindSymbol("foo.bar"). If AllowUnknownDependencies() has been called
+ // on the DescriptorPool, this will generate a placeholder type if
+ // the name is not found (unless the name itself is malformed). The
+ // placeholder_type parameter indicates what kind of placeholder should be
+ // constructed in this case. The resolve_mode parameter determines whether
+ // any symbol is returned, or only symbols that are types. Note, however,
+ // that LookupSymbol may still return a non-type symbol in LOOKUP_TYPES mode,
+ // if it believes that's all it could refer to. The caller should always
+ // check that it receives the type of symbol it was expecting.
+ enum ResolveMode { LOOKUP_ALL, LOOKUP_TYPES };
+ Symbol LookupSymbol(const 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);
+
+ // Used by BUILD_ARRAY macro (below) to avoid having to have the type
+ // specified as a macro parameter.
+ template <typename Type>
+ inline void AllocateArray(int size, Type** output) {
+ *output = tables_->AllocateArray<Type>(size);
+ }
+
+ // Allocates a copy of orig_options in tables_ and stores it in the
+ // descriptor. Remembers its uninterpreted options, to be interpreted
+ // later. DescriptorT must be one of the Descriptor messages from
+ // descriptor.proto.
+ template <class DescriptorT>
+ void AllocateOptions(const typename DescriptorT::OptionsType& orig_options,
+ DescriptorT* descriptor, int options_field_tag,
+ const std::string& option_name);
+ // Specialization for FileOptions.
+ void AllocateOptions(const FileOptions& orig_options,
+ FileDescriptor* descriptor);
+
+ // Implementation for AllocateOptions(). Don't call this directly.
+ template <class DescriptorT>
+ void AllocateOptionsImpl(
+ const 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);
+
+ // 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);
+
+ // These methods all have the same signature for the sake of the BUILD_ARRAY
+ // macro, below.
+ void BuildMessage(const DescriptorProto& proto, const Descriptor* parent,
+ Descriptor* result);
+ void BuildFieldOrExtension(const FieldDescriptorProto& proto,
+ Descriptor* parent, FieldDescriptor* result,
+ bool is_extension);
+ void BuildField(const FieldDescriptorProto& proto, Descriptor* parent,
+ FieldDescriptor* result) {
+ BuildFieldOrExtension(proto, parent, result, false);
+ }
+ void BuildExtension(const FieldDescriptorProto& proto, Descriptor* parent,
+ FieldDescriptor* result) {
+ BuildFieldOrExtension(proto, parent, result, true);
+ }
+ void BuildExtensionRange(const DescriptorProto::ExtensionRange& proto,
+ const Descriptor* parent,
+ Descriptor::ExtensionRange* result);
+ void BuildReservedRange(const DescriptorProto::ReservedRange& proto,
+ const Descriptor* parent,
+ Descriptor::ReservedRange* result);
+ void BuildReservedRange(const EnumDescriptorProto::EnumReservedRange& proto,
+ const EnumDescriptor* parent,
+ EnumDescriptor::ReservedRange* result);
+ void BuildOneof(const OneofDescriptorProto& proto, Descriptor* parent,
+ OneofDescriptor* result);
+ void CheckEnumValueUniqueness(const EnumDescriptorProto& proto,
+ const EnumDescriptor* result);
+ void BuildEnum(const EnumDescriptorProto& proto, const Descriptor* parent,
+ EnumDescriptor* result);
+ void BuildEnumValue(const EnumValueDescriptorProto& proto,
+ const EnumDescriptor* parent,
+ EnumValueDescriptor* result);
+ void BuildService(const ServiceDescriptorProto& proto, const void* dummy,
+ ServiceDescriptor* result);
+ void BuildMethod(const MethodDescriptorProto& proto,
+ const ServiceDescriptor* parent, MethodDescriptor* result);
+
+ void LogUnusedDependency(const FileDescriptorProto& proto,
+ const FileDescriptor* result);
+
+ // Must be run only after building.
+ //
+ // NOTE: Options will not be available during cross-linking, as they
+ // have not yet been interpreted. Defer any handling of options to the
+ // Validate*Options methods.
+ void CrossLinkFile(FileDescriptor* file, const FileDescriptorProto& proto);
+ void CrossLinkMessage(Descriptor* message, const DescriptorProto& proto);
+ void CrossLinkField(FieldDescriptor* field,
+ const FieldDescriptorProto& proto);
+ void CrossLinkExtensionRange(Descriptor::ExtensionRange* range,
+ const DescriptorProto::ExtensionRange& proto);
+ void CrossLinkEnum(EnumDescriptor* enum_type,
+ const EnumDescriptorProto& proto);
+ void CrossLinkEnumValue(EnumValueDescriptor* enum_value,
+ const EnumValueDescriptorProto& proto);
+ void CrossLinkService(ServiceDescriptor* service,
+ const ServiceDescriptorProto& proto);
+ void CrossLinkMethod(MethodDescriptor* method,
+ const MethodDescriptorProto& proto);
+
+ // Must be run only after cross-linking.
+ void InterpretOptions();
+
+ // A helper class for interpreting options.
+ class OptionInterpreter {
+ public:
+ // Creates an interpreter that operates in the context of the pool of the
+ // specified builder, which must not be nullptr. We don't take ownership of
+ // the builder.
+ explicit OptionInterpreter(DescriptorBuilder* builder);
+
+ ~OptionInterpreter();
+
+ // Interprets the uninterpreted options in the specified Options message.
+ // On error, calls AddError() on the underlying builder and returns false.
+ // Otherwise returns true.
+ bool InterpretOptions(OptionsToInterpret* options_to_interpret);
+
+ // Updates the given source code info by re-writing uninterpreted option
+ // locations to refer to the corresponding interpreted option.
+ void UpdateSourceCodeInfo(SourceCodeInfo* info);
+
+ class AggregateOptionFinder;
+
+ private:
+ // Interprets uninterpreted_option_ on the specified message, which
+ // must be the mutable copy of the original options message to which
+ // uninterpreted_option_ belongs. The given src_path is the source
+ // location path to the uninterpreted option, and options_path is the
+ // source location path to the options message. The location paths are
+ // recorded and then used in UpdateSourceCodeInfo.
+ bool InterpretSingleOption(Message* options,
+ const std::vector<int>& src_path,
+ const std::vector<int>& options_path);
+
+ // Adds the uninterpreted_option to the given options message verbatim.
+ // Used when AllowUnknownDependencies() is in effect and we can't find
+ // the option's definition.
+ void AddWithoutInterpreting(const UninterpretedOption& uninterpreted_option,
+ Message* options);
+
+ // A recursive helper function that drills into the intermediate fields
+ // in unknown_fields to check if field innermost_field is set on the
+ // innermost message. Returns false and sets an error if so.
+ bool ExamineIfOptionIsSet(
+ std::vector<const FieldDescriptor*>::const_iterator
+ intermediate_fields_iter,
+ std::vector<const FieldDescriptor*>::const_iterator
+ intermediate_fields_end,
+ const FieldDescriptor* innermost_field,
+ const 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.type() == Symbol::PACKAGE) {
+ // Arg, this is overcomplicated. The symbol is a package name. It could
+ // be that the package was defined in multiple files. result.GetFile()
+ // returns the first file we saw that used this package. We've determined
+ // that that file is not a direct dependency of the file we are currently
+ // building, but it could be that some other file which *is* a direct
+ // dependency also defines the same package. We can't really rule out this
+ // symbol unless none of the dependencies define it.
+ if (IsInPackage(file_, name)) return result;
+ for (std::set<const FileDescriptor*>::const_iterator it =
+ dependencies_.begin();
+ it != dependencies_.end(); ++it) {
+ // Note: A dependency may be nullptr if it was not found or had errors.
+ if (*it != nullptr && IsInPackage(*it, name)) return result;
+ }
+ }
+
+ possible_undeclared_dependency_ = file;
+ possible_undeclared_dependency_name_ = name;
+ return kNullSymbol;
+}
+
+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 kNullSymbol;
+ if (name[0] == '.') {
+ // Fully-qualified.
+ placeholder_full_name = name.substr(1);
+ } else {
+ placeholder_full_name = name;
+ }
+
+ std::string::size_type dotpos = placeholder_full_name.find_last_of('.');
+ if (dotpos != std::string::npos) {
+ placeholder_package =
+ tables_->AllocateString(placeholder_full_name.substr(0, dotpos));
+ placeholder_name = placeholder_full_name.substr(dotpos + 1);
+ } else {
+ placeholder_package = &internal::GetEmptyString();
+ placeholder_name = placeholder_full_name;
+ }
+
+ // Create the placeholders.
+ FileDescriptor* placeholder_file = NewPlaceholderFileWithMutexHeld(
+ StrCat(placeholder_full_name, ".placeholder.proto"));
+ placeholder_file->package_ = placeholder_package;
+
+ if (placeholder_type == PLACEHOLDER_ENUM) {
+ placeholder_file->enum_type_count_ = 1;
+ placeholder_file->enum_types_ = tables_->AllocateArray<EnumDescriptor>(1);
+
+ EnumDescriptor* placeholder_enum = &placeholder_file->enum_types_[0];
+ memset(static_cast<void*>(placeholder_enum), 0, sizeof(*placeholder_enum));
+
+ placeholder_enum->all_names_ =
+ tables_->AllocateStringArray(placeholder_name, placeholder_full_name);
+ placeholder_enum->file_ = placeholder_file;
+ placeholder_enum->options_ = &EnumOptions::default_instance();
+ placeholder_enum->is_placeholder_ = true;
+ placeholder_enum->is_unqualified_placeholder_ = (name[0] != '.');
+
+ // Enums must have at least one value.
+ placeholder_enum->value_count_ = 1;
+ placeholder_enum->values_ = tables_->AllocateArray<EnumValueDescriptor>(1);
+ // Disable fast-path lookup for this enum.
+ placeholder_enum->sequential_value_limit_ = -1;
+
+ EnumValueDescriptor* placeholder_value = &placeholder_enum->values_[0];
+ memset(static_cast<void*>(placeholder_value), 0,
+ sizeof(*placeholder_value));
+
+ // Note that enum value names are siblings of their type, not children.
+ placeholder_value->all_names_ = tables_->AllocateStringArray(
+ "PLACEHOLDER_VALUE", placeholder_package->empty()
+ ? "PLACEHOLDER_VALUE"
+ : *placeholder_package + ".PLACEHOLDER_VALUE");
+
+ placeholder_value->number_ = 0;
+ placeholder_value->type_ = placeholder_enum;
+ placeholder_value->options_ = &EnumValueOptions::default_instance();
+
+ return Symbol(placeholder_enum);
+ } else {
+ placeholder_file->message_type_count_ = 1;
+ placeholder_file->message_types_ = tables_->AllocateArray<Descriptor>(1);
+
+ Descriptor* placeholder_message = &placeholder_file->message_types_[0];
+ memset(static_cast<void*>(placeholder_message), 0,
+ sizeof(*placeholder_message));
+
+ placeholder_message->all_names_ =
+ tables_->AllocateStringArray(placeholder_name, placeholder_full_name);
+ placeholder_message->file_ = placeholder_file;
+ placeholder_message->options_ = &MessageOptions::default_instance();
+ placeholder_message->is_placeholder_ = true;
+ placeholder_message->is_unqualified_placeholder_ = (name[0] != '.');
+
+ if (placeholder_type == PLACEHOLDER_EXTENDABLE_MESSAGE) {
+ placeholder_message->extension_range_count_ = 1;
+ placeholder_message->extension_ranges_ =
+ tables_->AllocateArray<Descriptor::ExtensionRange>(1);
+ placeholder_message->extension_ranges_->start = 1;
+ // kMaxNumber + 1 because ExtensionRange::end is exclusive.
+ placeholder_message->extension_ranges_->end =
+ FieldDescriptor::kMaxNumber + 1;
+ placeholder_message->extension_ranges_->options_ = nullptr;
+ }
+
+ return Symbol(placeholder_message);
+ }
+}
+
+FileDescriptor* DescriptorPool::NewPlaceholderFile(
+ StringPiece name) const {
+ MutexLockMaybe lock(mutex_);
+ return NewPlaceholderFileWithMutexHeld(name);
+}
+
+FileDescriptor* DescriptorPool::NewPlaceholderFileWithMutexHeld(
+ StringPiece name) const {
+ if (mutex_) {
+ mutex_->AssertHeld();
+ }
+ FileDescriptor* placeholder = tables_->Allocate<FileDescriptor>();
+ memset(static_cast<void*>(placeholder), 0, sizeof(*placeholder));
+
+ placeholder->name_ = tables_->AllocateString(name);
+ placeholder->package_ = &internal::GetEmptyString();
+ placeholder->pool_ = this;
+ placeholder->options_ = &FileOptions::default_instance();
+ placeholder->tables_ = &FileDescriptorTables::GetEmptyInstance();
+ placeholder->source_code_info_ = &SourceCodeInfo::default_instance();
+ placeholder->is_placeholder_ = true;
+ placeholder->syntax_ = FileDescriptor::SYNTAX_UNKNOWN;
+ placeholder->finished_building_ = true;
+ // All other fields are zero or nullptr.
+
+ return placeholder;
+}
+
+bool DescriptorBuilder::AddSymbol(const 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()) {
+ auto* package = tables_->AllocateArray<Symbol::Package>(1);
+ // If the name is the package name, then it is already in the arena.
+ // If not, copy it there. It came from the call to AddPackage below.
+ package->name =
+ &name == &file->package() ? &name : tables_->AllocateString(name);
+ package->file = file;
+ tables_->AddSymbol(*package->name, Symbol(package));
+ // Also add parent package, if any.
+ 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.type() != Symbol::PACKAGE) {
+ // Symbol seems to have been defined in a different file.
+ AddError(name, proto, DescriptorPool::ErrorCollector::NAME,
+ "\"" + name +
+ "\" is already defined (as something other than "
+ "a package) in file \"" +
+ existing_symbol.GetFile()->name() + "\".");
+ }
+}
+
+void DescriptorBuilder::ValidateSymbolName(const 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.");
+ }
+ }
+ }
+}
+
+// -------------------------------------------------------------------
+
+// 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) {
+ std::vector<int> options_path;
+ descriptor->GetLocationPath(&options_path);
+ options_path.push_back(options_field_tag);
+ AllocateOptionsImpl(descriptor->full_name(), descriptor->full_name(),
+ orig_options, descriptor, options_path, option_name);
+}
+
+// We specialize for FileDescriptor.
+void DescriptorBuilder::AllocateOptions(const FileOptions& orig_options,
+ FileDescriptor* descriptor) {
+ std::vector<int> options_path;
+ options_path.push_back(FileDescriptorProto::kOptionsFieldNumber);
+ // We add the dummy token so that LookupSymbol does the right thing.
+ AllocateOptionsImpl(descriptor->package() + ".dummy", descriptor->name(),
+ orig_options, descriptor, options_path,
+ "google.protobuf.FileOptions");
+}
+
+template <class DescriptorT>
+void DescriptorBuilder::AllocateOptionsImpl(
+ const 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) {
+ // We need to use a dummy pointer to work around a bug in older versions of
+ // GCC. Otherwise, the following two lines could be replaced with:
+ // typename DescriptorT::OptionsType* options =
+ // tables_->AllocateMessage<typename DescriptorT::OptionsType>();
+ typename DescriptorT::OptionsType* const dummy = nullptr;
+ typename DescriptorT::OptionsType* options = tables_->AllocateMessage(dummy);
+
+ if (!orig_options.IsInitialized()) {
+ AddError(name_scope + "." + element_name, orig_options,
+ DescriptorPool::ErrorCollector::OPTION_NAME,
+ "Uninterpreted option is missing name or value.");
+ return;
+ }
+
+ // Avoid using MergeFrom()/CopyFrom() in this class to make it -fno-rtti
+ // friendly. Without RTTI, MergeFrom() and CopyFrom() will fallback to the
+ // reflection based method, which requires the Descriptor. However, we are in
+ // the middle of building the descriptors, thus the deadlock.
+ options->ParseFromString(orig_options.SerializeAsString());
+ descriptor->options_ = options;
+
+ // Don't add to options_to_interpret_ unless there were uninterpreted
+ // options. This not only avoids unnecessary work, but prevents a
+ // bootstrapping problem when building descriptors for descriptor.proto.
+ // descriptor.proto does not contain any uninterpreted options, but
+ // attempting to interpret options anyway will cause
+ // OptionsType::GetDescriptor() to be called which may then deadlock since
+ // we're still trying to build it.
+ if (options->uninterpreted_option_size() > 0) {
+ options_to_interpret_.push_back(OptionsToInterpret(
+ name_scope, element_name, options_path, &orig_options, options));
+ }
+
+ // If the custom option is in unknown fields, no need to interpret it.
+ // Remove the dependency file from unused_dependency.
+ const UnknownFieldSet& unknown_fields = orig_options.unknown_fields();
+ if (!unknown_fields.empty()) {
+ // Can not use options->GetDescriptor() which may case deadlock.
+ Symbol msg_symbol = tables_->FindSymbol(option_name);
+ if (msg_symbol.type() == Symbol::MESSAGE) {
+ for (int i = 0; i < unknown_fields.field_count(); ++i) {
+ assert_mutex_held(pool_);
+ const FieldDescriptor* field =
+ pool_->InternalFindExtensionByNumberNoLock(
+ msg_symbol.descriptor(), unknown_fields.field(i).number());
+ if (field) {
+ unused_dependency_.erase(field->file());
+ }
+ }
+ }
+ }
+}
+
+// A common pattern: We want to convert a repeated field in the descriptor
+// to an array of values, calling some method to build each value.
+#define BUILD_ARRAY(INPUT, OUTPUT, NAME, METHOD, PARENT) \
+ OUTPUT->NAME##_count_ = INPUT.NAME##_size(); \
+ AllocateArray(INPUT.NAME##_size(), &OUTPUT->NAME##s_); \
+ for (int i = 0; i < INPUT.NAME##_size(); i++) { \
+ METHOD(INPUT.NAME(i), PARENT, OUTPUT->NAME##s_ + i); \
+ }
+
+void DescriptorBuilder::AddRecursiveImportError(
+ const FileDescriptorProto& proto, int from_here) {
+ 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();
+}
+
+const FileDescriptor* DescriptorBuilder::BuildFile(
+ const FileDescriptorProto& proto) {
+ filename_ = proto.name();
+
+ // Check if the file already exists and is identical to the one being built.
+ // Note: This only works if the input is canonical -- that is, it
+ // fully-qualifies all type names, has no UninterpretedOptions, etc.
+ // This is fine, because this idempotency "feature" really only exists to
+ // accommodate one hack in the proto1->proto2 migration layer.
+ const FileDescriptor* existing_file = tables_->FindFile(filename_);
+ if (existing_file != nullptr) {
+ // File already in pool. Compare the existing one to the input.
+ if (ExistingFileMatchesProto(existing_file, proto)) {
+ // They're identical. Return the existing descriptor.
+ return existing_file;
+ }
+
+ // Not a match. The error will be detected and handled later.
+ }
+
+ // Check to see if this file is already on the pending files list.
+ // TODO(kenton): Allow recursive imports? It may not work with some
+ // (most?) programming languages. E.g., in C++, a forward declaration
+ // of a type is not sufficient to allow it to be used even in a
+ // generated header file due to inlining. This could perhaps be
+ // worked around using tricks involving inserting #include statements
+ // mid-file, but that's pretty ugly, and I'm pretty sure there are
+ // some languages out there that do not allow recursive dependencies
+ // at all.
+ for (size_t i = 0; i < tables_->pending_files_.size(); i++) {
+ if (tables_->pending_files_[i] == proto.name()) {
+ AddRecursiveImportError(proto, i);
+ return nullptr;
+ }
+ }
+
+ // If we have a fallback_database_, and we aren't doing lazy import building,
+ // attempt to load all dependencies now, before checkpointing tables_. This
+ // avoids confusion with recursive checkpoints.
+ if (!pool_->lazily_build_dependencies_) {
+ if (pool_->fallback_database_ != nullptr) {
+ tables_->pending_files_.push_back(proto.name());
+ for (int i = 0; i < proto.dependency_size(); i++) {
+ if (tables_->FindFile(proto.dependency(i)) == nullptr &&
+ (pool_->underlay_ == nullptr ||
+ pool_->underlay_->FindFileByName(proto.dependency(i)) ==
+ nullptr)) {
+ // We don't care what this returns since we'll find out below anyway.
+ pool_->TryFindFileInFallbackDatabase(proto.dependency(i));
+ }
+ }
+ tables_->pending_files_.pop_back();
+ }
+ }
+
+ // Checkpoint the tables so that we can roll back if something goes wrong.
+ tables_->AddCheckpoint();
+
+ FileDescriptor* result = BuildFileImpl(proto);
+
+ file_tables_->FinalizeTables();
+ if (result) {
+ tables_->ClearLastCheckpoint();
+ result->finished_building_ = true;
+ } else {
+ tables_->RollbackToLastCheckpoint();
+ }
+
+ return result;
+}
+
+FileDescriptor* DescriptorBuilder::BuildFileImpl(
+ const FileDescriptorProto& proto) {
+ FileDescriptor* result = tables_->Allocate<FileDescriptor>();
+ file_ = result;
+
+ result->is_placeholder_ = false;
+ result->finished_building_ = false;
+ SourceCodeInfo* info = nullptr;
+ if (proto.has_source_code_info()) {
+ info = tables_->AllocateMessage<SourceCodeInfo>();
+ info->CopyFrom(proto.source_code_info());
+ result->source_code_info_ = info;
+ } else {
+ result->source_code_info_ = &SourceCodeInfo::default_instance();
+ }
+
+ file_tables_ = tables_->AllocateFileTables();
+ file_->tables_ = file_tables_;
+
+ if (!proto.has_name()) {
+ AddError("", proto, DescriptorPool::ErrorCollector::OTHER,
+ "Missing field: FileDescriptorProto.name.");
+ }
+
+ // TODO(liujisi): Report error when the syntax is empty after all the protos
+ // have added the syntax statement.
+ if (proto.syntax().empty() || proto.syntax() == "proto2") {
+ file_->syntax_ = FileDescriptor::SYNTAX_PROTO2;
+ } else if (proto.syntax() == "proto3") {
+ file_->syntax_ = FileDescriptor::SYNTAX_PROTO3;
+ } else {
+ file_->syntax_ = FileDescriptor::SYNTAX_UNKNOWN;
+ AddError(proto.name(), proto, DescriptorPool::ErrorCollector::OTHER,
+ "Unrecognized syntax: " + proto.syntax());
+ }
+
+ result->name_ = tables_->AllocateString(proto.name());
+ if (proto.has_package()) {
+ result->package_ = tables_->AllocateString(proto.package());
+ } else {
+ // We cannot rely on proto.package() returning a valid string if
+ // proto.has_package() is false, because we might be running at static
+ // initialization time, in which case default values have not yet been
+ // initialized.
+ result->package_ = tables_->AllocateString("");
+ }
+ result->pool_ = pool_;
+
+ if (result->name().find('\0') != 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()) {
+ 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_ =
+ tables_->AllocateArray<const FileDescriptor*>(proto.dependency_size());
+ result->dependencies_once_ = nullptr;
+ unused_dependency_.clear();
+ std::set<int> weak_deps;
+ for (int i = 0; i < proto.weak_dependency_size(); ++i) {
+ weak_deps.insert(proto.weak_dependency(i));
+ }
+ for (int i = 0; i < proto.dependency_size(); i++) {
+ if (!seen_dependencies.insert(proto.dependency(i)).second) {
+ AddTwiceListedError(proto, i);
+ }
+
+ const FileDescriptor* dependency = tables_->FindFile(proto.dependency(i));
+ if (dependency == nullptr && pool_->underlay_ != nullptr) {
+ dependency = pool_->underlay_->FindFileByName(proto.dependency(i));
+ }
+
+ if (dependency == result) {
+ // Recursive import. dependency/result is not fully initialized, and it's
+ // dangerous to try to do anything with it. The recursive import error
+ // will be detected and reported in DescriptorBuilder::BuildFile().
+ return nullptr;
+ }
+
+ if (dependency == nullptr) {
+ if (!pool_->lazily_build_dependencies_) {
+ if (pool_->allow_unknown_ ||
+ (!pool_->enforce_weak_ && weak_deps.find(i) != weak_deps.end())) {
+ dependency =
+ pool_->NewPlaceholderFileWithMutexHeld(proto.dependency(i));
+ } else {
+ AddImportError(proto, i);
+ }
+ }
+ } else {
+ // Add to unused_dependency_ to track unused imported files.
+ // Note: do not track unused imported files for public import.
+ if (pool_->enforce_dependencies_ &&
+ (pool_->unused_import_track_files_.find(proto.name()) !=
+ pool_->unused_import_track_files_.end()) &&
+ (dependency->public_dependency_count() == 0)) {
+ unused_dependency_.insert(dependency);
+ }
+ }
+
+ result->dependencies_[i] = dependency;
+ if (pool_->lazily_build_dependencies_ && !dependency) {
+ if (result->dependencies_once_ == nullptr) {
+ result->dependencies_once_ =
+ tables_->Create<FileDescriptor::LazyInitData>();
+ result->dependencies_once_->dependencies_names =
+ tables_->AllocateArray<const char*>(proto.dependency_size());
+ if (proto.dependency_size() > 0) {
+ std::fill_n(result->dependencies_once_->dependencies_names,
+ proto.dependency_size(), nullptr);
+ }
+ }
+
+ result->dependencies_once_->dependencies_names[i] =
+ tables_->Strdup(proto.dependency(i));
+ }
+ }
+
+ // Check public dependencies.
+ int public_dependency_count = 0;
+ result->public_dependencies_ =
+ tables_->AllocateArray<int>(proto.public_dependency_size());
+ for (int i = 0; i < proto.public_dependency_size(); i++) {
+ // Only put valid public dependency indexes.
+ int index = proto.public_dependency(i);
+ if (index >= 0 && index < proto.dependency_size()) {
+ result->public_dependencies_[public_dependency_count++] = index;
+ // Do not track unused imported files for public import.
+ // Calling dependency(i) builds that file when doing lazy imports,
+ // need to avoid doing this. Unused dependency detection isn't done
+ // when building lazily, anyways.
+ if (!pool_->lazily_build_dependencies_) {
+ unused_dependency_.erase(result->dependency(index));
+ }
+ } else {
+ AddError(proto.name(), proto, DescriptorPool::ErrorCollector::OTHER,
+ "Invalid public dependency index.");
+ }
+ }
+ result->public_dependency_count_ = public_dependency_count;
+
+ // Build dependency set
+ dependencies_.clear();
+ // We don't/can't do proper dependency error checking when
+ // lazily_build_dependencies_, and calling dependency(i) will force
+ // a dependency to be built, which we don't want.
+ if (!pool_->lazily_build_dependencies_) {
+ for (int i = 0; i < result->dependency_count(); i++) {
+ RecordPublicDependencies(result->dependency(i));
+ }
+ }
+
+ // Check weak dependencies.
+ int weak_dependency_count = 0;
+ result->weak_dependencies_ =
+ tables_->AllocateArray<int>(proto.weak_dependency_size());
+ for (int i = 0; i < proto.weak_dependency_size(); i++) {
+ int index = proto.weak_dependency(i);
+ if (index >= 0 && index < proto.dependency_size()) {
+ result->weak_dependencies_[weak_dependency_count++] = index;
+ } else {
+ AddError(proto.name(), proto, DescriptorPool::ErrorCollector::OTHER,
+ "Invalid weak dependency index.");
+ }
+ }
+ result->weak_dependency_count_ = weak_dependency_count;
+
+ // Convert children.
+ BUILD_ARRAY(proto, result, message_type, BuildMessage, nullptr);
+ BUILD_ARRAY(proto, result, enum_type, BuildEnum, nullptr);
+ BUILD_ARRAY(proto, result, service, BuildService, nullptr);
+ BUILD_ARRAY(proto, result, extension, BuildExtension, nullptr);
+
+ // Copy options.
+ result->options_ = nullptr; // Set to default_instance later if necessary.
+ if (proto.has_options()) {
+ AllocateOptions(proto.options(), result);
+ }
+
+ // Note that the following steps must occur in exactly the specified order.
+
+ // Cross-link.
+ CrossLinkFile(result, proto);
+
+ // Interpret any remaining uninterpreted options gathered into
+ // options_to_interpret_ during descriptor building. Cross-linking has made
+ // extension options known, so all interpretations should now succeed.
+ if (!had_errors_) {
+ OptionInterpreter option_interpreter(this);
+ for (std::vector<OptionsToInterpret>::iterator iter =
+ options_to_interpret_.begin();
+ iter != options_to_interpret_.end(); ++iter) {
+ option_interpreter.InterpretOptions(&(*iter));
+ }
+ options_to_interpret_.clear();
+ if (info != nullptr) {
+ option_interpreter.UpdateSourceCodeInfo(info);
+ }
+ }
+
+ // Validate options. See comments at InternalSetLazilyBuildDependencies about
+ // error checking and lazy import building.
+ if (!had_errors_ && !pool_->lazily_build_dependencies_) {
+ ValidateFileOptions(result, proto);
+ }
+
+ // Additional naming conflict check for map entry types. Only need to check
+ // this if there are already errors.
+ if (had_errors_) {
+ for (int i = 0; i < proto.message_type_size(); ++i) {
+ DetectMapConflicts(result->message_type(i), proto.message_type(i));
+ }
+ }
+
+
+ // Again, see comments at InternalSetLazilyBuildDependencies about error
+ // checking. Also, don't log unused dependencies if there were previous
+ // errors, since the results might be inaccurate.
+ if (!had_errors_ && !unused_dependency_.empty() &&
+ !pool_->lazily_build_dependencies_) {
+ LogUnusedDependency(proto, result);
+ }
+
+ if (had_errors_) {
+ return nullptr;
+ } else {
+ return result;
+ }
+}
+
+
+const std::string* DescriptorBuilder::AllocateNameStrings(
+ const std::string& scope, const std::string& proto_name) {
+ if (scope.empty()) {
+ return tables_->AllocateStringArray(proto_name, proto_name);
+ } else {
+ return tables_->AllocateStringArray(proto_name,
+ StrCat(scope, ".", proto_name));
+ }
+}
+
+void DescriptorBuilder::BuildMessage(const DescriptorProto& proto,
+ const Descriptor* parent,
+ Descriptor* result) {
+ const std::string& scope =
+ (parent == nullptr) ? file_->package() : parent->full_name();
+ result->all_names_ = AllocateNameStrings(scope, proto.name());
+ ValidateSymbolName(proto.name(), result->full_name(), proto);
+
+ result->file_ = file_;
+ result->containing_type_ = parent;
+ result->is_placeholder_ = false;
+ result->is_unqualified_placeholder_ = false;
+ result->well_known_type_ = Descriptor::WELLKNOWNTYPE_UNSPECIFIED;
+
+ auto it = pool_->tables_->well_known_types_.find(result->full_name());
+ if (it != pool_->tables_->well_known_types_.end()) {
+ result->well_known_type_ = it->second;
+ }
+
+ // Calculate the continuous sequence of fields.
+ // These can be fast-path'd during lookup and don't need to be added to the
+ // tables.
+ // We use uint16_t to save space for sequential_field_limit_, so stop before
+ // overflowing it. Worst case, we are not taking full advantage on huge
+ // messages, but it is unlikely.
+ result->sequential_field_limit_ = 0;
+ for (int i = 0; i < std::numeric_limits<uint16_t>::max() &&
+ i < proto.field_size() && proto.field(i).number() == i + 1;
+ ++i) {
+ result->sequential_field_limit_ = i + 1;
+ }
+
+ // Build oneofs first so that fields and extension ranges can refer to them.
+ BUILD_ARRAY(proto, result, oneof_decl, BuildOneof, result);
+ BUILD_ARRAY(proto, result, field, BuildField, result);
+ BUILD_ARRAY(proto, result, nested_type, BuildMessage, result);
+ BUILD_ARRAY(proto, result, enum_type, BuildEnum, result);
+ BUILD_ARRAY(proto, result, extension_range, BuildExtensionRange, result);
+ BUILD_ARRAY(proto, result, extension, BuildExtension, result);
+ BUILD_ARRAY(proto, result, reserved_range, BuildReservedRange, result);
+
+ // Copy reserved names.
+ int reserved_name_count = proto.reserved_name_size();
+ result->reserved_name_count_ = reserved_name_count;
+ result->reserved_names_ =
+ tables_->AllocateArray<const std::string*>(reserved_name_count);
+ for (int i = 0; i < reserved_name_count; ++i) {
+ result->reserved_names_[i] =
+ tables_->AllocateString(proto.reserved_name(i));
+ }
+
+ // Copy options.
+ result->options_ = nullptr; // Set to default_instance later if necessary.
+ if (proto.has_options()) {
+ AllocateOptions(proto.options(), result,
+ DescriptorProto::kOptionsFieldNumber,
+ "google.protobuf.MessageOptions");
+ }
+
+ AddSymbol(result->full_name(), parent, result->name(), proto, Symbol(result));
+
+ for (int i = 0; i < proto.reserved_range_size(); i++) {
+ const DescriptorProto_ReservedRange& range1 = proto.reserved_range(i);
+ for (int j = i + 1; j < proto.reserved_range_size(); j++) {
+ const DescriptorProto_ReservedRange& range2 = proto.reserved_range(j);
+ if (range1.end() > range2.start() && range2.end() > range1.start()) {
+ AddError(result->full_name(), proto.reserved_range(i),
+ DescriptorPool::ErrorCollector::NUMBER,
+ strings::Substitute("Reserved range $0 to $1 overlaps with "
+ "already-defined range $2 to $3.",
+ range2.start(), range2.end() - 1,
+ range1.start(), range1.end() - 1));
+ }
+ }
+ }
+
+ HASH_SET<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) {
+ AddError(
+ field->full_name(), proto.extension_range(j),
+ DescriptorPool::ErrorCollector::NUMBER,
+ strings::Substitute(
+ "Extension range $0 to $1 includes field \"$2\" ($3).",
+ range->start, range->end - 1, field->name(), field->number()));
+ }
+ }
+ for (int j = 0; j < result->reserved_range_count(); j++) {
+ const Descriptor::ReservedRange* range = result->reserved_range(j);
+ if (range->start <= field->number() && field->number() < range->end) {
+ AddError(field->full_name(), proto.reserved_range(j),
+ DescriptorPool::ErrorCollector::NUMBER,
+ strings::Substitute("Field \"$0\" uses reserved number $1.",
+ field->name(), field->number()));
+ }
+ }
+ if (reserved_name_set.find(field->name()) != reserved_name_set.end()) {
+ AddError(
+ field->full_name(), proto.field(i),
+ DescriptorPool::ErrorCollector::NAME,
+ strings::Substitute("Field name \"$0\" is reserved.", field->name()));
+ }
+
+ }
+
+ // Check that extension ranges don't overlap and don't include
+ // reserved field numbers or names.
+ for (int i = 0; i < result->extension_range_count(); i++) {
+ const Descriptor::ExtensionRange* range1 = result->extension_range(i);
+ for (int j = 0; j < result->reserved_range_count(); j++) {
+ const Descriptor::ReservedRange* range2 = result->reserved_range(j);
+ if (range1->end > range2->start && range2->end > range1->start) {
+ AddError(result->full_name(), proto.extension_range(i),
+ DescriptorPool::ErrorCollector::NUMBER,
+ strings::Substitute("Extension range $0 to $1 overlaps with "
+ "reserved range $2 to $3.",
+ range1->start, range1->end - 1, range2->start,
+ range2->end - 1));
+ }
+ }
+ for (int j = i + 1; j < result->extension_range_count(); j++) {
+ const Descriptor::ExtensionRange* range2 = result->extension_range(j);
+ if (range1->end > range2->start && range2->end > range1->start) {
+ AddError(result->full_name(), proto.extension_range(i),
+ DescriptorPool::ErrorCollector::NUMBER,
+ strings::Substitute("Extension range $0 to $1 overlaps with "
+ "already-defined range $2 to $3.",
+ range2->start, range2->end - 1, range1->start,
+ range1->end - 1));
+ }
+ }
+ }
+}
+
+void DescriptorBuilder::BuildFieldOrExtension(const FieldDescriptorProto& proto,
+ Descriptor* parent,
+ FieldDescriptor* result,
+ bool is_extension) {
+ const 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 = tables_->AllocateFieldNames(
+ proto.name(), scope,
+ proto.has_json_name() ? &proto.json_name() : nullptr);
+ result->all_names_ = all_names.array;
+ result->lowercase_name_index_ = all_names.lowercase_index;
+ result->camelcase_name_index_ = all_names.camelcase_index;
+ result->json_name_index_ = all_names.json_index;
+
+ ValidateSymbolName(proto.name(), result->full_name(), proto);
+
+ result->file_ = file_;
+ result->number_ = proto.number();
+ result->is_extension_ = is_extension;
+ result->is_oneof_ = false;
+ result->proto3_optional_ = proto.proto3_optional();
+
+ if (proto.proto3_optional() &&
+ file_->syntax() != FileDescriptor::SYNTAX_PROTO3) {
+ AddError(result->full_name(), proto, DescriptorPool::ErrorCollector::TYPE,
+ "The [proto3_optional=true] option may only be set on proto3"
+ "fields, not " +
+ result->full_name());
+ }
+
+ result->has_json_name_ = proto.has_json_name();
+
+ // Some compilers do not allow static_cast directly between two enum types,
+ // so we must cast to int first.
+ result->type_ = static_cast<FieldDescriptor::Type>(
+ implicit_cast<int>(proto.type()));
+ result->label_ = static_cast<FieldDescriptor::Label>(
+ implicit_cast<int>(proto.label()));
+
+ if (result->label_ == FieldDescriptor::LABEL_REQUIRED) {
+ // An extension cannot have a required field (b/13365836).
+ if (result->is_extension_) {
+ AddError(result->full_name(), proto,
+ // Error location `TYPE`: we would really like to indicate
+ // `LABEL`, but the `ErrorLocation` enum has no entry for this,
+ // and we don't necessarily know about all implementations of the
+ // `ErrorCollector` interface to extend them to handle the new
+ // error location type properly.
+ DescriptorPool::ErrorCollector::TYPE,
+ "The extension " + result->full_name() + " cannot be required.");
+ }
+ }
+
+ // Some of these may be filled in when cross-linking.
+ result->containing_type_ = nullptr;
+ result->type_once_ = nullptr;
+ result->default_value_enum_ = nullptr;
+
+ result->has_default_value_ = proto.has_default_value();
+ if (proto.has_default_value() && result->is_repeated()) {
+ AddError(result->full_name(), proto,
+ DescriptorPool::ErrorCollector::DEFAULT_VALUE,
+ "Repeated fields can't have default values.");
+ }
+
+ if (proto.has_type()) {
+ if (proto.has_default_value()) {
+ char* end_pos = nullptr;
+ switch (result->cpp_type()) {
+ case FieldDescriptor::CPPTYPE_INT32:
+ result->default_value_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_ = tables_->AllocateString(
+ UnescapeCEscapeString(proto.default_value()));
+ } else {
+ result->default_value_string_ =
+ tables_->AllocateString(proto.default_value());
+ }
+ break;
+ case FieldDescriptor::CPPTYPE_MESSAGE:
+ AddError(result->full_name(), proto,
+ DescriptorPool::ErrorCollector::DEFAULT_VALUE,
+ "Messages can't have default values.");
+ result->has_default_value_ = false;
+ result->default_generated_instance_ = nullptr;
+ break;
+ }
+
+ if (end_pos != nullptr) {
+ // end_pos is only set non-null by the parsers for numeric types,
+ // above. This checks that the default was non-empty and had no extra
+ // junk after the end of the number.
+ if (proto.default_value().empty() || *end_pos != '\0') {
+ AddError(result->full_name(), proto,
+ DescriptorPool::ErrorCollector::DEFAULT_VALUE,
+ "Couldn't parse default value \"" + proto.default_value() +
+ "\".");
+ }
+ }
+ } else {
+ // No explicit default value
+ switch (result->cpp_type()) {
+ case FieldDescriptor::CPPTYPE_INT32:
+ result->default_value_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) {
+ AddError(result->full_name(), proto, DescriptorPool::ErrorCollector::NUMBER,
+ "Field numbers must be positive integers.");
+ } else if (!is_extension && result->number() > FieldDescriptor::kMaxNumber) {
+ // Only validate that the number is within the valid field range if it is
+ // not an extension. Since extension numbers are validated with the
+ // extendee's valid set of extension numbers, and those are in turn
+ // validated against the max allowed number, the check is unnecessary for
+ // extension fields.
+ // This avoids cross-linking issues that arise when attempting to check if
+ // the extendee is a message_set_wire_format message, which has a higher max
+ // on extension numbers.
+ AddError(result->full_name(), proto, DescriptorPool::ErrorCollector::NUMBER,
+ strings::Substitute("Field numbers cannot be greater than $0.",
+ FieldDescriptor::kMaxNumber));
+ } else if (result->number() >= FieldDescriptor::kFirstReservedNumber &&
+ result->number() <= FieldDescriptor::kLastReservedNumber) {
+ AddError(result->full_name(), proto, DescriptorPool::ErrorCollector::NUMBER,
+ strings::Substitute(
+ "Field numbers $0 through $1 are reserved for the protocol "
+ "buffer library implementation.",
+ FieldDescriptor::kFirstReservedNumber,
+ FieldDescriptor::kLastReservedNumber));
+ }
+
+ if (is_extension) {
+ if (!proto.has_extendee()) {
+ AddError(result->full_name(), proto,
+ DescriptorPool::ErrorCollector::EXTENDEE,
+ "FieldDescriptorProto.extendee not set for extension field.");
+ }
+
+ result->scope_.extension_scope = parent;
+
+ if (proto.has_oneof_index()) {
+ AddError(result->full_name(), proto, DescriptorPool::ErrorCollector::TYPE,
+ "FieldDescriptorProto.oneof_index should not be set for "
+ "extensions.");
+ }
+ } else {
+ if (proto.has_extendee()) {
+ AddError(result->full_name(), proto,
+ DescriptorPool::ErrorCollector::EXTENDEE,
+ "FieldDescriptorProto.extendee set for non-extension field.");
+ }
+
+ result->containing_type_ = parent;
+
+ if (proto.has_oneof_index()) {
+ if (proto.oneof_index() < 0 ||
+ proto.oneof_index() >= parent->oneof_decl_count()) {
+ AddError(result->full_name(), proto,
+ DescriptorPool::ErrorCollector::TYPE,
+ strings::Substitute("FieldDescriptorProto.oneof_index $0 is "
+ "out of range for type \"$1\".",
+ proto.oneof_index(), parent->name()));
+ } else {
+ result->is_oneof_ = true;
+ result->scope_.containing_oneof =
+ parent->oneof_decl(proto.oneof_index());
+ }
+ }
+ }
+
+ // Copy options.
+ result->options_ = nullptr; // Set to default_instance later if necessary.
+ if (proto.has_options()) {
+ AllocateOptions(proto.options(), result,
+ FieldDescriptorProto::kOptionsFieldNumber,
+ "google.protobuf.FieldOptions");
+ }
+
+
+ AddSymbol(result->full_name(), parent, result->name(), proto, Symbol(result));
+}
+
+void DescriptorBuilder::BuildExtensionRange(
+ const DescriptorProto::ExtensionRange& proto, const Descriptor* parent,
+ Descriptor::ExtensionRange* result) {
+ result->start = proto.start();
+ result->end = proto.end();
+ if (result->start <= 0) {
+ AddError(parent->full_name(), proto, DescriptorPool::ErrorCollector::NUMBER,
+ "Extension numbers must be positive integers.");
+ }
+
+ // Checking of the upper bound of the extension range is deferred until after
+ // options interpreting. This allows messages with message_set_wire_format to
+ // have extensions beyond FieldDescriptor::kMaxNumber, since the extension
+ // numbers are actually used as int32s in the message_set_wire_format.
+
+ if (result->start >= result->end) {
+ AddError(parent->full_name(), proto, DescriptorPool::ErrorCollector::NUMBER,
+ "Extension range end number must be greater than start number.");
+ }
+
+ result->options_ = nullptr; // Set to default_instance later if necessary.
+ if (proto.has_options()) {
+ std::vector<int> options_path;
+ parent->GetLocationPath(&options_path);
+ options_path.push_back(DescriptorProto::kExtensionRangeFieldNumber);
+ // find index of this extension range in order to compute path
+ int index;
+ for (index = 0; parent->extension_ranges_ + index != result; index++) {
+ }
+ options_path.push_back(index);
+ options_path.push_back(DescriptorProto_ExtensionRange::kOptionsFieldNumber);
+ AllocateOptionsImpl(parent->full_name(), parent->full_name(),
+ proto.options(), result, options_path,
+ "google.protobuf.ExtensionRangeOptions");
+ }
+}
+
+void DescriptorBuilder::BuildReservedRange(
+ const DescriptorProto::ReservedRange& proto, const Descriptor* parent,
+ Descriptor::ReservedRange* result) {
+ result->start = proto.start();
+ result->end = proto.end();
+ if (result->start <= 0) {
+ AddError(parent->full_name(), proto, DescriptorPool::ErrorCollector::NUMBER,
+ "Reserved numbers must be positive integers.");
+ }
+}
+
+void DescriptorBuilder::BuildReservedRange(
+ const EnumDescriptorProto::EnumReservedRange& proto,
+ const EnumDescriptor* parent, EnumDescriptor::ReservedRange* result) {
+ result->start = proto.start();
+ result->end = proto.end();
+
+ if (result->start > result->end) {
+ AddError(parent->full_name(), proto, DescriptorPool::ErrorCollector::NUMBER,
+ "Reserved range end number must be greater than start number.");
+ }
+}
+
+void DescriptorBuilder::BuildOneof(const OneofDescriptorProto& proto,
+ Descriptor* parent,
+ OneofDescriptor* result) {
+ result->all_names_ = AllocateNameStrings(parent->full_name(), proto.name());
+ ValidateSymbolName(proto.name(), result->full_name(), proto);
+
+ result->containing_type_ = parent;
+
+ // We need to fill these in later.
+ result->field_count_ = 0;
+ result->fields_ = nullptr;
+ result->options_ = nullptr;
+
+ // Copy options.
+ if (proto.has_options()) {
+ AllocateOptions(proto.options(), result,
+ OneofDescriptorProto::kOptionsFieldNumber,
+ "google.protobuf.OneofOptions");
+ }
+
+ AddSymbol(result->full_name(), parent, result->name(), proto, Symbol(result));
+}
+
+void DescriptorBuilder::CheckEnumValueUniqueness(
+ const EnumDescriptorProto& proto, const EnumDescriptor* result) {
+
+ // Check that enum labels are still unique when we remove the enum prefix from
+ // values that have it.
+ //
+ // This will fail for something like:
+ //
+ // enum MyEnum {
+ // MY_ENUM_FOO = 0;
+ // FOO = 1;
+ // }
+ //
+ // By enforcing this reasonable constraint, we allow code generators to strip
+ // the prefix and/or PascalCase it without creating conflicts. This can lead
+ // to much nicer language-specific enums like:
+ //
+ // enum NameType {
+ // FirstName = 1,
+ // LastName = 2,
+ // }
+ //
+ // Instead of:
+ //
+ // enum NameType {
+ // NAME_TYPE_FIRST_NAME = 1,
+ // NAME_TYPE_LAST_NAME = 2,
+ // }
+ PrefixRemover remover(result->name());
+ std::map<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) {
+ const std::string& scope =
+ (parent == nullptr) ? file_->package() : parent->full_name();
+
+ result->all_names_ = AllocateNameStrings(scope, proto.name());
+ ValidateSymbolName(proto.name(), result->full_name(), proto);
+ result->file_ = file_;
+ result->containing_type_ = parent;
+ result->is_placeholder_ = false;
+ result->is_unqualified_placeholder_ = false;
+
+ if (proto.value_size() == 0) {
+ // We cannot allow enums with no values because this would mean there
+ // would be no valid default value for fields of this type.
+ AddError(result->full_name(), proto, DescriptorPool::ErrorCollector::NAME,
+ "Enums must contain at least one value.");
+ }
+
+ // Calculate the continuous sequence of the labels.
+ // These can be fast-path'd during lookup and don't need to be added to the
+ // tables.
+ // We use uint16_t to save space for sequential_value_limit_, so stop before
+ // overflowing it. Worst case, we are not taking full advantage on huge
+ // enums, but it is unlikely.
+ for (int i = 0;
+ i < std::numeric_limits<uint16_t>::max() && i < proto.value_size() &&
+ // We do the math in 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_ =
+ tables_->AllocateArray<const std::string*>(reserved_name_count);
+ for (int i = 0; i < reserved_name_count; ++i) {
+ result->reserved_names_[i] =
+ tables_->AllocateString(proto.reserved_name(i));
+ }
+
+ CheckEnumValueUniqueness(proto, result);
+
+ // Copy options.
+ result->options_ = nullptr; // Set to default_instance later if necessary.
+ if (proto.has_options()) {
+ AllocateOptions(proto.options(), result,
+ EnumDescriptorProto::kOptionsFieldNumber,
+ "google.protobuf.EnumOptions");
+ }
+
+ AddSymbol(result->full_name(), parent, result->name(), proto, Symbol(result));
+
+ for (int i = 0; i < proto.reserved_range_size(); i++) {
+ const EnumDescriptorProto_EnumReservedRange& range1 =
+ proto.reserved_range(i);
+ for (int j = i + 1; j < proto.reserved_range_size(); j++) {
+ const EnumDescriptorProto_EnumReservedRange& range2 =
+ proto.reserved_range(j);
+ if (range1.end() >= range2.start() && range2.end() >= range1.start()) {
+ AddError(result->full_name(), proto.reserved_range(i),
+ DescriptorPool::ErrorCollector::NUMBER,
+ strings::Substitute("Reserved range $0 to $1 overlaps with "
+ "already-defined range $2 to $3.",
+ range2.start(), range2.end(), range1.start(),
+ range1.end()));
+ }
+ }
+ }
+
+ HASH_SET<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) {
+ // 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_ =
+ tables_->AllocateStringArray(proto.name(), std::move(full_name));
+ result->number_ = proto.number();
+ result->type_ = parent;
+
+ ValidateSymbolName(proto.name(), result->full_name(), proto);
+
+ // Copy options.
+ result->options_ = nullptr; // Set to default_instance later if necessary.
+ if (proto.has_options()) {
+ AllocateOptions(proto.options(), result,
+ EnumValueDescriptorProto::kOptionsFieldNumber,
+ "google.protobuf.EnumValueOptions");
+ }
+
+ // Again, enum values are weird because we makes them appear as siblings
+ // of the enum type instead of children of it. So, we use
+ // parent->containing_type() as the value's parent.
+ bool added_to_outer_scope =
+ AddSymbol(result->full_name(), parent->containing_type(), result->name(),
+ proto, Symbol::EnumValue(result, 0));
+
+ // However, we also want to be able to search for values within a single
+ // enum type, so we add it as a child of the enum type itself, too.
+ // Note: This could fail, but if it does, the error has already been
+ // reported by the above AddSymbol() call, so we ignore the return code.
+ bool added_to_inner_scope = file_tables_->AddAliasUnderParent(
+ parent, result->name(), Symbol::EnumValue(result, 1));
+
+ if (added_to_inner_scope && !added_to_outer_scope) {
+ // This value did not conflict with any values defined in the same enum,
+ // but it did conflict with some other symbol defined in the enum type's
+ // scope. Let's print an additional error to explain this.
+ 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) {
+ result->all_names_ = AllocateNameStrings(file_->package(), proto.name());
+ result->file_ = file_;
+ ValidateSymbolName(proto.name(), result->full_name(), proto);
+
+ BUILD_ARRAY(proto, result, method, BuildMethod, result);
+
+ // Copy options.
+ result->options_ = nullptr; // Set to default_instance later if necessary.
+ if (proto.has_options()) {
+ AllocateOptions(proto.options(), result,
+ ServiceDescriptorProto::kOptionsFieldNumber,
+ "google.protobuf.ServiceOptions");
+ }
+
+ AddSymbol(result->full_name(), nullptr, result->name(), proto,
+ Symbol(result));
+}
+
+void DescriptorBuilder::BuildMethod(const MethodDescriptorProto& proto,
+ const ServiceDescriptor* parent,
+ MethodDescriptor* result) {
+ result->service_ = parent;
+ result->all_names_ = AllocateNameStrings(parent->full_name(), proto.name());
+
+ ValidateSymbolName(proto.name(), result->full_name(), proto);
+
+ // These will be filled in when cross-linking.
+ result->input_type_.Init();
+ result->output_type_.Init();
+
+ // Copy options.
+ result->options_ = nullptr; // Set to default_instance later if necessary.
+ if (proto.has_options()) {
+ AllocateOptions(proto.options(), result,
+ MethodDescriptorProto::kOptionsFieldNumber,
+ "google.protobuf.MethodOptions");
+ }
+
+ result->client_streaming_ = proto.client_streaming();
+ result->server_streaming_ = proto.server_streaming();
+
+ AddSymbol(result->full_name(), parent, result->name(), proto, Symbol(result));
+}
+
+#undef BUILD_ARRAY
+
+// -------------------------------------------------------------------
+
+void DescriptorBuilder::CrossLinkFile(FileDescriptor* file,
+ const FileDescriptorProto& proto) {
+ if (file->options_ == nullptr) {
+ file->options_ = &FileOptions::default_instance();
+ }
+
+ for (int i = 0; i < file->message_type_count(); i++) {
+ CrossLinkMessage(&file->message_types_[i], proto.message_type(i));
+ }
+
+ for (int i = 0; i < file->extension_count(); i++) {
+ CrossLinkField(&file->extensions_[i], proto.extension(i));
+ }
+
+ for (int i = 0; i < file->enum_type_count(); i++) {
+ CrossLinkEnum(&file->enum_types_[i], proto.enum_type(i));
+ }
+
+ for (int i = 0; i < file->service_count(); i++) {
+ CrossLinkService(&file->services_[i], proto.service(i));
+ }
+}
+
+void DescriptorBuilder::CrossLinkMessage(Descriptor* message,
+ const DescriptorProto& proto) {
+ if (message->options_ == nullptr) {
+ message->options_ = &MessageOptions::default_instance();
+ }
+
+ for (int i = 0; i < message->nested_type_count(); i++) {
+ CrossLinkMessage(&message->nested_types_[i], proto.nested_type(i));
+ }
+
+ for (int i = 0; i < message->enum_type_count(); i++) {
+ CrossLinkEnum(&message->enum_types_[i], proto.enum_type(i));
+ }
+
+ for (int i = 0; i < message->field_count(); i++) {
+ CrossLinkField(&message->fields_[i], proto.field(i));
+ }
+
+ for (int i = 0; i < message->extension_count(); i++) {
+ CrossLinkField(&message->extensions_[i], proto.extension(i));
+ }
+
+ for (int i = 0; i < message->extension_range_count(); i++) {
+ CrossLinkExtensionRange(&message->extension_ranges_[i],
+ proto.extension_range(i));
+ }
+
+ // Set up field array for each oneof.
+
+ // First count the number of fields per oneof.
+ for (int i = 0; i < message->field_count(); i++) {
+ const OneofDescriptor* oneof_decl = message->field(i)->containing_oneof();
+ if (oneof_decl != nullptr) {
+ // Make sure fields belonging to the same oneof are defined consecutively.
+ // This enables optimizations in codegens and reflection libraries to
+ // skip fields in the oneof group, as only one of the field can be set.
+ // Note that field_count() returns how many fields in this oneof we have
+ // seen so far. field_count() > 0 guarantees that i > 0, so field(i-1) is
+ // safe.
+ if (oneof_decl->field_count() > 0 &&
+ message->field(i - 1)->containing_oneof() != oneof_decl) {
+ AddError(message->full_name() + "." + message->field(i - 1)->name(),
+ proto.field(i - 1), DescriptorPool::ErrorCollector::TYPE,
+ strings::Substitute(
+ "Fields in the same oneof must be defined consecutively. "
+ "\"$0\" cannot be defined before the completion of the "
+ "\"$1\" oneof definition.",
+ message->field(i - 1)->name(), oneof_decl->name()));
+ }
+ // Must go through oneof_decls_ array to get a non-const version of the
+ // OneofDescriptor.
+ auto& out_oneof_decl = message->oneof_decls_[oneof_decl->index()];
+ if (out_oneof_decl.field_count_ == 0) {
+ out_oneof_decl.fields_ = message->field(i);
+ }
+
+ if (!had_errors_) {
+ // Verify that they are contiguous.
+ // This is assumed by OneofDescriptor::field(i).
+ // But only if there are no errors.
+ GOOGLE_CHECK_EQ(out_oneof_decl.fields_ + out_oneof_decl.field_count_,
+ message->field(i));
+ }
+ ++out_oneof_decl.field_count_;
+ }
+ }
+
+ // Then verify the sizes.
+ for (int i = 0; i < message->oneof_decl_count(); i++) {
+ OneofDescriptor* oneof_decl = &message->oneof_decls_[i];
+
+ if (oneof_decl->field_count() == 0) {
+ AddError(message->full_name() + "." + oneof_decl->name(),
+ proto.oneof_decl(i), DescriptorPool::ErrorCollector::NAME,
+ "Oneof must have at least one field.");
+ }
+
+ if (oneof_decl->options_ == nullptr) {
+ oneof_decl->options_ = &OneofOptions::default_instance();
+ }
+ }
+
+ for (int i = 0; i < message->field_count(); i++) {
+ const FieldDescriptor* field = message->field(i);
+ if (field->proto3_optional_) {
+ if (!field->containing_oneof() ||
+ !field->containing_oneof()->is_synthetic()) {
+ AddError(message->full_name(), proto.field(i),
+ DescriptorPool::ErrorCollector::OTHER,
+ "Fields with proto3_optional set must be "
+ "a member of a one-field oneof");
+ }
+ }
+ }
+
+ // Synthetic oneofs must be last.
+ int first_synthetic = -1;
+ for (int i = 0; i < message->oneof_decl_count(); i++) {
+ const OneofDescriptor* oneof = message->oneof_decl(i);
+ if (oneof->is_synthetic()) {
+ if (first_synthetic == -1) {
+ first_synthetic = i;
+ }
+ } else {
+ if (first_synthetic != -1) {
+ AddError(message->full_name(), proto.oneof_decl(i),
+ DescriptorPool::ErrorCollector::OTHER,
+ "Synthetic oneofs must be after all other oneofs");
+ }
+ }
+ }
+
+ if (first_synthetic == -1) {
+ message->real_oneof_decl_count_ = message->oneof_decl_count_;
+ } else {
+ message->real_oneof_decl_count_ = first_synthetic;
+ }
+}
+
+void DescriptorBuilder::CrossLinkExtensionRange(
+ Descriptor::ExtensionRange* range,
+ const DescriptorProto::ExtensionRange& /*proto*/) {
+ if (range->options_ == nullptr) {
+ range->options_ = &ExtensionRangeOptions::default_instance();
+ }
+}
+
+void DescriptorBuilder::CrossLinkField(FieldDescriptor* field,
+ const FieldDescriptorProto& proto) {
+ if (field->options_ == nullptr) {
+ field->options_ = &FieldOptions::default_instance();
+ }
+
+ // Add the field to the lowercase-name and camelcase-name tables.
+ file_tables_->AddFieldByStylizedNames(field);
+
+ if (proto.has_extendee()) {
+ Symbol extendee =
+ LookupSymbol(proto.extendee(), field->full_name(),
+ DescriptorPool::PLACEHOLDER_EXTENDABLE_MESSAGE);
+ if (extendee.IsNull()) {
+ AddNotDefinedError(field->full_name(), proto,
+ DescriptorPool::ErrorCollector::EXTENDEE,
+ proto.extendee());
+ return;
+ } else if (extendee.type() != Symbol::MESSAGE) {
+ AddError(field->full_name(), proto,
+ DescriptorPool::ErrorCollector::EXTENDEE,
+ "\"" + proto.extendee() + "\" is not a message type.");
+ return;
+ }
+ field->containing_type_ = extendee.descriptor();
+
+ const Descriptor::ExtensionRange* extension_range =
+ field->containing_type()->FindExtensionRangeContainingNumber(
+ field->number());
+
+ if (extension_range == nullptr) {
+ // Set of valid extension numbers for MessageSet is different (< 2^32)
+ // from other extendees (< 2^29). If unknown deps are allowed, we may not
+ // have that information, and wrongly deem the extension as invalid.
+ auto skip_check = get_allow_unknown(pool_) &&
+ proto.extendee() == "google.protobuf.bridge.MessageSet";
+ if (!skip_check) {
+ AddError(field->full_name(), proto,
+ DescriptorPool::ErrorCollector::NUMBER,
+ strings::Substitute("\"$0\" does not declare $1 as an "
+ "extension number.",
+ field->containing_type()->full_name(),
+ field->number()));
+ }
+ }
+ }
+
+ if (field->containing_oneof() != nullptr) {
+ if (field->label() != FieldDescriptor::LABEL_OPTIONAL) {
+ // Note that this error will never happen when parsing .proto files.
+ // It can only happen if you manually construct a FileDescriptorProto
+ // that is incorrect.
+ AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::NAME,
+ "Fields of oneofs must themselves have label LABEL_OPTIONAL.");
+ }
+ }
+
+ if (proto.has_type_name()) {
+ // Assume we are expecting a message type unless the proto contains some
+ // evidence that it expects an enum type. This only makes a difference if
+ // we end up creating a placeholder.
+ bool expecting_enum = (proto.type() == FieldDescriptorProto::TYPE_ENUM) ||
+ proto.has_default_value();
+
+ // In case of weak fields we force building the dependency. We need to know
+ // if the type exist or not. If it doesn't exist we substitute Empty which
+ // should only be done if the type can't be found in the generated pool.
+ // TODO(gerbens) Ideally we should query the database directly to check
+ // if weak fields exist or not so that we don't need to force building
+ // weak dependencies. However the name lookup rules for symbols are
+ // somewhat complicated, so I defer it too another CL.
+ bool is_weak = !pool_->enforce_weak_ && proto.options().weak();
+ bool is_lazy = pool_->lazily_build_dependencies_ && !is_weak;
+
+ Symbol type =
+ LookupSymbol(proto.type_name(), field->full_name(),
+ expecting_enum ? DescriptorPool::PLACEHOLDER_ENUM
+ : DescriptorPool::PLACEHOLDER_MESSAGE,
+ LOOKUP_TYPES, !is_lazy);
+
+ if (type.IsNull()) {
+ if (is_lazy) {
+ // Save the symbol names for later for lookup, and allocate the once
+ // object needed for the accessors.
+ std::string name = proto.type_name();
+ field->type_once_ = tables_->Create<internal::once_flag>();
+ field->type_descriptor_.lazy_type_name = tables_->Strdup(name);
+ field->lazy_default_value_enum_name_ =
+ proto.has_default_value() ? tables_->Strdup(proto.default_value())
+ : nullptr;
+
+ // AddFieldByNumber and AddExtension are done later in this function,
+ // and can/must be done if the field type was not found. The related
+ // error checking is not necessary when in lazily_build_dependencies_
+ // mode, and can't be done without building the type's descriptor,
+ // which we don't want to do.
+ file_tables_->AddFieldByNumber(field);
+ if (field->is_extension()) {
+ tables_->AddExtension(field);
+ }
+ return;
+ } else {
+ // If the type is a weak type, we change the type to a google.protobuf.Empty
+ // field.
+ if (is_weak) {
+ type = FindSymbol(kNonLinkedWeakMessageReplacementName);
+ }
+ if (type.IsNull()) {
+ AddNotDefinedError(field->full_name(), proto,
+ DescriptorPool::ErrorCollector::TYPE,
+ proto.type_name());
+ return;
+ }
+ }
+ }
+
+ if (!proto.has_type()) {
+ // Choose field type based on symbol.
+ if (type.type() == Symbol::MESSAGE) {
+ field->type_ = FieldDescriptor::TYPE_MESSAGE;
+ } else if (type.type() == Symbol::ENUM) {
+ field->type_ = FieldDescriptor::TYPE_ENUM;
+ } else {
+ AddError(field->full_name(), proto,
+ DescriptorPool::ErrorCollector::TYPE,
+ "\"" + proto.type_name() + "\" is not a type.");
+ return;
+ }
+ }
+
+ if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+ field->type_descriptor_.message_type = type.descriptor();
+ if (field->type_descriptor_.message_type == nullptr) {
+ AddError(field->full_name(), proto,
+ DescriptorPool::ErrorCollector::TYPE,
+ "\"" + proto.type_name() + "\" is not a message type.");
+ return;
+ }
+
+ if (field->has_default_value()) {
+ AddError(field->full_name(), proto,
+ DescriptorPool::ErrorCollector::DEFAULT_VALUE,
+ "Messages can't have default values.");
+ }
+ } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) {
+ field->type_descriptor_.enum_type = type.enum_descriptor();
+ if (field->type_descriptor_.enum_type == nullptr) {
+ AddError(field->full_name(), proto,
+ DescriptorPool::ErrorCollector::TYPE,
+ "\"" + proto.type_name() + "\" is not an enum type.");
+ return;
+ }
+
+ if (field->enum_type()->is_placeholder_) {
+ // We can't look up default values for placeholder types. We'll have
+ // to just drop them.
+ field->has_default_value_ = false;
+ }
+
+ if (field->has_default_value()) {
+ // Ensure that the default value is an identifier. Parser cannot always
+ // verify this because it does not have complete type information.
+ // N.B. that this check yields better error messages but is not
+ // necessary for correctness (an enum symbol must be a valid identifier
+ // anyway), only for better errors.
+ if (!io::Tokenizer::IsIdentifier(proto.default_value())) {
+ AddError(field->full_name(), proto,
+ DescriptorPool::ErrorCollector::DEFAULT_VALUE,
+ "Default value for an enum field must be an identifier.");
+ } else {
+ // We can't just use field->enum_type()->FindValueByName() here
+ // because that locks the pool's mutex, which we have already locked
+ // at this point.
+ const EnumValueDescriptor* default_value =
+ LookupSymbolNoPlaceholder(proto.default_value(),
+ field->enum_type()->full_name())
+ .enum_value_descriptor();
+
+ if (default_value != nullptr &&
+ default_value->type() == field->enum_type()) {
+ field->default_value_enum_ = default_value;
+ } else {
+ AddError(field->full_name(), proto,
+ DescriptorPool::ErrorCollector::DEFAULT_VALUE,
+ "Enum type \"" + field->enum_type()->full_name() +
+ "\" has no value named \"" + proto.default_value() +
+ "\".");
+ }
+ }
+ } else if (field->enum_type()->value_count() > 0) {
+ // All enums must have at least one value, or we would have reported
+ // an error elsewhere. We use the first defined value as the default
+ // if a default is not explicitly defined.
+ field->default_value_enum_ = field->enum_type()->value(0);
+ }
+ } else {
+ AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE,
+ "Field with primitive type has type_name.");
+ }
+ } else {
+ if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE ||
+ field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) {
+ AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE,
+ "Field with message or enum type missing type_name.");
+ }
+ }
+
+ // Add the field to the fields-by-number table.
+ // Note: We have to do this *after* cross-linking because extensions do not
+ // know their containing type until now. If we're in
+ // lazily_build_dependencies_ mode, we're guaranteed there's no errors, so no
+ // risk to calling containing_type() or other accessors that will build
+ // dependencies.
+ if (!file_tables_->AddFieldByNumber(field)) {
+ const FieldDescriptor* conflicting_field = file_tables_->FindFieldByNumber(
+ field->containing_type(), field->number());
+ 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());
+ }
+}
+
+// -------------------------------------------------------------------
+
+#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()) {
+ 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.");
+ }
+ }
+ // 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: {
+ io::StringOutputStream outstr(
+ parent_unknown_fields->AddLengthDelimited((*iter)->number()));
+ io::CodedOutputStream out(&outstr);
+ internal::WireFormat::SerializeUnknownFields(*unknown_fields, &out);
+ GOOGLE_CHECK(!out.HadError())
+ << "Unexpected failure while serializing option submessage "
+ << debug_msg_name << "\".";
+ break;
+ }
+
+ case FieldDescriptor::TYPE_GROUP: {
+ parent_unknown_fields->AddGroup((*iter)->number())
+ ->MergeFrom(*unknown_fields);
+ break;
+ }
+
+ default:
+ GOOGLE_LOG(FATAL) << "Invalid wire type for CPPTYPE_MESSAGE: "
+ << (*iter)->type();
+ return false;
+ }
+ unknown_fields.reset(parent_unknown_fields.release());
+ }
+
+ // Now merge the UnknownFieldSet corresponding to the top-level message into
+ // the options message.
+ options->GetReflection()->MutableUnknownFields(options)->MergeFrom(
+ *unknown_fields);
+
+ // record the element path of the interpreted option
+ if (field->is_repeated()) {
+ int index = repeated_option_counts_[dest_path]++;
+ dest_path.push_back(index);
+ }
+ interpreted_paths_[src_path] = dest_path;
+
+ return true;
+}
+
+void DescriptorBuilder::OptionInterpreter::UpdateSourceCodeInfo(
+ SourceCodeInfo* info) {
+ if (interpreted_paths_.empty()) {
+ // nothing to do!
+ return;
+ }
+
+ // We find locations that match keys in interpreted_paths_ and
+ // 1) replace the path with the corresponding value in interpreted_paths_
+ // 2) remove any subsequent sub-locations (sub-location is one whose path
+ // has the parent path as a prefix)
+ //
+ // To avoid quadratic behavior of removing interior rows as we go,
+ // we keep a copy. But we don't actually copy anything until we've
+ // found the first match (so if the source code info has no locations
+ // that need to be changed, there is zero copy overhead).
+
+ RepeatedPtrField<SourceCodeInfo_Location>* locs = info->mutable_location();
+ RepeatedPtrField<SourceCodeInfo_Location> new_locs;
+ bool copying = false;
+
+ std::vector<int> pathv;
+ bool matched = false;
+
+ for (RepeatedPtrField<SourceCodeInfo_Location>::iterator loc = locs->begin();
+ loc != locs->end(); loc++) {
+ if (matched) {
+ // see if this location is in the range to remove
+ bool loc_matches = true;
+ if (loc->path_size() < static_cast<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;
+ Symbol result = file()->pool()->CrossLinkOnDemandHelper(
+ type_descriptor_.lazy_type_name, type_ == FieldDescriptor::TYPE_ENUM);
+ if (result.type() == Symbol::MESSAGE) {
+ type_ = FieldDescriptor::TYPE_MESSAGE;
+ type_descriptor_.message_type = result.descriptor();
+ } else if (result.type() == Symbol::ENUM) {
+ type_ = FieldDescriptor::TYPE_ENUM;
+ enum_type = type_descriptor_.enum_type = result.enum_descriptor();
+ }
+
+ if (enum_type) {
+ if (lazy_default_value_enum_name_) {
+ // Have to build the full name now instead of at CrossLink time,
+ // because enum_type may not be known at the time.
+ 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);
+ auto* names = dependencies_once_->dependencies_names;
+ for (int i = 0; i < dependency_count(); i++) {
+ if (names[i]) {
+ dependencies_[i] = pool_->FindFileByName(names[i]);
+ }
+ }
+}
+
+void FileDescriptor::DependenciesOnceInit(const FileDescriptor* to_init) {
+ to_init->InternalDependenciesOnceInit();
+}
+
+const FileDescriptor* FileDescriptor::dependency(int index) const {
+ if (dependencies_once_) {
+ // Do once init for all indices, as it's unlikely only a single index would
+ // be called, and saves on internal::call_once allocations.
+ internal::call_once(dependencies_once_->once,
+ FileDescriptor::DependenciesOnceInit, this);
+ }
+ return dependencies_[index];
+}
+
+const Descriptor* MethodDescriptor::input_type() const {
+ return input_type_.Get(service());
+}
+
+const Descriptor* MethodDescriptor::output_type() const {
+ return output_type_.Get(service());
+}
+
+
+namespace internal {
+void LazyDescriptor::Set(const Descriptor* descriptor) {
+ GOOGLE_CHECK(!once_);
+ descriptor_ = descriptor;
+}
+
+void LazyDescriptor::SetLazy(StringPiece name,
+ const FileDescriptor* file) {
+ // verify Init() has been called and Set hasn't been called yet.
+ GOOGLE_CHECK(!descriptor_);
+ GOOGLE_CHECK(!once_);
+ GOOGLE_CHECK(file && file->pool_);
+ GOOGLE_CHECK(file->pool_->lazily_build_dependencies_);
+ GOOGLE_CHECK(!file->finished_building_);
+ once_ = file->pool_->tables_->Create<internal::once_flag>();
+ lazy_name_ = file->pool_->tables_->Strdup(name);
+}
+
+void LazyDescriptor::Once(const ServiceDescriptor* service) {
+ if (once_) {
+ internal::call_once(*once_, [&] {
+ auto* file = service->file();
+ GOOGLE_CHECK(file->finished_building_);
+ descriptor_ =
+ file->pool_->CrossLinkOnDemandHelper(lazy_name_, false).descriptor();
+ });
+ }
+}
+
+} // namespace internal
+
+} // namespace protobuf
+} // namespace google
+
+#include <port_undef.inc>
diff --git a/NorthstarDedicatedTest/include/protobuf/descriptor.h b/NorthstarDedicatedTest/include/protobuf/descriptor.h
new file mode 100644
index 00000000..83a886ca
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/descriptor.h
@@ -0,0 +1,2417 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// This file contains classes which describe a type of protocol message.
+// You can use a message's descriptor to learn at runtime what fields
+// it contains and what the types of those fields are. The Message
+// interface also allows you to dynamically access and modify individual
+// fields by passing the FieldDescriptor of the field you are interested
+// in.
+//
+// Most users will not care about descriptors, because they will write
+// code specific to certain protocol types and will simply use the classes
+// generated by the protocol compiler directly. Advanced users who want
+// to operate on arbitrary types (not known at compile time) may want to
+// read descriptors in order to learn about the contents of a message.
+// A very small number of users will want to construct their own
+// Descriptors, either because they are implementing Message manually or
+// because they are writing something like the protocol compiler.
+//
+// For an example of how you might use descriptors, see the code example
+// at the top of message.h.
+
+#ifndef GOOGLE_PROTOBUF_DESCRIPTOR_H__
+#define GOOGLE_PROTOBUF_DESCRIPTOR_H__
+
+#include <atomic>
+#include <map>
+#include <memory>
+#include <set>
+#include <string>
+#include <vector>
+
+#include <stubs/common.h>
+#include <stubs/logging.h>
+#include <stubs/mutex.h>
+#include <stubs/once.h>
+#include <port.h>
+#include <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 {
+
+class PROTOBUF_EXPORT LazyDescriptor {
+ public:
+ // Init function to be called at init time of a descriptor containing
+ // a LazyDescriptor.
+ void Init() {
+ descriptor_ = nullptr;
+ once_ = nullptr;
+ }
+
+ // Sets the value of the descriptor if it is known during the descriptor
+ // building process. Not thread safe, should only be called during the
+ // descriptor build process. Should not be called after SetLazy has been
+ // called.
+ void Set(const Descriptor* descriptor);
+
+ // Sets the information needed to lazily cross link the descriptor at a later
+ // time, SetLazy is not thread safe, should be called only once at descriptor
+ // build time if the symbol wasn't found and building of the file containing
+ // that type is delayed because lazily_build_dependencies_ is set on the pool.
+ // Should not be called after Set() has been called.
+ void SetLazy(StringPiece name, const FileDescriptor* file);
+
+ // Returns the current value of the descriptor, thread-safe. If SetLazy(...)
+ // has been called, will do a one-time cross link of the type specified,
+ // building the descriptor file that contains the type if necessary.
+ inline const Descriptor* Get(const ServiceDescriptor* service) {
+ Once(service);
+ return descriptor_;
+ }
+
+ private:
+ void Once(const ServiceDescriptor* service);
+
+ union {
+ const Descriptor* descriptor_;
+ const char* lazy_name_;
+ };
+ internal::once_flag* once_;
+};
+
+class PROTOBUF_EXPORT SymbolBase {
+ private:
+ friend class google::protobuf::Symbol;
+ uint8_t symbol_type_;
+};
+
+// Some types have more than one SymbolBase because they have multiple
+// identities in the table. We can't have duplicate direct bases, so we use this
+// intermediate base to do so.
+// See BuildEnumValue for details.
+template <int N>
+class PROTOBUF_EXPORT SymbolBaseN : public SymbolBase {};
+
+} // namespace internal
+
+// Describes a type of protocol message, or a particular group within a
+// message. To obtain the Descriptor for a given message object, call
+// Message::GetDescriptor(). Generated message classes also have a
+// static method called descriptor() which returns the type's descriptor.
+// Use DescriptorPool to construct your own descriptors.
+class PROTOBUF_EXPORT Descriptor : private internal::SymbolBase {
+ public:
+ typedef DescriptorProto Proto;
+
+ // The name of the message type, not including its scope.
+ const 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);
+};
+
+
+// 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_;
+
+ internal::once_flag* type_once_;
+ static void TypeOnceInit(const FieldDescriptor* to_init);
+ void InternalTypeOnceInit() const;
+ const Descriptor* containing_type_;
+ union {
+ const OneofDescriptor* containing_oneof;
+ const Descriptor* extension_scope;
+ } scope_;
+ union {
+ mutable const Descriptor* message_type;
+ mutable const EnumDescriptor* enum_type;
+ const char* lazy_type_name;
+ } type_descriptor_;
+ const FieldOptions* options_;
+ // IMPORTANT: If you add a new field, make sure to search for all instances
+ // of Allocate<FieldDescriptor>() and AllocateArray<FieldDescriptor>() in
+ // descriptor.cc and update them to initialize the field.
+
+ union {
+ 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 char* lazy_default_value_enum_name_;
+ 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);
+};
+
+
+// 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);
+};
+
+// 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);
+};
+
+// 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);
+};
+
+// 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);
+};
+
+
+// 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);
+};
+
+
+// Describes a whole .proto file. To get the FileDescriptor for a compiled-in
+// file, get the descriptor for something defined in that file and call
+// descriptor->file(). Use DescriptorPool to construct your own descriptors.
+class PROTOBUF_EXPORT FileDescriptor {
+ public:
+ typedef FileDescriptorProto Proto;
+
+ // The filename, relative to the source tree.
+ // e.g. "foo/bar/baz.proto"
+ const 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:
+ typedef FileOptions OptionsType;
+
+ const std::string* name_;
+ const std::string* package_;
+ const DescriptorPool* pool_;
+
+ // Data required to do lazy initialization.
+ struct PROTOBUF_EXPORT LazyInitData {
+#ifndef SWIG
+ internal::once_flag once;
+#endif
+ const char** dependencies_names;
+ };
+
+ LazyInitData* dependencies_once_;
+ static void DependenciesOnceInit(const FileDescriptor* to_init);
+ void InternalDependenciesOnceInit() const;
+
+ // These are arranged to minimize padding on 64-bit.
+ int dependency_count_;
+ int public_dependency_count_;
+ int weak_dependency_count_;
+ int message_type_count_;
+ int enum_type_count_;
+ int service_count_;
+
+ bool is_placeholder_;
+ // Indicates the FileDescriptor is completed building. Used to verify
+ // that type accessor functions that can possibly build a dependent file
+ // aren't called during the process of building the file.
+ bool finished_building_;
+ // Actually a `Syntax` but stored as uint8_t to save space.
+ uint8_t syntax_;
+ // This one is here to fill the padding.
+ int extension_count_;
+
+ mutable const FileDescriptor** dependencies_;
+ int* public_dependencies_;
+ int* weak_dependencies_;
+ Descriptor* message_types_;
+ EnumDescriptor* enum_types_;
+ ServiceDescriptor* services_;
+ FieldDescriptor* extensions_;
+ const FileOptions* options_;
+
+ const FileDescriptorTables* tables_;
+ const SourceCodeInfo* source_code_info_;
+
+ // IMPORTANT: If you add a new field, make sure to search for all instances
+ // of Allocate<FileDescriptor>() and AllocateArray<FileDescriptor>() in
+ // descriptor.cc and update them to initialize the field.
+
+ FileDescriptor() {}
+ friend class DescriptorBuilder;
+ friend class DescriptorPool;
+ friend class Descriptor;
+ friend class FieldDescriptor;
+ friend class internal::LazyDescriptor;
+ friend class OneofDescriptor;
+ friend class EnumDescriptor;
+ friend class EnumValueDescriptor;
+ friend class MethodDescriptor;
+ friend class ServiceDescriptor;
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FileDescriptor);
+};
+
+
+// ===================================================================
+
+// Used to construct descriptors.
+//
+// Normally you won't want to build your own descriptors. Message classes
+// constructed by the protocol compiler will provide them for you. However,
+// if you are implementing Message on your own, or if you are writing a
+// program which can operate on totally arbitrary types and needs to load
+// them from some sort of database, you might need to.
+//
+// Since Descriptors are composed of a whole lot of cross-linked bits of
+// data that would be a pain to put together manually, the
+// DescriptorPool class is provided to make the process easier. It can
+// take a FileDescriptorProto (defined in descriptor.proto), validate it,
+// and convert it to a set of nicely cross-linked Descriptors.
+//
+// DescriptorPool also helps with memory management. Descriptors are
+// composed of many objects containing static data and pointers to each
+// other. In all likelihood, when it comes time to delete this data,
+// you'll want to delete it all at once. In fact, it is not uncommon to
+// have a whole pool of descriptors all cross-linked with each other which
+// you wish to delete all at once. This class represents such a pool, and
+// handles the memory management for you.
+//
+// You can also search for descriptors within a DescriptorPool by name, and
+// extensions by number.
+class PROTOBUF_EXPORT DescriptorPool {
+ public:
+ // Create a normal, empty DescriptorPool.
+ DescriptorPool();
+
+ // Constructs a DescriptorPool that, when it can't find something among the
+ // descriptors already in the pool, looks for it in the given
+ // DescriptorDatabase.
+ // Notes:
+ // - If a DescriptorPool is constructed this way, its BuildFile*() methods
+ // must not be called (they will assert-fail). The only way to populate
+ // the pool with descriptors is to call the Find*By*() methods.
+ // - The Find*By*() methods may block the calling thread if the
+ // DescriptorDatabase blocks. This in turn means that parsing messages
+ // may block if they need to look up extensions.
+ // - The Find*By*() methods will use mutexes for thread-safety, thus making
+ // them slower even when they don't have to fall back to the database.
+ // In fact, even the Find*By*() methods of descriptor objects owned by
+ // this pool will be slower, since they will have to obtain locks too.
+ // - An ErrorCollector may optionally be given to collect validation errors
+ // in files loaded from the database. If not given, errors will be printed
+ // to GOOGLE_LOG(ERROR). Remember that files are built on-demand, so this
+ // ErrorCollector may be called from any thread that calls one of the
+ // Find*By*() methods.
+ // - The DescriptorDatabase must not be mutated during the lifetime of
+ // the DescriptorPool. Even if the client takes care to avoid data races,
+ // changes to the content of the DescriptorDatabase may not be reflected
+ // in subsequent lookups in the DescriptorPool.
+ class ErrorCollector;
+ explicit DescriptorPool(DescriptorDatabase* fallback_database,
+ ErrorCollector* error_collector = nullptr);
+
+ ~DescriptorPool();
+
+ // Get a pointer to the generated pool. Generated protocol message classes
+ // which are compiled into the binary will allocate their descriptors in
+ // this pool. Do not add your own descriptors to this pool.
+ static const DescriptorPool* generated_pool();
+
+
+ // Find a FileDescriptor in the pool by file name. Returns nullptr if not
+ // found.
+ const FileDescriptor* FindFileByName(ConstStringParam name) const;
+
+ // Find the FileDescriptor in the pool which defines the given symbol.
+ // If any of the Find*ByName() methods below would succeed, then this is
+ // equivalent to calling that method and calling the result's file() method.
+ // Otherwise this returns nullptr.
+ const FileDescriptor* FindFileContainingSymbol(
+ ConstStringParam symbol_name) const;
+
+ // Looking up descriptors ------------------------------------------
+ // These find descriptors by fully-qualified name. These will find both
+ // top-level descriptors and nested descriptors. They return nullptr if not
+ // found.
+
+ const Descriptor* FindMessageTypeByName(ConstStringParam name) const;
+ const FieldDescriptor* FindFieldByName(ConstStringParam name) const;
+ const FieldDescriptor* FindExtensionByName(ConstStringParam name) const;
+ const OneofDescriptor* FindOneofByName(ConstStringParam name) const;
+ const EnumDescriptor* FindEnumTypeByName(ConstStringParam name) const;
+ const EnumValueDescriptor* FindEnumValueByName(ConstStringParam name) const;
+ const ServiceDescriptor* FindServiceByName(ConstStringParam name) const;
+ const MethodDescriptor* FindMethodByName(ConstStringParam name) const;
+
+ // Finds an extension of the given type by number. The extendee must be
+ // a member of this DescriptorPool or one of its underlays.
+ const FieldDescriptor* FindExtensionByNumber(const Descriptor* extendee,
+ int number) const;
+
+ // Finds an extension of the given type by its printable name.
+ // See comments above PrintableNameForExtension() for the definition of
+ // "printable name". The extendee must be a member of this DescriptorPool
+ // or one of its underlays. Returns nullptr if there is no known message
+ // extension with the given printable name.
+ const FieldDescriptor* FindExtensionByPrintableName(
+ const Descriptor* extendee, ConstStringParam printable_name) const;
+
+ // Finds extensions of extendee. The extensions will be appended to
+ // out in an undefined order. Only extensions defined directly in
+ // this DescriptorPool or one of its underlays are guaranteed to be
+ // found: extensions defined in the fallback database might not be found
+ // depending on the database implementation.
+ void FindAllExtensions(const Descriptor* extendee,
+ std::vector<const FieldDescriptor*>* out) const;
+
+ // Building descriptors --------------------------------------------
+
+ // When converting a FileDescriptorProto to a FileDescriptor, various
+ // errors might be detected in the input. The caller may handle these
+ // programmatically by implementing an ErrorCollector.
+ class PROTOBUF_EXPORT ErrorCollector {
+ public:
+ inline ErrorCollector() {}
+ virtual ~ErrorCollector();
+
+ // These constants specify what exact part of the construct is broken.
+ // This is useful e.g. for mapping the error back to an exact location
+ // in a .proto file.
+ enum ErrorLocation {
+ NAME, // the symbol name, or the package name for files
+ NUMBER, // field or extension range number
+ TYPE, // field type
+ EXTENDEE, // field extendee
+ DEFAULT_VALUE, // field default value
+ INPUT_TYPE, // method input type
+ OUTPUT_TYPE, // method output type
+ OPTION_NAME, // name in assignment
+ OPTION_VALUE, // value in option assignment
+ IMPORT, // import error
+ OTHER // some other problem
+ };
+
+ // Reports an error in the FileDescriptorProto. Use this function if the
+ // problem occurred should interrupt building the FileDescriptorProto.
+ virtual void AddError(
+ const 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 StreamDescriptor;
+ friend class DescriptorBuilder;
+ friend class FileDescriptorTables;
+
+ // Return true if the given name is a sub-symbol of any non-package
+ // descriptor that already exists in the descriptor pool. (The full
+ // definition of such types is already known.)
+ bool IsSubSymbolOfBuiltType(StringPiece name) const;
+
+ // Tries to find something in the fallback database and link in the
+ // corresponding proto file. Returns true if successful, in which case
+ // the caller should search for the thing again. These are declared
+ // const because they are called by (semantically) const methods.
+ bool TryFindFileInFallbackDatabase(StringPiece name) const;
+ bool TryFindSymbolInFallbackDatabase(StringPiece name) const;
+ bool TryFindExtensionInFallbackDatabase(const Descriptor* containing_type,
+ int field_number) const;
+
+ // This internal find extension method only check with its table and underlay
+ // descriptor_pool's table. It does not check with fallback DB and no
+ // additional proto file will be build in this method.
+ const FieldDescriptor* InternalFindExtensionByNumberNoLock(
+ const Descriptor* extendee, int number) const;
+
+ // Like BuildFile() but called internally when the file has been loaded from
+ // fallback_database_. Declared const because it is called by (semantically)
+ // const methods.
+ const FileDescriptor* BuildFileFromDatabase(
+ const FileDescriptorProto& proto) const;
+
+ // Helper for when lazily_build_dependencies_ is set, can look up a symbol
+ // after the file's descriptor is built, and can build the file where that
+ // symbol is defined if necessary. Will create a placeholder if the type
+ // doesn't exist in the fallback database, or the file doesn't build
+ // successfully.
+ Symbol CrossLinkOnDemandHelper(StringPiece name,
+ bool expecting_enum) const;
+
+ // Create a placeholder FileDescriptor of the specified name
+ FileDescriptor* NewPlaceholderFile(StringPiece name) const;
+ FileDescriptor* NewPlaceholderFileWithMutexHeld(StringPiece name) const;
+
+ enum PlaceholderType {
+ PLACEHOLDER_MESSAGE,
+ PLACEHOLDER_ENUM,
+ PLACEHOLDER_EXTENDABLE_MESSAGE
+ };
+ // Create a placeholder Descriptor of the specified name
+ Symbol NewPlaceholder(StringPiece name,
+ PlaceholderType placeholder_type) const;
+ Symbol NewPlaceholderWithMutexHeld(StringPiece name,
+ PlaceholderType placeholder_type) const;
+
+ // If fallback_database_ is nullptr, this is nullptr. Otherwise, this is a
+ // mutex which must be locked while accessing tables_.
+ internal::WrappedMutex* mutex_;
+
+ // See constructor.
+ DescriptorDatabase* fallback_database_;
+ ErrorCollector* default_error_collector_;
+ const DescriptorPool* underlay_;
+
+ // This class contains a lot of hash maps with complicated types that
+ // we'd like to keep out of the header.
+ class Tables;
+ std::unique_ptr<Tables> tables_;
+
+ bool enforce_dependencies_;
+ bool lazily_build_dependencies_;
+ bool allow_unknown_;
+ bool enforce_weak_;
+ bool disallow_enforce_utf8_;
+
+ // Set of files to track for unused imports. The bool value when true means
+ // unused imports are treated as errors (and as warnings when false).
+ std::map<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
+
+#include <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_DESCRIPTOR_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/descriptor.pb.cc b/NorthstarDedicatedTest/include/protobuf/descriptor.pb.cc
new file mode 100644
index 00000000..ded03f12
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/descriptor.pb.cc
@@ -0,0 +1,11125 @@
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+// source: google/protobuf/descriptor.proto
+
+#include <descriptor.pb.h>
+
+#include <algorithm>
+
+#include <io/coded_stream.h>
+#include <extension_set.h>
+#include <wire_format_lite.h>
+#include <descriptor.h>
+#include <generated_message_reflection.h>
+#include <reflection_ops.h>
+#include <wire_format.h>
+// @@protoc_insertion_point(includes)
+#include <port_def.inc>
+
+PROTOBUF_PRAGMA_INIT_SEG
+PROTOBUF_NAMESPACE_OPEN
+constexpr FileDescriptorSet::FileDescriptorSet(
+ ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized)
+ : file_(){}
+struct FileDescriptorSetDefaultTypeInternal {
+ constexpr FileDescriptorSetDefaultTypeInternal()
+ : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {}
+ ~FileDescriptorSetDefaultTypeInternal() {}
+ union {
+ FileDescriptorSet _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT FileDescriptorSetDefaultTypeInternal _FileDescriptorSet_default_instance_;
+constexpr FileDescriptorProto::FileDescriptorProto(
+ ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized)
+ : dependency_()
+ , message_type_()
+ , enum_type_()
+ , service_()
+ , extension_()
+ , public_dependency_()
+ , weak_dependency_()
+ , name_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string)
+ , package_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string)
+ , syntax_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string)
+ , options_(nullptr)
+ , source_code_info_(nullptr){}
+struct FileDescriptorProtoDefaultTypeInternal {
+ constexpr FileDescriptorProtoDefaultTypeInternal()
+ : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {}
+ ~FileDescriptorProtoDefaultTypeInternal() {}
+ union {
+ FileDescriptorProto _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT FileDescriptorProtoDefaultTypeInternal _FileDescriptorProto_default_instance_;
+constexpr DescriptorProto_ExtensionRange::DescriptorProto_ExtensionRange(
+ ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized)
+ : options_(nullptr)
+ , start_(0)
+ , end_(0){}
+struct DescriptorProto_ExtensionRangeDefaultTypeInternal {
+ constexpr DescriptorProto_ExtensionRangeDefaultTypeInternal()
+ : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {}
+ ~DescriptorProto_ExtensionRangeDefaultTypeInternal() {}
+ union {
+ DescriptorProto_ExtensionRange _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT DescriptorProto_ExtensionRangeDefaultTypeInternal _DescriptorProto_ExtensionRange_default_instance_;
+constexpr DescriptorProto_ReservedRange::DescriptorProto_ReservedRange(
+ ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized)
+ : start_(0)
+ , end_(0){}
+struct DescriptorProto_ReservedRangeDefaultTypeInternal {
+ constexpr DescriptorProto_ReservedRangeDefaultTypeInternal()
+ : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {}
+ ~DescriptorProto_ReservedRangeDefaultTypeInternal() {}
+ union {
+ DescriptorProto_ReservedRange _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT DescriptorProto_ReservedRangeDefaultTypeInternal _DescriptorProto_ReservedRange_default_instance_;
+constexpr DescriptorProto::DescriptorProto(
+ ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized)
+ : field_()
+ , nested_type_()
+ , enum_type_()
+ , extension_range_()
+ , extension_()
+ , oneof_decl_()
+ , reserved_range_()
+ , reserved_name_()
+ , name_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string)
+ , options_(nullptr){}
+struct DescriptorProtoDefaultTypeInternal {
+ constexpr DescriptorProtoDefaultTypeInternal()
+ : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {}
+ ~DescriptorProtoDefaultTypeInternal() {}
+ union {
+ DescriptorProto _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT DescriptorProtoDefaultTypeInternal _DescriptorProto_default_instance_;
+constexpr ExtensionRangeOptions::ExtensionRangeOptions(
+ ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized)
+ : uninterpreted_option_(){}
+struct ExtensionRangeOptionsDefaultTypeInternal {
+ constexpr ExtensionRangeOptionsDefaultTypeInternal()
+ : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {}
+ ~ExtensionRangeOptionsDefaultTypeInternal() {}
+ union {
+ ExtensionRangeOptions _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT ExtensionRangeOptionsDefaultTypeInternal _ExtensionRangeOptions_default_instance_;
+constexpr FieldDescriptorProto::FieldDescriptorProto(
+ ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized)
+ : name_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string)
+ , extendee_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string)
+ , type_name_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string)
+ , default_value_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string)
+ , json_name_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string)
+ , options_(nullptr)
+ , number_(0)
+ , oneof_index_(0)
+ , proto3_optional_(false)
+ , label_(1)
+
+ , type_(1)
+{}
+struct FieldDescriptorProtoDefaultTypeInternal {
+ constexpr FieldDescriptorProtoDefaultTypeInternal()
+ : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {}
+ ~FieldDescriptorProtoDefaultTypeInternal() {}
+ union {
+ FieldDescriptorProto _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT FieldDescriptorProtoDefaultTypeInternal _FieldDescriptorProto_default_instance_;
+constexpr OneofDescriptorProto::OneofDescriptorProto(
+ ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized)
+ : name_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string)
+ , options_(nullptr){}
+struct OneofDescriptorProtoDefaultTypeInternal {
+ constexpr OneofDescriptorProtoDefaultTypeInternal()
+ : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {}
+ ~OneofDescriptorProtoDefaultTypeInternal() {}
+ union {
+ OneofDescriptorProto _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT OneofDescriptorProtoDefaultTypeInternal _OneofDescriptorProto_default_instance_;
+constexpr EnumDescriptorProto_EnumReservedRange::EnumDescriptorProto_EnumReservedRange(
+ ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized)
+ : start_(0)
+ , end_(0){}
+struct EnumDescriptorProto_EnumReservedRangeDefaultTypeInternal {
+ constexpr EnumDescriptorProto_EnumReservedRangeDefaultTypeInternal()
+ : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {}
+ ~EnumDescriptorProto_EnumReservedRangeDefaultTypeInternal() {}
+ union {
+ EnumDescriptorProto_EnumReservedRange _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT EnumDescriptorProto_EnumReservedRangeDefaultTypeInternal _EnumDescriptorProto_EnumReservedRange_default_instance_;
+constexpr EnumDescriptorProto::EnumDescriptorProto(
+ ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized)
+ : value_()
+ , reserved_range_()
+ , reserved_name_()
+ , name_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string)
+ , options_(nullptr){}
+struct EnumDescriptorProtoDefaultTypeInternal {
+ constexpr EnumDescriptorProtoDefaultTypeInternal()
+ : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {}
+ ~EnumDescriptorProtoDefaultTypeInternal() {}
+ union {
+ EnumDescriptorProto _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT EnumDescriptorProtoDefaultTypeInternal _EnumDescriptorProto_default_instance_;
+constexpr EnumValueDescriptorProto::EnumValueDescriptorProto(
+ ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized)
+ : name_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string)
+ , options_(nullptr)
+ , number_(0){}
+struct EnumValueDescriptorProtoDefaultTypeInternal {
+ constexpr EnumValueDescriptorProtoDefaultTypeInternal()
+ : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {}
+ ~EnumValueDescriptorProtoDefaultTypeInternal() {}
+ union {
+ EnumValueDescriptorProto _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT EnumValueDescriptorProtoDefaultTypeInternal _EnumValueDescriptorProto_default_instance_;
+constexpr ServiceDescriptorProto::ServiceDescriptorProto(
+ ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized)
+ : method_()
+ , name_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string)
+ , options_(nullptr){}
+struct ServiceDescriptorProtoDefaultTypeInternal {
+ constexpr ServiceDescriptorProtoDefaultTypeInternal()
+ : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {}
+ ~ServiceDescriptorProtoDefaultTypeInternal() {}
+ union {
+ ServiceDescriptorProto _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT ServiceDescriptorProtoDefaultTypeInternal _ServiceDescriptorProto_default_instance_;
+constexpr MethodDescriptorProto::MethodDescriptorProto(
+ ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized)
+ : name_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string)
+ , input_type_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string)
+ , output_type_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string)
+ , options_(nullptr)
+ , client_streaming_(false)
+ , server_streaming_(false){}
+struct MethodDescriptorProtoDefaultTypeInternal {
+ constexpr MethodDescriptorProtoDefaultTypeInternal()
+ : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {}
+ ~MethodDescriptorProtoDefaultTypeInternal() {}
+ union {
+ MethodDescriptorProto _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT MethodDescriptorProtoDefaultTypeInternal _MethodDescriptorProto_default_instance_;
+constexpr FileOptions::FileOptions(
+ ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized)
+ : uninterpreted_option_()
+ , java_package_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string)
+ , java_outer_classname_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string)
+ , go_package_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string)
+ , objc_class_prefix_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string)
+ , csharp_namespace_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string)
+ , swift_prefix_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string)
+ , php_class_prefix_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string)
+ , php_namespace_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string)
+ , php_metadata_namespace_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string)
+ , ruby_package_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string)
+ , java_multiple_files_(false)
+ , java_generate_equals_and_hash_(false)
+ , java_string_check_utf8_(false)
+ , cc_generic_services_(false)
+ , java_generic_services_(false)
+ , py_generic_services_(false)
+ , php_generic_services_(false)
+ , deprecated_(false)
+ , optimize_for_(1)
+
+ , cc_enable_arenas_(true){}
+struct FileOptionsDefaultTypeInternal {
+ constexpr FileOptionsDefaultTypeInternal()
+ : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {}
+ ~FileOptionsDefaultTypeInternal() {}
+ union {
+ FileOptions _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT FileOptionsDefaultTypeInternal _FileOptions_default_instance_;
+constexpr MessageOptions::MessageOptions(
+ ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized)
+ : uninterpreted_option_()
+ , message_set_wire_format_(false)
+ , no_standard_descriptor_accessor_(false)
+ , deprecated_(false)
+ , map_entry_(false){}
+struct MessageOptionsDefaultTypeInternal {
+ constexpr MessageOptionsDefaultTypeInternal()
+ : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {}
+ ~MessageOptionsDefaultTypeInternal() {}
+ union {
+ MessageOptions _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT MessageOptionsDefaultTypeInternal _MessageOptions_default_instance_;
+constexpr FieldOptions::FieldOptions(
+ ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized)
+ : uninterpreted_option_()
+ , ctype_(0)
+
+ , packed_(false)
+ , lazy_(false)
+ , deprecated_(false)
+ , weak_(false)
+ , jstype_(0)
+{}
+struct FieldOptionsDefaultTypeInternal {
+ constexpr FieldOptionsDefaultTypeInternal()
+ : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {}
+ ~FieldOptionsDefaultTypeInternal() {}
+ union {
+ FieldOptions _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT FieldOptionsDefaultTypeInternal _FieldOptions_default_instance_;
+constexpr OneofOptions::OneofOptions(
+ ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized)
+ : uninterpreted_option_(){}
+struct OneofOptionsDefaultTypeInternal {
+ constexpr OneofOptionsDefaultTypeInternal()
+ : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {}
+ ~OneofOptionsDefaultTypeInternal() {}
+ union {
+ OneofOptions _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT OneofOptionsDefaultTypeInternal _OneofOptions_default_instance_;
+constexpr EnumOptions::EnumOptions(
+ ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized)
+ : uninterpreted_option_()
+ , allow_alias_(false)
+ , deprecated_(false){}
+struct EnumOptionsDefaultTypeInternal {
+ constexpr EnumOptionsDefaultTypeInternal()
+ : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {}
+ ~EnumOptionsDefaultTypeInternal() {}
+ union {
+ EnumOptions _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT EnumOptionsDefaultTypeInternal _EnumOptions_default_instance_;
+constexpr EnumValueOptions::EnumValueOptions(
+ ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized)
+ : uninterpreted_option_()
+ , deprecated_(false){}
+struct EnumValueOptionsDefaultTypeInternal {
+ constexpr EnumValueOptionsDefaultTypeInternal()
+ : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {}
+ ~EnumValueOptionsDefaultTypeInternal() {}
+ union {
+ EnumValueOptions _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT EnumValueOptionsDefaultTypeInternal _EnumValueOptions_default_instance_;
+constexpr ServiceOptions::ServiceOptions(
+ ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized)
+ : uninterpreted_option_()
+ , deprecated_(false){}
+struct ServiceOptionsDefaultTypeInternal {
+ constexpr ServiceOptionsDefaultTypeInternal()
+ : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {}
+ ~ServiceOptionsDefaultTypeInternal() {}
+ union {
+ ServiceOptions _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT ServiceOptionsDefaultTypeInternal _ServiceOptions_default_instance_;
+constexpr MethodOptions::MethodOptions(
+ ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized)
+ : uninterpreted_option_()
+ , deprecated_(false)
+ , idempotency_level_(0)
+{}
+struct MethodOptionsDefaultTypeInternal {
+ constexpr MethodOptionsDefaultTypeInternal()
+ : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {}
+ ~MethodOptionsDefaultTypeInternal() {}
+ union {
+ MethodOptions _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT MethodOptionsDefaultTypeInternal _MethodOptions_default_instance_;
+constexpr UninterpretedOption_NamePart::UninterpretedOption_NamePart(
+ ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized)
+ : name_part_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string)
+ , is_extension_(false){}
+struct UninterpretedOption_NamePartDefaultTypeInternal {
+ constexpr UninterpretedOption_NamePartDefaultTypeInternal()
+ : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {}
+ ~UninterpretedOption_NamePartDefaultTypeInternal() {}
+ union {
+ UninterpretedOption_NamePart _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT UninterpretedOption_NamePartDefaultTypeInternal _UninterpretedOption_NamePart_default_instance_;
+constexpr UninterpretedOption::UninterpretedOption(
+ ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized)
+ : name_()
+ , identifier_value_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string)
+ , string_value_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string)
+ , aggregate_value_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string)
+ , positive_int_value_(uint64_t{0u})
+ , negative_int_value_(int64_t{0})
+ , double_value_(0){}
+struct UninterpretedOptionDefaultTypeInternal {
+ constexpr UninterpretedOptionDefaultTypeInternal()
+ : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {}
+ ~UninterpretedOptionDefaultTypeInternal() {}
+ union {
+ UninterpretedOption _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT UninterpretedOptionDefaultTypeInternal _UninterpretedOption_default_instance_;
+constexpr SourceCodeInfo_Location::SourceCodeInfo_Location(
+ ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized)
+ : path_()
+ , _path_cached_byte_size_(0)
+ , span_()
+ , _span_cached_byte_size_(0)
+ , leading_detached_comments_()
+ , leading_comments_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string)
+ , trailing_comments_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string){}
+struct SourceCodeInfo_LocationDefaultTypeInternal {
+ constexpr SourceCodeInfo_LocationDefaultTypeInternal()
+ : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {}
+ ~SourceCodeInfo_LocationDefaultTypeInternal() {}
+ union {
+ SourceCodeInfo_Location _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT SourceCodeInfo_LocationDefaultTypeInternal _SourceCodeInfo_Location_default_instance_;
+constexpr SourceCodeInfo::SourceCodeInfo(
+ ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized)
+ : location_(){}
+struct SourceCodeInfoDefaultTypeInternal {
+ constexpr SourceCodeInfoDefaultTypeInternal()
+ : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {}
+ ~SourceCodeInfoDefaultTypeInternal() {}
+ union {
+ SourceCodeInfo _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT SourceCodeInfoDefaultTypeInternal _SourceCodeInfo_default_instance_;
+constexpr GeneratedCodeInfo_Annotation::GeneratedCodeInfo_Annotation(
+ ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized)
+ : path_()
+ , _path_cached_byte_size_(0)
+ , source_file_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string)
+ , begin_(0)
+ , end_(0){}
+struct GeneratedCodeInfo_AnnotationDefaultTypeInternal {
+ constexpr GeneratedCodeInfo_AnnotationDefaultTypeInternal()
+ : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {}
+ ~GeneratedCodeInfo_AnnotationDefaultTypeInternal() {}
+ union {
+ GeneratedCodeInfo_Annotation _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT GeneratedCodeInfo_AnnotationDefaultTypeInternal _GeneratedCodeInfo_Annotation_default_instance_;
+constexpr GeneratedCodeInfo::GeneratedCodeInfo(
+ ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized)
+ : annotation_(){}
+struct GeneratedCodeInfoDefaultTypeInternal {
+ constexpr GeneratedCodeInfoDefaultTypeInternal()
+ : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {}
+ ~GeneratedCodeInfoDefaultTypeInternal() {}
+ union {
+ GeneratedCodeInfo _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT GeneratedCodeInfoDefaultTypeInternal _GeneratedCodeInfo_default_instance_;
+PROTOBUF_NAMESPACE_CLOSE
+static ::PROTOBUF_NAMESPACE_ID::Metadata file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[27];
+static const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* file_level_enum_descriptors_google_2fprotobuf_2fdescriptor_2eproto[6];
+static constexpr ::PROTOBUF_NAMESPACE_ID::ServiceDescriptor const** file_level_service_descriptors_google_2fprotobuf_2fdescriptor_2eproto = nullptr;
+
+const 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, file_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileDescriptorProto, _has_bits_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileDescriptorProto, _internal_metadata_),
+ ~0u, // no _extensions_
+ ~0u, // no _oneof_case_
+ ~0u, // no _weak_field_map_
+ ~0u, // no _inlined_string_donated_
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileDescriptorProto, name_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileDescriptorProto, package_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileDescriptorProto, dependency_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileDescriptorProto, public_dependency_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileDescriptorProto, weak_dependency_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileDescriptorProto, message_type_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileDescriptorProto, enum_type_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileDescriptorProto, service_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileDescriptorProto, extension_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileDescriptorProto, options_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileDescriptorProto, source_code_info_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileDescriptorProto, syntax_),
+ 0,
+ 1,
+ ~0u,
+ ~0u,
+ ~0u,
+ ~0u,
+ ~0u,
+ ~0u,
+ ~0u,
+ 3,
+ 4,
+ 2,
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::DescriptorProto_ExtensionRange, _has_bits_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::DescriptorProto_ExtensionRange, _internal_metadata_),
+ ~0u, // no _extensions_
+ ~0u, // no _oneof_case_
+ ~0u, // no _weak_field_map_
+ ~0u, // no _inlined_string_donated_
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::DescriptorProto_ExtensionRange, start_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::DescriptorProto_ExtensionRange, end_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::DescriptorProto_ExtensionRange, options_),
+ 1,
+ 2,
+ 0,
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::DescriptorProto_ReservedRange, _has_bits_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::DescriptorProto_ReservedRange, _internal_metadata_),
+ ~0u, // no _extensions_
+ ~0u, // no _oneof_case_
+ ~0u, // no _weak_field_map_
+ ~0u, // no _inlined_string_donated_
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::DescriptorProto_ReservedRange, start_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::DescriptorProto_ReservedRange, end_),
+ 0,
+ 1,
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::DescriptorProto, _has_bits_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::DescriptorProto, _internal_metadata_),
+ ~0u, // no _extensions_
+ ~0u, // no _oneof_case_
+ ~0u, // no _weak_field_map_
+ ~0u, // no _inlined_string_donated_
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::DescriptorProto, name_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::DescriptorProto, field_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::DescriptorProto, extension_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::DescriptorProto, nested_type_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::DescriptorProto, enum_type_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::DescriptorProto, extension_range_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::DescriptorProto, oneof_decl_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::DescriptorProto, options_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::DescriptorProto, reserved_range_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::DescriptorProto, reserved_name_),
+ 0,
+ ~0u,
+ ~0u,
+ ~0u,
+ ~0u,
+ ~0u,
+ ~0u,
+ 1,
+ ~0u,
+ ~0u,
+ ~0u, // no _has_bits_
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions, _internal_metadata_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions, _extensions_),
+ ~0u, // no _oneof_case_
+ ~0u, // no _weak_field_map_
+ ~0u, // no _inlined_string_donated_
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions, uninterpreted_option_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto, _has_bits_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto, _internal_metadata_),
+ ~0u, // no _extensions_
+ ~0u, // no _oneof_case_
+ ~0u, // no _weak_field_map_
+ ~0u, // no _inlined_string_donated_
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto, name_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto, number_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto, label_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto, type_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto, type_name_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto, extendee_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto, default_value_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto, oneof_index_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto, json_name_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto, options_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto, proto3_optional_),
+ 0,
+ 6,
+ 9,
+ 10,
+ 2,
+ 1,
+ 3,
+ 7,
+ 4,
+ 5,
+ 8,
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::OneofDescriptorProto, _has_bits_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::OneofDescriptorProto, _internal_metadata_),
+ ~0u, // no _extensions_
+ ~0u, // no _oneof_case_
+ ~0u, // no _weak_field_map_
+ ~0u, // no _inlined_string_donated_
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::OneofDescriptorProto, name_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::OneofDescriptorProto, options_),
+ 0,
+ 1,
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto_EnumReservedRange, _has_bits_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto_EnumReservedRange, _internal_metadata_),
+ ~0u, // no _extensions_
+ ~0u, // no _oneof_case_
+ ~0u, // no _weak_field_map_
+ ~0u, // no _inlined_string_donated_
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto_EnumReservedRange, start_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto_EnumReservedRange, end_),
+ 0,
+ 1,
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto, _has_bits_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto, _internal_metadata_),
+ ~0u, // no _extensions_
+ ~0u, // no _oneof_case_
+ ~0u, // no _weak_field_map_
+ ~0u, // no _inlined_string_donated_
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto, name_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto, value_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto, options_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto, reserved_range_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto, reserved_name_),
+ 0,
+ ~0u,
+ 1,
+ ~0u,
+ ~0u,
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumValueDescriptorProto, _has_bits_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumValueDescriptorProto, _internal_metadata_),
+ ~0u, // no _extensions_
+ ~0u, // no _oneof_case_
+ ~0u, // no _weak_field_map_
+ ~0u, // no _inlined_string_donated_
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumValueDescriptorProto, name_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumValueDescriptorProto, number_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumValueDescriptorProto, options_),
+ 0,
+ 2,
+ 1,
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::ServiceDescriptorProto, _has_bits_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::ServiceDescriptorProto, _internal_metadata_),
+ ~0u, // no _extensions_
+ ~0u, // no _oneof_case_
+ ~0u, // no _weak_field_map_
+ ~0u, // no _inlined_string_donated_
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::ServiceDescriptorProto, name_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::ServiceDescriptorProto, method_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::ServiceDescriptorProto, options_),
+ 0,
+ ~0u,
+ 1,
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::MethodDescriptorProto, _has_bits_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::MethodDescriptorProto, _internal_metadata_),
+ ~0u, // no _extensions_
+ ~0u, // no _oneof_case_
+ ~0u, // no _weak_field_map_
+ ~0u, // no _inlined_string_donated_
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::MethodDescriptorProto, name_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::MethodDescriptorProto, input_type_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::MethodDescriptorProto, output_type_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::MethodDescriptorProto, options_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::MethodDescriptorProto, client_streaming_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::MethodDescriptorProto, server_streaming_),
+ 0,
+ 1,
+ 2,
+ 3,
+ 4,
+ 5,
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileOptions, _has_bits_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileOptions, _internal_metadata_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileOptions, _extensions_),
+ ~0u, // no _oneof_case_
+ ~0u, // no _weak_field_map_
+ ~0u, // no _inlined_string_donated_
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileOptions, java_package_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileOptions, java_outer_classname_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileOptions, java_multiple_files_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileOptions, java_generate_equals_and_hash_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileOptions, java_string_check_utf8_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileOptions, optimize_for_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileOptions, go_package_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileOptions, cc_generic_services_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileOptions, java_generic_services_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileOptions, py_generic_services_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileOptions, php_generic_services_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileOptions, deprecated_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileOptions, cc_enable_arenas_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileOptions, objc_class_prefix_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileOptions, csharp_namespace_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileOptions, swift_prefix_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileOptions, php_class_prefix_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileOptions, php_namespace_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileOptions, php_metadata_namespace_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileOptions, ruby_package_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileOptions, uninterpreted_option_),
+ 0,
+ 1,
+ 10,
+ 11,
+ 12,
+ 18,
+ 2,
+ 13,
+ 14,
+ 15,
+ 16,
+ 17,
+ 19,
+ 3,
+ 4,
+ 5,
+ 6,
+ 7,
+ 8,
+ 9,
+ ~0u,
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::MessageOptions, _has_bits_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::MessageOptions, _internal_metadata_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::MessageOptions, _extensions_),
+ ~0u, // no _oneof_case_
+ ~0u, // no _weak_field_map_
+ ~0u, // no _inlined_string_donated_
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::MessageOptions, message_set_wire_format_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::MessageOptions, no_standard_descriptor_accessor_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::MessageOptions, deprecated_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::MessageOptions, map_entry_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::MessageOptions, uninterpreted_option_),
+ 0,
+ 1,
+ 2,
+ 3,
+ ~0u,
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FieldOptions, _has_bits_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FieldOptions, _internal_metadata_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FieldOptions, _extensions_),
+ ~0u, // no _oneof_case_
+ ~0u, // no _weak_field_map_
+ ~0u, // no _inlined_string_donated_
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FieldOptions, ctype_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FieldOptions, packed_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FieldOptions, jstype_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FieldOptions, lazy_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FieldOptions, deprecated_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FieldOptions, weak_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FieldOptions, uninterpreted_option_),
+ 0,
+ 1,
+ 5,
+ 2,
+ 3,
+ 4,
+ ~0u,
+ ~0u, // no _has_bits_
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::OneofOptions, _internal_metadata_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::OneofOptions, _extensions_),
+ ~0u, // no _oneof_case_
+ ~0u, // no _weak_field_map_
+ ~0u, // no _inlined_string_donated_
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::OneofOptions, uninterpreted_option_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumOptions, _has_bits_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumOptions, _internal_metadata_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumOptions, _extensions_),
+ ~0u, // no _oneof_case_
+ ~0u, // no _weak_field_map_
+ ~0u, // no _inlined_string_donated_
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumOptions, allow_alias_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumOptions, deprecated_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumOptions, uninterpreted_option_),
+ 0,
+ 1,
+ ~0u,
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumValueOptions, _has_bits_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumValueOptions, _internal_metadata_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumValueOptions, _extensions_),
+ ~0u, // no _oneof_case_
+ ~0u, // no _weak_field_map_
+ ~0u, // no _inlined_string_donated_
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumValueOptions, deprecated_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumValueOptions, uninterpreted_option_),
+ 0,
+ ~0u,
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::ServiceOptions, _has_bits_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::ServiceOptions, _internal_metadata_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::ServiceOptions, _extensions_),
+ ~0u, // no _oneof_case_
+ ~0u, // no _weak_field_map_
+ ~0u, // no _inlined_string_donated_
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::ServiceOptions, deprecated_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::ServiceOptions, uninterpreted_option_),
+ 0,
+ ~0u,
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::MethodOptions, _has_bits_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::MethodOptions, _internal_metadata_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::MethodOptions, _extensions_),
+ ~0u, // no _oneof_case_
+ ~0u, // no _weak_field_map_
+ ~0u, // no _inlined_string_donated_
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::MethodOptions, deprecated_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::MethodOptions, idempotency_level_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::MethodOptions, uninterpreted_option_),
+ 0,
+ 1,
+ ~0u,
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::UninterpretedOption_NamePart, _has_bits_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::UninterpretedOption_NamePart, _internal_metadata_),
+ ~0u, // no _extensions_
+ ~0u, // no _oneof_case_
+ ~0u, // no _weak_field_map_
+ ~0u, // no _inlined_string_donated_
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::UninterpretedOption_NamePart, name_part_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::UninterpretedOption_NamePart, is_extension_),
+ 0,
+ 1,
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::UninterpretedOption, _has_bits_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::UninterpretedOption, _internal_metadata_),
+ ~0u, // no _extensions_
+ ~0u, // no _oneof_case_
+ ~0u, // no _weak_field_map_
+ ~0u, // no _inlined_string_donated_
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::UninterpretedOption, name_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::UninterpretedOption, identifier_value_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::UninterpretedOption, positive_int_value_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::UninterpretedOption, negative_int_value_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::UninterpretedOption, double_value_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::UninterpretedOption, string_value_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::UninterpretedOption, aggregate_value_),
+ ~0u,
+ 0,
+ 3,
+ 4,
+ 5,
+ 1,
+ 2,
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location, _has_bits_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location, _internal_metadata_),
+ ~0u, // no _extensions_
+ ~0u, // no _oneof_case_
+ ~0u, // no _weak_field_map_
+ ~0u, // no _inlined_string_donated_
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location, path_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location, span_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location, leading_comments_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location, trailing_comments_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location, leading_detached_comments_),
+ ~0u,
+ ~0u,
+ 0,
+ 1,
+ ~0u,
+ ~0u, // no _has_bits_
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::SourceCodeInfo, _internal_metadata_),
+ ~0u, // no _extensions_
+ ~0u, // no _oneof_case_
+ ~0u, // no _weak_field_map_
+ ~0u, // no _inlined_string_donated_
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::SourceCodeInfo, location_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation, _has_bits_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation, _internal_metadata_),
+ ~0u, // no _extensions_
+ ~0u, // no _oneof_case_
+ ~0u, // no _weak_field_map_
+ ~0u, // no _inlined_string_donated_
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation, path_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation, source_file_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation, begin_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation, end_),
+ ~0u,
+ 0,
+ 1,
+ 2,
+ ~0u, // no _has_bits_
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo, _internal_metadata_),
+ ~0u, // no _extensions_
+ ~0u, // no _oneof_case_
+ ~0u, // no _weak_field_map_
+ ~0u, // no _inlined_string_donated_
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo, annotation_),
+};
+static const ::PROTOBUF_NAMESPACE_ID::internal::MigrationSchema schemas[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = {
+ { 0, -1, -1, sizeof(::PROTOBUF_NAMESPACE_ID::FileDescriptorSet)},
+ { 7, 25, -1, sizeof(::PROTOBUF_NAMESPACE_ID::FileDescriptorProto)},
+ { 37, 46, -1, sizeof(::PROTOBUF_NAMESPACE_ID::DescriptorProto_ExtensionRange)},
+ { 49, 57, -1, sizeof(::PROTOBUF_NAMESPACE_ID::DescriptorProto_ReservedRange)},
+ { 59, 75, -1, sizeof(::PROTOBUF_NAMESPACE_ID::DescriptorProto)},
+ { 85, -1, -1, sizeof(::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions)},
+ { 92, 109, -1, sizeof(::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto)},
+ { 120, 128, -1, sizeof(::PROTOBUF_NAMESPACE_ID::OneofDescriptorProto)},
+ { 130, 138, -1, sizeof(::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto_EnumReservedRange)},
+ { 140, 151, -1, sizeof(::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto)},
+ { 156, 165, -1, sizeof(::PROTOBUF_NAMESPACE_ID::EnumValueDescriptorProto)},
+ { 168, 177, -1, sizeof(::PROTOBUF_NAMESPACE_ID::ServiceDescriptorProto)},
+ { 180, 192, -1, sizeof(::PROTOBUF_NAMESPACE_ID::MethodDescriptorProto)},
+ { 198, 225, -1, sizeof(::PROTOBUF_NAMESPACE_ID::FileOptions)},
+ { 246, 257, -1, sizeof(::PROTOBUF_NAMESPACE_ID::MessageOptions)},
+ { 262, 275, -1, sizeof(::PROTOBUF_NAMESPACE_ID::FieldOptions)},
+ { 282, -1, -1, sizeof(::PROTOBUF_NAMESPACE_ID::OneofOptions)},
+ { 289, 298, -1, sizeof(::PROTOBUF_NAMESPACE_ID::EnumOptions)},
+ { 301, 309, -1, sizeof(::PROTOBUF_NAMESPACE_ID::EnumValueOptions)},
+ { 311, 319, -1, sizeof(::PROTOBUF_NAMESPACE_ID::ServiceOptions)},
+ { 321, 330, -1, sizeof(::PROTOBUF_NAMESPACE_ID::MethodOptions)},
+ { 333, 341, -1, sizeof(::PROTOBUF_NAMESPACE_ID::UninterpretedOption_NamePart)},
+ { 343, 356, -1, sizeof(::PROTOBUF_NAMESPACE_ID::UninterpretedOption)},
+ { 363, 374, -1, sizeof(::PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location)},
+ { 379, -1, -1, sizeof(::PROTOBUF_NAMESPACE_ID::SourceCodeInfo)},
+ { 386, 396, -1, sizeof(::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation)},
+ { 400, -1, -1, sizeof(::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo)},
+};
+
+static ::PROTOBUF_NAMESPACE_ID::Message const * const file_default_instances[] = {
+ reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_FileDescriptorSet_default_instance_),
+ reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_FileDescriptorProto_default_instance_),
+ reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_DescriptorProto_ExtensionRange_default_instance_),
+ reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_DescriptorProto_ReservedRange_default_instance_),
+ reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_DescriptorProto_default_instance_),
+ reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_ExtensionRangeOptions_default_instance_),
+ reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_FieldDescriptorProto_default_instance_),
+ reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_OneofDescriptorProto_default_instance_),
+ reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_EnumDescriptorProto_EnumReservedRange_default_instance_),
+ reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_EnumDescriptorProto_default_instance_),
+ reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_EnumValueDescriptorProto_default_instance_),
+ reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_ServiceDescriptorProto_default_instance_),
+ reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_MethodDescriptorProto_default_instance_),
+ reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_FileOptions_default_instance_),
+ reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_MessageOptions_default_instance_),
+ reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_FieldOptions_default_instance_),
+ reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_OneofOptions_default_instance_),
+ reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_EnumOptions_default_instance_),
+ reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_EnumValueOptions_default_instance_),
+ reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_ServiceOptions_default_instance_),
+ reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_MethodOptions_default_instance_),
+ reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_UninterpretedOption_NamePart_default_instance_),
+ reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_UninterpretedOption_default_instance_),
+ reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_SourceCodeInfo_Location_default_instance_),
+ reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_SourceCodeInfo_default_instance_),
+ reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_GeneratedCodeInfo_Annotation_default_instance_),
+ reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_GeneratedCodeInfo_default_instance_),
+};
+
+const char descriptor_table_protodef_google_2fprotobuf_2fdescriptor_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) =
+ "\n google/protobuf/descriptor.proto\022\017goog"
+ "le.protobuf\"G\n\021FileDescriptorSet\0222\n\004file"
+ "\030\001 \003(\0132$.google.protobuf.FileDescriptorP"
+ "roto\"\333\003\n\023FileDescriptorProto\022\014\n\004name\030\001 \001"
+ "(\t\022\017\n\007package\030\002 \001(\t\022\022\n\ndependency\030\003 \003(\t\022"
+ "\031\n\021public_dependency\030\n \003(\005\022\027\n\017weak_depen"
+ "dency\030\013 \003(\005\0226\n\014message_type\030\004 \003(\0132 .goog"
+ "le.protobuf.DescriptorProto\0227\n\tenum_type"
+ "\030\005 \003(\0132$.google.protobuf.EnumDescriptorP"
+ "roto\0228\n\007service\030\006 \003(\0132\'.google.protobuf."
+ "ServiceDescriptorProto\0228\n\textension\030\007 \003("
+ "\0132%.google.protobuf.FieldDescriptorProto"
+ "\022-\n\007options\030\010 \001(\0132\034.google.protobuf.File"
+ "Options\0229\n\020source_code_info\030\t \001(\0132\037.goog"
+ "le.protobuf.SourceCodeInfo\022\016\n\006syntax\030\014 \001"
+ "(\t\"\251\005\n\017DescriptorProto\022\014\n\004name\030\001 \001(\t\0224\n\005"
+ "field\030\002 \003(\0132%.google.protobuf.FieldDescr"
+ "iptorProto\0228\n\textension\030\006 \003(\0132%.google.p"
+ "rotobuf.FieldDescriptorProto\0225\n\013nested_t"
+ "ype\030\003 \003(\0132 .google.protobuf.DescriptorPr"
+ "oto\0227\n\tenum_type\030\004 \003(\0132$.google.protobuf"
+ ".EnumDescriptorProto\022H\n\017extension_range\030"
+ "\005 \003(\0132/.google.protobuf.DescriptorProto."
+ "ExtensionRange\0229\n\noneof_decl\030\010 \003(\0132%.goo"
+ "gle.protobuf.OneofDescriptorProto\0220\n\007opt"
+ "ions\030\007 \001(\0132\037.google.protobuf.MessageOpti"
+ "ons\022F\n\016reserved_range\030\t \003(\0132..google.pro"
+ "tobuf.DescriptorProto.ReservedRange\022\025\n\rr"
+ "eserved_name\030\n \003(\t\032e\n\016ExtensionRange\022\r\n\005"
+ "start\030\001 \001(\005\022\013\n\003end\030\002 \001(\005\0227\n\007options\030\003 \001("
+ "\0132&.google.protobuf.ExtensionRangeOption"
+ "s\032+\n\rReservedRange\022\r\n\005start\030\001 \001(\005\022\013\n\003end"
+ "\030\002 \001(\005\"g\n\025ExtensionRangeOptions\022C\n\024unint"
+ "erpreted_option\030\347\007 \003(\0132$.google.protobuf"
+ ".UninterpretedOption*\t\010\350\007\020\200\200\200\200\002\"\325\005\n\024Fiel"
+ "dDescriptorProto\022\014\n\004name\030\001 \001(\t\022\016\n\006number"
+ "\030\003 \001(\005\022:\n\005label\030\004 \001(\0162+.google.protobuf."
+ "FieldDescriptorProto.Label\0228\n\004type\030\005 \001(\016"
+ "2*.google.protobuf.FieldDescriptorProto."
+ "Type\022\021\n\ttype_name\030\006 \001(\t\022\020\n\010extendee\030\002 \001("
+ "\t\022\025\n\rdefault_value\030\007 \001(\t\022\023\n\013oneof_index\030"
+ "\t \001(\005\022\021\n\tjson_name\030\n \001(\t\022.\n\007options\030\010 \001("
+ "\0132\035.google.protobuf.FieldOptions\022\027\n\017prot"
+ "o3_optional\030\021 \001(\010\"\266\002\n\004Type\022\017\n\013TYPE_DOUBL"
+ "E\020\001\022\016\n\nTYPE_FLOAT\020\002\022\016\n\nTYPE_INT64\020\003\022\017\n\013T"
+ "YPE_UINT64\020\004\022\016\n\nTYPE_INT32\020\005\022\020\n\014TYPE_FIX"
+ "ED64\020\006\022\020\n\014TYPE_FIXED32\020\007\022\r\n\tTYPE_BOOL\020\010\022"
+ "\017\n\013TYPE_STRING\020\t\022\016\n\nTYPE_GROUP\020\n\022\020\n\014TYPE"
+ "_MESSAGE\020\013\022\016\n\nTYPE_BYTES\020\014\022\017\n\013TYPE_UINT3"
+ "2\020\r\022\r\n\tTYPE_ENUM\020\016\022\021\n\rTYPE_SFIXED32\020\017\022\021\n"
+ "\rTYPE_SFIXED64\020\020\022\017\n\013TYPE_SINT32\020\021\022\017\n\013TYP"
+ "E_SINT64\020\022\"C\n\005Label\022\022\n\016LABEL_OPTIONAL\020\001\022"
+ "\022\n\016LABEL_REQUIRED\020\002\022\022\n\016LABEL_REPEATED\020\003\""
+ "T\n\024OneofDescriptorProto\022\014\n\004name\030\001 \001(\t\022.\n"
+ "\007options\030\002 \001(\0132\035.google.protobuf.OneofOp"
+ "tions\"\244\002\n\023EnumDescriptorProto\022\014\n\004name\030\001 "
+ "\001(\t\0228\n\005value\030\002 \003(\0132).google.protobuf.Enu"
+ "mValueDescriptorProto\022-\n\007options\030\003 \001(\0132\034"
+ ".google.protobuf.EnumOptions\022N\n\016reserved"
+ "_range\030\004 \003(\01326.google.protobuf.EnumDescr"
+ "iptorProto.EnumReservedRange\022\025\n\rreserved"
+ "_name\030\005 \003(\t\032/\n\021EnumReservedRange\022\r\n\005star"
+ "t\030\001 \001(\005\022\013\n\003end\030\002 \001(\005\"l\n\030EnumValueDescrip"
+ "torProto\022\014\n\004name\030\001 \001(\t\022\016\n\006number\030\002 \001(\005\0222"
+ "\n\007options\030\003 \001(\0132!.google.protobuf.EnumVa"
+ "lueOptions\"\220\001\n\026ServiceDescriptorProto\022\014\n"
+ "\004name\030\001 \001(\t\0226\n\006method\030\002 \003(\0132&.google.pro"
+ "tobuf.MethodDescriptorProto\0220\n\007options\030\003"
+ " \001(\0132\037.google.protobuf.ServiceOptions\"\301\001"
+ "\n\025MethodDescriptorProto\022\014\n\004name\030\001 \001(\t\022\022\n"
+ "\ninput_type\030\002 \001(\t\022\023\n\013output_type\030\003 \001(\t\022/"
+ "\n\007options\030\004 \001(\0132\036.google.protobuf.Method"
+ "Options\022\037\n\020client_streaming\030\005 \001(\010:\005false"
+ "\022\037\n\020server_streaming\030\006 \001(\010:\005false\"\245\006\n\013Fi"
+ "leOptions\022\024\n\014java_package\030\001 \001(\t\022\034\n\024java_"
+ "outer_classname\030\010 \001(\t\022\"\n\023java_multiple_f"
+ "iles\030\n \001(\010:\005false\022)\n\035java_generate_equal"
+ "s_and_hash\030\024 \001(\010B\002\030\001\022%\n\026java_string_chec"
+ "k_utf8\030\033 \001(\010:\005false\022F\n\014optimize_for\030\t \001("
+ "\0162).google.protobuf.FileOptions.Optimize"
+ "Mode:\005SPEED\022\022\n\ngo_package\030\013 \001(\t\022\"\n\023cc_ge"
+ "neric_services\030\020 \001(\010:\005false\022$\n\025java_gene"
+ "ric_services\030\021 \001(\010:\005false\022\"\n\023py_generic_"
+ "services\030\022 \001(\010:\005false\022#\n\024php_generic_ser"
+ "vices\030* \001(\010:\005false\022\031\n\ndeprecated\030\027 \001(\010:\005"
+ "false\022\036\n\020cc_enable_arenas\030\037 \001(\010:\004true\022\031\n"
+ "\021objc_class_prefix\030$ \001(\t\022\030\n\020csharp_names"
+ "pace\030% \001(\t\022\024\n\014swift_prefix\030\' \001(\t\022\030\n\020php_"
+ "class_prefix\030( \001(\t\022\025\n\rphp_namespace\030) \001("
+ "\t\022\036\n\026php_metadata_namespace\030, \001(\t\022\024\n\014rub"
+ "y_package\030- \001(\t\022C\n\024uninterpreted_option\030"
+ "\347\007 \003(\0132$.google.protobuf.UninterpretedOp"
+ "tion\":\n\014OptimizeMode\022\t\n\005SPEED\020\001\022\r\n\tCODE_"
+ "SIZE\020\002\022\020\n\014LITE_RUNTIME\020\003*\t\010\350\007\020\200\200\200\200\002J\004\010&\020"
+ "\'\"\204\002\n\016MessageOptions\022&\n\027message_set_wire"
+ "_format\030\001 \001(\010:\005false\022.\n\037no_standard_desc"
+ "riptor_accessor\030\002 \001(\010:\005false\022\031\n\ndeprecat"
+ "ed\030\003 \001(\010:\005false\022\021\n\tmap_entry\030\007 \001(\010\022C\n\024un"
+ "interpreted_option\030\347\007 \003(\0132$.google.proto"
+ "buf.UninterpretedOption*\t\010\350\007\020\200\200\200\200\002J\004\010\004\020\005"
+ "J\004\010\005\020\006J\004\010\006\020\007J\004\010\010\020\tJ\004\010\t\020\n\"\236\003\n\014FieldOption"
+ "s\022:\n\005ctype\030\001 \001(\0162#.google.protobuf.Field"
+ "Options.CType:\006STRING\022\016\n\006packed\030\002 \001(\010\022\?\n"
+ "\006jstype\030\006 \001(\0162$.google.protobuf.FieldOpt"
+ "ions.JSType:\tJS_NORMAL\022\023\n\004lazy\030\005 \001(\010:\005fa"
+ "lse\022\031\n\ndeprecated\030\003 \001(\010:\005false\022\023\n\004weak\030\n"
+ " \001(\010:\005false\022C\n\024uninterpreted_option\030\347\007 \003"
+ "(\0132$.google.protobuf.UninterpretedOption"
+ "\"/\n\005CType\022\n\n\006STRING\020\000\022\010\n\004CORD\020\001\022\020\n\014STRIN"
+ "G_PIECE\020\002\"5\n\006JSType\022\r\n\tJS_NORMAL\020\000\022\r\n\tJS"
+ "_STRING\020\001\022\r\n\tJS_NUMBER\020\002*\t\010\350\007\020\200\200\200\200\002J\004\010\004\020"
+ "\005\"^\n\014OneofOptions\022C\n\024uninterpreted_optio"
+ "n\030\347\007 \003(\0132$.google.protobuf.Uninterpreted"
+ "Option*\t\010\350\007\020\200\200\200\200\002\"\223\001\n\013EnumOptions\022\023\n\013all"
+ "ow_alias\030\002 \001(\010\022\031\n\ndeprecated\030\003 \001(\010:\005fals"
+ "e\022C\n\024uninterpreted_option\030\347\007 \003(\0132$.googl"
+ "e.protobuf.UninterpretedOption*\t\010\350\007\020\200\200\200\200"
+ "\002J\004\010\005\020\006\"}\n\020EnumValueOptions\022\031\n\ndeprecate"
+ "d\030\001 \001(\010:\005false\022C\n\024uninterpreted_option\030\347"
+ "\007 \003(\0132$.google.protobuf.UninterpretedOpt"
+ "ion*\t\010\350\007\020\200\200\200\200\002\"{\n\016ServiceOptions\022\031\n\ndepr"
+ "ecated\030! \001(\010:\005false\022C\n\024uninterpreted_opt"
+ "ion\030\347\007 \003(\0132$.google.protobuf.Uninterpret"
+ "edOption*\t\010\350\007\020\200\200\200\200\002\"\255\002\n\rMethodOptions\022\031\n"
+ "\ndeprecated\030! \001(\010:\005false\022_\n\021idempotency_"
+ "level\030\" \001(\0162/.google.protobuf.MethodOpti"
+ "ons.IdempotencyLevel:\023IDEMPOTENCY_UNKNOW"
+ "N\022C\n\024uninterpreted_option\030\347\007 \003(\0132$.googl"
+ "e.protobuf.UninterpretedOption\"P\n\020Idempo"
+ "tencyLevel\022\027\n\023IDEMPOTENCY_UNKNOWN\020\000\022\023\n\017N"
+ "O_SIDE_EFFECTS\020\001\022\016\n\nIDEMPOTENT\020\002*\t\010\350\007\020\200\200"
+ "\200\200\002\"\236\002\n\023UninterpretedOption\022;\n\004name\030\002 \003("
+ "\0132-.google.protobuf.UninterpretedOption."
+ "NamePart\022\030\n\020identifier_value\030\003 \001(\t\022\032\n\022po"
+ "sitive_int_value\030\004 \001(\004\022\032\n\022negative_int_v"
+ "alue\030\005 \001(\003\022\024\n\014double_value\030\006 \001(\001\022\024\n\014stri"
+ "ng_value\030\007 \001(\014\022\027\n\017aggregate_value\030\010 \001(\t\032"
+ "3\n\010NamePart\022\021\n\tname_part\030\001 \002(\t\022\024\n\014is_ext"
+ "ension\030\002 \002(\010\"\325\001\n\016SourceCodeInfo\022:\n\010locat"
+ "ion\030\001 \003(\0132(.google.protobuf.SourceCodeIn"
+ "fo.Location\032\206\001\n\010Location\022\020\n\004path\030\001 \003(\005B\002"
+ "\020\001\022\020\n\004span\030\002 \003(\005B\002\020\001\022\030\n\020leading_comments"
+ "\030\003 \001(\t\022\031\n\021trailing_comments\030\004 \001(\t\022!\n\031lea"
+ "ding_detached_comments\030\006 \003(\t\"\247\001\n\021Generat"
+ "edCodeInfo\022A\n\nannotation\030\001 \003(\0132-.google."
+ "protobuf.GeneratedCodeInfo.Annotation\032O\n"
+ "\nAnnotation\022\020\n\004path\030\001 \003(\005B\002\020\001\022\023\n\013source_"
+ "file\030\002 \001(\t\022\r\n\005begin\030\003 \001(\005\022\013\n\003end\030\004 \001(\005B~"
+ "\n\023com.google.protobufB\020DescriptorProtosH"
+ "\001Z-google.golang.org/protobuf/types/desc"
+ "riptorpb\370\001\001\242\002\003GPB\252\002\032Google.Protobuf.Refl"
+ "ection"
+ ;
+static ::PROTOBUF_NAMESPACE_ID::internal::once_flag descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once;
+const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fdescriptor_2eproto = {
+ false, false, 6046, descriptor_table_protodef_google_2fprotobuf_2fdescriptor_2eproto, "google/protobuf/descriptor.proto",
+ &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once, nullptr, 0, 27,
+ schemas, file_default_instances, TableStruct_google_2fprotobuf_2fdescriptor_2eproto::offsets,
+ file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto, file_level_enum_descriptors_google_2fprotobuf_2fdescriptor_2eproto, file_level_service_descriptors_google_2fprotobuf_2fdescriptor_2eproto,
+};
+PROTOBUF_ATTRIBUTE_WEAK const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable* descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter() {
+ return &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto;
+}
+
+// Force running AddDescriptors() at dynamic initialization time.
+PROTOBUF_ATTRIBUTE_INIT_PRIORITY static ::PROTOBUF_NAMESPACE_ID::internal::AddDescriptorsRunner dynamic_init_dummy_google_2fprotobuf_2fdescriptor_2eproto(&descriptor_table_google_2fprotobuf_2fdescriptor_2eproto);
+PROTOBUF_NAMESPACE_OPEN
+const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* FieldDescriptorProto_Type_descriptor() {
+ ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fdescriptor_2eproto);
+ return file_level_enum_descriptors_google_2fprotobuf_2fdescriptor_2eproto[0];
+}
+bool FieldDescriptorProto_Type_IsValid(int value) {
+ switch (value) {
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ case 8:
+ case 9:
+ case 10:
+ case 11:
+ case 12:
+ case 13:
+ case 14:
+ case 15:
+ case 16:
+ case 17:
+ case 18:
+ return true;
+ default:
+ return false;
+ }
+}
+
+#if (__cplusplus < 201703) && (!defined(_MSC_VER) || (_MSC_VER >= 1900 && _MSC_VER < 1912))
+constexpr FieldDescriptorProto_Type FieldDescriptorProto::TYPE_DOUBLE;
+constexpr FieldDescriptorProto_Type FieldDescriptorProto::TYPE_FLOAT;
+constexpr FieldDescriptorProto_Type FieldDescriptorProto::TYPE_INT64;
+constexpr FieldDescriptorProto_Type FieldDescriptorProto::TYPE_UINT64;
+constexpr FieldDescriptorProto_Type FieldDescriptorProto::TYPE_INT32;
+constexpr FieldDescriptorProto_Type FieldDescriptorProto::TYPE_FIXED64;
+constexpr FieldDescriptorProto_Type FieldDescriptorProto::TYPE_FIXED32;
+constexpr FieldDescriptorProto_Type FieldDescriptorProto::TYPE_BOOL;
+constexpr FieldDescriptorProto_Type FieldDescriptorProto::TYPE_STRING;
+constexpr FieldDescriptorProto_Type FieldDescriptorProto::TYPE_GROUP;
+constexpr FieldDescriptorProto_Type FieldDescriptorProto::TYPE_MESSAGE;
+constexpr FieldDescriptorProto_Type FieldDescriptorProto::TYPE_BYTES;
+constexpr FieldDescriptorProto_Type FieldDescriptorProto::TYPE_UINT32;
+constexpr FieldDescriptorProto_Type FieldDescriptorProto::TYPE_ENUM;
+constexpr FieldDescriptorProto_Type FieldDescriptorProto::TYPE_SFIXED32;
+constexpr FieldDescriptorProto_Type FieldDescriptorProto::TYPE_SFIXED64;
+constexpr FieldDescriptorProto_Type FieldDescriptorProto::TYPE_SINT32;
+constexpr FieldDescriptorProto_Type FieldDescriptorProto::TYPE_SINT64;
+constexpr FieldDescriptorProto_Type FieldDescriptorProto::Type_MIN;
+constexpr FieldDescriptorProto_Type FieldDescriptorProto::Type_MAX;
+constexpr int FieldDescriptorProto::Type_ARRAYSIZE;
+#endif // (__cplusplus < 201703) && (!defined(_MSC_VER) || (_MSC_VER >= 1900 && _MSC_VER < 1912))
+const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* FieldDescriptorProto_Label_descriptor() {
+ ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fdescriptor_2eproto);
+ return file_level_enum_descriptors_google_2fprotobuf_2fdescriptor_2eproto[1];
+}
+bool FieldDescriptorProto_Label_IsValid(int value) {
+ switch (value) {
+ case 1:
+ case 2:
+ case 3:
+ return true;
+ default:
+ return false;
+ }
+}
+
+#if (__cplusplus < 201703) && (!defined(_MSC_VER) || (_MSC_VER >= 1900 && _MSC_VER < 1912))
+constexpr FieldDescriptorProto_Label FieldDescriptorProto::LABEL_OPTIONAL;
+constexpr FieldDescriptorProto_Label FieldDescriptorProto::LABEL_REQUIRED;
+constexpr FieldDescriptorProto_Label FieldDescriptorProto::LABEL_REPEATED;
+constexpr FieldDescriptorProto_Label FieldDescriptorProto::Label_MIN;
+constexpr FieldDescriptorProto_Label FieldDescriptorProto::Label_MAX;
+constexpr int FieldDescriptorProto::Label_ARRAYSIZE;
+#endif // (__cplusplus < 201703) && (!defined(_MSC_VER) || (_MSC_VER >= 1900 && _MSC_VER < 1912))
+const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* FileOptions_OptimizeMode_descriptor() {
+ ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fdescriptor_2eproto);
+ return file_level_enum_descriptors_google_2fprotobuf_2fdescriptor_2eproto[2];
+}
+bool FileOptions_OptimizeMode_IsValid(int value) {
+ switch (value) {
+ case 1:
+ case 2:
+ case 3:
+ return true;
+ default:
+ return false;
+ }
+}
+
+#if (__cplusplus < 201703) && (!defined(_MSC_VER) || (_MSC_VER >= 1900 && _MSC_VER < 1912))
+constexpr FileOptions_OptimizeMode FileOptions::SPEED;
+constexpr FileOptions_OptimizeMode FileOptions::CODE_SIZE;
+constexpr FileOptions_OptimizeMode FileOptions::LITE_RUNTIME;
+constexpr FileOptions_OptimizeMode FileOptions::OptimizeMode_MIN;
+constexpr FileOptions_OptimizeMode FileOptions::OptimizeMode_MAX;
+constexpr int FileOptions::OptimizeMode_ARRAYSIZE;
+#endif // (__cplusplus < 201703) && (!defined(_MSC_VER) || (_MSC_VER >= 1900 && _MSC_VER < 1912))
+const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* FieldOptions_CType_descriptor() {
+ ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fdescriptor_2eproto);
+ return file_level_enum_descriptors_google_2fprotobuf_2fdescriptor_2eproto[3];
+}
+bool FieldOptions_CType_IsValid(int value) {
+ switch (value) {
+ case 0:
+ case 1:
+ case 2:
+ return true;
+ default:
+ return false;
+ }
+}
+
+#if (__cplusplus < 201703) && (!defined(_MSC_VER) || (_MSC_VER >= 1900 && _MSC_VER < 1912))
+constexpr FieldOptions_CType FieldOptions::STRING;
+constexpr FieldOptions_CType FieldOptions::CORD;
+constexpr FieldOptions_CType FieldOptions::STRING_PIECE;
+constexpr FieldOptions_CType FieldOptions::CType_MIN;
+constexpr FieldOptions_CType FieldOptions::CType_MAX;
+constexpr int FieldOptions::CType_ARRAYSIZE;
+#endif // (__cplusplus < 201703) && (!defined(_MSC_VER) || (_MSC_VER >= 1900 && _MSC_VER < 1912))
+const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* FieldOptions_JSType_descriptor() {
+ ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fdescriptor_2eproto);
+ return file_level_enum_descriptors_google_2fprotobuf_2fdescriptor_2eproto[4];
+}
+bool FieldOptions_JSType_IsValid(int value) {
+ switch (value) {
+ case 0:
+ case 1:
+ case 2:
+ return true;
+ default:
+ return false;
+ }
+}
+
+#if (__cplusplus < 201703) && (!defined(_MSC_VER) || (_MSC_VER >= 1900 && _MSC_VER < 1912))
+constexpr FieldOptions_JSType FieldOptions::JS_NORMAL;
+constexpr FieldOptions_JSType FieldOptions::JS_STRING;
+constexpr FieldOptions_JSType FieldOptions::JS_NUMBER;
+constexpr FieldOptions_JSType FieldOptions::JSType_MIN;
+constexpr FieldOptions_JSType FieldOptions::JSType_MAX;
+constexpr int FieldOptions::JSType_ARRAYSIZE;
+#endif // (__cplusplus < 201703) && (!defined(_MSC_VER) || (_MSC_VER >= 1900 && _MSC_VER < 1912))
+const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* MethodOptions_IdempotencyLevel_descriptor() {
+ ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fdescriptor_2eproto);
+ return file_level_enum_descriptors_google_2fprotobuf_2fdescriptor_2eproto[5];
+}
+bool MethodOptions_IdempotencyLevel_IsValid(int value) {
+ switch (value) {
+ case 0:
+ case 1:
+ case 2:
+ return true;
+ default:
+ return false;
+ }
+}
+
+#if (__cplusplus < 201703) && (!defined(_MSC_VER) || (_MSC_VER >= 1900 && _MSC_VER < 1912))
+constexpr MethodOptions_IdempotencyLevel MethodOptions::IDEMPOTENCY_UNKNOWN;
+constexpr MethodOptions_IdempotencyLevel MethodOptions::NO_SIDE_EFFECTS;
+constexpr MethodOptions_IdempotencyLevel MethodOptions::IDEMPOTENT;
+constexpr MethodOptions_IdempotencyLevel MethodOptions::IdempotencyLevel_MIN;
+constexpr MethodOptions_IdempotencyLevel MethodOptions::IdempotencyLevel_MAX;
+constexpr int MethodOptions::IdempotencyLevel_ARRAYSIZE;
+#endif // (__cplusplus < 201703) && (!defined(_MSC_VER) || (_MSC_VER >= 1900 && _MSC_VER < 1912))
+
+// ===================================================================
+
+class FileDescriptorSet::_Internal {
+ public:
+};
+
+FileDescriptorSet::FileDescriptorSet(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned)
+ : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned),
+ file_(arena) {
+ SharedCtor();
+ if (!is_message_owned) {
+ RegisterArenaDtor(arena);
+ }
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.FileDescriptorSet)
+}
+FileDescriptorSet::FileDescriptorSet(const FileDescriptorSet& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message(),
+ file_(from.file_) {
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.FileDescriptorSet)
+}
+
+inline void FileDescriptorSet::SharedCtor() {
+}
+
+FileDescriptorSet::~FileDescriptorSet() {
+ // @@protoc_insertion_point(destructor:google.protobuf.FileDescriptorSet)
+ if (GetArenaForAllocation() != nullptr) return;
+ SharedDtor();
+ _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+inline void FileDescriptorSet::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+}
+
+void FileDescriptorSet::ArenaDtor(void* object) {
+ FileDescriptorSet* _this = reinterpret_cast< FileDescriptorSet* >(object);
+ (void)_this;
+}
+void FileDescriptorSet::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) {
+}
+void FileDescriptorSet::SetCachedSize(int size) const {
+ _cached_size_.Set(size);
+}
+
+void FileDescriptorSet::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.FileDescriptorSet)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ file_.Clear();
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* FileDescriptorSet::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag);
+ switch (tag >> 3) {
+ // repeated .google.protobuf.FileDescriptorProto file = 1;
+ case 1:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 10)) {
+ ptr -= 1;
+ do {
+ ptr += 1;
+ ptr = ctx->ParseMessage(_internal_add_file(), ptr);
+ CHK_(ptr);
+ if (!ctx->DataAvailable(ptr)) break;
+ } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<10>(ptr));
+ } else
+ goto handle_unusual;
+ continue;
+ default:
+ goto handle_unusual;
+ } // switch
+ handle_unusual:
+ if ((tag == 0) || ((tag & 7) == 4)) {
+ CHK_(ptr);
+ ctx->SetLastTag(tag);
+ goto message_done;
+ }
+ ptr = UnknownFieldParse(
+ tag,
+ _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(),
+ ptr, ctx);
+ CHK_(ptr != nullptr);
+ } // while
+message_done:
+ return ptr;
+failure:
+ ptr = nullptr;
+ goto message_done;
+#undef CHK_
+}
+
+uint8_t* FileDescriptorSet::_InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const {
+ // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.FileDescriptorSet)
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ // repeated .google.protobuf.FileDescriptorProto file = 1;
+ for (unsigned int i = 0,
+ n = static_cast<unsigned int>(this->_internal_file_size()); i < n; i++) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(1, this->_internal_file(i), target, stream);
+ }
+
+ if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray(
+ _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.FileDescriptorSet)
+ return target;
+}
+
+size_t FileDescriptorSet::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.FileDescriptorSet)
+ size_t total_size = 0;
+
+ 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->file_) {
+ total_size +=
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg);
+ }
+
+ return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData FileDescriptorSet::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck,
+ FileDescriptorSet::MergeImpl
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*FileDescriptorSet::GetClassData() const { return &_class_data_; }
+
+void FileDescriptorSet::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to,
+ const ::PROTOBUF_NAMESPACE_ID::Message& from) {
+ static_cast<FileDescriptorSet *>(to)->MergeFrom(
+ static_cast<const FileDescriptorSet &>(from));
+}
+
+
+void FileDescriptorSet::MergeFrom(const FileDescriptorSet& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.FileDescriptorSet)
+ GOOGLE_DCHECK_NE(&from, this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ file_.MergeFrom(from.file_);
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+}
+
+void FileDescriptorSet::CopyFrom(const FileDescriptorSet& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.FileDescriptorSet)
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+bool FileDescriptorSet::IsInitialized() const {
+ if (!::PROTOBUF_NAMESPACE_ID::internal::AllAreInitialized(file_))
+ return false;
+ return true;
+}
+
+void FileDescriptorSet::InternalSwap(FileDescriptorSet* other) {
+ using std::swap;
+ _internal_metadata_.InternalSwap(&other->_internal_metadata_);
+ file_.InternalSwap(&other->file_);
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata FileDescriptorSet::GetMetadata() const {
+ return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(
+ &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
+ file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[0]);
+}
+
+// ===================================================================
+
+class FileDescriptorProto::_Internal {
+ public:
+ using HasBits = decltype(std::declval<FileDescriptorProto>()._has_bits_);
+ static void set_has_name(HasBits* has_bits) {
+ (*has_bits)[0] |= 1u;
+ }
+ static void set_has_package(HasBits* has_bits) {
+ (*has_bits)[0] |= 2u;
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::FileOptions& options(const FileDescriptorProto* msg);
+ static void set_has_options(HasBits* has_bits) {
+ (*has_bits)[0] |= 8u;
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo& source_code_info(const FileDescriptorProto* msg);
+ static void set_has_source_code_info(HasBits* has_bits) {
+ (*has_bits)[0] |= 16u;
+ }
+ static void set_has_syntax(HasBits* has_bits) {
+ (*has_bits)[0] |= 4u;
+ }
+};
+
+const ::PROTOBUF_NAMESPACE_ID::FileOptions&
+FileDescriptorProto::_Internal::options(const FileDescriptorProto* msg) {
+ return *msg->options_;
+}
+const ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo&
+FileDescriptorProto::_Internal::source_code_info(const FileDescriptorProto* msg) {
+ return *msg->source_code_info_;
+}
+FileDescriptorProto::FileDescriptorProto(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned)
+ : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned),
+ dependency_(arena),
+ message_type_(arena),
+ enum_type_(arena),
+ service_(arena),
+ extension_(arena),
+ public_dependency_(arena),
+ weak_dependency_(arena) {
+ SharedCtor();
+ if (!is_message_owned) {
+ RegisterArenaDtor(arena);
+ }
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.FileDescriptorProto)
+}
+FileDescriptorProto::FileDescriptorProto(const FileDescriptorProto& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message(),
+ _has_bits_(from._has_bits_),
+ dependency_(from.dependency_),
+ message_type_(from.message_type_),
+ enum_type_(from.enum_type_),
+ service_(from.service_),
+ extension_(from.extension_),
+ public_dependency_(from.public_dependency_),
+ weak_dependency_(from.weak_dependency_) {
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (from._internal_has_name()) {
+ name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_name(),
+ GetArenaForAllocation());
+ }
+ package_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ package_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (from._internal_has_package()) {
+ package_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_package(),
+ GetArenaForAllocation());
+ }
+ syntax_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ syntax_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (from._internal_has_syntax()) {
+ syntax_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_syntax(),
+ GetArenaForAllocation());
+ }
+ if (from._internal_has_options()) {
+ options_ = new ::PROTOBUF_NAMESPACE_ID::FileOptions(*from.options_);
+ } else {
+ options_ = nullptr;
+ }
+ if (from._internal_has_source_code_info()) {
+ source_code_info_ = new ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo(*from.source_code_info_);
+ } else {
+ source_code_info_ = nullptr;
+ }
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.FileDescriptorProto)
+}
+
+inline void FileDescriptorProto::SharedCtor() {
+name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+package_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ package_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+syntax_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ syntax_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+::memset(reinterpret_cast<char*>(this) + static_cast<size_t>(
+ reinterpret_cast<char*>(&options_) - reinterpret_cast<char*>(this)),
+ 0, static_cast<size_t>(reinterpret_cast<char*>(&source_code_info_) -
+ reinterpret_cast<char*>(&options_)) + sizeof(source_code_info_));
+}
+
+FileDescriptorProto::~FileDescriptorProto() {
+ // @@protoc_insertion_point(destructor:google.protobuf.FileDescriptorProto)
+ if (GetArenaForAllocation() != nullptr) return;
+ SharedDtor();
+ _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+inline void FileDescriptorProto::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+ name_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ package_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ syntax_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ if (this != internal_default_instance()) delete options_;
+ if (this != internal_default_instance()) delete source_code_info_;
+}
+
+void FileDescriptorProto::ArenaDtor(void* object) {
+ FileDescriptorProto* _this = reinterpret_cast< FileDescriptorProto* >(object);
+ (void)_this;
+}
+void FileDescriptorProto::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) {
+}
+void FileDescriptorProto::SetCachedSize(int size) const {
+ _cached_size_.Set(size);
+}
+
+void FileDescriptorProto::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.FileDescriptorProto)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ dependency_.Clear();
+ message_type_.Clear();
+ enum_type_.Clear();
+ service_.Clear();
+ extension_.Clear();
+ public_dependency_.Clear();
+ weak_dependency_.Clear();
+ cached_has_bits = _has_bits_[0];
+ if (cached_has_bits & 0x0000001fu) {
+ if (cached_has_bits & 0x00000001u) {
+ name_.ClearNonDefaultToEmpty();
+ }
+ if (cached_has_bits & 0x00000002u) {
+ package_.ClearNonDefaultToEmpty();
+ }
+ if (cached_has_bits & 0x00000004u) {
+ syntax_.ClearNonDefaultToEmpty();
+ }
+ if (cached_has_bits & 0x00000008u) {
+ GOOGLE_DCHECK(options_ != nullptr);
+ options_->Clear();
+ }
+ if (cached_has_bits & 0x00000010u) {
+ GOOGLE_DCHECK(source_code_info_ != nullptr);
+ source_code_info_->Clear();
+ }
+ }
+ _has_bits_.Clear();
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* FileDescriptorProto::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ _Internal::HasBits has_bits{};
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag);
+ switch (tag >> 3) {
+ // optional string name = 1;
+ case 1:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 10)) {
+ auto str = _internal_mutable_name();
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx);
+ #ifndef NDEBUG
+ ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.FileDescriptorProto.name");
+ #endif // !NDEBUG
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // optional string package = 2;
+ case 2:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 18)) {
+ auto str = _internal_mutable_package();
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx);
+ #ifndef NDEBUG
+ ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.FileDescriptorProto.package");
+ #endif // !NDEBUG
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // repeated string dependency = 3;
+ case 3:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 26)) {
+ ptr -= 1;
+ do {
+ ptr += 1;
+ auto str = _internal_add_dependency();
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx);
+ #ifndef NDEBUG
+ ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.FileDescriptorProto.dependency");
+ #endif // !NDEBUG
+ CHK_(ptr);
+ if (!ctx->DataAvailable(ptr)) break;
+ } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<26>(ptr));
+ } else
+ goto handle_unusual;
+ continue;
+ // repeated .google.protobuf.DescriptorProto message_type = 4;
+ case 4:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 34)) {
+ ptr -= 1;
+ do {
+ ptr += 1;
+ ptr = ctx->ParseMessage(_internal_add_message_type(), ptr);
+ CHK_(ptr);
+ if (!ctx->DataAvailable(ptr)) break;
+ } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<34>(ptr));
+ } else
+ goto handle_unusual;
+ continue;
+ // repeated .google.protobuf.EnumDescriptorProto enum_type = 5;
+ case 5:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 42)) {
+ ptr -= 1;
+ do {
+ ptr += 1;
+ ptr = ctx->ParseMessage(_internal_add_enum_type(), ptr);
+ CHK_(ptr);
+ if (!ctx->DataAvailable(ptr)) break;
+ } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<42>(ptr));
+ } else
+ goto handle_unusual;
+ continue;
+ // repeated .google.protobuf.ServiceDescriptorProto service = 6;
+ case 6:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 50)) {
+ ptr -= 1;
+ do {
+ ptr += 1;
+ ptr = ctx->ParseMessage(_internal_add_service(), ptr);
+ CHK_(ptr);
+ if (!ctx->DataAvailable(ptr)) break;
+ } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<50>(ptr));
+ } else
+ goto handle_unusual;
+ continue;
+ // repeated .google.protobuf.FieldDescriptorProto extension = 7;
+ case 7:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 58)) {
+ ptr -= 1;
+ do {
+ ptr += 1;
+ ptr = ctx->ParseMessage(_internal_add_extension(), ptr);
+ CHK_(ptr);
+ if (!ctx->DataAvailable(ptr)) break;
+ } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<58>(ptr));
+ } else
+ goto handle_unusual;
+ continue;
+ // optional .google.protobuf.FileOptions options = 8;
+ case 8:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 66)) {
+ ptr = ctx->ParseMessage(_internal_mutable_options(), ptr);
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // optional .google.protobuf.SourceCodeInfo source_code_info = 9;
+ case 9:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 74)) {
+ ptr = ctx->ParseMessage(_internal_mutable_source_code_info(), ptr);
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // repeated int32 public_dependency = 10;
+ case 10:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 80)) {
+ ptr -= 1;
+ do {
+ ptr += 1;
+ _internal_add_public_dependency(::PROTOBUF_NAMESPACE_ID::internal::ReadVarint32(&ptr));
+ CHK_(ptr);
+ if (!ctx->DataAvailable(ptr)) break;
+ } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<80>(ptr));
+ } else if (static_cast<uint8_t>(tag) == 82) {
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::PackedInt32Parser(_internal_mutable_public_dependency(), ptr, ctx);
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // repeated int32 weak_dependency = 11;
+ case 11:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 88)) {
+ ptr -= 1;
+ do {
+ ptr += 1;
+ _internal_add_weak_dependency(::PROTOBUF_NAMESPACE_ID::internal::ReadVarint32(&ptr));
+ CHK_(ptr);
+ if (!ctx->DataAvailable(ptr)) break;
+ } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<88>(ptr));
+ } else if (static_cast<uint8_t>(tag) == 90) {
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::PackedInt32Parser(_internal_mutable_weak_dependency(), ptr, ctx);
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // optional string syntax = 12;
+ case 12:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 98)) {
+ auto str = _internal_mutable_syntax();
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx);
+ #ifndef NDEBUG
+ ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.FileDescriptorProto.syntax");
+ #endif // !NDEBUG
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ default:
+ goto handle_unusual;
+ } // switch
+ handle_unusual:
+ if ((tag == 0) || ((tag & 7) == 4)) {
+ CHK_(ptr);
+ ctx->SetLastTag(tag);
+ goto message_done;
+ }
+ ptr = UnknownFieldParse(
+ tag,
+ _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(),
+ ptr, ctx);
+ CHK_(ptr != nullptr);
+ } // while
+message_done:
+ _has_bits_.Or(has_bits);
+ return ptr;
+failure:
+ ptr = nullptr;
+ goto message_done;
+#undef CHK_
+}
+
+uint8_t* FileDescriptorProto::_InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const {
+ // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.FileDescriptorProto)
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ cached_has_bits = _has_bits_[0];
+ // optional string name = 1;
+ if (cached_has_bits & 0x00000001u) {
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField(
+ this->_internal_name().data(), static_cast<int>(this->_internal_name().length()),
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE,
+ "google.protobuf.FileDescriptorProto.name");
+ target = stream->WriteStringMaybeAliased(
+ 1, this->_internal_name(), target);
+ }
+
+ // optional string package = 2;
+ if (cached_has_bits & 0x00000002u) {
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField(
+ this->_internal_package().data(), static_cast<int>(this->_internal_package().length()),
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE,
+ "google.protobuf.FileDescriptorProto.package");
+ target = stream->WriteStringMaybeAliased(
+ 2, this->_internal_package(), target);
+ }
+
+ // repeated string dependency = 3;
+ for (int i = 0, n = this->_internal_dependency_size(); i < n; i++) {
+ const auto& s = this->_internal_dependency(i);
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField(
+ s.data(), static_cast<int>(s.length()),
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE,
+ "google.protobuf.FileDescriptorProto.dependency");
+ target = stream->WriteString(3, s, target);
+ }
+
+ // repeated .google.protobuf.DescriptorProto message_type = 4;
+ for (unsigned int i = 0,
+ n = static_cast<unsigned int>(this->_internal_message_type_size()); i < n; i++) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(4, this->_internal_message_type(i), target, stream);
+ }
+
+ // repeated .google.protobuf.EnumDescriptorProto enum_type = 5;
+ for (unsigned int i = 0,
+ n = static_cast<unsigned int>(this->_internal_enum_type_size()); i < n; i++) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(5, this->_internal_enum_type(i), target, stream);
+ }
+
+ // repeated .google.protobuf.ServiceDescriptorProto service = 6;
+ for (unsigned int i = 0,
+ n = static_cast<unsigned int>(this->_internal_service_size()); i < n; i++) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(6, this->_internal_service(i), target, stream);
+ }
+
+ // repeated .google.protobuf.FieldDescriptorProto extension = 7;
+ for (unsigned int i = 0,
+ n = static_cast<unsigned int>(this->_internal_extension_size()); i < n; i++) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(7, this->_internal_extension(i), target, stream);
+ }
+
+ // optional .google.protobuf.FileOptions options = 8;
+ if (cached_has_bits & 0x00000008u) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(
+ 8, _Internal::options(this), target, stream);
+ }
+
+ // optional .google.protobuf.SourceCodeInfo source_code_info = 9;
+ if (cached_has_bits & 0x00000010u) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(
+ 9, _Internal::source_code_info(this), target, stream);
+ }
+
+ // repeated int32 public_dependency = 10;
+ for (int i = 0, n = this->_internal_public_dependency_size(); i < n; i++) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32ToArray(10, this->_internal_public_dependency(i), target);
+ }
+
+ // repeated int32 weak_dependency = 11;
+ for (int i = 0, n = this->_internal_weak_dependency_size(); i < n; i++) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32ToArray(11, this->_internal_weak_dependency(i), target);
+ }
+
+ // optional string syntax = 12;
+ if (cached_has_bits & 0x00000004u) {
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField(
+ this->_internal_syntax().data(), static_cast<int>(this->_internal_syntax().length()),
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE,
+ "google.protobuf.FileDescriptorProto.syntax");
+ target = stream->WriteStringMaybeAliased(
+ 12, this->_internal_syntax(), target);
+ }
+
+ if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray(
+ _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.FileDescriptorProto)
+ return target;
+}
+
+size_t FileDescriptorProto::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.FileDescriptorProto)
+ size_t total_size = 0;
+
+ 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(dependency_.size());
+ for (int i = 0, n = dependency_.size(); i < n; i++) {
+ total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
+ dependency_.Get(i));
+ }
+
+ // repeated .google.protobuf.DescriptorProto message_type = 4;
+ total_size += 1UL * this->_internal_message_type_size();
+ for (const auto& msg : this->message_type_) {
+ total_size +=
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg);
+ }
+
+ // repeated .google.protobuf.EnumDescriptorProto enum_type = 5;
+ total_size += 1UL * this->_internal_enum_type_size();
+ for (const auto& msg : this->enum_type_) {
+ total_size +=
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg);
+ }
+
+ // repeated .google.protobuf.ServiceDescriptorProto service = 6;
+ total_size += 1UL * this->_internal_service_size();
+ for (const auto& msg : this->service_) {
+ total_size +=
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg);
+ }
+
+ // repeated .google.protobuf.FieldDescriptorProto extension = 7;
+ total_size += 1UL * this->_internal_extension_size();
+ for (const auto& msg : this->extension_) {
+ total_size +=
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg);
+ }
+
+ // repeated int32 public_dependency = 10;
+ {
+ size_t data_size = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ Int32Size(this->public_dependency_);
+ total_size += 1 *
+ ::PROTOBUF_NAMESPACE_ID::internal::FromIntSize(this->_internal_public_dependency_size());
+ total_size += data_size;
+ }
+
+ // repeated int32 weak_dependency = 11;
+ {
+ size_t data_size = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ Int32Size(this->weak_dependency_);
+ total_size += 1 *
+ ::PROTOBUF_NAMESPACE_ID::internal::FromIntSize(this->_internal_weak_dependency_size());
+ total_size += data_size;
+ }
+
+ cached_has_bits = _has_bits_[0];
+ if (cached_has_bits & 0x0000001fu) {
+ // optional string name = 1;
+ if (cached_has_bits & 0x00000001u) {
+ total_size += 1 +
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
+ this->_internal_name());
+ }
+
+ // optional string package = 2;
+ if (cached_has_bits & 0x00000002u) {
+ total_size += 1 +
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
+ this->_internal_package());
+ }
+
+ // optional string syntax = 12;
+ if (cached_has_bits & 0x00000004u) {
+ total_size += 1 +
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
+ this->_internal_syntax());
+ }
+
+ // optional .google.protobuf.FileOptions options = 8;
+ if (cached_has_bits & 0x00000008u) {
+ total_size += 1 +
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(
+ *options_);
+ }
+
+ // optional .google.protobuf.SourceCodeInfo source_code_info = 9;
+ if (cached_has_bits & 0x00000010u) {
+ total_size += 1 +
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(
+ *source_code_info_);
+ }
+
+ }
+ return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData FileDescriptorProto::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck,
+ FileDescriptorProto::MergeImpl
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*FileDescriptorProto::GetClassData() const { return &_class_data_; }
+
+void FileDescriptorProto::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to,
+ const ::PROTOBUF_NAMESPACE_ID::Message& from) {
+ static_cast<FileDescriptorProto *>(to)->MergeFrom(
+ static_cast<const FileDescriptorProto &>(from));
+}
+
+
+void FileDescriptorProto::MergeFrom(const FileDescriptorProto& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.FileDescriptorProto)
+ GOOGLE_DCHECK_NE(&from, this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ dependency_.MergeFrom(from.dependency_);
+ message_type_.MergeFrom(from.message_type_);
+ enum_type_.MergeFrom(from.enum_type_);
+ service_.MergeFrom(from.service_);
+ extension_.MergeFrom(from.extension_);
+ public_dependency_.MergeFrom(from.public_dependency_);
+ weak_dependency_.MergeFrom(from.weak_dependency_);
+ cached_has_bits = from._has_bits_[0];
+ if (cached_has_bits & 0x0000001fu) {
+ if (cached_has_bits & 0x00000001u) {
+ _internal_set_name(from._internal_name());
+ }
+ if (cached_has_bits & 0x00000002u) {
+ _internal_set_package(from._internal_package());
+ }
+ if (cached_has_bits & 0x00000004u) {
+ _internal_set_syntax(from._internal_syntax());
+ }
+ if (cached_has_bits & 0x00000008u) {
+ _internal_mutable_options()->::PROTOBUF_NAMESPACE_ID::FileOptions::MergeFrom(from._internal_options());
+ }
+ if (cached_has_bits & 0x00000010u) {
+ _internal_mutable_source_code_info()->::PROTOBUF_NAMESPACE_ID::SourceCodeInfo::MergeFrom(from._internal_source_code_info());
+ }
+ }
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+}
+
+void FileDescriptorProto::CopyFrom(const FileDescriptorProto& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.FileDescriptorProto)
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+bool FileDescriptorProto::IsInitialized() const {
+ if (!::PROTOBUF_NAMESPACE_ID::internal::AllAreInitialized(message_type_))
+ return false;
+ if (!::PROTOBUF_NAMESPACE_ID::internal::AllAreInitialized(enum_type_))
+ return false;
+ if (!::PROTOBUF_NAMESPACE_ID::internal::AllAreInitialized(service_))
+ return false;
+ if (!::PROTOBUF_NAMESPACE_ID::internal::AllAreInitialized(extension_))
+ return false;
+ if (_internal_has_options()) {
+ if (!options_->IsInitialized()) return false;
+ }
+ return true;
+}
+
+void FileDescriptorProto::InternalSwap(FileDescriptorProto* other) {
+ using std::swap;
+ auto* lhs_arena = GetArenaForAllocation();
+ auto* rhs_arena = other->GetArenaForAllocation();
+ _internal_metadata_.InternalSwap(&other->_internal_metadata_);
+ swap(_has_bits_[0], other->_has_bits_[0]);
+ dependency_.InternalSwap(&other->dependency_);
+ message_type_.InternalSwap(&other->message_type_);
+ enum_type_.InternalSwap(&other->enum_type_);
+ service_.InternalSwap(&other->service_);
+ extension_.InternalSwap(&other->extension_);
+ public_dependency_.InternalSwap(&other->public_dependency_);
+ weak_dependency_.InternalSwap(&other->weak_dependency_);
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(),
+ &name_, lhs_arena,
+ &other->name_, rhs_arena
+ );
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(),
+ &package_, lhs_arena,
+ &other->package_, rhs_arena
+ );
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(),
+ &syntax_, lhs_arena,
+ &other->syntax_, rhs_arena
+ );
+ ::PROTOBUF_NAMESPACE_ID::internal::memswap<
+ PROTOBUF_FIELD_OFFSET(FileDescriptorProto, source_code_info_)
+ + sizeof(FileDescriptorProto::source_code_info_)
+ - PROTOBUF_FIELD_OFFSET(FileDescriptorProto, options_)>(
+ reinterpret_cast<char*>(&options_),
+ reinterpret_cast<char*>(&other->options_));
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata FileDescriptorProto::GetMetadata() const {
+ return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(
+ &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
+ file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[1]);
+}
+
+// ===================================================================
+
+class DescriptorProto_ExtensionRange::_Internal {
+ public:
+ using HasBits = decltype(std::declval<DescriptorProto_ExtensionRange>()._has_bits_);
+ static void set_has_start(HasBits* has_bits) {
+ (*has_bits)[0] |= 2u;
+ }
+ static void set_has_end(HasBits* has_bits) {
+ (*has_bits)[0] |= 4u;
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions& options(const DescriptorProto_ExtensionRange* msg);
+ static void set_has_options(HasBits* has_bits) {
+ (*has_bits)[0] |= 1u;
+ }
+};
+
+const ::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions&
+DescriptorProto_ExtensionRange::_Internal::options(const DescriptorProto_ExtensionRange* msg) {
+ return *msg->options_;
+}
+DescriptorProto_ExtensionRange::DescriptorProto_ExtensionRange(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned)
+ : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) {
+ SharedCtor();
+ if (!is_message_owned) {
+ RegisterArenaDtor(arena);
+ }
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.DescriptorProto.ExtensionRange)
+}
+DescriptorProto_ExtensionRange::DescriptorProto_ExtensionRange(const DescriptorProto_ExtensionRange& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message(),
+ _has_bits_(from._has_bits_) {
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ if (from._internal_has_options()) {
+ options_ = new ::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions(*from.options_);
+ } else {
+ options_ = nullptr;
+ }
+ ::memcpy(&start_, &from.start_,
+ static_cast<size_t>(reinterpret_cast<char*>(&end_) -
+ reinterpret_cast<char*>(&start_)) + sizeof(end_));
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.DescriptorProto.ExtensionRange)
+}
+
+inline void DescriptorProto_ExtensionRange::SharedCtor() {
+::memset(reinterpret_cast<char*>(this) + static_cast<size_t>(
+ reinterpret_cast<char*>(&options_) - reinterpret_cast<char*>(this)),
+ 0, static_cast<size_t>(reinterpret_cast<char*>(&end_) -
+ reinterpret_cast<char*>(&options_)) + sizeof(end_));
+}
+
+DescriptorProto_ExtensionRange::~DescriptorProto_ExtensionRange() {
+ // @@protoc_insertion_point(destructor:google.protobuf.DescriptorProto.ExtensionRange)
+ if (GetArenaForAllocation() != nullptr) return;
+ SharedDtor();
+ _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+inline void DescriptorProto_ExtensionRange::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+ if (this != internal_default_instance()) delete options_;
+}
+
+void DescriptorProto_ExtensionRange::ArenaDtor(void* object) {
+ DescriptorProto_ExtensionRange* _this = reinterpret_cast< DescriptorProto_ExtensionRange* >(object);
+ (void)_this;
+}
+void DescriptorProto_ExtensionRange::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) {
+}
+void DescriptorProto_ExtensionRange::SetCachedSize(int size) const {
+ _cached_size_.Set(size);
+}
+
+void DescriptorProto_ExtensionRange::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.DescriptorProto.ExtensionRange)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ cached_has_bits = _has_bits_[0];
+ if (cached_has_bits & 0x00000001u) {
+ GOOGLE_DCHECK(options_ != nullptr);
+ options_->Clear();
+ }
+ if (cached_has_bits & 0x00000006u) {
+ ::memset(&start_, 0, static_cast<size_t>(
+ reinterpret_cast<char*>(&end_) -
+ reinterpret_cast<char*>(&start_)) + sizeof(end_));
+ }
+ _has_bits_.Clear();
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* DescriptorProto_ExtensionRange::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ _Internal::HasBits has_bits{};
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag);
+ switch (tag >> 3) {
+ // optional int32 start = 1;
+ case 1:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 8)) {
+ _Internal::set_has_start(&has_bits);
+ start_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint32(&ptr);
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // optional int32 end = 2;
+ case 2:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 16)) {
+ _Internal::set_has_end(&has_bits);
+ end_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint32(&ptr);
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // optional .google.protobuf.ExtensionRangeOptions options = 3;
+ case 3:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 26)) {
+ ptr = ctx->ParseMessage(_internal_mutable_options(), ptr);
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ default:
+ goto handle_unusual;
+ } // switch
+ handle_unusual:
+ if ((tag == 0) || ((tag & 7) == 4)) {
+ CHK_(ptr);
+ ctx->SetLastTag(tag);
+ goto message_done;
+ }
+ ptr = UnknownFieldParse(
+ tag,
+ _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(),
+ ptr, ctx);
+ CHK_(ptr != nullptr);
+ } // while
+message_done:
+ _has_bits_.Or(has_bits);
+ return ptr;
+failure:
+ ptr = nullptr;
+ goto message_done;
+#undef CHK_
+}
+
+uint8_t* DescriptorProto_ExtensionRange::_InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const {
+ // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.DescriptorProto.ExtensionRange)
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ cached_has_bits = _has_bits_[0];
+ // optional int32 start = 1;
+ if (cached_has_bits & 0x00000002u) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32ToArray(1, this->_internal_start(), target);
+ }
+
+ // optional int32 end = 2;
+ if (cached_has_bits & 0x00000004u) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32ToArray(2, this->_internal_end(), target);
+ }
+
+ // optional .google.protobuf.ExtensionRangeOptions options = 3;
+ if (cached_has_bits & 0x00000001u) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(
+ 3, _Internal::options(this), target, stream);
+ }
+
+ if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray(
+ _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.DescriptorProto.ExtensionRange)
+ return target;
+}
+
+size_t DescriptorProto_ExtensionRange::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.DescriptorProto.ExtensionRange)
+ size_t total_size = 0;
+
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ cached_has_bits = _has_bits_[0];
+ if (cached_has_bits & 0x00000007u) {
+ // optional .google.protobuf.ExtensionRangeOptions options = 3;
+ if (cached_has_bits & 0x00000001u) {
+ total_size += 1 +
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(
+ *options_);
+ }
+
+ // optional int32 start = 1;
+ if (cached_has_bits & 0x00000002u) {
+ total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32SizePlusOne(this->_internal_start());
+ }
+
+ // optional int32 end = 2;
+ if (cached_has_bits & 0x00000004u) {
+ total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32SizePlusOne(this->_internal_end());
+ }
+
+ }
+ return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData DescriptorProto_ExtensionRange::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck,
+ DescriptorProto_ExtensionRange::MergeImpl
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*DescriptorProto_ExtensionRange::GetClassData() const { return &_class_data_; }
+
+void DescriptorProto_ExtensionRange::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to,
+ const ::PROTOBUF_NAMESPACE_ID::Message& from) {
+ static_cast<DescriptorProto_ExtensionRange *>(to)->MergeFrom(
+ static_cast<const DescriptorProto_ExtensionRange &>(from));
+}
+
+
+void DescriptorProto_ExtensionRange::MergeFrom(const DescriptorProto_ExtensionRange& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.DescriptorProto.ExtensionRange)
+ GOOGLE_DCHECK_NE(&from, this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ cached_has_bits = from._has_bits_[0];
+ if (cached_has_bits & 0x00000007u) {
+ if (cached_has_bits & 0x00000001u) {
+ _internal_mutable_options()->::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions::MergeFrom(from._internal_options());
+ }
+ if (cached_has_bits & 0x00000002u) {
+ start_ = from.start_;
+ }
+ if (cached_has_bits & 0x00000004u) {
+ end_ = from.end_;
+ }
+ _has_bits_[0] |= cached_has_bits;
+ }
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+}
+
+void DescriptorProto_ExtensionRange::CopyFrom(const DescriptorProto_ExtensionRange& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.DescriptorProto.ExtensionRange)
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+bool DescriptorProto_ExtensionRange::IsInitialized() const {
+ if (_internal_has_options()) {
+ if (!options_->IsInitialized()) return false;
+ }
+ return true;
+}
+
+void DescriptorProto_ExtensionRange::InternalSwap(DescriptorProto_ExtensionRange* other) {
+ using std::swap;
+ _internal_metadata_.InternalSwap(&other->_internal_metadata_);
+ swap(_has_bits_[0], other->_has_bits_[0]);
+ ::PROTOBUF_NAMESPACE_ID::internal::memswap<
+ PROTOBUF_FIELD_OFFSET(DescriptorProto_ExtensionRange, end_)
+ + sizeof(DescriptorProto_ExtensionRange::end_)
+ - PROTOBUF_FIELD_OFFSET(DescriptorProto_ExtensionRange, options_)>(
+ reinterpret_cast<char*>(&options_),
+ reinterpret_cast<char*>(&other->options_));
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata DescriptorProto_ExtensionRange::GetMetadata() const {
+ return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(
+ &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
+ file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[2]);
+}
+
+// ===================================================================
+
+class DescriptorProto_ReservedRange::_Internal {
+ public:
+ using HasBits = decltype(std::declval<DescriptorProto_ReservedRange>()._has_bits_);
+ static void set_has_start(HasBits* has_bits) {
+ (*has_bits)[0] |= 1u;
+ }
+ static void set_has_end(HasBits* has_bits) {
+ (*has_bits)[0] |= 2u;
+ }
+};
+
+DescriptorProto_ReservedRange::DescriptorProto_ReservedRange(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned)
+ : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) {
+ SharedCtor();
+ if (!is_message_owned) {
+ RegisterArenaDtor(arena);
+ }
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.DescriptorProto.ReservedRange)
+}
+DescriptorProto_ReservedRange::DescriptorProto_ReservedRange(const DescriptorProto_ReservedRange& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message(),
+ _has_bits_(from._has_bits_) {
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ ::memcpy(&start_, &from.start_,
+ static_cast<size_t>(reinterpret_cast<char*>(&end_) -
+ reinterpret_cast<char*>(&start_)) + sizeof(end_));
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.DescriptorProto.ReservedRange)
+}
+
+inline void DescriptorProto_ReservedRange::SharedCtor() {
+::memset(reinterpret_cast<char*>(this) + static_cast<size_t>(
+ reinterpret_cast<char*>(&start_) - reinterpret_cast<char*>(this)),
+ 0, static_cast<size_t>(reinterpret_cast<char*>(&end_) -
+ reinterpret_cast<char*>(&start_)) + sizeof(end_));
+}
+
+DescriptorProto_ReservedRange::~DescriptorProto_ReservedRange() {
+ // @@protoc_insertion_point(destructor:google.protobuf.DescriptorProto.ReservedRange)
+ if (GetArenaForAllocation() != nullptr) return;
+ SharedDtor();
+ _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+inline void DescriptorProto_ReservedRange::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+}
+
+void DescriptorProto_ReservedRange::ArenaDtor(void* object) {
+ DescriptorProto_ReservedRange* _this = reinterpret_cast< DescriptorProto_ReservedRange* >(object);
+ (void)_this;
+}
+void DescriptorProto_ReservedRange::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) {
+}
+void DescriptorProto_ReservedRange::SetCachedSize(int size) const {
+ _cached_size_.Set(size);
+}
+
+void DescriptorProto_ReservedRange::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.DescriptorProto.ReservedRange)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ cached_has_bits = _has_bits_[0];
+ if (cached_has_bits & 0x00000003u) {
+ ::memset(&start_, 0, static_cast<size_t>(
+ reinterpret_cast<char*>(&end_) -
+ reinterpret_cast<char*>(&start_)) + sizeof(end_));
+ }
+ _has_bits_.Clear();
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* DescriptorProto_ReservedRange::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ _Internal::HasBits has_bits{};
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag);
+ switch (tag >> 3) {
+ // optional int32 start = 1;
+ case 1:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 8)) {
+ _Internal::set_has_start(&has_bits);
+ start_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint32(&ptr);
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // optional int32 end = 2;
+ case 2:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 16)) {
+ _Internal::set_has_end(&has_bits);
+ end_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint32(&ptr);
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ default:
+ goto handle_unusual;
+ } // switch
+ handle_unusual:
+ if ((tag == 0) || ((tag & 7) == 4)) {
+ CHK_(ptr);
+ ctx->SetLastTag(tag);
+ goto message_done;
+ }
+ ptr = UnknownFieldParse(
+ tag,
+ _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(),
+ ptr, ctx);
+ CHK_(ptr != nullptr);
+ } // while
+message_done:
+ _has_bits_.Or(has_bits);
+ return ptr;
+failure:
+ ptr = nullptr;
+ goto message_done;
+#undef CHK_
+}
+
+uint8_t* DescriptorProto_ReservedRange::_InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const {
+ // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.DescriptorProto.ReservedRange)
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ cached_has_bits = _has_bits_[0];
+ // optional int32 start = 1;
+ if (cached_has_bits & 0x00000001u) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32ToArray(1, this->_internal_start(), target);
+ }
+
+ // optional int32 end = 2;
+ if (cached_has_bits & 0x00000002u) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32ToArray(2, this->_internal_end(), target);
+ }
+
+ if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray(
+ _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.DescriptorProto.ReservedRange)
+ return target;
+}
+
+size_t DescriptorProto_ReservedRange::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.DescriptorProto.ReservedRange)
+ size_t total_size = 0;
+
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ cached_has_bits = _has_bits_[0];
+ if (cached_has_bits & 0x00000003u) {
+ // optional int32 start = 1;
+ if (cached_has_bits & 0x00000001u) {
+ total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32SizePlusOne(this->_internal_start());
+ }
+
+ // optional int32 end = 2;
+ if (cached_has_bits & 0x00000002u) {
+ total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32SizePlusOne(this->_internal_end());
+ }
+
+ }
+ return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData DescriptorProto_ReservedRange::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck,
+ DescriptorProto_ReservedRange::MergeImpl
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*DescriptorProto_ReservedRange::GetClassData() const { return &_class_data_; }
+
+void DescriptorProto_ReservedRange::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to,
+ const ::PROTOBUF_NAMESPACE_ID::Message& from) {
+ static_cast<DescriptorProto_ReservedRange *>(to)->MergeFrom(
+ static_cast<const DescriptorProto_ReservedRange &>(from));
+}
+
+
+void DescriptorProto_ReservedRange::MergeFrom(const DescriptorProto_ReservedRange& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.DescriptorProto.ReservedRange)
+ GOOGLE_DCHECK_NE(&from, this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ cached_has_bits = from._has_bits_[0];
+ if (cached_has_bits & 0x00000003u) {
+ if (cached_has_bits & 0x00000001u) {
+ start_ = from.start_;
+ }
+ if (cached_has_bits & 0x00000002u) {
+ end_ = from.end_;
+ }
+ _has_bits_[0] |= cached_has_bits;
+ }
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+}
+
+void DescriptorProto_ReservedRange::CopyFrom(const DescriptorProto_ReservedRange& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.DescriptorProto.ReservedRange)
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+bool DescriptorProto_ReservedRange::IsInitialized() const {
+ return true;
+}
+
+void DescriptorProto_ReservedRange::InternalSwap(DescriptorProto_ReservedRange* other) {
+ using std::swap;
+ _internal_metadata_.InternalSwap(&other->_internal_metadata_);
+ swap(_has_bits_[0], other->_has_bits_[0]);
+ ::PROTOBUF_NAMESPACE_ID::internal::memswap<
+ PROTOBUF_FIELD_OFFSET(DescriptorProto_ReservedRange, end_)
+ + sizeof(DescriptorProto_ReservedRange::end_)
+ - PROTOBUF_FIELD_OFFSET(DescriptorProto_ReservedRange, start_)>(
+ reinterpret_cast<char*>(&start_),
+ reinterpret_cast<char*>(&other->start_));
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata DescriptorProto_ReservedRange::GetMetadata() const {
+ return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(
+ &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
+ file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[3]);
+}
+
+// ===================================================================
+
+class DescriptorProto::_Internal {
+ public:
+ using HasBits = decltype(std::declval<DescriptorProto>()._has_bits_);
+ static void set_has_name(HasBits* has_bits) {
+ (*has_bits)[0] |= 1u;
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::MessageOptions& options(const DescriptorProto* msg);
+ static void set_has_options(HasBits* has_bits) {
+ (*has_bits)[0] |= 2u;
+ }
+};
+
+const ::PROTOBUF_NAMESPACE_ID::MessageOptions&
+DescriptorProto::_Internal::options(const DescriptorProto* msg) {
+ return *msg->options_;
+}
+DescriptorProto::DescriptorProto(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned)
+ : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned),
+ field_(arena),
+ nested_type_(arena),
+ enum_type_(arena),
+ extension_range_(arena),
+ extension_(arena),
+ oneof_decl_(arena),
+ reserved_range_(arena),
+ reserved_name_(arena) {
+ SharedCtor();
+ if (!is_message_owned) {
+ RegisterArenaDtor(arena);
+ }
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.DescriptorProto)
+}
+DescriptorProto::DescriptorProto(const DescriptorProto& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message(),
+ _has_bits_(from._has_bits_),
+ field_(from.field_),
+ nested_type_(from.nested_type_),
+ enum_type_(from.enum_type_),
+ extension_range_(from.extension_range_),
+ extension_(from.extension_),
+ oneof_decl_(from.oneof_decl_),
+ reserved_range_(from.reserved_range_),
+ reserved_name_(from.reserved_name_) {
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (from._internal_has_name()) {
+ name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_name(),
+ GetArenaForAllocation());
+ }
+ if (from._internal_has_options()) {
+ options_ = new ::PROTOBUF_NAMESPACE_ID::MessageOptions(*from.options_);
+ } else {
+ options_ = nullptr;
+ }
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.DescriptorProto)
+}
+
+inline void DescriptorProto::SharedCtor() {
+name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+options_ = nullptr;
+}
+
+DescriptorProto::~DescriptorProto() {
+ // @@protoc_insertion_point(destructor:google.protobuf.DescriptorProto)
+ if (GetArenaForAllocation() != nullptr) return;
+ SharedDtor();
+ _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+inline void DescriptorProto::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+ name_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ if (this != internal_default_instance()) delete options_;
+}
+
+void DescriptorProto::ArenaDtor(void* object) {
+ DescriptorProto* _this = reinterpret_cast< DescriptorProto* >(object);
+ (void)_this;
+}
+void DescriptorProto::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) {
+}
+void DescriptorProto::SetCachedSize(int size) const {
+ _cached_size_.Set(size);
+}
+
+void DescriptorProto::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.DescriptorProto)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ field_.Clear();
+ nested_type_.Clear();
+ enum_type_.Clear();
+ extension_range_.Clear();
+ extension_.Clear();
+ oneof_decl_.Clear();
+ reserved_range_.Clear();
+ reserved_name_.Clear();
+ cached_has_bits = _has_bits_[0];
+ if (cached_has_bits & 0x00000003u) {
+ if (cached_has_bits & 0x00000001u) {
+ name_.ClearNonDefaultToEmpty();
+ }
+ if (cached_has_bits & 0x00000002u) {
+ GOOGLE_DCHECK(options_ != nullptr);
+ options_->Clear();
+ }
+ }
+ _has_bits_.Clear();
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* DescriptorProto::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ _Internal::HasBits has_bits{};
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag);
+ switch (tag >> 3) {
+ // optional string name = 1;
+ case 1:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 10)) {
+ auto str = _internal_mutable_name();
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx);
+ #ifndef NDEBUG
+ ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.DescriptorProto.name");
+ #endif // !NDEBUG
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // repeated .google.protobuf.FieldDescriptorProto field = 2;
+ case 2:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 18)) {
+ ptr -= 1;
+ do {
+ ptr += 1;
+ ptr = ctx->ParseMessage(_internal_add_field(), ptr);
+ CHK_(ptr);
+ if (!ctx->DataAvailable(ptr)) break;
+ } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<18>(ptr));
+ } else
+ goto handle_unusual;
+ continue;
+ // repeated .google.protobuf.DescriptorProto nested_type = 3;
+ case 3:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 26)) {
+ ptr -= 1;
+ do {
+ ptr += 1;
+ ptr = ctx->ParseMessage(_internal_add_nested_type(), ptr);
+ CHK_(ptr);
+ if (!ctx->DataAvailable(ptr)) break;
+ } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<26>(ptr));
+ } else
+ goto handle_unusual;
+ continue;
+ // repeated .google.protobuf.EnumDescriptorProto enum_type = 4;
+ case 4:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 34)) {
+ ptr -= 1;
+ do {
+ ptr += 1;
+ ptr = ctx->ParseMessage(_internal_add_enum_type(), ptr);
+ CHK_(ptr);
+ if (!ctx->DataAvailable(ptr)) break;
+ } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<34>(ptr));
+ } else
+ goto handle_unusual;
+ continue;
+ // repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5;
+ case 5:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 42)) {
+ ptr -= 1;
+ do {
+ ptr += 1;
+ ptr = ctx->ParseMessage(_internal_add_extension_range(), ptr);
+ CHK_(ptr);
+ if (!ctx->DataAvailable(ptr)) break;
+ } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<42>(ptr));
+ } else
+ goto handle_unusual;
+ continue;
+ // repeated .google.protobuf.FieldDescriptorProto extension = 6;
+ case 6:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 50)) {
+ ptr -= 1;
+ do {
+ ptr += 1;
+ ptr = ctx->ParseMessage(_internal_add_extension(), ptr);
+ CHK_(ptr);
+ if (!ctx->DataAvailable(ptr)) break;
+ } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<50>(ptr));
+ } else
+ goto handle_unusual;
+ continue;
+ // optional .google.protobuf.MessageOptions options = 7;
+ case 7:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 58)) {
+ ptr = ctx->ParseMessage(_internal_mutable_options(), ptr);
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // repeated .google.protobuf.OneofDescriptorProto oneof_decl = 8;
+ case 8:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 66)) {
+ ptr -= 1;
+ do {
+ ptr += 1;
+ ptr = ctx->ParseMessage(_internal_add_oneof_decl(), ptr);
+ CHK_(ptr);
+ if (!ctx->DataAvailable(ptr)) break;
+ } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<66>(ptr));
+ } else
+ goto handle_unusual;
+ continue;
+ // repeated .google.protobuf.DescriptorProto.ReservedRange reserved_range = 9;
+ case 9:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 74)) {
+ ptr -= 1;
+ do {
+ ptr += 1;
+ ptr = ctx->ParseMessage(_internal_add_reserved_range(), ptr);
+ CHK_(ptr);
+ if (!ctx->DataAvailable(ptr)) break;
+ } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<74>(ptr));
+ } else
+ goto handle_unusual;
+ continue;
+ // repeated string reserved_name = 10;
+ case 10:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 82)) {
+ ptr -= 1;
+ do {
+ ptr += 1;
+ auto str = _internal_add_reserved_name();
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx);
+ #ifndef NDEBUG
+ ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.DescriptorProto.reserved_name");
+ #endif // !NDEBUG
+ CHK_(ptr);
+ if (!ctx->DataAvailable(ptr)) break;
+ } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<82>(ptr));
+ } else
+ goto handle_unusual;
+ continue;
+ default:
+ goto handle_unusual;
+ } // switch
+ handle_unusual:
+ if ((tag == 0) || ((tag & 7) == 4)) {
+ CHK_(ptr);
+ ctx->SetLastTag(tag);
+ goto message_done;
+ }
+ ptr = UnknownFieldParse(
+ tag,
+ _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(),
+ ptr, ctx);
+ CHK_(ptr != nullptr);
+ } // while
+message_done:
+ _has_bits_.Or(has_bits);
+ return ptr;
+failure:
+ ptr = nullptr;
+ goto message_done;
+#undef CHK_
+}
+
+uint8_t* DescriptorProto::_InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const {
+ // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.DescriptorProto)
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ cached_has_bits = _has_bits_[0];
+ // optional string name = 1;
+ if (cached_has_bits & 0x00000001u) {
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField(
+ this->_internal_name().data(), static_cast<int>(this->_internal_name().length()),
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE,
+ "google.protobuf.DescriptorProto.name");
+ target = stream->WriteStringMaybeAliased(
+ 1, this->_internal_name(), target);
+ }
+
+ // repeated .google.protobuf.FieldDescriptorProto field = 2;
+ for (unsigned int i = 0,
+ n = static_cast<unsigned int>(this->_internal_field_size()); i < n; i++) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(2, this->_internal_field(i), target, stream);
+ }
+
+ // repeated .google.protobuf.DescriptorProto nested_type = 3;
+ for (unsigned int i = 0,
+ n = static_cast<unsigned int>(this->_internal_nested_type_size()); i < n; i++) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(3, this->_internal_nested_type(i), target, stream);
+ }
+
+ // repeated .google.protobuf.EnumDescriptorProto enum_type = 4;
+ for (unsigned int i = 0,
+ n = static_cast<unsigned int>(this->_internal_enum_type_size()); i < n; i++) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(4, this->_internal_enum_type(i), target, stream);
+ }
+
+ // repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5;
+ for (unsigned int i = 0,
+ n = static_cast<unsigned int>(this->_internal_extension_range_size()); i < n; i++) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(5, this->_internal_extension_range(i), target, stream);
+ }
+
+ // repeated .google.protobuf.FieldDescriptorProto extension = 6;
+ for (unsigned int i = 0,
+ n = static_cast<unsigned int>(this->_internal_extension_size()); i < n; i++) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(6, this->_internal_extension(i), target, stream);
+ }
+
+ // optional .google.protobuf.MessageOptions options = 7;
+ if (cached_has_bits & 0x00000002u) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(
+ 7, _Internal::options(this), target, stream);
+ }
+
+ // repeated .google.protobuf.OneofDescriptorProto oneof_decl = 8;
+ for (unsigned int i = 0,
+ n = static_cast<unsigned int>(this->_internal_oneof_decl_size()); i < n; i++) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(8, this->_internal_oneof_decl(i), target, stream);
+ }
+
+ // repeated .google.protobuf.DescriptorProto.ReservedRange reserved_range = 9;
+ for (unsigned int i = 0,
+ n = static_cast<unsigned int>(this->_internal_reserved_range_size()); i < n; i++) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(9, this->_internal_reserved_range(i), target, stream);
+ }
+
+ // repeated string reserved_name = 10;
+ for (int i = 0, n = this->_internal_reserved_name_size(); i < n; i++) {
+ const auto& s = this->_internal_reserved_name(i);
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField(
+ s.data(), static_cast<int>(s.length()),
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE,
+ "google.protobuf.DescriptorProto.reserved_name");
+ target = stream->WriteString(10, s, target);
+ }
+
+ if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray(
+ _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.DescriptorProto)
+ return target;
+}
+
+size_t DescriptorProto::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.DescriptorProto)
+ size_t total_size = 0;
+
+ 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->field_) {
+ total_size +=
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg);
+ }
+
+ // repeated .google.protobuf.DescriptorProto nested_type = 3;
+ total_size += 1UL * this->_internal_nested_type_size();
+ for (const auto& msg : this->nested_type_) {
+ total_size +=
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg);
+ }
+
+ // repeated .google.protobuf.EnumDescriptorProto enum_type = 4;
+ total_size += 1UL * this->_internal_enum_type_size();
+ for (const auto& msg : this->enum_type_) {
+ total_size +=
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg);
+ }
+
+ // repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5;
+ total_size += 1UL * this->_internal_extension_range_size();
+ for (const auto& msg : this->extension_range_) {
+ total_size +=
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg);
+ }
+
+ // repeated .google.protobuf.FieldDescriptorProto extension = 6;
+ total_size += 1UL * this->_internal_extension_size();
+ for (const auto& msg : this->extension_) {
+ total_size +=
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg);
+ }
+
+ // repeated .google.protobuf.OneofDescriptorProto oneof_decl = 8;
+ total_size += 1UL * this->_internal_oneof_decl_size();
+ for (const auto& msg : this->oneof_decl_) {
+ total_size +=
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg);
+ }
+
+ // repeated .google.protobuf.DescriptorProto.ReservedRange reserved_range = 9;
+ total_size += 1UL * this->_internal_reserved_range_size();
+ for (const auto& msg : this->reserved_range_) {
+ total_size +=
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg);
+ }
+
+ // repeated string reserved_name = 10;
+ total_size += 1 *
+ ::PROTOBUF_NAMESPACE_ID::internal::FromIntSize(reserved_name_.size());
+ for (int i = 0, n = reserved_name_.size(); i < n; i++) {
+ total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
+ reserved_name_.Get(i));
+ }
+
+ cached_has_bits = _has_bits_[0];
+ if (cached_has_bits & 0x00000003u) {
+ // optional string name = 1;
+ if (cached_has_bits & 0x00000001u) {
+ total_size += 1 +
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
+ this->_internal_name());
+ }
+
+ // optional .google.protobuf.MessageOptions options = 7;
+ if (cached_has_bits & 0x00000002u) {
+ total_size += 1 +
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(
+ *options_);
+ }
+
+ }
+ return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData DescriptorProto::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck,
+ DescriptorProto::MergeImpl
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*DescriptorProto::GetClassData() const { return &_class_data_; }
+
+void DescriptorProto::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to,
+ const ::PROTOBUF_NAMESPACE_ID::Message& from) {
+ static_cast<DescriptorProto *>(to)->MergeFrom(
+ static_cast<const DescriptorProto &>(from));
+}
+
+
+void DescriptorProto::MergeFrom(const DescriptorProto& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.DescriptorProto)
+ GOOGLE_DCHECK_NE(&from, this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ field_.MergeFrom(from.field_);
+ nested_type_.MergeFrom(from.nested_type_);
+ enum_type_.MergeFrom(from.enum_type_);
+ extension_range_.MergeFrom(from.extension_range_);
+ extension_.MergeFrom(from.extension_);
+ oneof_decl_.MergeFrom(from.oneof_decl_);
+ reserved_range_.MergeFrom(from.reserved_range_);
+ reserved_name_.MergeFrom(from.reserved_name_);
+ cached_has_bits = from._has_bits_[0];
+ if (cached_has_bits & 0x00000003u) {
+ if (cached_has_bits & 0x00000001u) {
+ _internal_set_name(from._internal_name());
+ }
+ if (cached_has_bits & 0x00000002u) {
+ _internal_mutable_options()->::PROTOBUF_NAMESPACE_ID::MessageOptions::MergeFrom(from._internal_options());
+ }
+ }
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+}
+
+void DescriptorProto::CopyFrom(const DescriptorProto& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.DescriptorProto)
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+bool DescriptorProto::IsInitialized() const {
+ if (!::PROTOBUF_NAMESPACE_ID::internal::AllAreInitialized(field_))
+ return false;
+ if (!::PROTOBUF_NAMESPACE_ID::internal::AllAreInitialized(nested_type_))
+ return false;
+ if (!::PROTOBUF_NAMESPACE_ID::internal::AllAreInitialized(enum_type_))
+ return false;
+ if (!::PROTOBUF_NAMESPACE_ID::internal::AllAreInitialized(extension_range_))
+ return false;
+ if (!::PROTOBUF_NAMESPACE_ID::internal::AllAreInitialized(extension_))
+ return false;
+ if (!::PROTOBUF_NAMESPACE_ID::internal::AllAreInitialized(oneof_decl_))
+ return false;
+ if (_internal_has_options()) {
+ if (!options_->IsInitialized()) return false;
+ }
+ return true;
+}
+
+void DescriptorProto::InternalSwap(DescriptorProto* other) {
+ using std::swap;
+ auto* lhs_arena = GetArenaForAllocation();
+ auto* rhs_arena = other->GetArenaForAllocation();
+ _internal_metadata_.InternalSwap(&other->_internal_metadata_);
+ swap(_has_bits_[0], other->_has_bits_[0]);
+ field_.InternalSwap(&other->field_);
+ nested_type_.InternalSwap(&other->nested_type_);
+ enum_type_.InternalSwap(&other->enum_type_);
+ extension_range_.InternalSwap(&other->extension_range_);
+ extension_.InternalSwap(&other->extension_);
+ oneof_decl_.InternalSwap(&other->oneof_decl_);
+ reserved_range_.InternalSwap(&other->reserved_range_);
+ reserved_name_.InternalSwap(&other->reserved_name_);
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(),
+ &name_, lhs_arena,
+ &other->name_, rhs_arena
+ );
+ swap(options_, other->options_);
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata DescriptorProto::GetMetadata() const {
+ return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(
+ &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
+ file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[4]);
+}
+
+// ===================================================================
+
+class ExtensionRangeOptions::_Internal {
+ public:
+};
+
+ExtensionRangeOptions::ExtensionRangeOptions(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned)
+ : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned),
+ _extensions_(arena),
+ uninterpreted_option_(arena) {
+ SharedCtor();
+ if (!is_message_owned) {
+ RegisterArenaDtor(arena);
+ }
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.ExtensionRangeOptions)
+}
+ExtensionRangeOptions::ExtensionRangeOptions(const ExtensionRangeOptions& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message(),
+ uninterpreted_option_(from.uninterpreted_option_) {
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ _extensions_.MergeFrom(internal_default_instance(), from._extensions_);
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.ExtensionRangeOptions)
+}
+
+inline void ExtensionRangeOptions::SharedCtor() {
+}
+
+ExtensionRangeOptions::~ExtensionRangeOptions() {
+ // @@protoc_insertion_point(destructor:google.protobuf.ExtensionRangeOptions)
+ if (GetArenaForAllocation() != nullptr) return;
+ SharedDtor();
+ _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+inline void ExtensionRangeOptions::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+}
+
+void ExtensionRangeOptions::ArenaDtor(void* object) {
+ ExtensionRangeOptions* _this = reinterpret_cast< ExtensionRangeOptions* >(object);
+ (void)_this;
+}
+void ExtensionRangeOptions::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) {
+}
+void ExtensionRangeOptions::SetCachedSize(int size) const {
+ _cached_size_.Set(size);
+}
+
+void ExtensionRangeOptions::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.ExtensionRangeOptions)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ _extensions_.Clear();
+ uninterpreted_option_.Clear();
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* ExtensionRangeOptions::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag);
+ switch (tag >> 3) {
+ // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+ case 999:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 58)) {
+ ptr -= 2;
+ do {
+ ptr += 2;
+ ptr = ctx->ParseMessage(_internal_add_uninterpreted_option(), ptr);
+ CHK_(ptr);
+ if (!ctx->DataAvailable(ptr)) break;
+ } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<7994>(ptr));
+ } else
+ goto handle_unusual;
+ continue;
+ default:
+ goto handle_unusual;
+ } // switch
+ handle_unusual:
+ if ((tag == 0) || ((tag & 7) == 4)) {
+ CHK_(ptr);
+ ctx->SetLastTag(tag);
+ goto message_done;
+ }
+ if ((8000u <= tag)) {
+ ptr = _extensions_.ParseField(tag, ptr, internal_default_instance(), &_internal_metadata_, ctx);
+ CHK_(ptr != nullptr);
+ continue;
+ }
+ ptr = UnknownFieldParse(
+ tag,
+ _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(),
+ ptr, ctx);
+ CHK_(ptr != nullptr);
+ } // while
+message_done:
+ return ptr;
+failure:
+ ptr = nullptr;
+ goto message_done;
+#undef CHK_
+}
+
+uint8_t* ExtensionRangeOptions::_InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const {
+ // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.ExtensionRangeOptions)
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+ for (unsigned int i = 0,
+ n = static_cast<unsigned int>(this->_internal_uninterpreted_option_size()); i < n; i++) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(999, this->_internal_uninterpreted_option(i), target, stream);
+ }
+
+ // Extension range [1000, 536870912)
+ target = _extensions_._InternalSerialize(
+ internal_default_instance(), 1000, 536870912, target, stream);
+
+ if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray(
+ _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.ExtensionRangeOptions)
+ return target;
+}
+
+size_t ExtensionRangeOptions::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.ExtensionRangeOptions)
+ size_t total_size = 0;
+
+ total_size += _extensions_.ByteSize();
+
+ 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->uninterpreted_option_) {
+ total_size +=
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg);
+ }
+
+ return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData ExtensionRangeOptions::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck,
+ ExtensionRangeOptions::MergeImpl
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*ExtensionRangeOptions::GetClassData() const { return &_class_data_; }
+
+void ExtensionRangeOptions::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to,
+ const ::PROTOBUF_NAMESPACE_ID::Message& from) {
+ static_cast<ExtensionRangeOptions *>(to)->MergeFrom(
+ static_cast<const ExtensionRangeOptions &>(from));
+}
+
+
+void ExtensionRangeOptions::MergeFrom(const ExtensionRangeOptions& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.ExtensionRangeOptions)
+ GOOGLE_DCHECK_NE(&from, this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ uninterpreted_option_.MergeFrom(from.uninterpreted_option_);
+ _extensions_.MergeFrom(internal_default_instance(), from._extensions_);
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+}
+
+void ExtensionRangeOptions::CopyFrom(const ExtensionRangeOptions& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.ExtensionRangeOptions)
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+bool ExtensionRangeOptions::IsInitialized() const {
+ if (!_extensions_.IsInitialized()) {
+ return false;
+ }
+
+ if (!::PROTOBUF_NAMESPACE_ID::internal::AllAreInitialized(uninterpreted_option_))
+ return false;
+ return true;
+}
+
+void ExtensionRangeOptions::InternalSwap(ExtensionRangeOptions* other) {
+ using std::swap;
+ _extensions_.InternalSwap(&other->_extensions_);
+ _internal_metadata_.InternalSwap(&other->_internal_metadata_);
+ uninterpreted_option_.InternalSwap(&other->uninterpreted_option_);
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata ExtensionRangeOptions::GetMetadata() const {
+ return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(
+ &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
+ file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[5]);
+}
+
+// ===================================================================
+
+class FieldDescriptorProto::_Internal {
+ public:
+ using HasBits = decltype(std::declval<FieldDescriptorProto>()._has_bits_);
+ static void set_has_name(HasBits* has_bits) {
+ (*has_bits)[0] |= 1u;
+ }
+ static void set_has_number(HasBits* has_bits) {
+ (*has_bits)[0] |= 64u;
+ }
+ static void set_has_label(HasBits* has_bits) {
+ (*has_bits)[0] |= 512u;
+ }
+ static void set_has_type(HasBits* has_bits) {
+ (*has_bits)[0] |= 1024u;
+ }
+ static void set_has_type_name(HasBits* has_bits) {
+ (*has_bits)[0] |= 4u;
+ }
+ static void set_has_extendee(HasBits* has_bits) {
+ (*has_bits)[0] |= 2u;
+ }
+ static void set_has_default_value(HasBits* has_bits) {
+ (*has_bits)[0] |= 8u;
+ }
+ static void set_has_oneof_index(HasBits* has_bits) {
+ (*has_bits)[0] |= 128u;
+ }
+ static void set_has_json_name(HasBits* has_bits) {
+ (*has_bits)[0] |= 16u;
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::FieldOptions& options(const FieldDescriptorProto* msg);
+ static void set_has_options(HasBits* has_bits) {
+ (*has_bits)[0] |= 32u;
+ }
+ static void set_has_proto3_optional(HasBits* has_bits) {
+ (*has_bits)[0] |= 256u;
+ }
+};
+
+const ::PROTOBUF_NAMESPACE_ID::FieldOptions&
+FieldDescriptorProto::_Internal::options(const FieldDescriptorProto* msg) {
+ return *msg->options_;
+}
+FieldDescriptorProto::FieldDescriptorProto(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned)
+ : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) {
+ SharedCtor();
+ if (!is_message_owned) {
+ RegisterArenaDtor(arena);
+ }
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.FieldDescriptorProto)
+}
+FieldDescriptorProto::FieldDescriptorProto(const FieldDescriptorProto& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message(),
+ _has_bits_(from._has_bits_) {
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (from._internal_has_name()) {
+ name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_name(),
+ GetArenaForAllocation());
+ }
+ extendee_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ extendee_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (from._internal_has_extendee()) {
+ extendee_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_extendee(),
+ GetArenaForAllocation());
+ }
+ type_name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ type_name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (from._internal_has_type_name()) {
+ type_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_type_name(),
+ GetArenaForAllocation());
+ }
+ default_value_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ default_value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (from._internal_has_default_value()) {
+ default_value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_default_value(),
+ GetArenaForAllocation());
+ }
+ json_name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ json_name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (from._internal_has_json_name()) {
+ json_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_json_name(),
+ GetArenaForAllocation());
+ }
+ if (from._internal_has_options()) {
+ options_ = new ::PROTOBUF_NAMESPACE_ID::FieldOptions(*from.options_);
+ } else {
+ options_ = nullptr;
+ }
+ ::memcpy(&number_, &from.number_,
+ static_cast<size_t>(reinterpret_cast<char*>(&type_) -
+ reinterpret_cast<char*>(&number_)) + sizeof(type_));
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.FieldDescriptorProto)
+}
+
+inline void FieldDescriptorProto::SharedCtor() {
+name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+extendee_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ extendee_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+type_name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ type_name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+default_value_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ default_value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+json_name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ json_name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+::memset(reinterpret_cast<char*>(this) + static_cast<size_t>(
+ reinterpret_cast<char*>(&options_) - reinterpret_cast<char*>(this)),
+ 0, static_cast<size_t>(reinterpret_cast<char*>(&proto3_optional_) -
+ reinterpret_cast<char*>(&options_)) + sizeof(proto3_optional_));
+label_ = 1;
+type_ = 1;
+}
+
+FieldDescriptorProto::~FieldDescriptorProto() {
+ // @@protoc_insertion_point(destructor:google.protobuf.FieldDescriptorProto)
+ if (GetArenaForAllocation() != nullptr) return;
+ SharedDtor();
+ _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+inline void FieldDescriptorProto::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+ name_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ extendee_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ type_name_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ default_value_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ json_name_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ if (this != internal_default_instance()) delete options_;
+}
+
+void FieldDescriptorProto::ArenaDtor(void* object) {
+ FieldDescriptorProto* _this = reinterpret_cast< FieldDescriptorProto* >(object);
+ (void)_this;
+}
+void FieldDescriptorProto::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) {
+}
+void FieldDescriptorProto::SetCachedSize(int size) const {
+ _cached_size_.Set(size);
+}
+
+void FieldDescriptorProto::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.FieldDescriptorProto)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ cached_has_bits = _has_bits_[0];
+ if (cached_has_bits & 0x0000003fu) {
+ if (cached_has_bits & 0x00000001u) {
+ name_.ClearNonDefaultToEmpty();
+ }
+ if (cached_has_bits & 0x00000002u) {
+ extendee_.ClearNonDefaultToEmpty();
+ }
+ if (cached_has_bits & 0x00000004u) {
+ type_name_.ClearNonDefaultToEmpty();
+ }
+ if (cached_has_bits & 0x00000008u) {
+ default_value_.ClearNonDefaultToEmpty();
+ }
+ if (cached_has_bits & 0x00000010u) {
+ json_name_.ClearNonDefaultToEmpty();
+ }
+ if (cached_has_bits & 0x00000020u) {
+ GOOGLE_DCHECK(options_ != nullptr);
+ options_->Clear();
+ }
+ }
+ if (cached_has_bits & 0x000000c0u) {
+ ::memset(&number_, 0, static_cast<size_t>(
+ reinterpret_cast<char*>(&oneof_index_) -
+ reinterpret_cast<char*>(&number_)) + sizeof(oneof_index_));
+ }
+ if (cached_has_bits & 0x00000700u) {
+ proto3_optional_ = false;
+ label_ = 1;
+ type_ = 1;
+ }
+ _has_bits_.Clear();
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* FieldDescriptorProto::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ _Internal::HasBits has_bits{};
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag);
+ switch (tag >> 3) {
+ // optional string name = 1;
+ case 1:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 10)) {
+ auto str = _internal_mutable_name();
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx);
+ #ifndef NDEBUG
+ ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.FieldDescriptorProto.name");
+ #endif // !NDEBUG
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // optional string extendee = 2;
+ case 2:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 18)) {
+ auto str = _internal_mutable_extendee();
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx);
+ #ifndef NDEBUG
+ ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.FieldDescriptorProto.extendee");
+ #endif // !NDEBUG
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // optional int32 number = 3;
+ case 3:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 24)) {
+ _Internal::set_has_number(&has_bits);
+ number_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint32(&ptr);
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // optional .google.protobuf.FieldDescriptorProto.Label label = 4;
+ case 4:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 32)) {
+ 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 = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx);
+ #ifndef NDEBUG
+ ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.FieldDescriptorProto.type_name");
+ #endif // !NDEBUG
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // optional string default_value = 7;
+ case 7:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 58)) {
+ auto str = _internal_mutable_default_value();
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx);
+ #ifndef NDEBUG
+ ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.FieldDescriptorProto.default_value");
+ #endif // !NDEBUG
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // optional .google.protobuf.FieldOptions options = 8;
+ case 8:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 66)) {
+ ptr = ctx->ParseMessage(_internal_mutable_options(), ptr);
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // optional int32 oneof_index = 9;
+ case 9:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 72)) {
+ _Internal::set_has_oneof_index(&has_bits);
+ oneof_index_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint32(&ptr);
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // optional string json_name = 10;
+ case 10:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 82)) {
+ auto str = _internal_mutable_json_name();
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx);
+ #ifndef NDEBUG
+ ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.FieldDescriptorProto.json_name");
+ #endif // !NDEBUG
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // optional bool proto3_optional = 17;
+ case 17:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 136)) {
+ _Internal::set_has_proto3_optional(&has_bits);
+ proto3_optional_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr);
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ default:
+ goto handle_unusual;
+ } // switch
+ handle_unusual:
+ if ((tag == 0) || ((tag & 7) == 4)) {
+ CHK_(ptr);
+ ctx->SetLastTag(tag);
+ goto message_done;
+ }
+ ptr = UnknownFieldParse(
+ tag,
+ _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(),
+ ptr, ctx);
+ CHK_(ptr != nullptr);
+ } // while
+message_done:
+ _has_bits_.Or(has_bits);
+ return ptr;
+failure:
+ ptr = nullptr;
+ goto message_done;
+#undef CHK_
+}
+
+uint8_t* FieldDescriptorProto::_InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const {
+ // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.FieldDescriptorProto)
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ cached_has_bits = _has_bits_[0];
+ // optional string name = 1;
+ if (cached_has_bits & 0x00000001u) {
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField(
+ this->_internal_name().data(), static_cast<int>(this->_internal_name().length()),
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE,
+ "google.protobuf.FieldDescriptorProto.name");
+ target = stream->WriteStringMaybeAliased(
+ 1, this->_internal_name(), target);
+ }
+
+ // optional string extendee = 2;
+ if (cached_has_bits & 0x00000002u) {
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField(
+ this->_internal_extendee().data(), static_cast<int>(this->_internal_extendee().length()),
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE,
+ "google.protobuf.FieldDescriptorProto.extendee");
+ target = stream->WriteStringMaybeAliased(
+ 2, this->_internal_extendee(), target);
+ }
+
+ // optional int32 number = 3;
+ if (cached_has_bits & 0x00000040u) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32ToArray(3, this->_internal_number(), target);
+ }
+
+ // optional .google.protobuf.FieldDescriptorProto.Label label = 4;
+ if (cached_has_bits & 0x00000200u) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteEnumToArray(
+ 4, this->_internal_label(), target);
+ }
+
+ // optional .google.protobuf.FieldDescriptorProto.Type type = 5;
+ if (cached_has_bits & 0x00000400u) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteEnumToArray(
+ 5, this->_internal_type(), target);
+ }
+
+ // optional string type_name = 6;
+ if (cached_has_bits & 0x00000004u) {
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField(
+ this->_internal_type_name().data(), static_cast<int>(this->_internal_type_name().length()),
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE,
+ "google.protobuf.FieldDescriptorProto.type_name");
+ target = stream->WriteStringMaybeAliased(
+ 6, this->_internal_type_name(), target);
+ }
+
+ // optional string default_value = 7;
+ if (cached_has_bits & 0x00000008u) {
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField(
+ this->_internal_default_value().data(), static_cast<int>(this->_internal_default_value().length()),
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE,
+ "google.protobuf.FieldDescriptorProto.default_value");
+ target = stream->WriteStringMaybeAliased(
+ 7, this->_internal_default_value(), target);
+ }
+
+ // optional .google.protobuf.FieldOptions options = 8;
+ if (cached_has_bits & 0x00000020u) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(
+ 8, _Internal::options(this), target, stream);
+ }
+
+ // optional int32 oneof_index = 9;
+ if (cached_has_bits & 0x00000080u) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32ToArray(9, this->_internal_oneof_index(), target);
+ }
+
+ // optional string json_name = 10;
+ if (cached_has_bits & 0x00000010u) {
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField(
+ this->_internal_json_name().data(), static_cast<int>(this->_internal_json_name().length()),
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE,
+ "google.protobuf.FieldDescriptorProto.json_name");
+ target = stream->WriteStringMaybeAliased(
+ 10, this->_internal_json_name(), target);
+ }
+
+ // optional bool proto3_optional = 17;
+ if (cached_has_bits & 0x00000100u) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBoolToArray(17, this->_internal_proto3_optional(), target);
+ }
+
+ if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray(
+ _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.FieldDescriptorProto)
+ return target;
+}
+
+size_t FieldDescriptorProto::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.FieldDescriptorProto)
+ size_t total_size = 0;
+
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ cached_has_bits = _has_bits_[0];
+ if (cached_has_bits & 0x000000ffu) {
+ // optional string name = 1;
+ if (cached_has_bits & 0x00000001u) {
+ total_size += 1 +
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
+ this->_internal_name());
+ }
+
+ // optional string extendee = 2;
+ if (cached_has_bits & 0x00000002u) {
+ total_size += 1 +
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
+ this->_internal_extendee());
+ }
+
+ // optional string type_name = 6;
+ if (cached_has_bits & 0x00000004u) {
+ total_size += 1 +
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
+ this->_internal_type_name());
+ }
+
+ // optional string default_value = 7;
+ if (cached_has_bits & 0x00000008u) {
+ total_size += 1 +
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
+ this->_internal_default_value());
+ }
+
+ // optional string json_name = 10;
+ if (cached_has_bits & 0x00000010u) {
+ total_size += 1 +
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
+ this->_internal_json_name());
+ }
+
+ // optional .google.protobuf.FieldOptions options = 8;
+ if (cached_has_bits & 0x00000020u) {
+ total_size += 1 +
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(
+ *options_);
+ }
+
+ // optional int32 number = 3;
+ if (cached_has_bits & 0x00000040u) {
+ total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32SizePlusOne(this->_internal_number());
+ }
+
+ // optional int32 oneof_index = 9;
+ if (cached_has_bits & 0x00000080u) {
+ total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32SizePlusOne(this->_internal_oneof_index());
+ }
+
+ }
+ if (cached_has_bits & 0x00000700u) {
+ // optional bool proto3_optional = 17;
+ if (cached_has_bits & 0x00000100u) {
+ total_size += 2 + 1;
+ }
+
+ // optional .google.protobuf.FieldDescriptorProto.Label label = 4;
+ if (cached_has_bits & 0x00000200u) {
+ total_size += 1 +
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::EnumSize(this->_internal_label());
+ }
+
+ // optional .google.protobuf.FieldDescriptorProto.Type type = 5;
+ if (cached_has_bits & 0x00000400u) {
+ total_size += 1 +
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::EnumSize(this->_internal_type());
+ }
+
+ }
+ return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData FieldDescriptorProto::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck,
+ FieldDescriptorProto::MergeImpl
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*FieldDescriptorProto::GetClassData() const { return &_class_data_; }
+
+void FieldDescriptorProto::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to,
+ const ::PROTOBUF_NAMESPACE_ID::Message& from) {
+ static_cast<FieldDescriptorProto *>(to)->MergeFrom(
+ static_cast<const FieldDescriptorProto &>(from));
+}
+
+
+void FieldDescriptorProto::MergeFrom(const FieldDescriptorProto& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.FieldDescriptorProto)
+ GOOGLE_DCHECK_NE(&from, this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ cached_has_bits = from._has_bits_[0];
+ if (cached_has_bits & 0x000000ffu) {
+ if (cached_has_bits & 0x00000001u) {
+ _internal_set_name(from._internal_name());
+ }
+ if (cached_has_bits & 0x00000002u) {
+ _internal_set_extendee(from._internal_extendee());
+ }
+ if (cached_has_bits & 0x00000004u) {
+ _internal_set_type_name(from._internal_type_name());
+ }
+ if (cached_has_bits & 0x00000008u) {
+ _internal_set_default_value(from._internal_default_value());
+ }
+ if (cached_has_bits & 0x00000010u) {
+ _internal_set_json_name(from._internal_json_name());
+ }
+ if (cached_has_bits & 0x00000020u) {
+ _internal_mutable_options()->::PROTOBUF_NAMESPACE_ID::FieldOptions::MergeFrom(from._internal_options());
+ }
+ if (cached_has_bits & 0x00000040u) {
+ number_ = from.number_;
+ }
+ if (cached_has_bits & 0x00000080u) {
+ oneof_index_ = from.oneof_index_;
+ }
+ _has_bits_[0] |= cached_has_bits;
+ }
+ if (cached_has_bits & 0x00000700u) {
+ if (cached_has_bits & 0x00000100u) {
+ proto3_optional_ = from.proto3_optional_;
+ }
+ if (cached_has_bits & 0x00000200u) {
+ label_ = from.label_;
+ }
+ if (cached_has_bits & 0x00000400u) {
+ type_ = from.type_;
+ }
+ _has_bits_[0] |= cached_has_bits;
+ }
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+}
+
+void FieldDescriptorProto::CopyFrom(const FieldDescriptorProto& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.FieldDescriptorProto)
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+bool FieldDescriptorProto::IsInitialized() const {
+ if (_internal_has_options()) {
+ if (!options_->IsInitialized()) return false;
+ }
+ return true;
+}
+
+void FieldDescriptorProto::InternalSwap(FieldDescriptorProto* other) {
+ using std::swap;
+ auto* lhs_arena = GetArenaForAllocation();
+ auto* rhs_arena = other->GetArenaForAllocation();
+ _internal_metadata_.InternalSwap(&other->_internal_metadata_);
+ swap(_has_bits_[0], other->_has_bits_[0]);
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(),
+ &name_, lhs_arena,
+ &other->name_, rhs_arena
+ );
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(),
+ &extendee_, lhs_arena,
+ &other->extendee_, rhs_arena
+ );
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(),
+ &type_name_, lhs_arena,
+ &other->type_name_, rhs_arena
+ );
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(),
+ &default_value_, lhs_arena,
+ &other->default_value_, rhs_arena
+ );
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(),
+ &json_name_, lhs_arena,
+ &other->json_name_, rhs_arena
+ );
+ ::PROTOBUF_NAMESPACE_ID::internal::memswap<
+ PROTOBUF_FIELD_OFFSET(FieldDescriptorProto, proto3_optional_)
+ + sizeof(FieldDescriptorProto::proto3_optional_)
+ - PROTOBUF_FIELD_OFFSET(FieldDescriptorProto, options_)>(
+ reinterpret_cast<char*>(&options_),
+ reinterpret_cast<char*>(&other->options_));
+ swap(label_, other->label_);
+ swap(type_, other->type_);
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata FieldDescriptorProto::GetMetadata() const {
+ return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(
+ &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
+ file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[6]);
+}
+
+// ===================================================================
+
+class OneofDescriptorProto::_Internal {
+ public:
+ using HasBits = decltype(std::declval<OneofDescriptorProto>()._has_bits_);
+ static void set_has_name(HasBits* has_bits) {
+ (*has_bits)[0] |= 1u;
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::OneofOptions& options(const OneofDescriptorProto* msg);
+ static void set_has_options(HasBits* has_bits) {
+ (*has_bits)[0] |= 2u;
+ }
+};
+
+const ::PROTOBUF_NAMESPACE_ID::OneofOptions&
+OneofDescriptorProto::_Internal::options(const OneofDescriptorProto* msg) {
+ return *msg->options_;
+}
+OneofDescriptorProto::OneofDescriptorProto(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned)
+ : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) {
+ SharedCtor();
+ if (!is_message_owned) {
+ RegisterArenaDtor(arena);
+ }
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.OneofDescriptorProto)
+}
+OneofDescriptorProto::OneofDescriptorProto(const OneofDescriptorProto& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message(),
+ _has_bits_(from._has_bits_) {
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (from._internal_has_name()) {
+ name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_name(),
+ GetArenaForAllocation());
+ }
+ if (from._internal_has_options()) {
+ options_ = new ::PROTOBUF_NAMESPACE_ID::OneofOptions(*from.options_);
+ } else {
+ options_ = nullptr;
+ }
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.OneofDescriptorProto)
+}
+
+inline void OneofDescriptorProto::SharedCtor() {
+name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+options_ = nullptr;
+}
+
+OneofDescriptorProto::~OneofDescriptorProto() {
+ // @@protoc_insertion_point(destructor:google.protobuf.OneofDescriptorProto)
+ if (GetArenaForAllocation() != nullptr) return;
+ SharedDtor();
+ _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+inline void OneofDescriptorProto::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+ name_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ if (this != internal_default_instance()) delete options_;
+}
+
+void OneofDescriptorProto::ArenaDtor(void* object) {
+ OneofDescriptorProto* _this = reinterpret_cast< OneofDescriptorProto* >(object);
+ (void)_this;
+}
+void OneofDescriptorProto::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) {
+}
+void OneofDescriptorProto::SetCachedSize(int size) const {
+ _cached_size_.Set(size);
+}
+
+void OneofDescriptorProto::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.OneofDescriptorProto)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ cached_has_bits = _has_bits_[0];
+ if (cached_has_bits & 0x00000003u) {
+ if (cached_has_bits & 0x00000001u) {
+ name_.ClearNonDefaultToEmpty();
+ }
+ if (cached_has_bits & 0x00000002u) {
+ GOOGLE_DCHECK(options_ != nullptr);
+ options_->Clear();
+ }
+ }
+ _has_bits_.Clear();
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* OneofDescriptorProto::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ _Internal::HasBits has_bits{};
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag);
+ switch (tag >> 3) {
+ // optional string name = 1;
+ case 1:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 10)) {
+ auto str = _internal_mutable_name();
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx);
+ #ifndef NDEBUG
+ ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.OneofDescriptorProto.name");
+ #endif // !NDEBUG
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // optional .google.protobuf.OneofOptions options = 2;
+ case 2:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 18)) {
+ ptr = ctx->ParseMessage(_internal_mutable_options(), ptr);
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ default:
+ goto handle_unusual;
+ } // switch
+ handle_unusual:
+ if ((tag == 0) || ((tag & 7) == 4)) {
+ CHK_(ptr);
+ ctx->SetLastTag(tag);
+ goto message_done;
+ }
+ ptr = UnknownFieldParse(
+ tag,
+ _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(),
+ ptr, ctx);
+ CHK_(ptr != nullptr);
+ } // while
+message_done:
+ _has_bits_.Or(has_bits);
+ return ptr;
+failure:
+ ptr = nullptr;
+ goto message_done;
+#undef CHK_
+}
+
+uint8_t* OneofDescriptorProto::_InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const {
+ // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.OneofDescriptorProto)
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ cached_has_bits = _has_bits_[0];
+ // optional string name = 1;
+ if (cached_has_bits & 0x00000001u) {
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField(
+ this->_internal_name().data(), static_cast<int>(this->_internal_name().length()),
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE,
+ "google.protobuf.OneofDescriptorProto.name");
+ target = stream->WriteStringMaybeAliased(
+ 1, this->_internal_name(), target);
+ }
+
+ // optional .google.protobuf.OneofOptions options = 2;
+ if (cached_has_bits & 0x00000002u) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(
+ 2, _Internal::options(this), target, stream);
+ }
+
+ if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray(
+ _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.OneofDescriptorProto)
+ return target;
+}
+
+size_t OneofDescriptorProto::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.OneofDescriptorProto)
+ size_t total_size = 0;
+
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ cached_has_bits = _has_bits_[0];
+ if (cached_has_bits & 0x00000003u) {
+ // optional string name = 1;
+ if (cached_has_bits & 0x00000001u) {
+ total_size += 1 +
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
+ this->_internal_name());
+ }
+
+ // optional .google.protobuf.OneofOptions options = 2;
+ if (cached_has_bits & 0x00000002u) {
+ total_size += 1 +
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(
+ *options_);
+ }
+
+ }
+ return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData OneofDescriptorProto::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck,
+ OneofDescriptorProto::MergeImpl
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*OneofDescriptorProto::GetClassData() const { return &_class_data_; }
+
+void OneofDescriptorProto::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to,
+ const ::PROTOBUF_NAMESPACE_ID::Message& from) {
+ static_cast<OneofDescriptorProto *>(to)->MergeFrom(
+ static_cast<const OneofDescriptorProto &>(from));
+}
+
+
+void OneofDescriptorProto::MergeFrom(const OneofDescriptorProto& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.OneofDescriptorProto)
+ GOOGLE_DCHECK_NE(&from, this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ cached_has_bits = from._has_bits_[0];
+ if (cached_has_bits & 0x00000003u) {
+ if (cached_has_bits & 0x00000001u) {
+ _internal_set_name(from._internal_name());
+ }
+ if (cached_has_bits & 0x00000002u) {
+ _internal_mutable_options()->::PROTOBUF_NAMESPACE_ID::OneofOptions::MergeFrom(from._internal_options());
+ }
+ }
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+}
+
+void OneofDescriptorProto::CopyFrom(const OneofDescriptorProto& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.OneofDescriptorProto)
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+bool OneofDescriptorProto::IsInitialized() const {
+ if (_internal_has_options()) {
+ if (!options_->IsInitialized()) return false;
+ }
+ return true;
+}
+
+void OneofDescriptorProto::InternalSwap(OneofDescriptorProto* other) {
+ using std::swap;
+ auto* lhs_arena = GetArenaForAllocation();
+ auto* rhs_arena = other->GetArenaForAllocation();
+ _internal_metadata_.InternalSwap(&other->_internal_metadata_);
+ swap(_has_bits_[0], other->_has_bits_[0]);
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(),
+ &name_, lhs_arena,
+ &other->name_, rhs_arena
+ );
+ swap(options_, other->options_);
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata OneofDescriptorProto::GetMetadata() const {
+ return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(
+ &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
+ file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[7]);
+}
+
+// ===================================================================
+
+class EnumDescriptorProto_EnumReservedRange::_Internal {
+ public:
+ using HasBits = decltype(std::declval<EnumDescriptorProto_EnumReservedRange>()._has_bits_);
+ static void set_has_start(HasBits* has_bits) {
+ (*has_bits)[0] |= 1u;
+ }
+ static void set_has_end(HasBits* has_bits) {
+ (*has_bits)[0] |= 2u;
+ }
+};
+
+EnumDescriptorProto_EnumReservedRange::EnumDescriptorProto_EnumReservedRange(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned)
+ : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) {
+ SharedCtor();
+ if (!is_message_owned) {
+ RegisterArenaDtor(arena);
+ }
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.EnumDescriptorProto.EnumReservedRange)
+}
+EnumDescriptorProto_EnumReservedRange::EnumDescriptorProto_EnumReservedRange(const EnumDescriptorProto_EnumReservedRange& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message(),
+ _has_bits_(from._has_bits_) {
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ ::memcpy(&start_, &from.start_,
+ static_cast<size_t>(reinterpret_cast<char*>(&end_) -
+ reinterpret_cast<char*>(&start_)) + sizeof(end_));
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.EnumDescriptorProto.EnumReservedRange)
+}
+
+inline void EnumDescriptorProto_EnumReservedRange::SharedCtor() {
+::memset(reinterpret_cast<char*>(this) + static_cast<size_t>(
+ reinterpret_cast<char*>(&start_) - reinterpret_cast<char*>(this)),
+ 0, static_cast<size_t>(reinterpret_cast<char*>(&end_) -
+ reinterpret_cast<char*>(&start_)) + sizeof(end_));
+}
+
+EnumDescriptorProto_EnumReservedRange::~EnumDescriptorProto_EnumReservedRange() {
+ // @@protoc_insertion_point(destructor:google.protobuf.EnumDescriptorProto.EnumReservedRange)
+ if (GetArenaForAllocation() != nullptr) return;
+ SharedDtor();
+ _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+inline void EnumDescriptorProto_EnumReservedRange::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+}
+
+void EnumDescriptorProto_EnumReservedRange::ArenaDtor(void* object) {
+ EnumDescriptorProto_EnumReservedRange* _this = reinterpret_cast< EnumDescriptorProto_EnumReservedRange* >(object);
+ (void)_this;
+}
+void EnumDescriptorProto_EnumReservedRange::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) {
+}
+void EnumDescriptorProto_EnumReservedRange::SetCachedSize(int size) const {
+ _cached_size_.Set(size);
+}
+
+void EnumDescriptorProto_EnumReservedRange::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.EnumDescriptorProto.EnumReservedRange)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ cached_has_bits = _has_bits_[0];
+ if (cached_has_bits & 0x00000003u) {
+ ::memset(&start_, 0, static_cast<size_t>(
+ reinterpret_cast<char*>(&end_) -
+ reinterpret_cast<char*>(&start_)) + sizeof(end_));
+ }
+ _has_bits_.Clear();
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* EnumDescriptorProto_EnumReservedRange::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ _Internal::HasBits has_bits{};
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag);
+ switch (tag >> 3) {
+ // optional int32 start = 1;
+ case 1:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 8)) {
+ _Internal::set_has_start(&has_bits);
+ start_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint32(&ptr);
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // optional int32 end = 2;
+ case 2:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 16)) {
+ _Internal::set_has_end(&has_bits);
+ end_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint32(&ptr);
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ default:
+ goto handle_unusual;
+ } // switch
+ handle_unusual:
+ if ((tag == 0) || ((tag & 7) == 4)) {
+ CHK_(ptr);
+ ctx->SetLastTag(tag);
+ goto message_done;
+ }
+ ptr = UnknownFieldParse(
+ tag,
+ _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(),
+ ptr, ctx);
+ CHK_(ptr != nullptr);
+ } // while
+message_done:
+ _has_bits_.Or(has_bits);
+ return ptr;
+failure:
+ ptr = nullptr;
+ goto message_done;
+#undef CHK_
+}
+
+uint8_t* EnumDescriptorProto_EnumReservedRange::_InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const {
+ // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.EnumDescriptorProto.EnumReservedRange)
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ cached_has_bits = _has_bits_[0];
+ // optional int32 start = 1;
+ if (cached_has_bits & 0x00000001u) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32ToArray(1, this->_internal_start(), target);
+ }
+
+ // optional int32 end = 2;
+ if (cached_has_bits & 0x00000002u) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32ToArray(2, this->_internal_end(), target);
+ }
+
+ if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray(
+ _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.EnumDescriptorProto.EnumReservedRange)
+ return target;
+}
+
+size_t EnumDescriptorProto_EnumReservedRange::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.EnumDescriptorProto.EnumReservedRange)
+ size_t total_size = 0;
+
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ cached_has_bits = _has_bits_[0];
+ if (cached_has_bits & 0x00000003u) {
+ // optional int32 start = 1;
+ if (cached_has_bits & 0x00000001u) {
+ total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32SizePlusOne(this->_internal_start());
+ }
+
+ // optional int32 end = 2;
+ if (cached_has_bits & 0x00000002u) {
+ total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32SizePlusOne(this->_internal_end());
+ }
+
+ }
+ return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData EnumDescriptorProto_EnumReservedRange::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck,
+ EnumDescriptorProto_EnumReservedRange::MergeImpl
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*EnumDescriptorProto_EnumReservedRange::GetClassData() const { return &_class_data_; }
+
+void EnumDescriptorProto_EnumReservedRange::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to,
+ const ::PROTOBUF_NAMESPACE_ID::Message& from) {
+ static_cast<EnumDescriptorProto_EnumReservedRange *>(to)->MergeFrom(
+ static_cast<const EnumDescriptorProto_EnumReservedRange &>(from));
+}
+
+
+void EnumDescriptorProto_EnumReservedRange::MergeFrom(const EnumDescriptorProto_EnumReservedRange& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.EnumDescriptorProto.EnumReservedRange)
+ GOOGLE_DCHECK_NE(&from, this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ cached_has_bits = from._has_bits_[0];
+ if (cached_has_bits & 0x00000003u) {
+ if (cached_has_bits & 0x00000001u) {
+ start_ = from.start_;
+ }
+ if (cached_has_bits & 0x00000002u) {
+ end_ = from.end_;
+ }
+ _has_bits_[0] |= cached_has_bits;
+ }
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+}
+
+void EnumDescriptorProto_EnumReservedRange::CopyFrom(const EnumDescriptorProto_EnumReservedRange& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.EnumDescriptorProto.EnumReservedRange)
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+bool EnumDescriptorProto_EnumReservedRange::IsInitialized() const {
+ return true;
+}
+
+void EnumDescriptorProto_EnumReservedRange::InternalSwap(EnumDescriptorProto_EnumReservedRange* other) {
+ using std::swap;
+ _internal_metadata_.InternalSwap(&other->_internal_metadata_);
+ swap(_has_bits_[0], other->_has_bits_[0]);
+ ::PROTOBUF_NAMESPACE_ID::internal::memswap<
+ PROTOBUF_FIELD_OFFSET(EnumDescriptorProto_EnumReservedRange, end_)
+ + sizeof(EnumDescriptorProto_EnumReservedRange::end_)
+ - PROTOBUF_FIELD_OFFSET(EnumDescriptorProto_EnumReservedRange, start_)>(
+ reinterpret_cast<char*>(&start_),
+ reinterpret_cast<char*>(&other->start_));
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata EnumDescriptorProto_EnumReservedRange::GetMetadata() const {
+ return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(
+ &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
+ file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[8]);
+}
+
+// ===================================================================
+
+class EnumDescriptorProto::_Internal {
+ public:
+ using HasBits = decltype(std::declval<EnumDescriptorProto>()._has_bits_);
+ static void set_has_name(HasBits* has_bits) {
+ (*has_bits)[0] |= 1u;
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::EnumOptions& options(const EnumDescriptorProto* msg);
+ static void set_has_options(HasBits* has_bits) {
+ (*has_bits)[0] |= 2u;
+ }
+};
+
+const ::PROTOBUF_NAMESPACE_ID::EnumOptions&
+EnumDescriptorProto::_Internal::options(const EnumDescriptorProto* msg) {
+ return *msg->options_;
+}
+EnumDescriptorProto::EnumDescriptorProto(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned)
+ : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned),
+ value_(arena),
+ reserved_range_(arena),
+ reserved_name_(arena) {
+ SharedCtor();
+ if (!is_message_owned) {
+ RegisterArenaDtor(arena);
+ }
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.EnumDescriptorProto)
+}
+EnumDescriptorProto::EnumDescriptorProto(const EnumDescriptorProto& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message(),
+ _has_bits_(from._has_bits_),
+ value_(from.value_),
+ reserved_range_(from.reserved_range_),
+ reserved_name_(from.reserved_name_) {
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (from._internal_has_name()) {
+ name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_name(),
+ GetArenaForAllocation());
+ }
+ if (from._internal_has_options()) {
+ options_ = new ::PROTOBUF_NAMESPACE_ID::EnumOptions(*from.options_);
+ } else {
+ options_ = nullptr;
+ }
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.EnumDescriptorProto)
+}
+
+inline void EnumDescriptorProto::SharedCtor() {
+name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+options_ = nullptr;
+}
+
+EnumDescriptorProto::~EnumDescriptorProto() {
+ // @@protoc_insertion_point(destructor:google.protobuf.EnumDescriptorProto)
+ if (GetArenaForAllocation() != nullptr) return;
+ SharedDtor();
+ _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+inline void EnumDescriptorProto::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+ name_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ if (this != internal_default_instance()) delete options_;
+}
+
+void EnumDescriptorProto::ArenaDtor(void* object) {
+ EnumDescriptorProto* _this = reinterpret_cast< EnumDescriptorProto* >(object);
+ (void)_this;
+}
+void EnumDescriptorProto::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) {
+}
+void EnumDescriptorProto::SetCachedSize(int size) const {
+ _cached_size_.Set(size);
+}
+
+void EnumDescriptorProto::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.EnumDescriptorProto)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ value_.Clear();
+ reserved_range_.Clear();
+ reserved_name_.Clear();
+ cached_has_bits = _has_bits_[0];
+ if (cached_has_bits & 0x00000003u) {
+ if (cached_has_bits & 0x00000001u) {
+ name_.ClearNonDefaultToEmpty();
+ }
+ if (cached_has_bits & 0x00000002u) {
+ GOOGLE_DCHECK(options_ != nullptr);
+ options_->Clear();
+ }
+ }
+ _has_bits_.Clear();
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* EnumDescriptorProto::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ _Internal::HasBits has_bits{};
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag);
+ switch (tag >> 3) {
+ // optional string name = 1;
+ case 1:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 10)) {
+ auto str = _internal_mutable_name();
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx);
+ #ifndef NDEBUG
+ ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.EnumDescriptorProto.name");
+ #endif // !NDEBUG
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // repeated .google.protobuf.EnumValueDescriptorProto value = 2;
+ case 2:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 18)) {
+ ptr -= 1;
+ do {
+ ptr += 1;
+ ptr = ctx->ParseMessage(_internal_add_value(), ptr);
+ CHK_(ptr);
+ if (!ctx->DataAvailable(ptr)) break;
+ } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<18>(ptr));
+ } else
+ goto handle_unusual;
+ continue;
+ // optional .google.protobuf.EnumOptions options = 3;
+ case 3:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 26)) {
+ ptr = ctx->ParseMessage(_internal_mutable_options(), ptr);
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // repeated .google.protobuf.EnumDescriptorProto.EnumReservedRange reserved_range = 4;
+ case 4:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 34)) {
+ ptr -= 1;
+ do {
+ ptr += 1;
+ ptr = ctx->ParseMessage(_internal_add_reserved_range(), ptr);
+ CHK_(ptr);
+ if (!ctx->DataAvailable(ptr)) break;
+ } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<34>(ptr));
+ } else
+ goto handle_unusual;
+ continue;
+ // repeated string reserved_name = 5;
+ case 5:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 42)) {
+ ptr -= 1;
+ do {
+ ptr += 1;
+ auto str = _internal_add_reserved_name();
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx);
+ #ifndef NDEBUG
+ ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.EnumDescriptorProto.reserved_name");
+ #endif // !NDEBUG
+ CHK_(ptr);
+ if (!ctx->DataAvailable(ptr)) break;
+ } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<42>(ptr));
+ } else
+ goto handle_unusual;
+ continue;
+ default:
+ goto handle_unusual;
+ } // switch
+ handle_unusual:
+ if ((tag == 0) || ((tag & 7) == 4)) {
+ CHK_(ptr);
+ ctx->SetLastTag(tag);
+ goto message_done;
+ }
+ ptr = UnknownFieldParse(
+ tag,
+ _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(),
+ ptr, ctx);
+ CHK_(ptr != nullptr);
+ } // while
+message_done:
+ _has_bits_.Or(has_bits);
+ return ptr;
+failure:
+ ptr = nullptr;
+ goto message_done;
+#undef CHK_
+}
+
+uint8_t* EnumDescriptorProto::_InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const {
+ // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.EnumDescriptorProto)
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ cached_has_bits = _has_bits_[0];
+ // optional string name = 1;
+ if (cached_has_bits & 0x00000001u) {
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField(
+ this->_internal_name().data(), static_cast<int>(this->_internal_name().length()),
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE,
+ "google.protobuf.EnumDescriptorProto.name");
+ target = stream->WriteStringMaybeAliased(
+ 1, this->_internal_name(), target);
+ }
+
+ // repeated .google.protobuf.EnumValueDescriptorProto value = 2;
+ for (unsigned int i = 0,
+ n = static_cast<unsigned int>(this->_internal_value_size()); i < n; i++) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(2, this->_internal_value(i), target, stream);
+ }
+
+ // optional .google.protobuf.EnumOptions options = 3;
+ if (cached_has_bits & 0x00000002u) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(
+ 3, _Internal::options(this), target, stream);
+ }
+
+ // repeated .google.protobuf.EnumDescriptorProto.EnumReservedRange reserved_range = 4;
+ for (unsigned int i = 0,
+ n = static_cast<unsigned int>(this->_internal_reserved_range_size()); i < n; i++) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(4, this->_internal_reserved_range(i), target, stream);
+ }
+
+ // repeated string reserved_name = 5;
+ for (int i = 0, n = this->_internal_reserved_name_size(); i < n; i++) {
+ const auto& s = this->_internal_reserved_name(i);
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField(
+ s.data(), static_cast<int>(s.length()),
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE,
+ "google.protobuf.EnumDescriptorProto.reserved_name");
+ target = stream->WriteString(5, s, target);
+ }
+
+ if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray(
+ _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.EnumDescriptorProto)
+ return target;
+}
+
+size_t EnumDescriptorProto::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.EnumDescriptorProto)
+ size_t total_size = 0;
+
+ 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->value_) {
+ total_size +=
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg);
+ }
+
+ // repeated .google.protobuf.EnumDescriptorProto.EnumReservedRange reserved_range = 4;
+ total_size += 1UL * this->_internal_reserved_range_size();
+ for (const auto& msg : this->reserved_range_) {
+ total_size +=
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg);
+ }
+
+ // repeated string reserved_name = 5;
+ total_size += 1 *
+ ::PROTOBUF_NAMESPACE_ID::internal::FromIntSize(reserved_name_.size());
+ for (int i = 0, n = reserved_name_.size(); i < n; i++) {
+ total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
+ reserved_name_.Get(i));
+ }
+
+ cached_has_bits = _has_bits_[0];
+ if (cached_has_bits & 0x00000003u) {
+ // optional string name = 1;
+ if (cached_has_bits & 0x00000001u) {
+ total_size += 1 +
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
+ this->_internal_name());
+ }
+
+ // optional .google.protobuf.EnumOptions options = 3;
+ if (cached_has_bits & 0x00000002u) {
+ total_size += 1 +
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(
+ *options_);
+ }
+
+ }
+ return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData EnumDescriptorProto::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck,
+ EnumDescriptorProto::MergeImpl
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*EnumDescriptorProto::GetClassData() const { return &_class_data_; }
+
+void EnumDescriptorProto::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to,
+ const ::PROTOBUF_NAMESPACE_ID::Message& from) {
+ static_cast<EnumDescriptorProto *>(to)->MergeFrom(
+ static_cast<const EnumDescriptorProto &>(from));
+}
+
+
+void EnumDescriptorProto::MergeFrom(const EnumDescriptorProto& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.EnumDescriptorProto)
+ GOOGLE_DCHECK_NE(&from, this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ value_.MergeFrom(from.value_);
+ reserved_range_.MergeFrom(from.reserved_range_);
+ reserved_name_.MergeFrom(from.reserved_name_);
+ cached_has_bits = from._has_bits_[0];
+ if (cached_has_bits & 0x00000003u) {
+ if (cached_has_bits & 0x00000001u) {
+ _internal_set_name(from._internal_name());
+ }
+ if (cached_has_bits & 0x00000002u) {
+ _internal_mutable_options()->::PROTOBUF_NAMESPACE_ID::EnumOptions::MergeFrom(from._internal_options());
+ }
+ }
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+}
+
+void EnumDescriptorProto::CopyFrom(const EnumDescriptorProto& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.EnumDescriptorProto)
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+bool EnumDescriptorProto::IsInitialized() const {
+ if (!::PROTOBUF_NAMESPACE_ID::internal::AllAreInitialized(value_))
+ return false;
+ if (_internal_has_options()) {
+ if (!options_->IsInitialized()) return false;
+ }
+ return true;
+}
+
+void EnumDescriptorProto::InternalSwap(EnumDescriptorProto* other) {
+ using std::swap;
+ auto* lhs_arena = GetArenaForAllocation();
+ auto* rhs_arena = other->GetArenaForAllocation();
+ _internal_metadata_.InternalSwap(&other->_internal_metadata_);
+ swap(_has_bits_[0], other->_has_bits_[0]);
+ value_.InternalSwap(&other->value_);
+ reserved_range_.InternalSwap(&other->reserved_range_);
+ reserved_name_.InternalSwap(&other->reserved_name_);
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(),
+ &name_, lhs_arena,
+ &other->name_, rhs_arena
+ );
+ swap(options_, other->options_);
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata EnumDescriptorProto::GetMetadata() const {
+ return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(
+ &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
+ file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[9]);
+}
+
+// ===================================================================
+
+class EnumValueDescriptorProto::_Internal {
+ public:
+ using HasBits = decltype(std::declval<EnumValueDescriptorProto>()._has_bits_);
+ static void set_has_name(HasBits* has_bits) {
+ (*has_bits)[0] |= 1u;
+ }
+ static void set_has_number(HasBits* has_bits) {
+ (*has_bits)[0] |= 4u;
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::EnumValueOptions& options(const EnumValueDescriptorProto* msg);
+ static void set_has_options(HasBits* has_bits) {
+ (*has_bits)[0] |= 2u;
+ }
+};
+
+const ::PROTOBUF_NAMESPACE_ID::EnumValueOptions&
+EnumValueDescriptorProto::_Internal::options(const EnumValueDescriptorProto* msg) {
+ return *msg->options_;
+}
+EnumValueDescriptorProto::EnumValueDescriptorProto(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned)
+ : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) {
+ SharedCtor();
+ if (!is_message_owned) {
+ RegisterArenaDtor(arena);
+ }
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.EnumValueDescriptorProto)
+}
+EnumValueDescriptorProto::EnumValueDescriptorProto(const EnumValueDescriptorProto& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message(),
+ _has_bits_(from._has_bits_) {
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (from._internal_has_name()) {
+ name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_name(),
+ GetArenaForAllocation());
+ }
+ if (from._internal_has_options()) {
+ options_ = new ::PROTOBUF_NAMESPACE_ID::EnumValueOptions(*from.options_);
+ } else {
+ options_ = nullptr;
+ }
+ number_ = from.number_;
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.EnumValueDescriptorProto)
+}
+
+inline void EnumValueDescriptorProto::SharedCtor() {
+name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+::memset(reinterpret_cast<char*>(this) + static_cast<size_t>(
+ reinterpret_cast<char*>(&options_) - reinterpret_cast<char*>(this)),
+ 0, static_cast<size_t>(reinterpret_cast<char*>(&number_) -
+ reinterpret_cast<char*>(&options_)) + sizeof(number_));
+}
+
+EnumValueDescriptorProto::~EnumValueDescriptorProto() {
+ // @@protoc_insertion_point(destructor:google.protobuf.EnumValueDescriptorProto)
+ if (GetArenaForAllocation() != nullptr) return;
+ SharedDtor();
+ _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+inline void EnumValueDescriptorProto::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+ name_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ if (this != internal_default_instance()) delete options_;
+}
+
+void EnumValueDescriptorProto::ArenaDtor(void* object) {
+ EnumValueDescriptorProto* _this = reinterpret_cast< EnumValueDescriptorProto* >(object);
+ (void)_this;
+}
+void EnumValueDescriptorProto::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) {
+}
+void EnumValueDescriptorProto::SetCachedSize(int size) const {
+ _cached_size_.Set(size);
+}
+
+void EnumValueDescriptorProto::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.EnumValueDescriptorProto)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ cached_has_bits = _has_bits_[0];
+ if (cached_has_bits & 0x00000003u) {
+ if (cached_has_bits & 0x00000001u) {
+ name_.ClearNonDefaultToEmpty();
+ }
+ if (cached_has_bits & 0x00000002u) {
+ GOOGLE_DCHECK(options_ != nullptr);
+ options_->Clear();
+ }
+ }
+ number_ = 0;
+ _has_bits_.Clear();
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* EnumValueDescriptorProto::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ _Internal::HasBits has_bits{};
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag);
+ switch (tag >> 3) {
+ // optional string name = 1;
+ case 1:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 10)) {
+ auto str = _internal_mutable_name();
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx);
+ #ifndef NDEBUG
+ ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.EnumValueDescriptorProto.name");
+ #endif // !NDEBUG
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // optional int32 number = 2;
+ case 2:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 16)) {
+ _Internal::set_has_number(&has_bits);
+ number_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint32(&ptr);
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // optional .google.protobuf.EnumValueOptions options = 3;
+ case 3:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 26)) {
+ ptr = ctx->ParseMessage(_internal_mutable_options(), ptr);
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ default:
+ goto handle_unusual;
+ } // switch
+ handle_unusual:
+ if ((tag == 0) || ((tag & 7) == 4)) {
+ CHK_(ptr);
+ ctx->SetLastTag(tag);
+ goto message_done;
+ }
+ ptr = UnknownFieldParse(
+ tag,
+ _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(),
+ ptr, ctx);
+ CHK_(ptr != nullptr);
+ } // while
+message_done:
+ _has_bits_.Or(has_bits);
+ return ptr;
+failure:
+ ptr = nullptr;
+ goto message_done;
+#undef CHK_
+}
+
+uint8_t* EnumValueDescriptorProto::_InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const {
+ // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.EnumValueDescriptorProto)
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ cached_has_bits = _has_bits_[0];
+ // optional string name = 1;
+ if (cached_has_bits & 0x00000001u) {
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField(
+ this->_internal_name().data(), static_cast<int>(this->_internal_name().length()),
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE,
+ "google.protobuf.EnumValueDescriptorProto.name");
+ target = stream->WriteStringMaybeAliased(
+ 1, this->_internal_name(), target);
+ }
+
+ // optional int32 number = 2;
+ if (cached_has_bits & 0x00000004u) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32ToArray(2, this->_internal_number(), target);
+ }
+
+ // optional .google.protobuf.EnumValueOptions options = 3;
+ if (cached_has_bits & 0x00000002u) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(
+ 3, _Internal::options(this), target, stream);
+ }
+
+ if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray(
+ _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.EnumValueDescriptorProto)
+ return target;
+}
+
+size_t EnumValueDescriptorProto::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.EnumValueDescriptorProto)
+ size_t total_size = 0;
+
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ cached_has_bits = _has_bits_[0];
+ if (cached_has_bits & 0x00000007u) {
+ // optional string name = 1;
+ if (cached_has_bits & 0x00000001u) {
+ total_size += 1 +
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
+ this->_internal_name());
+ }
+
+ // optional .google.protobuf.EnumValueOptions options = 3;
+ if (cached_has_bits & 0x00000002u) {
+ total_size += 1 +
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(
+ *options_);
+ }
+
+ // optional int32 number = 2;
+ if (cached_has_bits & 0x00000004u) {
+ total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32SizePlusOne(this->_internal_number());
+ }
+
+ }
+ return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData EnumValueDescriptorProto::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck,
+ EnumValueDescriptorProto::MergeImpl
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*EnumValueDescriptorProto::GetClassData() const { return &_class_data_; }
+
+void EnumValueDescriptorProto::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to,
+ const ::PROTOBUF_NAMESPACE_ID::Message& from) {
+ static_cast<EnumValueDescriptorProto *>(to)->MergeFrom(
+ static_cast<const EnumValueDescriptorProto &>(from));
+}
+
+
+void EnumValueDescriptorProto::MergeFrom(const EnumValueDescriptorProto& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.EnumValueDescriptorProto)
+ GOOGLE_DCHECK_NE(&from, this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ cached_has_bits = from._has_bits_[0];
+ if (cached_has_bits & 0x00000007u) {
+ if (cached_has_bits & 0x00000001u) {
+ _internal_set_name(from._internal_name());
+ }
+ if (cached_has_bits & 0x00000002u) {
+ _internal_mutable_options()->::PROTOBUF_NAMESPACE_ID::EnumValueOptions::MergeFrom(from._internal_options());
+ }
+ if (cached_has_bits & 0x00000004u) {
+ number_ = from.number_;
+ }
+ _has_bits_[0] |= cached_has_bits;
+ }
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+}
+
+void EnumValueDescriptorProto::CopyFrom(const EnumValueDescriptorProto& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.EnumValueDescriptorProto)
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+bool EnumValueDescriptorProto::IsInitialized() const {
+ if (_internal_has_options()) {
+ if (!options_->IsInitialized()) return false;
+ }
+ return true;
+}
+
+void EnumValueDescriptorProto::InternalSwap(EnumValueDescriptorProto* other) {
+ using std::swap;
+ auto* lhs_arena = GetArenaForAllocation();
+ auto* rhs_arena = other->GetArenaForAllocation();
+ _internal_metadata_.InternalSwap(&other->_internal_metadata_);
+ swap(_has_bits_[0], other->_has_bits_[0]);
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(),
+ &name_, lhs_arena,
+ &other->name_, rhs_arena
+ );
+ ::PROTOBUF_NAMESPACE_ID::internal::memswap<
+ PROTOBUF_FIELD_OFFSET(EnumValueDescriptorProto, number_)
+ + sizeof(EnumValueDescriptorProto::number_)
+ - PROTOBUF_FIELD_OFFSET(EnumValueDescriptorProto, options_)>(
+ reinterpret_cast<char*>(&options_),
+ reinterpret_cast<char*>(&other->options_));
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata EnumValueDescriptorProto::GetMetadata() const {
+ return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(
+ &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
+ file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[10]);
+}
+
+// ===================================================================
+
+class ServiceDescriptorProto::_Internal {
+ public:
+ using HasBits = decltype(std::declval<ServiceDescriptorProto>()._has_bits_);
+ static void set_has_name(HasBits* has_bits) {
+ (*has_bits)[0] |= 1u;
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::ServiceOptions& options(const ServiceDescriptorProto* msg);
+ static void set_has_options(HasBits* has_bits) {
+ (*has_bits)[0] |= 2u;
+ }
+};
+
+const ::PROTOBUF_NAMESPACE_ID::ServiceOptions&
+ServiceDescriptorProto::_Internal::options(const ServiceDescriptorProto* msg) {
+ return *msg->options_;
+}
+ServiceDescriptorProto::ServiceDescriptorProto(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned)
+ : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned),
+ method_(arena) {
+ SharedCtor();
+ if (!is_message_owned) {
+ RegisterArenaDtor(arena);
+ }
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.ServiceDescriptorProto)
+}
+ServiceDescriptorProto::ServiceDescriptorProto(const ServiceDescriptorProto& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message(),
+ _has_bits_(from._has_bits_),
+ method_(from.method_) {
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (from._internal_has_name()) {
+ name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_name(),
+ GetArenaForAllocation());
+ }
+ if (from._internal_has_options()) {
+ options_ = new ::PROTOBUF_NAMESPACE_ID::ServiceOptions(*from.options_);
+ } else {
+ options_ = nullptr;
+ }
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.ServiceDescriptorProto)
+}
+
+inline void ServiceDescriptorProto::SharedCtor() {
+name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+options_ = nullptr;
+}
+
+ServiceDescriptorProto::~ServiceDescriptorProto() {
+ // @@protoc_insertion_point(destructor:google.protobuf.ServiceDescriptorProto)
+ if (GetArenaForAllocation() != nullptr) return;
+ SharedDtor();
+ _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+inline void ServiceDescriptorProto::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+ name_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ if (this != internal_default_instance()) delete options_;
+}
+
+void ServiceDescriptorProto::ArenaDtor(void* object) {
+ ServiceDescriptorProto* _this = reinterpret_cast< ServiceDescriptorProto* >(object);
+ (void)_this;
+}
+void ServiceDescriptorProto::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) {
+}
+void ServiceDescriptorProto::SetCachedSize(int size) const {
+ _cached_size_.Set(size);
+}
+
+void ServiceDescriptorProto::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.ServiceDescriptorProto)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ method_.Clear();
+ cached_has_bits = _has_bits_[0];
+ if (cached_has_bits & 0x00000003u) {
+ if (cached_has_bits & 0x00000001u) {
+ name_.ClearNonDefaultToEmpty();
+ }
+ if (cached_has_bits & 0x00000002u) {
+ GOOGLE_DCHECK(options_ != nullptr);
+ options_->Clear();
+ }
+ }
+ _has_bits_.Clear();
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* ServiceDescriptorProto::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ _Internal::HasBits has_bits{};
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag);
+ switch (tag >> 3) {
+ // optional string name = 1;
+ case 1:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 10)) {
+ auto str = _internal_mutable_name();
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx);
+ #ifndef NDEBUG
+ ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.ServiceDescriptorProto.name");
+ #endif // !NDEBUG
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // repeated .google.protobuf.MethodDescriptorProto method = 2;
+ case 2:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 18)) {
+ ptr -= 1;
+ do {
+ ptr += 1;
+ ptr = ctx->ParseMessage(_internal_add_method(), ptr);
+ CHK_(ptr);
+ if (!ctx->DataAvailable(ptr)) break;
+ } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<18>(ptr));
+ } else
+ goto handle_unusual;
+ continue;
+ // optional .google.protobuf.ServiceOptions options = 3;
+ case 3:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 26)) {
+ ptr = ctx->ParseMessage(_internal_mutable_options(), ptr);
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ default:
+ goto handle_unusual;
+ } // switch
+ handle_unusual:
+ if ((tag == 0) || ((tag & 7) == 4)) {
+ CHK_(ptr);
+ ctx->SetLastTag(tag);
+ goto message_done;
+ }
+ ptr = UnknownFieldParse(
+ tag,
+ _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(),
+ ptr, ctx);
+ CHK_(ptr != nullptr);
+ } // while
+message_done:
+ _has_bits_.Or(has_bits);
+ return ptr;
+failure:
+ ptr = nullptr;
+ goto message_done;
+#undef CHK_
+}
+
+uint8_t* ServiceDescriptorProto::_InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const {
+ // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.ServiceDescriptorProto)
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ cached_has_bits = _has_bits_[0];
+ // optional string name = 1;
+ if (cached_has_bits & 0x00000001u) {
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField(
+ this->_internal_name().data(), static_cast<int>(this->_internal_name().length()),
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE,
+ "google.protobuf.ServiceDescriptorProto.name");
+ target = stream->WriteStringMaybeAliased(
+ 1, this->_internal_name(), target);
+ }
+
+ // repeated .google.protobuf.MethodDescriptorProto method = 2;
+ for (unsigned int i = 0,
+ n = static_cast<unsigned int>(this->_internal_method_size()); i < n; i++) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(2, this->_internal_method(i), target, stream);
+ }
+
+ // optional .google.protobuf.ServiceOptions options = 3;
+ if (cached_has_bits & 0x00000002u) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(
+ 3, _Internal::options(this), target, stream);
+ }
+
+ if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray(
+ _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.ServiceDescriptorProto)
+ return target;
+}
+
+size_t ServiceDescriptorProto::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.ServiceDescriptorProto)
+ size_t total_size = 0;
+
+ 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->method_) {
+ total_size +=
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg);
+ }
+
+ cached_has_bits = _has_bits_[0];
+ if (cached_has_bits & 0x00000003u) {
+ // optional string name = 1;
+ if (cached_has_bits & 0x00000001u) {
+ total_size += 1 +
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
+ this->_internal_name());
+ }
+
+ // optional .google.protobuf.ServiceOptions options = 3;
+ if (cached_has_bits & 0x00000002u) {
+ total_size += 1 +
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(
+ *options_);
+ }
+
+ }
+ return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData ServiceDescriptorProto::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck,
+ ServiceDescriptorProto::MergeImpl
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*ServiceDescriptorProto::GetClassData() const { return &_class_data_; }
+
+void ServiceDescriptorProto::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to,
+ const ::PROTOBUF_NAMESPACE_ID::Message& from) {
+ static_cast<ServiceDescriptorProto *>(to)->MergeFrom(
+ static_cast<const ServiceDescriptorProto &>(from));
+}
+
+
+void ServiceDescriptorProto::MergeFrom(const ServiceDescriptorProto& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.ServiceDescriptorProto)
+ GOOGLE_DCHECK_NE(&from, this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ method_.MergeFrom(from.method_);
+ cached_has_bits = from._has_bits_[0];
+ if (cached_has_bits & 0x00000003u) {
+ if (cached_has_bits & 0x00000001u) {
+ _internal_set_name(from._internal_name());
+ }
+ if (cached_has_bits & 0x00000002u) {
+ _internal_mutable_options()->::PROTOBUF_NAMESPACE_ID::ServiceOptions::MergeFrom(from._internal_options());
+ }
+ }
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+}
+
+void ServiceDescriptorProto::CopyFrom(const ServiceDescriptorProto& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.ServiceDescriptorProto)
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+bool ServiceDescriptorProto::IsInitialized() const {
+ if (!::PROTOBUF_NAMESPACE_ID::internal::AllAreInitialized(method_))
+ return false;
+ if (_internal_has_options()) {
+ if (!options_->IsInitialized()) return false;
+ }
+ return true;
+}
+
+void ServiceDescriptorProto::InternalSwap(ServiceDescriptorProto* other) {
+ using std::swap;
+ auto* lhs_arena = GetArenaForAllocation();
+ auto* rhs_arena = other->GetArenaForAllocation();
+ _internal_metadata_.InternalSwap(&other->_internal_metadata_);
+ swap(_has_bits_[0], other->_has_bits_[0]);
+ method_.InternalSwap(&other->method_);
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(),
+ &name_, lhs_arena,
+ &other->name_, rhs_arena
+ );
+ swap(options_, other->options_);
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata ServiceDescriptorProto::GetMetadata() const {
+ return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(
+ &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
+ file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[11]);
+}
+
+// ===================================================================
+
+class MethodDescriptorProto::_Internal {
+ public:
+ using HasBits = decltype(std::declval<MethodDescriptorProto>()._has_bits_);
+ static void set_has_name(HasBits* has_bits) {
+ (*has_bits)[0] |= 1u;
+ }
+ static void set_has_input_type(HasBits* has_bits) {
+ (*has_bits)[0] |= 2u;
+ }
+ static void set_has_output_type(HasBits* has_bits) {
+ (*has_bits)[0] |= 4u;
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::MethodOptions& options(const MethodDescriptorProto* msg);
+ static void set_has_options(HasBits* has_bits) {
+ (*has_bits)[0] |= 8u;
+ }
+ static void set_has_client_streaming(HasBits* has_bits) {
+ (*has_bits)[0] |= 16u;
+ }
+ static void set_has_server_streaming(HasBits* has_bits) {
+ (*has_bits)[0] |= 32u;
+ }
+};
+
+const ::PROTOBUF_NAMESPACE_ID::MethodOptions&
+MethodDescriptorProto::_Internal::options(const MethodDescriptorProto* msg) {
+ return *msg->options_;
+}
+MethodDescriptorProto::MethodDescriptorProto(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned)
+ : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) {
+ SharedCtor();
+ if (!is_message_owned) {
+ RegisterArenaDtor(arena);
+ }
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.MethodDescriptorProto)
+}
+MethodDescriptorProto::MethodDescriptorProto(const MethodDescriptorProto& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message(),
+ _has_bits_(from._has_bits_) {
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (from._internal_has_name()) {
+ name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_name(),
+ GetArenaForAllocation());
+ }
+ input_type_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ input_type_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (from._internal_has_input_type()) {
+ input_type_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_input_type(),
+ GetArenaForAllocation());
+ }
+ output_type_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ output_type_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (from._internal_has_output_type()) {
+ output_type_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_output_type(),
+ GetArenaForAllocation());
+ }
+ if (from._internal_has_options()) {
+ options_ = new ::PROTOBUF_NAMESPACE_ID::MethodOptions(*from.options_);
+ } else {
+ options_ = nullptr;
+ }
+ ::memcpy(&client_streaming_, &from.client_streaming_,
+ static_cast<size_t>(reinterpret_cast<char*>(&server_streaming_) -
+ reinterpret_cast<char*>(&client_streaming_)) + sizeof(server_streaming_));
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.MethodDescriptorProto)
+}
+
+inline void MethodDescriptorProto::SharedCtor() {
+name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+input_type_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ input_type_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+output_type_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ output_type_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+::memset(reinterpret_cast<char*>(this) + static_cast<size_t>(
+ reinterpret_cast<char*>(&options_) - reinterpret_cast<char*>(this)),
+ 0, static_cast<size_t>(reinterpret_cast<char*>(&server_streaming_) -
+ reinterpret_cast<char*>(&options_)) + sizeof(server_streaming_));
+}
+
+MethodDescriptorProto::~MethodDescriptorProto() {
+ // @@protoc_insertion_point(destructor:google.protobuf.MethodDescriptorProto)
+ if (GetArenaForAllocation() != nullptr) return;
+ SharedDtor();
+ _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+inline void MethodDescriptorProto::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+ name_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ input_type_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ output_type_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ if (this != internal_default_instance()) delete options_;
+}
+
+void MethodDescriptorProto::ArenaDtor(void* object) {
+ MethodDescriptorProto* _this = reinterpret_cast< MethodDescriptorProto* >(object);
+ (void)_this;
+}
+void MethodDescriptorProto::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) {
+}
+void MethodDescriptorProto::SetCachedSize(int size) const {
+ _cached_size_.Set(size);
+}
+
+void MethodDescriptorProto::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.MethodDescriptorProto)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ cached_has_bits = _has_bits_[0];
+ if (cached_has_bits & 0x0000000fu) {
+ if (cached_has_bits & 0x00000001u) {
+ name_.ClearNonDefaultToEmpty();
+ }
+ if (cached_has_bits & 0x00000002u) {
+ input_type_.ClearNonDefaultToEmpty();
+ }
+ if (cached_has_bits & 0x00000004u) {
+ output_type_.ClearNonDefaultToEmpty();
+ }
+ if (cached_has_bits & 0x00000008u) {
+ GOOGLE_DCHECK(options_ != nullptr);
+ options_->Clear();
+ }
+ }
+ ::memset(&client_streaming_, 0, static_cast<size_t>(
+ reinterpret_cast<char*>(&server_streaming_) -
+ reinterpret_cast<char*>(&client_streaming_)) + sizeof(server_streaming_));
+ _has_bits_.Clear();
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* MethodDescriptorProto::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ _Internal::HasBits has_bits{};
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag);
+ switch (tag >> 3) {
+ // optional string name = 1;
+ case 1:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 10)) {
+ auto str = _internal_mutable_name();
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx);
+ #ifndef NDEBUG
+ ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.MethodDescriptorProto.name");
+ #endif // !NDEBUG
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // optional string input_type = 2;
+ case 2:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 18)) {
+ auto str = _internal_mutable_input_type();
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx);
+ #ifndef NDEBUG
+ ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.MethodDescriptorProto.input_type");
+ #endif // !NDEBUG
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // optional string output_type = 3;
+ case 3:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 26)) {
+ auto str = _internal_mutable_output_type();
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx);
+ #ifndef NDEBUG
+ ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.MethodDescriptorProto.output_type");
+ #endif // !NDEBUG
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // optional .google.protobuf.MethodOptions options = 4;
+ case 4:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 34)) {
+ ptr = ctx->ParseMessage(_internal_mutable_options(), ptr);
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // optional bool client_streaming = 5 [default = false];
+ case 5:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 40)) {
+ _Internal::set_has_client_streaming(&has_bits);
+ client_streaming_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr);
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // optional bool server_streaming = 6 [default = false];
+ case 6:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 48)) {
+ _Internal::set_has_server_streaming(&has_bits);
+ server_streaming_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr);
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ default:
+ goto handle_unusual;
+ } // switch
+ handle_unusual:
+ if ((tag == 0) || ((tag & 7) == 4)) {
+ CHK_(ptr);
+ ctx->SetLastTag(tag);
+ goto message_done;
+ }
+ ptr = UnknownFieldParse(
+ tag,
+ _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(),
+ ptr, ctx);
+ CHK_(ptr != nullptr);
+ } // while
+message_done:
+ _has_bits_.Or(has_bits);
+ return ptr;
+failure:
+ ptr = nullptr;
+ goto message_done;
+#undef CHK_
+}
+
+uint8_t* MethodDescriptorProto::_InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const {
+ // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.MethodDescriptorProto)
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ cached_has_bits = _has_bits_[0];
+ // optional string name = 1;
+ if (cached_has_bits & 0x00000001u) {
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField(
+ this->_internal_name().data(), static_cast<int>(this->_internal_name().length()),
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE,
+ "google.protobuf.MethodDescriptorProto.name");
+ target = stream->WriteStringMaybeAliased(
+ 1, this->_internal_name(), target);
+ }
+
+ // optional string input_type = 2;
+ if (cached_has_bits & 0x00000002u) {
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField(
+ this->_internal_input_type().data(), static_cast<int>(this->_internal_input_type().length()),
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE,
+ "google.protobuf.MethodDescriptorProto.input_type");
+ target = stream->WriteStringMaybeAliased(
+ 2, this->_internal_input_type(), target);
+ }
+
+ // optional string output_type = 3;
+ if (cached_has_bits & 0x00000004u) {
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField(
+ this->_internal_output_type().data(), static_cast<int>(this->_internal_output_type().length()),
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE,
+ "google.protobuf.MethodDescriptorProto.output_type");
+ target = stream->WriteStringMaybeAliased(
+ 3, this->_internal_output_type(), target);
+ }
+
+ // optional .google.protobuf.MethodOptions options = 4;
+ if (cached_has_bits & 0x00000008u) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(
+ 4, _Internal::options(this), target, stream);
+ }
+
+ // optional bool client_streaming = 5 [default = false];
+ if (cached_has_bits & 0x00000010u) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBoolToArray(5, this->_internal_client_streaming(), target);
+ }
+
+ // optional bool server_streaming = 6 [default = false];
+ if (cached_has_bits & 0x00000020u) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBoolToArray(6, this->_internal_server_streaming(), target);
+ }
+
+ if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray(
+ _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.MethodDescriptorProto)
+ return target;
+}
+
+size_t MethodDescriptorProto::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.MethodDescriptorProto)
+ size_t total_size = 0;
+
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ cached_has_bits = _has_bits_[0];
+ if (cached_has_bits & 0x0000003fu) {
+ // optional string name = 1;
+ if (cached_has_bits & 0x00000001u) {
+ total_size += 1 +
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
+ this->_internal_name());
+ }
+
+ // optional string input_type = 2;
+ if (cached_has_bits & 0x00000002u) {
+ total_size += 1 +
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
+ this->_internal_input_type());
+ }
+
+ // optional string output_type = 3;
+ if (cached_has_bits & 0x00000004u) {
+ total_size += 1 +
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
+ this->_internal_output_type());
+ }
+
+ // optional .google.protobuf.MethodOptions options = 4;
+ if (cached_has_bits & 0x00000008u) {
+ total_size += 1 +
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(
+ *options_);
+ }
+
+ // optional bool client_streaming = 5 [default = false];
+ if (cached_has_bits & 0x00000010u) {
+ total_size += 1 + 1;
+ }
+
+ // optional bool server_streaming = 6 [default = false];
+ if (cached_has_bits & 0x00000020u) {
+ total_size += 1 + 1;
+ }
+
+ }
+ return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData MethodDescriptorProto::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck,
+ MethodDescriptorProto::MergeImpl
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*MethodDescriptorProto::GetClassData() const { return &_class_data_; }
+
+void MethodDescriptorProto::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to,
+ const ::PROTOBUF_NAMESPACE_ID::Message& from) {
+ static_cast<MethodDescriptorProto *>(to)->MergeFrom(
+ static_cast<const MethodDescriptorProto &>(from));
+}
+
+
+void MethodDescriptorProto::MergeFrom(const MethodDescriptorProto& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.MethodDescriptorProto)
+ GOOGLE_DCHECK_NE(&from, this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ cached_has_bits = from._has_bits_[0];
+ if (cached_has_bits & 0x0000003fu) {
+ if (cached_has_bits & 0x00000001u) {
+ _internal_set_name(from._internal_name());
+ }
+ if (cached_has_bits & 0x00000002u) {
+ _internal_set_input_type(from._internal_input_type());
+ }
+ if (cached_has_bits & 0x00000004u) {
+ _internal_set_output_type(from._internal_output_type());
+ }
+ if (cached_has_bits & 0x00000008u) {
+ _internal_mutable_options()->::PROTOBUF_NAMESPACE_ID::MethodOptions::MergeFrom(from._internal_options());
+ }
+ if (cached_has_bits & 0x00000010u) {
+ client_streaming_ = from.client_streaming_;
+ }
+ if (cached_has_bits & 0x00000020u) {
+ server_streaming_ = from.server_streaming_;
+ }
+ _has_bits_[0] |= cached_has_bits;
+ }
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+}
+
+void MethodDescriptorProto::CopyFrom(const MethodDescriptorProto& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.MethodDescriptorProto)
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+bool MethodDescriptorProto::IsInitialized() const {
+ if (_internal_has_options()) {
+ if (!options_->IsInitialized()) return false;
+ }
+ return true;
+}
+
+void MethodDescriptorProto::InternalSwap(MethodDescriptorProto* other) {
+ using std::swap;
+ auto* lhs_arena = GetArenaForAllocation();
+ auto* rhs_arena = other->GetArenaForAllocation();
+ _internal_metadata_.InternalSwap(&other->_internal_metadata_);
+ swap(_has_bits_[0], other->_has_bits_[0]);
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(),
+ &name_, lhs_arena,
+ &other->name_, rhs_arena
+ );
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(),
+ &input_type_, lhs_arena,
+ &other->input_type_, rhs_arena
+ );
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(),
+ &output_type_, lhs_arena,
+ &other->output_type_, rhs_arena
+ );
+ ::PROTOBUF_NAMESPACE_ID::internal::memswap<
+ PROTOBUF_FIELD_OFFSET(MethodDescriptorProto, server_streaming_)
+ + sizeof(MethodDescriptorProto::server_streaming_)
+ - PROTOBUF_FIELD_OFFSET(MethodDescriptorProto, options_)>(
+ reinterpret_cast<char*>(&options_),
+ reinterpret_cast<char*>(&other->options_));
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata MethodDescriptorProto::GetMetadata() const {
+ return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(
+ &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
+ file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[12]);
+}
+
+// ===================================================================
+
+class FileOptions::_Internal {
+ public:
+ using HasBits = decltype(std::declval<FileOptions>()._has_bits_);
+ static void set_has_java_package(HasBits* has_bits) {
+ (*has_bits)[0] |= 1u;
+ }
+ static void set_has_java_outer_classname(HasBits* has_bits) {
+ (*has_bits)[0] |= 2u;
+ }
+ static void set_has_java_multiple_files(HasBits* has_bits) {
+ (*has_bits)[0] |= 1024u;
+ }
+ static void set_has_java_generate_equals_and_hash(HasBits* has_bits) {
+ (*has_bits)[0] |= 2048u;
+ }
+ static void set_has_java_string_check_utf8(HasBits* has_bits) {
+ (*has_bits)[0] |= 4096u;
+ }
+ static void set_has_optimize_for(HasBits* has_bits) {
+ (*has_bits)[0] |= 262144u;
+ }
+ static void set_has_go_package(HasBits* has_bits) {
+ (*has_bits)[0] |= 4u;
+ }
+ static void set_has_cc_generic_services(HasBits* has_bits) {
+ (*has_bits)[0] |= 8192u;
+ }
+ static void set_has_java_generic_services(HasBits* has_bits) {
+ (*has_bits)[0] |= 16384u;
+ }
+ static void set_has_py_generic_services(HasBits* has_bits) {
+ (*has_bits)[0] |= 32768u;
+ }
+ static void set_has_php_generic_services(HasBits* has_bits) {
+ (*has_bits)[0] |= 65536u;
+ }
+ static void set_has_deprecated(HasBits* has_bits) {
+ (*has_bits)[0] |= 131072u;
+ }
+ static void set_has_cc_enable_arenas(HasBits* has_bits) {
+ (*has_bits)[0] |= 524288u;
+ }
+ static void set_has_objc_class_prefix(HasBits* has_bits) {
+ (*has_bits)[0] |= 8u;
+ }
+ static void set_has_csharp_namespace(HasBits* has_bits) {
+ (*has_bits)[0] |= 16u;
+ }
+ static void set_has_swift_prefix(HasBits* has_bits) {
+ (*has_bits)[0] |= 32u;
+ }
+ static void set_has_php_class_prefix(HasBits* has_bits) {
+ (*has_bits)[0] |= 64u;
+ }
+ static void set_has_php_namespace(HasBits* has_bits) {
+ (*has_bits)[0] |= 128u;
+ }
+ static void set_has_php_metadata_namespace(HasBits* has_bits) {
+ (*has_bits)[0] |= 256u;
+ }
+ static void set_has_ruby_package(HasBits* has_bits) {
+ (*has_bits)[0] |= 512u;
+ }
+};
+
+FileOptions::FileOptions(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned)
+ : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned),
+ _extensions_(arena),
+ uninterpreted_option_(arena) {
+ SharedCtor();
+ if (!is_message_owned) {
+ RegisterArenaDtor(arena);
+ }
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.FileOptions)
+}
+FileOptions::FileOptions(const FileOptions& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message(),
+ _has_bits_(from._has_bits_),
+ uninterpreted_option_(from.uninterpreted_option_) {
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ _extensions_.MergeFrom(internal_default_instance(), from._extensions_);
+ java_package_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ java_package_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (from._internal_has_java_package()) {
+ java_package_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_java_package(),
+ GetArenaForAllocation());
+ }
+ java_outer_classname_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ java_outer_classname_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (from._internal_has_java_outer_classname()) {
+ java_outer_classname_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_java_outer_classname(),
+ GetArenaForAllocation());
+ }
+ go_package_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ go_package_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (from._internal_has_go_package()) {
+ go_package_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_go_package(),
+ GetArenaForAllocation());
+ }
+ objc_class_prefix_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ objc_class_prefix_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (from._internal_has_objc_class_prefix()) {
+ objc_class_prefix_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_objc_class_prefix(),
+ GetArenaForAllocation());
+ }
+ csharp_namespace_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ csharp_namespace_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (from._internal_has_csharp_namespace()) {
+ csharp_namespace_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_csharp_namespace(),
+ GetArenaForAllocation());
+ }
+ swift_prefix_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ swift_prefix_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (from._internal_has_swift_prefix()) {
+ swift_prefix_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_swift_prefix(),
+ GetArenaForAllocation());
+ }
+ php_class_prefix_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ php_class_prefix_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (from._internal_has_php_class_prefix()) {
+ php_class_prefix_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_php_class_prefix(),
+ GetArenaForAllocation());
+ }
+ php_namespace_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ php_namespace_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (from._internal_has_php_namespace()) {
+ php_namespace_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_php_namespace(),
+ GetArenaForAllocation());
+ }
+ php_metadata_namespace_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ php_metadata_namespace_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (from._internal_has_php_metadata_namespace()) {
+ php_metadata_namespace_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_php_metadata_namespace(),
+ GetArenaForAllocation());
+ }
+ ruby_package_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ ruby_package_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (from._internal_has_ruby_package()) {
+ ruby_package_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_ruby_package(),
+ GetArenaForAllocation());
+ }
+ ::memcpy(&java_multiple_files_, &from.java_multiple_files_,
+ static_cast<size_t>(reinterpret_cast<char*>(&cc_enable_arenas_) -
+ reinterpret_cast<char*>(&java_multiple_files_)) + sizeof(cc_enable_arenas_));
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.FileOptions)
+}
+
+inline void FileOptions::SharedCtor() {
+java_package_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ java_package_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+java_outer_classname_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ java_outer_classname_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+go_package_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ go_package_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+objc_class_prefix_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ objc_class_prefix_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+csharp_namespace_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ csharp_namespace_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+swift_prefix_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ swift_prefix_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+php_class_prefix_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ php_class_prefix_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+php_namespace_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ php_namespace_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+php_metadata_namespace_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ php_metadata_namespace_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ruby_package_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ ruby_package_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+::memset(reinterpret_cast<char*>(this) + static_cast<size_t>(
+ reinterpret_cast<char*>(&java_multiple_files_) - reinterpret_cast<char*>(this)),
+ 0, static_cast<size_t>(reinterpret_cast<char*>(&deprecated_) -
+ reinterpret_cast<char*>(&java_multiple_files_)) + sizeof(deprecated_));
+optimize_for_ = 1;
+cc_enable_arenas_ = true;
+}
+
+FileOptions::~FileOptions() {
+ // @@protoc_insertion_point(destructor:google.protobuf.FileOptions)
+ if (GetArenaForAllocation() != nullptr) return;
+ SharedDtor();
+ _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+inline void FileOptions::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+ java_package_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ java_outer_classname_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ go_package_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ objc_class_prefix_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ csharp_namespace_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ swift_prefix_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ php_class_prefix_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ php_namespace_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ php_metadata_namespace_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ ruby_package_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+}
+
+void FileOptions::ArenaDtor(void* object) {
+ FileOptions* _this = reinterpret_cast< FileOptions* >(object);
+ (void)_this;
+}
+void FileOptions::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) {
+}
+void FileOptions::SetCachedSize(int size) const {
+ _cached_size_.Set(size);
+}
+
+void FileOptions::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.FileOptions)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ _extensions_.Clear();
+ uninterpreted_option_.Clear();
+ cached_has_bits = _has_bits_[0];
+ if (cached_has_bits & 0x000000ffu) {
+ if (cached_has_bits & 0x00000001u) {
+ java_package_.ClearNonDefaultToEmpty();
+ }
+ if (cached_has_bits & 0x00000002u) {
+ java_outer_classname_.ClearNonDefaultToEmpty();
+ }
+ if (cached_has_bits & 0x00000004u) {
+ go_package_.ClearNonDefaultToEmpty();
+ }
+ if (cached_has_bits & 0x00000008u) {
+ objc_class_prefix_.ClearNonDefaultToEmpty();
+ }
+ if (cached_has_bits & 0x00000010u) {
+ csharp_namespace_.ClearNonDefaultToEmpty();
+ }
+ if (cached_has_bits & 0x00000020u) {
+ swift_prefix_.ClearNonDefaultToEmpty();
+ }
+ if (cached_has_bits & 0x00000040u) {
+ php_class_prefix_.ClearNonDefaultToEmpty();
+ }
+ if (cached_has_bits & 0x00000080u) {
+ php_namespace_.ClearNonDefaultToEmpty();
+ }
+ }
+ if (cached_has_bits & 0x00000300u) {
+ if (cached_has_bits & 0x00000100u) {
+ php_metadata_namespace_.ClearNonDefaultToEmpty();
+ }
+ if (cached_has_bits & 0x00000200u) {
+ ruby_package_.ClearNonDefaultToEmpty();
+ }
+ }
+ if (cached_has_bits & 0x0000fc00u) {
+ ::memset(&java_multiple_files_, 0, static_cast<size_t>(
+ reinterpret_cast<char*>(&py_generic_services_) -
+ reinterpret_cast<char*>(&java_multiple_files_)) + sizeof(py_generic_services_));
+ }
+ if (cached_has_bits & 0x000f0000u) {
+ ::memset(&php_generic_services_, 0, static_cast<size_t>(
+ reinterpret_cast<char*>(&deprecated_) -
+ reinterpret_cast<char*>(&php_generic_services_)) + sizeof(deprecated_));
+ optimize_for_ = 1;
+ cc_enable_arenas_ = true;
+ }
+ _has_bits_.Clear();
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* FileOptions::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ _Internal::HasBits has_bits{};
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag);
+ switch (tag >> 3) {
+ // optional string java_package = 1;
+ case 1:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 10)) {
+ auto str = _internal_mutable_java_package();
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx);
+ #ifndef NDEBUG
+ ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.FileOptions.java_package");
+ #endif // !NDEBUG
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // optional string java_outer_classname = 8;
+ case 8:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 66)) {
+ auto str = _internal_mutable_java_outer_classname();
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx);
+ #ifndef NDEBUG
+ ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.FileOptions.java_outer_classname");
+ #endif // !NDEBUG
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED];
+ case 9:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 72)) {
+ 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);
+ java_multiple_files_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr);
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // optional string go_package = 11;
+ case 11:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 90)) {
+ auto str = _internal_mutable_go_package();
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx);
+ #ifndef NDEBUG
+ ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.FileOptions.go_package");
+ #endif // !NDEBUG
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // optional bool cc_generic_services = 16 [default = false];
+ case 16:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 128)) {
+ _Internal::set_has_cc_generic_services(&has_bits);
+ cc_generic_services_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr);
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // optional bool java_generic_services = 17 [default = false];
+ case 17:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 136)) {
+ _Internal::set_has_java_generic_services(&has_bits);
+ java_generic_services_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr);
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // optional bool py_generic_services = 18 [default = false];
+ case 18:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 144)) {
+ _Internal::set_has_py_generic_services(&has_bits);
+ py_generic_services_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr);
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // optional bool java_generate_equals_and_hash = 20 [deprecated = true];
+ case 20:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 160)) {
+ _Internal::set_has_java_generate_equals_and_hash(&has_bits);
+ java_generate_equals_and_hash_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr);
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // optional bool deprecated = 23 [default = false];
+ case 23:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 184)) {
+ _Internal::set_has_deprecated(&has_bits);
+ deprecated_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr);
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // optional bool java_string_check_utf8 = 27 [default = false];
+ case 27:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 216)) {
+ _Internal::set_has_java_string_check_utf8(&has_bits);
+ java_string_check_utf8_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr);
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // optional bool cc_enable_arenas = 31 [default = true];
+ case 31:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 248)) {
+ _Internal::set_has_cc_enable_arenas(&has_bits);
+ cc_enable_arenas_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr);
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // optional string objc_class_prefix = 36;
+ case 36:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 34)) {
+ auto str = _internal_mutable_objc_class_prefix();
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx);
+ #ifndef NDEBUG
+ ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.FileOptions.objc_class_prefix");
+ #endif // !NDEBUG
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // optional string csharp_namespace = 37;
+ case 37:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 42)) {
+ auto str = _internal_mutable_csharp_namespace();
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx);
+ #ifndef NDEBUG
+ ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.FileOptions.csharp_namespace");
+ #endif // !NDEBUG
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // optional string swift_prefix = 39;
+ case 39:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 58)) {
+ auto str = _internal_mutable_swift_prefix();
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx);
+ #ifndef NDEBUG
+ ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.FileOptions.swift_prefix");
+ #endif // !NDEBUG
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // optional string php_class_prefix = 40;
+ case 40:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 66)) {
+ auto str = _internal_mutable_php_class_prefix();
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx);
+ #ifndef NDEBUG
+ ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.FileOptions.php_class_prefix");
+ #endif // !NDEBUG
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // optional string php_namespace = 41;
+ case 41:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 74)) {
+ auto str = _internal_mutable_php_namespace();
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx);
+ #ifndef NDEBUG
+ ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.FileOptions.php_namespace");
+ #endif // !NDEBUG
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // optional bool php_generic_services = 42 [default = false];
+ case 42:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 80)) {
+ _Internal::set_has_php_generic_services(&has_bits);
+ php_generic_services_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr);
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // optional string php_metadata_namespace = 44;
+ case 44:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 98)) {
+ auto str = _internal_mutable_php_metadata_namespace();
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx);
+ #ifndef NDEBUG
+ ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.FileOptions.php_metadata_namespace");
+ #endif // !NDEBUG
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // optional string ruby_package = 45;
+ case 45:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 106)) {
+ auto str = _internal_mutable_ruby_package();
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx);
+ #ifndef NDEBUG
+ ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.FileOptions.ruby_package");
+ #endif // !NDEBUG
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+ case 999:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 58)) {
+ ptr -= 2;
+ do {
+ ptr += 2;
+ ptr = ctx->ParseMessage(_internal_add_uninterpreted_option(), ptr);
+ CHK_(ptr);
+ if (!ctx->DataAvailable(ptr)) break;
+ } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<7994>(ptr));
+ } else
+ goto handle_unusual;
+ continue;
+ default:
+ goto handle_unusual;
+ } // switch
+ handle_unusual:
+ if ((tag == 0) || ((tag & 7) == 4)) {
+ CHK_(ptr);
+ ctx->SetLastTag(tag);
+ goto message_done;
+ }
+ if ((8000u <= tag)) {
+ ptr = _extensions_.ParseField(tag, ptr, internal_default_instance(), &_internal_metadata_, ctx);
+ CHK_(ptr != nullptr);
+ continue;
+ }
+ ptr = UnknownFieldParse(
+ tag,
+ _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(),
+ ptr, ctx);
+ CHK_(ptr != nullptr);
+ } // while
+message_done:
+ _has_bits_.Or(has_bits);
+ return ptr;
+failure:
+ ptr = nullptr;
+ goto message_done;
+#undef CHK_
+}
+
+uint8_t* FileOptions::_InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const {
+ // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.FileOptions)
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ cached_has_bits = _has_bits_[0];
+ // optional string java_package = 1;
+ if (cached_has_bits & 0x00000001u) {
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField(
+ this->_internal_java_package().data(), static_cast<int>(this->_internal_java_package().length()),
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE,
+ "google.protobuf.FileOptions.java_package");
+ target = stream->WriteStringMaybeAliased(
+ 1, this->_internal_java_package(), target);
+ }
+
+ // optional string java_outer_classname = 8;
+ if (cached_has_bits & 0x00000002u) {
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField(
+ this->_internal_java_outer_classname().data(), static_cast<int>(this->_internal_java_outer_classname().length()),
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE,
+ "google.protobuf.FileOptions.java_outer_classname");
+ target = stream->WriteStringMaybeAliased(
+ 8, this->_internal_java_outer_classname(), target);
+ }
+
+ // optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED];
+ if (cached_has_bits & 0x00040000u) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteEnumToArray(
+ 9, this->_internal_optimize_for(), target);
+ }
+
+ // optional bool java_multiple_files = 10 [default = false];
+ if (cached_has_bits & 0x00000400u) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBoolToArray(10, this->_internal_java_multiple_files(), target);
+ }
+
+ // optional string go_package = 11;
+ if (cached_has_bits & 0x00000004u) {
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField(
+ this->_internal_go_package().data(), static_cast<int>(this->_internal_go_package().length()),
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE,
+ "google.protobuf.FileOptions.go_package");
+ target = stream->WriteStringMaybeAliased(
+ 11, this->_internal_go_package(), target);
+ }
+
+ // optional bool cc_generic_services = 16 [default = false];
+ if (cached_has_bits & 0x00002000u) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBoolToArray(16, this->_internal_cc_generic_services(), target);
+ }
+
+ // optional bool java_generic_services = 17 [default = false];
+ if (cached_has_bits & 0x00004000u) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBoolToArray(17, this->_internal_java_generic_services(), target);
+ }
+
+ // optional bool py_generic_services = 18 [default = false];
+ if (cached_has_bits & 0x00008000u) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBoolToArray(18, this->_internal_py_generic_services(), target);
+ }
+
+ // optional bool java_generate_equals_and_hash = 20 [deprecated = true];
+ if (cached_has_bits & 0x00000800u) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBoolToArray(20, this->_internal_java_generate_equals_and_hash(), target);
+ }
+
+ // optional bool deprecated = 23 [default = false];
+ if (cached_has_bits & 0x00020000u) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBoolToArray(23, this->_internal_deprecated(), target);
+ }
+
+ // optional bool java_string_check_utf8 = 27 [default = false];
+ if (cached_has_bits & 0x00001000u) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBoolToArray(27, this->_internal_java_string_check_utf8(), target);
+ }
+
+ // optional bool cc_enable_arenas = 31 [default = true];
+ if (cached_has_bits & 0x00080000u) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBoolToArray(31, this->_internal_cc_enable_arenas(), target);
+ }
+
+ // optional string objc_class_prefix = 36;
+ if (cached_has_bits & 0x00000008u) {
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField(
+ this->_internal_objc_class_prefix().data(), static_cast<int>(this->_internal_objc_class_prefix().length()),
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE,
+ "google.protobuf.FileOptions.objc_class_prefix");
+ target = stream->WriteStringMaybeAliased(
+ 36, this->_internal_objc_class_prefix(), target);
+ }
+
+ // optional string csharp_namespace = 37;
+ if (cached_has_bits & 0x00000010u) {
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField(
+ this->_internal_csharp_namespace().data(), static_cast<int>(this->_internal_csharp_namespace().length()),
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE,
+ "google.protobuf.FileOptions.csharp_namespace");
+ target = stream->WriteStringMaybeAliased(
+ 37, this->_internal_csharp_namespace(), target);
+ }
+
+ // optional string swift_prefix = 39;
+ if (cached_has_bits & 0x00000020u) {
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField(
+ this->_internal_swift_prefix().data(), static_cast<int>(this->_internal_swift_prefix().length()),
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE,
+ "google.protobuf.FileOptions.swift_prefix");
+ target = stream->WriteStringMaybeAliased(
+ 39, this->_internal_swift_prefix(), target);
+ }
+
+ // optional string php_class_prefix = 40;
+ if (cached_has_bits & 0x00000040u) {
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField(
+ this->_internal_php_class_prefix().data(), static_cast<int>(this->_internal_php_class_prefix().length()),
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE,
+ "google.protobuf.FileOptions.php_class_prefix");
+ target = stream->WriteStringMaybeAliased(
+ 40, this->_internal_php_class_prefix(), target);
+ }
+
+ // optional string php_namespace = 41;
+ if (cached_has_bits & 0x00000080u) {
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField(
+ this->_internal_php_namespace().data(), static_cast<int>(this->_internal_php_namespace().length()),
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE,
+ "google.protobuf.FileOptions.php_namespace");
+ target = stream->WriteStringMaybeAliased(
+ 41, this->_internal_php_namespace(), target);
+ }
+
+ // optional bool php_generic_services = 42 [default = false];
+ if (cached_has_bits & 0x00010000u) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBoolToArray(42, this->_internal_php_generic_services(), target);
+ }
+
+ // optional string php_metadata_namespace = 44;
+ if (cached_has_bits & 0x00000100u) {
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField(
+ this->_internal_php_metadata_namespace().data(), static_cast<int>(this->_internal_php_metadata_namespace().length()),
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE,
+ "google.protobuf.FileOptions.php_metadata_namespace");
+ target = stream->WriteStringMaybeAliased(
+ 44, this->_internal_php_metadata_namespace(), target);
+ }
+
+ // optional string ruby_package = 45;
+ if (cached_has_bits & 0x00000200u) {
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField(
+ this->_internal_ruby_package().data(), static_cast<int>(this->_internal_ruby_package().length()),
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE,
+ "google.protobuf.FileOptions.ruby_package");
+ target = stream->WriteStringMaybeAliased(
+ 45, this->_internal_ruby_package(), target);
+ }
+
+ // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+ for (unsigned int i = 0,
+ n = static_cast<unsigned int>(this->_internal_uninterpreted_option_size()); i < n; i++) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(999, this->_internal_uninterpreted_option(i), target, stream);
+ }
+
+ // Extension range [1000, 536870912)
+ target = _extensions_._InternalSerialize(
+ internal_default_instance(), 1000, 536870912, target, stream);
+
+ if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray(
+ _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.FileOptions)
+ return target;
+}
+
+size_t FileOptions::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.FileOptions)
+ size_t total_size = 0;
+
+ total_size += _extensions_.ByteSize();
+
+ 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->uninterpreted_option_) {
+ total_size +=
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg);
+ }
+
+ cached_has_bits = _has_bits_[0];
+ if (cached_has_bits & 0x000000ffu) {
+ // optional string java_package = 1;
+ if (cached_has_bits & 0x00000001u) {
+ total_size += 1 +
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
+ this->_internal_java_package());
+ }
+
+ // optional string java_outer_classname = 8;
+ if (cached_has_bits & 0x00000002u) {
+ total_size += 1 +
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
+ this->_internal_java_outer_classname());
+ }
+
+ // optional string go_package = 11;
+ if (cached_has_bits & 0x00000004u) {
+ total_size += 1 +
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
+ this->_internal_go_package());
+ }
+
+ // optional string objc_class_prefix = 36;
+ if (cached_has_bits & 0x00000008u) {
+ total_size += 2 +
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
+ this->_internal_objc_class_prefix());
+ }
+
+ // optional string csharp_namespace = 37;
+ if (cached_has_bits & 0x00000010u) {
+ total_size += 2 +
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
+ this->_internal_csharp_namespace());
+ }
+
+ // optional string swift_prefix = 39;
+ if (cached_has_bits & 0x00000020u) {
+ total_size += 2 +
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
+ this->_internal_swift_prefix());
+ }
+
+ // optional string php_class_prefix = 40;
+ if (cached_has_bits & 0x00000040u) {
+ total_size += 2 +
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
+ this->_internal_php_class_prefix());
+ }
+
+ // optional string php_namespace = 41;
+ if (cached_has_bits & 0x00000080u) {
+ total_size += 2 +
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
+ this->_internal_php_namespace());
+ }
+
+ }
+ if (cached_has_bits & 0x0000ff00u) {
+ // optional string php_metadata_namespace = 44;
+ if (cached_has_bits & 0x00000100u) {
+ total_size += 2 +
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
+ this->_internal_php_metadata_namespace());
+ }
+
+ // optional string ruby_package = 45;
+ if (cached_has_bits & 0x00000200u) {
+ total_size += 2 +
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
+ this->_internal_ruby_package());
+ }
+
+ // optional bool java_multiple_files = 10 [default = false];
+ if (cached_has_bits & 0x00000400u) {
+ total_size += 1 + 1;
+ }
+
+ // optional bool java_generate_equals_and_hash = 20 [deprecated = true];
+ if (cached_has_bits & 0x00000800u) {
+ total_size += 2 + 1;
+ }
+
+ // optional bool java_string_check_utf8 = 27 [default = false];
+ if (cached_has_bits & 0x00001000u) {
+ total_size += 2 + 1;
+ }
+
+ // optional bool cc_generic_services = 16 [default = false];
+ if (cached_has_bits & 0x00002000u) {
+ total_size += 2 + 1;
+ }
+
+ // optional bool java_generic_services = 17 [default = false];
+ if (cached_has_bits & 0x00004000u) {
+ total_size += 2 + 1;
+ }
+
+ // optional bool py_generic_services = 18 [default = false];
+ if (cached_has_bits & 0x00008000u) {
+ total_size += 2 + 1;
+ }
+
+ }
+ if (cached_has_bits & 0x000f0000u) {
+ // optional bool php_generic_services = 42 [default = false];
+ if (cached_has_bits & 0x00010000u) {
+ total_size += 2 + 1;
+ }
+
+ // optional bool deprecated = 23 [default = false];
+ if (cached_has_bits & 0x00020000u) {
+ total_size += 2 + 1;
+ }
+
+ // optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED];
+ if (cached_has_bits & 0x00040000u) {
+ total_size += 1 +
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::EnumSize(this->_internal_optimize_for());
+ }
+
+ // optional bool cc_enable_arenas = 31 [default = true];
+ if (cached_has_bits & 0x00080000u) {
+ total_size += 2 + 1;
+ }
+
+ }
+ return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData FileOptions::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck,
+ FileOptions::MergeImpl
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*FileOptions::GetClassData() const { return &_class_data_; }
+
+void FileOptions::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to,
+ const ::PROTOBUF_NAMESPACE_ID::Message& from) {
+ static_cast<FileOptions *>(to)->MergeFrom(
+ static_cast<const FileOptions &>(from));
+}
+
+
+void FileOptions::MergeFrom(const FileOptions& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.FileOptions)
+ GOOGLE_DCHECK_NE(&from, this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ uninterpreted_option_.MergeFrom(from.uninterpreted_option_);
+ cached_has_bits = from._has_bits_[0];
+ if (cached_has_bits & 0x000000ffu) {
+ if (cached_has_bits & 0x00000001u) {
+ _internal_set_java_package(from._internal_java_package());
+ }
+ if (cached_has_bits & 0x00000002u) {
+ _internal_set_java_outer_classname(from._internal_java_outer_classname());
+ }
+ if (cached_has_bits & 0x00000004u) {
+ _internal_set_go_package(from._internal_go_package());
+ }
+ if (cached_has_bits & 0x00000008u) {
+ _internal_set_objc_class_prefix(from._internal_objc_class_prefix());
+ }
+ if (cached_has_bits & 0x00000010u) {
+ _internal_set_csharp_namespace(from._internal_csharp_namespace());
+ }
+ if (cached_has_bits & 0x00000020u) {
+ _internal_set_swift_prefix(from._internal_swift_prefix());
+ }
+ if (cached_has_bits & 0x00000040u) {
+ _internal_set_php_class_prefix(from._internal_php_class_prefix());
+ }
+ if (cached_has_bits & 0x00000080u) {
+ _internal_set_php_namespace(from._internal_php_namespace());
+ }
+ }
+ if (cached_has_bits & 0x0000ff00u) {
+ if (cached_has_bits & 0x00000100u) {
+ _internal_set_php_metadata_namespace(from._internal_php_metadata_namespace());
+ }
+ if (cached_has_bits & 0x00000200u) {
+ _internal_set_ruby_package(from._internal_ruby_package());
+ }
+ if (cached_has_bits & 0x00000400u) {
+ java_multiple_files_ = from.java_multiple_files_;
+ }
+ if (cached_has_bits & 0x00000800u) {
+ java_generate_equals_and_hash_ = from.java_generate_equals_and_hash_;
+ }
+ if (cached_has_bits & 0x00001000u) {
+ java_string_check_utf8_ = from.java_string_check_utf8_;
+ }
+ if (cached_has_bits & 0x00002000u) {
+ cc_generic_services_ = from.cc_generic_services_;
+ }
+ if (cached_has_bits & 0x00004000u) {
+ java_generic_services_ = from.java_generic_services_;
+ }
+ if (cached_has_bits & 0x00008000u) {
+ py_generic_services_ = from.py_generic_services_;
+ }
+ _has_bits_[0] |= cached_has_bits;
+ }
+ if (cached_has_bits & 0x000f0000u) {
+ if (cached_has_bits & 0x00010000u) {
+ php_generic_services_ = from.php_generic_services_;
+ }
+ if (cached_has_bits & 0x00020000u) {
+ deprecated_ = from.deprecated_;
+ }
+ if (cached_has_bits & 0x00040000u) {
+ optimize_for_ = from.optimize_for_;
+ }
+ if (cached_has_bits & 0x00080000u) {
+ cc_enable_arenas_ = from.cc_enable_arenas_;
+ }
+ _has_bits_[0] |= cached_has_bits;
+ }
+ _extensions_.MergeFrom(internal_default_instance(), from._extensions_);
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+}
+
+void FileOptions::CopyFrom(const FileOptions& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.FileOptions)
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+bool FileOptions::IsInitialized() const {
+ if (!_extensions_.IsInitialized()) {
+ return false;
+ }
+
+ if (!::PROTOBUF_NAMESPACE_ID::internal::AllAreInitialized(uninterpreted_option_))
+ return false;
+ return true;
+}
+
+void FileOptions::InternalSwap(FileOptions* other) {
+ using std::swap;
+ _extensions_.InternalSwap(&other->_extensions_);
+ auto* lhs_arena = GetArenaForAllocation();
+ auto* rhs_arena = other->GetArenaForAllocation();
+ _internal_metadata_.InternalSwap(&other->_internal_metadata_);
+ swap(_has_bits_[0], other->_has_bits_[0]);
+ uninterpreted_option_.InternalSwap(&other->uninterpreted_option_);
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(),
+ &java_package_, lhs_arena,
+ &other->java_package_, rhs_arena
+ );
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(),
+ &java_outer_classname_, lhs_arena,
+ &other->java_outer_classname_, rhs_arena
+ );
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(),
+ &go_package_, lhs_arena,
+ &other->go_package_, rhs_arena
+ );
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(),
+ &objc_class_prefix_, lhs_arena,
+ &other->objc_class_prefix_, rhs_arena
+ );
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(),
+ &csharp_namespace_, lhs_arena,
+ &other->csharp_namespace_, rhs_arena
+ );
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(),
+ &swift_prefix_, lhs_arena,
+ &other->swift_prefix_, rhs_arena
+ );
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(),
+ &php_class_prefix_, lhs_arena,
+ &other->php_class_prefix_, rhs_arena
+ );
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(),
+ &php_namespace_, lhs_arena,
+ &other->php_namespace_, rhs_arena
+ );
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(),
+ &php_metadata_namespace_, lhs_arena,
+ &other->php_metadata_namespace_, rhs_arena
+ );
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(),
+ &ruby_package_, lhs_arena,
+ &other->ruby_package_, rhs_arena
+ );
+ ::PROTOBUF_NAMESPACE_ID::internal::memswap<
+ PROTOBUF_FIELD_OFFSET(FileOptions, deprecated_)
+ + sizeof(FileOptions::deprecated_)
+ - PROTOBUF_FIELD_OFFSET(FileOptions, java_multiple_files_)>(
+ reinterpret_cast<char*>(&java_multiple_files_),
+ reinterpret_cast<char*>(&other->java_multiple_files_));
+ swap(optimize_for_, other->optimize_for_);
+ swap(cc_enable_arenas_, other->cc_enable_arenas_);
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata FileOptions::GetMetadata() const {
+ return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(
+ &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
+ file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[13]);
+}
+
+// ===================================================================
+
+class MessageOptions::_Internal {
+ public:
+ using HasBits = decltype(std::declval<MessageOptions>()._has_bits_);
+ static void set_has_message_set_wire_format(HasBits* has_bits) {
+ (*has_bits)[0] |= 1u;
+ }
+ static void set_has_no_standard_descriptor_accessor(HasBits* has_bits) {
+ (*has_bits)[0] |= 2u;
+ }
+ static void set_has_deprecated(HasBits* has_bits) {
+ (*has_bits)[0] |= 4u;
+ }
+ static void set_has_map_entry(HasBits* has_bits) {
+ (*has_bits)[0] |= 8u;
+ }
+};
+
+MessageOptions::MessageOptions(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned)
+ : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned),
+ _extensions_(arena),
+ uninterpreted_option_(arena) {
+ SharedCtor();
+ if (!is_message_owned) {
+ RegisterArenaDtor(arena);
+ }
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.MessageOptions)
+}
+MessageOptions::MessageOptions(const MessageOptions& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message(),
+ _has_bits_(from._has_bits_),
+ uninterpreted_option_(from.uninterpreted_option_) {
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ _extensions_.MergeFrom(internal_default_instance(), from._extensions_);
+ ::memcpy(&message_set_wire_format_, &from.message_set_wire_format_,
+ static_cast<size_t>(reinterpret_cast<char*>(&map_entry_) -
+ reinterpret_cast<char*>(&message_set_wire_format_)) + sizeof(map_entry_));
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.MessageOptions)
+}
+
+inline void MessageOptions::SharedCtor() {
+::memset(reinterpret_cast<char*>(this) + static_cast<size_t>(
+ reinterpret_cast<char*>(&message_set_wire_format_) - reinterpret_cast<char*>(this)),
+ 0, static_cast<size_t>(reinterpret_cast<char*>(&map_entry_) -
+ reinterpret_cast<char*>(&message_set_wire_format_)) + sizeof(map_entry_));
+}
+
+MessageOptions::~MessageOptions() {
+ // @@protoc_insertion_point(destructor:google.protobuf.MessageOptions)
+ if (GetArenaForAllocation() != nullptr) return;
+ SharedDtor();
+ _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+inline void MessageOptions::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+}
+
+void MessageOptions::ArenaDtor(void* object) {
+ MessageOptions* _this = reinterpret_cast< MessageOptions* >(object);
+ (void)_this;
+}
+void MessageOptions::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) {
+}
+void MessageOptions::SetCachedSize(int size) const {
+ _cached_size_.Set(size);
+}
+
+void MessageOptions::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.MessageOptions)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ _extensions_.Clear();
+ uninterpreted_option_.Clear();
+ ::memset(&message_set_wire_format_, 0, static_cast<size_t>(
+ reinterpret_cast<char*>(&map_entry_) -
+ reinterpret_cast<char*>(&message_set_wire_format_)) + sizeof(map_entry_));
+ _has_bits_.Clear();
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* MessageOptions::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ _Internal::HasBits has_bits{};
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag);
+ switch (tag >> 3) {
+ // optional bool message_set_wire_format = 1 [default = false];
+ case 1:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 8)) {
+ _Internal::set_has_message_set_wire_format(&has_bits);
+ message_set_wire_format_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr);
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // optional bool no_standard_descriptor_accessor = 2 [default = false];
+ case 2:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 16)) {
+ _Internal::set_has_no_standard_descriptor_accessor(&has_bits);
+ no_standard_descriptor_accessor_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr);
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // optional bool deprecated = 3 [default = false];
+ case 3:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 24)) {
+ _Internal::set_has_deprecated(&has_bits);
+ deprecated_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr);
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // optional bool map_entry = 7;
+ case 7:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 56)) {
+ _Internal::set_has_map_entry(&has_bits);
+ map_entry_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr);
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+ case 999:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 58)) {
+ ptr -= 2;
+ do {
+ ptr += 2;
+ ptr = ctx->ParseMessage(_internal_add_uninterpreted_option(), ptr);
+ CHK_(ptr);
+ if (!ctx->DataAvailable(ptr)) break;
+ } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<7994>(ptr));
+ } else
+ goto handle_unusual;
+ continue;
+ default:
+ goto handle_unusual;
+ } // switch
+ handle_unusual:
+ if ((tag == 0) || ((tag & 7) == 4)) {
+ CHK_(ptr);
+ ctx->SetLastTag(tag);
+ goto message_done;
+ }
+ if ((8000u <= tag)) {
+ ptr = _extensions_.ParseField(tag, ptr, internal_default_instance(), &_internal_metadata_, ctx);
+ CHK_(ptr != nullptr);
+ continue;
+ }
+ ptr = UnknownFieldParse(
+ tag,
+ _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(),
+ ptr, ctx);
+ CHK_(ptr != nullptr);
+ } // while
+message_done:
+ _has_bits_.Or(has_bits);
+ return ptr;
+failure:
+ ptr = nullptr;
+ goto message_done;
+#undef CHK_
+}
+
+uint8_t* MessageOptions::_InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const {
+ // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.MessageOptions)
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ cached_has_bits = _has_bits_[0];
+ // optional bool message_set_wire_format = 1 [default = false];
+ if (cached_has_bits & 0x00000001u) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBoolToArray(1, this->_internal_message_set_wire_format(), target);
+ }
+
+ // optional bool no_standard_descriptor_accessor = 2 [default = false];
+ if (cached_has_bits & 0x00000002u) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBoolToArray(2, this->_internal_no_standard_descriptor_accessor(), target);
+ }
+
+ // optional bool deprecated = 3 [default = false];
+ if (cached_has_bits & 0x00000004u) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBoolToArray(3, this->_internal_deprecated(), target);
+ }
+
+ // optional bool map_entry = 7;
+ if (cached_has_bits & 0x00000008u) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBoolToArray(7, this->_internal_map_entry(), target);
+ }
+
+ // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+ for (unsigned int i = 0,
+ n = static_cast<unsigned int>(this->_internal_uninterpreted_option_size()); i < n; i++) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(999, this->_internal_uninterpreted_option(i), target, stream);
+ }
+
+ // Extension range [1000, 536870912)
+ target = _extensions_._InternalSerialize(
+ internal_default_instance(), 1000, 536870912, target, stream);
+
+ if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray(
+ _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.MessageOptions)
+ return target;
+}
+
+size_t MessageOptions::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.MessageOptions)
+ size_t total_size = 0;
+
+ total_size += _extensions_.ByteSize();
+
+ 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->uninterpreted_option_) {
+ total_size +=
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg);
+ }
+
+ cached_has_bits = _has_bits_[0];
+ if (cached_has_bits & 0x0000000fu) {
+ // optional bool message_set_wire_format = 1 [default = false];
+ if (cached_has_bits & 0x00000001u) {
+ total_size += 1 + 1;
+ }
+
+ // optional bool no_standard_descriptor_accessor = 2 [default = false];
+ if (cached_has_bits & 0x00000002u) {
+ total_size += 1 + 1;
+ }
+
+ // optional bool deprecated = 3 [default = false];
+ if (cached_has_bits & 0x00000004u) {
+ total_size += 1 + 1;
+ }
+
+ // optional bool map_entry = 7;
+ if (cached_has_bits & 0x00000008u) {
+ total_size += 1 + 1;
+ }
+
+ }
+ return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData MessageOptions::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck,
+ MessageOptions::MergeImpl
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*MessageOptions::GetClassData() const { return &_class_data_; }
+
+void MessageOptions::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to,
+ const ::PROTOBUF_NAMESPACE_ID::Message& from) {
+ static_cast<MessageOptions *>(to)->MergeFrom(
+ static_cast<const MessageOptions &>(from));
+}
+
+
+void MessageOptions::MergeFrom(const MessageOptions& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.MessageOptions)
+ GOOGLE_DCHECK_NE(&from, this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ uninterpreted_option_.MergeFrom(from.uninterpreted_option_);
+ cached_has_bits = from._has_bits_[0];
+ if (cached_has_bits & 0x0000000fu) {
+ if (cached_has_bits & 0x00000001u) {
+ message_set_wire_format_ = from.message_set_wire_format_;
+ }
+ if (cached_has_bits & 0x00000002u) {
+ no_standard_descriptor_accessor_ = from.no_standard_descriptor_accessor_;
+ }
+ if (cached_has_bits & 0x00000004u) {
+ deprecated_ = from.deprecated_;
+ }
+ if (cached_has_bits & 0x00000008u) {
+ map_entry_ = from.map_entry_;
+ }
+ _has_bits_[0] |= cached_has_bits;
+ }
+ _extensions_.MergeFrom(internal_default_instance(), from._extensions_);
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+}
+
+void MessageOptions::CopyFrom(const MessageOptions& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.MessageOptions)
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+bool MessageOptions::IsInitialized() const {
+ if (!_extensions_.IsInitialized()) {
+ return false;
+ }
+
+ if (!::PROTOBUF_NAMESPACE_ID::internal::AllAreInitialized(uninterpreted_option_))
+ return false;
+ return true;
+}
+
+void MessageOptions::InternalSwap(MessageOptions* other) {
+ using std::swap;
+ _extensions_.InternalSwap(&other->_extensions_);
+ _internal_metadata_.InternalSwap(&other->_internal_metadata_);
+ swap(_has_bits_[0], other->_has_bits_[0]);
+ uninterpreted_option_.InternalSwap(&other->uninterpreted_option_);
+ ::PROTOBUF_NAMESPACE_ID::internal::memswap<
+ PROTOBUF_FIELD_OFFSET(MessageOptions, map_entry_)
+ + sizeof(MessageOptions::map_entry_)
+ - PROTOBUF_FIELD_OFFSET(MessageOptions, message_set_wire_format_)>(
+ reinterpret_cast<char*>(&message_set_wire_format_),
+ reinterpret_cast<char*>(&other->message_set_wire_format_));
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata MessageOptions::GetMetadata() const {
+ return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(
+ &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
+ file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[14]);
+}
+
+// ===================================================================
+
+class FieldOptions::_Internal {
+ public:
+ using HasBits = decltype(std::declval<FieldOptions>()._has_bits_);
+ static void set_has_ctype(HasBits* has_bits) {
+ (*has_bits)[0] |= 1u;
+ }
+ static void set_has_packed(HasBits* has_bits) {
+ (*has_bits)[0] |= 2u;
+ }
+ static void set_has_jstype(HasBits* has_bits) {
+ (*has_bits)[0] |= 32u;
+ }
+ static void set_has_lazy(HasBits* has_bits) {
+ (*has_bits)[0] |= 4u;
+ }
+ static void set_has_deprecated(HasBits* has_bits) {
+ (*has_bits)[0] |= 8u;
+ }
+ static void set_has_weak(HasBits* has_bits) {
+ (*has_bits)[0] |= 16u;
+ }
+};
+
+FieldOptions::FieldOptions(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned)
+ : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned),
+ _extensions_(arena),
+ uninterpreted_option_(arena) {
+ SharedCtor();
+ if (!is_message_owned) {
+ RegisterArenaDtor(arena);
+ }
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.FieldOptions)
+}
+FieldOptions::FieldOptions(const FieldOptions& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message(),
+ _has_bits_(from._has_bits_),
+ uninterpreted_option_(from.uninterpreted_option_) {
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ _extensions_.MergeFrom(internal_default_instance(), from._extensions_);
+ ::memcpy(&ctype_, &from.ctype_,
+ static_cast<size_t>(reinterpret_cast<char*>(&jstype_) -
+ reinterpret_cast<char*>(&ctype_)) + sizeof(jstype_));
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.FieldOptions)
+}
+
+inline void FieldOptions::SharedCtor() {
+::memset(reinterpret_cast<char*>(this) + static_cast<size_t>(
+ reinterpret_cast<char*>(&ctype_) - reinterpret_cast<char*>(this)),
+ 0, static_cast<size_t>(reinterpret_cast<char*>(&jstype_) -
+ reinterpret_cast<char*>(&ctype_)) + sizeof(jstype_));
+}
+
+FieldOptions::~FieldOptions() {
+ // @@protoc_insertion_point(destructor:google.protobuf.FieldOptions)
+ if (GetArenaForAllocation() != nullptr) return;
+ SharedDtor();
+ _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+inline void FieldOptions::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+}
+
+void FieldOptions::ArenaDtor(void* object) {
+ FieldOptions* _this = reinterpret_cast< FieldOptions* >(object);
+ (void)_this;
+}
+void FieldOptions::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) {
+}
+void FieldOptions::SetCachedSize(int size) const {
+ _cached_size_.Set(size);
+}
+
+void FieldOptions::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.FieldOptions)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ _extensions_.Clear();
+ uninterpreted_option_.Clear();
+ cached_has_bits = _has_bits_[0];
+ if (cached_has_bits & 0x0000003fu) {
+ ::memset(&ctype_, 0, static_cast<size_t>(
+ reinterpret_cast<char*>(&jstype_) -
+ reinterpret_cast<char*>(&ctype_)) + sizeof(jstype_));
+ }
+ _has_bits_.Clear();
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* FieldOptions::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ _Internal::HasBits has_bits{};
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag);
+ switch (tag >> 3) {
+ // optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING];
+ case 1:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 8)) {
+ 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);
+ packed_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr);
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // optional bool deprecated = 3 [default = false];
+ case 3:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 24)) {
+ _Internal::set_has_deprecated(&has_bits);
+ deprecated_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr);
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // optional bool lazy = 5 [default = false];
+ case 5:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 40)) {
+ _Internal::set_has_lazy(&has_bits);
+ lazy_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr);
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // optional .google.protobuf.FieldOptions.JSType jstype = 6 [default = JS_NORMAL];
+ case 6:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 48)) {
+ 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);
+ weak_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr);
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+ case 999:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 58)) {
+ ptr -= 2;
+ do {
+ ptr += 2;
+ ptr = ctx->ParseMessage(_internal_add_uninterpreted_option(), ptr);
+ CHK_(ptr);
+ if (!ctx->DataAvailable(ptr)) break;
+ } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<7994>(ptr));
+ } else
+ goto handle_unusual;
+ continue;
+ default:
+ goto handle_unusual;
+ } // switch
+ handle_unusual:
+ if ((tag == 0) || ((tag & 7) == 4)) {
+ CHK_(ptr);
+ ctx->SetLastTag(tag);
+ goto message_done;
+ }
+ if ((8000u <= tag)) {
+ ptr = _extensions_.ParseField(tag, ptr, internal_default_instance(), &_internal_metadata_, ctx);
+ CHK_(ptr != nullptr);
+ continue;
+ }
+ ptr = UnknownFieldParse(
+ tag,
+ _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(),
+ ptr, ctx);
+ CHK_(ptr != nullptr);
+ } // while
+message_done:
+ _has_bits_.Or(has_bits);
+ return ptr;
+failure:
+ ptr = nullptr;
+ goto message_done;
+#undef CHK_
+}
+
+uint8_t* FieldOptions::_InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const {
+ // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.FieldOptions)
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ cached_has_bits = _has_bits_[0];
+ // optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING];
+ if (cached_has_bits & 0x00000001u) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteEnumToArray(
+ 1, this->_internal_ctype(), target);
+ }
+
+ // optional bool packed = 2;
+ if (cached_has_bits & 0x00000002u) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBoolToArray(2, this->_internal_packed(), target);
+ }
+
+ // optional bool deprecated = 3 [default = false];
+ if (cached_has_bits & 0x00000008u) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBoolToArray(3, this->_internal_deprecated(), target);
+ }
+
+ // optional bool lazy = 5 [default = false];
+ if (cached_has_bits & 0x00000004u) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBoolToArray(5, this->_internal_lazy(), target);
+ }
+
+ // optional .google.protobuf.FieldOptions.JSType jstype = 6 [default = JS_NORMAL];
+ if (cached_has_bits & 0x00000020u) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteEnumToArray(
+ 6, this->_internal_jstype(), target);
+ }
+
+ // optional bool weak = 10 [default = false];
+ if (cached_has_bits & 0x00000010u) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBoolToArray(10, this->_internal_weak(), target);
+ }
+
+ // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+ for (unsigned int i = 0,
+ n = static_cast<unsigned int>(this->_internal_uninterpreted_option_size()); i < n; i++) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(999, this->_internal_uninterpreted_option(i), target, stream);
+ }
+
+ // Extension range [1000, 536870912)
+ target = _extensions_._InternalSerialize(
+ internal_default_instance(), 1000, 536870912, target, stream);
+
+ if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray(
+ _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.FieldOptions)
+ return target;
+}
+
+size_t FieldOptions::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.FieldOptions)
+ size_t total_size = 0;
+
+ total_size += _extensions_.ByteSize();
+
+ 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->uninterpreted_option_) {
+ total_size +=
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg);
+ }
+
+ cached_has_bits = _has_bits_[0];
+ if (cached_has_bits & 0x0000003fu) {
+ // optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING];
+ if (cached_has_bits & 0x00000001u) {
+ total_size += 1 +
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::EnumSize(this->_internal_ctype());
+ }
+
+ // optional bool packed = 2;
+ if (cached_has_bits & 0x00000002u) {
+ total_size += 1 + 1;
+ }
+
+ // optional bool lazy = 5 [default = false];
+ if (cached_has_bits & 0x00000004u) {
+ total_size += 1 + 1;
+ }
+
+ // optional bool deprecated = 3 [default = false];
+ if (cached_has_bits & 0x00000008u) {
+ total_size += 1 + 1;
+ }
+
+ // optional bool weak = 10 [default = false];
+ if (cached_has_bits & 0x00000010u) {
+ total_size += 1 + 1;
+ }
+
+ // optional .google.protobuf.FieldOptions.JSType jstype = 6 [default = JS_NORMAL];
+ if (cached_has_bits & 0x00000020u) {
+ total_size += 1 +
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::EnumSize(this->_internal_jstype());
+ }
+
+ }
+ return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData FieldOptions::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck,
+ FieldOptions::MergeImpl
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*FieldOptions::GetClassData() const { return &_class_data_; }
+
+void FieldOptions::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to,
+ const ::PROTOBUF_NAMESPACE_ID::Message& from) {
+ static_cast<FieldOptions *>(to)->MergeFrom(
+ static_cast<const FieldOptions &>(from));
+}
+
+
+void FieldOptions::MergeFrom(const FieldOptions& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.FieldOptions)
+ GOOGLE_DCHECK_NE(&from, this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ uninterpreted_option_.MergeFrom(from.uninterpreted_option_);
+ cached_has_bits = from._has_bits_[0];
+ if (cached_has_bits & 0x0000003fu) {
+ if (cached_has_bits & 0x00000001u) {
+ ctype_ = from.ctype_;
+ }
+ if (cached_has_bits & 0x00000002u) {
+ packed_ = from.packed_;
+ }
+ if (cached_has_bits & 0x00000004u) {
+ lazy_ = from.lazy_;
+ }
+ if (cached_has_bits & 0x00000008u) {
+ deprecated_ = from.deprecated_;
+ }
+ if (cached_has_bits & 0x00000010u) {
+ weak_ = from.weak_;
+ }
+ if (cached_has_bits & 0x00000020u) {
+ jstype_ = from.jstype_;
+ }
+ _has_bits_[0] |= cached_has_bits;
+ }
+ _extensions_.MergeFrom(internal_default_instance(), from._extensions_);
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+}
+
+void FieldOptions::CopyFrom(const FieldOptions& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.FieldOptions)
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+bool FieldOptions::IsInitialized() const {
+ if (!_extensions_.IsInitialized()) {
+ return false;
+ }
+
+ if (!::PROTOBUF_NAMESPACE_ID::internal::AllAreInitialized(uninterpreted_option_))
+ return false;
+ return true;
+}
+
+void FieldOptions::InternalSwap(FieldOptions* other) {
+ using std::swap;
+ _extensions_.InternalSwap(&other->_extensions_);
+ _internal_metadata_.InternalSwap(&other->_internal_metadata_);
+ swap(_has_bits_[0], other->_has_bits_[0]);
+ uninterpreted_option_.InternalSwap(&other->uninterpreted_option_);
+ ::PROTOBUF_NAMESPACE_ID::internal::memswap<
+ PROTOBUF_FIELD_OFFSET(FieldOptions, jstype_)
+ + sizeof(FieldOptions::jstype_)
+ - PROTOBUF_FIELD_OFFSET(FieldOptions, ctype_)>(
+ reinterpret_cast<char*>(&ctype_),
+ reinterpret_cast<char*>(&other->ctype_));
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata FieldOptions::GetMetadata() const {
+ return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(
+ &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
+ file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[15]);
+}
+
+// ===================================================================
+
+class OneofOptions::_Internal {
+ public:
+};
+
+OneofOptions::OneofOptions(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned)
+ : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned),
+ _extensions_(arena),
+ uninterpreted_option_(arena) {
+ SharedCtor();
+ if (!is_message_owned) {
+ RegisterArenaDtor(arena);
+ }
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.OneofOptions)
+}
+OneofOptions::OneofOptions(const OneofOptions& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message(),
+ uninterpreted_option_(from.uninterpreted_option_) {
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ _extensions_.MergeFrom(internal_default_instance(), from._extensions_);
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.OneofOptions)
+}
+
+inline void OneofOptions::SharedCtor() {
+}
+
+OneofOptions::~OneofOptions() {
+ // @@protoc_insertion_point(destructor:google.protobuf.OneofOptions)
+ if (GetArenaForAllocation() != nullptr) return;
+ SharedDtor();
+ _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+inline void OneofOptions::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+}
+
+void OneofOptions::ArenaDtor(void* object) {
+ OneofOptions* _this = reinterpret_cast< OneofOptions* >(object);
+ (void)_this;
+}
+void OneofOptions::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) {
+}
+void OneofOptions::SetCachedSize(int size) const {
+ _cached_size_.Set(size);
+}
+
+void OneofOptions::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.OneofOptions)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ _extensions_.Clear();
+ uninterpreted_option_.Clear();
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* OneofOptions::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag);
+ switch (tag >> 3) {
+ // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+ case 999:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 58)) {
+ ptr -= 2;
+ do {
+ ptr += 2;
+ ptr = ctx->ParseMessage(_internal_add_uninterpreted_option(), ptr);
+ CHK_(ptr);
+ if (!ctx->DataAvailable(ptr)) break;
+ } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<7994>(ptr));
+ } else
+ goto handle_unusual;
+ continue;
+ default:
+ goto handle_unusual;
+ } // switch
+ handle_unusual:
+ if ((tag == 0) || ((tag & 7) == 4)) {
+ CHK_(ptr);
+ ctx->SetLastTag(tag);
+ goto message_done;
+ }
+ if ((8000u <= tag)) {
+ ptr = _extensions_.ParseField(tag, ptr, internal_default_instance(), &_internal_metadata_, ctx);
+ CHK_(ptr != nullptr);
+ continue;
+ }
+ ptr = UnknownFieldParse(
+ tag,
+ _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(),
+ ptr, ctx);
+ CHK_(ptr != nullptr);
+ } // while
+message_done:
+ return ptr;
+failure:
+ ptr = nullptr;
+ goto message_done;
+#undef CHK_
+}
+
+uint8_t* OneofOptions::_InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const {
+ // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.OneofOptions)
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+ for (unsigned int i = 0,
+ n = static_cast<unsigned int>(this->_internal_uninterpreted_option_size()); i < n; i++) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(999, this->_internal_uninterpreted_option(i), target, stream);
+ }
+
+ // Extension range [1000, 536870912)
+ target = _extensions_._InternalSerialize(
+ internal_default_instance(), 1000, 536870912, target, stream);
+
+ if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray(
+ _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.OneofOptions)
+ return target;
+}
+
+size_t OneofOptions::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.OneofOptions)
+ size_t total_size = 0;
+
+ total_size += _extensions_.ByteSize();
+
+ 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->uninterpreted_option_) {
+ total_size +=
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg);
+ }
+
+ return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData OneofOptions::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck,
+ OneofOptions::MergeImpl
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*OneofOptions::GetClassData() const { return &_class_data_; }
+
+void OneofOptions::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to,
+ const ::PROTOBUF_NAMESPACE_ID::Message& from) {
+ static_cast<OneofOptions *>(to)->MergeFrom(
+ static_cast<const OneofOptions &>(from));
+}
+
+
+void OneofOptions::MergeFrom(const OneofOptions& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.OneofOptions)
+ GOOGLE_DCHECK_NE(&from, this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ uninterpreted_option_.MergeFrom(from.uninterpreted_option_);
+ _extensions_.MergeFrom(internal_default_instance(), from._extensions_);
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+}
+
+void OneofOptions::CopyFrom(const OneofOptions& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.OneofOptions)
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+bool OneofOptions::IsInitialized() const {
+ if (!_extensions_.IsInitialized()) {
+ return false;
+ }
+
+ if (!::PROTOBUF_NAMESPACE_ID::internal::AllAreInitialized(uninterpreted_option_))
+ return false;
+ return true;
+}
+
+void OneofOptions::InternalSwap(OneofOptions* other) {
+ using std::swap;
+ _extensions_.InternalSwap(&other->_extensions_);
+ _internal_metadata_.InternalSwap(&other->_internal_metadata_);
+ uninterpreted_option_.InternalSwap(&other->uninterpreted_option_);
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata OneofOptions::GetMetadata() const {
+ return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(
+ &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
+ file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[16]);
+}
+
+// ===================================================================
+
+class EnumOptions::_Internal {
+ public:
+ using HasBits = decltype(std::declval<EnumOptions>()._has_bits_);
+ static void set_has_allow_alias(HasBits* has_bits) {
+ (*has_bits)[0] |= 1u;
+ }
+ static void set_has_deprecated(HasBits* has_bits) {
+ (*has_bits)[0] |= 2u;
+ }
+};
+
+EnumOptions::EnumOptions(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned)
+ : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned),
+ _extensions_(arena),
+ uninterpreted_option_(arena) {
+ SharedCtor();
+ if (!is_message_owned) {
+ RegisterArenaDtor(arena);
+ }
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.EnumOptions)
+}
+EnumOptions::EnumOptions(const EnumOptions& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message(),
+ _has_bits_(from._has_bits_),
+ uninterpreted_option_(from.uninterpreted_option_) {
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ _extensions_.MergeFrom(internal_default_instance(), from._extensions_);
+ ::memcpy(&allow_alias_, &from.allow_alias_,
+ static_cast<size_t>(reinterpret_cast<char*>(&deprecated_) -
+ reinterpret_cast<char*>(&allow_alias_)) + sizeof(deprecated_));
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.EnumOptions)
+}
+
+inline void EnumOptions::SharedCtor() {
+::memset(reinterpret_cast<char*>(this) + static_cast<size_t>(
+ reinterpret_cast<char*>(&allow_alias_) - reinterpret_cast<char*>(this)),
+ 0, static_cast<size_t>(reinterpret_cast<char*>(&deprecated_) -
+ reinterpret_cast<char*>(&allow_alias_)) + sizeof(deprecated_));
+}
+
+EnumOptions::~EnumOptions() {
+ // @@protoc_insertion_point(destructor:google.protobuf.EnumOptions)
+ if (GetArenaForAllocation() != nullptr) return;
+ SharedDtor();
+ _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+inline void EnumOptions::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+}
+
+void EnumOptions::ArenaDtor(void* object) {
+ EnumOptions* _this = reinterpret_cast< EnumOptions* >(object);
+ (void)_this;
+}
+void EnumOptions::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) {
+}
+void EnumOptions::SetCachedSize(int size) const {
+ _cached_size_.Set(size);
+}
+
+void EnumOptions::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.EnumOptions)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ _extensions_.Clear();
+ uninterpreted_option_.Clear();
+ ::memset(&allow_alias_, 0, static_cast<size_t>(
+ reinterpret_cast<char*>(&deprecated_) -
+ reinterpret_cast<char*>(&allow_alias_)) + sizeof(deprecated_));
+ _has_bits_.Clear();
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* EnumOptions::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ _Internal::HasBits has_bits{};
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag);
+ switch (tag >> 3) {
+ // optional bool allow_alias = 2;
+ case 2:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 16)) {
+ _Internal::set_has_allow_alias(&has_bits);
+ allow_alias_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr);
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // optional bool deprecated = 3 [default = false];
+ case 3:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 24)) {
+ _Internal::set_has_deprecated(&has_bits);
+ deprecated_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr);
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+ case 999:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 58)) {
+ ptr -= 2;
+ do {
+ ptr += 2;
+ ptr = ctx->ParseMessage(_internal_add_uninterpreted_option(), ptr);
+ CHK_(ptr);
+ if (!ctx->DataAvailable(ptr)) break;
+ } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<7994>(ptr));
+ } else
+ goto handle_unusual;
+ continue;
+ default:
+ goto handle_unusual;
+ } // switch
+ handle_unusual:
+ if ((tag == 0) || ((tag & 7) == 4)) {
+ CHK_(ptr);
+ ctx->SetLastTag(tag);
+ goto message_done;
+ }
+ if ((8000u <= tag)) {
+ ptr = _extensions_.ParseField(tag, ptr, internal_default_instance(), &_internal_metadata_, ctx);
+ CHK_(ptr != nullptr);
+ continue;
+ }
+ ptr = UnknownFieldParse(
+ tag,
+ _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(),
+ ptr, ctx);
+ CHK_(ptr != nullptr);
+ } // while
+message_done:
+ _has_bits_.Or(has_bits);
+ return ptr;
+failure:
+ ptr = nullptr;
+ goto message_done;
+#undef CHK_
+}
+
+uint8_t* EnumOptions::_InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const {
+ // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.EnumOptions)
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ cached_has_bits = _has_bits_[0];
+ // optional bool allow_alias = 2;
+ if (cached_has_bits & 0x00000001u) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBoolToArray(2, this->_internal_allow_alias(), target);
+ }
+
+ // optional bool deprecated = 3 [default = false];
+ if (cached_has_bits & 0x00000002u) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBoolToArray(3, this->_internal_deprecated(), target);
+ }
+
+ // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+ for (unsigned int i = 0,
+ n = static_cast<unsigned int>(this->_internal_uninterpreted_option_size()); i < n; i++) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(999, this->_internal_uninterpreted_option(i), target, stream);
+ }
+
+ // Extension range [1000, 536870912)
+ target = _extensions_._InternalSerialize(
+ internal_default_instance(), 1000, 536870912, target, stream);
+
+ if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray(
+ _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.EnumOptions)
+ return target;
+}
+
+size_t EnumOptions::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.EnumOptions)
+ size_t total_size = 0;
+
+ total_size += _extensions_.ByteSize();
+
+ 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->uninterpreted_option_) {
+ total_size +=
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg);
+ }
+
+ cached_has_bits = _has_bits_[0];
+ if (cached_has_bits & 0x00000003u) {
+ // optional bool allow_alias = 2;
+ if (cached_has_bits & 0x00000001u) {
+ total_size += 1 + 1;
+ }
+
+ // optional bool deprecated = 3 [default = false];
+ if (cached_has_bits & 0x00000002u) {
+ total_size += 1 + 1;
+ }
+
+ }
+ return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData EnumOptions::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck,
+ EnumOptions::MergeImpl
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*EnumOptions::GetClassData() const { return &_class_data_; }
+
+void EnumOptions::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to,
+ const ::PROTOBUF_NAMESPACE_ID::Message& from) {
+ static_cast<EnumOptions *>(to)->MergeFrom(
+ static_cast<const EnumOptions &>(from));
+}
+
+
+void EnumOptions::MergeFrom(const EnumOptions& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.EnumOptions)
+ GOOGLE_DCHECK_NE(&from, this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ uninterpreted_option_.MergeFrom(from.uninterpreted_option_);
+ cached_has_bits = from._has_bits_[0];
+ if (cached_has_bits & 0x00000003u) {
+ if (cached_has_bits & 0x00000001u) {
+ allow_alias_ = from.allow_alias_;
+ }
+ if (cached_has_bits & 0x00000002u) {
+ deprecated_ = from.deprecated_;
+ }
+ _has_bits_[0] |= cached_has_bits;
+ }
+ _extensions_.MergeFrom(internal_default_instance(), from._extensions_);
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+}
+
+void EnumOptions::CopyFrom(const EnumOptions& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.EnumOptions)
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+bool EnumOptions::IsInitialized() const {
+ if (!_extensions_.IsInitialized()) {
+ return false;
+ }
+
+ if (!::PROTOBUF_NAMESPACE_ID::internal::AllAreInitialized(uninterpreted_option_))
+ return false;
+ return true;
+}
+
+void EnumOptions::InternalSwap(EnumOptions* other) {
+ using std::swap;
+ _extensions_.InternalSwap(&other->_extensions_);
+ _internal_metadata_.InternalSwap(&other->_internal_metadata_);
+ swap(_has_bits_[0], other->_has_bits_[0]);
+ uninterpreted_option_.InternalSwap(&other->uninterpreted_option_);
+ ::PROTOBUF_NAMESPACE_ID::internal::memswap<
+ PROTOBUF_FIELD_OFFSET(EnumOptions, deprecated_)
+ + sizeof(EnumOptions::deprecated_)
+ - PROTOBUF_FIELD_OFFSET(EnumOptions, allow_alias_)>(
+ reinterpret_cast<char*>(&allow_alias_),
+ reinterpret_cast<char*>(&other->allow_alias_));
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata EnumOptions::GetMetadata() const {
+ return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(
+ &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
+ file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[17]);
+}
+
+// ===================================================================
+
+class EnumValueOptions::_Internal {
+ public:
+ using HasBits = decltype(std::declval<EnumValueOptions>()._has_bits_);
+ static void set_has_deprecated(HasBits* has_bits) {
+ (*has_bits)[0] |= 1u;
+ }
+};
+
+EnumValueOptions::EnumValueOptions(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned)
+ : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned),
+ _extensions_(arena),
+ uninterpreted_option_(arena) {
+ SharedCtor();
+ if (!is_message_owned) {
+ RegisterArenaDtor(arena);
+ }
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.EnumValueOptions)
+}
+EnumValueOptions::EnumValueOptions(const EnumValueOptions& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message(),
+ _has_bits_(from._has_bits_),
+ uninterpreted_option_(from.uninterpreted_option_) {
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ _extensions_.MergeFrom(internal_default_instance(), from._extensions_);
+ deprecated_ = from.deprecated_;
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.EnumValueOptions)
+}
+
+inline void EnumValueOptions::SharedCtor() {
+deprecated_ = false;
+}
+
+EnumValueOptions::~EnumValueOptions() {
+ // @@protoc_insertion_point(destructor:google.protobuf.EnumValueOptions)
+ if (GetArenaForAllocation() != nullptr) return;
+ SharedDtor();
+ _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+inline void EnumValueOptions::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+}
+
+void EnumValueOptions::ArenaDtor(void* object) {
+ EnumValueOptions* _this = reinterpret_cast< EnumValueOptions* >(object);
+ (void)_this;
+}
+void EnumValueOptions::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) {
+}
+void EnumValueOptions::SetCachedSize(int size) const {
+ _cached_size_.Set(size);
+}
+
+void EnumValueOptions::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.EnumValueOptions)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ _extensions_.Clear();
+ uninterpreted_option_.Clear();
+ deprecated_ = false;
+ _has_bits_.Clear();
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* EnumValueOptions::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ _Internal::HasBits has_bits{};
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag);
+ switch (tag >> 3) {
+ // optional bool deprecated = 1 [default = false];
+ case 1:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 8)) {
+ _Internal::set_has_deprecated(&has_bits);
+ deprecated_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr);
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+ case 999:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 58)) {
+ ptr -= 2;
+ do {
+ ptr += 2;
+ ptr = ctx->ParseMessage(_internal_add_uninterpreted_option(), ptr);
+ CHK_(ptr);
+ if (!ctx->DataAvailable(ptr)) break;
+ } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<7994>(ptr));
+ } else
+ goto handle_unusual;
+ continue;
+ default:
+ goto handle_unusual;
+ } // switch
+ handle_unusual:
+ if ((tag == 0) || ((tag & 7) == 4)) {
+ CHK_(ptr);
+ ctx->SetLastTag(tag);
+ goto message_done;
+ }
+ if ((8000u <= tag)) {
+ ptr = _extensions_.ParseField(tag, ptr, internal_default_instance(), &_internal_metadata_, ctx);
+ CHK_(ptr != nullptr);
+ continue;
+ }
+ ptr = UnknownFieldParse(
+ tag,
+ _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(),
+ ptr, ctx);
+ CHK_(ptr != nullptr);
+ } // while
+message_done:
+ _has_bits_.Or(has_bits);
+ return ptr;
+failure:
+ ptr = nullptr;
+ goto message_done;
+#undef CHK_
+}
+
+uint8_t* EnumValueOptions::_InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const {
+ // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.EnumValueOptions)
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ cached_has_bits = _has_bits_[0];
+ // optional bool deprecated = 1 [default = false];
+ if (cached_has_bits & 0x00000001u) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBoolToArray(1, this->_internal_deprecated(), target);
+ }
+
+ // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+ for (unsigned int i = 0,
+ n = static_cast<unsigned int>(this->_internal_uninterpreted_option_size()); i < n; i++) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(999, this->_internal_uninterpreted_option(i), target, stream);
+ }
+
+ // Extension range [1000, 536870912)
+ target = _extensions_._InternalSerialize(
+ internal_default_instance(), 1000, 536870912, target, stream);
+
+ if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray(
+ _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.EnumValueOptions)
+ return target;
+}
+
+size_t EnumValueOptions::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.EnumValueOptions)
+ size_t total_size = 0;
+
+ total_size += _extensions_.ByteSize();
+
+ 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->uninterpreted_option_) {
+ total_size +=
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg);
+ }
+
+ // optional bool deprecated = 1 [default = false];
+ cached_has_bits = _has_bits_[0];
+ if (cached_has_bits & 0x00000001u) {
+ total_size += 1 + 1;
+ }
+
+ return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData EnumValueOptions::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck,
+ EnumValueOptions::MergeImpl
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*EnumValueOptions::GetClassData() const { return &_class_data_; }
+
+void EnumValueOptions::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to,
+ const ::PROTOBUF_NAMESPACE_ID::Message& from) {
+ static_cast<EnumValueOptions *>(to)->MergeFrom(
+ static_cast<const EnumValueOptions &>(from));
+}
+
+
+void EnumValueOptions::MergeFrom(const EnumValueOptions& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.EnumValueOptions)
+ GOOGLE_DCHECK_NE(&from, this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ uninterpreted_option_.MergeFrom(from.uninterpreted_option_);
+ if (from._internal_has_deprecated()) {
+ _internal_set_deprecated(from._internal_deprecated());
+ }
+ _extensions_.MergeFrom(internal_default_instance(), from._extensions_);
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+}
+
+void EnumValueOptions::CopyFrom(const EnumValueOptions& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.EnumValueOptions)
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+bool EnumValueOptions::IsInitialized() const {
+ if (!_extensions_.IsInitialized()) {
+ return false;
+ }
+
+ if (!::PROTOBUF_NAMESPACE_ID::internal::AllAreInitialized(uninterpreted_option_))
+ return false;
+ return true;
+}
+
+void EnumValueOptions::InternalSwap(EnumValueOptions* other) {
+ using std::swap;
+ _extensions_.InternalSwap(&other->_extensions_);
+ _internal_metadata_.InternalSwap(&other->_internal_metadata_);
+ swap(_has_bits_[0], other->_has_bits_[0]);
+ uninterpreted_option_.InternalSwap(&other->uninterpreted_option_);
+ swap(deprecated_, other->deprecated_);
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata EnumValueOptions::GetMetadata() const {
+ return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(
+ &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
+ file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[18]);
+}
+
+// ===================================================================
+
+class ServiceOptions::_Internal {
+ public:
+ using HasBits = decltype(std::declval<ServiceOptions>()._has_bits_);
+ static void set_has_deprecated(HasBits* has_bits) {
+ (*has_bits)[0] |= 1u;
+ }
+};
+
+ServiceOptions::ServiceOptions(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned)
+ : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned),
+ _extensions_(arena),
+ uninterpreted_option_(arena) {
+ SharedCtor();
+ if (!is_message_owned) {
+ RegisterArenaDtor(arena);
+ }
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.ServiceOptions)
+}
+ServiceOptions::ServiceOptions(const ServiceOptions& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message(),
+ _has_bits_(from._has_bits_),
+ uninterpreted_option_(from.uninterpreted_option_) {
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ _extensions_.MergeFrom(internal_default_instance(), from._extensions_);
+ deprecated_ = from.deprecated_;
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.ServiceOptions)
+}
+
+inline void ServiceOptions::SharedCtor() {
+deprecated_ = false;
+}
+
+ServiceOptions::~ServiceOptions() {
+ // @@protoc_insertion_point(destructor:google.protobuf.ServiceOptions)
+ if (GetArenaForAllocation() != nullptr) return;
+ SharedDtor();
+ _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+inline void ServiceOptions::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+}
+
+void ServiceOptions::ArenaDtor(void* object) {
+ ServiceOptions* _this = reinterpret_cast< ServiceOptions* >(object);
+ (void)_this;
+}
+void ServiceOptions::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) {
+}
+void ServiceOptions::SetCachedSize(int size) const {
+ _cached_size_.Set(size);
+}
+
+void ServiceOptions::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.ServiceOptions)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ _extensions_.Clear();
+ uninterpreted_option_.Clear();
+ deprecated_ = false;
+ _has_bits_.Clear();
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* ServiceOptions::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ _Internal::HasBits has_bits{};
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag);
+ switch (tag >> 3) {
+ // optional bool deprecated = 33 [default = false];
+ case 33:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 8)) {
+ _Internal::set_has_deprecated(&has_bits);
+ deprecated_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr);
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+ case 999:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 58)) {
+ ptr -= 2;
+ do {
+ ptr += 2;
+ ptr = ctx->ParseMessage(_internal_add_uninterpreted_option(), ptr);
+ CHK_(ptr);
+ if (!ctx->DataAvailable(ptr)) break;
+ } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<7994>(ptr));
+ } else
+ goto handle_unusual;
+ continue;
+ default:
+ goto handle_unusual;
+ } // switch
+ handle_unusual:
+ if ((tag == 0) || ((tag & 7) == 4)) {
+ CHK_(ptr);
+ ctx->SetLastTag(tag);
+ goto message_done;
+ }
+ if ((8000u <= tag)) {
+ ptr = _extensions_.ParseField(tag, ptr, internal_default_instance(), &_internal_metadata_, ctx);
+ CHK_(ptr != nullptr);
+ continue;
+ }
+ ptr = UnknownFieldParse(
+ tag,
+ _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(),
+ ptr, ctx);
+ CHK_(ptr != nullptr);
+ } // while
+message_done:
+ _has_bits_.Or(has_bits);
+ return ptr;
+failure:
+ ptr = nullptr;
+ goto message_done;
+#undef CHK_
+}
+
+uint8_t* ServiceOptions::_InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const {
+ // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.ServiceOptions)
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ cached_has_bits = _has_bits_[0];
+ // optional bool deprecated = 33 [default = false];
+ if (cached_has_bits & 0x00000001u) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBoolToArray(33, this->_internal_deprecated(), target);
+ }
+
+ // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+ for (unsigned int i = 0,
+ n = static_cast<unsigned int>(this->_internal_uninterpreted_option_size()); i < n; i++) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(999, this->_internal_uninterpreted_option(i), target, stream);
+ }
+
+ // Extension range [1000, 536870912)
+ target = _extensions_._InternalSerialize(
+ internal_default_instance(), 1000, 536870912, target, stream);
+
+ if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray(
+ _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.ServiceOptions)
+ return target;
+}
+
+size_t ServiceOptions::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.ServiceOptions)
+ size_t total_size = 0;
+
+ total_size += _extensions_.ByteSize();
+
+ 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->uninterpreted_option_) {
+ total_size +=
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg);
+ }
+
+ // optional bool deprecated = 33 [default = false];
+ cached_has_bits = _has_bits_[0];
+ if (cached_has_bits & 0x00000001u) {
+ total_size += 2 + 1;
+ }
+
+ return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData ServiceOptions::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck,
+ ServiceOptions::MergeImpl
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*ServiceOptions::GetClassData() const { return &_class_data_; }
+
+void ServiceOptions::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to,
+ const ::PROTOBUF_NAMESPACE_ID::Message& from) {
+ static_cast<ServiceOptions *>(to)->MergeFrom(
+ static_cast<const ServiceOptions &>(from));
+}
+
+
+void ServiceOptions::MergeFrom(const ServiceOptions& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.ServiceOptions)
+ GOOGLE_DCHECK_NE(&from, this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ uninterpreted_option_.MergeFrom(from.uninterpreted_option_);
+ if (from._internal_has_deprecated()) {
+ _internal_set_deprecated(from._internal_deprecated());
+ }
+ _extensions_.MergeFrom(internal_default_instance(), from._extensions_);
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+}
+
+void ServiceOptions::CopyFrom(const ServiceOptions& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.ServiceOptions)
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+bool ServiceOptions::IsInitialized() const {
+ if (!_extensions_.IsInitialized()) {
+ return false;
+ }
+
+ if (!::PROTOBUF_NAMESPACE_ID::internal::AllAreInitialized(uninterpreted_option_))
+ return false;
+ return true;
+}
+
+void ServiceOptions::InternalSwap(ServiceOptions* other) {
+ using std::swap;
+ _extensions_.InternalSwap(&other->_extensions_);
+ _internal_metadata_.InternalSwap(&other->_internal_metadata_);
+ swap(_has_bits_[0], other->_has_bits_[0]);
+ uninterpreted_option_.InternalSwap(&other->uninterpreted_option_);
+ swap(deprecated_, other->deprecated_);
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata ServiceOptions::GetMetadata() const {
+ return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(
+ &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
+ file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[19]);
+}
+
+// ===================================================================
+
+class MethodOptions::_Internal {
+ public:
+ using HasBits = decltype(std::declval<MethodOptions>()._has_bits_);
+ static void set_has_deprecated(HasBits* has_bits) {
+ (*has_bits)[0] |= 1u;
+ }
+ static void set_has_idempotency_level(HasBits* has_bits) {
+ (*has_bits)[0] |= 2u;
+ }
+};
+
+MethodOptions::MethodOptions(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned)
+ : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned),
+ _extensions_(arena),
+ uninterpreted_option_(arena) {
+ SharedCtor();
+ if (!is_message_owned) {
+ RegisterArenaDtor(arena);
+ }
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.MethodOptions)
+}
+MethodOptions::MethodOptions(const MethodOptions& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message(),
+ _has_bits_(from._has_bits_),
+ uninterpreted_option_(from.uninterpreted_option_) {
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ _extensions_.MergeFrom(internal_default_instance(), from._extensions_);
+ ::memcpy(&deprecated_, &from.deprecated_,
+ static_cast<size_t>(reinterpret_cast<char*>(&idempotency_level_) -
+ reinterpret_cast<char*>(&deprecated_)) + sizeof(idempotency_level_));
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.MethodOptions)
+}
+
+inline void MethodOptions::SharedCtor() {
+::memset(reinterpret_cast<char*>(this) + static_cast<size_t>(
+ reinterpret_cast<char*>(&deprecated_) - reinterpret_cast<char*>(this)),
+ 0, static_cast<size_t>(reinterpret_cast<char*>(&idempotency_level_) -
+ reinterpret_cast<char*>(&deprecated_)) + sizeof(idempotency_level_));
+}
+
+MethodOptions::~MethodOptions() {
+ // @@protoc_insertion_point(destructor:google.protobuf.MethodOptions)
+ if (GetArenaForAllocation() != nullptr) return;
+ SharedDtor();
+ _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+inline void MethodOptions::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+}
+
+void MethodOptions::ArenaDtor(void* object) {
+ MethodOptions* _this = reinterpret_cast< MethodOptions* >(object);
+ (void)_this;
+}
+void MethodOptions::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) {
+}
+void MethodOptions::SetCachedSize(int size) const {
+ _cached_size_.Set(size);
+}
+
+void MethodOptions::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.MethodOptions)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ _extensions_.Clear();
+ uninterpreted_option_.Clear();
+ cached_has_bits = _has_bits_[0];
+ if (cached_has_bits & 0x00000003u) {
+ ::memset(&deprecated_, 0, static_cast<size_t>(
+ reinterpret_cast<char*>(&idempotency_level_) -
+ reinterpret_cast<char*>(&deprecated_)) + sizeof(idempotency_level_));
+ }
+ _has_bits_.Clear();
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* MethodOptions::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ _Internal::HasBits has_bits{};
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag);
+ switch (tag >> 3) {
+ // optional bool deprecated = 33 [default = false];
+ case 33:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 8)) {
+ _Internal::set_has_deprecated(&has_bits);
+ deprecated_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr);
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // optional .google.protobuf.MethodOptions.IdempotencyLevel idempotency_level = 34 [default = IDEMPOTENCY_UNKNOWN];
+ case 34:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 16)) {
+ 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 = _extensions_.ParseField(tag, ptr, internal_default_instance(), &_internal_metadata_, ctx);
+ CHK_(ptr != nullptr);
+ continue;
+ }
+ ptr = UnknownFieldParse(
+ tag,
+ _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(),
+ ptr, ctx);
+ CHK_(ptr != nullptr);
+ } // while
+message_done:
+ _has_bits_.Or(has_bits);
+ return ptr;
+failure:
+ ptr = nullptr;
+ goto message_done;
+#undef CHK_
+}
+
+uint8_t* MethodOptions::_InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const {
+ // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.MethodOptions)
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ cached_has_bits = _has_bits_[0];
+ // optional bool deprecated = 33 [default = false];
+ if (cached_has_bits & 0x00000001u) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBoolToArray(33, this->_internal_deprecated(), target);
+ }
+
+ // optional .google.protobuf.MethodOptions.IdempotencyLevel idempotency_level = 34 [default = IDEMPOTENCY_UNKNOWN];
+ if (cached_has_bits & 0x00000002u) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteEnumToArray(
+ 34, this->_internal_idempotency_level(), target);
+ }
+
+ // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+ for (unsigned int i = 0,
+ n = static_cast<unsigned int>(this->_internal_uninterpreted_option_size()); i < n; i++) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(999, this->_internal_uninterpreted_option(i), target, stream);
+ }
+
+ // Extension range [1000, 536870912)
+ target = _extensions_._InternalSerialize(
+ internal_default_instance(), 1000, 536870912, target, stream);
+
+ if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray(
+ _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.MethodOptions)
+ return target;
+}
+
+size_t MethodOptions::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.MethodOptions)
+ size_t total_size = 0;
+
+ total_size += _extensions_.ByteSize();
+
+ 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->uninterpreted_option_) {
+ total_size +=
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg);
+ }
+
+ cached_has_bits = _has_bits_[0];
+ if (cached_has_bits & 0x00000003u) {
+ // optional bool deprecated = 33 [default = false];
+ if (cached_has_bits & 0x00000001u) {
+ total_size += 2 + 1;
+ }
+
+ // optional .google.protobuf.MethodOptions.IdempotencyLevel idempotency_level = 34 [default = IDEMPOTENCY_UNKNOWN];
+ if (cached_has_bits & 0x00000002u) {
+ total_size += 2 +
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::EnumSize(this->_internal_idempotency_level());
+ }
+
+ }
+ return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData MethodOptions::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck,
+ MethodOptions::MergeImpl
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*MethodOptions::GetClassData() const { return &_class_data_; }
+
+void MethodOptions::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to,
+ const ::PROTOBUF_NAMESPACE_ID::Message& from) {
+ static_cast<MethodOptions *>(to)->MergeFrom(
+ static_cast<const MethodOptions &>(from));
+}
+
+
+void MethodOptions::MergeFrom(const MethodOptions& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.MethodOptions)
+ GOOGLE_DCHECK_NE(&from, this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ uninterpreted_option_.MergeFrom(from.uninterpreted_option_);
+ cached_has_bits = from._has_bits_[0];
+ if (cached_has_bits & 0x00000003u) {
+ if (cached_has_bits & 0x00000001u) {
+ deprecated_ = from.deprecated_;
+ }
+ if (cached_has_bits & 0x00000002u) {
+ idempotency_level_ = from.idempotency_level_;
+ }
+ _has_bits_[0] |= cached_has_bits;
+ }
+ _extensions_.MergeFrom(internal_default_instance(), from._extensions_);
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+}
+
+void MethodOptions::CopyFrom(const MethodOptions& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.MethodOptions)
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+bool MethodOptions::IsInitialized() const {
+ if (!_extensions_.IsInitialized()) {
+ return false;
+ }
+
+ if (!::PROTOBUF_NAMESPACE_ID::internal::AllAreInitialized(uninterpreted_option_))
+ return false;
+ return true;
+}
+
+void MethodOptions::InternalSwap(MethodOptions* other) {
+ using std::swap;
+ _extensions_.InternalSwap(&other->_extensions_);
+ _internal_metadata_.InternalSwap(&other->_internal_metadata_);
+ swap(_has_bits_[0], other->_has_bits_[0]);
+ uninterpreted_option_.InternalSwap(&other->uninterpreted_option_);
+ ::PROTOBUF_NAMESPACE_ID::internal::memswap<
+ PROTOBUF_FIELD_OFFSET(MethodOptions, idempotency_level_)
+ + sizeof(MethodOptions::idempotency_level_)
+ - PROTOBUF_FIELD_OFFSET(MethodOptions, deprecated_)>(
+ reinterpret_cast<char*>(&deprecated_),
+ reinterpret_cast<char*>(&other->deprecated_));
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata MethodOptions::GetMetadata() const {
+ return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(
+ &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
+ file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[20]);
+}
+
+// ===================================================================
+
+class UninterpretedOption_NamePart::_Internal {
+ public:
+ using HasBits = decltype(std::declval<UninterpretedOption_NamePart>()._has_bits_);
+ static void set_has_name_part(HasBits* has_bits) {
+ (*has_bits)[0] |= 1u;
+ }
+ static void set_has_is_extension(HasBits* has_bits) {
+ (*has_bits)[0] |= 2u;
+ }
+ static bool MissingRequiredFields(const HasBits& has_bits) {
+ return ((has_bits[0] & 0x00000003) ^ 0x00000003) != 0;
+ }
+};
+
+UninterpretedOption_NamePart::UninterpretedOption_NamePart(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned)
+ : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) {
+ SharedCtor();
+ if (!is_message_owned) {
+ RegisterArenaDtor(arena);
+ }
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.UninterpretedOption.NamePart)
+}
+UninterpretedOption_NamePart::UninterpretedOption_NamePart(const UninterpretedOption_NamePart& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message(),
+ _has_bits_(from._has_bits_) {
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ name_part_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ name_part_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (from._internal_has_name_part()) {
+ name_part_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_name_part(),
+ GetArenaForAllocation());
+ }
+ is_extension_ = from.is_extension_;
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.UninterpretedOption.NamePart)
+}
+
+inline void UninterpretedOption_NamePart::SharedCtor() {
+name_part_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ name_part_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+is_extension_ = false;
+}
+
+UninterpretedOption_NamePart::~UninterpretedOption_NamePart() {
+ // @@protoc_insertion_point(destructor:google.protobuf.UninterpretedOption.NamePart)
+ if (GetArenaForAllocation() != nullptr) return;
+ SharedDtor();
+ _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+inline void UninterpretedOption_NamePart::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+ name_part_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+}
+
+void UninterpretedOption_NamePart::ArenaDtor(void* object) {
+ UninterpretedOption_NamePart* _this = reinterpret_cast< UninterpretedOption_NamePart* >(object);
+ (void)_this;
+}
+void UninterpretedOption_NamePart::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) {
+}
+void UninterpretedOption_NamePart::SetCachedSize(int size) const {
+ _cached_size_.Set(size);
+}
+
+void UninterpretedOption_NamePart::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.UninterpretedOption.NamePart)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ cached_has_bits = _has_bits_[0];
+ if (cached_has_bits & 0x00000001u) {
+ name_part_.ClearNonDefaultToEmpty();
+ }
+ is_extension_ = false;
+ _has_bits_.Clear();
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* UninterpretedOption_NamePart::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ _Internal::HasBits has_bits{};
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag);
+ switch (tag >> 3) {
+ // required string name_part = 1;
+ case 1:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 10)) {
+ auto str = _internal_mutable_name_part();
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx);
+ #ifndef NDEBUG
+ ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.UninterpretedOption.NamePart.name_part");
+ #endif // !NDEBUG
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // required bool is_extension = 2;
+ case 2:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 16)) {
+ _Internal::set_has_is_extension(&has_bits);
+ is_extension_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr);
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ default:
+ goto handle_unusual;
+ } // switch
+ handle_unusual:
+ if ((tag == 0) || ((tag & 7) == 4)) {
+ CHK_(ptr);
+ ctx->SetLastTag(tag);
+ goto message_done;
+ }
+ ptr = UnknownFieldParse(
+ tag,
+ _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(),
+ ptr, ctx);
+ CHK_(ptr != nullptr);
+ } // while
+message_done:
+ _has_bits_.Or(has_bits);
+ return ptr;
+failure:
+ ptr = nullptr;
+ goto message_done;
+#undef CHK_
+}
+
+uint8_t* UninterpretedOption_NamePart::_InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const {
+ // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.UninterpretedOption.NamePart)
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ cached_has_bits = _has_bits_[0];
+ // required string name_part = 1;
+ if (cached_has_bits & 0x00000001u) {
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField(
+ this->_internal_name_part().data(), static_cast<int>(this->_internal_name_part().length()),
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE,
+ "google.protobuf.UninterpretedOption.NamePart.name_part");
+ target = stream->WriteStringMaybeAliased(
+ 1, this->_internal_name_part(), target);
+ }
+
+ // required bool is_extension = 2;
+ if (cached_has_bits & 0x00000002u) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBoolToArray(2, this->_internal_is_extension(), target);
+ }
+
+ if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray(
+ _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.UninterpretedOption.NamePart)
+ return target;
+}
+
+size_t UninterpretedOption_NamePart::RequiredFieldsByteSizeFallback() const {
+// @@protoc_insertion_point(required_fields_byte_size_fallback_start:google.protobuf.UninterpretedOption.NamePart)
+ size_t total_size = 0;
+
+ if (_internal_has_name_part()) {
+ // required string name_part = 1;
+ total_size += 1 +
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
+ this->_internal_name_part());
+ }
+
+ if (_internal_has_is_extension()) {
+ // required bool is_extension = 2;
+ total_size += 1 + 1;
+ }
+
+ return total_size;
+}
+size_t UninterpretedOption_NamePart::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.UninterpretedOption.NamePart)
+ size_t total_size = 0;
+
+ if (((_has_bits_[0] & 0x00000003) ^ 0x00000003) == 0) { // All required fields are present.
+ // required string name_part = 1;
+ total_size += 1 +
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
+ this->_internal_name_part());
+
+ // required bool is_extension = 2;
+ total_size += 1 + 1;
+
+ } else {
+ total_size += RequiredFieldsByteSizeFallback();
+ }
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData UninterpretedOption_NamePart::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck,
+ UninterpretedOption_NamePart::MergeImpl
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*UninterpretedOption_NamePart::GetClassData() const { return &_class_data_; }
+
+void UninterpretedOption_NamePart::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to,
+ const ::PROTOBUF_NAMESPACE_ID::Message& from) {
+ static_cast<UninterpretedOption_NamePart *>(to)->MergeFrom(
+ static_cast<const UninterpretedOption_NamePart &>(from));
+}
+
+
+void UninterpretedOption_NamePart::MergeFrom(const UninterpretedOption_NamePart& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.UninterpretedOption.NamePart)
+ GOOGLE_DCHECK_NE(&from, this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ cached_has_bits = from._has_bits_[0];
+ if (cached_has_bits & 0x00000003u) {
+ if (cached_has_bits & 0x00000001u) {
+ _internal_set_name_part(from._internal_name_part());
+ }
+ if (cached_has_bits & 0x00000002u) {
+ is_extension_ = from.is_extension_;
+ }
+ _has_bits_[0] |= cached_has_bits;
+ }
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+}
+
+void UninterpretedOption_NamePart::CopyFrom(const UninterpretedOption_NamePart& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.UninterpretedOption.NamePart)
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+bool UninterpretedOption_NamePart::IsInitialized() const {
+ if (_Internal::MissingRequiredFields(_has_bits_)) return false;
+ return true;
+}
+
+void UninterpretedOption_NamePart::InternalSwap(UninterpretedOption_NamePart* other) {
+ using std::swap;
+ auto* lhs_arena = GetArenaForAllocation();
+ auto* rhs_arena = other->GetArenaForAllocation();
+ _internal_metadata_.InternalSwap(&other->_internal_metadata_);
+ swap(_has_bits_[0], other->_has_bits_[0]);
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(),
+ &name_part_, lhs_arena,
+ &other->name_part_, rhs_arena
+ );
+ swap(is_extension_, other->is_extension_);
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata UninterpretedOption_NamePart::GetMetadata() const {
+ return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(
+ &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
+ file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[21]);
+}
+
+// ===================================================================
+
+class UninterpretedOption::_Internal {
+ public:
+ using HasBits = decltype(std::declval<UninterpretedOption>()._has_bits_);
+ static void set_has_identifier_value(HasBits* has_bits) {
+ (*has_bits)[0] |= 1u;
+ }
+ static void set_has_positive_int_value(HasBits* has_bits) {
+ (*has_bits)[0] |= 8u;
+ }
+ static void set_has_negative_int_value(HasBits* has_bits) {
+ (*has_bits)[0] |= 16u;
+ }
+ static void set_has_double_value(HasBits* has_bits) {
+ (*has_bits)[0] |= 32u;
+ }
+ static void set_has_string_value(HasBits* has_bits) {
+ (*has_bits)[0] |= 2u;
+ }
+ static void set_has_aggregate_value(HasBits* has_bits) {
+ (*has_bits)[0] |= 4u;
+ }
+};
+
+UninterpretedOption::UninterpretedOption(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned)
+ : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned),
+ name_(arena) {
+ SharedCtor();
+ if (!is_message_owned) {
+ RegisterArenaDtor(arena);
+ }
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.UninterpretedOption)
+}
+UninterpretedOption::UninterpretedOption(const UninterpretedOption& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message(),
+ _has_bits_(from._has_bits_),
+ name_(from.name_) {
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ identifier_value_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ identifier_value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (from._internal_has_identifier_value()) {
+ identifier_value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_identifier_value(),
+ GetArenaForAllocation());
+ }
+ string_value_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ string_value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (from._internal_has_string_value()) {
+ string_value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_string_value(),
+ GetArenaForAllocation());
+ }
+ aggregate_value_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ aggregate_value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (from._internal_has_aggregate_value()) {
+ aggregate_value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_aggregate_value(),
+ GetArenaForAllocation());
+ }
+ ::memcpy(&positive_int_value_, &from.positive_int_value_,
+ static_cast<size_t>(reinterpret_cast<char*>(&double_value_) -
+ reinterpret_cast<char*>(&positive_int_value_)) + sizeof(double_value_));
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.UninterpretedOption)
+}
+
+inline void UninterpretedOption::SharedCtor() {
+identifier_value_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ identifier_value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+string_value_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ string_value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+aggregate_value_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ aggregate_value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+::memset(reinterpret_cast<char*>(this) + static_cast<size_t>(
+ reinterpret_cast<char*>(&positive_int_value_) - reinterpret_cast<char*>(this)),
+ 0, static_cast<size_t>(reinterpret_cast<char*>(&double_value_) -
+ reinterpret_cast<char*>(&positive_int_value_)) + sizeof(double_value_));
+}
+
+UninterpretedOption::~UninterpretedOption() {
+ // @@protoc_insertion_point(destructor:google.protobuf.UninterpretedOption)
+ if (GetArenaForAllocation() != nullptr) return;
+ SharedDtor();
+ _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+inline void UninterpretedOption::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+ identifier_value_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ string_value_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ aggregate_value_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+}
+
+void UninterpretedOption::ArenaDtor(void* object) {
+ UninterpretedOption* _this = reinterpret_cast< UninterpretedOption* >(object);
+ (void)_this;
+}
+void UninterpretedOption::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) {
+}
+void UninterpretedOption::SetCachedSize(int size) const {
+ _cached_size_.Set(size);
+}
+
+void UninterpretedOption::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.UninterpretedOption)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ name_.Clear();
+ cached_has_bits = _has_bits_[0];
+ if (cached_has_bits & 0x00000007u) {
+ if (cached_has_bits & 0x00000001u) {
+ identifier_value_.ClearNonDefaultToEmpty();
+ }
+ if (cached_has_bits & 0x00000002u) {
+ string_value_.ClearNonDefaultToEmpty();
+ }
+ if (cached_has_bits & 0x00000004u) {
+ aggregate_value_.ClearNonDefaultToEmpty();
+ }
+ }
+ if (cached_has_bits & 0x00000038u) {
+ ::memset(&positive_int_value_, 0, static_cast<size_t>(
+ reinterpret_cast<char*>(&double_value_) -
+ reinterpret_cast<char*>(&positive_int_value_)) + sizeof(double_value_));
+ }
+ _has_bits_.Clear();
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* UninterpretedOption::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ _Internal::HasBits has_bits{};
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag);
+ switch (tag >> 3) {
+ // repeated .google.protobuf.UninterpretedOption.NamePart name = 2;
+ case 2:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 18)) {
+ ptr -= 1;
+ do {
+ ptr += 1;
+ ptr = ctx->ParseMessage(_internal_add_name(), ptr);
+ CHK_(ptr);
+ if (!ctx->DataAvailable(ptr)) break;
+ } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<18>(ptr));
+ } else
+ goto handle_unusual;
+ continue;
+ // optional string identifier_value = 3;
+ case 3:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 26)) {
+ auto str = _internal_mutable_identifier_value();
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx);
+ #ifndef NDEBUG
+ ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.UninterpretedOption.identifier_value");
+ #endif // !NDEBUG
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // optional uint64 positive_int_value = 4;
+ case 4:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 32)) {
+ _Internal::set_has_positive_int_value(&has_bits);
+ positive_int_value_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr);
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // optional int64 negative_int_value = 5;
+ case 5:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 40)) {
+ _Internal::set_has_negative_int_value(&has_bits);
+ negative_int_value_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr);
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // optional double double_value = 6;
+ case 6:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 49)) {
+ _Internal::set_has_double_value(&has_bits);
+ double_value_ = ::PROTOBUF_NAMESPACE_ID::internal::UnalignedLoad<double>(ptr);
+ ptr += sizeof(double);
+ } else
+ goto handle_unusual;
+ continue;
+ // optional bytes string_value = 7;
+ case 7:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 58)) {
+ auto str = _internal_mutable_string_value();
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx);
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // optional string aggregate_value = 8;
+ case 8:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 66)) {
+ auto str = _internal_mutable_aggregate_value();
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx);
+ #ifndef NDEBUG
+ ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.UninterpretedOption.aggregate_value");
+ #endif // !NDEBUG
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ default:
+ goto handle_unusual;
+ } // switch
+ handle_unusual:
+ if ((tag == 0) || ((tag & 7) == 4)) {
+ CHK_(ptr);
+ ctx->SetLastTag(tag);
+ goto message_done;
+ }
+ ptr = UnknownFieldParse(
+ tag,
+ _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(),
+ ptr, ctx);
+ CHK_(ptr != nullptr);
+ } // while
+message_done:
+ _has_bits_.Or(has_bits);
+ return ptr;
+failure:
+ ptr = nullptr;
+ goto message_done;
+#undef CHK_
+}
+
+uint8_t* UninterpretedOption::_InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const {
+ // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.UninterpretedOption)
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ // repeated .google.protobuf.UninterpretedOption.NamePart name = 2;
+ for (unsigned int i = 0,
+ n = static_cast<unsigned int>(this->_internal_name_size()); i < n; i++) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(2, this->_internal_name(i), target, stream);
+ }
+
+ cached_has_bits = _has_bits_[0];
+ // optional string identifier_value = 3;
+ if (cached_has_bits & 0x00000001u) {
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField(
+ this->_internal_identifier_value().data(), static_cast<int>(this->_internal_identifier_value().length()),
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE,
+ "google.protobuf.UninterpretedOption.identifier_value");
+ target = stream->WriteStringMaybeAliased(
+ 3, this->_internal_identifier_value(), target);
+ }
+
+ // optional uint64 positive_int_value = 4;
+ if (cached_has_bits & 0x00000008u) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteUInt64ToArray(4, this->_internal_positive_int_value(), target);
+ }
+
+ // optional int64 negative_int_value = 5;
+ if (cached_has_bits & 0x00000010u) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt64ToArray(5, this->_internal_negative_int_value(), target);
+ }
+
+ // optional double double_value = 6;
+ if (cached_has_bits & 0x00000020u) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteDoubleToArray(6, this->_internal_double_value(), target);
+ }
+
+ // optional bytes string_value = 7;
+ if (cached_has_bits & 0x00000002u) {
+ target = stream->WriteBytesMaybeAliased(
+ 7, this->_internal_string_value(), target);
+ }
+
+ // optional string aggregate_value = 8;
+ if (cached_has_bits & 0x00000004u) {
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField(
+ this->_internal_aggregate_value().data(), static_cast<int>(this->_internal_aggregate_value().length()),
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE,
+ "google.protobuf.UninterpretedOption.aggregate_value");
+ target = stream->WriteStringMaybeAliased(
+ 8, this->_internal_aggregate_value(), target);
+ }
+
+ if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray(
+ _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.UninterpretedOption)
+ return target;
+}
+
+size_t UninterpretedOption::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.UninterpretedOption)
+ size_t total_size = 0;
+
+ 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->name_) {
+ total_size +=
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg);
+ }
+
+ cached_has_bits = _has_bits_[0];
+ if (cached_has_bits & 0x0000003fu) {
+ // optional string identifier_value = 3;
+ if (cached_has_bits & 0x00000001u) {
+ total_size += 1 +
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
+ this->_internal_identifier_value());
+ }
+
+ // optional bytes string_value = 7;
+ if (cached_has_bits & 0x00000002u) {
+ total_size += 1 +
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::BytesSize(
+ this->_internal_string_value());
+ }
+
+ // optional string aggregate_value = 8;
+ if (cached_has_bits & 0x00000004u) {
+ total_size += 1 +
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
+ this->_internal_aggregate_value());
+ }
+
+ // optional uint64 positive_int_value = 4;
+ if (cached_has_bits & 0x00000008u) {
+ total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::UInt64SizePlusOne(this->_internal_positive_int_value());
+ }
+
+ // optional int64 negative_int_value = 5;
+ if (cached_has_bits & 0x00000010u) {
+ total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int64SizePlusOne(this->_internal_negative_int_value());
+ }
+
+ // optional double double_value = 6;
+ if (cached_has_bits & 0x00000020u) {
+ total_size += 1 + 8;
+ }
+
+ }
+ return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData UninterpretedOption::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck,
+ UninterpretedOption::MergeImpl
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*UninterpretedOption::GetClassData() const { return &_class_data_; }
+
+void UninterpretedOption::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to,
+ const ::PROTOBUF_NAMESPACE_ID::Message& from) {
+ static_cast<UninterpretedOption *>(to)->MergeFrom(
+ static_cast<const UninterpretedOption &>(from));
+}
+
+
+void UninterpretedOption::MergeFrom(const UninterpretedOption& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.UninterpretedOption)
+ GOOGLE_DCHECK_NE(&from, this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ name_.MergeFrom(from.name_);
+ cached_has_bits = from._has_bits_[0];
+ if (cached_has_bits & 0x0000003fu) {
+ if (cached_has_bits & 0x00000001u) {
+ _internal_set_identifier_value(from._internal_identifier_value());
+ }
+ if (cached_has_bits & 0x00000002u) {
+ _internal_set_string_value(from._internal_string_value());
+ }
+ if (cached_has_bits & 0x00000004u) {
+ _internal_set_aggregate_value(from._internal_aggregate_value());
+ }
+ if (cached_has_bits & 0x00000008u) {
+ positive_int_value_ = from.positive_int_value_;
+ }
+ if (cached_has_bits & 0x00000010u) {
+ negative_int_value_ = from.negative_int_value_;
+ }
+ if (cached_has_bits & 0x00000020u) {
+ double_value_ = from.double_value_;
+ }
+ _has_bits_[0] |= cached_has_bits;
+ }
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+}
+
+void UninterpretedOption::CopyFrom(const UninterpretedOption& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.UninterpretedOption)
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+bool UninterpretedOption::IsInitialized() const {
+ if (!::PROTOBUF_NAMESPACE_ID::internal::AllAreInitialized(name_))
+ return false;
+ return true;
+}
+
+void UninterpretedOption::InternalSwap(UninterpretedOption* other) {
+ using std::swap;
+ auto* lhs_arena = GetArenaForAllocation();
+ auto* rhs_arena = other->GetArenaForAllocation();
+ _internal_metadata_.InternalSwap(&other->_internal_metadata_);
+ swap(_has_bits_[0], other->_has_bits_[0]);
+ name_.InternalSwap(&other->name_);
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(),
+ &identifier_value_, lhs_arena,
+ &other->identifier_value_, rhs_arena
+ );
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(),
+ &string_value_, lhs_arena,
+ &other->string_value_, rhs_arena
+ );
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(),
+ &aggregate_value_, lhs_arena,
+ &other->aggregate_value_, rhs_arena
+ );
+ ::PROTOBUF_NAMESPACE_ID::internal::memswap<
+ PROTOBUF_FIELD_OFFSET(UninterpretedOption, double_value_)
+ + sizeof(UninterpretedOption::double_value_)
+ - PROTOBUF_FIELD_OFFSET(UninterpretedOption, positive_int_value_)>(
+ reinterpret_cast<char*>(&positive_int_value_),
+ reinterpret_cast<char*>(&other->positive_int_value_));
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata UninterpretedOption::GetMetadata() const {
+ return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(
+ &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
+ file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[22]);
+}
+
+// ===================================================================
+
+class SourceCodeInfo_Location::_Internal {
+ public:
+ using HasBits = decltype(std::declval<SourceCodeInfo_Location>()._has_bits_);
+ static void set_has_leading_comments(HasBits* has_bits) {
+ (*has_bits)[0] |= 1u;
+ }
+ static void set_has_trailing_comments(HasBits* has_bits) {
+ (*has_bits)[0] |= 2u;
+ }
+};
+
+SourceCodeInfo_Location::SourceCodeInfo_Location(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned)
+ : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned),
+ path_(arena),
+ span_(arena),
+ leading_detached_comments_(arena) {
+ SharedCtor();
+ if (!is_message_owned) {
+ RegisterArenaDtor(arena);
+ }
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.SourceCodeInfo.Location)
+}
+SourceCodeInfo_Location::SourceCodeInfo_Location(const SourceCodeInfo_Location& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message(),
+ _has_bits_(from._has_bits_),
+ path_(from.path_),
+ span_(from.span_),
+ leading_detached_comments_(from.leading_detached_comments_) {
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ leading_comments_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ leading_comments_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (from._internal_has_leading_comments()) {
+ leading_comments_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_leading_comments(),
+ GetArenaForAllocation());
+ }
+ trailing_comments_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ trailing_comments_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (from._internal_has_trailing_comments()) {
+ trailing_comments_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_trailing_comments(),
+ GetArenaForAllocation());
+ }
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.SourceCodeInfo.Location)
+}
+
+inline void SourceCodeInfo_Location::SharedCtor() {
+leading_comments_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ leading_comments_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+trailing_comments_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ trailing_comments_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+}
+
+SourceCodeInfo_Location::~SourceCodeInfo_Location() {
+ // @@protoc_insertion_point(destructor:google.protobuf.SourceCodeInfo.Location)
+ if (GetArenaForAllocation() != nullptr) return;
+ SharedDtor();
+ _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+inline void SourceCodeInfo_Location::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+ leading_comments_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ trailing_comments_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+}
+
+void SourceCodeInfo_Location::ArenaDtor(void* object) {
+ SourceCodeInfo_Location* _this = reinterpret_cast< SourceCodeInfo_Location* >(object);
+ (void)_this;
+}
+void SourceCodeInfo_Location::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) {
+}
+void SourceCodeInfo_Location::SetCachedSize(int size) const {
+ _cached_size_.Set(size);
+}
+
+void SourceCodeInfo_Location::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.SourceCodeInfo.Location)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ path_.Clear();
+ span_.Clear();
+ leading_detached_comments_.Clear();
+ cached_has_bits = _has_bits_[0];
+ if (cached_has_bits & 0x00000003u) {
+ if (cached_has_bits & 0x00000001u) {
+ leading_comments_.ClearNonDefaultToEmpty();
+ }
+ if (cached_has_bits & 0x00000002u) {
+ trailing_comments_.ClearNonDefaultToEmpty();
+ }
+ }
+ _has_bits_.Clear();
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* SourceCodeInfo_Location::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ _Internal::HasBits has_bits{};
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag);
+ switch (tag >> 3) {
+ // repeated int32 path = 1 [packed = true];
+ case 1:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 10)) {
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::PackedInt32Parser(_internal_mutable_path(), ptr, ctx);
+ CHK_(ptr);
+ } else if (static_cast<uint8_t>(tag) == 8) {
+ _internal_add_path(::PROTOBUF_NAMESPACE_ID::internal::ReadVarint32(&ptr));
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // repeated int32 span = 2 [packed = true];
+ case 2:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 18)) {
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::PackedInt32Parser(_internal_mutable_span(), ptr, ctx);
+ CHK_(ptr);
+ } else if (static_cast<uint8_t>(tag) == 16) {
+ _internal_add_span(::PROTOBUF_NAMESPACE_ID::internal::ReadVarint32(&ptr));
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // optional string leading_comments = 3;
+ case 3:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 26)) {
+ auto str = _internal_mutable_leading_comments();
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx);
+ #ifndef NDEBUG
+ ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.SourceCodeInfo.Location.leading_comments");
+ #endif // !NDEBUG
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // optional string trailing_comments = 4;
+ case 4:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 34)) {
+ auto str = _internal_mutable_trailing_comments();
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx);
+ #ifndef NDEBUG
+ ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.SourceCodeInfo.Location.trailing_comments");
+ #endif // !NDEBUG
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // repeated string leading_detached_comments = 6;
+ case 6:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 50)) {
+ ptr -= 1;
+ do {
+ ptr += 1;
+ auto str = _internal_add_leading_detached_comments();
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx);
+ #ifndef NDEBUG
+ ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.SourceCodeInfo.Location.leading_detached_comments");
+ #endif // !NDEBUG
+ CHK_(ptr);
+ if (!ctx->DataAvailable(ptr)) break;
+ } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<50>(ptr));
+ } else
+ goto handle_unusual;
+ continue;
+ default:
+ goto handle_unusual;
+ } // switch
+ handle_unusual:
+ if ((tag == 0) || ((tag & 7) == 4)) {
+ CHK_(ptr);
+ ctx->SetLastTag(tag);
+ goto message_done;
+ }
+ ptr = UnknownFieldParse(
+ tag,
+ _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(),
+ ptr, ctx);
+ CHK_(ptr != nullptr);
+ } // while
+message_done:
+ _has_bits_.Or(has_bits);
+ return ptr;
+failure:
+ ptr = nullptr;
+ goto message_done;
+#undef CHK_
+}
+
+uint8_t* SourceCodeInfo_Location::_InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const {
+ // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.SourceCodeInfo.Location)
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ // repeated int32 path = 1 [packed = true];
+ {
+ int byte_size = _path_cached_byte_size_.load(std::memory_order_relaxed);
+ if (byte_size > 0) {
+ target = stream->WriteInt32Packed(
+ 1, _internal_path(), byte_size, target);
+ }
+ }
+
+ // repeated int32 span = 2 [packed = true];
+ {
+ int byte_size = _span_cached_byte_size_.load(std::memory_order_relaxed);
+ if (byte_size > 0) {
+ target = stream->WriteInt32Packed(
+ 2, _internal_span(), byte_size, target);
+ }
+ }
+
+ cached_has_bits = _has_bits_[0];
+ // optional string leading_comments = 3;
+ if (cached_has_bits & 0x00000001u) {
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField(
+ this->_internal_leading_comments().data(), static_cast<int>(this->_internal_leading_comments().length()),
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE,
+ "google.protobuf.SourceCodeInfo.Location.leading_comments");
+ target = stream->WriteStringMaybeAliased(
+ 3, this->_internal_leading_comments(), target);
+ }
+
+ // optional string trailing_comments = 4;
+ if (cached_has_bits & 0x00000002u) {
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField(
+ this->_internal_trailing_comments().data(), static_cast<int>(this->_internal_trailing_comments().length()),
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE,
+ "google.protobuf.SourceCodeInfo.Location.trailing_comments");
+ target = stream->WriteStringMaybeAliased(
+ 4, this->_internal_trailing_comments(), target);
+ }
+
+ // repeated string leading_detached_comments = 6;
+ for (int i = 0, n = this->_internal_leading_detached_comments_size(); i < n; i++) {
+ const auto& s = this->_internal_leading_detached_comments(i);
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField(
+ s.data(), static_cast<int>(s.length()),
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE,
+ "google.protobuf.SourceCodeInfo.Location.leading_detached_comments");
+ target = stream->WriteString(6, s, target);
+ }
+
+ if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray(
+ _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.SourceCodeInfo.Location)
+ return target;
+}
+
+size_t SourceCodeInfo_Location::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.SourceCodeInfo.Location)
+ size_t total_size = 0;
+
+ 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 = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ Int32Size(this->path_);
+ if (data_size > 0) {
+ total_size += 1 +
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32Size(
+ static_cast<int32_t>(data_size));
+ }
+ int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(data_size);
+ _path_cached_byte_size_.store(cached_size,
+ std::memory_order_relaxed);
+ total_size += data_size;
+ }
+
+ // repeated int32 span = 2 [packed = true];
+ {
+ size_t data_size = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ Int32Size(this->span_);
+ if (data_size > 0) {
+ total_size += 1 +
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32Size(
+ static_cast<int32_t>(data_size));
+ }
+ int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(data_size);
+ _span_cached_byte_size_.store(cached_size,
+ std::memory_order_relaxed);
+ total_size += data_size;
+ }
+
+ // repeated string leading_detached_comments = 6;
+ total_size += 1 *
+ ::PROTOBUF_NAMESPACE_ID::internal::FromIntSize(leading_detached_comments_.size());
+ for (int i = 0, n = leading_detached_comments_.size(); i < n; i++) {
+ total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
+ leading_detached_comments_.Get(i));
+ }
+
+ cached_has_bits = _has_bits_[0];
+ if (cached_has_bits & 0x00000003u) {
+ // optional string leading_comments = 3;
+ if (cached_has_bits & 0x00000001u) {
+ total_size += 1 +
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
+ this->_internal_leading_comments());
+ }
+
+ // optional string trailing_comments = 4;
+ if (cached_has_bits & 0x00000002u) {
+ total_size += 1 +
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
+ this->_internal_trailing_comments());
+ }
+
+ }
+ return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData SourceCodeInfo_Location::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck,
+ SourceCodeInfo_Location::MergeImpl
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*SourceCodeInfo_Location::GetClassData() const { return &_class_data_; }
+
+void SourceCodeInfo_Location::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to,
+ const ::PROTOBUF_NAMESPACE_ID::Message& from) {
+ static_cast<SourceCodeInfo_Location *>(to)->MergeFrom(
+ static_cast<const SourceCodeInfo_Location &>(from));
+}
+
+
+void SourceCodeInfo_Location::MergeFrom(const SourceCodeInfo_Location& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.SourceCodeInfo.Location)
+ GOOGLE_DCHECK_NE(&from, this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ path_.MergeFrom(from.path_);
+ span_.MergeFrom(from.span_);
+ leading_detached_comments_.MergeFrom(from.leading_detached_comments_);
+ cached_has_bits = from._has_bits_[0];
+ if (cached_has_bits & 0x00000003u) {
+ if (cached_has_bits & 0x00000001u) {
+ _internal_set_leading_comments(from._internal_leading_comments());
+ }
+ if (cached_has_bits & 0x00000002u) {
+ _internal_set_trailing_comments(from._internal_trailing_comments());
+ }
+ }
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+}
+
+void SourceCodeInfo_Location::CopyFrom(const SourceCodeInfo_Location& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.SourceCodeInfo.Location)
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+bool SourceCodeInfo_Location::IsInitialized() const {
+ return true;
+}
+
+void SourceCodeInfo_Location::InternalSwap(SourceCodeInfo_Location* other) {
+ using std::swap;
+ auto* lhs_arena = GetArenaForAllocation();
+ auto* rhs_arena = other->GetArenaForAllocation();
+ _internal_metadata_.InternalSwap(&other->_internal_metadata_);
+ swap(_has_bits_[0], other->_has_bits_[0]);
+ path_.InternalSwap(&other->path_);
+ span_.InternalSwap(&other->span_);
+ leading_detached_comments_.InternalSwap(&other->leading_detached_comments_);
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(),
+ &leading_comments_, lhs_arena,
+ &other->leading_comments_, rhs_arena
+ );
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(),
+ &trailing_comments_, lhs_arena,
+ &other->trailing_comments_, rhs_arena
+ );
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata SourceCodeInfo_Location::GetMetadata() const {
+ return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(
+ &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
+ file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[23]);
+}
+
+// ===================================================================
+
+class SourceCodeInfo::_Internal {
+ public:
+};
+
+SourceCodeInfo::SourceCodeInfo(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned)
+ : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned),
+ location_(arena) {
+ SharedCtor();
+ if (!is_message_owned) {
+ RegisterArenaDtor(arena);
+ }
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.SourceCodeInfo)
+}
+SourceCodeInfo::SourceCodeInfo(const SourceCodeInfo& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message(),
+ location_(from.location_) {
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.SourceCodeInfo)
+}
+
+inline void SourceCodeInfo::SharedCtor() {
+}
+
+SourceCodeInfo::~SourceCodeInfo() {
+ // @@protoc_insertion_point(destructor:google.protobuf.SourceCodeInfo)
+ if (GetArenaForAllocation() != nullptr) return;
+ SharedDtor();
+ _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+inline void SourceCodeInfo::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+}
+
+void SourceCodeInfo::ArenaDtor(void* object) {
+ SourceCodeInfo* _this = reinterpret_cast< SourceCodeInfo* >(object);
+ (void)_this;
+}
+void SourceCodeInfo::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) {
+}
+void SourceCodeInfo::SetCachedSize(int size) const {
+ _cached_size_.Set(size);
+}
+
+void SourceCodeInfo::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.SourceCodeInfo)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ location_.Clear();
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* SourceCodeInfo::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag);
+ switch (tag >> 3) {
+ // repeated .google.protobuf.SourceCodeInfo.Location location = 1;
+ case 1:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 10)) {
+ ptr -= 1;
+ do {
+ ptr += 1;
+ ptr = ctx->ParseMessage(_internal_add_location(), ptr);
+ CHK_(ptr);
+ if (!ctx->DataAvailable(ptr)) break;
+ } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<10>(ptr));
+ } else
+ goto handle_unusual;
+ continue;
+ default:
+ goto handle_unusual;
+ } // switch
+ handle_unusual:
+ if ((tag == 0) || ((tag & 7) == 4)) {
+ CHK_(ptr);
+ ctx->SetLastTag(tag);
+ goto message_done;
+ }
+ ptr = UnknownFieldParse(
+ tag,
+ _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(),
+ ptr, ctx);
+ CHK_(ptr != nullptr);
+ } // while
+message_done:
+ return ptr;
+failure:
+ ptr = nullptr;
+ goto message_done;
+#undef CHK_
+}
+
+uint8_t* SourceCodeInfo::_InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const {
+ // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.SourceCodeInfo)
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ // repeated .google.protobuf.SourceCodeInfo.Location location = 1;
+ for (unsigned int i = 0,
+ n = static_cast<unsigned int>(this->_internal_location_size()); i < n; i++) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(1, this->_internal_location(i), target, stream);
+ }
+
+ if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray(
+ _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.SourceCodeInfo)
+ return target;
+}
+
+size_t SourceCodeInfo::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.SourceCodeInfo)
+ size_t total_size = 0;
+
+ 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->location_) {
+ total_size +=
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg);
+ }
+
+ return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData SourceCodeInfo::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck,
+ SourceCodeInfo::MergeImpl
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*SourceCodeInfo::GetClassData() const { return &_class_data_; }
+
+void SourceCodeInfo::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to,
+ const ::PROTOBUF_NAMESPACE_ID::Message& from) {
+ static_cast<SourceCodeInfo *>(to)->MergeFrom(
+ static_cast<const SourceCodeInfo &>(from));
+}
+
+
+void SourceCodeInfo::MergeFrom(const SourceCodeInfo& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.SourceCodeInfo)
+ GOOGLE_DCHECK_NE(&from, this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ location_.MergeFrom(from.location_);
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+}
+
+void SourceCodeInfo::CopyFrom(const SourceCodeInfo& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.SourceCodeInfo)
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+bool SourceCodeInfo::IsInitialized() const {
+ return true;
+}
+
+void SourceCodeInfo::InternalSwap(SourceCodeInfo* other) {
+ using std::swap;
+ _internal_metadata_.InternalSwap(&other->_internal_metadata_);
+ location_.InternalSwap(&other->location_);
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata SourceCodeInfo::GetMetadata() const {
+ return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(
+ &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
+ file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[24]);
+}
+
+// ===================================================================
+
+class GeneratedCodeInfo_Annotation::_Internal {
+ public:
+ using HasBits = decltype(std::declval<GeneratedCodeInfo_Annotation>()._has_bits_);
+ static void set_has_source_file(HasBits* has_bits) {
+ (*has_bits)[0] |= 1u;
+ }
+ static void set_has_begin(HasBits* has_bits) {
+ (*has_bits)[0] |= 2u;
+ }
+ static void set_has_end(HasBits* has_bits) {
+ (*has_bits)[0] |= 4u;
+ }
+};
+
+GeneratedCodeInfo_Annotation::GeneratedCodeInfo_Annotation(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned)
+ : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned),
+ path_(arena) {
+ SharedCtor();
+ if (!is_message_owned) {
+ RegisterArenaDtor(arena);
+ }
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.GeneratedCodeInfo.Annotation)
+}
+GeneratedCodeInfo_Annotation::GeneratedCodeInfo_Annotation(const GeneratedCodeInfo_Annotation& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message(),
+ _has_bits_(from._has_bits_),
+ path_(from.path_) {
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ source_file_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ source_file_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (from._internal_has_source_file()) {
+ source_file_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_source_file(),
+ GetArenaForAllocation());
+ }
+ ::memcpy(&begin_, &from.begin_,
+ static_cast<size_t>(reinterpret_cast<char*>(&end_) -
+ reinterpret_cast<char*>(&begin_)) + sizeof(end_));
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.GeneratedCodeInfo.Annotation)
+}
+
+inline void GeneratedCodeInfo_Annotation::SharedCtor() {
+source_file_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ source_file_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+::memset(reinterpret_cast<char*>(this) + static_cast<size_t>(
+ reinterpret_cast<char*>(&begin_) - reinterpret_cast<char*>(this)),
+ 0, static_cast<size_t>(reinterpret_cast<char*>(&end_) -
+ reinterpret_cast<char*>(&begin_)) + sizeof(end_));
+}
+
+GeneratedCodeInfo_Annotation::~GeneratedCodeInfo_Annotation() {
+ // @@protoc_insertion_point(destructor:google.protobuf.GeneratedCodeInfo.Annotation)
+ if (GetArenaForAllocation() != nullptr) return;
+ SharedDtor();
+ _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+inline void GeneratedCodeInfo_Annotation::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+ source_file_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+}
+
+void GeneratedCodeInfo_Annotation::ArenaDtor(void* object) {
+ GeneratedCodeInfo_Annotation* _this = reinterpret_cast< GeneratedCodeInfo_Annotation* >(object);
+ (void)_this;
+}
+void GeneratedCodeInfo_Annotation::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) {
+}
+void GeneratedCodeInfo_Annotation::SetCachedSize(int size) const {
+ _cached_size_.Set(size);
+}
+
+void GeneratedCodeInfo_Annotation::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.GeneratedCodeInfo.Annotation)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ path_.Clear();
+ cached_has_bits = _has_bits_[0];
+ if (cached_has_bits & 0x00000001u) {
+ source_file_.ClearNonDefaultToEmpty();
+ }
+ if (cached_has_bits & 0x00000006u) {
+ ::memset(&begin_, 0, static_cast<size_t>(
+ reinterpret_cast<char*>(&end_) -
+ reinterpret_cast<char*>(&begin_)) + sizeof(end_));
+ }
+ _has_bits_.Clear();
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* GeneratedCodeInfo_Annotation::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ _Internal::HasBits has_bits{};
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag);
+ switch (tag >> 3) {
+ // repeated int32 path = 1 [packed = true];
+ case 1:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 10)) {
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::PackedInt32Parser(_internal_mutable_path(), ptr, ctx);
+ CHK_(ptr);
+ } else if (static_cast<uint8_t>(tag) == 8) {
+ _internal_add_path(::PROTOBUF_NAMESPACE_ID::internal::ReadVarint32(&ptr));
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // optional string source_file = 2;
+ case 2:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 18)) {
+ auto str = _internal_mutable_source_file();
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx);
+ #ifndef NDEBUG
+ ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.GeneratedCodeInfo.Annotation.source_file");
+ #endif // !NDEBUG
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // optional int32 begin = 3;
+ case 3:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 24)) {
+ _Internal::set_has_begin(&has_bits);
+ begin_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint32(&ptr);
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // optional int32 end = 4;
+ case 4:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 32)) {
+ _Internal::set_has_end(&has_bits);
+ end_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint32(&ptr);
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ default:
+ goto handle_unusual;
+ } // switch
+ handle_unusual:
+ if ((tag == 0) || ((tag & 7) == 4)) {
+ CHK_(ptr);
+ ctx->SetLastTag(tag);
+ goto message_done;
+ }
+ ptr = UnknownFieldParse(
+ tag,
+ _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(),
+ ptr, ctx);
+ CHK_(ptr != nullptr);
+ } // while
+message_done:
+ _has_bits_.Or(has_bits);
+ return ptr;
+failure:
+ ptr = nullptr;
+ goto message_done;
+#undef CHK_
+}
+
+uint8_t* GeneratedCodeInfo_Annotation::_InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const {
+ // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.GeneratedCodeInfo.Annotation)
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ // repeated int32 path = 1 [packed = true];
+ {
+ int byte_size = _path_cached_byte_size_.load(std::memory_order_relaxed);
+ if (byte_size > 0) {
+ target = stream->WriteInt32Packed(
+ 1, _internal_path(), byte_size, target);
+ }
+ }
+
+ cached_has_bits = _has_bits_[0];
+ // optional string source_file = 2;
+ if (cached_has_bits & 0x00000001u) {
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField(
+ this->_internal_source_file().data(), static_cast<int>(this->_internal_source_file().length()),
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE,
+ "google.protobuf.GeneratedCodeInfo.Annotation.source_file");
+ target = stream->WriteStringMaybeAliased(
+ 2, this->_internal_source_file(), target);
+ }
+
+ // optional int32 begin = 3;
+ if (cached_has_bits & 0x00000002u) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32ToArray(3, this->_internal_begin(), target);
+ }
+
+ // optional int32 end = 4;
+ if (cached_has_bits & 0x00000004u) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32ToArray(4, this->_internal_end(), target);
+ }
+
+ if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray(
+ _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.GeneratedCodeInfo.Annotation)
+ return target;
+}
+
+size_t GeneratedCodeInfo_Annotation::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.GeneratedCodeInfo.Annotation)
+ size_t total_size = 0;
+
+ 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 = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ Int32Size(this->path_);
+ if (data_size > 0) {
+ total_size += 1 +
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32Size(
+ static_cast<int32_t>(data_size));
+ }
+ int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(data_size);
+ _path_cached_byte_size_.store(cached_size,
+ std::memory_order_relaxed);
+ total_size += data_size;
+ }
+
+ cached_has_bits = _has_bits_[0];
+ if (cached_has_bits & 0x00000007u) {
+ // optional string source_file = 2;
+ if (cached_has_bits & 0x00000001u) {
+ total_size += 1 +
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
+ this->_internal_source_file());
+ }
+
+ // optional int32 begin = 3;
+ if (cached_has_bits & 0x00000002u) {
+ total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32SizePlusOne(this->_internal_begin());
+ }
+
+ // optional int32 end = 4;
+ if (cached_has_bits & 0x00000004u) {
+ total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32SizePlusOne(this->_internal_end());
+ }
+
+ }
+ return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData GeneratedCodeInfo_Annotation::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck,
+ GeneratedCodeInfo_Annotation::MergeImpl
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GeneratedCodeInfo_Annotation::GetClassData() const { return &_class_data_; }
+
+void GeneratedCodeInfo_Annotation::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to,
+ const ::PROTOBUF_NAMESPACE_ID::Message& from) {
+ static_cast<GeneratedCodeInfo_Annotation *>(to)->MergeFrom(
+ static_cast<const GeneratedCodeInfo_Annotation &>(from));
+}
+
+
+void GeneratedCodeInfo_Annotation::MergeFrom(const GeneratedCodeInfo_Annotation& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.GeneratedCodeInfo.Annotation)
+ GOOGLE_DCHECK_NE(&from, this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ path_.MergeFrom(from.path_);
+ cached_has_bits = from._has_bits_[0];
+ if (cached_has_bits & 0x00000007u) {
+ if (cached_has_bits & 0x00000001u) {
+ _internal_set_source_file(from._internal_source_file());
+ }
+ if (cached_has_bits & 0x00000002u) {
+ begin_ = from.begin_;
+ }
+ if (cached_has_bits & 0x00000004u) {
+ end_ = from.end_;
+ }
+ _has_bits_[0] |= cached_has_bits;
+ }
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+}
+
+void GeneratedCodeInfo_Annotation::CopyFrom(const GeneratedCodeInfo_Annotation& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.GeneratedCodeInfo.Annotation)
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+bool GeneratedCodeInfo_Annotation::IsInitialized() const {
+ return true;
+}
+
+void GeneratedCodeInfo_Annotation::InternalSwap(GeneratedCodeInfo_Annotation* other) {
+ using std::swap;
+ auto* lhs_arena = GetArenaForAllocation();
+ auto* rhs_arena = other->GetArenaForAllocation();
+ _internal_metadata_.InternalSwap(&other->_internal_metadata_);
+ swap(_has_bits_[0], other->_has_bits_[0]);
+ path_.InternalSwap(&other->path_);
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(),
+ &source_file_, lhs_arena,
+ &other->source_file_, rhs_arena
+ );
+ ::PROTOBUF_NAMESPACE_ID::internal::memswap<
+ PROTOBUF_FIELD_OFFSET(GeneratedCodeInfo_Annotation, end_)
+ + sizeof(GeneratedCodeInfo_Annotation::end_)
+ - PROTOBUF_FIELD_OFFSET(GeneratedCodeInfo_Annotation, begin_)>(
+ reinterpret_cast<char*>(&begin_),
+ reinterpret_cast<char*>(&other->begin_));
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata GeneratedCodeInfo_Annotation::GetMetadata() const {
+ return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(
+ &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
+ file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[25]);
+}
+
+// ===================================================================
+
+class GeneratedCodeInfo::_Internal {
+ public:
+};
+
+GeneratedCodeInfo::GeneratedCodeInfo(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned)
+ : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned),
+ annotation_(arena) {
+ SharedCtor();
+ if (!is_message_owned) {
+ RegisterArenaDtor(arena);
+ }
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.GeneratedCodeInfo)
+}
+GeneratedCodeInfo::GeneratedCodeInfo(const GeneratedCodeInfo& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message(),
+ annotation_(from.annotation_) {
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.GeneratedCodeInfo)
+}
+
+inline void GeneratedCodeInfo::SharedCtor() {
+}
+
+GeneratedCodeInfo::~GeneratedCodeInfo() {
+ // @@protoc_insertion_point(destructor:google.protobuf.GeneratedCodeInfo)
+ if (GetArenaForAllocation() != nullptr) return;
+ SharedDtor();
+ _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+inline void GeneratedCodeInfo::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+}
+
+void GeneratedCodeInfo::ArenaDtor(void* object) {
+ GeneratedCodeInfo* _this = reinterpret_cast< GeneratedCodeInfo* >(object);
+ (void)_this;
+}
+void GeneratedCodeInfo::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) {
+}
+void GeneratedCodeInfo::SetCachedSize(int size) const {
+ _cached_size_.Set(size);
+}
+
+void GeneratedCodeInfo::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.GeneratedCodeInfo)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ annotation_.Clear();
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* GeneratedCodeInfo::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag);
+ switch (tag >> 3) {
+ // repeated .google.protobuf.GeneratedCodeInfo.Annotation annotation = 1;
+ case 1:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 10)) {
+ ptr -= 1;
+ do {
+ ptr += 1;
+ ptr = ctx->ParseMessage(_internal_add_annotation(), ptr);
+ CHK_(ptr);
+ if (!ctx->DataAvailable(ptr)) break;
+ } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<10>(ptr));
+ } else
+ goto handle_unusual;
+ continue;
+ default:
+ goto handle_unusual;
+ } // switch
+ handle_unusual:
+ if ((tag == 0) || ((tag & 7) == 4)) {
+ CHK_(ptr);
+ ctx->SetLastTag(tag);
+ goto message_done;
+ }
+ ptr = UnknownFieldParse(
+ tag,
+ _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(),
+ ptr, ctx);
+ CHK_(ptr != nullptr);
+ } // while
+message_done:
+ return ptr;
+failure:
+ ptr = nullptr;
+ goto message_done;
+#undef CHK_
+}
+
+uint8_t* GeneratedCodeInfo::_InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const {
+ // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.GeneratedCodeInfo)
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ // repeated .google.protobuf.GeneratedCodeInfo.Annotation annotation = 1;
+ for (unsigned int i = 0,
+ n = static_cast<unsigned int>(this->_internal_annotation_size()); i < n; i++) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(1, this->_internal_annotation(i), target, stream);
+ }
+
+ if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray(
+ _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.GeneratedCodeInfo)
+ return target;
+}
+
+size_t GeneratedCodeInfo::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.GeneratedCodeInfo)
+ size_t total_size = 0;
+
+ 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->annotation_) {
+ total_size +=
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg);
+ }
+
+ return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData GeneratedCodeInfo::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck,
+ GeneratedCodeInfo::MergeImpl
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GeneratedCodeInfo::GetClassData() const { return &_class_data_; }
+
+void GeneratedCodeInfo::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to,
+ const ::PROTOBUF_NAMESPACE_ID::Message& from) {
+ static_cast<GeneratedCodeInfo *>(to)->MergeFrom(
+ static_cast<const GeneratedCodeInfo &>(from));
+}
+
+
+void GeneratedCodeInfo::MergeFrom(const GeneratedCodeInfo& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.GeneratedCodeInfo)
+ GOOGLE_DCHECK_NE(&from, this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ annotation_.MergeFrom(from.annotation_);
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+}
+
+void GeneratedCodeInfo::CopyFrom(const GeneratedCodeInfo& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.GeneratedCodeInfo)
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+bool GeneratedCodeInfo::IsInitialized() const {
+ return true;
+}
+
+void GeneratedCodeInfo::InternalSwap(GeneratedCodeInfo* other) {
+ using std::swap;
+ _internal_metadata_.InternalSwap(&other->_internal_metadata_);
+ annotation_.InternalSwap(&other->annotation_);
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata GeneratedCodeInfo::GetMetadata() const {
+ return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(
+ &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
+ file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[26]);
+}
+
+// @@protoc_insertion_point(namespace_scope)
+PROTOBUF_NAMESPACE_CLOSE
+PROTOBUF_NAMESPACE_OPEN
+template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::FileDescriptorSet* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::FileDescriptorSet >(Arena* arena) {
+ return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::FileDescriptorSet >(arena);
+}
+template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::FileDescriptorProto* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::FileDescriptorProto >(Arena* arena) {
+ return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::FileDescriptorProto >(arena);
+}
+template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::DescriptorProto_ExtensionRange* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::DescriptorProto_ExtensionRange >(Arena* arena) {
+ return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::DescriptorProto_ExtensionRange >(arena);
+}
+template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::DescriptorProto_ReservedRange* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::DescriptorProto_ReservedRange >(Arena* arena) {
+ return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::DescriptorProto_ReservedRange >(arena);
+}
+template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::DescriptorProto* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::DescriptorProto >(Arena* arena) {
+ return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::DescriptorProto >(arena);
+}
+template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions >(Arena* arena) {
+ return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions >(arena);
+}
+template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto >(Arena* arena) {
+ return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto >(arena);
+}
+template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::OneofDescriptorProto* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::OneofDescriptorProto >(Arena* arena) {
+ return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::OneofDescriptorProto >(arena);
+}
+template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto_EnumReservedRange* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto_EnumReservedRange >(Arena* arena) {
+ return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto_EnumReservedRange >(arena);
+}
+template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto >(Arena* arena) {
+ return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto >(arena);
+}
+template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::EnumValueDescriptorProto* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::EnumValueDescriptorProto >(Arena* arena) {
+ return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::EnumValueDescriptorProto >(arena);
+}
+template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::ServiceDescriptorProto* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::ServiceDescriptorProto >(Arena* arena) {
+ return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::ServiceDescriptorProto >(arena);
+}
+template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::MethodDescriptorProto* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::MethodDescriptorProto >(Arena* arena) {
+ return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::MethodDescriptorProto >(arena);
+}
+template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::FileOptions* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::FileOptions >(Arena* arena) {
+ return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::FileOptions >(arena);
+}
+template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::MessageOptions* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::MessageOptions >(Arena* arena) {
+ return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::MessageOptions >(arena);
+}
+template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::FieldOptions* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::FieldOptions >(Arena* arena) {
+ return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::FieldOptions >(arena);
+}
+template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::OneofOptions* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::OneofOptions >(Arena* arena) {
+ return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::OneofOptions >(arena);
+}
+template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::EnumOptions* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::EnumOptions >(Arena* arena) {
+ return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::EnumOptions >(arena);
+}
+template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::EnumValueOptions* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::EnumValueOptions >(Arena* arena) {
+ return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::EnumValueOptions >(arena);
+}
+template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::ServiceOptions* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::ServiceOptions >(Arena* arena) {
+ return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::ServiceOptions >(arena);
+}
+template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::MethodOptions* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::MethodOptions >(Arena* arena) {
+ return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::MethodOptions >(arena);
+}
+template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::UninterpretedOption_NamePart* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption_NamePart >(Arena* arena) {
+ return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption_NamePart >(arena);
+}
+template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption >(Arena* arena) {
+ return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption >(arena);
+}
+template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location >(Arena* arena) {
+ return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location >(arena);
+}
+template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo >(Arena* arena) {
+ return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo >(arena);
+}
+template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation >(Arena* arena) {
+ return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation >(arena);
+}
+template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo >(Arena* arena) {
+ return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo >(arena);
+}
+PROTOBUF_NAMESPACE_CLOSE
+
+// @@protoc_insertion_point(global_scope)
+#include <port_undef.inc>
diff --git a/NorthstarDedicatedTest/include/protobuf/descriptor.pb.h b/NorthstarDedicatedTest/include/protobuf/descriptor.pb.h
new file mode 100644
index 00000000..92a4b8e0
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/descriptor.pb.h
@@ -0,0 +1,14766 @@
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+// source: google/protobuf/descriptor.proto
+
+#ifndef GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fdescriptor_2eproto
+#define GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fdescriptor_2eproto
+
+#include <limits>
+#include <string>
+
+#include <port_def.inc>
+#if PROTOBUF_VERSION < 3019000
+#error This file was generated by a newer version of protoc which is
+#error incompatible with your Protocol Buffer headers. Please update
+#error your headers.
+#endif
+#if 3019004 < 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 <port_undef.inc>
+#include <io/coded_stream.h>
+#include <arena.h>
+#include <arenastring.h>
+#include <generated_message_table_driven.h>
+#include <generated_message_util.h>
+#include <metadata_lite.h>
+#include <generated_message_reflection.h>
+#include <message.h>
+#include <repeated_field.h> // IWYU pragma: export
+#include <extension_set.h> // IWYU pragma: export
+#include <generated_enum_reflection.h>
+#include <unknown_field_set.h>
+// @@protoc_insertion_point(includes)
+#include <port_def.inc>
+#define PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fdescriptor_2eproto PROTOBUF_EXPORT
+PROTOBUF_NAMESPACE_OPEN
+namespace internal {
+class AnyMetadata;
+} // namespace internal
+PROTOBUF_NAMESPACE_CLOSE
+
+// Internal implementation detail -- do not use these members.
+struct PROTOBUF_EXPORT TableStruct_google_2fprotobuf_2fdescriptor_2eproto {
+ static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTableField entries[]
+ PROTOBUF_SECTION_VARIABLE(protodesc_cold);
+ static const ::PROTOBUF_NAMESPACE_ID::internal::AuxiliaryParseTableField aux[]
+ PROTOBUF_SECTION_VARIABLE(protodesc_cold);
+ static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTable schema[27]
+ PROTOBUF_SECTION_VARIABLE(protodesc_cold);
+ static const ::PROTOBUF_NAMESPACE_ID::internal::FieldMetadata field_metadata[];
+ static const ::PROTOBUF_NAMESPACE_ID::internal::SerializationTable serialization_table[];
+ static const 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 constexpr FileDescriptorSet(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
+
+ FileDescriptorSet(const FileDescriptorSet& from);
+ FileDescriptorSet(FileDescriptorSet&& from) noexcept
+ : FileDescriptorSet() {
+ *this = ::std::move(from);
+ }
+
+ inline FileDescriptorSet& operator=(const FileDescriptorSet& from) {
+ CopyFrom(from);
+ return *this;
+ }
+ inline FileDescriptorSet& operator=(FileDescriptorSet&& from) noexcept {
+ if (this == &from) return *this;
+ if (GetOwningArena() == from.GetOwningArena()
+ #ifdef PROTOBUF_FORCE_COPY_IN_MOVE
+ && GetOwningArena() != nullptr
+ #endif // !PROTOBUF_FORCE_COPY_IN_MOVE
+ ) {
+ InternalSwap(&from);
+ } else {
+ CopyFrom(from);
+ }
+ return *this;
+ }
+
+ inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const {
+ return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance);
+ }
+ inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() {
+ return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+ }
+
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
+ return GetDescriptor();
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
+ return default_instance().GetMetadata().descriptor;
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
+ return default_instance().GetMetadata().reflection;
+ }
+ static const FileDescriptorSet& default_instance() {
+ return *internal_default_instance();
+ }
+ static inline const FileDescriptorSet* internal_default_instance() {
+ return reinterpret_cast<const FileDescriptorSet*>(
+ &_FileDescriptorSet_default_instance_);
+ }
+ static constexpr int kIndexInFileMessages =
+ 0;
+
+ friend void swap(FileDescriptorSet& a, FileDescriptorSet& b) {
+ a.Swap(&b);
+ }
+ inline void Swap(FileDescriptorSet* other) {
+ if (other == this) return;
+ #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() != nullptr &&
+ GetOwningArena() == other->GetOwningArena()) {
+ #else // PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() == other->GetOwningArena()) {
+ #endif // !PROTOBUF_FORCE_COPY_IN_SWAP
+ InternalSwap(other);
+ } else {
+ ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
+ }
+ }
+ void UnsafeArenaSwap(FileDescriptorSet* other) {
+ if (other == this) return;
+ GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena());
+ InternalSwap(other);
+ }
+
+ // implements Message ----------------------------------------------
+
+ FileDescriptorSet* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
+ return CreateMaybeMessage<FileDescriptorSet>(arena);
+ }
+ using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
+ void CopyFrom(const FileDescriptorSet& from);
+ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
+ void MergeFrom(const FileDescriptorSet& from);
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from);
+ public:
+ PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+ bool IsInitialized() const final;
+
+ size_t ByteSizeLong() const final;
+ const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
+ uint8_t* _InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
+ int GetCachedSize() const final { return _cached_size_.Get(); }
+
+ private:
+ void SharedCtor();
+ void SharedDtor();
+ void SetCachedSize(int size) const final;
+ void InternalSwap(FileDescriptorSet* other);
+
+ private:
+ friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
+ static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
+ return "google.protobuf.FileDescriptorSet";
+ }
+ protected:
+ explicit FileDescriptorSet(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned = false);
+ private:
+ static void ArenaDtor(void* object);
+ inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
+ public:
+
+ static const ClassData _class_data_;
+ const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;
+
+ ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;
+
+ // nested types ----------------------------------------------------
+
+ // accessors -------------------------------------------------------
+
+ enum : int {
+ kFileFieldNumber = 1,
+ };
+ // repeated .google.protobuf.FileDescriptorProto file = 1;
+ int file_size() const;
+ private:
+ int _internal_file_size() const;
+ public:
+ void clear_file();
+ ::PROTOBUF_NAMESPACE_ID::FileDescriptorProto* mutable_file(int index);
+ ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::FileDescriptorProto >*
+ mutable_file();
+ private:
+ const ::PROTOBUF_NAMESPACE_ID::FileDescriptorProto& _internal_file(int index) const;
+ ::PROTOBUF_NAMESPACE_ID::FileDescriptorProto* _internal_add_file();
+ public:
+ const ::PROTOBUF_NAMESPACE_ID::FileDescriptorProto& file(int index) const;
+ ::PROTOBUF_NAMESPACE_ID::FileDescriptorProto* add_file();
+ const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::FileDescriptorProto >&
+ file() const;
+
+ // @@protoc_insertion_point(class_scope:google.protobuf.FileDescriptorSet)
+ private:
+ class _Internal;
+
+ template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
+ typedef void InternalArenaConstructable_;
+ typedef void DestructorSkippable_;
+ ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::FileDescriptorProto > file_;
+ mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
+ friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
+};
+// -------------------------------------------------------------------
+
+class PROTOBUF_EXPORT FileDescriptorProto final :
+ public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.FileDescriptorProto) */ {
+ public:
+ inline FileDescriptorProto() : FileDescriptorProto(nullptr) {}
+ ~FileDescriptorProto() override;
+ explicit constexpr FileDescriptorProto(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
+
+ FileDescriptorProto(const FileDescriptorProto& from);
+ FileDescriptorProto(FileDescriptorProto&& from) noexcept
+ : FileDescriptorProto() {
+ *this = ::std::move(from);
+ }
+
+ inline FileDescriptorProto& operator=(const FileDescriptorProto& from) {
+ CopyFrom(from);
+ return *this;
+ }
+ inline FileDescriptorProto& operator=(FileDescriptorProto&& from) noexcept {
+ if (this == &from) return *this;
+ if (GetOwningArena() == from.GetOwningArena()
+ #ifdef PROTOBUF_FORCE_COPY_IN_MOVE
+ && GetOwningArena() != nullptr
+ #endif // !PROTOBUF_FORCE_COPY_IN_MOVE
+ ) {
+ InternalSwap(&from);
+ } else {
+ CopyFrom(from);
+ }
+ return *this;
+ }
+
+ inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const {
+ return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance);
+ }
+ inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() {
+ return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+ }
+
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
+ return GetDescriptor();
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
+ return default_instance().GetMetadata().descriptor;
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
+ return default_instance().GetMetadata().reflection;
+ }
+ static const FileDescriptorProto& default_instance() {
+ return *internal_default_instance();
+ }
+ static inline const FileDescriptorProto* internal_default_instance() {
+ return reinterpret_cast<const FileDescriptorProto*>(
+ &_FileDescriptorProto_default_instance_);
+ }
+ static constexpr int kIndexInFileMessages =
+ 1;
+
+ friend void swap(FileDescriptorProto& a, FileDescriptorProto& b) {
+ a.Swap(&b);
+ }
+ inline void Swap(FileDescriptorProto* other) {
+ if (other == this) return;
+ #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() != nullptr &&
+ GetOwningArena() == other->GetOwningArena()) {
+ #else // PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() == other->GetOwningArena()) {
+ #endif // !PROTOBUF_FORCE_COPY_IN_SWAP
+ InternalSwap(other);
+ } else {
+ ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
+ }
+ }
+ void UnsafeArenaSwap(FileDescriptorProto* other) {
+ if (other == this) return;
+ GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena());
+ InternalSwap(other);
+ }
+
+ // implements Message ----------------------------------------------
+
+ FileDescriptorProto* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
+ return CreateMaybeMessage<FileDescriptorProto>(arena);
+ }
+ using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
+ void CopyFrom(const FileDescriptorProto& from);
+ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
+ void MergeFrom(const FileDescriptorProto& from);
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from);
+ public:
+ PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+ bool IsInitialized() const final;
+
+ size_t ByteSizeLong() const final;
+ const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
+ uint8_t* _InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
+ int GetCachedSize() const final { return _cached_size_.Get(); }
+
+ private:
+ void SharedCtor();
+ void SharedDtor();
+ void SetCachedSize(int size) const final;
+ void InternalSwap(FileDescriptorProto* other);
+
+ private:
+ friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
+ static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
+ return "google.protobuf.FileDescriptorProto";
+ }
+ protected:
+ explicit FileDescriptorProto(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned = false);
+ private:
+ static void ArenaDtor(void* object);
+ inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
+ public:
+
+ static const ClassData _class_data_;
+ const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;
+
+ ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;
+
+ // nested types ----------------------------------------------------
+
+ // accessors -------------------------------------------------------
+
+ enum : int {
+ kDependencyFieldNumber = 3,
+ kMessageTypeFieldNumber = 4,
+ kEnumTypeFieldNumber = 5,
+ kServiceFieldNumber = 6,
+ kExtensionFieldNumber = 7,
+ kPublicDependencyFieldNumber = 10,
+ kWeakDependencyFieldNumber = 11,
+ kNameFieldNumber = 1,
+ kPackageFieldNumber = 2,
+ kSyntaxFieldNumber = 12,
+ kOptionsFieldNumber = 8,
+ kSourceCodeInfoFieldNumber = 9,
+ };
+ // repeated string dependency = 3;
+ int dependency_size() const;
+ private:
+ int _internal_dependency_size() const;
+ public:
+ void clear_dependency();
+ const 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_;
+ ::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_;
+ friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
+};
+// -------------------------------------------------------------------
+
+class PROTOBUF_EXPORT DescriptorProto_ExtensionRange final :
+ public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.DescriptorProto.ExtensionRange) */ {
+ public:
+ inline DescriptorProto_ExtensionRange() : DescriptorProto_ExtensionRange(nullptr) {}
+ ~DescriptorProto_ExtensionRange() override;
+ explicit constexpr DescriptorProto_ExtensionRange(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
+
+ DescriptorProto_ExtensionRange(const DescriptorProto_ExtensionRange& from);
+ DescriptorProto_ExtensionRange(DescriptorProto_ExtensionRange&& from) noexcept
+ : DescriptorProto_ExtensionRange() {
+ *this = ::std::move(from);
+ }
+
+ inline DescriptorProto_ExtensionRange& operator=(const DescriptorProto_ExtensionRange& from) {
+ CopyFrom(from);
+ return *this;
+ }
+ inline DescriptorProto_ExtensionRange& operator=(DescriptorProto_ExtensionRange&& from) noexcept {
+ if (this == &from) return *this;
+ if (GetOwningArena() == from.GetOwningArena()
+ #ifdef PROTOBUF_FORCE_COPY_IN_MOVE
+ && GetOwningArena() != nullptr
+ #endif // !PROTOBUF_FORCE_COPY_IN_MOVE
+ ) {
+ InternalSwap(&from);
+ } else {
+ CopyFrom(from);
+ }
+ return *this;
+ }
+
+ inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const {
+ return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance);
+ }
+ inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() {
+ return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+ }
+
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
+ return GetDescriptor();
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
+ return default_instance().GetMetadata().descriptor;
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
+ return default_instance().GetMetadata().reflection;
+ }
+ static const DescriptorProto_ExtensionRange& default_instance() {
+ return *internal_default_instance();
+ }
+ static inline const DescriptorProto_ExtensionRange* internal_default_instance() {
+ return reinterpret_cast<const DescriptorProto_ExtensionRange*>(
+ &_DescriptorProto_ExtensionRange_default_instance_);
+ }
+ static constexpr int kIndexInFileMessages =
+ 2;
+
+ friend void swap(DescriptorProto_ExtensionRange& a, DescriptorProto_ExtensionRange& b) {
+ a.Swap(&b);
+ }
+ inline void Swap(DescriptorProto_ExtensionRange* other) {
+ if (other == this) return;
+ #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() != nullptr &&
+ GetOwningArena() == other->GetOwningArena()) {
+ #else // PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() == other->GetOwningArena()) {
+ #endif // !PROTOBUF_FORCE_COPY_IN_SWAP
+ InternalSwap(other);
+ } else {
+ ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
+ }
+ }
+ void UnsafeArenaSwap(DescriptorProto_ExtensionRange* other) {
+ if (other == this) return;
+ GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena());
+ InternalSwap(other);
+ }
+
+ // implements Message ----------------------------------------------
+
+ DescriptorProto_ExtensionRange* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
+ return CreateMaybeMessage<DescriptorProto_ExtensionRange>(arena);
+ }
+ using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
+ void CopyFrom(const DescriptorProto_ExtensionRange& from);
+ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
+ void MergeFrom(const DescriptorProto_ExtensionRange& from);
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from);
+ public:
+ PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+ bool IsInitialized() const final;
+
+ size_t ByteSizeLong() const final;
+ const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
+ uint8_t* _InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
+ int GetCachedSize() const final { return _cached_size_.Get(); }
+
+ private:
+ void SharedCtor();
+ void SharedDtor();
+ void SetCachedSize(int size) const final;
+ void InternalSwap(DescriptorProto_ExtensionRange* other);
+
+ private:
+ friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
+ static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
+ return "google.protobuf.DescriptorProto.ExtensionRange";
+ }
+ protected:
+ explicit DescriptorProto_ExtensionRange(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned = false);
+ private:
+ static void ArenaDtor(void* object);
+ inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
+ public:
+
+ static const ClassData _class_data_;
+ const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;
+
+ ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;
+
+ // nested types ----------------------------------------------------
+
+ // accessors -------------------------------------------------------
+
+ enum : int {
+ kOptionsFieldNumber = 3,
+ kStartFieldNumber = 1,
+ kEndFieldNumber = 2,
+ };
+ // optional .google.protobuf.ExtensionRangeOptions options = 3;
+ bool has_options() const;
+ private:
+ bool _internal_has_options() const;
+ public:
+ void clear_options();
+ const ::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions& options() const;
+ PROTOBUF_NODISCARD ::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions* release_options();
+ ::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions* mutable_options();
+ void set_allocated_options(::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions* options);
+ private:
+ const ::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions& _internal_options() const;
+ ::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions* _internal_mutable_options();
+ public:
+ void unsafe_arena_set_allocated_options(
+ ::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions* options);
+ ::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions* unsafe_arena_release_options();
+
+ // optional int32 start = 1;
+ bool has_start() const;
+ private:
+ bool _internal_has_start() const;
+ public:
+ void clear_start();
+ 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_;
+ ::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_;
+ friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
+};
+// -------------------------------------------------------------------
+
+class PROTOBUF_EXPORT DescriptorProto_ReservedRange final :
+ public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.DescriptorProto.ReservedRange) */ {
+ public:
+ inline DescriptorProto_ReservedRange() : DescriptorProto_ReservedRange(nullptr) {}
+ ~DescriptorProto_ReservedRange() override;
+ explicit constexpr DescriptorProto_ReservedRange(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
+
+ DescriptorProto_ReservedRange(const DescriptorProto_ReservedRange& from);
+ DescriptorProto_ReservedRange(DescriptorProto_ReservedRange&& from) noexcept
+ : DescriptorProto_ReservedRange() {
+ *this = ::std::move(from);
+ }
+
+ inline DescriptorProto_ReservedRange& operator=(const DescriptorProto_ReservedRange& from) {
+ CopyFrom(from);
+ return *this;
+ }
+ inline DescriptorProto_ReservedRange& operator=(DescriptorProto_ReservedRange&& from) noexcept {
+ if (this == &from) return *this;
+ if (GetOwningArena() == from.GetOwningArena()
+ #ifdef PROTOBUF_FORCE_COPY_IN_MOVE
+ && GetOwningArena() != nullptr
+ #endif // !PROTOBUF_FORCE_COPY_IN_MOVE
+ ) {
+ InternalSwap(&from);
+ } else {
+ CopyFrom(from);
+ }
+ return *this;
+ }
+
+ inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const {
+ return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance);
+ }
+ inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() {
+ return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+ }
+
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
+ return GetDescriptor();
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
+ return default_instance().GetMetadata().descriptor;
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
+ return default_instance().GetMetadata().reflection;
+ }
+ static const DescriptorProto_ReservedRange& default_instance() {
+ return *internal_default_instance();
+ }
+ static inline const DescriptorProto_ReservedRange* internal_default_instance() {
+ return reinterpret_cast<const DescriptorProto_ReservedRange*>(
+ &_DescriptorProto_ReservedRange_default_instance_);
+ }
+ static constexpr int kIndexInFileMessages =
+ 3;
+
+ friend void swap(DescriptorProto_ReservedRange& a, DescriptorProto_ReservedRange& b) {
+ a.Swap(&b);
+ }
+ inline void Swap(DescriptorProto_ReservedRange* other) {
+ if (other == this) return;
+ #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() != nullptr &&
+ GetOwningArena() == other->GetOwningArena()) {
+ #else // PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() == other->GetOwningArena()) {
+ #endif // !PROTOBUF_FORCE_COPY_IN_SWAP
+ InternalSwap(other);
+ } else {
+ ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
+ }
+ }
+ void UnsafeArenaSwap(DescriptorProto_ReservedRange* other) {
+ if (other == this) return;
+ GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena());
+ InternalSwap(other);
+ }
+
+ // implements Message ----------------------------------------------
+
+ DescriptorProto_ReservedRange* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
+ return CreateMaybeMessage<DescriptorProto_ReservedRange>(arena);
+ }
+ using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
+ void CopyFrom(const DescriptorProto_ReservedRange& from);
+ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
+ void MergeFrom(const DescriptorProto_ReservedRange& from);
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from);
+ public:
+ PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+ bool IsInitialized() const final;
+
+ size_t ByteSizeLong() const final;
+ const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
+ uint8_t* _InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
+ int GetCachedSize() const final { return _cached_size_.Get(); }
+
+ private:
+ void SharedCtor();
+ void SharedDtor();
+ void SetCachedSize(int size) const final;
+ void InternalSwap(DescriptorProto_ReservedRange* other);
+
+ private:
+ friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
+ static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
+ return "google.protobuf.DescriptorProto.ReservedRange";
+ }
+ protected:
+ explicit DescriptorProto_ReservedRange(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned = false);
+ private:
+ static void ArenaDtor(void* object);
+ inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
+ public:
+
+ static const ClassData _class_data_;
+ const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;
+
+ ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;
+
+ // nested types ----------------------------------------------------
+
+ // accessors -------------------------------------------------------
+
+ enum : int {
+ kStartFieldNumber = 1,
+ kEndFieldNumber = 2,
+ };
+ // optional int32 start = 1;
+ bool has_start() const;
+ private:
+ bool _internal_has_start() const;
+ public:
+ void clear_start();
+ 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_;
+ ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_;
+ mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
+ int32_t start_;
+ int32_t end_;
+ friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
+};
+// -------------------------------------------------------------------
+
+class PROTOBUF_EXPORT DescriptorProto final :
+ public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.DescriptorProto) */ {
+ public:
+ inline DescriptorProto() : DescriptorProto(nullptr) {}
+ ~DescriptorProto() override;
+ explicit constexpr DescriptorProto(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
+
+ DescriptorProto(const DescriptorProto& from);
+ DescriptorProto(DescriptorProto&& from) noexcept
+ : DescriptorProto() {
+ *this = ::std::move(from);
+ }
+
+ inline DescriptorProto& operator=(const DescriptorProto& from) {
+ CopyFrom(from);
+ return *this;
+ }
+ inline DescriptorProto& operator=(DescriptorProto&& from) noexcept {
+ if (this == &from) return *this;
+ if (GetOwningArena() == from.GetOwningArena()
+ #ifdef PROTOBUF_FORCE_COPY_IN_MOVE
+ && GetOwningArena() != nullptr
+ #endif // !PROTOBUF_FORCE_COPY_IN_MOVE
+ ) {
+ InternalSwap(&from);
+ } else {
+ CopyFrom(from);
+ }
+ return *this;
+ }
+
+ inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const {
+ return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance);
+ }
+ inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() {
+ return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+ }
+
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
+ return GetDescriptor();
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
+ return default_instance().GetMetadata().descriptor;
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
+ return default_instance().GetMetadata().reflection;
+ }
+ static const DescriptorProto& default_instance() {
+ return *internal_default_instance();
+ }
+ static inline const DescriptorProto* internal_default_instance() {
+ return reinterpret_cast<const DescriptorProto*>(
+ &_DescriptorProto_default_instance_);
+ }
+ static constexpr int kIndexInFileMessages =
+ 4;
+
+ friend void swap(DescriptorProto& a, DescriptorProto& b) {
+ a.Swap(&b);
+ }
+ inline void Swap(DescriptorProto* other) {
+ if (other == this) return;
+ #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() != nullptr &&
+ GetOwningArena() == other->GetOwningArena()) {
+ #else // PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() == other->GetOwningArena()) {
+ #endif // !PROTOBUF_FORCE_COPY_IN_SWAP
+ InternalSwap(other);
+ } else {
+ ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
+ }
+ }
+ void UnsafeArenaSwap(DescriptorProto* other) {
+ if (other == this) return;
+ GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena());
+ InternalSwap(other);
+ }
+
+ // implements Message ----------------------------------------------
+
+ DescriptorProto* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
+ return CreateMaybeMessage<DescriptorProto>(arena);
+ }
+ using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
+ void CopyFrom(const DescriptorProto& from);
+ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
+ void MergeFrom(const DescriptorProto& from);
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from);
+ public:
+ PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+ bool IsInitialized() const final;
+
+ size_t ByteSizeLong() const final;
+ const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
+ uint8_t* _InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
+ int GetCachedSize() const final { return _cached_size_.Get(); }
+
+ private:
+ void SharedCtor();
+ void SharedDtor();
+ void SetCachedSize(int size) const final;
+ void InternalSwap(DescriptorProto* other);
+
+ private:
+ friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
+ static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
+ return "google.protobuf.DescriptorProto";
+ }
+ protected:
+ explicit DescriptorProto(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned = false);
+ private:
+ static void ArenaDtor(void* object);
+ inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
+ public:
+
+ static const ClassData _class_data_;
+ const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;
+
+ ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;
+
+ // nested types ----------------------------------------------------
+
+ typedef DescriptorProto_ExtensionRange ExtensionRange;
+ typedef DescriptorProto_ReservedRange ReservedRange;
+
+ // accessors -------------------------------------------------------
+
+ enum : int {
+ kFieldFieldNumber = 2,
+ kNestedTypeFieldNumber = 3,
+ kEnumTypeFieldNumber = 4,
+ kExtensionRangeFieldNumber = 5,
+ kExtensionFieldNumber = 6,
+ kOneofDeclFieldNumber = 8,
+ kReservedRangeFieldNumber = 9,
+ kReservedNameFieldNumber = 10,
+ kNameFieldNumber = 1,
+ kOptionsFieldNumber = 7,
+ };
+ // repeated .google.protobuf.FieldDescriptorProto field = 2;
+ int field_size() const;
+ private:
+ int _internal_field_size() const;
+ public:
+ void clear_field();
+ ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto* mutable_field(int index);
+ ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto >*
+ mutable_field();
+ private:
+ const ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto& _internal_field(int index) const;
+ ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto* _internal_add_field();
+ public:
+ const ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto& field(int index) const;
+ ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto* add_field();
+ const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto >&
+ field() const;
+
+ // repeated .google.protobuf.DescriptorProto nested_type = 3;
+ int nested_type_size() const;
+ private:
+ int _internal_nested_type_size() const;
+ public:
+ void clear_nested_type();
+ ::PROTOBUF_NAMESPACE_ID::DescriptorProto* mutable_nested_type(int index);
+ ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::DescriptorProto >*
+ mutable_nested_type();
+ private:
+ const ::PROTOBUF_NAMESPACE_ID::DescriptorProto& _internal_nested_type(int index) const;
+ ::PROTOBUF_NAMESPACE_ID::DescriptorProto* _internal_add_nested_type();
+ public:
+ const ::PROTOBUF_NAMESPACE_ID::DescriptorProto& nested_type(int index) const;
+ ::PROTOBUF_NAMESPACE_ID::DescriptorProto* add_nested_type();
+ const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::DescriptorProto >&
+ nested_type() const;
+
+ // repeated .google.protobuf.EnumDescriptorProto enum_type = 4;
+ int enum_type_size() const;
+ private:
+ int _internal_enum_type_size() const;
+ public:
+ void clear_enum_type();
+ ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto* mutable_enum_type(int index);
+ ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto >*
+ mutable_enum_type();
+ private:
+ const ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto& _internal_enum_type(int index) const;
+ ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto* _internal_add_enum_type();
+ public:
+ const ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto& enum_type(int index) const;
+ ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto* add_enum_type();
+ const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto >&
+ enum_type() const;
+
+ // repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5;
+ int extension_range_size() const;
+ private:
+ int _internal_extension_range_size() const;
+ public:
+ void clear_extension_range();
+ ::PROTOBUF_NAMESPACE_ID::DescriptorProto_ExtensionRange* mutable_extension_range(int index);
+ ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::DescriptorProto_ExtensionRange >*
+ mutable_extension_range();
+ private:
+ const ::PROTOBUF_NAMESPACE_ID::DescriptorProto_ExtensionRange& _internal_extension_range(int index) const;
+ ::PROTOBUF_NAMESPACE_ID::DescriptorProto_ExtensionRange* _internal_add_extension_range();
+ public:
+ const ::PROTOBUF_NAMESPACE_ID::DescriptorProto_ExtensionRange& extension_range(int index) const;
+ ::PROTOBUF_NAMESPACE_ID::DescriptorProto_ExtensionRange* add_extension_range();
+ const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::DescriptorProto_ExtensionRange >&
+ extension_range() const;
+
+ // repeated .google.protobuf.FieldDescriptorProto extension = 6;
+ int extension_size() const;
+ private:
+ int _internal_extension_size() const;
+ public:
+ void clear_extension();
+ ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto* mutable_extension(int index);
+ ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto >*
+ mutable_extension();
+ private:
+ const ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto& _internal_extension(int index) const;
+ ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto* _internal_add_extension();
+ public:
+ const ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto& extension(int index) const;
+ ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto* add_extension();
+ const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto >&
+ extension() const;
+
+ // repeated .google.protobuf.OneofDescriptorProto oneof_decl = 8;
+ int oneof_decl_size() const;
+ private:
+ int _internal_oneof_decl_size() const;
+ public:
+ void clear_oneof_decl();
+ ::PROTOBUF_NAMESPACE_ID::OneofDescriptorProto* mutable_oneof_decl(int index);
+ ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::OneofDescriptorProto >*
+ mutable_oneof_decl();
+ private:
+ const ::PROTOBUF_NAMESPACE_ID::OneofDescriptorProto& _internal_oneof_decl(int index) const;
+ ::PROTOBUF_NAMESPACE_ID::OneofDescriptorProto* _internal_add_oneof_decl();
+ public:
+ const ::PROTOBUF_NAMESPACE_ID::OneofDescriptorProto& oneof_decl(int index) const;
+ ::PROTOBUF_NAMESPACE_ID::OneofDescriptorProto* add_oneof_decl();
+ const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::OneofDescriptorProto >&
+ oneof_decl() const;
+
+ // repeated .google.protobuf.DescriptorProto.ReservedRange reserved_range = 9;
+ int reserved_range_size() const;
+ private:
+ int _internal_reserved_range_size() const;
+ public:
+ void clear_reserved_range();
+ ::PROTOBUF_NAMESPACE_ID::DescriptorProto_ReservedRange* mutable_reserved_range(int index);
+ ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::DescriptorProto_ReservedRange >*
+ mutable_reserved_range();
+ private:
+ const ::PROTOBUF_NAMESPACE_ID::DescriptorProto_ReservedRange& _internal_reserved_range(int index) const;
+ ::PROTOBUF_NAMESPACE_ID::DescriptorProto_ReservedRange* _internal_add_reserved_range();
+ public:
+ const ::PROTOBUF_NAMESPACE_ID::DescriptorProto_ReservedRange& reserved_range(int index) const;
+ ::PROTOBUF_NAMESPACE_ID::DescriptorProto_ReservedRange* add_reserved_range();
+ const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::DescriptorProto_ReservedRange >&
+ reserved_range() const;
+
+ // repeated string reserved_name = 10;
+ int reserved_name_size() const;
+ private:
+ int _internal_reserved_name_size() const;
+ public:
+ void clear_reserved_name();
+ const 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_;
+ ::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_;
+ friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
+};
+// -------------------------------------------------------------------
+
+class PROTOBUF_EXPORT ExtensionRangeOptions final :
+ public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.ExtensionRangeOptions) */ {
+ public:
+ inline ExtensionRangeOptions() : ExtensionRangeOptions(nullptr) {}
+ ~ExtensionRangeOptions() override;
+ explicit constexpr ExtensionRangeOptions(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
+
+ ExtensionRangeOptions(const ExtensionRangeOptions& from);
+ ExtensionRangeOptions(ExtensionRangeOptions&& from) noexcept
+ : ExtensionRangeOptions() {
+ *this = ::std::move(from);
+ }
+
+ inline ExtensionRangeOptions& operator=(const ExtensionRangeOptions& from) {
+ CopyFrom(from);
+ return *this;
+ }
+ inline ExtensionRangeOptions& operator=(ExtensionRangeOptions&& from) noexcept {
+ if (this == &from) return *this;
+ if (GetOwningArena() == from.GetOwningArena()
+ #ifdef PROTOBUF_FORCE_COPY_IN_MOVE
+ && GetOwningArena() != nullptr
+ #endif // !PROTOBUF_FORCE_COPY_IN_MOVE
+ ) {
+ InternalSwap(&from);
+ } else {
+ CopyFrom(from);
+ }
+ return *this;
+ }
+
+ inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const {
+ return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance);
+ }
+ inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() {
+ return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+ }
+
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
+ return GetDescriptor();
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
+ return default_instance().GetMetadata().descriptor;
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
+ return default_instance().GetMetadata().reflection;
+ }
+ static const ExtensionRangeOptions& default_instance() {
+ return *internal_default_instance();
+ }
+ static inline const ExtensionRangeOptions* internal_default_instance() {
+ return reinterpret_cast<const ExtensionRangeOptions*>(
+ &_ExtensionRangeOptions_default_instance_);
+ }
+ static constexpr int kIndexInFileMessages =
+ 5;
+
+ friend void swap(ExtensionRangeOptions& a, ExtensionRangeOptions& b) {
+ a.Swap(&b);
+ }
+ inline void Swap(ExtensionRangeOptions* other) {
+ if (other == this) return;
+ #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() != nullptr &&
+ GetOwningArena() == other->GetOwningArena()) {
+ #else // PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() == other->GetOwningArena()) {
+ #endif // !PROTOBUF_FORCE_COPY_IN_SWAP
+ InternalSwap(other);
+ } else {
+ ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
+ }
+ }
+ void UnsafeArenaSwap(ExtensionRangeOptions* other) {
+ if (other == this) return;
+ GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena());
+ InternalSwap(other);
+ }
+
+ // implements Message ----------------------------------------------
+
+ ExtensionRangeOptions* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
+ return CreateMaybeMessage<ExtensionRangeOptions>(arena);
+ }
+ using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
+ void CopyFrom(const ExtensionRangeOptions& from);
+ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
+ void MergeFrom(const ExtensionRangeOptions& from);
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from);
+ public:
+ PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+ bool IsInitialized() const final;
+
+ size_t ByteSizeLong() const final;
+ const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
+ uint8_t* _InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
+ int GetCachedSize() const final { return _cached_size_.Get(); }
+
+ private:
+ void SharedCtor();
+ void SharedDtor();
+ void SetCachedSize(int size) const final;
+ void InternalSwap(ExtensionRangeOptions* other);
+
+ private:
+ friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
+ static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
+ return "google.protobuf.ExtensionRangeOptions";
+ }
+ protected:
+ explicit ExtensionRangeOptions(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned = false);
+ private:
+ static void ArenaDtor(void* object);
+ inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
+ public:
+
+ static const ClassData _class_data_;
+ const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;
+
+ ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;
+
+ // nested types ----------------------------------------------------
+
+ // accessors -------------------------------------------------------
+
+ enum : int {
+ kUninterpretedOptionFieldNumber = 999,
+ };
+ // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+ int uninterpreted_option_size() const;
+ private:
+ int _internal_uninterpreted_option_size() const;
+ public:
+ void clear_uninterpreted_option();
+ ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* mutable_uninterpreted_option(int index);
+ ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption >*
+ mutable_uninterpreted_option();
+ private:
+ const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption& _internal_uninterpreted_option(int index) const;
+ ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* _internal_add_uninterpreted_option();
+ public:
+ const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption& uninterpreted_option(int index) const;
+ ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* add_uninterpreted_option();
+ const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption >&
+ uninterpreted_option() const;
+
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline bool HasExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ ExtensionRangeOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const {
+
+ return _extensions_.Has(id.number());
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline void ClearExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ ExtensionRangeOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {
+ _extensions_.ClearExtension(id.number());
+
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline int ExtensionSize(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ ExtensionRangeOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const {
+
+ return _extensions_.ExtensionSize(id.number());
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline typename _proto_TypeTraits::Singular::ConstType GetExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ ExtensionRangeOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const {
+
+ return _proto_TypeTraits::Get(id.number(), _extensions_,
+ id.default_value());
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline typename _proto_TypeTraits::Singular::MutableType MutableExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ ExtensionRangeOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {
+
+ return _proto_TypeTraits::Mutable(id.number(), _field_type,
+ &_extensions_);
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline void SetExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ ExtensionRangeOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
+ typename _proto_TypeTraits::Singular::ConstType value) {
+ _proto_TypeTraits::Set(id.number(), _field_type, value, &_extensions_);
+
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline void SetAllocatedExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ ExtensionRangeOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
+ typename _proto_TypeTraits::Singular::MutableType value) {
+ _proto_TypeTraits::SetAllocated(id.number(), _field_type, value,
+ &_extensions_);
+
+ }
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline void UnsafeArenaSetAllocatedExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ ExtensionRangeOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
+ typename _proto_TypeTraits::Singular::MutableType value) {
+ _proto_TypeTraits::UnsafeArenaSetAllocated(id.number(), _field_type,
+ value, &_extensions_);
+
+ }
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ PROTOBUF_NODISCARD inline
+ typename _proto_TypeTraits::Singular::MutableType
+ ReleaseExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ ExtensionRangeOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {
+
+ return _proto_TypeTraits::Release(id.number(), _field_type,
+ &_extensions_);
+ }
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline typename _proto_TypeTraits::Singular::MutableType
+ UnsafeArenaReleaseExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ ExtensionRangeOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {
+
+ return _proto_TypeTraits::UnsafeArenaRelease(id.number(), _field_type,
+ &_extensions_);
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline typename _proto_TypeTraits::Repeated::ConstType GetExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ ExtensionRangeOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
+ int index) const {
+
+ return _proto_TypeTraits::Get(id.number(), _extensions_, index);
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline typename _proto_TypeTraits::Repeated::MutableType MutableExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ ExtensionRangeOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
+ int index) {
+
+ return _proto_TypeTraits::Mutable(id.number(), index, &_extensions_);
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline void SetExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ ExtensionRangeOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
+ int index, typename _proto_TypeTraits::Repeated::ConstType value) {
+ _proto_TypeTraits::Set(id.number(), index, value, &_extensions_);
+
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline typename _proto_TypeTraits::Repeated::MutableType AddExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ ExtensionRangeOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {
+ typename _proto_TypeTraits::Repeated::MutableType to_add =
+ _proto_TypeTraits::Add(id.number(), _field_type, &_extensions_);
+
+ return to_add;
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline void AddExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ ExtensionRangeOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
+ typename _proto_TypeTraits::Repeated::ConstType value) {
+ _proto_TypeTraits::Add(id.number(), _field_type, _is_packed, value,
+ &_extensions_);
+
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline const typename _proto_TypeTraits::Repeated::RepeatedFieldType&
+ GetRepeatedExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ ExtensionRangeOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const {
+
+ return _proto_TypeTraits::GetRepeated(id.number(), _extensions_);
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline typename _proto_TypeTraits::Repeated::RepeatedFieldType*
+ MutableRepeatedExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ ExtensionRangeOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {
+
+ return _proto_TypeTraits::MutableRepeated(id.number(), _field_type,
+ _is_packed, &_extensions_);
+ }
+
+ // @@protoc_insertion_point(class_scope:google.protobuf.ExtensionRangeOptions)
+ private:
+ class _Internal;
+
+ ::PROTOBUF_NAMESPACE_ID::internal::ExtensionSet _extensions_;
+
+ template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
+ typedef void InternalArenaConstructable_;
+ typedef void DestructorSkippable_;
+ ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption > uninterpreted_option_;
+ mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
+ friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
+};
+// -------------------------------------------------------------------
+
+class PROTOBUF_EXPORT FieldDescriptorProto final :
+ public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.FieldDescriptorProto) */ {
+ public:
+ inline FieldDescriptorProto() : FieldDescriptorProto(nullptr) {}
+ ~FieldDescriptorProto() override;
+ explicit constexpr FieldDescriptorProto(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
+
+ FieldDescriptorProto(const FieldDescriptorProto& from);
+ FieldDescriptorProto(FieldDescriptorProto&& from) noexcept
+ : FieldDescriptorProto() {
+ *this = ::std::move(from);
+ }
+
+ inline FieldDescriptorProto& operator=(const FieldDescriptorProto& from) {
+ CopyFrom(from);
+ return *this;
+ }
+ inline FieldDescriptorProto& operator=(FieldDescriptorProto&& from) noexcept {
+ if (this == &from) return *this;
+ if (GetOwningArena() == from.GetOwningArena()
+ #ifdef PROTOBUF_FORCE_COPY_IN_MOVE
+ && GetOwningArena() != nullptr
+ #endif // !PROTOBUF_FORCE_COPY_IN_MOVE
+ ) {
+ InternalSwap(&from);
+ } else {
+ CopyFrom(from);
+ }
+ return *this;
+ }
+
+ inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const {
+ return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance);
+ }
+ inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() {
+ return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+ }
+
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
+ return GetDescriptor();
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
+ return default_instance().GetMetadata().descriptor;
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
+ return default_instance().GetMetadata().reflection;
+ }
+ static const FieldDescriptorProto& default_instance() {
+ return *internal_default_instance();
+ }
+ static inline const FieldDescriptorProto* internal_default_instance() {
+ return reinterpret_cast<const FieldDescriptorProto*>(
+ &_FieldDescriptorProto_default_instance_);
+ }
+ static constexpr int kIndexInFileMessages =
+ 6;
+
+ friend void swap(FieldDescriptorProto& a, FieldDescriptorProto& b) {
+ a.Swap(&b);
+ }
+ inline void Swap(FieldDescriptorProto* other) {
+ if (other == this) return;
+ #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() != nullptr &&
+ GetOwningArena() == other->GetOwningArena()) {
+ #else // PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() == other->GetOwningArena()) {
+ #endif // !PROTOBUF_FORCE_COPY_IN_SWAP
+ InternalSwap(other);
+ } else {
+ ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
+ }
+ }
+ void UnsafeArenaSwap(FieldDescriptorProto* other) {
+ if (other == this) return;
+ GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena());
+ InternalSwap(other);
+ }
+
+ // implements Message ----------------------------------------------
+
+ FieldDescriptorProto* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
+ return CreateMaybeMessage<FieldDescriptorProto>(arena);
+ }
+ using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
+ void CopyFrom(const FieldDescriptorProto& from);
+ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
+ void MergeFrom(const FieldDescriptorProto& from);
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from);
+ public:
+ PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+ bool IsInitialized() const final;
+
+ size_t ByteSizeLong() const final;
+ const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
+ uint8_t* _InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
+ int GetCachedSize() const final { return _cached_size_.Get(); }
+
+ private:
+ void SharedCtor();
+ void SharedDtor();
+ void SetCachedSize(int size) const final;
+ void InternalSwap(FieldDescriptorProto* other);
+
+ private:
+ friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
+ static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
+ return "google.protobuf.FieldDescriptorProto";
+ }
+ protected:
+ explicit FieldDescriptorProto(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned = false);
+ private:
+ static void ArenaDtor(void* object);
+ inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
+ public:
+
+ static const ClassData _class_data_;
+ const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;
+
+ ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;
+
+ // nested types ----------------------------------------------------
+
+ typedef FieldDescriptorProto_Type Type;
+ static constexpr Type TYPE_DOUBLE =
+ FieldDescriptorProto_Type_TYPE_DOUBLE;
+ static constexpr Type TYPE_FLOAT =
+ FieldDescriptorProto_Type_TYPE_FLOAT;
+ static constexpr Type TYPE_INT64 =
+ FieldDescriptorProto_Type_TYPE_INT64;
+ static constexpr Type TYPE_UINT64 =
+ FieldDescriptorProto_Type_TYPE_UINT64;
+ static constexpr Type TYPE_INT32 =
+ FieldDescriptorProto_Type_TYPE_INT32;
+ static constexpr Type TYPE_FIXED64 =
+ FieldDescriptorProto_Type_TYPE_FIXED64;
+ static constexpr Type TYPE_FIXED32 =
+ FieldDescriptorProto_Type_TYPE_FIXED32;
+ static constexpr Type TYPE_BOOL =
+ FieldDescriptorProto_Type_TYPE_BOOL;
+ static constexpr Type TYPE_STRING =
+ FieldDescriptorProto_Type_TYPE_STRING;
+ static constexpr Type TYPE_GROUP =
+ FieldDescriptorProto_Type_TYPE_GROUP;
+ static constexpr Type TYPE_MESSAGE =
+ FieldDescriptorProto_Type_TYPE_MESSAGE;
+ static constexpr Type TYPE_BYTES =
+ FieldDescriptorProto_Type_TYPE_BYTES;
+ static constexpr Type TYPE_UINT32 =
+ FieldDescriptorProto_Type_TYPE_UINT32;
+ static constexpr Type TYPE_ENUM =
+ FieldDescriptorProto_Type_TYPE_ENUM;
+ static constexpr Type TYPE_SFIXED32 =
+ FieldDescriptorProto_Type_TYPE_SFIXED32;
+ static constexpr Type TYPE_SFIXED64 =
+ FieldDescriptorProto_Type_TYPE_SFIXED64;
+ static constexpr Type TYPE_SINT32 =
+ FieldDescriptorProto_Type_TYPE_SINT32;
+ static constexpr Type TYPE_SINT64 =
+ FieldDescriptorProto_Type_TYPE_SINT64;
+ static inline bool Type_IsValid(int value) {
+ return FieldDescriptorProto_Type_IsValid(value);
+ }
+ static constexpr Type Type_MIN =
+ FieldDescriptorProto_Type_Type_MIN;
+ static constexpr Type Type_MAX =
+ FieldDescriptorProto_Type_Type_MAX;
+ static constexpr int Type_ARRAYSIZE =
+ FieldDescriptorProto_Type_Type_ARRAYSIZE;
+ static inline const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor*
+ Type_descriptor() {
+ return FieldDescriptorProto_Type_descriptor();
+ }
+ template<typename T>
+ static inline const 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_;
+ ::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_;
+ friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
+};
+// -------------------------------------------------------------------
+
+class PROTOBUF_EXPORT OneofDescriptorProto final :
+ public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.OneofDescriptorProto) */ {
+ public:
+ inline OneofDescriptorProto() : OneofDescriptorProto(nullptr) {}
+ ~OneofDescriptorProto() override;
+ explicit constexpr OneofDescriptorProto(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
+
+ OneofDescriptorProto(const OneofDescriptorProto& from);
+ OneofDescriptorProto(OneofDescriptorProto&& from) noexcept
+ : OneofDescriptorProto() {
+ *this = ::std::move(from);
+ }
+
+ inline OneofDescriptorProto& operator=(const OneofDescriptorProto& from) {
+ CopyFrom(from);
+ return *this;
+ }
+ inline OneofDescriptorProto& operator=(OneofDescriptorProto&& from) noexcept {
+ if (this == &from) return *this;
+ if (GetOwningArena() == from.GetOwningArena()
+ #ifdef PROTOBUF_FORCE_COPY_IN_MOVE
+ && GetOwningArena() != nullptr
+ #endif // !PROTOBUF_FORCE_COPY_IN_MOVE
+ ) {
+ InternalSwap(&from);
+ } else {
+ CopyFrom(from);
+ }
+ return *this;
+ }
+
+ inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const {
+ return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance);
+ }
+ inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() {
+ return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+ }
+
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
+ return GetDescriptor();
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
+ return default_instance().GetMetadata().descriptor;
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
+ return default_instance().GetMetadata().reflection;
+ }
+ static const OneofDescriptorProto& default_instance() {
+ return *internal_default_instance();
+ }
+ static inline const OneofDescriptorProto* internal_default_instance() {
+ return reinterpret_cast<const OneofDescriptorProto*>(
+ &_OneofDescriptorProto_default_instance_);
+ }
+ static constexpr int kIndexInFileMessages =
+ 7;
+
+ friend void swap(OneofDescriptorProto& a, OneofDescriptorProto& b) {
+ a.Swap(&b);
+ }
+ inline void Swap(OneofDescriptorProto* other) {
+ if (other == this) return;
+ #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() != nullptr &&
+ GetOwningArena() == other->GetOwningArena()) {
+ #else // PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() == other->GetOwningArena()) {
+ #endif // !PROTOBUF_FORCE_COPY_IN_SWAP
+ InternalSwap(other);
+ } else {
+ ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
+ }
+ }
+ void UnsafeArenaSwap(OneofDescriptorProto* other) {
+ if (other == this) return;
+ GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena());
+ InternalSwap(other);
+ }
+
+ // implements Message ----------------------------------------------
+
+ OneofDescriptorProto* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
+ return CreateMaybeMessage<OneofDescriptorProto>(arena);
+ }
+ using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
+ void CopyFrom(const OneofDescriptorProto& from);
+ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
+ void MergeFrom(const OneofDescriptorProto& from);
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from);
+ public:
+ PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+ bool IsInitialized() const final;
+
+ size_t ByteSizeLong() const final;
+ const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
+ uint8_t* _InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
+ int GetCachedSize() const final { return _cached_size_.Get(); }
+
+ private:
+ void SharedCtor();
+ void SharedDtor();
+ void SetCachedSize(int size) const final;
+ void InternalSwap(OneofDescriptorProto* other);
+
+ private:
+ friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
+ static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
+ return "google.protobuf.OneofDescriptorProto";
+ }
+ protected:
+ explicit OneofDescriptorProto(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned = false);
+ private:
+ static void ArenaDtor(void* object);
+ inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
+ public:
+
+ static const ClassData _class_data_;
+ const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;
+
+ ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;
+
+ // nested types ----------------------------------------------------
+
+ // accessors -------------------------------------------------------
+
+ enum : int {
+ kNameFieldNumber = 1,
+ kOptionsFieldNumber = 2,
+ };
+ // optional string name = 1;
+ bool has_name() const;
+ private:
+ bool _internal_has_name() const;
+ public:
+ void clear_name();
+ const 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_;
+ ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_;
+ mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr name_;
+ ::PROTOBUF_NAMESPACE_ID::OneofOptions* options_;
+ friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
+};
+// -------------------------------------------------------------------
+
+class PROTOBUF_EXPORT EnumDescriptorProto_EnumReservedRange final :
+ public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.EnumDescriptorProto.EnumReservedRange) */ {
+ public:
+ inline EnumDescriptorProto_EnumReservedRange() : EnumDescriptorProto_EnumReservedRange(nullptr) {}
+ ~EnumDescriptorProto_EnumReservedRange() override;
+ explicit constexpr EnumDescriptorProto_EnumReservedRange(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
+
+ EnumDescriptorProto_EnumReservedRange(const EnumDescriptorProto_EnumReservedRange& from);
+ EnumDescriptorProto_EnumReservedRange(EnumDescriptorProto_EnumReservedRange&& from) noexcept
+ : EnumDescriptorProto_EnumReservedRange() {
+ *this = ::std::move(from);
+ }
+
+ inline EnumDescriptorProto_EnumReservedRange& operator=(const EnumDescriptorProto_EnumReservedRange& from) {
+ CopyFrom(from);
+ return *this;
+ }
+ inline EnumDescriptorProto_EnumReservedRange& operator=(EnumDescriptorProto_EnumReservedRange&& from) noexcept {
+ if (this == &from) return *this;
+ if (GetOwningArena() == from.GetOwningArena()
+ #ifdef PROTOBUF_FORCE_COPY_IN_MOVE
+ && GetOwningArena() != nullptr
+ #endif // !PROTOBUF_FORCE_COPY_IN_MOVE
+ ) {
+ InternalSwap(&from);
+ } else {
+ CopyFrom(from);
+ }
+ return *this;
+ }
+
+ inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const {
+ return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance);
+ }
+ inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() {
+ return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+ }
+
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
+ return GetDescriptor();
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
+ return default_instance().GetMetadata().descriptor;
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
+ return default_instance().GetMetadata().reflection;
+ }
+ static const EnumDescriptorProto_EnumReservedRange& default_instance() {
+ return *internal_default_instance();
+ }
+ static inline const EnumDescriptorProto_EnumReservedRange* internal_default_instance() {
+ return reinterpret_cast<const EnumDescriptorProto_EnumReservedRange*>(
+ &_EnumDescriptorProto_EnumReservedRange_default_instance_);
+ }
+ static constexpr int kIndexInFileMessages =
+ 8;
+
+ friend void swap(EnumDescriptorProto_EnumReservedRange& a, EnumDescriptorProto_EnumReservedRange& b) {
+ a.Swap(&b);
+ }
+ inline void Swap(EnumDescriptorProto_EnumReservedRange* other) {
+ if (other == this) return;
+ #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() != nullptr &&
+ GetOwningArena() == other->GetOwningArena()) {
+ #else // PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() == other->GetOwningArena()) {
+ #endif // !PROTOBUF_FORCE_COPY_IN_SWAP
+ InternalSwap(other);
+ } else {
+ ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
+ }
+ }
+ void UnsafeArenaSwap(EnumDescriptorProto_EnumReservedRange* other) {
+ if (other == this) return;
+ GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena());
+ InternalSwap(other);
+ }
+
+ // implements Message ----------------------------------------------
+
+ EnumDescriptorProto_EnumReservedRange* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
+ return CreateMaybeMessage<EnumDescriptorProto_EnumReservedRange>(arena);
+ }
+ using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
+ void CopyFrom(const EnumDescriptorProto_EnumReservedRange& from);
+ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
+ void MergeFrom(const EnumDescriptorProto_EnumReservedRange& from);
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from);
+ public:
+ PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+ bool IsInitialized() const final;
+
+ size_t ByteSizeLong() const final;
+ const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
+ uint8_t* _InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
+ int GetCachedSize() const final { return _cached_size_.Get(); }
+
+ private:
+ void SharedCtor();
+ void SharedDtor();
+ void SetCachedSize(int size) const final;
+ void InternalSwap(EnumDescriptorProto_EnumReservedRange* other);
+
+ private:
+ friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
+ static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
+ return "google.protobuf.EnumDescriptorProto.EnumReservedRange";
+ }
+ protected:
+ explicit EnumDescriptorProto_EnumReservedRange(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned = false);
+ private:
+ static void ArenaDtor(void* object);
+ inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
+ public:
+
+ static const ClassData _class_data_;
+ const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;
+
+ ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;
+
+ // nested types ----------------------------------------------------
+
+ // accessors -------------------------------------------------------
+
+ enum : int {
+ kStartFieldNumber = 1,
+ kEndFieldNumber = 2,
+ };
+ // optional int32 start = 1;
+ bool has_start() const;
+ private:
+ bool _internal_has_start() const;
+ public:
+ void clear_start();
+ 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_;
+ ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_;
+ mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
+ int32_t start_;
+ int32_t end_;
+ friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
+};
+// -------------------------------------------------------------------
+
+class PROTOBUF_EXPORT EnumDescriptorProto final :
+ public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.EnumDescriptorProto) */ {
+ public:
+ inline EnumDescriptorProto() : EnumDescriptorProto(nullptr) {}
+ ~EnumDescriptorProto() override;
+ explicit constexpr EnumDescriptorProto(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
+
+ EnumDescriptorProto(const EnumDescriptorProto& from);
+ EnumDescriptorProto(EnumDescriptorProto&& from) noexcept
+ : EnumDescriptorProto() {
+ *this = ::std::move(from);
+ }
+
+ inline EnumDescriptorProto& operator=(const EnumDescriptorProto& from) {
+ CopyFrom(from);
+ return *this;
+ }
+ inline EnumDescriptorProto& operator=(EnumDescriptorProto&& from) noexcept {
+ if (this == &from) return *this;
+ if (GetOwningArena() == from.GetOwningArena()
+ #ifdef PROTOBUF_FORCE_COPY_IN_MOVE
+ && GetOwningArena() != nullptr
+ #endif // !PROTOBUF_FORCE_COPY_IN_MOVE
+ ) {
+ InternalSwap(&from);
+ } else {
+ CopyFrom(from);
+ }
+ return *this;
+ }
+
+ inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const {
+ return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance);
+ }
+ inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() {
+ return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+ }
+
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
+ return GetDescriptor();
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
+ return default_instance().GetMetadata().descriptor;
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
+ return default_instance().GetMetadata().reflection;
+ }
+ static const EnumDescriptorProto& default_instance() {
+ return *internal_default_instance();
+ }
+ static inline const EnumDescriptorProto* internal_default_instance() {
+ return reinterpret_cast<const EnumDescriptorProto*>(
+ &_EnumDescriptorProto_default_instance_);
+ }
+ static constexpr int kIndexInFileMessages =
+ 9;
+
+ friend void swap(EnumDescriptorProto& a, EnumDescriptorProto& b) {
+ a.Swap(&b);
+ }
+ inline void Swap(EnumDescriptorProto* other) {
+ if (other == this) return;
+ #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() != nullptr &&
+ GetOwningArena() == other->GetOwningArena()) {
+ #else // PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() == other->GetOwningArena()) {
+ #endif // !PROTOBUF_FORCE_COPY_IN_SWAP
+ InternalSwap(other);
+ } else {
+ ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
+ }
+ }
+ void UnsafeArenaSwap(EnumDescriptorProto* other) {
+ if (other == this) return;
+ GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena());
+ InternalSwap(other);
+ }
+
+ // implements Message ----------------------------------------------
+
+ EnumDescriptorProto* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
+ return CreateMaybeMessage<EnumDescriptorProto>(arena);
+ }
+ using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
+ void CopyFrom(const EnumDescriptorProto& from);
+ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
+ void MergeFrom(const EnumDescriptorProto& from);
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from);
+ public:
+ PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+ bool IsInitialized() const final;
+
+ size_t ByteSizeLong() const final;
+ const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
+ uint8_t* _InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
+ int GetCachedSize() const final { return _cached_size_.Get(); }
+
+ private:
+ void SharedCtor();
+ void SharedDtor();
+ void SetCachedSize(int size) const final;
+ void InternalSwap(EnumDescriptorProto* other);
+
+ private:
+ friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
+ static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
+ return "google.protobuf.EnumDescriptorProto";
+ }
+ protected:
+ explicit EnumDescriptorProto(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned = false);
+ private:
+ static void ArenaDtor(void* object);
+ inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
+ public:
+
+ static const ClassData _class_data_;
+ const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;
+
+ ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;
+
+ // nested types ----------------------------------------------------
+
+ typedef EnumDescriptorProto_EnumReservedRange EnumReservedRange;
+
+ // accessors -------------------------------------------------------
+
+ enum : int {
+ kValueFieldNumber = 2,
+ kReservedRangeFieldNumber = 4,
+ kReservedNameFieldNumber = 5,
+ kNameFieldNumber = 1,
+ kOptionsFieldNumber = 3,
+ };
+ // repeated .google.protobuf.EnumValueDescriptorProto value = 2;
+ int value_size() const;
+ private:
+ int _internal_value_size() const;
+ public:
+ void clear_value();
+ ::PROTOBUF_NAMESPACE_ID::EnumValueDescriptorProto* mutable_value(int index);
+ ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::EnumValueDescriptorProto >*
+ mutable_value();
+ private:
+ const ::PROTOBUF_NAMESPACE_ID::EnumValueDescriptorProto& _internal_value(int index) const;
+ ::PROTOBUF_NAMESPACE_ID::EnumValueDescriptorProto* _internal_add_value();
+ public:
+ const ::PROTOBUF_NAMESPACE_ID::EnumValueDescriptorProto& value(int index) const;
+ ::PROTOBUF_NAMESPACE_ID::EnumValueDescriptorProto* add_value();
+ const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::EnumValueDescriptorProto >&
+ value() const;
+
+ // repeated .google.protobuf.EnumDescriptorProto.EnumReservedRange reserved_range = 4;
+ int reserved_range_size() const;
+ private:
+ int _internal_reserved_range_size() const;
+ public:
+ void clear_reserved_range();
+ ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto_EnumReservedRange* mutable_reserved_range(int index);
+ ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto_EnumReservedRange >*
+ mutable_reserved_range();
+ private:
+ const ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto_EnumReservedRange& _internal_reserved_range(int index) const;
+ ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto_EnumReservedRange* _internal_add_reserved_range();
+ public:
+ const ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto_EnumReservedRange& reserved_range(int index) const;
+ ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto_EnumReservedRange* add_reserved_range();
+ const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto_EnumReservedRange >&
+ reserved_range() const;
+
+ // repeated string reserved_name = 5;
+ int reserved_name_size() const;
+ private:
+ int _internal_reserved_name_size() const;
+ public:
+ void clear_reserved_name();
+ const 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_;
+ ::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_;
+ friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
+};
+// -------------------------------------------------------------------
+
+class PROTOBUF_EXPORT EnumValueDescriptorProto final :
+ public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.EnumValueDescriptorProto) */ {
+ public:
+ inline EnumValueDescriptorProto() : EnumValueDescriptorProto(nullptr) {}
+ ~EnumValueDescriptorProto() override;
+ explicit constexpr EnumValueDescriptorProto(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
+
+ EnumValueDescriptorProto(const EnumValueDescriptorProto& from);
+ EnumValueDescriptorProto(EnumValueDescriptorProto&& from) noexcept
+ : EnumValueDescriptorProto() {
+ *this = ::std::move(from);
+ }
+
+ inline EnumValueDescriptorProto& operator=(const EnumValueDescriptorProto& from) {
+ CopyFrom(from);
+ return *this;
+ }
+ inline EnumValueDescriptorProto& operator=(EnumValueDescriptorProto&& from) noexcept {
+ if (this == &from) return *this;
+ if (GetOwningArena() == from.GetOwningArena()
+ #ifdef PROTOBUF_FORCE_COPY_IN_MOVE
+ && GetOwningArena() != nullptr
+ #endif // !PROTOBUF_FORCE_COPY_IN_MOVE
+ ) {
+ InternalSwap(&from);
+ } else {
+ CopyFrom(from);
+ }
+ return *this;
+ }
+
+ inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const {
+ return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance);
+ }
+ inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() {
+ return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+ }
+
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
+ return GetDescriptor();
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
+ return default_instance().GetMetadata().descriptor;
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
+ return default_instance().GetMetadata().reflection;
+ }
+ static const EnumValueDescriptorProto& default_instance() {
+ return *internal_default_instance();
+ }
+ static inline const EnumValueDescriptorProto* internal_default_instance() {
+ return reinterpret_cast<const EnumValueDescriptorProto*>(
+ &_EnumValueDescriptorProto_default_instance_);
+ }
+ static constexpr int kIndexInFileMessages =
+ 10;
+
+ friend void swap(EnumValueDescriptorProto& a, EnumValueDescriptorProto& b) {
+ a.Swap(&b);
+ }
+ inline void Swap(EnumValueDescriptorProto* other) {
+ if (other == this) return;
+ #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() != nullptr &&
+ GetOwningArena() == other->GetOwningArena()) {
+ #else // PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() == other->GetOwningArena()) {
+ #endif // !PROTOBUF_FORCE_COPY_IN_SWAP
+ InternalSwap(other);
+ } else {
+ ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
+ }
+ }
+ void UnsafeArenaSwap(EnumValueDescriptorProto* other) {
+ if (other == this) return;
+ GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena());
+ InternalSwap(other);
+ }
+
+ // implements Message ----------------------------------------------
+
+ EnumValueDescriptorProto* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
+ return CreateMaybeMessage<EnumValueDescriptorProto>(arena);
+ }
+ using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
+ void CopyFrom(const EnumValueDescriptorProto& from);
+ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
+ void MergeFrom(const EnumValueDescriptorProto& from);
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from);
+ public:
+ PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+ bool IsInitialized() const final;
+
+ size_t ByteSizeLong() const final;
+ const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
+ uint8_t* _InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
+ int GetCachedSize() const final { return _cached_size_.Get(); }
+
+ private:
+ void SharedCtor();
+ void SharedDtor();
+ void SetCachedSize(int size) const final;
+ void InternalSwap(EnumValueDescriptorProto* other);
+
+ private:
+ friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
+ static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
+ return "google.protobuf.EnumValueDescriptorProto";
+ }
+ protected:
+ explicit EnumValueDescriptorProto(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned = false);
+ private:
+ static void ArenaDtor(void* object);
+ inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
+ public:
+
+ static const ClassData _class_data_;
+ const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;
+
+ ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;
+
+ // nested types ----------------------------------------------------
+
+ // accessors -------------------------------------------------------
+
+ enum : int {
+ kNameFieldNumber = 1,
+ kOptionsFieldNumber = 3,
+ kNumberFieldNumber = 2,
+ };
+ // optional string name = 1;
+ bool has_name() const;
+ private:
+ bool _internal_has_name() const;
+ public:
+ void clear_name();
+ const 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_;
+ ::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_;
+ friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
+};
+// -------------------------------------------------------------------
+
+class PROTOBUF_EXPORT ServiceDescriptorProto final :
+ public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.ServiceDescriptorProto) */ {
+ public:
+ inline ServiceDescriptorProto() : ServiceDescriptorProto(nullptr) {}
+ ~ServiceDescriptorProto() override;
+ explicit constexpr ServiceDescriptorProto(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
+
+ ServiceDescriptorProto(const ServiceDescriptorProto& from);
+ ServiceDescriptorProto(ServiceDescriptorProto&& from) noexcept
+ : ServiceDescriptorProto() {
+ *this = ::std::move(from);
+ }
+
+ inline ServiceDescriptorProto& operator=(const ServiceDescriptorProto& from) {
+ CopyFrom(from);
+ return *this;
+ }
+ inline ServiceDescriptorProto& operator=(ServiceDescriptorProto&& from) noexcept {
+ if (this == &from) return *this;
+ if (GetOwningArena() == from.GetOwningArena()
+ #ifdef PROTOBUF_FORCE_COPY_IN_MOVE
+ && GetOwningArena() != nullptr
+ #endif // !PROTOBUF_FORCE_COPY_IN_MOVE
+ ) {
+ InternalSwap(&from);
+ } else {
+ CopyFrom(from);
+ }
+ return *this;
+ }
+
+ inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const {
+ return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance);
+ }
+ inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() {
+ return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+ }
+
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
+ return GetDescriptor();
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
+ return default_instance().GetMetadata().descriptor;
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
+ return default_instance().GetMetadata().reflection;
+ }
+ static const ServiceDescriptorProto& default_instance() {
+ return *internal_default_instance();
+ }
+ static inline const ServiceDescriptorProto* internal_default_instance() {
+ return reinterpret_cast<const ServiceDescriptorProto*>(
+ &_ServiceDescriptorProto_default_instance_);
+ }
+ static constexpr int kIndexInFileMessages =
+ 11;
+
+ friend void swap(ServiceDescriptorProto& a, ServiceDescriptorProto& b) {
+ a.Swap(&b);
+ }
+ inline void Swap(ServiceDescriptorProto* other) {
+ if (other == this) return;
+ #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() != nullptr &&
+ GetOwningArena() == other->GetOwningArena()) {
+ #else // PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() == other->GetOwningArena()) {
+ #endif // !PROTOBUF_FORCE_COPY_IN_SWAP
+ InternalSwap(other);
+ } else {
+ ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
+ }
+ }
+ void UnsafeArenaSwap(ServiceDescriptorProto* other) {
+ if (other == this) return;
+ GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena());
+ InternalSwap(other);
+ }
+
+ // implements Message ----------------------------------------------
+
+ ServiceDescriptorProto* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
+ return CreateMaybeMessage<ServiceDescriptorProto>(arena);
+ }
+ using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
+ void CopyFrom(const ServiceDescriptorProto& from);
+ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
+ void MergeFrom(const ServiceDescriptorProto& from);
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from);
+ public:
+ PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+ bool IsInitialized() const final;
+
+ size_t ByteSizeLong() const final;
+ const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
+ uint8_t* _InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
+ int GetCachedSize() const final { return _cached_size_.Get(); }
+
+ private:
+ void SharedCtor();
+ void SharedDtor();
+ void SetCachedSize(int size) const final;
+ void InternalSwap(ServiceDescriptorProto* other);
+
+ private:
+ friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
+ static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
+ return "google.protobuf.ServiceDescriptorProto";
+ }
+ protected:
+ explicit ServiceDescriptorProto(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned = false);
+ private:
+ static void ArenaDtor(void* object);
+ inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
+ public:
+
+ static const ClassData _class_data_;
+ const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;
+
+ ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;
+
+ // nested types ----------------------------------------------------
+
+ // accessors -------------------------------------------------------
+
+ enum : int {
+ kMethodFieldNumber = 2,
+ kNameFieldNumber = 1,
+ kOptionsFieldNumber = 3,
+ };
+ // repeated .google.protobuf.MethodDescriptorProto method = 2;
+ int method_size() const;
+ private:
+ int _internal_method_size() const;
+ public:
+ void clear_method();
+ ::PROTOBUF_NAMESPACE_ID::MethodDescriptorProto* mutable_method(int index);
+ ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::MethodDescriptorProto >*
+ mutable_method();
+ private:
+ const ::PROTOBUF_NAMESPACE_ID::MethodDescriptorProto& _internal_method(int index) const;
+ ::PROTOBUF_NAMESPACE_ID::MethodDescriptorProto* _internal_add_method();
+ public:
+ const ::PROTOBUF_NAMESPACE_ID::MethodDescriptorProto& method(int index) const;
+ ::PROTOBUF_NAMESPACE_ID::MethodDescriptorProto* add_method();
+ const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::MethodDescriptorProto >&
+ method() const;
+
+ // optional string name = 1;
+ bool has_name() const;
+ private:
+ bool _internal_has_name() const;
+ public:
+ void clear_name();
+ const 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_;
+ ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_;
+ mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
+ ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::MethodDescriptorProto > method_;
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr name_;
+ ::PROTOBUF_NAMESPACE_ID::ServiceOptions* options_;
+ friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
+};
+// -------------------------------------------------------------------
+
+class PROTOBUF_EXPORT MethodDescriptorProto final :
+ public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.MethodDescriptorProto) */ {
+ public:
+ inline MethodDescriptorProto() : MethodDescriptorProto(nullptr) {}
+ ~MethodDescriptorProto() override;
+ explicit constexpr MethodDescriptorProto(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
+
+ MethodDescriptorProto(const MethodDescriptorProto& from);
+ MethodDescriptorProto(MethodDescriptorProto&& from) noexcept
+ : MethodDescriptorProto() {
+ *this = ::std::move(from);
+ }
+
+ inline MethodDescriptorProto& operator=(const MethodDescriptorProto& from) {
+ CopyFrom(from);
+ return *this;
+ }
+ inline MethodDescriptorProto& operator=(MethodDescriptorProto&& from) noexcept {
+ if (this == &from) return *this;
+ if (GetOwningArena() == from.GetOwningArena()
+ #ifdef PROTOBUF_FORCE_COPY_IN_MOVE
+ && GetOwningArena() != nullptr
+ #endif // !PROTOBUF_FORCE_COPY_IN_MOVE
+ ) {
+ InternalSwap(&from);
+ } else {
+ CopyFrom(from);
+ }
+ return *this;
+ }
+
+ inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const {
+ return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance);
+ }
+ inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() {
+ return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+ }
+
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
+ return GetDescriptor();
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
+ return default_instance().GetMetadata().descriptor;
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
+ return default_instance().GetMetadata().reflection;
+ }
+ static const MethodDescriptorProto& default_instance() {
+ return *internal_default_instance();
+ }
+ static inline const MethodDescriptorProto* internal_default_instance() {
+ return reinterpret_cast<const MethodDescriptorProto*>(
+ &_MethodDescriptorProto_default_instance_);
+ }
+ static constexpr int kIndexInFileMessages =
+ 12;
+
+ friend void swap(MethodDescriptorProto& a, MethodDescriptorProto& b) {
+ a.Swap(&b);
+ }
+ inline void Swap(MethodDescriptorProto* other) {
+ if (other == this) return;
+ #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() != nullptr &&
+ GetOwningArena() == other->GetOwningArena()) {
+ #else // PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() == other->GetOwningArena()) {
+ #endif // !PROTOBUF_FORCE_COPY_IN_SWAP
+ InternalSwap(other);
+ } else {
+ ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
+ }
+ }
+ void UnsafeArenaSwap(MethodDescriptorProto* other) {
+ if (other == this) return;
+ GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena());
+ InternalSwap(other);
+ }
+
+ // implements Message ----------------------------------------------
+
+ MethodDescriptorProto* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
+ return CreateMaybeMessage<MethodDescriptorProto>(arena);
+ }
+ using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
+ void CopyFrom(const MethodDescriptorProto& from);
+ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
+ void MergeFrom(const MethodDescriptorProto& from);
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from);
+ public:
+ PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+ bool IsInitialized() const final;
+
+ size_t ByteSizeLong() const final;
+ const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
+ uint8_t* _InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
+ int GetCachedSize() const final { return _cached_size_.Get(); }
+
+ private:
+ void SharedCtor();
+ void SharedDtor();
+ void SetCachedSize(int size) const final;
+ void InternalSwap(MethodDescriptorProto* other);
+
+ private:
+ friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
+ static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
+ return "google.protobuf.MethodDescriptorProto";
+ }
+ protected:
+ explicit MethodDescriptorProto(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned = false);
+ private:
+ static void ArenaDtor(void* object);
+ inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
+ public:
+
+ static const ClassData _class_data_;
+ const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;
+
+ ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;
+
+ // nested types ----------------------------------------------------
+
+ // accessors -------------------------------------------------------
+
+ enum : int {
+ kNameFieldNumber = 1,
+ kInputTypeFieldNumber = 2,
+ kOutputTypeFieldNumber = 3,
+ kOptionsFieldNumber = 4,
+ kClientStreamingFieldNumber = 5,
+ kServerStreamingFieldNumber = 6,
+ };
+ // optional string name = 1;
+ bool has_name() const;
+ private:
+ bool _internal_has_name() const;
+ public:
+ void clear_name();
+ const 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_;
+ ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_;
+ mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr name_;
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr input_type_;
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr output_type_;
+ ::PROTOBUF_NAMESPACE_ID::MethodOptions* options_;
+ bool client_streaming_;
+ bool server_streaming_;
+ friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
+};
+// -------------------------------------------------------------------
+
+class PROTOBUF_EXPORT FileOptions final :
+ public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.FileOptions) */ {
+ public:
+ inline FileOptions() : FileOptions(nullptr) {}
+ ~FileOptions() override;
+ explicit constexpr FileOptions(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
+
+ FileOptions(const FileOptions& from);
+ FileOptions(FileOptions&& from) noexcept
+ : FileOptions() {
+ *this = ::std::move(from);
+ }
+
+ inline FileOptions& operator=(const FileOptions& from) {
+ CopyFrom(from);
+ return *this;
+ }
+ inline FileOptions& operator=(FileOptions&& from) noexcept {
+ if (this == &from) return *this;
+ if (GetOwningArena() == from.GetOwningArena()
+ #ifdef PROTOBUF_FORCE_COPY_IN_MOVE
+ && GetOwningArena() != nullptr
+ #endif // !PROTOBUF_FORCE_COPY_IN_MOVE
+ ) {
+ InternalSwap(&from);
+ } else {
+ CopyFrom(from);
+ }
+ return *this;
+ }
+
+ inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const {
+ return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance);
+ }
+ inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() {
+ return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+ }
+
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
+ return GetDescriptor();
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
+ return default_instance().GetMetadata().descriptor;
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
+ return default_instance().GetMetadata().reflection;
+ }
+ static const FileOptions& default_instance() {
+ return *internal_default_instance();
+ }
+ static inline const FileOptions* internal_default_instance() {
+ return reinterpret_cast<const FileOptions*>(
+ &_FileOptions_default_instance_);
+ }
+ static constexpr int kIndexInFileMessages =
+ 13;
+
+ friend void swap(FileOptions& a, FileOptions& b) {
+ a.Swap(&b);
+ }
+ inline void Swap(FileOptions* other) {
+ if (other == this) return;
+ #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() != nullptr &&
+ GetOwningArena() == other->GetOwningArena()) {
+ #else // PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() == other->GetOwningArena()) {
+ #endif // !PROTOBUF_FORCE_COPY_IN_SWAP
+ InternalSwap(other);
+ } else {
+ ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
+ }
+ }
+ void UnsafeArenaSwap(FileOptions* other) {
+ if (other == this) return;
+ GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena());
+ InternalSwap(other);
+ }
+
+ // implements Message ----------------------------------------------
+
+ FileOptions* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
+ return CreateMaybeMessage<FileOptions>(arena);
+ }
+ using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
+ void CopyFrom(const FileOptions& from);
+ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
+ void MergeFrom(const FileOptions& from);
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from);
+ public:
+ PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+ bool IsInitialized() const final;
+
+ size_t ByteSizeLong() const final;
+ const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
+ uint8_t* _InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
+ int GetCachedSize() const final { return _cached_size_.Get(); }
+
+ private:
+ void SharedCtor();
+ void SharedDtor();
+ void SetCachedSize(int size) const final;
+ void InternalSwap(FileOptions* other);
+
+ private:
+ friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
+ static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
+ return "google.protobuf.FileOptions";
+ }
+ protected:
+ explicit FileOptions(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned = false);
+ private:
+ static void ArenaDtor(void* object);
+ inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
+ public:
+
+ static const ClassData _class_data_;
+ const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;
+
+ ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;
+
+ // nested types ----------------------------------------------------
+
+ typedef FileOptions_OptimizeMode OptimizeMode;
+ static constexpr OptimizeMode SPEED =
+ FileOptions_OptimizeMode_SPEED;
+ static constexpr OptimizeMode CODE_SIZE =
+ FileOptions_OptimizeMode_CODE_SIZE;
+ static constexpr OptimizeMode LITE_RUNTIME =
+ FileOptions_OptimizeMode_LITE_RUNTIME;
+ static inline bool OptimizeMode_IsValid(int value) {
+ return FileOptions_OptimizeMode_IsValid(value);
+ }
+ static constexpr OptimizeMode OptimizeMode_MIN =
+ FileOptions_OptimizeMode_OptimizeMode_MIN;
+ static constexpr OptimizeMode OptimizeMode_MAX =
+ FileOptions_OptimizeMode_OptimizeMode_MAX;
+ static constexpr int OptimizeMode_ARRAYSIZE =
+ FileOptions_OptimizeMode_OptimizeMode_ARRAYSIZE;
+ static inline const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor*
+ OptimizeMode_descriptor() {
+ return FileOptions_OptimizeMode_descriptor();
+ }
+ template<typename T>
+ static inline const 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 _extensions_.Has(id.number());
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline void ClearExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ FileOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {
+ _extensions_.ClearExtension(id.number());
+
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline int ExtensionSize(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ FileOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const {
+
+ return _extensions_.ExtensionSize(id.number());
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline typename _proto_TypeTraits::Singular::ConstType GetExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ FileOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const {
+
+ return _proto_TypeTraits::Get(id.number(), _extensions_,
+ id.default_value());
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline typename _proto_TypeTraits::Singular::MutableType MutableExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ FileOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {
+
+ return _proto_TypeTraits::Mutable(id.number(), _field_type,
+ &_extensions_);
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline void SetExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ FileOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
+ typename _proto_TypeTraits::Singular::ConstType value) {
+ _proto_TypeTraits::Set(id.number(), _field_type, value, &_extensions_);
+
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline void SetAllocatedExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ FileOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
+ typename _proto_TypeTraits::Singular::MutableType value) {
+ _proto_TypeTraits::SetAllocated(id.number(), _field_type, value,
+ &_extensions_);
+
+ }
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline void UnsafeArenaSetAllocatedExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ FileOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
+ typename _proto_TypeTraits::Singular::MutableType value) {
+ _proto_TypeTraits::UnsafeArenaSetAllocated(id.number(), _field_type,
+ value, &_extensions_);
+
+ }
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ PROTOBUF_NODISCARD inline
+ typename _proto_TypeTraits::Singular::MutableType
+ ReleaseExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ FileOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {
+
+ return _proto_TypeTraits::Release(id.number(), _field_type,
+ &_extensions_);
+ }
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline typename _proto_TypeTraits::Singular::MutableType
+ UnsafeArenaReleaseExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ FileOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {
+
+ return _proto_TypeTraits::UnsafeArenaRelease(id.number(), _field_type,
+ &_extensions_);
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline typename _proto_TypeTraits::Repeated::ConstType GetExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ FileOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
+ int index) const {
+
+ return _proto_TypeTraits::Get(id.number(), _extensions_, index);
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline typename _proto_TypeTraits::Repeated::MutableType MutableExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ FileOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
+ int index) {
+
+ return _proto_TypeTraits::Mutable(id.number(), index, &_extensions_);
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline void SetExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ FileOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
+ int index, typename _proto_TypeTraits::Repeated::ConstType value) {
+ _proto_TypeTraits::Set(id.number(), index, value, &_extensions_);
+
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline typename _proto_TypeTraits::Repeated::MutableType AddExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ FileOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {
+ typename _proto_TypeTraits::Repeated::MutableType to_add =
+ _proto_TypeTraits::Add(id.number(), _field_type, &_extensions_);
+
+ return to_add;
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline void AddExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ FileOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
+ typename _proto_TypeTraits::Repeated::ConstType value) {
+ _proto_TypeTraits::Add(id.number(), _field_type, _is_packed, value,
+ &_extensions_);
+
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline const typename _proto_TypeTraits::Repeated::RepeatedFieldType&
+ GetRepeatedExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ FileOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const {
+
+ return _proto_TypeTraits::GetRepeated(id.number(), _extensions_);
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline typename _proto_TypeTraits::Repeated::RepeatedFieldType*
+ MutableRepeatedExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ FileOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {
+
+ return _proto_TypeTraits::MutableRepeated(id.number(), _field_type,
+ _is_packed, &_extensions_);
+ }
+
+ // @@protoc_insertion_point(class_scope:google.protobuf.FileOptions)
+ private:
+ class _Internal;
+
+ ::PROTOBUF_NAMESPACE_ID::internal::ExtensionSet _extensions_;
+
+ template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
+ typedef void InternalArenaConstructable_;
+ typedef void DestructorSkippable_;
+ ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_;
+ mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
+ ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption > uninterpreted_option_;
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr java_package_;
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr java_outer_classname_;
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr go_package_;
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr objc_class_prefix_;
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr csharp_namespace_;
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr swift_prefix_;
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr php_class_prefix_;
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr php_namespace_;
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr php_metadata_namespace_;
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr ruby_package_;
+ bool java_multiple_files_;
+ bool java_generate_equals_and_hash_;
+ bool java_string_check_utf8_;
+ bool cc_generic_services_;
+ bool java_generic_services_;
+ bool py_generic_services_;
+ bool php_generic_services_;
+ bool deprecated_;
+ int optimize_for_;
+ bool cc_enable_arenas_;
+ friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
+};
+// -------------------------------------------------------------------
+
+class PROTOBUF_EXPORT MessageOptions final :
+ public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.MessageOptions) */ {
+ public:
+ inline MessageOptions() : MessageOptions(nullptr) {}
+ ~MessageOptions() override;
+ explicit constexpr MessageOptions(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
+
+ MessageOptions(const MessageOptions& from);
+ MessageOptions(MessageOptions&& from) noexcept
+ : MessageOptions() {
+ *this = ::std::move(from);
+ }
+
+ inline MessageOptions& operator=(const MessageOptions& from) {
+ CopyFrom(from);
+ return *this;
+ }
+ inline MessageOptions& operator=(MessageOptions&& from) noexcept {
+ if (this == &from) return *this;
+ if (GetOwningArena() == from.GetOwningArena()
+ #ifdef PROTOBUF_FORCE_COPY_IN_MOVE
+ && GetOwningArena() != nullptr
+ #endif // !PROTOBUF_FORCE_COPY_IN_MOVE
+ ) {
+ InternalSwap(&from);
+ } else {
+ CopyFrom(from);
+ }
+ return *this;
+ }
+
+ inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const {
+ return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance);
+ }
+ inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() {
+ return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+ }
+
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
+ return GetDescriptor();
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
+ return default_instance().GetMetadata().descriptor;
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
+ return default_instance().GetMetadata().reflection;
+ }
+ static const MessageOptions& default_instance() {
+ return *internal_default_instance();
+ }
+ static inline const MessageOptions* internal_default_instance() {
+ return reinterpret_cast<const MessageOptions*>(
+ &_MessageOptions_default_instance_);
+ }
+ static constexpr int kIndexInFileMessages =
+ 14;
+
+ friend void swap(MessageOptions& a, MessageOptions& b) {
+ a.Swap(&b);
+ }
+ inline void Swap(MessageOptions* other) {
+ if (other == this) return;
+ #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() != nullptr &&
+ GetOwningArena() == other->GetOwningArena()) {
+ #else // PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() == other->GetOwningArena()) {
+ #endif // !PROTOBUF_FORCE_COPY_IN_SWAP
+ InternalSwap(other);
+ } else {
+ ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
+ }
+ }
+ void UnsafeArenaSwap(MessageOptions* other) {
+ if (other == this) return;
+ GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena());
+ InternalSwap(other);
+ }
+
+ // implements Message ----------------------------------------------
+
+ MessageOptions* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
+ return CreateMaybeMessage<MessageOptions>(arena);
+ }
+ using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
+ void CopyFrom(const MessageOptions& from);
+ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
+ void MergeFrom(const MessageOptions& from);
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from);
+ public:
+ PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+ bool IsInitialized() const final;
+
+ size_t ByteSizeLong() const final;
+ const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
+ uint8_t* _InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
+ int GetCachedSize() const final { return _cached_size_.Get(); }
+
+ private:
+ void SharedCtor();
+ void SharedDtor();
+ void SetCachedSize(int size) const final;
+ void InternalSwap(MessageOptions* other);
+
+ private:
+ friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
+ static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
+ return "google.protobuf.MessageOptions";
+ }
+ protected:
+ explicit MessageOptions(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned = false);
+ private:
+ static void ArenaDtor(void* object);
+ inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
+ public:
+
+ static const ClassData _class_data_;
+ const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;
+
+ ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;
+
+ // nested types ----------------------------------------------------
+
+ // accessors -------------------------------------------------------
+
+ enum : int {
+ kUninterpretedOptionFieldNumber = 999,
+ kMessageSetWireFormatFieldNumber = 1,
+ kNoStandardDescriptorAccessorFieldNumber = 2,
+ kDeprecatedFieldNumber = 3,
+ kMapEntryFieldNumber = 7,
+ };
+ // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+ int uninterpreted_option_size() const;
+ private:
+ int _internal_uninterpreted_option_size() const;
+ public:
+ void clear_uninterpreted_option();
+ ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* mutable_uninterpreted_option(int index);
+ ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption >*
+ mutable_uninterpreted_option();
+ private:
+ const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption& _internal_uninterpreted_option(int index) const;
+ ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* _internal_add_uninterpreted_option();
+ public:
+ const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption& uninterpreted_option(int index) const;
+ ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* add_uninterpreted_option();
+ const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption >&
+ uninterpreted_option() const;
+
+ // optional bool message_set_wire_format = 1 [default = false];
+ bool has_message_set_wire_format() const;
+ private:
+ bool _internal_has_message_set_wire_format() const;
+ public:
+ void clear_message_set_wire_format();
+ bool message_set_wire_format() const;
+ void set_message_set_wire_format(bool value);
+ private:
+ bool _internal_message_set_wire_format() const;
+ void _internal_set_message_set_wire_format(bool value);
+ public:
+
+ // optional bool no_standard_descriptor_accessor = 2 [default = false];
+ bool has_no_standard_descriptor_accessor() const;
+ private:
+ bool _internal_has_no_standard_descriptor_accessor() const;
+ public:
+ void clear_no_standard_descriptor_accessor();
+ bool no_standard_descriptor_accessor() const;
+ void set_no_standard_descriptor_accessor(bool value);
+ private:
+ bool _internal_no_standard_descriptor_accessor() const;
+ void _internal_set_no_standard_descriptor_accessor(bool value);
+ public:
+
+ // optional bool deprecated = 3 [default = false];
+ bool has_deprecated() const;
+ private:
+ bool _internal_has_deprecated() const;
+ public:
+ void clear_deprecated();
+ bool deprecated() const;
+ void set_deprecated(bool value);
+ private:
+ bool _internal_deprecated() const;
+ void _internal_set_deprecated(bool value);
+ public:
+
+ // optional bool map_entry = 7;
+ bool has_map_entry() const;
+ private:
+ bool _internal_has_map_entry() const;
+ public:
+ void clear_map_entry();
+ bool map_entry() const;
+ void set_map_entry(bool value);
+ private:
+ bool _internal_map_entry() const;
+ void _internal_set_map_entry(bool value);
+ public:
+
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline bool HasExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ MessageOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const {
+
+ return _extensions_.Has(id.number());
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline void ClearExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ MessageOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {
+ _extensions_.ClearExtension(id.number());
+
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline int ExtensionSize(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ MessageOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const {
+
+ return _extensions_.ExtensionSize(id.number());
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline typename _proto_TypeTraits::Singular::ConstType GetExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ MessageOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const {
+
+ return _proto_TypeTraits::Get(id.number(), _extensions_,
+ id.default_value());
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline typename _proto_TypeTraits::Singular::MutableType MutableExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ MessageOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {
+
+ return _proto_TypeTraits::Mutable(id.number(), _field_type,
+ &_extensions_);
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline void SetExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ MessageOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
+ typename _proto_TypeTraits::Singular::ConstType value) {
+ _proto_TypeTraits::Set(id.number(), _field_type, value, &_extensions_);
+
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline void SetAllocatedExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ MessageOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
+ typename _proto_TypeTraits::Singular::MutableType value) {
+ _proto_TypeTraits::SetAllocated(id.number(), _field_type, value,
+ &_extensions_);
+
+ }
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline void UnsafeArenaSetAllocatedExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ MessageOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
+ typename _proto_TypeTraits::Singular::MutableType value) {
+ _proto_TypeTraits::UnsafeArenaSetAllocated(id.number(), _field_type,
+ value, &_extensions_);
+
+ }
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ PROTOBUF_NODISCARD inline
+ typename _proto_TypeTraits::Singular::MutableType
+ ReleaseExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ MessageOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {
+
+ return _proto_TypeTraits::Release(id.number(), _field_type,
+ &_extensions_);
+ }
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline typename _proto_TypeTraits::Singular::MutableType
+ UnsafeArenaReleaseExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ MessageOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {
+
+ return _proto_TypeTraits::UnsafeArenaRelease(id.number(), _field_type,
+ &_extensions_);
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline typename _proto_TypeTraits::Repeated::ConstType GetExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ MessageOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
+ int index) const {
+
+ return _proto_TypeTraits::Get(id.number(), _extensions_, index);
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline typename _proto_TypeTraits::Repeated::MutableType MutableExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ MessageOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
+ int index) {
+
+ return _proto_TypeTraits::Mutable(id.number(), index, &_extensions_);
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline void SetExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ MessageOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
+ int index, typename _proto_TypeTraits::Repeated::ConstType value) {
+ _proto_TypeTraits::Set(id.number(), index, value, &_extensions_);
+
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline typename _proto_TypeTraits::Repeated::MutableType AddExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ MessageOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {
+ typename _proto_TypeTraits::Repeated::MutableType to_add =
+ _proto_TypeTraits::Add(id.number(), _field_type, &_extensions_);
+
+ return to_add;
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline void AddExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ MessageOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
+ typename _proto_TypeTraits::Repeated::ConstType value) {
+ _proto_TypeTraits::Add(id.number(), _field_type, _is_packed, value,
+ &_extensions_);
+
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline const typename _proto_TypeTraits::Repeated::RepeatedFieldType&
+ GetRepeatedExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ MessageOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const {
+
+ return _proto_TypeTraits::GetRepeated(id.number(), _extensions_);
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline typename _proto_TypeTraits::Repeated::RepeatedFieldType*
+ MutableRepeatedExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ MessageOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {
+
+ return _proto_TypeTraits::MutableRepeated(id.number(), _field_type,
+ _is_packed, &_extensions_);
+ }
+
+ // @@protoc_insertion_point(class_scope:google.protobuf.MessageOptions)
+ private:
+ class _Internal;
+
+ ::PROTOBUF_NAMESPACE_ID::internal::ExtensionSet _extensions_;
+
+ template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
+ typedef void InternalArenaConstructable_;
+ typedef void DestructorSkippable_;
+ ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_;
+ mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
+ ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption > uninterpreted_option_;
+ bool message_set_wire_format_;
+ bool no_standard_descriptor_accessor_;
+ bool deprecated_;
+ bool map_entry_;
+ friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
+};
+// -------------------------------------------------------------------
+
+class PROTOBUF_EXPORT FieldOptions final :
+ public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.FieldOptions) */ {
+ public:
+ inline FieldOptions() : FieldOptions(nullptr) {}
+ ~FieldOptions() override;
+ explicit constexpr FieldOptions(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
+
+ FieldOptions(const FieldOptions& from);
+ FieldOptions(FieldOptions&& from) noexcept
+ : FieldOptions() {
+ *this = ::std::move(from);
+ }
+
+ inline FieldOptions& operator=(const FieldOptions& from) {
+ CopyFrom(from);
+ return *this;
+ }
+ inline FieldOptions& operator=(FieldOptions&& from) noexcept {
+ if (this == &from) return *this;
+ if (GetOwningArena() == from.GetOwningArena()
+ #ifdef PROTOBUF_FORCE_COPY_IN_MOVE
+ && GetOwningArena() != nullptr
+ #endif // !PROTOBUF_FORCE_COPY_IN_MOVE
+ ) {
+ InternalSwap(&from);
+ } else {
+ CopyFrom(from);
+ }
+ return *this;
+ }
+
+ inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const {
+ return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance);
+ }
+ inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() {
+ return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+ }
+
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
+ return GetDescriptor();
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
+ return default_instance().GetMetadata().descriptor;
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
+ return default_instance().GetMetadata().reflection;
+ }
+ static const FieldOptions& default_instance() {
+ return *internal_default_instance();
+ }
+ static inline const FieldOptions* internal_default_instance() {
+ return reinterpret_cast<const FieldOptions*>(
+ &_FieldOptions_default_instance_);
+ }
+ static constexpr int kIndexInFileMessages =
+ 15;
+
+ friend void swap(FieldOptions& a, FieldOptions& b) {
+ a.Swap(&b);
+ }
+ inline void Swap(FieldOptions* other) {
+ if (other == this) return;
+ #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() != nullptr &&
+ GetOwningArena() == other->GetOwningArena()) {
+ #else // PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() == other->GetOwningArena()) {
+ #endif // !PROTOBUF_FORCE_COPY_IN_SWAP
+ InternalSwap(other);
+ } else {
+ ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
+ }
+ }
+ void UnsafeArenaSwap(FieldOptions* other) {
+ if (other == this) return;
+ GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena());
+ InternalSwap(other);
+ }
+
+ // implements Message ----------------------------------------------
+
+ FieldOptions* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
+ return CreateMaybeMessage<FieldOptions>(arena);
+ }
+ using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
+ void CopyFrom(const FieldOptions& from);
+ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
+ void MergeFrom(const FieldOptions& from);
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from);
+ public:
+ PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+ bool IsInitialized() const final;
+
+ size_t ByteSizeLong() const final;
+ const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
+ uint8_t* _InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
+ int GetCachedSize() const final { return _cached_size_.Get(); }
+
+ private:
+ void SharedCtor();
+ void SharedDtor();
+ void SetCachedSize(int size) const final;
+ void InternalSwap(FieldOptions* other);
+
+ private:
+ friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
+ static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
+ return "google.protobuf.FieldOptions";
+ }
+ protected:
+ explicit FieldOptions(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned = false);
+ private:
+ static void ArenaDtor(void* object);
+ inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
+ public:
+
+ static const ClassData _class_data_;
+ const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;
+
+ ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;
+
+ // nested types ----------------------------------------------------
+
+ typedef FieldOptions_CType CType;
+ static constexpr CType STRING =
+ FieldOptions_CType_STRING;
+ static constexpr CType CORD =
+ FieldOptions_CType_CORD;
+ static constexpr CType STRING_PIECE =
+ FieldOptions_CType_STRING_PIECE;
+ static inline bool CType_IsValid(int value) {
+ return FieldOptions_CType_IsValid(value);
+ }
+ static constexpr CType CType_MIN =
+ FieldOptions_CType_CType_MIN;
+ static constexpr CType CType_MAX =
+ FieldOptions_CType_CType_MAX;
+ static constexpr int CType_ARRAYSIZE =
+ FieldOptions_CType_CType_ARRAYSIZE;
+ static inline const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor*
+ CType_descriptor() {
+ return FieldOptions_CType_descriptor();
+ }
+ template<typename T>
+ static inline const 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,
+ kPackedFieldNumber = 2,
+ kLazyFieldNumber = 5,
+ kDeprecatedFieldNumber = 3,
+ kWeakFieldNumber = 10,
+ kJstypeFieldNumber = 6,
+ };
+ // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+ int uninterpreted_option_size() const;
+ private:
+ int _internal_uninterpreted_option_size() const;
+ public:
+ void clear_uninterpreted_option();
+ ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* mutable_uninterpreted_option(int index);
+ ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption >*
+ mutable_uninterpreted_option();
+ private:
+ const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption& _internal_uninterpreted_option(int index) const;
+ ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* _internal_add_uninterpreted_option();
+ public:
+ const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption& uninterpreted_option(int index) const;
+ ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* add_uninterpreted_option();
+ const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption >&
+ uninterpreted_option() const;
+
+ // optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING];
+ bool has_ctype() const;
+ private:
+ bool _internal_has_ctype() const;
+ public:
+ void clear_ctype();
+ ::PROTOBUF_NAMESPACE_ID::FieldOptions_CType ctype() const;
+ void set_ctype(::PROTOBUF_NAMESPACE_ID::FieldOptions_CType value);
+ private:
+ ::PROTOBUF_NAMESPACE_ID::FieldOptions_CType _internal_ctype() const;
+ void _internal_set_ctype(::PROTOBUF_NAMESPACE_ID::FieldOptions_CType value);
+ public:
+
+ // optional bool packed = 2;
+ bool has_packed() const;
+ private:
+ bool _internal_has_packed() const;
+ public:
+ void clear_packed();
+ bool packed() const;
+ void set_packed(bool value);
+ private:
+ bool _internal_packed() const;
+ void _internal_set_packed(bool value);
+ public:
+
+ // optional bool lazy = 5 [default = false];
+ bool has_lazy() const;
+ private:
+ bool _internal_has_lazy() const;
+ public:
+ void clear_lazy();
+ bool lazy() const;
+ void set_lazy(bool value);
+ private:
+ bool _internal_lazy() const;
+ void _internal_set_lazy(bool value);
+ public:
+
+ // optional bool deprecated = 3 [default = false];
+ bool has_deprecated() const;
+ private:
+ bool _internal_has_deprecated() const;
+ public:
+ void clear_deprecated();
+ bool deprecated() const;
+ void set_deprecated(bool value);
+ private:
+ bool _internal_deprecated() const;
+ void _internal_set_deprecated(bool value);
+ public:
+
+ // optional bool weak = 10 [default = false];
+ bool has_weak() const;
+ private:
+ bool _internal_has_weak() const;
+ public:
+ void clear_weak();
+ bool weak() const;
+ void set_weak(bool value);
+ private:
+ bool _internal_weak() const;
+ void _internal_set_weak(bool value);
+ public:
+
+ // optional .google.protobuf.FieldOptions.JSType jstype = 6 [default = JS_NORMAL];
+ bool has_jstype() const;
+ private:
+ bool _internal_has_jstype() const;
+ public:
+ void clear_jstype();
+ ::PROTOBUF_NAMESPACE_ID::FieldOptions_JSType jstype() const;
+ void set_jstype(::PROTOBUF_NAMESPACE_ID::FieldOptions_JSType value);
+ private:
+ ::PROTOBUF_NAMESPACE_ID::FieldOptions_JSType _internal_jstype() const;
+ void _internal_set_jstype(::PROTOBUF_NAMESPACE_ID::FieldOptions_JSType value);
+ public:
+
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline bool HasExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ FieldOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const {
+
+ return _extensions_.Has(id.number());
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline void ClearExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ FieldOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {
+ _extensions_.ClearExtension(id.number());
+
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline int ExtensionSize(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ FieldOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const {
+
+ return _extensions_.ExtensionSize(id.number());
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline typename _proto_TypeTraits::Singular::ConstType GetExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ FieldOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const {
+
+ return _proto_TypeTraits::Get(id.number(), _extensions_,
+ id.default_value());
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline typename _proto_TypeTraits::Singular::MutableType MutableExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ FieldOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {
+
+ return _proto_TypeTraits::Mutable(id.number(), _field_type,
+ &_extensions_);
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline void SetExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ FieldOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
+ typename _proto_TypeTraits::Singular::ConstType value) {
+ _proto_TypeTraits::Set(id.number(), _field_type, value, &_extensions_);
+
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline void SetAllocatedExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ FieldOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
+ typename _proto_TypeTraits::Singular::MutableType value) {
+ _proto_TypeTraits::SetAllocated(id.number(), _field_type, value,
+ &_extensions_);
+
+ }
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline void UnsafeArenaSetAllocatedExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ FieldOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
+ typename _proto_TypeTraits::Singular::MutableType value) {
+ _proto_TypeTraits::UnsafeArenaSetAllocated(id.number(), _field_type,
+ value, &_extensions_);
+
+ }
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ PROTOBUF_NODISCARD inline
+ typename _proto_TypeTraits::Singular::MutableType
+ ReleaseExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ FieldOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {
+
+ return _proto_TypeTraits::Release(id.number(), _field_type,
+ &_extensions_);
+ }
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline typename _proto_TypeTraits::Singular::MutableType
+ UnsafeArenaReleaseExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ FieldOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {
+
+ return _proto_TypeTraits::UnsafeArenaRelease(id.number(), _field_type,
+ &_extensions_);
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline typename _proto_TypeTraits::Repeated::ConstType GetExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ FieldOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
+ int index) const {
+
+ return _proto_TypeTraits::Get(id.number(), _extensions_, index);
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline typename _proto_TypeTraits::Repeated::MutableType MutableExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ FieldOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
+ int index) {
+
+ return _proto_TypeTraits::Mutable(id.number(), index, &_extensions_);
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline void SetExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ FieldOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
+ int index, typename _proto_TypeTraits::Repeated::ConstType value) {
+ _proto_TypeTraits::Set(id.number(), index, value, &_extensions_);
+
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline typename _proto_TypeTraits::Repeated::MutableType AddExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ FieldOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {
+ typename _proto_TypeTraits::Repeated::MutableType to_add =
+ _proto_TypeTraits::Add(id.number(), _field_type, &_extensions_);
+
+ return to_add;
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline void AddExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ FieldOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
+ typename _proto_TypeTraits::Repeated::ConstType value) {
+ _proto_TypeTraits::Add(id.number(), _field_type, _is_packed, value,
+ &_extensions_);
+
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline const typename _proto_TypeTraits::Repeated::RepeatedFieldType&
+ GetRepeatedExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ FieldOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const {
+
+ return _proto_TypeTraits::GetRepeated(id.number(), _extensions_);
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline typename _proto_TypeTraits::Repeated::RepeatedFieldType*
+ MutableRepeatedExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ FieldOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {
+
+ return _proto_TypeTraits::MutableRepeated(id.number(), _field_type,
+ _is_packed, &_extensions_);
+ }
+
+ // @@protoc_insertion_point(class_scope:google.protobuf.FieldOptions)
+ private:
+ class _Internal;
+
+ ::PROTOBUF_NAMESPACE_ID::internal::ExtensionSet _extensions_;
+
+ template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
+ typedef void InternalArenaConstructable_;
+ typedef void DestructorSkippable_;
+ ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_;
+ mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
+ ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption > uninterpreted_option_;
+ int ctype_;
+ bool packed_;
+ bool lazy_;
+ bool deprecated_;
+ bool weak_;
+ int jstype_;
+ friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
+};
+// -------------------------------------------------------------------
+
+class PROTOBUF_EXPORT OneofOptions final :
+ public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.OneofOptions) */ {
+ public:
+ inline OneofOptions() : OneofOptions(nullptr) {}
+ ~OneofOptions() override;
+ explicit constexpr OneofOptions(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
+
+ OneofOptions(const OneofOptions& from);
+ OneofOptions(OneofOptions&& from) noexcept
+ : OneofOptions() {
+ *this = ::std::move(from);
+ }
+
+ inline OneofOptions& operator=(const OneofOptions& from) {
+ CopyFrom(from);
+ return *this;
+ }
+ inline OneofOptions& operator=(OneofOptions&& from) noexcept {
+ if (this == &from) return *this;
+ if (GetOwningArena() == from.GetOwningArena()
+ #ifdef PROTOBUF_FORCE_COPY_IN_MOVE
+ && GetOwningArena() != nullptr
+ #endif // !PROTOBUF_FORCE_COPY_IN_MOVE
+ ) {
+ InternalSwap(&from);
+ } else {
+ CopyFrom(from);
+ }
+ return *this;
+ }
+
+ inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const {
+ return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance);
+ }
+ inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() {
+ return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+ }
+
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
+ return GetDescriptor();
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
+ return default_instance().GetMetadata().descriptor;
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
+ return default_instance().GetMetadata().reflection;
+ }
+ static const OneofOptions& default_instance() {
+ return *internal_default_instance();
+ }
+ static inline const OneofOptions* internal_default_instance() {
+ return reinterpret_cast<const OneofOptions*>(
+ &_OneofOptions_default_instance_);
+ }
+ static constexpr int kIndexInFileMessages =
+ 16;
+
+ friend void swap(OneofOptions& a, OneofOptions& b) {
+ a.Swap(&b);
+ }
+ inline void Swap(OneofOptions* other) {
+ if (other == this) return;
+ #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() != nullptr &&
+ GetOwningArena() == other->GetOwningArena()) {
+ #else // PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() == other->GetOwningArena()) {
+ #endif // !PROTOBUF_FORCE_COPY_IN_SWAP
+ InternalSwap(other);
+ } else {
+ ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
+ }
+ }
+ void UnsafeArenaSwap(OneofOptions* other) {
+ if (other == this) return;
+ GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena());
+ InternalSwap(other);
+ }
+
+ // implements Message ----------------------------------------------
+
+ OneofOptions* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
+ return CreateMaybeMessage<OneofOptions>(arena);
+ }
+ using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
+ void CopyFrom(const OneofOptions& from);
+ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
+ void MergeFrom(const OneofOptions& from);
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from);
+ public:
+ PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+ bool IsInitialized() const final;
+
+ size_t ByteSizeLong() const final;
+ const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
+ uint8_t* _InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
+ int GetCachedSize() const final { return _cached_size_.Get(); }
+
+ private:
+ void SharedCtor();
+ void SharedDtor();
+ void SetCachedSize(int size) const final;
+ void InternalSwap(OneofOptions* other);
+
+ private:
+ friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
+ static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
+ return "google.protobuf.OneofOptions";
+ }
+ protected:
+ explicit OneofOptions(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned = false);
+ private:
+ static void ArenaDtor(void* object);
+ inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
+ public:
+
+ static const ClassData _class_data_;
+ const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;
+
+ ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;
+
+ // nested types ----------------------------------------------------
+
+ // accessors -------------------------------------------------------
+
+ enum : int {
+ kUninterpretedOptionFieldNumber = 999,
+ };
+ // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+ int uninterpreted_option_size() const;
+ private:
+ int _internal_uninterpreted_option_size() const;
+ public:
+ void clear_uninterpreted_option();
+ ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* mutable_uninterpreted_option(int index);
+ ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption >*
+ mutable_uninterpreted_option();
+ private:
+ const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption& _internal_uninterpreted_option(int index) const;
+ ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* _internal_add_uninterpreted_option();
+ public:
+ const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption& uninterpreted_option(int index) const;
+ ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* add_uninterpreted_option();
+ const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption >&
+ uninterpreted_option() const;
+
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline bool HasExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ OneofOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const {
+
+ return _extensions_.Has(id.number());
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline void ClearExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ OneofOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {
+ _extensions_.ClearExtension(id.number());
+
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline int ExtensionSize(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ OneofOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const {
+
+ return _extensions_.ExtensionSize(id.number());
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline typename _proto_TypeTraits::Singular::ConstType GetExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ OneofOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const {
+
+ return _proto_TypeTraits::Get(id.number(), _extensions_,
+ id.default_value());
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline typename _proto_TypeTraits::Singular::MutableType MutableExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ OneofOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {
+
+ return _proto_TypeTraits::Mutable(id.number(), _field_type,
+ &_extensions_);
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline void SetExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ OneofOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
+ typename _proto_TypeTraits::Singular::ConstType value) {
+ _proto_TypeTraits::Set(id.number(), _field_type, value, &_extensions_);
+
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline void SetAllocatedExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ OneofOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
+ typename _proto_TypeTraits::Singular::MutableType value) {
+ _proto_TypeTraits::SetAllocated(id.number(), _field_type, value,
+ &_extensions_);
+
+ }
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline void UnsafeArenaSetAllocatedExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ OneofOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
+ typename _proto_TypeTraits::Singular::MutableType value) {
+ _proto_TypeTraits::UnsafeArenaSetAllocated(id.number(), _field_type,
+ value, &_extensions_);
+
+ }
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ PROTOBUF_NODISCARD inline
+ typename _proto_TypeTraits::Singular::MutableType
+ ReleaseExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ OneofOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {
+
+ return _proto_TypeTraits::Release(id.number(), _field_type,
+ &_extensions_);
+ }
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline typename _proto_TypeTraits::Singular::MutableType
+ UnsafeArenaReleaseExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ OneofOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {
+
+ return _proto_TypeTraits::UnsafeArenaRelease(id.number(), _field_type,
+ &_extensions_);
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline typename _proto_TypeTraits::Repeated::ConstType GetExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ OneofOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
+ int index) const {
+
+ return _proto_TypeTraits::Get(id.number(), _extensions_, index);
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline typename _proto_TypeTraits::Repeated::MutableType MutableExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ OneofOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
+ int index) {
+
+ return _proto_TypeTraits::Mutable(id.number(), index, &_extensions_);
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline void SetExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ OneofOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
+ int index, typename _proto_TypeTraits::Repeated::ConstType value) {
+ _proto_TypeTraits::Set(id.number(), index, value, &_extensions_);
+
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline typename _proto_TypeTraits::Repeated::MutableType AddExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ OneofOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {
+ typename _proto_TypeTraits::Repeated::MutableType to_add =
+ _proto_TypeTraits::Add(id.number(), _field_type, &_extensions_);
+
+ return to_add;
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline void AddExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ OneofOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
+ typename _proto_TypeTraits::Repeated::ConstType value) {
+ _proto_TypeTraits::Add(id.number(), _field_type, _is_packed, value,
+ &_extensions_);
+
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline const typename _proto_TypeTraits::Repeated::RepeatedFieldType&
+ GetRepeatedExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ OneofOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const {
+
+ return _proto_TypeTraits::GetRepeated(id.number(), _extensions_);
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline typename _proto_TypeTraits::Repeated::RepeatedFieldType*
+ MutableRepeatedExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ OneofOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {
+
+ return _proto_TypeTraits::MutableRepeated(id.number(), _field_type,
+ _is_packed, &_extensions_);
+ }
+
+ // @@protoc_insertion_point(class_scope:google.protobuf.OneofOptions)
+ private:
+ class _Internal;
+
+ ::PROTOBUF_NAMESPACE_ID::internal::ExtensionSet _extensions_;
+
+ template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
+ typedef void InternalArenaConstructable_;
+ typedef void DestructorSkippable_;
+ ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption > uninterpreted_option_;
+ mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
+ friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
+};
+// -------------------------------------------------------------------
+
+class PROTOBUF_EXPORT EnumOptions final :
+ public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.EnumOptions) */ {
+ public:
+ inline EnumOptions() : EnumOptions(nullptr) {}
+ ~EnumOptions() override;
+ explicit constexpr EnumOptions(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
+
+ EnumOptions(const EnumOptions& from);
+ EnumOptions(EnumOptions&& from) noexcept
+ : EnumOptions() {
+ *this = ::std::move(from);
+ }
+
+ inline EnumOptions& operator=(const EnumOptions& from) {
+ CopyFrom(from);
+ return *this;
+ }
+ inline EnumOptions& operator=(EnumOptions&& from) noexcept {
+ if (this == &from) return *this;
+ if (GetOwningArena() == from.GetOwningArena()
+ #ifdef PROTOBUF_FORCE_COPY_IN_MOVE
+ && GetOwningArena() != nullptr
+ #endif // !PROTOBUF_FORCE_COPY_IN_MOVE
+ ) {
+ InternalSwap(&from);
+ } else {
+ CopyFrom(from);
+ }
+ return *this;
+ }
+
+ inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const {
+ return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance);
+ }
+ inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() {
+ return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+ }
+
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
+ return GetDescriptor();
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
+ return default_instance().GetMetadata().descriptor;
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
+ return default_instance().GetMetadata().reflection;
+ }
+ static const EnumOptions& default_instance() {
+ return *internal_default_instance();
+ }
+ static inline const EnumOptions* internal_default_instance() {
+ return reinterpret_cast<const EnumOptions*>(
+ &_EnumOptions_default_instance_);
+ }
+ static constexpr int kIndexInFileMessages =
+ 17;
+
+ friend void swap(EnumOptions& a, EnumOptions& b) {
+ a.Swap(&b);
+ }
+ inline void Swap(EnumOptions* other) {
+ if (other == this) return;
+ #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() != nullptr &&
+ GetOwningArena() == other->GetOwningArena()) {
+ #else // PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() == other->GetOwningArena()) {
+ #endif // !PROTOBUF_FORCE_COPY_IN_SWAP
+ InternalSwap(other);
+ } else {
+ ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
+ }
+ }
+ void UnsafeArenaSwap(EnumOptions* other) {
+ if (other == this) return;
+ GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena());
+ InternalSwap(other);
+ }
+
+ // implements Message ----------------------------------------------
+
+ EnumOptions* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
+ return CreateMaybeMessage<EnumOptions>(arena);
+ }
+ using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
+ void CopyFrom(const EnumOptions& from);
+ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
+ void MergeFrom(const EnumOptions& from);
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from);
+ public:
+ PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+ bool IsInitialized() const final;
+
+ size_t ByteSizeLong() const final;
+ const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
+ uint8_t* _InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
+ int GetCachedSize() const final { return _cached_size_.Get(); }
+
+ private:
+ void SharedCtor();
+ void SharedDtor();
+ void SetCachedSize(int size) const final;
+ void InternalSwap(EnumOptions* other);
+
+ private:
+ friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
+ static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
+ return "google.protobuf.EnumOptions";
+ }
+ protected:
+ explicit EnumOptions(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned = false);
+ private:
+ static void ArenaDtor(void* object);
+ inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
+ public:
+
+ static const ClassData _class_data_;
+ const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;
+
+ ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;
+
+ // nested types ----------------------------------------------------
+
+ // accessors -------------------------------------------------------
+
+ enum : int {
+ kUninterpretedOptionFieldNumber = 999,
+ kAllowAliasFieldNumber = 2,
+ kDeprecatedFieldNumber = 3,
+ };
+ // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+ int uninterpreted_option_size() const;
+ private:
+ int _internal_uninterpreted_option_size() const;
+ public:
+ void clear_uninterpreted_option();
+ ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* mutable_uninterpreted_option(int index);
+ ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption >*
+ mutable_uninterpreted_option();
+ private:
+ const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption& _internal_uninterpreted_option(int index) const;
+ ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* _internal_add_uninterpreted_option();
+ public:
+ const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption& uninterpreted_option(int index) const;
+ ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* add_uninterpreted_option();
+ const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption >&
+ uninterpreted_option() const;
+
+ // optional bool allow_alias = 2;
+ bool has_allow_alias() const;
+ private:
+ bool _internal_has_allow_alias() const;
+ public:
+ void clear_allow_alias();
+ bool allow_alias() const;
+ void set_allow_alias(bool value);
+ private:
+ bool _internal_allow_alias() const;
+ void _internal_set_allow_alias(bool value);
+ public:
+
+ // optional bool deprecated = 3 [default = false];
+ bool has_deprecated() const;
+ private:
+ bool _internal_has_deprecated() const;
+ public:
+ void clear_deprecated();
+ bool deprecated() const;
+ void set_deprecated(bool value);
+ private:
+ bool _internal_deprecated() const;
+ void _internal_set_deprecated(bool value);
+ public:
+
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline bool HasExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ EnumOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const {
+
+ return _extensions_.Has(id.number());
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline void ClearExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ EnumOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {
+ _extensions_.ClearExtension(id.number());
+
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline int ExtensionSize(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ EnumOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const {
+
+ return _extensions_.ExtensionSize(id.number());
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline typename _proto_TypeTraits::Singular::ConstType GetExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ EnumOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const {
+
+ return _proto_TypeTraits::Get(id.number(), _extensions_,
+ id.default_value());
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline typename _proto_TypeTraits::Singular::MutableType MutableExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ EnumOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {
+
+ return _proto_TypeTraits::Mutable(id.number(), _field_type,
+ &_extensions_);
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline void SetExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ EnumOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
+ typename _proto_TypeTraits::Singular::ConstType value) {
+ _proto_TypeTraits::Set(id.number(), _field_type, value, &_extensions_);
+
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline void SetAllocatedExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ EnumOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
+ typename _proto_TypeTraits::Singular::MutableType value) {
+ _proto_TypeTraits::SetAllocated(id.number(), _field_type, value,
+ &_extensions_);
+
+ }
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline void UnsafeArenaSetAllocatedExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ EnumOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
+ typename _proto_TypeTraits::Singular::MutableType value) {
+ _proto_TypeTraits::UnsafeArenaSetAllocated(id.number(), _field_type,
+ value, &_extensions_);
+
+ }
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ PROTOBUF_NODISCARD inline
+ typename _proto_TypeTraits::Singular::MutableType
+ ReleaseExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ EnumOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {
+
+ return _proto_TypeTraits::Release(id.number(), _field_type,
+ &_extensions_);
+ }
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline typename _proto_TypeTraits::Singular::MutableType
+ UnsafeArenaReleaseExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ EnumOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {
+
+ return _proto_TypeTraits::UnsafeArenaRelease(id.number(), _field_type,
+ &_extensions_);
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline typename _proto_TypeTraits::Repeated::ConstType GetExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ EnumOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
+ int index) const {
+
+ return _proto_TypeTraits::Get(id.number(), _extensions_, index);
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline typename _proto_TypeTraits::Repeated::MutableType MutableExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ EnumOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
+ int index) {
+
+ return _proto_TypeTraits::Mutable(id.number(), index, &_extensions_);
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline void SetExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ EnumOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
+ int index, typename _proto_TypeTraits::Repeated::ConstType value) {
+ _proto_TypeTraits::Set(id.number(), index, value, &_extensions_);
+
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline typename _proto_TypeTraits::Repeated::MutableType AddExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ EnumOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {
+ typename _proto_TypeTraits::Repeated::MutableType to_add =
+ _proto_TypeTraits::Add(id.number(), _field_type, &_extensions_);
+
+ return to_add;
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline void AddExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ EnumOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
+ typename _proto_TypeTraits::Repeated::ConstType value) {
+ _proto_TypeTraits::Add(id.number(), _field_type, _is_packed, value,
+ &_extensions_);
+
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline const typename _proto_TypeTraits::Repeated::RepeatedFieldType&
+ GetRepeatedExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ EnumOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const {
+
+ return _proto_TypeTraits::GetRepeated(id.number(), _extensions_);
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline typename _proto_TypeTraits::Repeated::RepeatedFieldType*
+ MutableRepeatedExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ EnumOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {
+
+ return _proto_TypeTraits::MutableRepeated(id.number(), _field_type,
+ _is_packed, &_extensions_);
+ }
+
+ // @@protoc_insertion_point(class_scope:google.protobuf.EnumOptions)
+ private:
+ class _Internal;
+
+ ::PROTOBUF_NAMESPACE_ID::internal::ExtensionSet _extensions_;
+
+ template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
+ typedef void InternalArenaConstructable_;
+ typedef void DestructorSkippable_;
+ ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_;
+ mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
+ ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption > uninterpreted_option_;
+ bool allow_alias_;
+ bool deprecated_;
+ friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
+};
+// -------------------------------------------------------------------
+
+class PROTOBUF_EXPORT EnumValueOptions final :
+ public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.EnumValueOptions) */ {
+ public:
+ inline EnumValueOptions() : EnumValueOptions(nullptr) {}
+ ~EnumValueOptions() override;
+ explicit constexpr EnumValueOptions(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
+
+ EnumValueOptions(const EnumValueOptions& from);
+ EnumValueOptions(EnumValueOptions&& from) noexcept
+ : EnumValueOptions() {
+ *this = ::std::move(from);
+ }
+
+ inline EnumValueOptions& operator=(const EnumValueOptions& from) {
+ CopyFrom(from);
+ return *this;
+ }
+ inline EnumValueOptions& operator=(EnumValueOptions&& from) noexcept {
+ if (this == &from) return *this;
+ if (GetOwningArena() == from.GetOwningArena()
+ #ifdef PROTOBUF_FORCE_COPY_IN_MOVE
+ && GetOwningArena() != nullptr
+ #endif // !PROTOBUF_FORCE_COPY_IN_MOVE
+ ) {
+ InternalSwap(&from);
+ } else {
+ CopyFrom(from);
+ }
+ return *this;
+ }
+
+ inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const {
+ return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance);
+ }
+ inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() {
+ return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+ }
+
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
+ return GetDescriptor();
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
+ return default_instance().GetMetadata().descriptor;
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
+ return default_instance().GetMetadata().reflection;
+ }
+ static const EnumValueOptions& default_instance() {
+ return *internal_default_instance();
+ }
+ static inline const EnumValueOptions* internal_default_instance() {
+ return reinterpret_cast<const EnumValueOptions*>(
+ &_EnumValueOptions_default_instance_);
+ }
+ static constexpr int kIndexInFileMessages =
+ 18;
+
+ friend void swap(EnumValueOptions& a, EnumValueOptions& b) {
+ a.Swap(&b);
+ }
+ inline void Swap(EnumValueOptions* other) {
+ if (other == this) return;
+ #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() != nullptr &&
+ GetOwningArena() == other->GetOwningArena()) {
+ #else // PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() == other->GetOwningArena()) {
+ #endif // !PROTOBUF_FORCE_COPY_IN_SWAP
+ InternalSwap(other);
+ } else {
+ ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
+ }
+ }
+ void UnsafeArenaSwap(EnumValueOptions* other) {
+ if (other == this) return;
+ GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena());
+ InternalSwap(other);
+ }
+
+ // implements Message ----------------------------------------------
+
+ EnumValueOptions* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
+ return CreateMaybeMessage<EnumValueOptions>(arena);
+ }
+ using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
+ void CopyFrom(const EnumValueOptions& from);
+ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
+ void MergeFrom(const EnumValueOptions& from);
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from);
+ public:
+ PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+ bool IsInitialized() const final;
+
+ size_t ByteSizeLong() const final;
+ const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
+ uint8_t* _InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
+ int GetCachedSize() const final { return _cached_size_.Get(); }
+
+ private:
+ void SharedCtor();
+ void SharedDtor();
+ void SetCachedSize(int size) const final;
+ void InternalSwap(EnumValueOptions* other);
+
+ private:
+ friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
+ static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
+ return "google.protobuf.EnumValueOptions";
+ }
+ protected:
+ explicit EnumValueOptions(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned = false);
+ private:
+ static void ArenaDtor(void* object);
+ inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
+ public:
+
+ static const ClassData _class_data_;
+ const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;
+
+ ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;
+
+ // nested types ----------------------------------------------------
+
+ // accessors -------------------------------------------------------
+
+ enum : int {
+ kUninterpretedOptionFieldNumber = 999,
+ kDeprecatedFieldNumber = 1,
+ };
+ // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+ int uninterpreted_option_size() const;
+ private:
+ int _internal_uninterpreted_option_size() const;
+ public:
+ void clear_uninterpreted_option();
+ ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* mutable_uninterpreted_option(int index);
+ ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption >*
+ mutable_uninterpreted_option();
+ private:
+ const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption& _internal_uninterpreted_option(int index) const;
+ ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* _internal_add_uninterpreted_option();
+ public:
+ const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption& uninterpreted_option(int index) const;
+ ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* add_uninterpreted_option();
+ const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption >&
+ uninterpreted_option() const;
+
+ // optional bool deprecated = 1 [default = false];
+ bool has_deprecated() const;
+ private:
+ bool _internal_has_deprecated() const;
+ public:
+ void clear_deprecated();
+ bool deprecated() const;
+ void set_deprecated(bool value);
+ private:
+ bool _internal_deprecated() const;
+ void _internal_set_deprecated(bool value);
+ public:
+
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline bool HasExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ EnumValueOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const {
+
+ return _extensions_.Has(id.number());
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline void ClearExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ EnumValueOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {
+ _extensions_.ClearExtension(id.number());
+
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline int ExtensionSize(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ EnumValueOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const {
+
+ return _extensions_.ExtensionSize(id.number());
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline typename _proto_TypeTraits::Singular::ConstType GetExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ EnumValueOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const {
+
+ return _proto_TypeTraits::Get(id.number(), _extensions_,
+ id.default_value());
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline typename _proto_TypeTraits::Singular::MutableType MutableExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ EnumValueOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {
+
+ return _proto_TypeTraits::Mutable(id.number(), _field_type,
+ &_extensions_);
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline void SetExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ EnumValueOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
+ typename _proto_TypeTraits::Singular::ConstType value) {
+ _proto_TypeTraits::Set(id.number(), _field_type, value, &_extensions_);
+
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline void SetAllocatedExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ EnumValueOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
+ typename _proto_TypeTraits::Singular::MutableType value) {
+ _proto_TypeTraits::SetAllocated(id.number(), _field_type, value,
+ &_extensions_);
+
+ }
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline void UnsafeArenaSetAllocatedExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ EnumValueOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
+ typename _proto_TypeTraits::Singular::MutableType value) {
+ _proto_TypeTraits::UnsafeArenaSetAllocated(id.number(), _field_type,
+ value, &_extensions_);
+
+ }
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ PROTOBUF_NODISCARD inline
+ typename _proto_TypeTraits::Singular::MutableType
+ ReleaseExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ EnumValueOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {
+
+ return _proto_TypeTraits::Release(id.number(), _field_type,
+ &_extensions_);
+ }
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline typename _proto_TypeTraits::Singular::MutableType
+ UnsafeArenaReleaseExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ EnumValueOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {
+
+ return _proto_TypeTraits::UnsafeArenaRelease(id.number(), _field_type,
+ &_extensions_);
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline typename _proto_TypeTraits::Repeated::ConstType GetExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ EnumValueOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
+ int index) const {
+
+ return _proto_TypeTraits::Get(id.number(), _extensions_, index);
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline typename _proto_TypeTraits::Repeated::MutableType MutableExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ EnumValueOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
+ int index) {
+
+ return _proto_TypeTraits::Mutable(id.number(), index, &_extensions_);
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline void SetExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ EnumValueOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
+ int index, typename _proto_TypeTraits::Repeated::ConstType value) {
+ _proto_TypeTraits::Set(id.number(), index, value, &_extensions_);
+
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline typename _proto_TypeTraits::Repeated::MutableType AddExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ EnumValueOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {
+ typename _proto_TypeTraits::Repeated::MutableType to_add =
+ _proto_TypeTraits::Add(id.number(), _field_type, &_extensions_);
+
+ return to_add;
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline void AddExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ EnumValueOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
+ typename _proto_TypeTraits::Repeated::ConstType value) {
+ _proto_TypeTraits::Add(id.number(), _field_type, _is_packed, value,
+ &_extensions_);
+
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline const typename _proto_TypeTraits::Repeated::RepeatedFieldType&
+ GetRepeatedExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ EnumValueOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const {
+
+ return _proto_TypeTraits::GetRepeated(id.number(), _extensions_);
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline typename _proto_TypeTraits::Repeated::RepeatedFieldType*
+ MutableRepeatedExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ EnumValueOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {
+
+ return _proto_TypeTraits::MutableRepeated(id.number(), _field_type,
+ _is_packed, &_extensions_);
+ }
+
+ // @@protoc_insertion_point(class_scope:google.protobuf.EnumValueOptions)
+ private:
+ class _Internal;
+
+ ::PROTOBUF_NAMESPACE_ID::internal::ExtensionSet _extensions_;
+
+ template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
+ typedef void InternalArenaConstructable_;
+ typedef void DestructorSkippable_;
+ ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_;
+ mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
+ ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption > uninterpreted_option_;
+ bool deprecated_;
+ friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
+};
+// -------------------------------------------------------------------
+
+class PROTOBUF_EXPORT ServiceOptions final :
+ public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.ServiceOptions) */ {
+ public:
+ inline ServiceOptions() : ServiceOptions(nullptr) {}
+ ~ServiceOptions() override;
+ explicit constexpr ServiceOptions(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
+
+ ServiceOptions(const ServiceOptions& from);
+ ServiceOptions(ServiceOptions&& from) noexcept
+ : ServiceOptions() {
+ *this = ::std::move(from);
+ }
+
+ inline ServiceOptions& operator=(const ServiceOptions& from) {
+ CopyFrom(from);
+ return *this;
+ }
+ inline ServiceOptions& operator=(ServiceOptions&& from) noexcept {
+ if (this == &from) return *this;
+ if (GetOwningArena() == from.GetOwningArena()
+ #ifdef PROTOBUF_FORCE_COPY_IN_MOVE
+ && GetOwningArena() != nullptr
+ #endif // !PROTOBUF_FORCE_COPY_IN_MOVE
+ ) {
+ InternalSwap(&from);
+ } else {
+ CopyFrom(from);
+ }
+ return *this;
+ }
+
+ inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const {
+ return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance);
+ }
+ inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() {
+ return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+ }
+
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
+ return GetDescriptor();
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
+ return default_instance().GetMetadata().descriptor;
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
+ return default_instance().GetMetadata().reflection;
+ }
+ static const ServiceOptions& default_instance() {
+ return *internal_default_instance();
+ }
+ static inline const ServiceOptions* internal_default_instance() {
+ return reinterpret_cast<const ServiceOptions*>(
+ &_ServiceOptions_default_instance_);
+ }
+ static constexpr int kIndexInFileMessages =
+ 19;
+
+ friend void swap(ServiceOptions& a, ServiceOptions& b) {
+ a.Swap(&b);
+ }
+ inline void Swap(ServiceOptions* other) {
+ if (other == this) return;
+ #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() != nullptr &&
+ GetOwningArena() == other->GetOwningArena()) {
+ #else // PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() == other->GetOwningArena()) {
+ #endif // !PROTOBUF_FORCE_COPY_IN_SWAP
+ InternalSwap(other);
+ } else {
+ ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
+ }
+ }
+ void UnsafeArenaSwap(ServiceOptions* other) {
+ if (other == this) return;
+ GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena());
+ InternalSwap(other);
+ }
+
+ // implements Message ----------------------------------------------
+
+ ServiceOptions* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
+ return CreateMaybeMessage<ServiceOptions>(arena);
+ }
+ using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
+ void CopyFrom(const ServiceOptions& from);
+ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
+ void MergeFrom(const ServiceOptions& from);
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from);
+ public:
+ PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+ bool IsInitialized() const final;
+
+ size_t ByteSizeLong() const final;
+ const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
+ uint8_t* _InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
+ int GetCachedSize() const final { return _cached_size_.Get(); }
+
+ private:
+ void SharedCtor();
+ void SharedDtor();
+ void SetCachedSize(int size) const final;
+ void InternalSwap(ServiceOptions* other);
+
+ private:
+ friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
+ static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
+ return "google.protobuf.ServiceOptions";
+ }
+ protected:
+ explicit ServiceOptions(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned = false);
+ private:
+ static void ArenaDtor(void* object);
+ inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
+ public:
+
+ static const ClassData _class_data_;
+ const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;
+
+ ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;
+
+ // nested types ----------------------------------------------------
+
+ // accessors -------------------------------------------------------
+
+ enum : int {
+ kUninterpretedOptionFieldNumber = 999,
+ kDeprecatedFieldNumber = 33,
+ };
+ // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+ int uninterpreted_option_size() const;
+ private:
+ int _internal_uninterpreted_option_size() const;
+ public:
+ void clear_uninterpreted_option();
+ ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* mutable_uninterpreted_option(int index);
+ ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption >*
+ mutable_uninterpreted_option();
+ private:
+ const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption& _internal_uninterpreted_option(int index) const;
+ ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* _internal_add_uninterpreted_option();
+ public:
+ const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption& uninterpreted_option(int index) const;
+ ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* add_uninterpreted_option();
+ const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption >&
+ uninterpreted_option() const;
+
+ // optional bool deprecated = 33 [default = false];
+ bool has_deprecated() const;
+ private:
+ bool _internal_has_deprecated() const;
+ public:
+ void clear_deprecated();
+ bool deprecated() const;
+ void set_deprecated(bool value);
+ private:
+ bool _internal_deprecated() const;
+ void _internal_set_deprecated(bool value);
+ public:
+
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline bool HasExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ ServiceOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const {
+
+ return _extensions_.Has(id.number());
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline void ClearExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ ServiceOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {
+ _extensions_.ClearExtension(id.number());
+
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline int ExtensionSize(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ ServiceOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const {
+
+ return _extensions_.ExtensionSize(id.number());
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline typename _proto_TypeTraits::Singular::ConstType GetExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ ServiceOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const {
+
+ return _proto_TypeTraits::Get(id.number(), _extensions_,
+ id.default_value());
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline typename _proto_TypeTraits::Singular::MutableType MutableExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ ServiceOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {
+
+ return _proto_TypeTraits::Mutable(id.number(), _field_type,
+ &_extensions_);
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline void SetExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ ServiceOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
+ typename _proto_TypeTraits::Singular::ConstType value) {
+ _proto_TypeTraits::Set(id.number(), _field_type, value, &_extensions_);
+
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline void SetAllocatedExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ ServiceOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
+ typename _proto_TypeTraits::Singular::MutableType value) {
+ _proto_TypeTraits::SetAllocated(id.number(), _field_type, value,
+ &_extensions_);
+
+ }
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline void UnsafeArenaSetAllocatedExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ ServiceOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
+ typename _proto_TypeTraits::Singular::MutableType value) {
+ _proto_TypeTraits::UnsafeArenaSetAllocated(id.number(), _field_type,
+ value, &_extensions_);
+
+ }
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ PROTOBUF_NODISCARD inline
+ typename _proto_TypeTraits::Singular::MutableType
+ ReleaseExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ ServiceOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {
+
+ return _proto_TypeTraits::Release(id.number(), _field_type,
+ &_extensions_);
+ }
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline typename _proto_TypeTraits::Singular::MutableType
+ UnsafeArenaReleaseExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ ServiceOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {
+
+ return _proto_TypeTraits::UnsafeArenaRelease(id.number(), _field_type,
+ &_extensions_);
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline typename _proto_TypeTraits::Repeated::ConstType GetExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ ServiceOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
+ int index) const {
+
+ return _proto_TypeTraits::Get(id.number(), _extensions_, index);
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline typename _proto_TypeTraits::Repeated::MutableType MutableExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ ServiceOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
+ int index) {
+
+ return _proto_TypeTraits::Mutable(id.number(), index, &_extensions_);
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline void SetExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ ServiceOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
+ int index, typename _proto_TypeTraits::Repeated::ConstType value) {
+ _proto_TypeTraits::Set(id.number(), index, value, &_extensions_);
+
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline typename _proto_TypeTraits::Repeated::MutableType AddExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ ServiceOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {
+ typename _proto_TypeTraits::Repeated::MutableType to_add =
+ _proto_TypeTraits::Add(id.number(), _field_type, &_extensions_);
+
+ return to_add;
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline void AddExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ ServiceOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
+ typename _proto_TypeTraits::Repeated::ConstType value) {
+ _proto_TypeTraits::Add(id.number(), _field_type, _is_packed, value,
+ &_extensions_);
+
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline const typename _proto_TypeTraits::Repeated::RepeatedFieldType&
+ GetRepeatedExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ ServiceOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const {
+
+ return _proto_TypeTraits::GetRepeated(id.number(), _extensions_);
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline typename _proto_TypeTraits::Repeated::RepeatedFieldType*
+ MutableRepeatedExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ ServiceOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {
+
+ return _proto_TypeTraits::MutableRepeated(id.number(), _field_type,
+ _is_packed, &_extensions_);
+ }
+
+ // @@protoc_insertion_point(class_scope:google.protobuf.ServiceOptions)
+ private:
+ class _Internal;
+
+ ::PROTOBUF_NAMESPACE_ID::internal::ExtensionSet _extensions_;
+
+ template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
+ typedef void InternalArenaConstructable_;
+ typedef void DestructorSkippable_;
+ ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_;
+ mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
+ ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption > uninterpreted_option_;
+ bool deprecated_;
+ friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
+};
+// -------------------------------------------------------------------
+
+class PROTOBUF_EXPORT MethodOptions final :
+ public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.MethodOptions) */ {
+ public:
+ inline MethodOptions() : MethodOptions(nullptr) {}
+ ~MethodOptions() override;
+ explicit constexpr MethodOptions(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
+
+ MethodOptions(const MethodOptions& from);
+ MethodOptions(MethodOptions&& from) noexcept
+ : MethodOptions() {
+ *this = ::std::move(from);
+ }
+
+ inline MethodOptions& operator=(const MethodOptions& from) {
+ CopyFrom(from);
+ return *this;
+ }
+ inline MethodOptions& operator=(MethodOptions&& from) noexcept {
+ if (this == &from) return *this;
+ if (GetOwningArena() == from.GetOwningArena()
+ #ifdef PROTOBUF_FORCE_COPY_IN_MOVE
+ && GetOwningArena() != nullptr
+ #endif // !PROTOBUF_FORCE_COPY_IN_MOVE
+ ) {
+ InternalSwap(&from);
+ } else {
+ CopyFrom(from);
+ }
+ return *this;
+ }
+
+ inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const {
+ return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance);
+ }
+ inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() {
+ return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+ }
+
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
+ return GetDescriptor();
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
+ return default_instance().GetMetadata().descriptor;
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
+ return default_instance().GetMetadata().reflection;
+ }
+ static const MethodOptions& default_instance() {
+ return *internal_default_instance();
+ }
+ static inline const MethodOptions* internal_default_instance() {
+ return reinterpret_cast<const MethodOptions*>(
+ &_MethodOptions_default_instance_);
+ }
+ static constexpr int kIndexInFileMessages =
+ 20;
+
+ friend void swap(MethodOptions& a, MethodOptions& b) {
+ a.Swap(&b);
+ }
+ inline void Swap(MethodOptions* other) {
+ if (other == this) return;
+ #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() != nullptr &&
+ GetOwningArena() == other->GetOwningArena()) {
+ #else // PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() == other->GetOwningArena()) {
+ #endif // !PROTOBUF_FORCE_COPY_IN_SWAP
+ InternalSwap(other);
+ } else {
+ ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
+ }
+ }
+ void UnsafeArenaSwap(MethodOptions* other) {
+ if (other == this) return;
+ GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena());
+ InternalSwap(other);
+ }
+
+ // implements Message ----------------------------------------------
+
+ MethodOptions* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
+ return CreateMaybeMessage<MethodOptions>(arena);
+ }
+ using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
+ void CopyFrom(const MethodOptions& from);
+ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
+ void MergeFrom(const MethodOptions& from);
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from);
+ public:
+ PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+ bool IsInitialized() const final;
+
+ size_t ByteSizeLong() const final;
+ const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
+ uint8_t* _InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
+ int GetCachedSize() const final { return _cached_size_.Get(); }
+
+ private:
+ void SharedCtor();
+ void SharedDtor();
+ void SetCachedSize(int size) const final;
+ void InternalSwap(MethodOptions* other);
+
+ private:
+ friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
+ static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
+ return "google.protobuf.MethodOptions";
+ }
+ protected:
+ explicit MethodOptions(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned = false);
+ private:
+ static void ArenaDtor(void* object);
+ inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
+ public:
+
+ static const ClassData _class_data_;
+ const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;
+
+ ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;
+
+ // nested types ----------------------------------------------------
+
+ typedef MethodOptions_IdempotencyLevel IdempotencyLevel;
+ static constexpr IdempotencyLevel IDEMPOTENCY_UNKNOWN =
+ MethodOptions_IdempotencyLevel_IDEMPOTENCY_UNKNOWN;
+ static constexpr IdempotencyLevel NO_SIDE_EFFECTS =
+ MethodOptions_IdempotencyLevel_NO_SIDE_EFFECTS;
+ static constexpr IdempotencyLevel IDEMPOTENT =
+ MethodOptions_IdempotencyLevel_IDEMPOTENT;
+ static inline bool IdempotencyLevel_IsValid(int value) {
+ return MethodOptions_IdempotencyLevel_IsValid(value);
+ }
+ static constexpr IdempotencyLevel IdempotencyLevel_MIN =
+ MethodOptions_IdempotencyLevel_IdempotencyLevel_MIN;
+ static constexpr IdempotencyLevel IdempotencyLevel_MAX =
+ MethodOptions_IdempotencyLevel_IdempotencyLevel_MAX;
+ static constexpr int IdempotencyLevel_ARRAYSIZE =
+ MethodOptions_IdempotencyLevel_IdempotencyLevel_ARRAYSIZE;
+ static inline const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor*
+ IdempotencyLevel_descriptor() {
+ return MethodOptions_IdempotencyLevel_descriptor();
+ }
+ template<typename T>
+ static inline const 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 _extensions_.Has(id.number());
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline void ClearExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ MethodOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {
+ _extensions_.ClearExtension(id.number());
+
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline int ExtensionSize(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ MethodOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const {
+
+ return _extensions_.ExtensionSize(id.number());
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline typename _proto_TypeTraits::Singular::ConstType GetExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ MethodOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const {
+
+ return _proto_TypeTraits::Get(id.number(), _extensions_,
+ id.default_value());
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline typename _proto_TypeTraits::Singular::MutableType MutableExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ MethodOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {
+
+ return _proto_TypeTraits::Mutable(id.number(), _field_type,
+ &_extensions_);
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline void SetExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ MethodOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
+ typename _proto_TypeTraits::Singular::ConstType value) {
+ _proto_TypeTraits::Set(id.number(), _field_type, value, &_extensions_);
+
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline void SetAllocatedExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ MethodOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
+ typename _proto_TypeTraits::Singular::MutableType value) {
+ _proto_TypeTraits::SetAllocated(id.number(), _field_type, value,
+ &_extensions_);
+
+ }
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline void UnsafeArenaSetAllocatedExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ MethodOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
+ typename _proto_TypeTraits::Singular::MutableType value) {
+ _proto_TypeTraits::UnsafeArenaSetAllocated(id.number(), _field_type,
+ value, &_extensions_);
+
+ }
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ PROTOBUF_NODISCARD inline
+ typename _proto_TypeTraits::Singular::MutableType
+ ReleaseExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ MethodOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {
+
+ return _proto_TypeTraits::Release(id.number(), _field_type,
+ &_extensions_);
+ }
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline typename _proto_TypeTraits::Singular::MutableType
+ UnsafeArenaReleaseExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ MethodOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {
+
+ return _proto_TypeTraits::UnsafeArenaRelease(id.number(), _field_type,
+ &_extensions_);
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline typename _proto_TypeTraits::Repeated::ConstType GetExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ MethodOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
+ int index) const {
+
+ return _proto_TypeTraits::Get(id.number(), _extensions_, index);
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline typename _proto_TypeTraits::Repeated::MutableType MutableExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ MethodOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
+ int index) {
+
+ return _proto_TypeTraits::Mutable(id.number(), index, &_extensions_);
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline void SetExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ MethodOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
+ int index, typename _proto_TypeTraits::Repeated::ConstType value) {
+ _proto_TypeTraits::Set(id.number(), index, value, &_extensions_);
+
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline typename _proto_TypeTraits::Repeated::MutableType AddExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ MethodOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {
+ typename _proto_TypeTraits::Repeated::MutableType to_add =
+ _proto_TypeTraits::Add(id.number(), _field_type, &_extensions_);
+
+ return to_add;
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline void AddExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ MethodOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
+ typename _proto_TypeTraits::Repeated::ConstType value) {
+ _proto_TypeTraits::Add(id.number(), _field_type, _is_packed, value,
+ &_extensions_);
+
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline const typename _proto_TypeTraits::Repeated::RepeatedFieldType&
+ GetRepeatedExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ MethodOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const {
+
+ return _proto_TypeTraits::GetRepeated(id.number(), _extensions_);
+ }
+
+ template <typename _proto_TypeTraits,
+ ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
+ bool _is_packed>
+ inline typename _proto_TypeTraits::Repeated::RepeatedFieldType*
+ MutableRepeatedExtension(
+ const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
+ MethodOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {
+
+ return _proto_TypeTraits::MutableRepeated(id.number(), _field_type,
+ _is_packed, &_extensions_);
+ }
+
+ // @@protoc_insertion_point(class_scope:google.protobuf.MethodOptions)
+ private:
+ class _Internal;
+
+ ::PROTOBUF_NAMESPACE_ID::internal::ExtensionSet _extensions_;
+
+ template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
+ typedef void InternalArenaConstructable_;
+ typedef void DestructorSkippable_;
+ ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_;
+ mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
+ ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption > uninterpreted_option_;
+ bool deprecated_;
+ int idempotency_level_;
+ friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
+};
+// -------------------------------------------------------------------
+
+class PROTOBUF_EXPORT UninterpretedOption_NamePart final :
+ public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.UninterpretedOption.NamePart) */ {
+ public:
+ inline UninterpretedOption_NamePart() : UninterpretedOption_NamePart(nullptr) {}
+ ~UninterpretedOption_NamePart() override;
+ explicit constexpr UninterpretedOption_NamePart(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
+
+ UninterpretedOption_NamePart(const UninterpretedOption_NamePart& from);
+ UninterpretedOption_NamePart(UninterpretedOption_NamePart&& from) noexcept
+ : UninterpretedOption_NamePart() {
+ *this = ::std::move(from);
+ }
+
+ inline UninterpretedOption_NamePart& operator=(const UninterpretedOption_NamePart& from) {
+ CopyFrom(from);
+ return *this;
+ }
+ inline UninterpretedOption_NamePart& operator=(UninterpretedOption_NamePart&& from) noexcept {
+ if (this == &from) return *this;
+ if (GetOwningArena() == from.GetOwningArena()
+ #ifdef PROTOBUF_FORCE_COPY_IN_MOVE
+ && GetOwningArena() != nullptr
+ #endif // !PROTOBUF_FORCE_COPY_IN_MOVE
+ ) {
+ InternalSwap(&from);
+ } else {
+ CopyFrom(from);
+ }
+ return *this;
+ }
+
+ inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const {
+ return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance);
+ }
+ inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() {
+ return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+ }
+
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
+ return GetDescriptor();
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
+ return default_instance().GetMetadata().descriptor;
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
+ return default_instance().GetMetadata().reflection;
+ }
+ static const UninterpretedOption_NamePart& default_instance() {
+ return *internal_default_instance();
+ }
+ static inline const UninterpretedOption_NamePart* internal_default_instance() {
+ return reinterpret_cast<const UninterpretedOption_NamePart*>(
+ &_UninterpretedOption_NamePart_default_instance_);
+ }
+ static constexpr int kIndexInFileMessages =
+ 21;
+
+ friend void swap(UninterpretedOption_NamePart& a, UninterpretedOption_NamePart& b) {
+ a.Swap(&b);
+ }
+ inline void Swap(UninterpretedOption_NamePart* other) {
+ if (other == this) return;
+ #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() != nullptr &&
+ GetOwningArena() == other->GetOwningArena()) {
+ #else // PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() == other->GetOwningArena()) {
+ #endif // !PROTOBUF_FORCE_COPY_IN_SWAP
+ InternalSwap(other);
+ } else {
+ ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
+ }
+ }
+ void UnsafeArenaSwap(UninterpretedOption_NamePart* other) {
+ if (other == this) return;
+ GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena());
+ InternalSwap(other);
+ }
+
+ // implements Message ----------------------------------------------
+
+ UninterpretedOption_NamePart* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
+ return CreateMaybeMessage<UninterpretedOption_NamePart>(arena);
+ }
+ using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
+ void CopyFrom(const UninterpretedOption_NamePart& from);
+ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
+ void MergeFrom(const UninterpretedOption_NamePart& from);
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from);
+ public:
+ PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+ bool IsInitialized() const final;
+
+ size_t ByteSizeLong() const final;
+ const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
+ uint8_t* _InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
+ int GetCachedSize() const final { return _cached_size_.Get(); }
+
+ private:
+ void SharedCtor();
+ void SharedDtor();
+ void SetCachedSize(int size) const final;
+ void InternalSwap(UninterpretedOption_NamePart* other);
+
+ private:
+ friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
+ static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
+ return "google.protobuf.UninterpretedOption.NamePart";
+ }
+ protected:
+ explicit UninterpretedOption_NamePart(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned = false);
+ private:
+ static void ArenaDtor(void* object);
+ inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
+ public:
+
+ static const ClassData _class_data_;
+ const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;
+
+ ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;
+
+ // nested types ----------------------------------------------------
+
+ // accessors -------------------------------------------------------
+
+ enum : int {
+ kNamePartFieldNumber = 1,
+ kIsExtensionFieldNumber = 2,
+ };
+ // required string name_part = 1;
+ bool has_name_part() const;
+ private:
+ bool _internal_has_name_part() const;
+ public:
+ void clear_name_part();
+ const 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_;
+ ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_;
+ mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr name_part_;
+ bool is_extension_;
+ friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
+};
+// -------------------------------------------------------------------
+
+class PROTOBUF_EXPORT UninterpretedOption final :
+ public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.UninterpretedOption) */ {
+ public:
+ inline UninterpretedOption() : UninterpretedOption(nullptr) {}
+ ~UninterpretedOption() override;
+ explicit constexpr UninterpretedOption(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
+
+ UninterpretedOption(const UninterpretedOption& from);
+ UninterpretedOption(UninterpretedOption&& from) noexcept
+ : UninterpretedOption() {
+ *this = ::std::move(from);
+ }
+
+ inline UninterpretedOption& operator=(const UninterpretedOption& from) {
+ CopyFrom(from);
+ return *this;
+ }
+ inline UninterpretedOption& operator=(UninterpretedOption&& from) noexcept {
+ if (this == &from) return *this;
+ if (GetOwningArena() == from.GetOwningArena()
+ #ifdef PROTOBUF_FORCE_COPY_IN_MOVE
+ && GetOwningArena() != nullptr
+ #endif // !PROTOBUF_FORCE_COPY_IN_MOVE
+ ) {
+ InternalSwap(&from);
+ } else {
+ CopyFrom(from);
+ }
+ return *this;
+ }
+
+ inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const {
+ return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance);
+ }
+ inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() {
+ return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+ }
+
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
+ return GetDescriptor();
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
+ return default_instance().GetMetadata().descriptor;
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
+ return default_instance().GetMetadata().reflection;
+ }
+ static const UninterpretedOption& default_instance() {
+ return *internal_default_instance();
+ }
+ static inline const UninterpretedOption* internal_default_instance() {
+ return reinterpret_cast<const UninterpretedOption*>(
+ &_UninterpretedOption_default_instance_);
+ }
+ static constexpr int kIndexInFileMessages =
+ 22;
+
+ friend void swap(UninterpretedOption& a, UninterpretedOption& b) {
+ a.Swap(&b);
+ }
+ inline void Swap(UninterpretedOption* other) {
+ if (other == this) return;
+ #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() != nullptr &&
+ GetOwningArena() == other->GetOwningArena()) {
+ #else // PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() == other->GetOwningArena()) {
+ #endif // !PROTOBUF_FORCE_COPY_IN_SWAP
+ InternalSwap(other);
+ } else {
+ ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
+ }
+ }
+ void UnsafeArenaSwap(UninterpretedOption* other) {
+ if (other == this) return;
+ GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena());
+ InternalSwap(other);
+ }
+
+ // implements Message ----------------------------------------------
+
+ UninterpretedOption* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
+ return CreateMaybeMessage<UninterpretedOption>(arena);
+ }
+ using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
+ void CopyFrom(const UninterpretedOption& from);
+ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
+ void MergeFrom(const UninterpretedOption& from);
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from);
+ public:
+ PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+ bool IsInitialized() const final;
+
+ size_t ByteSizeLong() const final;
+ const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
+ uint8_t* _InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
+ int GetCachedSize() const final { return _cached_size_.Get(); }
+
+ private:
+ void SharedCtor();
+ void SharedDtor();
+ void SetCachedSize(int size) const final;
+ void InternalSwap(UninterpretedOption* other);
+
+ private:
+ friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
+ static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
+ return "google.protobuf.UninterpretedOption";
+ }
+ protected:
+ explicit UninterpretedOption(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned = false);
+ private:
+ static void ArenaDtor(void* object);
+ inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
+ public:
+
+ static const ClassData _class_data_;
+ const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;
+
+ ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;
+
+ // nested types ----------------------------------------------------
+
+ typedef UninterpretedOption_NamePart NamePart;
+
+ // accessors -------------------------------------------------------
+
+ enum : int {
+ kNameFieldNumber = 2,
+ kIdentifierValueFieldNumber = 3,
+ kStringValueFieldNumber = 7,
+ kAggregateValueFieldNumber = 8,
+ kPositiveIntValueFieldNumber = 4,
+ kNegativeIntValueFieldNumber = 5,
+ kDoubleValueFieldNumber = 6,
+ };
+ // repeated .google.protobuf.UninterpretedOption.NamePart name = 2;
+ int name_size() const;
+ private:
+ int _internal_name_size() const;
+ public:
+ void clear_name();
+ ::PROTOBUF_NAMESPACE_ID::UninterpretedOption_NamePart* mutable_name(int index);
+ ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption_NamePart >*
+ mutable_name();
+ private:
+ const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption_NamePart& _internal_name(int index) const;
+ ::PROTOBUF_NAMESPACE_ID::UninterpretedOption_NamePart* _internal_add_name();
+ public:
+ const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption_NamePart& name(int index) const;
+ ::PROTOBUF_NAMESPACE_ID::UninterpretedOption_NamePart* add_name();
+ const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption_NamePart >&
+ name() const;
+
+ // optional string identifier_value = 3;
+ bool has_identifier_value() const;
+ private:
+ bool _internal_has_identifier_value() const;
+ public:
+ void clear_identifier_value();
+ const 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_;
+ ::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_;
+ friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
+};
+// -------------------------------------------------------------------
+
+class PROTOBUF_EXPORT SourceCodeInfo_Location final :
+ public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.SourceCodeInfo.Location) */ {
+ public:
+ inline SourceCodeInfo_Location() : SourceCodeInfo_Location(nullptr) {}
+ ~SourceCodeInfo_Location() override;
+ explicit constexpr SourceCodeInfo_Location(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
+
+ SourceCodeInfo_Location(const SourceCodeInfo_Location& from);
+ SourceCodeInfo_Location(SourceCodeInfo_Location&& from) noexcept
+ : SourceCodeInfo_Location() {
+ *this = ::std::move(from);
+ }
+
+ inline SourceCodeInfo_Location& operator=(const SourceCodeInfo_Location& from) {
+ CopyFrom(from);
+ return *this;
+ }
+ inline SourceCodeInfo_Location& operator=(SourceCodeInfo_Location&& from) noexcept {
+ if (this == &from) return *this;
+ if (GetOwningArena() == from.GetOwningArena()
+ #ifdef PROTOBUF_FORCE_COPY_IN_MOVE
+ && GetOwningArena() != nullptr
+ #endif // !PROTOBUF_FORCE_COPY_IN_MOVE
+ ) {
+ InternalSwap(&from);
+ } else {
+ CopyFrom(from);
+ }
+ return *this;
+ }
+
+ inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const {
+ return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance);
+ }
+ inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() {
+ return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+ }
+
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
+ return GetDescriptor();
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
+ return default_instance().GetMetadata().descriptor;
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
+ return default_instance().GetMetadata().reflection;
+ }
+ static const SourceCodeInfo_Location& default_instance() {
+ return *internal_default_instance();
+ }
+ static inline const SourceCodeInfo_Location* internal_default_instance() {
+ return reinterpret_cast<const SourceCodeInfo_Location*>(
+ &_SourceCodeInfo_Location_default_instance_);
+ }
+ static constexpr int kIndexInFileMessages =
+ 23;
+
+ friend void swap(SourceCodeInfo_Location& a, SourceCodeInfo_Location& b) {
+ a.Swap(&b);
+ }
+ inline void Swap(SourceCodeInfo_Location* other) {
+ if (other == this) return;
+ #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() != nullptr &&
+ GetOwningArena() == other->GetOwningArena()) {
+ #else // PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() == other->GetOwningArena()) {
+ #endif // !PROTOBUF_FORCE_COPY_IN_SWAP
+ InternalSwap(other);
+ } else {
+ ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
+ }
+ }
+ void UnsafeArenaSwap(SourceCodeInfo_Location* other) {
+ if (other == this) return;
+ GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena());
+ InternalSwap(other);
+ }
+
+ // implements Message ----------------------------------------------
+
+ SourceCodeInfo_Location* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
+ return CreateMaybeMessage<SourceCodeInfo_Location>(arena);
+ }
+ using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
+ void CopyFrom(const SourceCodeInfo_Location& from);
+ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
+ void MergeFrom(const SourceCodeInfo_Location& from);
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from);
+ public:
+ PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+ bool IsInitialized() const final;
+
+ size_t ByteSizeLong() const final;
+ const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
+ uint8_t* _InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
+ int GetCachedSize() const final { return _cached_size_.Get(); }
+
+ private:
+ void SharedCtor();
+ void SharedDtor();
+ void SetCachedSize(int size) const final;
+ void InternalSwap(SourceCodeInfo_Location* other);
+
+ private:
+ friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
+ static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
+ return "google.protobuf.SourceCodeInfo.Location";
+ }
+ protected:
+ explicit SourceCodeInfo_Location(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned = false);
+ private:
+ static void ArenaDtor(void* object);
+ inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
+ public:
+
+ static const ClassData _class_data_;
+ const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;
+
+ ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;
+
+ // nested types ----------------------------------------------------
+
+ // accessors -------------------------------------------------------
+
+ enum : int {
+ kPathFieldNumber = 1,
+ kSpanFieldNumber = 2,
+ kLeadingDetachedCommentsFieldNumber = 6,
+ kLeadingCommentsFieldNumber = 3,
+ kTrailingCommentsFieldNumber = 4,
+ };
+ // repeated int32 path = 1 [packed = true];
+ int path_size() const;
+ private:
+ int _internal_path_size() const;
+ public:
+ void clear_path();
+ private:
+ 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_;
+ ::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_;
+ friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
+};
+// -------------------------------------------------------------------
+
+class PROTOBUF_EXPORT SourceCodeInfo final :
+ public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.SourceCodeInfo) */ {
+ public:
+ inline SourceCodeInfo() : SourceCodeInfo(nullptr) {}
+ ~SourceCodeInfo() override;
+ explicit constexpr SourceCodeInfo(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
+
+ SourceCodeInfo(const SourceCodeInfo& from);
+ SourceCodeInfo(SourceCodeInfo&& from) noexcept
+ : SourceCodeInfo() {
+ *this = ::std::move(from);
+ }
+
+ inline SourceCodeInfo& operator=(const SourceCodeInfo& from) {
+ CopyFrom(from);
+ return *this;
+ }
+ inline SourceCodeInfo& operator=(SourceCodeInfo&& from) noexcept {
+ if (this == &from) return *this;
+ if (GetOwningArena() == from.GetOwningArena()
+ #ifdef PROTOBUF_FORCE_COPY_IN_MOVE
+ && GetOwningArena() != nullptr
+ #endif // !PROTOBUF_FORCE_COPY_IN_MOVE
+ ) {
+ InternalSwap(&from);
+ } else {
+ CopyFrom(from);
+ }
+ return *this;
+ }
+
+ inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const {
+ return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance);
+ }
+ inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() {
+ return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+ }
+
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
+ return GetDescriptor();
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
+ return default_instance().GetMetadata().descriptor;
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
+ return default_instance().GetMetadata().reflection;
+ }
+ static const SourceCodeInfo& default_instance() {
+ return *internal_default_instance();
+ }
+ static inline const SourceCodeInfo* internal_default_instance() {
+ return reinterpret_cast<const SourceCodeInfo*>(
+ &_SourceCodeInfo_default_instance_);
+ }
+ static constexpr int kIndexInFileMessages =
+ 24;
+
+ friend void swap(SourceCodeInfo& a, SourceCodeInfo& b) {
+ a.Swap(&b);
+ }
+ inline void Swap(SourceCodeInfo* other) {
+ if (other == this) return;
+ #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() != nullptr &&
+ GetOwningArena() == other->GetOwningArena()) {
+ #else // PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() == other->GetOwningArena()) {
+ #endif // !PROTOBUF_FORCE_COPY_IN_SWAP
+ InternalSwap(other);
+ } else {
+ ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
+ }
+ }
+ void UnsafeArenaSwap(SourceCodeInfo* other) {
+ if (other == this) return;
+ GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena());
+ InternalSwap(other);
+ }
+
+ // implements Message ----------------------------------------------
+
+ SourceCodeInfo* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
+ return CreateMaybeMessage<SourceCodeInfo>(arena);
+ }
+ using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
+ void CopyFrom(const SourceCodeInfo& from);
+ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
+ void MergeFrom(const SourceCodeInfo& from);
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from);
+ public:
+ PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+ bool IsInitialized() const final;
+
+ size_t ByteSizeLong() const final;
+ const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
+ uint8_t* _InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
+ int GetCachedSize() const final { return _cached_size_.Get(); }
+
+ private:
+ void SharedCtor();
+ void SharedDtor();
+ void SetCachedSize(int size) const final;
+ void InternalSwap(SourceCodeInfo* other);
+
+ private:
+ friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
+ static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
+ return "google.protobuf.SourceCodeInfo";
+ }
+ protected:
+ explicit SourceCodeInfo(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned = false);
+ private:
+ static void ArenaDtor(void* object);
+ inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
+ public:
+
+ static const ClassData _class_data_;
+ const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;
+
+ ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;
+
+ // nested types ----------------------------------------------------
+
+ typedef SourceCodeInfo_Location Location;
+
+ // accessors -------------------------------------------------------
+
+ enum : int {
+ kLocationFieldNumber = 1,
+ };
+ // repeated .google.protobuf.SourceCodeInfo.Location location = 1;
+ int location_size() const;
+ private:
+ int _internal_location_size() const;
+ public:
+ void clear_location();
+ ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location* mutable_location(int index);
+ ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location >*
+ mutable_location();
+ private:
+ const ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location& _internal_location(int index) const;
+ ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location* _internal_add_location();
+ public:
+ const ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location& location(int index) const;
+ ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location* add_location();
+ const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location >&
+ location() const;
+
+ // @@protoc_insertion_point(class_scope:google.protobuf.SourceCodeInfo)
+ private:
+ class _Internal;
+
+ template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
+ typedef void InternalArenaConstructable_;
+ typedef void DestructorSkippable_;
+ ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location > location_;
+ mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
+ friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
+};
+// -------------------------------------------------------------------
+
+class PROTOBUF_EXPORT GeneratedCodeInfo_Annotation final :
+ public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.GeneratedCodeInfo.Annotation) */ {
+ public:
+ inline GeneratedCodeInfo_Annotation() : GeneratedCodeInfo_Annotation(nullptr) {}
+ ~GeneratedCodeInfo_Annotation() override;
+ explicit constexpr GeneratedCodeInfo_Annotation(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
+
+ GeneratedCodeInfo_Annotation(const GeneratedCodeInfo_Annotation& from);
+ GeneratedCodeInfo_Annotation(GeneratedCodeInfo_Annotation&& from) noexcept
+ : GeneratedCodeInfo_Annotation() {
+ *this = ::std::move(from);
+ }
+
+ inline GeneratedCodeInfo_Annotation& operator=(const GeneratedCodeInfo_Annotation& from) {
+ CopyFrom(from);
+ return *this;
+ }
+ inline GeneratedCodeInfo_Annotation& operator=(GeneratedCodeInfo_Annotation&& from) noexcept {
+ if (this == &from) return *this;
+ if (GetOwningArena() == from.GetOwningArena()
+ #ifdef PROTOBUF_FORCE_COPY_IN_MOVE
+ && GetOwningArena() != nullptr
+ #endif // !PROTOBUF_FORCE_COPY_IN_MOVE
+ ) {
+ InternalSwap(&from);
+ } else {
+ CopyFrom(from);
+ }
+ return *this;
+ }
+
+ inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const {
+ return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance);
+ }
+ inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() {
+ return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+ }
+
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
+ return GetDescriptor();
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
+ return default_instance().GetMetadata().descriptor;
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
+ return default_instance().GetMetadata().reflection;
+ }
+ static const GeneratedCodeInfo_Annotation& default_instance() {
+ return *internal_default_instance();
+ }
+ static inline const GeneratedCodeInfo_Annotation* internal_default_instance() {
+ return reinterpret_cast<const GeneratedCodeInfo_Annotation*>(
+ &_GeneratedCodeInfo_Annotation_default_instance_);
+ }
+ static constexpr int kIndexInFileMessages =
+ 25;
+
+ friend void swap(GeneratedCodeInfo_Annotation& a, GeneratedCodeInfo_Annotation& b) {
+ a.Swap(&b);
+ }
+ inline void Swap(GeneratedCodeInfo_Annotation* other) {
+ if (other == this) return;
+ #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() != nullptr &&
+ GetOwningArena() == other->GetOwningArena()) {
+ #else // PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() == other->GetOwningArena()) {
+ #endif // !PROTOBUF_FORCE_COPY_IN_SWAP
+ InternalSwap(other);
+ } else {
+ ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
+ }
+ }
+ void UnsafeArenaSwap(GeneratedCodeInfo_Annotation* other) {
+ if (other == this) return;
+ GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena());
+ InternalSwap(other);
+ }
+
+ // implements Message ----------------------------------------------
+
+ GeneratedCodeInfo_Annotation* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
+ return CreateMaybeMessage<GeneratedCodeInfo_Annotation>(arena);
+ }
+ using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
+ void CopyFrom(const GeneratedCodeInfo_Annotation& from);
+ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
+ void MergeFrom(const GeneratedCodeInfo_Annotation& from);
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from);
+ public:
+ PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+ bool IsInitialized() const final;
+
+ size_t ByteSizeLong() const final;
+ const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
+ uint8_t* _InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
+ int GetCachedSize() const final { return _cached_size_.Get(); }
+
+ private:
+ void SharedCtor();
+ void SharedDtor();
+ void SetCachedSize(int size) const final;
+ void InternalSwap(GeneratedCodeInfo_Annotation* other);
+
+ private:
+ friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
+ static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
+ return "google.protobuf.GeneratedCodeInfo.Annotation";
+ }
+ protected:
+ explicit GeneratedCodeInfo_Annotation(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned = false);
+ private:
+ static void ArenaDtor(void* object);
+ inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
+ public:
+
+ static const ClassData _class_data_;
+ const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;
+
+ ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;
+
+ // nested types ----------------------------------------------------
+
+ // accessors -------------------------------------------------------
+
+ enum : int {
+ kPathFieldNumber = 1,
+ kSourceFileFieldNumber = 2,
+ kBeginFieldNumber = 3,
+ kEndFieldNumber = 4,
+ };
+ // repeated int32 path = 1 [packed = true];
+ int path_size() const;
+ private:
+ int _internal_path_size() const;
+ public:
+ void clear_path();
+ private:
+ 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_;
+ ::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_;
+ friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
+};
+// -------------------------------------------------------------------
+
+class PROTOBUF_EXPORT GeneratedCodeInfo final :
+ public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.GeneratedCodeInfo) */ {
+ public:
+ inline GeneratedCodeInfo() : GeneratedCodeInfo(nullptr) {}
+ ~GeneratedCodeInfo() override;
+ explicit constexpr GeneratedCodeInfo(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
+
+ GeneratedCodeInfo(const GeneratedCodeInfo& from);
+ GeneratedCodeInfo(GeneratedCodeInfo&& from) noexcept
+ : GeneratedCodeInfo() {
+ *this = ::std::move(from);
+ }
+
+ inline GeneratedCodeInfo& operator=(const GeneratedCodeInfo& from) {
+ CopyFrom(from);
+ return *this;
+ }
+ inline GeneratedCodeInfo& operator=(GeneratedCodeInfo&& from) noexcept {
+ if (this == &from) return *this;
+ if (GetOwningArena() == from.GetOwningArena()
+ #ifdef PROTOBUF_FORCE_COPY_IN_MOVE
+ && GetOwningArena() != nullptr
+ #endif // !PROTOBUF_FORCE_COPY_IN_MOVE
+ ) {
+ InternalSwap(&from);
+ } else {
+ CopyFrom(from);
+ }
+ return *this;
+ }
+
+ inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const {
+ return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance);
+ }
+ inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() {
+ return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+ }
+
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
+ return GetDescriptor();
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
+ return default_instance().GetMetadata().descriptor;
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
+ return default_instance().GetMetadata().reflection;
+ }
+ static const GeneratedCodeInfo& default_instance() {
+ return *internal_default_instance();
+ }
+ static inline const GeneratedCodeInfo* internal_default_instance() {
+ return reinterpret_cast<const GeneratedCodeInfo*>(
+ &_GeneratedCodeInfo_default_instance_);
+ }
+ static constexpr int kIndexInFileMessages =
+ 26;
+
+ friend void swap(GeneratedCodeInfo& a, GeneratedCodeInfo& b) {
+ a.Swap(&b);
+ }
+ inline void Swap(GeneratedCodeInfo* other) {
+ if (other == this) return;
+ #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() != nullptr &&
+ GetOwningArena() == other->GetOwningArena()) {
+ #else // PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() == other->GetOwningArena()) {
+ #endif // !PROTOBUF_FORCE_COPY_IN_SWAP
+ InternalSwap(other);
+ } else {
+ ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
+ }
+ }
+ void UnsafeArenaSwap(GeneratedCodeInfo* other) {
+ if (other == this) return;
+ GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena());
+ InternalSwap(other);
+ }
+
+ // implements Message ----------------------------------------------
+
+ GeneratedCodeInfo* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
+ return CreateMaybeMessage<GeneratedCodeInfo>(arena);
+ }
+ using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
+ void CopyFrom(const GeneratedCodeInfo& from);
+ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
+ void MergeFrom(const GeneratedCodeInfo& from);
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from);
+ public:
+ PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+ bool IsInitialized() const final;
+
+ size_t ByteSizeLong() const final;
+ const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
+ uint8_t* _InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
+ int GetCachedSize() const final { return _cached_size_.Get(); }
+
+ private:
+ void SharedCtor();
+ void SharedDtor();
+ void SetCachedSize(int size) const final;
+ void InternalSwap(GeneratedCodeInfo* other);
+
+ private:
+ friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
+ static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
+ return "google.protobuf.GeneratedCodeInfo";
+ }
+ protected:
+ explicit GeneratedCodeInfo(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned = false);
+ private:
+ static void ArenaDtor(void* object);
+ inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
+ public:
+
+ static const ClassData _class_data_;
+ const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;
+
+ ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;
+
+ // nested types ----------------------------------------------------
+
+ typedef GeneratedCodeInfo_Annotation Annotation;
+
+ // accessors -------------------------------------------------------
+
+ enum : int {
+ kAnnotationFieldNumber = 1,
+ };
+ // repeated .google.protobuf.GeneratedCodeInfo.Annotation annotation = 1;
+ int annotation_size() const;
+ private:
+ int _internal_annotation_size() const;
+ public:
+ void clear_annotation();
+ ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation* mutable_annotation(int index);
+ ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation >*
+ mutable_annotation();
+ private:
+ const ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation& _internal_annotation(int index) const;
+ ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation* _internal_add_annotation();
+ public:
+ const ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation& annotation(int index) const;
+ ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation* add_annotation();
+ const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation >&
+ annotation() const;
+
+ // @@protoc_insertion_point(class_scope:google.protobuf.GeneratedCodeInfo)
+ private:
+ class _Internal;
+
+ template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
+ typedef void InternalArenaConstructable_;
+ typedef void DestructorSkippable_;
+ ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation > annotation_;
+ mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
+ friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
+};
+// ===================================================================
+
+
+// ===================================================================
+
+#ifdef __GNUC__
+ #pragma GCC diagnostic push
+ #pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#endif // __GNUC__
+// FileDescriptorSet
+
+// repeated .google.protobuf.FileDescriptorProto file = 1;
+inline int FileDescriptorSet::_internal_file_size() const {
+ return file_.size();
+}
+inline int FileDescriptorSet::file_size() const {
+ return _internal_file_size();
+}
+inline void FileDescriptorSet::clear_file() {
+ file_.Clear();
+}
+inline ::PROTOBUF_NAMESPACE_ID::FileDescriptorProto* FileDescriptorSet::mutable_file(int index) {
+ // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorSet.file)
+ return file_.Mutable(index);
+}
+inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::FileDescriptorProto >*
+FileDescriptorSet::mutable_file() {
+ // @@protoc_insertion_point(field_mutable_list:google.protobuf.FileDescriptorSet.file)
+ return &file_;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::FileDescriptorProto& FileDescriptorSet::_internal_file(int index) const {
+ return file_.Get(index);
+}
+inline const ::PROTOBUF_NAMESPACE_ID::FileDescriptorProto& FileDescriptorSet::file(int index) const {
+ // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorSet.file)
+ return _internal_file(index);
+}
+inline ::PROTOBUF_NAMESPACE_ID::FileDescriptorProto* FileDescriptorSet::_internal_add_file() {
+ return file_.Add();
+}
+inline ::PROTOBUF_NAMESPACE_ID::FileDescriptorProto* FileDescriptorSet::add_file() {
+ ::PROTOBUF_NAMESPACE_ID::FileDescriptorProto* _add = _internal_add_file();
+ // @@protoc_insertion_point(field_add:google.protobuf.FileDescriptorSet.file)
+ return _add;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::FileDescriptorProto >&
+FileDescriptorSet::file() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.FileDescriptorSet.file)
+ return file_;
+}
+
+// -------------------------------------------------------------------
+
+// FileDescriptorProto
+
+// optional string name = 1;
+inline bool FileDescriptorProto::_internal_has_name() const {
+ bool value = (_has_bits_[0] & 0x00000001u) != 0;
+ return value;
+}
+inline bool FileDescriptorProto::has_name() const {
+ return _internal_has_name();
+}
+inline void FileDescriptorProto::clear_name() {
+ name_.ClearToEmpty();
+ _has_bits_[0] &= ~0x00000001u;
+}
+inline const 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) {
+ _has_bits_[0] |= 0x00000001u;
+ name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
+ // @@protoc_insertion_point(field_set:google.protobuf.FileDescriptorProto.name)
+}
+inline 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 name_.Get();
+}
+inline void FileDescriptorProto::_internal_set_name(const std::string& value) {
+ _has_bits_[0] |= 0x00000001u;
+ name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation());
+}
+inline std::string* FileDescriptorProto::_internal_mutable_name() {
+ _has_bits_[0] |= 0x00000001u;
+ return name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation());
+}
+inline std::string* FileDescriptorProto::release_name() {
+ // @@protoc_insertion_point(field_release:google.protobuf.FileDescriptorProto.name)
+ if (!_internal_has_name()) {
+ return nullptr;
+ }
+ _has_bits_[0] &= ~0x00000001u;
+ auto* p = name_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (name_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
+ name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ return p;
+}
+inline void FileDescriptorProto::set_allocated_name(std::string* name) {
+ if (name != nullptr) {
+ _has_bits_[0] |= 0x00000001u;
+ } else {
+ _has_bits_[0] &= ~0x00000001u;
+ }
+ name_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), name,
+ GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (name_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
+ name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileDescriptorProto.name)
+}
+
+// optional string package = 2;
+inline bool FileDescriptorProto::_internal_has_package() const {
+ bool value = (_has_bits_[0] & 0x00000002u) != 0;
+ return value;
+}
+inline bool FileDescriptorProto::has_package() const {
+ return _internal_has_package();
+}
+inline void FileDescriptorProto::clear_package() {
+ package_.ClearToEmpty();
+ _has_bits_[0] &= ~0x00000002u;
+}
+inline const 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) {
+ _has_bits_[0] |= 0x00000002u;
+ package_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
+ // @@protoc_insertion_point(field_set:google.protobuf.FileDescriptorProto.package)
+}
+inline 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 package_.Get();
+}
+inline void FileDescriptorProto::_internal_set_package(const std::string& value) {
+ _has_bits_[0] |= 0x00000002u;
+ package_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation());
+}
+inline std::string* FileDescriptorProto::_internal_mutable_package() {
+ _has_bits_[0] |= 0x00000002u;
+ return package_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation());
+}
+inline std::string* FileDescriptorProto::release_package() {
+ // @@protoc_insertion_point(field_release:google.protobuf.FileDescriptorProto.package)
+ if (!_internal_has_package()) {
+ return nullptr;
+ }
+ _has_bits_[0] &= ~0x00000002u;
+ auto* p = package_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (package_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
+ package_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ return p;
+}
+inline void FileDescriptorProto::set_allocated_package(std::string* package) {
+ if (package != nullptr) {
+ _has_bits_[0] |= 0x00000002u;
+ } else {
+ _has_bits_[0] &= ~0x00000002u;
+ }
+ package_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), package,
+ GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (package_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
+ package_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileDescriptorProto.package)
+}
+
+// repeated string dependency = 3;
+inline int FileDescriptorProto::_internal_dependency_size() const {
+ return dependency_.size();
+}
+inline int FileDescriptorProto::dependency_size() const {
+ return _internal_dependency_size();
+}
+inline void FileDescriptorProto::clear_dependency() {
+ dependency_.Clear();
+}
+inline 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 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 dependency_.Mutable(index);
+}
+inline void FileDescriptorProto::set_dependency(int index, const std::string& value) {
+ dependency_.Mutable(index)->assign(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.FileDescriptorProto.dependency)
+}
+inline void FileDescriptorProto::set_dependency(int index, std::string&& value) {
+ dependency_.Mutable(index)->assign(std::move(value));
+ // @@protoc_insertion_point(field_set:google.protobuf.FileDescriptorProto.dependency)
+}
+inline void FileDescriptorProto::set_dependency(int index, const char* value) {
+ GOOGLE_DCHECK(value != nullptr);
+ dependency_.Mutable(index)->assign(value);
+ // @@protoc_insertion_point(field_set_char:google.protobuf.FileDescriptorProto.dependency)
+}
+inline void FileDescriptorProto::set_dependency(int index, const char* value, size_t size) {
+ dependency_.Mutable(index)->assign(
+ reinterpret_cast<const char*>(value), size);
+ // @@protoc_insertion_point(field_set_pointer:google.protobuf.FileDescriptorProto.dependency)
+}
+inline std::string* FileDescriptorProto::_internal_add_dependency() {
+ return dependency_.Add();
+}
+inline void FileDescriptorProto::add_dependency(const std::string& value) {
+ dependency_.Add()->assign(value);
+ // @@protoc_insertion_point(field_add:google.protobuf.FileDescriptorProto.dependency)
+}
+inline void FileDescriptorProto::add_dependency(std::string&& value) {
+ dependency_.Add(std::move(value));
+ // @@protoc_insertion_point(field_add:google.protobuf.FileDescriptorProto.dependency)
+}
+inline void FileDescriptorProto::add_dependency(const char* value) {
+ GOOGLE_DCHECK(value != nullptr);
+ dependency_.Add()->assign(value);
+ // @@protoc_insertion_point(field_add_char:google.protobuf.FileDescriptorProto.dependency)
+}
+inline void FileDescriptorProto::add_dependency(const char* value, size_t size) {
+ dependency_.Add()->assign(reinterpret_cast<const char*>(value), size);
+ // @@protoc_insertion_point(field_add_pointer:google.protobuf.FileDescriptorProto.dependency)
+}
+inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string>&
+FileDescriptorProto::dependency() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.FileDescriptorProto.dependency)
+ return dependency_;
+}
+inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string>*
+FileDescriptorProto::mutable_dependency() {
+ // @@protoc_insertion_point(field_mutable_list:google.protobuf.FileDescriptorProto.dependency)
+ return &dependency_;
+}
+
+// repeated int32 public_dependency = 10;
+inline int FileDescriptorProto::_internal_public_dependency_size() const {
+ return public_dependency_.size();
+}
+inline int FileDescriptorProto::public_dependency_size() const {
+ return _internal_public_dependency_size();
+}
+inline void FileDescriptorProto::clear_public_dependency() {
+ public_dependency_.Clear();
+}
+inline int32_t FileDescriptorProto::_internal_public_dependency(int index) const {
+ return 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) {
+ 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) {
+ 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 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 &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 weak_dependency_.size();
+}
+inline int FileDescriptorProto::weak_dependency_size() const {
+ return _internal_weak_dependency_size();
+}
+inline void FileDescriptorProto::clear_weak_dependency() {
+ weak_dependency_.Clear();
+}
+inline int32_t FileDescriptorProto::_internal_weak_dependency(int index) const {
+ return 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) {
+ 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) {
+ 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 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 &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 message_type_.size();
+}
+inline int FileDescriptorProto::message_type_size() const {
+ return _internal_message_type_size();
+}
+inline void FileDescriptorProto::clear_message_type() {
+ message_type_.Clear();
+}
+inline ::PROTOBUF_NAMESPACE_ID::DescriptorProto* FileDescriptorProto::mutable_message_type(int index) {
+ // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorProto.message_type)
+ return message_type_.Mutable(index);
+}
+inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::DescriptorProto >*
+FileDescriptorProto::mutable_message_type() {
+ // @@protoc_insertion_point(field_mutable_list:google.protobuf.FileDescriptorProto.message_type)
+ return &message_type_;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::DescriptorProto& FileDescriptorProto::_internal_message_type(int index) const {
+ return message_type_.Get(index);
+}
+inline const ::PROTOBUF_NAMESPACE_ID::DescriptorProto& FileDescriptorProto::message_type(int index) const {
+ // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.message_type)
+ return _internal_message_type(index);
+}
+inline ::PROTOBUF_NAMESPACE_ID::DescriptorProto* FileDescriptorProto::_internal_add_message_type() {
+ return message_type_.Add();
+}
+inline ::PROTOBUF_NAMESPACE_ID::DescriptorProto* FileDescriptorProto::add_message_type() {
+ ::PROTOBUF_NAMESPACE_ID::DescriptorProto* _add = _internal_add_message_type();
+ // @@protoc_insertion_point(field_add:google.protobuf.FileDescriptorProto.message_type)
+ return _add;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::DescriptorProto >&
+FileDescriptorProto::message_type() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.FileDescriptorProto.message_type)
+ return message_type_;
+}
+
+// repeated .google.protobuf.EnumDescriptorProto enum_type = 5;
+inline int FileDescriptorProto::_internal_enum_type_size() const {
+ return enum_type_.size();
+}
+inline int FileDescriptorProto::enum_type_size() const {
+ return _internal_enum_type_size();
+}
+inline void FileDescriptorProto::clear_enum_type() {
+ enum_type_.Clear();
+}
+inline ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto* FileDescriptorProto::mutable_enum_type(int index) {
+ // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorProto.enum_type)
+ return enum_type_.Mutable(index);
+}
+inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto >*
+FileDescriptorProto::mutable_enum_type() {
+ // @@protoc_insertion_point(field_mutable_list:google.protobuf.FileDescriptorProto.enum_type)
+ return &enum_type_;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto& FileDescriptorProto::_internal_enum_type(int index) const {
+ return enum_type_.Get(index);
+}
+inline const ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto& FileDescriptorProto::enum_type(int index) const {
+ // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.enum_type)
+ return _internal_enum_type(index);
+}
+inline ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto* FileDescriptorProto::_internal_add_enum_type() {
+ return enum_type_.Add();
+}
+inline ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto* FileDescriptorProto::add_enum_type() {
+ ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto* _add = _internal_add_enum_type();
+ // @@protoc_insertion_point(field_add:google.protobuf.FileDescriptorProto.enum_type)
+ return _add;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto >&
+FileDescriptorProto::enum_type() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.FileDescriptorProto.enum_type)
+ return enum_type_;
+}
+
+// repeated .google.protobuf.ServiceDescriptorProto service = 6;
+inline int FileDescriptorProto::_internal_service_size() const {
+ return service_.size();
+}
+inline int FileDescriptorProto::service_size() const {
+ return _internal_service_size();
+}
+inline void FileDescriptorProto::clear_service() {
+ service_.Clear();
+}
+inline ::PROTOBUF_NAMESPACE_ID::ServiceDescriptorProto* FileDescriptorProto::mutable_service(int index) {
+ // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorProto.service)
+ return service_.Mutable(index);
+}
+inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::ServiceDescriptorProto >*
+FileDescriptorProto::mutable_service() {
+ // @@protoc_insertion_point(field_mutable_list:google.protobuf.FileDescriptorProto.service)
+ return &service_;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::ServiceDescriptorProto& FileDescriptorProto::_internal_service(int index) const {
+ return service_.Get(index);
+}
+inline const ::PROTOBUF_NAMESPACE_ID::ServiceDescriptorProto& FileDescriptorProto::service(int index) const {
+ // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.service)
+ return _internal_service(index);
+}
+inline ::PROTOBUF_NAMESPACE_ID::ServiceDescriptorProto* FileDescriptorProto::_internal_add_service() {
+ return service_.Add();
+}
+inline ::PROTOBUF_NAMESPACE_ID::ServiceDescriptorProto* FileDescriptorProto::add_service() {
+ ::PROTOBUF_NAMESPACE_ID::ServiceDescriptorProto* _add = _internal_add_service();
+ // @@protoc_insertion_point(field_add:google.protobuf.FileDescriptorProto.service)
+ return _add;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::ServiceDescriptorProto >&
+FileDescriptorProto::service() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.FileDescriptorProto.service)
+ return service_;
+}
+
+// repeated .google.protobuf.FieldDescriptorProto extension = 7;
+inline int FileDescriptorProto::_internal_extension_size() const {
+ return extension_.size();
+}
+inline int FileDescriptorProto::extension_size() const {
+ return _internal_extension_size();
+}
+inline void FileDescriptorProto::clear_extension() {
+ extension_.Clear();
+}
+inline ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto* FileDescriptorProto::mutable_extension(int index) {
+ // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorProto.extension)
+ return extension_.Mutable(index);
+}
+inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto >*
+FileDescriptorProto::mutable_extension() {
+ // @@protoc_insertion_point(field_mutable_list:google.protobuf.FileDescriptorProto.extension)
+ return &extension_;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto& FileDescriptorProto::_internal_extension(int index) const {
+ return extension_.Get(index);
+}
+inline const ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto& FileDescriptorProto::extension(int index) const {
+ // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.extension)
+ return _internal_extension(index);
+}
+inline ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto* FileDescriptorProto::_internal_add_extension() {
+ return extension_.Add();
+}
+inline ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto* FileDescriptorProto::add_extension() {
+ ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto* _add = _internal_add_extension();
+ // @@protoc_insertion_point(field_add:google.protobuf.FileDescriptorProto.extension)
+ return _add;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto >&
+FileDescriptorProto::extension() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.FileDescriptorProto.extension)
+ return extension_;
+}
+
+// optional .google.protobuf.FileOptions options = 8;
+inline bool FileDescriptorProto::_internal_has_options() const {
+ bool value = (_has_bits_[0] & 0x00000008u) != 0;
+ PROTOBUF_ASSUME(!value || options_ != nullptr);
+ return value;
+}
+inline bool FileDescriptorProto::has_options() const {
+ return _internal_has_options();
+}
+inline void FileDescriptorProto::clear_options() {
+ if (options_ != nullptr) options_->Clear();
+ _has_bits_[0] &= ~0x00000008u;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::FileOptions& FileDescriptorProto::_internal_options() const {
+ const ::PROTOBUF_NAMESPACE_ID::FileOptions* p = options_;
+ return p != nullptr ? *p : reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::FileOptions&>(
+ ::PROTOBUF_NAMESPACE_ID::_FileOptions_default_instance_);
+}
+inline const ::PROTOBUF_NAMESPACE_ID::FileOptions& FileDescriptorProto::options() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.options)
+ return _internal_options();
+}
+inline void FileDescriptorProto::unsafe_arena_set_allocated_options(
+ ::PROTOBUF_NAMESPACE_ID::FileOptions* options) {
+ if (GetArenaForAllocation() == nullptr) {
+ delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(options_);
+ }
+ options_ = options;
+ if (options) {
+ _has_bits_[0] |= 0x00000008u;
+ } else {
+ _has_bits_[0] &= ~0x00000008u;
+ }
+ // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.FileDescriptorProto.options)
+}
+inline ::PROTOBUF_NAMESPACE_ID::FileOptions* FileDescriptorProto::release_options() {
+ _has_bits_[0] &= ~0x00000008u;
+ ::PROTOBUF_NAMESPACE_ID::FileOptions* temp = options_;
+ options_ = nullptr;
+#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE
+ auto* old = reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(temp);
+ temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
+ if (GetArenaForAllocation() == nullptr) { delete old; }
+#else // PROTOBUF_FORCE_COPY_IN_RELEASE
+ if (GetArenaForAllocation() != nullptr) {
+ temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
+ }
+#endif // !PROTOBUF_FORCE_COPY_IN_RELEASE
+ return temp;
+}
+inline ::PROTOBUF_NAMESPACE_ID::FileOptions* FileDescriptorProto::unsafe_arena_release_options() {
+ // @@protoc_insertion_point(field_release:google.protobuf.FileDescriptorProto.options)
+ _has_bits_[0] &= ~0x00000008u;
+ ::PROTOBUF_NAMESPACE_ID::FileOptions* temp = options_;
+ options_ = nullptr;
+ return temp;
+}
+inline ::PROTOBUF_NAMESPACE_ID::FileOptions* FileDescriptorProto::_internal_mutable_options() {
+ _has_bits_[0] |= 0x00000008u;
+ if (options_ == nullptr) {
+ auto* p = CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::FileOptions>(GetArenaForAllocation());
+ options_ = p;
+ }
+ return options_;
+}
+inline ::PROTOBUF_NAMESPACE_ID::FileOptions* FileDescriptorProto::mutable_options() {
+ ::PROTOBUF_NAMESPACE_ID::FileOptions* _msg = _internal_mutable_options();
+ // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorProto.options)
+ return _msg;
+}
+inline void FileDescriptorProto::set_allocated_options(::PROTOBUF_NAMESPACE_ID::FileOptions* options) {
+ ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaForAllocation();
+ if (message_arena == nullptr) {
+ delete options_;
+ }
+ if (options) {
+ ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
+ ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper<::PROTOBUF_NAMESPACE_ID::FileOptions>::GetOwningArena(options);
+ if (message_arena != submessage_arena) {
+ options = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
+ message_arena, options, submessage_arena);
+ }
+ _has_bits_[0] |= 0x00000008u;
+ } else {
+ _has_bits_[0] &= ~0x00000008u;
+ }
+ options_ = options;
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileDescriptorProto.options)
+}
+
+// optional .google.protobuf.SourceCodeInfo source_code_info = 9;
+inline bool FileDescriptorProto::_internal_has_source_code_info() const {
+ bool value = (_has_bits_[0] & 0x00000010u) != 0;
+ PROTOBUF_ASSUME(!value || source_code_info_ != nullptr);
+ return value;
+}
+inline bool FileDescriptorProto::has_source_code_info() const {
+ return _internal_has_source_code_info();
+}
+inline void FileDescriptorProto::clear_source_code_info() {
+ if (source_code_info_ != nullptr) source_code_info_->Clear();
+ _has_bits_[0] &= ~0x00000010u;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo& FileDescriptorProto::_internal_source_code_info() const {
+ const ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo* p = source_code_info_;
+ return p != nullptr ? *p : reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo&>(
+ ::PROTOBUF_NAMESPACE_ID::_SourceCodeInfo_default_instance_);
+}
+inline const ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo& FileDescriptorProto::source_code_info() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.source_code_info)
+ return _internal_source_code_info();
+}
+inline void FileDescriptorProto::unsafe_arena_set_allocated_source_code_info(
+ ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo* source_code_info) {
+ if (GetArenaForAllocation() == nullptr) {
+ delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(source_code_info_);
+ }
+ source_code_info_ = source_code_info;
+ if (source_code_info) {
+ _has_bits_[0] |= 0x00000010u;
+ } else {
+ _has_bits_[0] &= ~0x00000010u;
+ }
+ // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.FileDescriptorProto.source_code_info)
+}
+inline ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo* FileDescriptorProto::release_source_code_info() {
+ _has_bits_[0] &= ~0x00000010u;
+ ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo* temp = source_code_info_;
+ source_code_info_ = nullptr;
+#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE
+ auto* old = reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(temp);
+ temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
+ if (GetArenaForAllocation() == nullptr) { delete old; }
+#else // PROTOBUF_FORCE_COPY_IN_RELEASE
+ if (GetArenaForAllocation() != nullptr) {
+ temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
+ }
+#endif // !PROTOBUF_FORCE_COPY_IN_RELEASE
+ return temp;
+}
+inline ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo* FileDescriptorProto::unsafe_arena_release_source_code_info() {
+ // @@protoc_insertion_point(field_release:google.protobuf.FileDescriptorProto.source_code_info)
+ _has_bits_[0] &= ~0x00000010u;
+ ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo* temp = source_code_info_;
+ source_code_info_ = nullptr;
+ return temp;
+}
+inline ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo* FileDescriptorProto::_internal_mutable_source_code_info() {
+ _has_bits_[0] |= 0x00000010u;
+ if (source_code_info_ == nullptr) {
+ auto* p = CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::SourceCodeInfo>(GetArenaForAllocation());
+ source_code_info_ = p;
+ }
+ return source_code_info_;
+}
+inline ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo* FileDescriptorProto::mutable_source_code_info() {
+ ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo* _msg = _internal_mutable_source_code_info();
+ // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorProto.source_code_info)
+ return _msg;
+}
+inline void FileDescriptorProto::set_allocated_source_code_info(::PROTOBUF_NAMESPACE_ID::SourceCodeInfo* source_code_info) {
+ ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaForAllocation();
+ if (message_arena == nullptr) {
+ delete source_code_info_;
+ }
+ if (source_code_info) {
+ ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
+ ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper<::PROTOBUF_NAMESPACE_ID::SourceCodeInfo>::GetOwningArena(source_code_info);
+ if (message_arena != submessage_arena) {
+ source_code_info = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
+ message_arena, source_code_info, submessage_arena);
+ }
+ _has_bits_[0] |= 0x00000010u;
+ } else {
+ _has_bits_[0] &= ~0x00000010u;
+ }
+ source_code_info_ = source_code_info;
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileDescriptorProto.source_code_info)
+}
+
+// optional string syntax = 12;
+inline bool FileDescriptorProto::_internal_has_syntax() const {
+ bool value = (_has_bits_[0] & 0x00000004u) != 0;
+ return value;
+}
+inline bool FileDescriptorProto::has_syntax() const {
+ return _internal_has_syntax();
+}
+inline void FileDescriptorProto::clear_syntax() {
+ syntax_.ClearToEmpty();
+ _has_bits_[0] &= ~0x00000004u;
+}
+inline const 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) {
+ _has_bits_[0] |= 0x00000004u;
+ syntax_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
+ // @@protoc_insertion_point(field_set:google.protobuf.FileDescriptorProto.syntax)
+}
+inline 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 syntax_.Get();
+}
+inline void FileDescriptorProto::_internal_set_syntax(const std::string& value) {
+ _has_bits_[0] |= 0x00000004u;
+ syntax_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation());
+}
+inline std::string* FileDescriptorProto::_internal_mutable_syntax() {
+ _has_bits_[0] |= 0x00000004u;
+ return syntax_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation());
+}
+inline std::string* FileDescriptorProto::release_syntax() {
+ // @@protoc_insertion_point(field_release:google.protobuf.FileDescriptorProto.syntax)
+ if (!_internal_has_syntax()) {
+ return nullptr;
+ }
+ _has_bits_[0] &= ~0x00000004u;
+ auto* p = syntax_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (syntax_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
+ syntax_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ return p;
+}
+inline void FileDescriptorProto::set_allocated_syntax(std::string* syntax) {
+ if (syntax != nullptr) {
+ _has_bits_[0] |= 0x00000004u;
+ } else {
+ _has_bits_[0] &= ~0x00000004u;
+ }
+ syntax_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), syntax,
+ GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (syntax_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
+ syntax_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileDescriptorProto.syntax)
+}
+
+// -------------------------------------------------------------------
+
+// DescriptorProto_ExtensionRange
+
+// optional int32 start = 1;
+inline bool DescriptorProto_ExtensionRange::_internal_has_start() const {
+ bool value = (_has_bits_[0] & 0x00000002u) != 0;
+ return value;
+}
+inline bool DescriptorProto_ExtensionRange::has_start() const {
+ return _internal_has_start();
+}
+inline void DescriptorProto_ExtensionRange::clear_start() {
+ start_ = 0;
+ _has_bits_[0] &= ~0x00000002u;
+}
+inline int32_t DescriptorProto_ExtensionRange::_internal_start() const {
+ return 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) {
+ _has_bits_[0] |= 0x00000002u;
+ 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 = (_has_bits_[0] & 0x00000004u) != 0;
+ return value;
+}
+inline bool DescriptorProto_ExtensionRange::has_end() const {
+ return _internal_has_end();
+}
+inline void DescriptorProto_ExtensionRange::clear_end() {
+ end_ = 0;
+ _has_bits_[0] &= ~0x00000004u;
+}
+inline int32_t DescriptorProto_ExtensionRange::_internal_end() const {
+ return 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) {
+ _has_bits_[0] |= 0x00000004u;
+ 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 = (_has_bits_[0] & 0x00000001u) != 0;
+ PROTOBUF_ASSUME(!value || options_ != nullptr);
+ return value;
+}
+inline bool DescriptorProto_ExtensionRange::has_options() const {
+ return _internal_has_options();
+}
+inline void DescriptorProto_ExtensionRange::clear_options() {
+ if (options_ != nullptr) options_->Clear();
+ _has_bits_[0] &= ~0x00000001u;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions& DescriptorProto_ExtensionRange::_internal_options() const {
+ const ::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions* p = options_;
+ return p != nullptr ? *p : reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions&>(
+ ::PROTOBUF_NAMESPACE_ID::_ExtensionRangeOptions_default_instance_);
+}
+inline const ::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions& DescriptorProto_ExtensionRange::options() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.ExtensionRange.options)
+ return _internal_options();
+}
+inline void DescriptorProto_ExtensionRange::unsafe_arena_set_allocated_options(
+ ::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions* options) {
+ if (GetArenaForAllocation() == nullptr) {
+ delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(options_);
+ }
+ options_ = options;
+ if (options) {
+ _has_bits_[0] |= 0x00000001u;
+ } else {
+ _has_bits_[0] &= ~0x00000001u;
+ }
+ // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.DescriptorProto.ExtensionRange.options)
+}
+inline ::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions* DescriptorProto_ExtensionRange::release_options() {
+ _has_bits_[0] &= ~0x00000001u;
+ ::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions* temp = options_;
+ options_ = nullptr;
+#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE
+ auto* old = reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(temp);
+ temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
+ if (GetArenaForAllocation() == nullptr) { delete old; }
+#else // PROTOBUF_FORCE_COPY_IN_RELEASE
+ if (GetArenaForAllocation() != nullptr) {
+ temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
+ }
+#endif // !PROTOBUF_FORCE_COPY_IN_RELEASE
+ return temp;
+}
+inline ::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions* DescriptorProto_ExtensionRange::unsafe_arena_release_options() {
+ // @@protoc_insertion_point(field_release:google.protobuf.DescriptorProto.ExtensionRange.options)
+ _has_bits_[0] &= ~0x00000001u;
+ ::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions* temp = options_;
+ options_ = nullptr;
+ return temp;
+}
+inline ::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions* DescriptorProto_ExtensionRange::_internal_mutable_options() {
+ _has_bits_[0] |= 0x00000001u;
+ if (options_ == nullptr) {
+ auto* p = CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions>(GetArenaForAllocation());
+ options_ = p;
+ }
+ return options_;
+}
+inline ::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions* DescriptorProto_ExtensionRange::mutable_options() {
+ ::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions* _msg = _internal_mutable_options();
+ // @@protoc_insertion_point(field_mutable:google.protobuf.DescriptorProto.ExtensionRange.options)
+ return _msg;
+}
+inline void DescriptorProto_ExtensionRange::set_allocated_options(::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions* options) {
+ ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaForAllocation();
+ if (message_arena == nullptr) {
+ delete options_;
+ }
+ if (options) {
+ ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
+ ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper<::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions>::GetOwningArena(options);
+ if (message_arena != submessage_arena) {
+ options = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
+ message_arena, options, submessage_arena);
+ }
+ _has_bits_[0] |= 0x00000001u;
+ } else {
+ _has_bits_[0] &= ~0x00000001u;
+ }
+ options_ = options;
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.DescriptorProto.ExtensionRange.options)
+}
+
+// -------------------------------------------------------------------
+
+// DescriptorProto_ReservedRange
+
+// optional int32 start = 1;
+inline bool DescriptorProto_ReservedRange::_internal_has_start() const {
+ bool value = (_has_bits_[0] & 0x00000001u) != 0;
+ return value;
+}
+inline bool DescriptorProto_ReservedRange::has_start() const {
+ return _internal_has_start();
+}
+inline void DescriptorProto_ReservedRange::clear_start() {
+ start_ = 0;
+ _has_bits_[0] &= ~0x00000001u;
+}
+inline int32_t DescriptorProto_ReservedRange::_internal_start() const {
+ return 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) {
+ _has_bits_[0] |= 0x00000001u;
+ 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 = (_has_bits_[0] & 0x00000002u) != 0;
+ return value;
+}
+inline bool DescriptorProto_ReservedRange::has_end() const {
+ return _internal_has_end();
+}
+inline void DescriptorProto_ReservedRange::clear_end() {
+ end_ = 0;
+ _has_bits_[0] &= ~0x00000002u;
+}
+inline int32_t DescriptorProto_ReservedRange::_internal_end() const {
+ return 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) {
+ _has_bits_[0] |= 0x00000002u;
+ 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 = (_has_bits_[0] & 0x00000001u) != 0;
+ return value;
+}
+inline bool DescriptorProto::has_name() const {
+ return _internal_has_name();
+}
+inline void DescriptorProto::clear_name() {
+ name_.ClearToEmpty();
+ _has_bits_[0] &= ~0x00000001u;
+}
+inline const 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) {
+ _has_bits_[0] |= 0x00000001u;
+ name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
+ // @@protoc_insertion_point(field_set:google.protobuf.DescriptorProto.name)
+}
+inline 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 name_.Get();
+}
+inline void DescriptorProto::_internal_set_name(const std::string& value) {
+ _has_bits_[0] |= 0x00000001u;
+ name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation());
+}
+inline std::string* DescriptorProto::_internal_mutable_name() {
+ _has_bits_[0] |= 0x00000001u;
+ return name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation());
+}
+inline std::string* DescriptorProto::release_name() {
+ // @@protoc_insertion_point(field_release:google.protobuf.DescriptorProto.name)
+ if (!_internal_has_name()) {
+ return nullptr;
+ }
+ _has_bits_[0] &= ~0x00000001u;
+ auto* p = name_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (name_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
+ name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ return p;
+}
+inline void DescriptorProto::set_allocated_name(std::string* name) {
+ if (name != nullptr) {
+ _has_bits_[0] |= 0x00000001u;
+ } else {
+ _has_bits_[0] &= ~0x00000001u;
+ }
+ name_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), name,
+ GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (name_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
+ name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.DescriptorProto.name)
+}
+
+// repeated .google.protobuf.FieldDescriptorProto field = 2;
+inline int DescriptorProto::_internal_field_size() const {
+ return field_.size();
+}
+inline int DescriptorProto::field_size() const {
+ return _internal_field_size();
+}
+inline void DescriptorProto::clear_field() {
+ field_.Clear();
+}
+inline ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto* DescriptorProto::mutable_field(int index) {
+ // @@protoc_insertion_point(field_mutable:google.protobuf.DescriptorProto.field)
+ return field_.Mutable(index);
+}
+inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto >*
+DescriptorProto::mutable_field() {
+ // @@protoc_insertion_point(field_mutable_list:google.protobuf.DescriptorProto.field)
+ return &field_;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto& DescriptorProto::_internal_field(int index) const {
+ return field_.Get(index);
+}
+inline const ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto& DescriptorProto::field(int index) const {
+ // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.field)
+ return _internal_field(index);
+}
+inline ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto* DescriptorProto::_internal_add_field() {
+ return field_.Add();
+}
+inline ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto* DescriptorProto::add_field() {
+ ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto* _add = _internal_add_field();
+ // @@protoc_insertion_point(field_add:google.protobuf.DescriptorProto.field)
+ return _add;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto >&
+DescriptorProto::field() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.DescriptorProto.field)
+ return field_;
+}
+
+// repeated .google.protobuf.FieldDescriptorProto extension = 6;
+inline int DescriptorProto::_internal_extension_size() const {
+ return extension_.size();
+}
+inline int DescriptorProto::extension_size() const {
+ return _internal_extension_size();
+}
+inline void DescriptorProto::clear_extension() {
+ extension_.Clear();
+}
+inline ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto* DescriptorProto::mutable_extension(int index) {
+ // @@protoc_insertion_point(field_mutable:google.protobuf.DescriptorProto.extension)
+ return extension_.Mutable(index);
+}
+inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto >*
+DescriptorProto::mutable_extension() {
+ // @@protoc_insertion_point(field_mutable_list:google.protobuf.DescriptorProto.extension)
+ return &extension_;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto& DescriptorProto::_internal_extension(int index) const {
+ return extension_.Get(index);
+}
+inline const ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto& DescriptorProto::extension(int index) const {
+ // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.extension)
+ return _internal_extension(index);
+}
+inline ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto* DescriptorProto::_internal_add_extension() {
+ return extension_.Add();
+}
+inline ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto* DescriptorProto::add_extension() {
+ ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto* _add = _internal_add_extension();
+ // @@protoc_insertion_point(field_add:google.protobuf.DescriptorProto.extension)
+ return _add;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto >&
+DescriptorProto::extension() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.DescriptorProto.extension)
+ return extension_;
+}
+
+// repeated .google.protobuf.DescriptorProto nested_type = 3;
+inline int DescriptorProto::_internal_nested_type_size() const {
+ return nested_type_.size();
+}
+inline int DescriptorProto::nested_type_size() const {
+ return _internal_nested_type_size();
+}
+inline void DescriptorProto::clear_nested_type() {
+ nested_type_.Clear();
+}
+inline ::PROTOBUF_NAMESPACE_ID::DescriptorProto* DescriptorProto::mutable_nested_type(int index) {
+ // @@protoc_insertion_point(field_mutable:google.protobuf.DescriptorProto.nested_type)
+ return nested_type_.Mutable(index);
+}
+inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::DescriptorProto >*
+DescriptorProto::mutable_nested_type() {
+ // @@protoc_insertion_point(field_mutable_list:google.protobuf.DescriptorProto.nested_type)
+ return &nested_type_;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::DescriptorProto& DescriptorProto::_internal_nested_type(int index) const {
+ return nested_type_.Get(index);
+}
+inline const ::PROTOBUF_NAMESPACE_ID::DescriptorProto& DescriptorProto::nested_type(int index) const {
+ // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.nested_type)
+ return _internal_nested_type(index);
+}
+inline ::PROTOBUF_NAMESPACE_ID::DescriptorProto* DescriptorProto::_internal_add_nested_type() {
+ return nested_type_.Add();
+}
+inline ::PROTOBUF_NAMESPACE_ID::DescriptorProto* DescriptorProto::add_nested_type() {
+ ::PROTOBUF_NAMESPACE_ID::DescriptorProto* _add = _internal_add_nested_type();
+ // @@protoc_insertion_point(field_add:google.protobuf.DescriptorProto.nested_type)
+ return _add;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::DescriptorProto >&
+DescriptorProto::nested_type() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.DescriptorProto.nested_type)
+ return nested_type_;
+}
+
+// repeated .google.protobuf.EnumDescriptorProto enum_type = 4;
+inline int DescriptorProto::_internal_enum_type_size() const {
+ return enum_type_.size();
+}
+inline int DescriptorProto::enum_type_size() const {
+ return _internal_enum_type_size();
+}
+inline void DescriptorProto::clear_enum_type() {
+ enum_type_.Clear();
+}
+inline ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto* DescriptorProto::mutable_enum_type(int index) {
+ // @@protoc_insertion_point(field_mutable:google.protobuf.DescriptorProto.enum_type)
+ return enum_type_.Mutable(index);
+}
+inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto >*
+DescriptorProto::mutable_enum_type() {
+ // @@protoc_insertion_point(field_mutable_list:google.protobuf.DescriptorProto.enum_type)
+ return &enum_type_;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto& DescriptorProto::_internal_enum_type(int index) const {
+ return enum_type_.Get(index);
+}
+inline const ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto& DescriptorProto::enum_type(int index) const {
+ // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.enum_type)
+ return _internal_enum_type(index);
+}
+inline ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto* DescriptorProto::_internal_add_enum_type() {
+ return enum_type_.Add();
+}
+inline ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto* DescriptorProto::add_enum_type() {
+ ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto* _add = _internal_add_enum_type();
+ // @@protoc_insertion_point(field_add:google.protobuf.DescriptorProto.enum_type)
+ return _add;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto >&
+DescriptorProto::enum_type() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.DescriptorProto.enum_type)
+ return enum_type_;
+}
+
+// repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5;
+inline int DescriptorProto::_internal_extension_range_size() const {
+ return extension_range_.size();
+}
+inline int DescriptorProto::extension_range_size() const {
+ return _internal_extension_range_size();
+}
+inline void DescriptorProto::clear_extension_range() {
+ extension_range_.Clear();
+}
+inline ::PROTOBUF_NAMESPACE_ID::DescriptorProto_ExtensionRange* DescriptorProto::mutable_extension_range(int index) {
+ // @@protoc_insertion_point(field_mutable:google.protobuf.DescriptorProto.extension_range)
+ return extension_range_.Mutable(index);
+}
+inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::DescriptorProto_ExtensionRange >*
+DescriptorProto::mutable_extension_range() {
+ // @@protoc_insertion_point(field_mutable_list:google.protobuf.DescriptorProto.extension_range)
+ return &extension_range_;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::DescriptorProto_ExtensionRange& DescriptorProto::_internal_extension_range(int index) const {
+ return extension_range_.Get(index);
+}
+inline const ::PROTOBUF_NAMESPACE_ID::DescriptorProto_ExtensionRange& DescriptorProto::extension_range(int index) const {
+ // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.extension_range)
+ return _internal_extension_range(index);
+}
+inline ::PROTOBUF_NAMESPACE_ID::DescriptorProto_ExtensionRange* DescriptorProto::_internal_add_extension_range() {
+ return extension_range_.Add();
+}
+inline ::PROTOBUF_NAMESPACE_ID::DescriptorProto_ExtensionRange* DescriptorProto::add_extension_range() {
+ ::PROTOBUF_NAMESPACE_ID::DescriptorProto_ExtensionRange* _add = _internal_add_extension_range();
+ // @@protoc_insertion_point(field_add:google.protobuf.DescriptorProto.extension_range)
+ return _add;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::DescriptorProto_ExtensionRange >&
+DescriptorProto::extension_range() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.DescriptorProto.extension_range)
+ return extension_range_;
+}
+
+// repeated .google.protobuf.OneofDescriptorProto oneof_decl = 8;
+inline int DescriptorProto::_internal_oneof_decl_size() const {
+ return oneof_decl_.size();
+}
+inline int DescriptorProto::oneof_decl_size() const {
+ return _internal_oneof_decl_size();
+}
+inline void DescriptorProto::clear_oneof_decl() {
+ oneof_decl_.Clear();
+}
+inline ::PROTOBUF_NAMESPACE_ID::OneofDescriptorProto* DescriptorProto::mutable_oneof_decl(int index) {
+ // @@protoc_insertion_point(field_mutable:google.protobuf.DescriptorProto.oneof_decl)
+ return oneof_decl_.Mutable(index);
+}
+inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::OneofDescriptorProto >*
+DescriptorProto::mutable_oneof_decl() {
+ // @@protoc_insertion_point(field_mutable_list:google.protobuf.DescriptorProto.oneof_decl)
+ return &oneof_decl_;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::OneofDescriptorProto& DescriptorProto::_internal_oneof_decl(int index) const {
+ return oneof_decl_.Get(index);
+}
+inline const ::PROTOBUF_NAMESPACE_ID::OneofDescriptorProto& DescriptorProto::oneof_decl(int index) const {
+ // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.oneof_decl)
+ return _internal_oneof_decl(index);
+}
+inline ::PROTOBUF_NAMESPACE_ID::OneofDescriptorProto* DescriptorProto::_internal_add_oneof_decl() {
+ return oneof_decl_.Add();
+}
+inline ::PROTOBUF_NAMESPACE_ID::OneofDescriptorProto* DescriptorProto::add_oneof_decl() {
+ ::PROTOBUF_NAMESPACE_ID::OneofDescriptorProto* _add = _internal_add_oneof_decl();
+ // @@protoc_insertion_point(field_add:google.protobuf.DescriptorProto.oneof_decl)
+ return _add;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::OneofDescriptorProto >&
+DescriptorProto::oneof_decl() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.DescriptorProto.oneof_decl)
+ return oneof_decl_;
+}
+
+// optional .google.protobuf.MessageOptions options = 7;
+inline bool DescriptorProto::_internal_has_options() const {
+ bool value = (_has_bits_[0] & 0x00000002u) != 0;
+ PROTOBUF_ASSUME(!value || options_ != nullptr);
+ return value;
+}
+inline bool DescriptorProto::has_options() const {
+ return _internal_has_options();
+}
+inline void DescriptorProto::clear_options() {
+ if (options_ != nullptr) options_->Clear();
+ _has_bits_[0] &= ~0x00000002u;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::MessageOptions& DescriptorProto::_internal_options() const {
+ const ::PROTOBUF_NAMESPACE_ID::MessageOptions* p = options_;
+ return p != nullptr ? *p : reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::MessageOptions&>(
+ ::PROTOBUF_NAMESPACE_ID::_MessageOptions_default_instance_);
+}
+inline const ::PROTOBUF_NAMESPACE_ID::MessageOptions& DescriptorProto::options() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.options)
+ return _internal_options();
+}
+inline void DescriptorProto::unsafe_arena_set_allocated_options(
+ ::PROTOBUF_NAMESPACE_ID::MessageOptions* options) {
+ if (GetArenaForAllocation() == nullptr) {
+ delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(options_);
+ }
+ options_ = options;
+ if (options) {
+ _has_bits_[0] |= 0x00000002u;
+ } else {
+ _has_bits_[0] &= ~0x00000002u;
+ }
+ // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.DescriptorProto.options)
+}
+inline ::PROTOBUF_NAMESPACE_ID::MessageOptions* DescriptorProto::release_options() {
+ _has_bits_[0] &= ~0x00000002u;
+ ::PROTOBUF_NAMESPACE_ID::MessageOptions* temp = options_;
+ options_ = nullptr;
+#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE
+ auto* old = reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(temp);
+ temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
+ if (GetArenaForAllocation() == nullptr) { delete old; }
+#else // PROTOBUF_FORCE_COPY_IN_RELEASE
+ if (GetArenaForAllocation() != nullptr) {
+ temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
+ }
+#endif // !PROTOBUF_FORCE_COPY_IN_RELEASE
+ return temp;
+}
+inline ::PROTOBUF_NAMESPACE_ID::MessageOptions* DescriptorProto::unsafe_arena_release_options() {
+ // @@protoc_insertion_point(field_release:google.protobuf.DescriptorProto.options)
+ _has_bits_[0] &= ~0x00000002u;
+ ::PROTOBUF_NAMESPACE_ID::MessageOptions* temp = options_;
+ options_ = nullptr;
+ return temp;
+}
+inline ::PROTOBUF_NAMESPACE_ID::MessageOptions* DescriptorProto::_internal_mutable_options() {
+ _has_bits_[0] |= 0x00000002u;
+ if (options_ == nullptr) {
+ auto* p = CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::MessageOptions>(GetArenaForAllocation());
+ options_ = p;
+ }
+ return options_;
+}
+inline ::PROTOBUF_NAMESPACE_ID::MessageOptions* DescriptorProto::mutable_options() {
+ ::PROTOBUF_NAMESPACE_ID::MessageOptions* _msg = _internal_mutable_options();
+ // @@protoc_insertion_point(field_mutable:google.protobuf.DescriptorProto.options)
+ return _msg;
+}
+inline void DescriptorProto::set_allocated_options(::PROTOBUF_NAMESPACE_ID::MessageOptions* options) {
+ ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaForAllocation();
+ if (message_arena == nullptr) {
+ delete options_;
+ }
+ if (options) {
+ ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
+ ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper<::PROTOBUF_NAMESPACE_ID::MessageOptions>::GetOwningArena(options);
+ if (message_arena != submessage_arena) {
+ options = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
+ message_arena, options, submessage_arena);
+ }
+ _has_bits_[0] |= 0x00000002u;
+ } else {
+ _has_bits_[0] &= ~0x00000002u;
+ }
+ options_ = options;
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.DescriptorProto.options)
+}
+
+// repeated .google.protobuf.DescriptorProto.ReservedRange reserved_range = 9;
+inline int DescriptorProto::_internal_reserved_range_size() const {
+ return reserved_range_.size();
+}
+inline int DescriptorProto::reserved_range_size() const {
+ return _internal_reserved_range_size();
+}
+inline void DescriptorProto::clear_reserved_range() {
+ reserved_range_.Clear();
+}
+inline ::PROTOBUF_NAMESPACE_ID::DescriptorProto_ReservedRange* DescriptorProto::mutable_reserved_range(int index) {
+ // @@protoc_insertion_point(field_mutable:google.protobuf.DescriptorProto.reserved_range)
+ return reserved_range_.Mutable(index);
+}
+inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::DescriptorProto_ReservedRange >*
+DescriptorProto::mutable_reserved_range() {
+ // @@protoc_insertion_point(field_mutable_list:google.protobuf.DescriptorProto.reserved_range)
+ return &reserved_range_;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::DescriptorProto_ReservedRange& DescriptorProto::_internal_reserved_range(int index) const {
+ return reserved_range_.Get(index);
+}
+inline const ::PROTOBUF_NAMESPACE_ID::DescriptorProto_ReservedRange& DescriptorProto::reserved_range(int index) const {
+ // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.reserved_range)
+ return _internal_reserved_range(index);
+}
+inline ::PROTOBUF_NAMESPACE_ID::DescriptorProto_ReservedRange* DescriptorProto::_internal_add_reserved_range() {
+ return reserved_range_.Add();
+}
+inline ::PROTOBUF_NAMESPACE_ID::DescriptorProto_ReservedRange* DescriptorProto::add_reserved_range() {
+ ::PROTOBUF_NAMESPACE_ID::DescriptorProto_ReservedRange* _add = _internal_add_reserved_range();
+ // @@protoc_insertion_point(field_add:google.protobuf.DescriptorProto.reserved_range)
+ return _add;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::DescriptorProto_ReservedRange >&
+DescriptorProto::reserved_range() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.DescriptorProto.reserved_range)
+ return reserved_range_;
+}
+
+// repeated string reserved_name = 10;
+inline int DescriptorProto::_internal_reserved_name_size() const {
+ return reserved_name_.size();
+}
+inline int DescriptorProto::reserved_name_size() const {
+ return _internal_reserved_name_size();
+}
+inline void DescriptorProto::clear_reserved_name() {
+ reserved_name_.Clear();
+}
+inline 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 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 reserved_name_.Mutable(index);
+}
+inline void DescriptorProto::set_reserved_name(int index, const std::string& value) {
+ reserved_name_.Mutable(index)->assign(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.DescriptorProto.reserved_name)
+}
+inline void DescriptorProto::set_reserved_name(int index, std::string&& value) {
+ reserved_name_.Mutable(index)->assign(std::move(value));
+ // @@protoc_insertion_point(field_set:google.protobuf.DescriptorProto.reserved_name)
+}
+inline void DescriptorProto::set_reserved_name(int index, const char* value) {
+ GOOGLE_DCHECK(value != nullptr);
+ reserved_name_.Mutable(index)->assign(value);
+ // @@protoc_insertion_point(field_set_char:google.protobuf.DescriptorProto.reserved_name)
+}
+inline void DescriptorProto::set_reserved_name(int index, const char* value, size_t size) {
+ reserved_name_.Mutable(index)->assign(
+ reinterpret_cast<const char*>(value), size);
+ // @@protoc_insertion_point(field_set_pointer:google.protobuf.DescriptorProto.reserved_name)
+}
+inline std::string* DescriptorProto::_internal_add_reserved_name() {
+ return reserved_name_.Add();
+}
+inline void DescriptorProto::add_reserved_name(const std::string& value) {
+ reserved_name_.Add()->assign(value);
+ // @@protoc_insertion_point(field_add:google.protobuf.DescriptorProto.reserved_name)
+}
+inline void DescriptorProto::add_reserved_name(std::string&& value) {
+ reserved_name_.Add(std::move(value));
+ // @@protoc_insertion_point(field_add:google.protobuf.DescriptorProto.reserved_name)
+}
+inline void DescriptorProto::add_reserved_name(const char* value) {
+ GOOGLE_DCHECK(value != nullptr);
+ reserved_name_.Add()->assign(value);
+ // @@protoc_insertion_point(field_add_char:google.protobuf.DescriptorProto.reserved_name)
+}
+inline void DescriptorProto::add_reserved_name(const char* value, size_t size) {
+ reserved_name_.Add()->assign(reinterpret_cast<const char*>(value), size);
+ // @@protoc_insertion_point(field_add_pointer:google.protobuf.DescriptorProto.reserved_name)
+}
+inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string>&
+DescriptorProto::reserved_name() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.DescriptorProto.reserved_name)
+ return 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 &reserved_name_;
+}
+
+// -------------------------------------------------------------------
+
+// ExtensionRangeOptions
+
+// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+inline int ExtensionRangeOptions::_internal_uninterpreted_option_size() const {
+ return uninterpreted_option_.size();
+}
+inline int ExtensionRangeOptions::uninterpreted_option_size() const {
+ return _internal_uninterpreted_option_size();
+}
+inline void ExtensionRangeOptions::clear_uninterpreted_option() {
+ uninterpreted_option_.Clear();
+}
+inline ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* ExtensionRangeOptions::mutable_uninterpreted_option(int index) {
+ // @@protoc_insertion_point(field_mutable:google.protobuf.ExtensionRangeOptions.uninterpreted_option)
+ return uninterpreted_option_.Mutable(index);
+}
+inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption >*
+ExtensionRangeOptions::mutable_uninterpreted_option() {
+ // @@protoc_insertion_point(field_mutable_list:google.protobuf.ExtensionRangeOptions.uninterpreted_option)
+ return &uninterpreted_option_;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption& ExtensionRangeOptions::_internal_uninterpreted_option(int index) const {
+ return uninterpreted_option_.Get(index);
+}
+inline const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption& ExtensionRangeOptions::uninterpreted_option(int index) const {
+ // @@protoc_insertion_point(field_get:google.protobuf.ExtensionRangeOptions.uninterpreted_option)
+ return _internal_uninterpreted_option(index);
+}
+inline ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* ExtensionRangeOptions::_internal_add_uninterpreted_option() {
+ return uninterpreted_option_.Add();
+}
+inline ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* ExtensionRangeOptions::add_uninterpreted_option() {
+ ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* _add = _internal_add_uninterpreted_option();
+ // @@protoc_insertion_point(field_add:google.protobuf.ExtensionRangeOptions.uninterpreted_option)
+ return _add;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption >&
+ExtensionRangeOptions::uninterpreted_option() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.ExtensionRangeOptions.uninterpreted_option)
+ return uninterpreted_option_;
+}
+
+// -------------------------------------------------------------------
+
+// FieldDescriptorProto
+
+// optional string name = 1;
+inline bool FieldDescriptorProto::_internal_has_name() const {
+ bool value = (_has_bits_[0] & 0x00000001u) != 0;
+ return value;
+}
+inline bool FieldDescriptorProto::has_name() const {
+ return _internal_has_name();
+}
+inline void FieldDescriptorProto::clear_name() {
+ name_.ClearToEmpty();
+ _has_bits_[0] &= ~0x00000001u;
+}
+inline const 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) {
+ _has_bits_[0] |= 0x00000001u;
+ name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
+ // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.name)
+}
+inline 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 name_.Get();
+}
+inline void FieldDescriptorProto::_internal_set_name(const std::string& value) {
+ _has_bits_[0] |= 0x00000001u;
+ name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation());
+}
+inline std::string* FieldDescriptorProto::_internal_mutable_name() {
+ _has_bits_[0] |= 0x00000001u;
+ return name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation());
+}
+inline std::string* FieldDescriptorProto::release_name() {
+ // @@protoc_insertion_point(field_release:google.protobuf.FieldDescriptorProto.name)
+ if (!_internal_has_name()) {
+ return nullptr;
+ }
+ _has_bits_[0] &= ~0x00000001u;
+ auto* p = name_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (name_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
+ name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ return p;
+}
+inline void FieldDescriptorProto::set_allocated_name(std::string* name) {
+ if (name != nullptr) {
+ _has_bits_[0] |= 0x00000001u;
+ } else {
+ _has_bits_[0] &= ~0x00000001u;
+ }
+ name_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), name,
+ GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (name_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
+ name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.FieldDescriptorProto.name)
+}
+
+// optional int32 number = 3;
+inline bool FieldDescriptorProto::_internal_has_number() const {
+ bool value = (_has_bits_[0] & 0x00000040u) != 0;
+ return value;
+}
+inline bool FieldDescriptorProto::has_number() const {
+ return _internal_has_number();
+}
+inline void FieldDescriptorProto::clear_number() {
+ number_ = 0;
+ _has_bits_[0] &= ~0x00000040u;
+}
+inline int32_t FieldDescriptorProto::_internal_number() const {
+ return 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) {
+ _has_bits_[0] |= 0x00000040u;
+ 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 = (_has_bits_[0] & 0x00000200u) != 0;
+ return value;
+}
+inline bool FieldDescriptorProto::has_label() const {
+ return _internal_has_label();
+}
+inline void FieldDescriptorProto::clear_label() {
+ label_ = 1;
+ _has_bits_[0] &= ~0x00000200u;
+}
+inline ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto_Label FieldDescriptorProto::_internal_label() const {
+ return static_cast< ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto_Label >(label_);
+}
+inline ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto_Label FieldDescriptorProto::label() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.label)
+ return _internal_label();
+}
+inline void FieldDescriptorProto::_internal_set_label(::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto_Label value) {
+ assert(::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto_Label_IsValid(value));
+ _has_bits_[0] |= 0x00000200u;
+ label_ = value;
+}
+inline void FieldDescriptorProto::set_label(::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto_Label value) {
+ _internal_set_label(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.label)
+}
+
+// optional .google.protobuf.FieldDescriptorProto.Type type = 5;
+inline bool FieldDescriptorProto::_internal_has_type() const {
+ bool value = (_has_bits_[0] & 0x00000400u) != 0;
+ return value;
+}
+inline bool FieldDescriptorProto::has_type() const {
+ return _internal_has_type();
+}
+inline void FieldDescriptorProto::clear_type() {
+ type_ = 1;
+ _has_bits_[0] &= ~0x00000400u;
+}
+inline ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto_Type FieldDescriptorProto::_internal_type() const {
+ return static_cast< ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto_Type >(type_);
+}
+inline ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto_Type FieldDescriptorProto::type() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.type)
+ return _internal_type();
+}
+inline void FieldDescriptorProto::_internal_set_type(::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto_Type value) {
+ assert(::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto_Type_IsValid(value));
+ _has_bits_[0] |= 0x00000400u;
+ type_ = value;
+}
+inline void FieldDescriptorProto::set_type(::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto_Type value) {
+ _internal_set_type(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.type)
+}
+
+// optional string type_name = 6;
+inline bool FieldDescriptorProto::_internal_has_type_name() const {
+ bool value = (_has_bits_[0] & 0x00000004u) != 0;
+ return value;
+}
+inline bool FieldDescriptorProto::has_type_name() const {
+ return _internal_has_type_name();
+}
+inline void FieldDescriptorProto::clear_type_name() {
+ type_name_.ClearToEmpty();
+ _has_bits_[0] &= ~0x00000004u;
+}
+inline const 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) {
+ _has_bits_[0] |= 0x00000004u;
+ type_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
+ // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.type_name)
+}
+inline 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 type_name_.Get();
+}
+inline void FieldDescriptorProto::_internal_set_type_name(const std::string& value) {
+ _has_bits_[0] |= 0x00000004u;
+ type_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation());
+}
+inline std::string* FieldDescriptorProto::_internal_mutable_type_name() {
+ _has_bits_[0] |= 0x00000004u;
+ return type_name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, 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;
+ }
+ _has_bits_[0] &= ~0x00000004u;
+ auto* p = type_name_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (type_name_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
+ type_name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ return p;
+}
+inline void FieldDescriptorProto::set_allocated_type_name(std::string* type_name) {
+ if (type_name != nullptr) {
+ _has_bits_[0] |= 0x00000004u;
+ } else {
+ _has_bits_[0] &= ~0x00000004u;
+ }
+ type_name_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), type_name,
+ GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (type_name_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
+ type_name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.FieldDescriptorProto.type_name)
+}
+
+// optional string extendee = 2;
+inline bool FieldDescriptorProto::_internal_has_extendee() const {
+ bool value = (_has_bits_[0] & 0x00000002u) != 0;
+ return value;
+}
+inline bool FieldDescriptorProto::has_extendee() const {
+ return _internal_has_extendee();
+}
+inline void FieldDescriptorProto::clear_extendee() {
+ extendee_.ClearToEmpty();
+ _has_bits_[0] &= ~0x00000002u;
+}
+inline const 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) {
+ _has_bits_[0] |= 0x00000002u;
+ extendee_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
+ // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.extendee)
+}
+inline 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 extendee_.Get();
+}
+inline void FieldDescriptorProto::_internal_set_extendee(const std::string& value) {
+ _has_bits_[0] |= 0x00000002u;
+ extendee_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation());
+}
+inline std::string* FieldDescriptorProto::_internal_mutable_extendee() {
+ _has_bits_[0] |= 0x00000002u;
+ return extendee_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation());
+}
+inline std::string* FieldDescriptorProto::release_extendee() {
+ // @@protoc_insertion_point(field_release:google.protobuf.FieldDescriptorProto.extendee)
+ if (!_internal_has_extendee()) {
+ return nullptr;
+ }
+ _has_bits_[0] &= ~0x00000002u;
+ auto* p = extendee_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (extendee_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
+ extendee_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ return p;
+}
+inline void FieldDescriptorProto::set_allocated_extendee(std::string* extendee) {
+ if (extendee != nullptr) {
+ _has_bits_[0] |= 0x00000002u;
+ } else {
+ _has_bits_[0] &= ~0x00000002u;
+ }
+ extendee_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), extendee,
+ GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (extendee_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
+ extendee_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.FieldDescriptorProto.extendee)
+}
+
+// optional string default_value = 7;
+inline bool FieldDescriptorProto::_internal_has_default_value() const {
+ bool value = (_has_bits_[0] & 0x00000008u) != 0;
+ return value;
+}
+inline bool FieldDescriptorProto::has_default_value() const {
+ return _internal_has_default_value();
+}
+inline void FieldDescriptorProto::clear_default_value() {
+ default_value_.ClearToEmpty();
+ _has_bits_[0] &= ~0x00000008u;
+}
+inline const 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) {
+ _has_bits_[0] |= 0x00000008u;
+ default_value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
+ // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.default_value)
+}
+inline 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 default_value_.Get();
+}
+inline void FieldDescriptorProto::_internal_set_default_value(const std::string& value) {
+ _has_bits_[0] |= 0x00000008u;
+ default_value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation());
+}
+inline std::string* FieldDescriptorProto::_internal_mutable_default_value() {
+ _has_bits_[0] |= 0x00000008u;
+ return default_value_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, 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;
+ }
+ _has_bits_[0] &= ~0x00000008u;
+ auto* p = default_value_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (default_value_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
+ default_value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ return p;
+}
+inline void FieldDescriptorProto::set_allocated_default_value(std::string* default_value) {
+ if (default_value != nullptr) {
+ _has_bits_[0] |= 0x00000008u;
+ } else {
+ _has_bits_[0] &= ~0x00000008u;
+ }
+ default_value_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), default_value,
+ GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (default_value_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
+ default_value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.FieldDescriptorProto.default_value)
+}
+
+// optional int32 oneof_index = 9;
+inline bool FieldDescriptorProto::_internal_has_oneof_index() const {
+ bool value = (_has_bits_[0] & 0x00000080u) != 0;
+ return value;
+}
+inline bool FieldDescriptorProto::has_oneof_index() const {
+ return _internal_has_oneof_index();
+}
+inline void FieldDescriptorProto::clear_oneof_index() {
+ oneof_index_ = 0;
+ _has_bits_[0] &= ~0x00000080u;
+}
+inline int32_t FieldDescriptorProto::_internal_oneof_index() const {
+ return 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) {
+ _has_bits_[0] |= 0x00000080u;
+ 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 = (_has_bits_[0] & 0x00000010u) != 0;
+ return value;
+}
+inline bool FieldDescriptorProto::has_json_name() const {
+ return _internal_has_json_name();
+}
+inline void FieldDescriptorProto::clear_json_name() {
+ json_name_.ClearToEmpty();
+ _has_bits_[0] &= ~0x00000010u;
+}
+inline const 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) {
+ _has_bits_[0] |= 0x00000010u;
+ json_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
+ // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.json_name)
+}
+inline 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 json_name_.Get();
+}
+inline void FieldDescriptorProto::_internal_set_json_name(const std::string& value) {
+ _has_bits_[0] |= 0x00000010u;
+ json_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation());
+}
+inline std::string* FieldDescriptorProto::_internal_mutable_json_name() {
+ _has_bits_[0] |= 0x00000010u;
+ return json_name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, 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;
+ }
+ _has_bits_[0] &= ~0x00000010u;
+ auto* p = json_name_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (json_name_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
+ json_name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ return p;
+}
+inline void FieldDescriptorProto::set_allocated_json_name(std::string* json_name) {
+ if (json_name != nullptr) {
+ _has_bits_[0] |= 0x00000010u;
+ } else {
+ _has_bits_[0] &= ~0x00000010u;
+ }
+ json_name_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), json_name,
+ GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (json_name_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
+ json_name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.FieldDescriptorProto.json_name)
+}
+
+// optional .google.protobuf.FieldOptions options = 8;
+inline bool FieldDescriptorProto::_internal_has_options() const {
+ bool value = (_has_bits_[0] & 0x00000020u) != 0;
+ PROTOBUF_ASSUME(!value || options_ != nullptr);
+ return value;
+}
+inline bool FieldDescriptorProto::has_options() const {
+ return _internal_has_options();
+}
+inline void FieldDescriptorProto::clear_options() {
+ if (options_ != nullptr) options_->Clear();
+ _has_bits_[0] &= ~0x00000020u;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::FieldOptions& FieldDescriptorProto::_internal_options() const {
+ const ::PROTOBUF_NAMESPACE_ID::FieldOptions* p = options_;
+ return p != nullptr ? *p : reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::FieldOptions&>(
+ ::PROTOBUF_NAMESPACE_ID::_FieldOptions_default_instance_);
+}
+inline const ::PROTOBUF_NAMESPACE_ID::FieldOptions& FieldDescriptorProto::options() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.options)
+ return _internal_options();
+}
+inline void FieldDescriptorProto::unsafe_arena_set_allocated_options(
+ ::PROTOBUF_NAMESPACE_ID::FieldOptions* options) {
+ if (GetArenaForAllocation() == nullptr) {
+ delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(options_);
+ }
+ options_ = options;
+ if (options) {
+ _has_bits_[0] |= 0x00000020u;
+ } else {
+ _has_bits_[0] &= ~0x00000020u;
+ }
+ // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.FieldDescriptorProto.options)
+}
+inline ::PROTOBUF_NAMESPACE_ID::FieldOptions* FieldDescriptorProto::release_options() {
+ _has_bits_[0] &= ~0x00000020u;
+ ::PROTOBUF_NAMESPACE_ID::FieldOptions* temp = options_;
+ options_ = nullptr;
+#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE
+ auto* old = reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(temp);
+ temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
+ if (GetArenaForAllocation() == nullptr) { delete old; }
+#else // PROTOBUF_FORCE_COPY_IN_RELEASE
+ if (GetArenaForAllocation() != nullptr) {
+ temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
+ }
+#endif // !PROTOBUF_FORCE_COPY_IN_RELEASE
+ return temp;
+}
+inline ::PROTOBUF_NAMESPACE_ID::FieldOptions* FieldDescriptorProto::unsafe_arena_release_options() {
+ // @@protoc_insertion_point(field_release:google.protobuf.FieldDescriptorProto.options)
+ _has_bits_[0] &= ~0x00000020u;
+ ::PROTOBUF_NAMESPACE_ID::FieldOptions* temp = options_;
+ options_ = nullptr;
+ return temp;
+}
+inline ::PROTOBUF_NAMESPACE_ID::FieldOptions* FieldDescriptorProto::_internal_mutable_options() {
+ _has_bits_[0] |= 0x00000020u;
+ if (options_ == nullptr) {
+ auto* p = CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::FieldOptions>(GetArenaForAllocation());
+ options_ = p;
+ }
+ return options_;
+}
+inline ::PROTOBUF_NAMESPACE_ID::FieldOptions* FieldDescriptorProto::mutable_options() {
+ ::PROTOBUF_NAMESPACE_ID::FieldOptions* _msg = _internal_mutable_options();
+ // @@protoc_insertion_point(field_mutable:google.protobuf.FieldDescriptorProto.options)
+ return _msg;
+}
+inline void FieldDescriptorProto::set_allocated_options(::PROTOBUF_NAMESPACE_ID::FieldOptions* options) {
+ ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaForAllocation();
+ if (message_arena == nullptr) {
+ delete options_;
+ }
+ if (options) {
+ ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
+ ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper<::PROTOBUF_NAMESPACE_ID::FieldOptions>::GetOwningArena(options);
+ if (message_arena != submessage_arena) {
+ options = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
+ message_arena, options, submessage_arena);
+ }
+ _has_bits_[0] |= 0x00000020u;
+ } else {
+ _has_bits_[0] &= ~0x00000020u;
+ }
+ options_ = options;
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.FieldDescriptorProto.options)
+}
+
+// optional bool proto3_optional = 17;
+inline bool FieldDescriptorProto::_internal_has_proto3_optional() const {
+ bool value = (_has_bits_[0] & 0x00000100u) != 0;
+ return value;
+}
+inline bool FieldDescriptorProto::has_proto3_optional() const {
+ return _internal_has_proto3_optional();
+}
+inline void FieldDescriptorProto::clear_proto3_optional() {
+ proto3_optional_ = false;
+ _has_bits_[0] &= ~0x00000100u;
+}
+inline bool FieldDescriptorProto::_internal_proto3_optional() const {
+ return proto3_optional_;
+}
+inline bool FieldDescriptorProto::proto3_optional() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.proto3_optional)
+ return _internal_proto3_optional();
+}
+inline void FieldDescriptorProto::_internal_set_proto3_optional(bool value) {
+ _has_bits_[0] |= 0x00000100u;
+ proto3_optional_ = value;
+}
+inline void FieldDescriptorProto::set_proto3_optional(bool value) {
+ _internal_set_proto3_optional(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.proto3_optional)
+}
+
+// -------------------------------------------------------------------
+
+// OneofDescriptorProto
+
+// optional string name = 1;
+inline bool OneofDescriptorProto::_internal_has_name() const {
+ bool value = (_has_bits_[0] & 0x00000001u) != 0;
+ return value;
+}
+inline bool OneofDescriptorProto::has_name() const {
+ return _internal_has_name();
+}
+inline void OneofDescriptorProto::clear_name() {
+ name_.ClearToEmpty();
+ _has_bits_[0] &= ~0x00000001u;
+}
+inline const 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) {
+ _has_bits_[0] |= 0x00000001u;
+ name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
+ // @@protoc_insertion_point(field_set:google.protobuf.OneofDescriptorProto.name)
+}
+inline 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 name_.Get();
+}
+inline void OneofDescriptorProto::_internal_set_name(const std::string& value) {
+ _has_bits_[0] |= 0x00000001u;
+ name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation());
+}
+inline std::string* OneofDescriptorProto::_internal_mutable_name() {
+ _has_bits_[0] |= 0x00000001u;
+ return name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation());
+}
+inline std::string* OneofDescriptorProto::release_name() {
+ // @@protoc_insertion_point(field_release:google.protobuf.OneofDescriptorProto.name)
+ if (!_internal_has_name()) {
+ return nullptr;
+ }
+ _has_bits_[0] &= ~0x00000001u;
+ auto* p = name_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (name_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
+ name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ return p;
+}
+inline void OneofDescriptorProto::set_allocated_name(std::string* name) {
+ if (name != nullptr) {
+ _has_bits_[0] |= 0x00000001u;
+ } else {
+ _has_bits_[0] &= ~0x00000001u;
+ }
+ name_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), name,
+ GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (name_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
+ name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.OneofDescriptorProto.name)
+}
+
+// optional .google.protobuf.OneofOptions options = 2;
+inline bool OneofDescriptorProto::_internal_has_options() const {
+ bool value = (_has_bits_[0] & 0x00000002u) != 0;
+ PROTOBUF_ASSUME(!value || options_ != nullptr);
+ return value;
+}
+inline bool OneofDescriptorProto::has_options() const {
+ return _internal_has_options();
+}
+inline void OneofDescriptorProto::clear_options() {
+ if (options_ != nullptr) options_->Clear();
+ _has_bits_[0] &= ~0x00000002u;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::OneofOptions& OneofDescriptorProto::_internal_options() const {
+ const ::PROTOBUF_NAMESPACE_ID::OneofOptions* p = options_;
+ return p != nullptr ? *p : reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::OneofOptions&>(
+ ::PROTOBUF_NAMESPACE_ID::_OneofOptions_default_instance_);
+}
+inline const ::PROTOBUF_NAMESPACE_ID::OneofOptions& OneofDescriptorProto::options() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.OneofDescriptorProto.options)
+ return _internal_options();
+}
+inline void OneofDescriptorProto::unsafe_arena_set_allocated_options(
+ ::PROTOBUF_NAMESPACE_ID::OneofOptions* options) {
+ if (GetArenaForAllocation() == nullptr) {
+ delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(options_);
+ }
+ options_ = options;
+ if (options) {
+ _has_bits_[0] |= 0x00000002u;
+ } else {
+ _has_bits_[0] &= ~0x00000002u;
+ }
+ // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.OneofDescriptorProto.options)
+}
+inline ::PROTOBUF_NAMESPACE_ID::OneofOptions* OneofDescriptorProto::release_options() {
+ _has_bits_[0] &= ~0x00000002u;
+ ::PROTOBUF_NAMESPACE_ID::OneofOptions* temp = options_;
+ options_ = nullptr;
+#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE
+ auto* old = reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(temp);
+ temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
+ if (GetArenaForAllocation() == nullptr) { delete old; }
+#else // PROTOBUF_FORCE_COPY_IN_RELEASE
+ if (GetArenaForAllocation() != nullptr) {
+ temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
+ }
+#endif // !PROTOBUF_FORCE_COPY_IN_RELEASE
+ return temp;
+}
+inline ::PROTOBUF_NAMESPACE_ID::OneofOptions* OneofDescriptorProto::unsafe_arena_release_options() {
+ // @@protoc_insertion_point(field_release:google.protobuf.OneofDescriptorProto.options)
+ _has_bits_[0] &= ~0x00000002u;
+ ::PROTOBUF_NAMESPACE_ID::OneofOptions* temp = options_;
+ options_ = nullptr;
+ return temp;
+}
+inline ::PROTOBUF_NAMESPACE_ID::OneofOptions* OneofDescriptorProto::_internal_mutable_options() {
+ _has_bits_[0] |= 0x00000002u;
+ if (options_ == nullptr) {
+ auto* p = CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::OneofOptions>(GetArenaForAllocation());
+ options_ = p;
+ }
+ return options_;
+}
+inline ::PROTOBUF_NAMESPACE_ID::OneofOptions* OneofDescriptorProto::mutable_options() {
+ ::PROTOBUF_NAMESPACE_ID::OneofOptions* _msg = _internal_mutable_options();
+ // @@protoc_insertion_point(field_mutable:google.protobuf.OneofDescriptorProto.options)
+ return _msg;
+}
+inline void OneofDescriptorProto::set_allocated_options(::PROTOBUF_NAMESPACE_ID::OneofOptions* options) {
+ ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaForAllocation();
+ if (message_arena == nullptr) {
+ delete options_;
+ }
+ if (options) {
+ ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
+ ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper<::PROTOBUF_NAMESPACE_ID::OneofOptions>::GetOwningArena(options);
+ if (message_arena != submessage_arena) {
+ options = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
+ message_arena, options, submessage_arena);
+ }
+ _has_bits_[0] |= 0x00000002u;
+ } else {
+ _has_bits_[0] &= ~0x00000002u;
+ }
+ options_ = options;
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.OneofDescriptorProto.options)
+}
+
+// -------------------------------------------------------------------
+
+// EnumDescriptorProto_EnumReservedRange
+
+// optional int32 start = 1;
+inline bool EnumDescriptorProto_EnumReservedRange::_internal_has_start() const {
+ bool value = (_has_bits_[0] & 0x00000001u) != 0;
+ return value;
+}
+inline bool EnumDescriptorProto_EnumReservedRange::has_start() const {
+ return _internal_has_start();
+}
+inline void EnumDescriptorProto_EnumReservedRange::clear_start() {
+ start_ = 0;
+ _has_bits_[0] &= ~0x00000001u;
+}
+inline int32_t EnumDescriptorProto_EnumReservedRange::_internal_start() const {
+ return 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) {
+ _has_bits_[0] |= 0x00000001u;
+ 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 = (_has_bits_[0] & 0x00000002u) != 0;
+ return value;
+}
+inline bool EnumDescriptorProto_EnumReservedRange::has_end() const {
+ return _internal_has_end();
+}
+inline void EnumDescriptorProto_EnumReservedRange::clear_end() {
+ end_ = 0;
+ _has_bits_[0] &= ~0x00000002u;
+}
+inline int32_t EnumDescriptorProto_EnumReservedRange::_internal_end() const {
+ return 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) {
+ _has_bits_[0] |= 0x00000002u;
+ 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 = (_has_bits_[0] & 0x00000001u) != 0;
+ return value;
+}
+inline bool EnumDescriptorProto::has_name() const {
+ return _internal_has_name();
+}
+inline void EnumDescriptorProto::clear_name() {
+ name_.ClearToEmpty();
+ _has_bits_[0] &= ~0x00000001u;
+}
+inline const 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) {
+ _has_bits_[0] |= 0x00000001u;
+ name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
+ // @@protoc_insertion_point(field_set:google.protobuf.EnumDescriptorProto.name)
+}
+inline 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 name_.Get();
+}
+inline void EnumDescriptorProto::_internal_set_name(const std::string& value) {
+ _has_bits_[0] |= 0x00000001u;
+ name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation());
+}
+inline std::string* EnumDescriptorProto::_internal_mutable_name() {
+ _has_bits_[0] |= 0x00000001u;
+ return name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation());
+}
+inline std::string* EnumDescriptorProto::release_name() {
+ // @@protoc_insertion_point(field_release:google.protobuf.EnumDescriptorProto.name)
+ if (!_internal_has_name()) {
+ return nullptr;
+ }
+ _has_bits_[0] &= ~0x00000001u;
+ auto* p = name_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (name_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
+ name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ return p;
+}
+inline void EnumDescriptorProto::set_allocated_name(std::string* name) {
+ if (name != nullptr) {
+ _has_bits_[0] |= 0x00000001u;
+ } else {
+ _has_bits_[0] &= ~0x00000001u;
+ }
+ name_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), name,
+ GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (name_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
+ name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.EnumDescriptorProto.name)
+}
+
+// repeated .google.protobuf.EnumValueDescriptorProto value = 2;
+inline int EnumDescriptorProto::_internal_value_size() const {
+ return value_.size();
+}
+inline int EnumDescriptorProto::value_size() const {
+ return _internal_value_size();
+}
+inline void EnumDescriptorProto::clear_value() {
+ value_.Clear();
+}
+inline ::PROTOBUF_NAMESPACE_ID::EnumValueDescriptorProto* EnumDescriptorProto::mutable_value(int index) {
+ // @@protoc_insertion_point(field_mutable:google.protobuf.EnumDescriptorProto.value)
+ return value_.Mutable(index);
+}
+inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::EnumValueDescriptorProto >*
+EnumDescriptorProto::mutable_value() {
+ // @@protoc_insertion_point(field_mutable_list:google.protobuf.EnumDescriptorProto.value)
+ return &value_;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::EnumValueDescriptorProto& EnumDescriptorProto::_internal_value(int index) const {
+ return value_.Get(index);
+}
+inline const ::PROTOBUF_NAMESPACE_ID::EnumValueDescriptorProto& EnumDescriptorProto::value(int index) const {
+ // @@protoc_insertion_point(field_get:google.protobuf.EnumDescriptorProto.value)
+ return _internal_value(index);
+}
+inline ::PROTOBUF_NAMESPACE_ID::EnumValueDescriptorProto* EnumDescriptorProto::_internal_add_value() {
+ return value_.Add();
+}
+inline ::PROTOBUF_NAMESPACE_ID::EnumValueDescriptorProto* EnumDescriptorProto::add_value() {
+ ::PROTOBUF_NAMESPACE_ID::EnumValueDescriptorProto* _add = _internal_add_value();
+ // @@protoc_insertion_point(field_add:google.protobuf.EnumDescriptorProto.value)
+ return _add;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::EnumValueDescriptorProto >&
+EnumDescriptorProto::value() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.EnumDescriptorProto.value)
+ return value_;
+}
+
+// optional .google.protobuf.EnumOptions options = 3;
+inline bool EnumDescriptorProto::_internal_has_options() const {
+ bool value = (_has_bits_[0] & 0x00000002u) != 0;
+ PROTOBUF_ASSUME(!value || options_ != nullptr);
+ return value;
+}
+inline bool EnumDescriptorProto::has_options() const {
+ return _internal_has_options();
+}
+inline void EnumDescriptorProto::clear_options() {
+ if (options_ != nullptr) options_->Clear();
+ _has_bits_[0] &= ~0x00000002u;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::EnumOptions& EnumDescriptorProto::_internal_options() const {
+ const ::PROTOBUF_NAMESPACE_ID::EnumOptions* p = options_;
+ return p != nullptr ? *p : reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::EnumOptions&>(
+ ::PROTOBUF_NAMESPACE_ID::_EnumOptions_default_instance_);
+}
+inline const ::PROTOBUF_NAMESPACE_ID::EnumOptions& EnumDescriptorProto::options() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.EnumDescriptorProto.options)
+ return _internal_options();
+}
+inline void EnumDescriptorProto::unsafe_arena_set_allocated_options(
+ ::PROTOBUF_NAMESPACE_ID::EnumOptions* options) {
+ if (GetArenaForAllocation() == nullptr) {
+ delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(options_);
+ }
+ options_ = options;
+ if (options) {
+ _has_bits_[0] |= 0x00000002u;
+ } else {
+ _has_bits_[0] &= ~0x00000002u;
+ }
+ // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.EnumDescriptorProto.options)
+}
+inline ::PROTOBUF_NAMESPACE_ID::EnumOptions* EnumDescriptorProto::release_options() {
+ _has_bits_[0] &= ~0x00000002u;
+ ::PROTOBUF_NAMESPACE_ID::EnumOptions* temp = options_;
+ options_ = nullptr;
+#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE
+ auto* old = reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(temp);
+ temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
+ if (GetArenaForAllocation() == nullptr) { delete old; }
+#else // PROTOBUF_FORCE_COPY_IN_RELEASE
+ if (GetArenaForAllocation() != nullptr) {
+ temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
+ }
+#endif // !PROTOBUF_FORCE_COPY_IN_RELEASE
+ return temp;
+}
+inline ::PROTOBUF_NAMESPACE_ID::EnumOptions* EnumDescriptorProto::unsafe_arena_release_options() {
+ // @@protoc_insertion_point(field_release:google.protobuf.EnumDescriptorProto.options)
+ _has_bits_[0] &= ~0x00000002u;
+ ::PROTOBUF_NAMESPACE_ID::EnumOptions* temp = options_;
+ options_ = nullptr;
+ return temp;
+}
+inline ::PROTOBUF_NAMESPACE_ID::EnumOptions* EnumDescriptorProto::_internal_mutable_options() {
+ _has_bits_[0] |= 0x00000002u;
+ if (options_ == nullptr) {
+ auto* p = CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::EnumOptions>(GetArenaForAllocation());
+ options_ = p;
+ }
+ return options_;
+}
+inline ::PROTOBUF_NAMESPACE_ID::EnumOptions* EnumDescriptorProto::mutable_options() {
+ ::PROTOBUF_NAMESPACE_ID::EnumOptions* _msg = _internal_mutable_options();
+ // @@protoc_insertion_point(field_mutable:google.protobuf.EnumDescriptorProto.options)
+ return _msg;
+}
+inline void EnumDescriptorProto::set_allocated_options(::PROTOBUF_NAMESPACE_ID::EnumOptions* options) {
+ ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaForAllocation();
+ if (message_arena == nullptr) {
+ delete options_;
+ }
+ if (options) {
+ ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
+ ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper<::PROTOBUF_NAMESPACE_ID::EnumOptions>::GetOwningArena(options);
+ if (message_arena != submessage_arena) {
+ options = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
+ message_arena, options, submessage_arena);
+ }
+ _has_bits_[0] |= 0x00000002u;
+ } else {
+ _has_bits_[0] &= ~0x00000002u;
+ }
+ options_ = options;
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.EnumDescriptorProto.options)
+}
+
+// repeated .google.protobuf.EnumDescriptorProto.EnumReservedRange reserved_range = 4;
+inline int EnumDescriptorProto::_internal_reserved_range_size() const {
+ return reserved_range_.size();
+}
+inline int EnumDescriptorProto::reserved_range_size() const {
+ return _internal_reserved_range_size();
+}
+inline void EnumDescriptorProto::clear_reserved_range() {
+ reserved_range_.Clear();
+}
+inline ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto_EnumReservedRange* EnumDescriptorProto::mutable_reserved_range(int index) {
+ // @@protoc_insertion_point(field_mutable:google.protobuf.EnumDescriptorProto.reserved_range)
+ return reserved_range_.Mutable(index);
+}
+inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto_EnumReservedRange >*
+EnumDescriptorProto::mutable_reserved_range() {
+ // @@protoc_insertion_point(field_mutable_list:google.protobuf.EnumDescriptorProto.reserved_range)
+ return &reserved_range_;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto_EnumReservedRange& EnumDescriptorProto::_internal_reserved_range(int index) const {
+ return reserved_range_.Get(index);
+}
+inline const ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto_EnumReservedRange& EnumDescriptorProto::reserved_range(int index) const {
+ // @@protoc_insertion_point(field_get:google.protobuf.EnumDescriptorProto.reserved_range)
+ return _internal_reserved_range(index);
+}
+inline ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto_EnumReservedRange* EnumDescriptorProto::_internal_add_reserved_range() {
+ return reserved_range_.Add();
+}
+inline ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto_EnumReservedRange* EnumDescriptorProto::add_reserved_range() {
+ ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto_EnumReservedRange* _add = _internal_add_reserved_range();
+ // @@protoc_insertion_point(field_add:google.protobuf.EnumDescriptorProto.reserved_range)
+ return _add;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto_EnumReservedRange >&
+EnumDescriptorProto::reserved_range() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.EnumDescriptorProto.reserved_range)
+ return reserved_range_;
+}
+
+// repeated string reserved_name = 5;
+inline int EnumDescriptorProto::_internal_reserved_name_size() const {
+ return reserved_name_.size();
+}
+inline int EnumDescriptorProto::reserved_name_size() const {
+ return _internal_reserved_name_size();
+}
+inline void EnumDescriptorProto::clear_reserved_name() {
+ reserved_name_.Clear();
+}
+inline 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 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 reserved_name_.Mutable(index);
+}
+inline void EnumDescriptorProto::set_reserved_name(int index, const std::string& value) {
+ reserved_name_.Mutable(index)->assign(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.EnumDescriptorProto.reserved_name)
+}
+inline void EnumDescriptorProto::set_reserved_name(int index, std::string&& value) {
+ reserved_name_.Mutable(index)->assign(std::move(value));
+ // @@protoc_insertion_point(field_set:google.protobuf.EnumDescriptorProto.reserved_name)
+}
+inline void EnumDescriptorProto::set_reserved_name(int index, const char* value) {
+ GOOGLE_DCHECK(value != nullptr);
+ reserved_name_.Mutable(index)->assign(value);
+ // @@protoc_insertion_point(field_set_char:google.protobuf.EnumDescriptorProto.reserved_name)
+}
+inline void EnumDescriptorProto::set_reserved_name(int index, const char* value, size_t size) {
+ reserved_name_.Mutable(index)->assign(
+ reinterpret_cast<const char*>(value), size);
+ // @@protoc_insertion_point(field_set_pointer:google.protobuf.EnumDescriptorProto.reserved_name)
+}
+inline std::string* EnumDescriptorProto::_internal_add_reserved_name() {
+ return reserved_name_.Add();
+}
+inline void EnumDescriptorProto::add_reserved_name(const std::string& value) {
+ reserved_name_.Add()->assign(value);
+ // @@protoc_insertion_point(field_add:google.protobuf.EnumDescriptorProto.reserved_name)
+}
+inline void EnumDescriptorProto::add_reserved_name(std::string&& value) {
+ reserved_name_.Add(std::move(value));
+ // @@protoc_insertion_point(field_add:google.protobuf.EnumDescriptorProto.reserved_name)
+}
+inline void EnumDescriptorProto::add_reserved_name(const char* value) {
+ GOOGLE_DCHECK(value != nullptr);
+ reserved_name_.Add()->assign(value);
+ // @@protoc_insertion_point(field_add_char:google.protobuf.EnumDescriptorProto.reserved_name)
+}
+inline void EnumDescriptorProto::add_reserved_name(const char* value, size_t size) {
+ reserved_name_.Add()->assign(reinterpret_cast<const char*>(value), size);
+ // @@protoc_insertion_point(field_add_pointer:google.protobuf.EnumDescriptorProto.reserved_name)
+}
+inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string>&
+EnumDescriptorProto::reserved_name() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.EnumDescriptorProto.reserved_name)
+ return 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 &reserved_name_;
+}
+
+// -------------------------------------------------------------------
+
+// EnumValueDescriptorProto
+
+// optional string name = 1;
+inline bool EnumValueDescriptorProto::_internal_has_name() const {
+ bool value = (_has_bits_[0] & 0x00000001u) != 0;
+ return value;
+}
+inline bool EnumValueDescriptorProto::has_name() const {
+ return _internal_has_name();
+}
+inline void EnumValueDescriptorProto::clear_name() {
+ name_.ClearToEmpty();
+ _has_bits_[0] &= ~0x00000001u;
+}
+inline const 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) {
+ _has_bits_[0] |= 0x00000001u;
+ name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
+ // @@protoc_insertion_point(field_set:google.protobuf.EnumValueDescriptorProto.name)
+}
+inline 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 name_.Get();
+}
+inline void EnumValueDescriptorProto::_internal_set_name(const std::string& value) {
+ _has_bits_[0] |= 0x00000001u;
+ name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation());
+}
+inline std::string* EnumValueDescriptorProto::_internal_mutable_name() {
+ _has_bits_[0] |= 0x00000001u;
+ return name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation());
+}
+inline std::string* EnumValueDescriptorProto::release_name() {
+ // @@protoc_insertion_point(field_release:google.protobuf.EnumValueDescriptorProto.name)
+ if (!_internal_has_name()) {
+ return nullptr;
+ }
+ _has_bits_[0] &= ~0x00000001u;
+ auto* p = name_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (name_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
+ name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ return p;
+}
+inline void EnumValueDescriptorProto::set_allocated_name(std::string* name) {
+ if (name != nullptr) {
+ _has_bits_[0] |= 0x00000001u;
+ } else {
+ _has_bits_[0] &= ~0x00000001u;
+ }
+ name_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), name,
+ GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (name_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
+ name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.EnumValueDescriptorProto.name)
+}
+
+// optional int32 number = 2;
+inline bool EnumValueDescriptorProto::_internal_has_number() const {
+ bool value = (_has_bits_[0] & 0x00000004u) != 0;
+ return value;
+}
+inline bool EnumValueDescriptorProto::has_number() const {
+ return _internal_has_number();
+}
+inline void EnumValueDescriptorProto::clear_number() {
+ number_ = 0;
+ _has_bits_[0] &= ~0x00000004u;
+}
+inline int32_t EnumValueDescriptorProto::_internal_number() const {
+ return 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) {
+ _has_bits_[0] |= 0x00000004u;
+ 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 = (_has_bits_[0] & 0x00000002u) != 0;
+ PROTOBUF_ASSUME(!value || options_ != nullptr);
+ return value;
+}
+inline bool EnumValueDescriptorProto::has_options() const {
+ return _internal_has_options();
+}
+inline void EnumValueDescriptorProto::clear_options() {
+ if (options_ != nullptr) options_->Clear();
+ _has_bits_[0] &= ~0x00000002u;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::EnumValueOptions& EnumValueDescriptorProto::_internal_options() const {
+ const ::PROTOBUF_NAMESPACE_ID::EnumValueOptions* p = options_;
+ return p != nullptr ? *p : reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::EnumValueOptions&>(
+ ::PROTOBUF_NAMESPACE_ID::_EnumValueOptions_default_instance_);
+}
+inline const ::PROTOBUF_NAMESPACE_ID::EnumValueOptions& EnumValueDescriptorProto::options() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.EnumValueDescriptorProto.options)
+ return _internal_options();
+}
+inline void EnumValueDescriptorProto::unsafe_arena_set_allocated_options(
+ ::PROTOBUF_NAMESPACE_ID::EnumValueOptions* options) {
+ if (GetArenaForAllocation() == nullptr) {
+ delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(options_);
+ }
+ options_ = options;
+ if (options) {
+ _has_bits_[0] |= 0x00000002u;
+ } else {
+ _has_bits_[0] &= ~0x00000002u;
+ }
+ // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.EnumValueDescriptorProto.options)
+}
+inline ::PROTOBUF_NAMESPACE_ID::EnumValueOptions* EnumValueDescriptorProto::release_options() {
+ _has_bits_[0] &= ~0x00000002u;
+ ::PROTOBUF_NAMESPACE_ID::EnumValueOptions* temp = options_;
+ options_ = nullptr;
+#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE
+ auto* old = reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(temp);
+ temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
+ if (GetArenaForAllocation() == nullptr) { delete old; }
+#else // PROTOBUF_FORCE_COPY_IN_RELEASE
+ if (GetArenaForAllocation() != nullptr) {
+ temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
+ }
+#endif // !PROTOBUF_FORCE_COPY_IN_RELEASE
+ return temp;
+}
+inline ::PROTOBUF_NAMESPACE_ID::EnumValueOptions* EnumValueDescriptorProto::unsafe_arena_release_options() {
+ // @@protoc_insertion_point(field_release:google.protobuf.EnumValueDescriptorProto.options)
+ _has_bits_[0] &= ~0x00000002u;
+ ::PROTOBUF_NAMESPACE_ID::EnumValueOptions* temp = options_;
+ options_ = nullptr;
+ return temp;
+}
+inline ::PROTOBUF_NAMESPACE_ID::EnumValueOptions* EnumValueDescriptorProto::_internal_mutable_options() {
+ _has_bits_[0] |= 0x00000002u;
+ if (options_ == nullptr) {
+ auto* p = CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::EnumValueOptions>(GetArenaForAllocation());
+ options_ = p;
+ }
+ return options_;
+}
+inline ::PROTOBUF_NAMESPACE_ID::EnumValueOptions* EnumValueDescriptorProto::mutable_options() {
+ ::PROTOBUF_NAMESPACE_ID::EnumValueOptions* _msg = _internal_mutable_options();
+ // @@protoc_insertion_point(field_mutable:google.protobuf.EnumValueDescriptorProto.options)
+ return _msg;
+}
+inline void EnumValueDescriptorProto::set_allocated_options(::PROTOBUF_NAMESPACE_ID::EnumValueOptions* options) {
+ ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaForAllocation();
+ if (message_arena == nullptr) {
+ delete options_;
+ }
+ if (options) {
+ ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
+ ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper<::PROTOBUF_NAMESPACE_ID::EnumValueOptions>::GetOwningArena(options);
+ if (message_arena != submessage_arena) {
+ options = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
+ message_arena, options, submessage_arena);
+ }
+ _has_bits_[0] |= 0x00000002u;
+ } else {
+ _has_bits_[0] &= ~0x00000002u;
+ }
+ options_ = options;
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.EnumValueDescriptorProto.options)
+}
+
+// -------------------------------------------------------------------
+
+// ServiceDescriptorProto
+
+// optional string name = 1;
+inline bool ServiceDescriptorProto::_internal_has_name() const {
+ bool value = (_has_bits_[0] & 0x00000001u) != 0;
+ return value;
+}
+inline bool ServiceDescriptorProto::has_name() const {
+ return _internal_has_name();
+}
+inline void ServiceDescriptorProto::clear_name() {
+ name_.ClearToEmpty();
+ _has_bits_[0] &= ~0x00000001u;
+}
+inline const 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) {
+ _has_bits_[0] |= 0x00000001u;
+ name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
+ // @@protoc_insertion_point(field_set:google.protobuf.ServiceDescriptorProto.name)
+}
+inline 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 name_.Get();
+}
+inline void ServiceDescriptorProto::_internal_set_name(const std::string& value) {
+ _has_bits_[0] |= 0x00000001u;
+ name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation());
+}
+inline std::string* ServiceDescriptorProto::_internal_mutable_name() {
+ _has_bits_[0] |= 0x00000001u;
+ return name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation());
+}
+inline std::string* ServiceDescriptorProto::release_name() {
+ // @@protoc_insertion_point(field_release:google.protobuf.ServiceDescriptorProto.name)
+ if (!_internal_has_name()) {
+ return nullptr;
+ }
+ _has_bits_[0] &= ~0x00000001u;
+ auto* p = name_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (name_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
+ name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ return p;
+}
+inline void ServiceDescriptorProto::set_allocated_name(std::string* name) {
+ if (name != nullptr) {
+ _has_bits_[0] |= 0x00000001u;
+ } else {
+ _has_bits_[0] &= ~0x00000001u;
+ }
+ name_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), name,
+ GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (name_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
+ name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.ServiceDescriptorProto.name)
+}
+
+// repeated .google.protobuf.MethodDescriptorProto method = 2;
+inline int ServiceDescriptorProto::_internal_method_size() const {
+ return method_.size();
+}
+inline int ServiceDescriptorProto::method_size() const {
+ return _internal_method_size();
+}
+inline void ServiceDescriptorProto::clear_method() {
+ method_.Clear();
+}
+inline ::PROTOBUF_NAMESPACE_ID::MethodDescriptorProto* ServiceDescriptorProto::mutable_method(int index) {
+ // @@protoc_insertion_point(field_mutable:google.protobuf.ServiceDescriptorProto.method)
+ return method_.Mutable(index);
+}
+inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::MethodDescriptorProto >*
+ServiceDescriptorProto::mutable_method() {
+ // @@protoc_insertion_point(field_mutable_list:google.protobuf.ServiceDescriptorProto.method)
+ return &method_;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::MethodDescriptorProto& ServiceDescriptorProto::_internal_method(int index) const {
+ return method_.Get(index);
+}
+inline const ::PROTOBUF_NAMESPACE_ID::MethodDescriptorProto& ServiceDescriptorProto::method(int index) const {
+ // @@protoc_insertion_point(field_get:google.protobuf.ServiceDescriptorProto.method)
+ return _internal_method(index);
+}
+inline ::PROTOBUF_NAMESPACE_ID::MethodDescriptorProto* ServiceDescriptorProto::_internal_add_method() {
+ return method_.Add();
+}
+inline ::PROTOBUF_NAMESPACE_ID::MethodDescriptorProto* ServiceDescriptorProto::add_method() {
+ ::PROTOBUF_NAMESPACE_ID::MethodDescriptorProto* _add = _internal_add_method();
+ // @@protoc_insertion_point(field_add:google.protobuf.ServiceDescriptorProto.method)
+ return _add;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::MethodDescriptorProto >&
+ServiceDescriptorProto::method() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.ServiceDescriptorProto.method)
+ return method_;
+}
+
+// optional .google.protobuf.ServiceOptions options = 3;
+inline bool ServiceDescriptorProto::_internal_has_options() const {
+ bool value = (_has_bits_[0] & 0x00000002u) != 0;
+ PROTOBUF_ASSUME(!value || options_ != nullptr);
+ return value;
+}
+inline bool ServiceDescriptorProto::has_options() const {
+ return _internal_has_options();
+}
+inline void ServiceDescriptorProto::clear_options() {
+ if (options_ != nullptr) options_->Clear();
+ _has_bits_[0] &= ~0x00000002u;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::ServiceOptions& ServiceDescriptorProto::_internal_options() const {
+ const ::PROTOBUF_NAMESPACE_ID::ServiceOptions* p = options_;
+ return p != nullptr ? *p : reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::ServiceOptions&>(
+ ::PROTOBUF_NAMESPACE_ID::_ServiceOptions_default_instance_);
+}
+inline const ::PROTOBUF_NAMESPACE_ID::ServiceOptions& ServiceDescriptorProto::options() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.ServiceDescriptorProto.options)
+ return _internal_options();
+}
+inline void ServiceDescriptorProto::unsafe_arena_set_allocated_options(
+ ::PROTOBUF_NAMESPACE_ID::ServiceOptions* options) {
+ if (GetArenaForAllocation() == nullptr) {
+ delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(options_);
+ }
+ options_ = options;
+ if (options) {
+ _has_bits_[0] |= 0x00000002u;
+ } else {
+ _has_bits_[0] &= ~0x00000002u;
+ }
+ // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.ServiceDescriptorProto.options)
+}
+inline ::PROTOBUF_NAMESPACE_ID::ServiceOptions* ServiceDescriptorProto::release_options() {
+ _has_bits_[0] &= ~0x00000002u;
+ ::PROTOBUF_NAMESPACE_ID::ServiceOptions* temp = options_;
+ options_ = nullptr;
+#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE
+ auto* old = reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(temp);
+ temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
+ if (GetArenaForAllocation() == nullptr) { delete old; }
+#else // PROTOBUF_FORCE_COPY_IN_RELEASE
+ if (GetArenaForAllocation() != nullptr) {
+ temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
+ }
+#endif // !PROTOBUF_FORCE_COPY_IN_RELEASE
+ return temp;
+}
+inline ::PROTOBUF_NAMESPACE_ID::ServiceOptions* ServiceDescriptorProto::unsafe_arena_release_options() {
+ // @@protoc_insertion_point(field_release:google.protobuf.ServiceDescriptorProto.options)
+ _has_bits_[0] &= ~0x00000002u;
+ ::PROTOBUF_NAMESPACE_ID::ServiceOptions* temp = options_;
+ options_ = nullptr;
+ return temp;
+}
+inline ::PROTOBUF_NAMESPACE_ID::ServiceOptions* ServiceDescriptorProto::_internal_mutable_options() {
+ _has_bits_[0] |= 0x00000002u;
+ if (options_ == nullptr) {
+ auto* p = CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::ServiceOptions>(GetArenaForAllocation());
+ options_ = p;
+ }
+ return options_;
+}
+inline ::PROTOBUF_NAMESPACE_ID::ServiceOptions* ServiceDescriptorProto::mutable_options() {
+ ::PROTOBUF_NAMESPACE_ID::ServiceOptions* _msg = _internal_mutable_options();
+ // @@protoc_insertion_point(field_mutable:google.protobuf.ServiceDescriptorProto.options)
+ return _msg;
+}
+inline void ServiceDescriptorProto::set_allocated_options(::PROTOBUF_NAMESPACE_ID::ServiceOptions* options) {
+ ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaForAllocation();
+ if (message_arena == nullptr) {
+ delete options_;
+ }
+ if (options) {
+ ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
+ ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper<::PROTOBUF_NAMESPACE_ID::ServiceOptions>::GetOwningArena(options);
+ if (message_arena != submessage_arena) {
+ options = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
+ message_arena, options, submessage_arena);
+ }
+ _has_bits_[0] |= 0x00000002u;
+ } else {
+ _has_bits_[0] &= ~0x00000002u;
+ }
+ options_ = options;
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.ServiceDescriptorProto.options)
+}
+
+// -------------------------------------------------------------------
+
+// MethodDescriptorProto
+
+// optional string name = 1;
+inline bool MethodDescriptorProto::_internal_has_name() const {
+ bool value = (_has_bits_[0] & 0x00000001u) != 0;
+ return value;
+}
+inline bool MethodDescriptorProto::has_name() const {
+ return _internal_has_name();
+}
+inline void MethodDescriptorProto::clear_name() {
+ name_.ClearToEmpty();
+ _has_bits_[0] &= ~0x00000001u;
+}
+inline const 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) {
+ _has_bits_[0] |= 0x00000001u;
+ name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
+ // @@protoc_insertion_point(field_set:google.protobuf.MethodDescriptorProto.name)
+}
+inline 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 name_.Get();
+}
+inline void MethodDescriptorProto::_internal_set_name(const std::string& value) {
+ _has_bits_[0] |= 0x00000001u;
+ name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation());
+}
+inline std::string* MethodDescriptorProto::_internal_mutable_name() {
+ _has_bits_[0] |= 0x00000001u;
+ return name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation());
+}
+inline std::string* MethodDescriptorProto::release_name() {
+ // @@protoc_insertion_point(field_release:google.protobuf.MethodDescriptorProto.name)
+ if (!_internal_has_name()) {
+ return nullptr;
+ }
+ _has_bits_[0] &= ~0x00000001u;
+ auto* p = name_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (name_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
+ name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ return p;
+}
+inline void MethodDescriptorProto::set_allocated_name(std::string* name) {
+ if (name != nullptr) {
+ _has_bits_[0] |= 0x00000001u;
+ } else {
+ _has_bits_[0] &= ~0x00000001u;
+ }
+ name_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), name,
+ GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (name_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
+ name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.MethodDescriptorProto.name)
+}
+
+// optional string input_type = 2;
+inline bool MethodDescriptorProto::_internal_has_input_type() const {
+ bool value = (_has_bits_[0] & 0x00000002u) != 0;
+ return value;
+}
+inline bool MethodDescriptorProto::has_input_type() const {
+ return _internal_has_input_type();
+}
+inline void MethodDescriptorProto::clear_input_type() {
+ input_type_.ClearToEmpty();
+ _has_bits_[0] &= ~0x00000002u;
+}
+inline const 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) {
+ _has_bits_[0] |= 0x00000002u;
+ input_type_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
+ // @@protoc_insertion_point(field_set:google.protobuf.MethodDescriptorProto.input_type)
+}
+inline 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 input_type_.Get();
+}
+inline void MethodDescriptorProto::_internal_set_input_type(const std::string& value) {
+ _has_bits_[0] |= 0x00000002u;
+ input_type_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation());
+}
+inline std::string* MethodDescriptorProto::_internal_mutable_input_type() {
+ _has_bits_[0] |= 0x00000002u;
+ return input_type_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, 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;
+ }
+ _has_bits_[0] &= ~0x00000002u;
+ auto* p = input_type_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (input_type_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
+ input_type_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ return p;
+}
+inline void MethodDescriptorProto::set_allocated_input_type(std::string* input_type) {
+ if (input_type != nullptr) {
+ _has_bits_[0] |= 0x00000002u;
+ } else {
+ _has_bits_[0] &= ~0x00000002u;
+ }
+ input_type_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), input_type,
+ GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (input_type_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
+ input_type_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.MethodDescriptorProto.input_type)
+}
+
+// optional string output_type = 3;
+inline bool MethodDescriptorProto::_internal_has_output_type() const {
+ bool value = (_has_bits_[0] & 0x00000004u) != 0;
+ return value;
+}
+inline bool MethodDescriptorProto::has_output_type() const {
+ return _internal_has_output_type();
+}
+inline void MethodDescriptorProto::clear_output_type() {
+ output_type_.ClearToEmpty();
+ _has_bits_[0] &= ~0x00000004u;
+}
+inline const 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) {
+ _has_bits_[0] |= 0x00000004u;
+ output_type_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
+ // @@protoc_insertion_point(field_set:google.protobuf.MethodDescriptorProto.output_type)
+}
+inline 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 output_type_.Get();
+}
+inline void MethodDescriptorProto::_internal_set_output_type(const std::string& value) {
+ _has_bits_[0] |= 0x00000004u;
+ output_type_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation());
+}
+inline std::string* MethodDescriptorProto::_internal_mutable_output_type() {
+ _has_bits_[0] |= 0x00000004u;
+ return output_type_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, 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;
+ }
+ _has_bits_[0] &= ~0x00000004u;
+ auto* p = output_type_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (output_type_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
+ output_type_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ return p;
+}
+inline void MethodDescriptorProto::set_allocated_output_type(std::string* output_type) {
+ if (output_type != nullptr) {
+ _has_bits_[0] |= 0x00000004u;
+ } else {
+ _has_bits_[0] &= ~0x00000004u;
+ }
+ output_type_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), output_type,
+ GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (output_type_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
+ output_type_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.MethodDescriptorProto.output_type)
+}
+
+// optional .google.protobuf.MethodOptions options = 4;
+inline bool MethodDescriptorProto::_internal_has_options() const {
+ bool value = (_has_bits_[0] & 0x00000008u) != 0;
+ PROTOBUF_ASSUME(!value || options_ != nullptr);
+ return value;
+}
+inline bool MethodDescriptorProto::has_options() const {
+ return _internal_has_options();
+}
+inline void MethodDescriptorProto::clear_options() {
+ if (options_ != nullptr) options_->Clear();
+ _has_bits_[0] &= ~0x00000008u;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::MethodOptions& MethodDescriptorProto::_internal_options() const {
+ const ::PROTOBUF_NAMESPACE_ID::MethodOptions* p = options_;
+ return p != nullptr ? *p : reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::MethodOptions&>(
+ ::PROTOBUF_NAMESPACE_ID::_MethodOptions_default_instance_);
+}
+inline const ::PROTOBUF_NAMESPACE_ID::MethodOptions& MethodDescriptorProto::options() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.MethodDescriptorProto.options)
+ return _internal_options();
+}
+inline void MethodDescriptorProto::unsafe_arena_set_allocated_options(
+ ::PROTOBUF_NAMESPACE_ID::MethodOptions* options) {
+ if (GetArenaForAllocation() == nullptr) {
+ delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(options_);
+ }
+ options_ = options;
+ if (options) {
+ _has_bits_[0] |= 0x00000008u;
+ } else {
+ _has_bits_[0] &= ~0x00000008u;
+ }
+ // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.MethodDescriptorProto.options)
+}
+inline ::PROTOBUF_NAMESPACE_ID::MethodOptions* MethodDescriptorProto::release_options() {
+ _has_bits_[0] &= ~0x00000008u;
+ ::PROTOBUF_NAMESPACE_ID::MethodOptions* temp = options_;
+ options_ = nullptr;
+#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE
+ auto* old = reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(temp);
+ temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
+ if (GetArenaForAllocation() == nullptr) { delete old; }
+#else // PROTOBUF_FORCE_COPY_IN_RELEASE
+ if (GetArenaForAllocation() != nullptr) {
+ temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
+ }
+#endif // !PROTOBUF_FORCE_COPY_IN_RELEASE
+ return temp;
+}
+inline ::PROTOBUF_NAMESPACE_ID::MethodOptions* MethodDescriptorProto::unsafe_arena_release_options() {
+ // @@protoc_insertion_point(field_release:google.protobuf.MethodDescriptorProto.options)
+ _has_bits_[0] &= ~0x00000008u;
+ ::PROTOBUF_NAMESPACE_ID::MethodOptions* temp = options_;
+ options_ = nullptr;
+ return temp;
+}
+inline ::PROTOBUF_NAMESPACE_ID::MethodOptions* MethodDescriptorProto::_internal_mutable_options() {
+ _has_bits_[0] |= 0x00000008u;
+ if (options_ == nullptr) {
+ auto* p = CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::MethodOptions>(GetArenaForAllocation());
+ options_ = p;
+ }
+ return options_;
+}
+inline ::PROTOBUF_NAMESPACE_ID::MethodOptions* MethodDescriptorProto::mutable_options() {
+ ::PROTOBUF_NAMESPACE_ID::MethodOptions* _msg = _internal_mutable_options();
+ // @@protoc_insertion_point(field_mutable:google.protobuf.MethodDescriptorProto.options)
+ return _msg;
+}
+inline void MethodDescriptorProto::set_allocated_options(::PROTOBUF_NAMESPACE_ID::MethodOptions* options) {
+ ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaForAllocation();
+ if (message_arena == nullptr) {
+ delete options_;
+ }
+ if (options) {
+ ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
+ ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper<::PROTOBUF_NAMESPACE_ID::MethodOptions>::GetOwningArena(options);
+ if (message_arena != submessage_arena) {
+ options = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
+ message_arena, options, submessage_arena);
+ }
+ _has_bits_[0] |= 0x00000008u;
+ } else {
+ _has_bits_[0] &= ~0x00000008u;
+ }
+ options_ = options;
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.MethodDescriptorProto.options)
+}
+
+// optional bool client_streaming = 5 [default = false];
+inline bool MethodDescriptorProto::_internal_has_client_streaming() const {
+ bool value = (_has_bits_[0] & 0x00000010u) != 0;
+ return value;
+}
+inline bool MethodDescriptorProto::has_client_streaming() const {
+ return _internal_has_client_streaming();
+}
+inline void MethodDescriptorProto::clear_client_streaming() {
+ client_streaming_ = false;
+ _has_bits_[0] &= ~0x00000010u;
+}
+inline bool MethodDescriptorProto::_internal_client_streaming() const {
+ return client_streaming_;
+}
+inline bool MethodDescriptorProto::client_streaming() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.MethodDescriptorProto.client_streaming)
+ return _internal_client_streaming();
+}
+inline void MethodDescriptorProto::_internal_set_client_streaming(bool value) {
+ _has_bits_[0] |= 0x00000010u;
+ client_streaming_ = value;
+}
+inline void MethodDescriptorProto::set_client_streaming(bool value) {
+ _internal_set_client_streaming(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.MethodDescriptorProto.client_streaming)
+}
+
+// optional bool server_streaming = 6 [default = false];
+inline bool MethodDescriptorProto::_internal_has_server_streaming() const {
+ bool value = (_has_bits_[0] & 0x00000020u) != 0;
+ return value;
+}
+inline bool MethodDescriptorProto::has_server_streaming() const {
+ return _internal_has_server_streaming();
+}
+inline void MethodDescriptorProto::clear_server_streaming() {
+ server_streaming_ = false;
+ _has_bits_[0] &= ~0x00000020u;
+}
+inline bool MethodDescriptorProto::_internal_server_streaming() const {
+ return server_streaming_;
+}
+inline bool MethodDescriptorProto::server_streaming() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.MethodDescriptorProto.server_streaming)
+ return _internal_server_streaming();
+}
+inline void MethodDescriptorProto::_internal_set_server_streaming(bool value) {
+ _has_bits_[0] |= 0x00000020u;
+ server_streaming_ = value;
+}
+inline void MethodDescriptorProto::set_server_streaming(bool value) {
+ _internal_set_server_streaming(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.MethodDescriptorProto.server_streaming)
+}
+
+// -------------------------------------------------------------------
+
+// FileOptions
+
+// optional string java_package = 1;
+inline bool FileOptions::_internal_has_java_package() const {
+ bool value = (_has_bits_[0] & 0x00000001u) != 0;
+ return value;
+}
+inline bool FileOptions::has_java_package() const {
+ return _internal_has_java_package();
+}
+inline void FileOptions::clear_java_package() {
+ java_package_.ClearToEmpty();
+ _has_bits_[0] &= ~0x00000001u;
+}
+inline const 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) {
+ _has_bits_[0] |= 0x00000001u;
+ java_package_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
+ // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.java_package)
+}
+inline 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 java_package_.Get();
+}
+inline void FileOptions::_internal_set_java_package(const std::string& value) {
+ _has_bits_[0] |= 0x00000001u;
+ java_package_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation());
+}
+inline std::string* FileOptions::_internal_mutable_java_package() {
+ _has_bits_[0] |= 0x00000001u;
+ return java_package_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, 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;
+ }
+ _has_bits_[0] &= ~0x00000001u;
+ auto* p = java_package_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (java_package_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
+ java_package_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ return p;
+}
+inline void FileOptions::set_allocated_java_package(std::string* java_package) {
+ if (java_package != nullptr) {
+ _has_bits_[0] |= 0x00000001u;
+ } else {
+ _has_bits_[0] &= ~0x00000001u;
+ }
+ java_package_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), java_package,
+ GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (java_package_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
+ java_package_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileOptions.java_package)
+}
+
+// optional string java_outer_classname = 8;
+inline bool FileOptions::_internal_has_java_outer_classname() const {
+ bool value = (_has_bits_[0] & 0x00000002u) != 0;
+ return value;
+}
+inline bool FileOptions::has_java_outer_classname() const {
+ return _internal_has_java_outer_classname();
+}
+inline void FileOptions::clear_java_outer_classname() {
+ java_outer_classname_.ClearToEmpty();
+ _has_bits_[0] &= ~0x00000002u;
+}
+inline const 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) {
+ _has_bits_[0] |= 0x00000002u;
+ java_outer_classname_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
+ // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.java_outer_classname)
+}
+inline 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 java_outer_classname_.Get();
+}
+inline void FileOptions::_internal_set_java_outer_classname(const std::string& value) {
+ _has_bits_[0] |= 0x00000002u;
+ java_outer_classname_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation());
+}
+inline std::string* FileOptions::_internal_mutable_java_outer_classname() {
+ _has_bits_[0] |= 0x00000002u;
+ return java_outer_classname_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, 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;
+ }
+ _has_bits_[0] &= ~0x00000002u;
+ auto* p = java_outer_classname_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (java_outer_classname_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
+ java_outer_classname_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ return p;
+}
+inline void FileOptions::set_allocated_java_outer_classname(std::string* java_outer_classname) {
+ if (java_outer_classname != nullptr) {
+ _has_bits_[0] |= 0x00000002u;
+ } else {
+ _has_bits_[0] &= ~0x00000002u;
+ }
+ java_outer_classname_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), java_outer_classname,
+ GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (java_outer_classname_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
+ java_outer_classname_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileOptions.java_outer_classname)
+}
+
+// optional bool java_multiple_files = 10 [default = false];
+inline bool FileOptions::_internal_has_java_multiple_files() const {
+ bool value = (_has_bits_[0] & 0x00000400u) != 0;
+ return value;
+}
+inline bool FileOptions::has_java_multiple_files() const {
+ return _internal_has_java_multiple_files();
+}
+inline void FileOptions::clear_java_multiple_files() {
+ java_multiple_files_ = false;
+ _has_bits_[0] &= ~0x00000400u;
+}
+inline bool FileOptions::_internal_java_multiple_files() const {
+ return java_multiple_files_;
+}
+inline bool FileOptions::java_multiple_files() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.java_multiple_files)
+ return _internal_java_multiple_files();
+}
+inline void FileOptions::_internal_set_java_multiple_files(bool value) {
+ _has_bits_[0] |= 0x00000400u;
+ java_multiple_files_ = value;
+}
+inline void FileOptions::set_java_multiple_files(bool value) {
+ _internal_set_java_multiple_files(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.java_multiple_files)
+}
+
+// optional bool java_generate_equals_and_hash = 20 [deprecated = true];
+inline bool FileOptions::_internal_has_java_generate_equals_and_hash() const {
+ bool value = (_has_bits_[0] & 0x00000800u) != 0;
+ return value;
+}
+inline bool FileOptions::has_java_generate_equals_and_hash() const {
+ return _internal_has_java_generate_equals_and_hash();
+}
+inline void FileOptions::clear_java_generate_equals_and_hash() {
+ java_generate_equals_and_hash_ = false;
+ _has_bits_[0] &= ~0x00000800u;
+}
+inline bool FileOptions::_internal_java_generate_equals_and_hash() const {
+ return java_generate_equals_and_hash_;
+}
+inline bool FileOptions::java_generate_equals_and_hash() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.java_generate_equals_and_hash)
+ return _internal_java_generate_equals_and_hash();
+}
+inline void FileOptions::_internal_set_java_generate_equals_and_hash(bool value) {
+ _has_bits_[0] |= 0x00000800u;
+ java_generate_equals_and_hash_ = value;
+}
+inline void FileOptions::set_java_generate_equals_and_hash(bool value) {
+ _internal_set_java_generate_equals_and_hash(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.java_generate_equals_and_hash)
+}
+
+// optional bool java_string_check_utf8 = 27 [default = false];
+inline bool FileOptions::_internal_has_java_string_check_utf8() const {
+ bool value = (_has_bits_[0] & 0x00001000u) != 0;
+ return value;
+}
+inline bool FileOptions::has_java_string_check_utf8() const {
+ return _internal_has_java_string_check_utf8();
+}
+inline void FileOptions::clear_java_string_check_utf8() {
+ java_string_check_utf8_ = false;
+ _has_bits_[0] &= ~0x00001000u;
+}
+inline bool FileOptions::_internal_java_string_check_utf8() const {
+ return java_string_check_utf8_;
+}
+inline bool FileOptions::java_string_check_utf8() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.java_string_check_utf8)
+ return _internal_java_string_check_utf8();
+}
+inline void FileOptions::_internal_set_java_string_check_utf8(bool value) {
+ _has_bits_[0] |= 0x00001000u;
+ java_string_check_utf8_ = value;
+}
+inline void FileOptions::set_java_string_check_utf8(bool value) {
+ _internal_set_java_string_check_utf8(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.java_string_check_utf8)
+}
+
+// optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED];
+inline bool FileOptions::_internal_has_optimize_for() const {
+ bool value = (_has_bits_[0] & 0x00040000u) != 0;
+ return value;
+}
+inline bool FileOptions::has_optimize_for() const {
+ return _internal_has_optimize_for();
+}
+inline void FileOptions::clear_optimize_for() {
+ optimize_for_ = 1;
+ _has_bits_[0] &= ~0x00040000u;
+}
+inline ::PROTOBUF_NAMESPACE_ID::FileOptions_OptimizeMode FileOptions::_internal_optimize_for() const {
+ return static_cast< ::PROTOBUF_NAMESPACE_ID::FileOptions_OptimizeMode >(optimize_for_);
+}
+inline ::PROTOBUF_NAMESPACE_ID::FileOptions_OptimizeMode FileOptions::optimize_for() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.optimize_for)
+ return _internal_optimize_for();
+}
+inline void FileOptions::_internal_set_optimize_for(::PROTOBUF_NAMESPACE_ID::FileOptions_OptimizeMode value) {
+ assert(::PROTOBUF_NAMESPACE_ID::FileOptions_OptimizeMode_IsValid(value));
+ _has_bits_[0] |= 0x00040000u;
+ optimize_for_ = value;
+}
+inline void FileOptions::set_optimize_for(::PROTOBUF_NAMESPACE_ID::FileOptions_OptimizeMode value) {
+ _internal_set_optimize_for(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.optimize_for)
+}
+
+// optional string go_package = 11;
+inline bool FileOptions::_internal_has_go_package() const {
+ bool value = (_has_bits_[0] & 0x00000004u) != 0;
+ return value;
+}
+inline bool FileOptions::has_go_package() const {
+ return _internal_has_go_package();
+}
+inline void FileOptions::clear_go_package() {
+ go_package_.ClearToEmpty();
+ _has_bits_[0] &= ~0x00000004u;
+}
+inline const 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) {
+ _has_bits_[0] |= 0x00000004u;
+ go_package_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
+ // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.go_package)
+}
+inline 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 go_package_.Get();
+}
+inline void FileOptions::_internal_set_go_package(const std::string& value) {
+ _has_bits_[0] |= 0x00000004u;
+ go_package_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation());
+}
+inline std::string* FileOptions::_internal_mutable_go_package() {
+ _has_bits_[0] |= 0x00000004u;
+ return go_package_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, 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;
+ }
+ _has_bits_[0] &= ~0x00000004u;
+ auto* p = go_package_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (go_package_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
+ go_package_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ return p;
+}
+inline void FileOptions::set_allocated_go_package(std::string* go_package) {
+ if (go_package != nullptr) {
+ _has_bits_[0] |= 0x00000004u;
+ } else {
+ _has_bits_[0] &= ~0x00000004u;
+ }
+ go_package_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), go_package,
+ GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (go_package_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
+ go_package_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileOptions.go_package)
+}
+
+// optional bool cc_generic_services = 16 [default = false];
+inline bool FileOptions::_internal_has_cc_generic_services() const {
+ bool value = (_has_bits_[0] & 0x00002000u) != 0;
+ return value;
+}
+inline bool FileOptions::has_cc_generic_services() const {
+ return _internal_has_cc_generic_services();
+}
+inline void FileOptions::clear_cc_generic_services() {
+ cc_generic_services_ = false;
+ _has_bits_[0] &= ~0x00002000u;
+}
+inline bool FileOptions::_internal_cc_generic_services() const {
+ return cc_generic_services_;
+}
+inline bool FileOptions::cc_generic_services() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.cc_generic_services)
+ return _internal_cc_generic_services();
+}
+inline void FileOptions::_internal_set_cc_generic_services(bool value) {
+ _has_bits_[0] |= 0x00002000u;
+ cc_generic_services_ = value;
+}
+inline void FileOptions::set_cc_generic_services(bool value) {
+ _internal_set_cc_generic_services(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.cc_generic_services)
+}
+
+// optional bool java_generic_services = 17 [default = false];
+inline bool FileOptions::_internal_has_java_generic_services() const {
+ bool value = (_has_bits_[0] & 0x00004000u) != 0;
+ return value;
+}
+inline bool FileOptions::has_java_generic_services() const {
+ return _internal_has_java_generic_services();
+}
+inline void FileOptions::clear_java_generic_services() {
+ java_generic_services_ = false;
+ _has_bits_[0] &= ~0x00004000u;
+}
+inline bool FileOptions::_internal_java_generic_services() const {
+ return java_generic_services_;
+}
+inline bool FileOptions::java_generic_services() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.java_generic_services)
+ return _internal_java_generic_services();
+}
+inline void FileOptions::_internal_set_java_generic_services(bool value) {
+ _has_bits_[0] |= 0x00004000u;
+ java_generic_services_ = value;
+}
+inline void FileOptions::set_java_generic_services(bool value) {
+ _internal_set_java_generic_services(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.java_generic_services)
+}
+
+// optional bool py_generic_services = 18 [default = false];
+inline bool FileOptions::_internal_has_py_generic_services() const {
+ bool value = (_has_bits_[0] & 0x00008000u) != 0;
+ return value;
+}
+inline bool FileOptions::has_py_generic_services() const {
+ return _internal_has_py_generic_services();
+}
+inline void FileOptions::clear_py_generic_services() {
+ py_generic_services_ = false;
+ _has_bits_[0] &= ~0x00008000u;
+}
+inline bool FileOptions::_internal_py_generic_services() const {
+ return py_generic_services_;
+}
+inline bool FileOptions::py_generic_services() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.py_generic_services)
+ return _internal_py_generic_services();
+}
+inline void FileOptions::_internal_set_py_generic_services(bool value) {
+ _has_bits_[0] |= 0x00008000u;
+ py_generic_services_ = value;
+}
+inline void FileOptions::set_py_generic_services(bool value) {
+ _internal_set_py_generic_services(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.py_generic_services)
+}
+
+// optional bool php_generic_services = 42 [default = false];
+inline bool FileOptions::_internal_has_php_generic_services() const {
+ bool value = (_has_bits_[0] & 0x00010000u) != 0;
+ return value;
+}
+inline bool FileOptions::has_php_generic_services() const {
+ return _internal_has_php_generic_services();
+}
+inline void FileOptions::clear_php_generic_services() {
+ php_generic_services_ = false;
+ _has_bits_[0] &= ~0x00010000u;
+}
+inline bool FileOptions::_internal_php_generic_services() const {
+ return php_generic_services_;
+}
+inline bool FileOptions::php_generic_services() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.php_generic_services)
+ return _internal_php_generic_services();
+}
+inline void FileOptions::_internal_set_php_generic_services(bool value) {
+ _has_bits_[0] |= 0x00010000u;
+ php_generic_services_ = value;
+}
+inline void FileOptions::set_php_generic_services(bool value) {
+ _internal_set_php_generic_services(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.php_generic_services)
+}
+
+// optional bool deprecated = 23 [default = false];
+inline bool FileOptions::_internal_has_deprecated() const {
+ bool value = (_has_bits_[0] & 0x00020000u) != 0;
+ return value;
+}
+inline bool FileOptions::has_deprecated() const {
+ return _internal_has_deprecated();
+}
+inline void FileOptions::clear_deprecated() {
+ deprecated_ = false;
+ _has_bits_[0] &= ~0x00020000u;
+}
+inline bool FileOptions::_internal_deprecated() const {
+ return deprecated_;
+}
+inline bool FileOptions::deprecated() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.deprecated)
+ return _internal_deprecated();
+}
+inline void FileOptions::_internal_set_deprecated(bool value) {
+ _has_bits_[0] |= 0x00020000u;
+ deprecated_ = value;
+}
+inline void FileOptions::set_deprecated(bool value) {
+ _internal_set_deprecated(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.deprecated)
+}
+
+// optional bool cc_enable_arenas = 31 [default = true];
+inline bool FileOptions::_internal_has_cc_enable_arenas() const {
+ bool value = (_has_bits_[0] & 0x00080000u) != 0;
+ return value;
+}
+inline bool FileOptions::has_cc_enable_arenas() const {
+ return _internal_has_cc_enable_arenas();
+}
+inline void FileOptions::clear_cc_enable_arenas() {
+ cc_enable_arenas_ = true;
+ _has_bits_[0] &= ~0x00080000u;
+}
+inline bool FileOptions::_internal_cc_enable_arenas() const {
+ return cc_enable_arenas_;
+}
+inline bool FileOptions::cc_enable_arenas() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.cc_enable_arenas)
+ return _internal_cc_enable_arenas();
+}
+inline void FileOptions::_internal_set_cc_enable_arenas(bool value) {
+ _has_bits_[0] |= 0x00080000u;
+ cc_enable_arenas_ = value;
+}
+inline void FileOptions::set_cc_enable_arenas(bool value) {
+ _internal_set_cc_enable_arenas(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.cc_enable_arenas)
+}
+
+// optional string objc_class_prefix = 36;
+inline bool FileOptions::_internal_has_objc_class_prefix() const {
+ bool value = (_has_bits_[0] & 0x00000008u) != 0;
+ return value;
+}
+inline bool FileOptions::has_objc_class_prefix() const {
+ return _internal_has_objc_class_prefix();
+}
+inline void FileOptions::clear_objc_class_prefix() {
+ objc_class_prefix_.ClearToEmpty();
+ _has_bits_[0] &= ~0x00000008u;
+}
+inline const 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) {
+ _has_bits_[0] |= 0x00000008u;
+ objc_class_prefix_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
+ // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.objc_class_prefix)
+}
+inline 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 objc_class_prefix_.Get();
+}
+inline void FileOptions::_internal_set_objc_class_prefix(const std::string& value) {
+ _has_bits_[0] |= 0x00000008u;
+ objc_class_prefix_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation());
+}
+inline std::string* FileOptions::_internal_mutable_objc_class_prefix() {
+ _has_bits_[0] |= 0x00000008u;
+ return objc_class_prefix_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, 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;
+ }
+ _has_bits_[0] &= ~0x00000008u;
+ auto* p = objc_class_prefix_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (objc_class_prefix_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
+ objc_class_prefix_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ return p;
+}
+inline void FileOptions::set_allocated_objc_class_prefix(std::string* objc_class_prefix) {
+ if (objc_class_prefix != nullptr) {
+ _has_bits_[0] |= 0x00000008u;
+ } else {
+ _has_bits_[0] &= ~0x00000008u;
+ }
+ objc_class_prefix_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), objc_class_prefix,
+ GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (objc_class_prefix_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
+ objc_class_prefix_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileOptions.objc_class_prefix)
+}
+
+// optional string csharp_namespace = 37;
+inline bool FileOptions::_internal_has_csharp_namespace() const {
+ bool value = (_has_bits_[0] & 0x00000010u) != 0;
+ return value;
+}
+inline bool FileOptions::has_csharp_namespace() const {
+ return _internal_has_csharp_namespace();
+}
+inline void FileOptions::clear_csharp_namespace() {
+ csharp_namespace_.ClearToEmpty();
+ _has_bits_[0] &= ~0x00000010u;
+}
+inline const 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) {
+ _has_bits_[0] |= 0x00000010u;
+ csharp_namespace_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
+ // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.csharp_namespace)
+}
+inline 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 csharp_namespace_.Get();
+}
+inline void FileOptions::_internal_set_csharp_namespace(const std::string& value) {
+ _has_bits_[0] |= 0x00000010u;
+ csharp_namespace_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation());
+}
+inline std::string* FileOptions::_internal_mutable_csharp_namespace() {
+ _has_bits_[0] |= 0x00000010u;
+ return csharp_namespace_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, 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;
+ }
+ _has_bits_[0] &= ~0x00000010u;
+ auto* p = csharp_namespace_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (csharp_namespace_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
+ csharp_namespace_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ return p;
+}
+inline void FileOptions::set_allocated_csharp_namespace(std::string* csharp_namespace) {
+ if (csharp_namespace != nullptr) {
+ _has_bits_[0] |= 0x00000010u;
+ } else {
+ _has_bits_[0] &= ~0x00000010u;
+ }
+ csharp_namespace_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), csharp_namespace,
+ GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (csharp_namespace_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
+ csharp_namespace_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileOptions.csharp_namespace)
+}
+
+// optional string swift_prefix = 39;
+inline bool FileOptions::_internal_has_swift_prefix() const {
+ bool value = (_has_bits_[0] & 0x00000020u) != 0;
+ return value;
+}
+inline bool FileOptions::has_swift_prefix() const {
+ return _internal_has_swift_prefix();
+}
+inline void FileOptions::clear_swift_prefix() {
+ swift_prefix_.ClearToEmpty();
+ _has_bits_[0] &= ~0x00000020u;
+}
+inline const 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) {
+ _has_bits_[0] |= 0x00000020u;
+ swift_prefix_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
+ // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.swift_prefix)
+}
+inline 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 swift_prefix_.Get();
+}
+inline void FileOptions::_internal_set_swift_prefix(const std::string& value) {
+ _has_bits_[0] |= 0x00000020u;
+ swift_prefix_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation());
+}
+inline std::string* FileOptions::_internal_mutable_swift_prefix() {
+ _has_bits_[0] |= 0x00000020u;
+ return swift_prefix_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, 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;
+ }
+ _has_bits_[0] &= ~0x00000020u;
+ auto* p = swift_prefix_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (swift_prefix_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
+ swift_prefix_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ return p;
+}
+inline void FileOptions::set_allocated_swift_prefix(std::string* swift_prefix) {
+ if (swift_prefix != nullptr) {
+ _has_bits_[0] |= 0x00000020u;
+ } else {
+ _has_bits_[0] &= ~0x00000020u;
+ }
+ swift_prefix_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), swift_prefix,
+ GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (swift_prefix_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
+ swift_prefix_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileOptions.swift_prefix)
+}
+
+// optional string php_class_prefix = 40;
+inline bool FileOptions::_internal_has_php_class_prefix() const {
+ bool value = (_has_bits_[0] & 0x00000040u) != 0;
+ return value;
+}
+inline bool FileOptions::has_php_class_prefix() const {
+ return _internal_has_php_class_prefix();
+}
+inline void FileOptions::clear_php_class_prefix() {
+ php_class_prefix_.ClearToEmpty();
+ _has_bits_[0] &= ~0x00000040u;
+}
+inline const 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) {
+ _has_bits_[0] |= 0x00000040u;
+ php_class_prefix_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
+ // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.php_class_prefix)
+}
+inline 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 php_class_prefix_.Get();
+}
+inline void FileOptions::_internal_set_php_class_prefix(const std::string& value) {
+ _has_bits_[0] |= 0x00000040u;
+ php_class_prefix_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation());
+}
+inline std::string* FileOptions::_internal_mutable_php_class_prefix() {
+ _has_bits_[0] |= 0x00000040u;
+ return php_class_prefix_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, 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;
+ }
+ _has_bits_[0] &= ~0x00000040u;
+ auto* p = php_class_prefix_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (php_class_prefix_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
+ php_class_prefix_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ return p;
+}
+inline void FileOptions::set_allocated_php_class_prefix(std::string* php_class_prefix) {
+ if (php_class_prefix != nullptr) {
+ _has_bits_[0] |= 0x00000040u;
+ } else {
+ _has_bits_[0] &= ~0x00000040u;
+ }
+ php_class_prefix_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), php_class_prefix,
+ GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (php_class_prefix_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
+ php_class_prefix_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileOptions.php_class_prefix)
+}
+
+// optional string php_namespace = 41;
+inline bool FileOptions::_internal_has_php_namespace() const {
+ bool value = (_has_bits_[0] & 0x00000080u) != 0;
+ return value;
+}
+inline bool FileOptions::has_php_namespace() const {
+ return _internal_has_php_namespace();
+}
+inline void FileOptions::clear_php_namespace() {
+ php_namespace_.ClearToEmpty();
+ _has_bits_[0] &= ~0x00000080u;
+}
+inline const 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) {
+ _has_bits_[0] |= 0x00000080u;
+ php_namespace_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
+ // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.php_namespace)
+}
+inline 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 php_namespace_.Get();
+}
+inline void FileOptions::_internal_set_php_namespace(const std::string& value) {
+ _has_bits_[0] |= 0x00000080u;
+ php_namespace_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation());
+}
+inline std::string* FileOptions::_internal_mutable_php_namespace() {
+ _has_bits_[0] |= 0x00000080u;
+ return php_namespace_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, 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;
+ }
+ _has_bits_[0] &= ~0x00000080u;
+ auto* p = php_namespace_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (php_namespace_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
+ php_namespace_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ return p;
+}
+inline void FileOptions::set_allocated_php_namespace(std::string* php_namespace) {
+ if (php_namespace != nullptr) {
+ _has_bits_[0] |= 0x00000080u;
+ } else {
+ _has_bits_[0] &= ~0x00000080u;
+ }
+ php_namespace_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), php_namespace,
+ GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (php_namespace_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
+ php_namespace_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileOptions.php_namespace)
+}
+
+// optional string php_metadata_namespace = 44;
+inline bool FileOptions::_internal_has_php_metadata_namespace() const {
+ bool value = (_has_bits_[0] & 0x00000100u) != 0;
+ return value;
+}
+inline bool FileOptions::has_php_metadata_namespace() const {
+ return _internal_has_php_metadata_namespace();
+}
+inline void FileOptions::clear_php_metadata_namespace() {
+ php_metadata_namespace_.ClearToEmpty();
+ _has_bits_[0] &= ~0x00000100u;
+}
+inline const 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) {
+ _has_bits_[0] |= 0x00000100u;
+ php_metadata_namespace_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
+ // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.php_metadata_namespace)
+}
+inline 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 php_metadata_namespace_.Get();
+}
+inline void FileOptions::_internal_set_php_metadata_namespace(const std::string& value) {
+ _has_bits_[0] |= 0x00000100u;
+ php_metadata_namespace_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation());
+}
+inline std::string* FileOptions::_internal_mutable_php_metadata_namespace() {
+ _has_bits_[0] |= 0x00000100u;
+ return php_metadata_namespace_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, 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;
+ }
+ _has_bits_[0] &= ~0x00000100u;
+ auto* p = php_metadata_namespace_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (php_metadata_namespace_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
+ php_metadata_namespace_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ return p;
+}
+inline void FileOptions::set_allocated_php_metadata_namespace(std::string* php_metadata_namespace) {
+ if (php_metadata_namespace != nullptr) {
+ _has_bits_[0] |= 0x00000100u;
+ } else {
+ _has_bits_[0] &= ~0x00000100u;
+ }
+ php_metadata_namespace_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), php_metadata_namespace,
+ GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (php_metadata_namespace_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
+ php_metadata_namespace_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileOptions.php_metadata_namespace)
+}
+
+// optional string ruby_package = 45;
+inline bool FileOptions::_internal_has_ruby_package() const {
+ bool value = (_has_bits_[0] & 0x00000200u) != 0;
+ return value;
+}
+inline bool FileOptions::has_ruby_package() const {
+ return _internal_has_ruby_package();
+}
+inline void FileOptions::clear_ruby_package() {
+ ruby_package_.ClearToEmpty();
+ _has_bits_[0] &= ~0x00000200u;
+}
+inline const 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) {
+ _has_bits_[0] |= 0x00000200u;
+ ruby_package_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
+ // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.ruby_package)
+}
+inline 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 ruby_package_.Get();
+}
+inline void FileOptions::_internal_set_ruby_package(const std::string& value) {
+ _has_bits_[0] |= 0x00000200u;
+ ruby_package_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation());
+}
+inline std::string* FileOptions::_internal_mutable_ruby_package() {
+ _has_bits_[0] |= 0x00000200u;
+ return ruby_package_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, 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;
+ }
+ _has_bits_[0] &= ~0x00000200u;
+ auto* p = ruby_package_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (ruby_package_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
+ ruby_package_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ return p;
+}
+inline void FileOptions::set_allocated_ruby_package(std::string* ruby_package) {
+ if (ruby_package != nullptr) {
+ _has_bits_[0] |= 0x00000200u;
+ } else {
+ _has_bits_[0] &= ~0x00000200u;
+ }
+ ruby_package_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ruby_package,
+ GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (ruby_package_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
+ ruby_package_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileOptions.ruby_package)
+}
+
+// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+inline int FileOptions::_internal_uninterpreted_option_size() const {
+ return uninterpreted_option_.size();
+}
+inline int FileOptions::uninterpreted_option_size() const {
+ return _internal_uninterpreted_option_size();
+}
+inline void FileOptions::clear_uninterpreted_option() {
+ uninterpreted_option_.Clear();
+}
+inline ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* FileOptions::mutable_uninterpreted_option(int index) {
+ // @@protoc_insertion_point(field_mutable:google.protobuf.FileOptions.uninterpreted_option)
+ return uninterpreted_option_.Mutable(index);
+}
+inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption >*
+FileOptions::mutable_uninterpreted_option() {
+ // @@protoc_insertion_point(field_mutable_list:google.protobuf.FileOptions.uninterpreted_option)
+ return &uninterpreted_option_;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption& FileOptions::_internal_uninterpreted_option(int index) const {
+ return uninterpreted_option_.Get(index);
+}
+inline const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption& FileOptions::uninterpreted_option(int index) const {
+ // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.uninterpreted_option)
+ return _internal_uninterpreted_option(index);
+}
+inline ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* FileOptions::_internal_add_uninterpreted_option() {
+ return uninterpreted_option_.Add();
+}
+inline ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* FileOptions::add_uninterpreted_option() {
+ ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* _add = _internal_add_uninterpreted_option();
+ // @@protoc_insertion_point(field_add:google.protobuf.FileOptions.uninterpreted_option)
+ return _add;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption >&
+FileOptions::uninterpreted_option() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.FileOptions.uninterpreted_option)
+ return uninterpreted_option_;
+}
+
+// -------------------------------------------------------------------
+
+// MessageOptions
+
+// optional bool message_set_wire_format = 1 [default = false];
+inline bool MessageOptions::_internal_has_message_set_wire_format() const {
+ bool value = (_has_bits_[0] & 0x00000001u) != 0;
+ return value;
+}
+inline bool MessageOptions::has_message_set_wire_format() const {
+ return _internal_has_message_set_wire_format();
+}
+inline void MessageOptions::clear_message_set_wire_format() {
+ message_set_wire_format_ = false;
+ _has_bits_[0] &= ~0x00000001u;
+}
+inline bool MessageOptions::_internal_message_set_wire_format() const {
+ return message_set_wire_format_;
+}
+inline bool MessageOptions::message_set_wire_format() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.MessageOptions.message_set_wire_format)
+ return _internal_message_set_wire_format();
+}
+inline void MessageOptions::_internal_set_message_set_wire_format(bool value) {
+ _has_bits_[0] |= 0x00000001u;
+ message_set_wire_format_ = value;
+}
+inline void MessageOptions::set_message_set_wire_format(bool value) {
+ _internal_set_message_set_wire_format(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.MessageOptions.message_set_wire_format)
+}
+
+// optional bool no_standard_descriptor_accessor = 2 [default = false];
+inline bool MessageOptions::_internal_has_no_standard_descriptor_accessor() const {
+ bool value = (_has_bits_[0] & 0x00000002u) != 0;
+ return value;
+}
+inline bool MessageOptions::has_no_standard_descriptor_accessor() const {
+ return _internal_has_no_standard_descriptor_accessor();
+}
+inline void MessageOptions::clear_no_standard_descriptor_accessor() {
+ no_standard_descriptor_accessor_ = false;
+ _has_bits_[0] &= ~0x00000002u;
+}
+inline bool MessageOptions::_internal_no_standard_descriptor_accessor() const {
+ return no_standard_descriptor_accessor_;
+}
+inline bool MessageOptions::no_standard_descriptor_accessor() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.MessageOptions.no_standard_descriptor_accessor)
+ return _internal_no_standard_descriptor_accessor();
+}
+inline void MessageOptions::_internal_set_no_standard_descriptor_accessor(bool value) {
+ _has_bits_[0] |= 0x00000002u;
+ no_standard_descriptor_accessor_ = value;
+}
+inline void MessageOptions::set_no_standard_descriptor_accessor(bool value) {
+ _internal_set_no_standard_descriptor_accessor(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.MessageOptions.no_standard_descriptor_accessor)
+}
+
+// optional bool deprecated = 3 [default = false];
+inline bool MessageOptions::_internal_has_deprecated() const {
+ bool value = (_has_bits_[0] & 0x00000004u) != 0;
+ return value;
+}
+inline bool MessageOptions::has_deprecated() const {
+ return _internal_has_deprecated();
+}
+inline void MessageOptions::clear_deprecated() {
+ deprecated_ = false;
+ _has_bits_[0] &= ~0x00000004u;
+}
+inline bool MessageOptions::_internal_deprecated() const {
+ return deprecated_;
+}
+inline bool MessageOptions::deprecated() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.MessageOptions.deprecated)
+ return _internal_deprecated();
+}
+inline void MessageOptions::_internal_set_deprecated(bool value) {
+ _has_bits_[0] |= 0x00000004u;
+ deprecated_ = value;
+}
+inline void MessageOptions::set_deprecated(bool value) {
+ _internal_set_deprecated(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.MessageOptions.deprecated)
+}
+
+// optional bool map_entry = 7;
+inline bool MessageOptions::_internal_has_map_entry() const {
+ bool value = (_has_bits_[0] & 0x00000008u) != 0;
+ return value;
+}
+inline bool MessageOptions::has_map_entry() const {
+ return _internal_has_map_entry();
+}
+inline void MessageOptions::clear_map_entry() {
+ map_entry_ = false;
+ _has_bits_[0] &= ~0x00000008u;
+}
+inline bool MessageOptions::_internal_map_entry() const {
+ return map_entry_;
+}
+inline bool MessageOptions::map_entry() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.MessageOptions.map_entry)
+ return _internal_map_entry();
+}
+inline void MessageOptions::_internal_set_map_entry(bool value) {
+ _has_bits_[0] |= 0x00000008u;
+ map_entry_ = value;
+}
+inline void MessageOptions::set_map_entry(bool value) {
+ _internal_set_map_entry(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.MessageOptions.map_entry)
+}
+
+// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+inline int MessageOptions::_internal_uninterpreted_option_size() const {
+ return uninterpreted_option_.size();
+}
+inline int MessageOptions::uninterpreted_option_size() const {
+ return _internal_uninterpreted_option_size();
+}
+inline void MessageOptions::clear_uninterpreted_option() {
+ uninterpreted_option_.Clear();
+}
+inline ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* MessageOptions::mutable_uninterpreted_option(int index) {
+ // @@protoc_insertion_point(field_mutable:google.protobuf.MessageOptions.uninterpreted_option)
+ return uninterpreted_option_.Mutable(index);
+}
+inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption >*
+MessageOptions::mutable_uninterpreted_option() {
+ // @@protoc_insertion_point(field_mutable_list:google.protobuf.MessageOptions.uninterpreted_option)
+ return &uninterpreted_option_;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption& MessageOptions::_internal_uninterpreted_option(int index) const {
+ return uninterpreted_option_.Get(index);
+}
+inline const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption& MessageOptions::uninterpreted_option(int index) const {
+ // @@protoc_insertion_point(field_get:google.protobuf.MessageOptions.uninterpreted_option)
+ return _internal_uninterpreted_option(index);
+}
+inline ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* MessageOptions::_internal_add_uninterpreted_option() {
+ return uninterpreted_option_.Add();
+}
+inline ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* MessageOptions::add_uninterpreted_option() {
+ ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* _add = _internal_add_uninterpreted_option();
+ // @@protoc_insertion_point(field_add:google.protobuf.MessageOptions.uninterpreted_option)
+ return _add;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption >&
+MessageOptions::uninterpreted_option() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.MessageOptions.uninterpreted_option)
+ return uninterpreted_option_;
+}
+
+// -------------------------------------------------------------------
+
+// FieldOptions
+
+// optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING];
+inline bool FieldOptions::_internal_has_ctype() const {
+ bool value = (_has_bits_[0] & 0x00000001u) != 0;
+ return value;
+}
+inline bool FieldOptions::has_ctype() const {
+ return _internal_has_ctype();
+}
+inline void FieldOptions::clear_ctype() {
+ ctype_ = 0;
+ _has_bits_[0] &= ~0x00000001u;
+}
+inline ::PROTOBUF_NAMESPACE_ID::FieldOptions_CType FieldOptions::_internal_ctype() const {
+ return static_cast< ::PROTOBUF_NAMESPACE_ID::FieldOptions_CType >(ctype_);
+}
+inline ::PROTOBUF_NAMESPACE_ID::FieldOptions_CType FieldOptions::ctype() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.FieldOptions.ctype)
+ return _internal_ctype();
+}
+inline void FieldOptions::_internal_set_ctype(::PROTOBUF_NAMESPACE_ID::FieldOptions_CType value) {
+ assert(::PROTOBUF_NAMESPACE_ID::FieldOptions_CType_IsValid(value));
+ _has_bits_[0] |= 0x00000001u;
+ ctype_ = value;
+}
+inline void FieldOptions::set_ctype(::PROTOBUF_NAMESPACE_ID::FieldOptions_CType value) {
+ _internal_set_ctype(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.FieldOptions.ctype)
+}
+
+// optional bool packed = 2;
+inline bool FieldOptions::_internal_has_packed() const {
+ bool value = (_has_bits_[0] & 0x00000002u) != 0;
+ return value;
+}
+inline bool FieldOptions::has_packed() const {
+ return _internal_has_packed();
+}
+inline void FieldOptions::clear_packed() {
+ packed_ = false;
+ _has_bits_[0] &= ~0x00000002u;
+}
+inline bool FieldOptions::_internal_packed() const {
+ return packed_;
+}
+inline bool FieldOptions::packed() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.FieldOptions.packed)
+ return _internal_packed();
+}
+inline void FieldOptions::_internal_set_packed(bool value) {
+ _has_bits_[0] |= 0x00000002u;
+ packed_ = value;
+}
+inline void FieldOptions::set_packed(bool value) {
+ _internal_set_packed(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.FieldOptions.packed)
+}
+
+// optional .google.protobuf.FieldOptions.JSType jstype = 6 [default = JS_NORMAL];
+inline bool FieldOptions::_internal_has_jstype() const {
+ bool value = (_has_bits_[0] & 0x00000020u) != 0;
+ return value;
+}
+inline bool FieldOptions::has_jstype() const {
+ return _internal_has_jstype();
+}
+inline void FieldOptions::clear_jstype() {
+ jstype_ = 0;
+ _has_bits_[0] &= ~0x00000020u;
+}
+inline ::PROTOBUF_NAMESPACE_ID::FieldOptions_JSType FieldOptions::_internal_jstype() const {
+ return static_cast< ::PROTOBUF_NAMESPACE_ID::FieldOptions_JSType >(jstype_);
+}
+inline ::PROTOBUF_NAMESPACE_ID::FieldOptions_JSType FieldOptions::jstype() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.FieldOptions.jstype)
+ return _internal_jstype();
+}
+inline void FieldOptions::_internal_set_jstype(::PROTOBUF_NAMESPACE_ID::FieldOptions_JSType value) {
+ assert(::PROTOBUF_NAMESPACE_ID::FieldOptions_JSType_IsValid(value));
+ _has_bits_[0] |= 0x00000020u;
+ jstype_ = value;
+}
+inline void FieldOptions::set_jstype(::PROTOBUF_NAMESPACE_ID::FieldOptions_JSType value) {
+ _internal_set_jstype(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.FieldOptions.jstype)
+}
+
+// optional bool lazy = 5 [default = false];
+inline bool FieldOptions::_internal_has_lazy() const {
+ bool value = (_has_bits_[0] & 0x00000004u) != 0;
+ return value;
+}
+inline bool FieldOptions::has_lazy() const {
+ return _internal_has_lazy();
+}
+inline void FieldOptions::clear_lazy() {
+ lazy_ = false;
+ _has_bits_[0] &= ~0x00000004u;
+}
+inline bool FieldOptions::_internal_lazy() const {
+ return lazy_;
+}
+inline bool FieldOptions::lazy() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.FieldOptions.lazy)
+ return _internal_lazy();
+}
+inline void FieldOptions::_internal_set_lazy(bool value) {
+ _has_bits_[0] |= 0x00000004u;
+ lazy_ = value;
+}
+inline void FieldOptions::set_lazy(bool value) {
+ _internal_set_lazy(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.FieldOptions.lazy)
+}
+
+// optional bool deprecated = 3 [default = false];
+inline bool FieldOptions::_internal_has_deprecated() const {
+ bool value = (_has_bits_[0] & 0x00000008u) != 0;
+ return value;
+}
+inline bool FieldOptions::has_deprecated() const {
+ return _internal_has_deprecated();
+}
+inline void FieldOptions::clear_deprecated() {
+ deprecated_ = false;
+ _has_bits_[0] &= ~0x00000008u;
+}
+inline bool FieldOptions::_internal_deprecated() const {
+ return deprecated_;
+}
+inline bool FieldOptions::deprecated() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.FieldOptions.deprecated)
+ return _internal_deprecated();
+}
+inline void FieldOptions::_internal_set_deprecated(bool value) {
+ _has_bits_[0] |= 0x00000008u;
+ deprecated_ = value;
+}
+inline void FieldOptions::set_deprecated(bool value) {
+ _internal_set_deprecated(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.FieldOptions.deprecated)
+}
+
+// optional bool weak = 10 [default = false];
+inline bool FieldOptions::_internal_has_weak() const {
+ bool value = (_has_bits_[0] & 0x00000010u) != 0;
+ return value;
+}
+inline bool FieldOptions::has_weak() const {
+ return _internal_has_weak();
+}
+inline void FieldOptions::clear_weak() {
+ weak_ = false;
+ _has_bits_[0] &= ~0x00000010u;
+}
+inline bool FieldOptions::_internal_weak() const {
+ return weak_;
+}
+inline bool FieldOptions::weak() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.FieldOptions.weak)
+ return _internal_weak();
+}
+inline void FieldOptions::_internal_set_weak(bool value) {
+ _has_bits_[0] |= 0x00000010u;
+ weak_ = value;
+}
+inline void FieldOptions::set_weak(bool value) {
+ _internal_set_weak(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.FieldOptions.weak)
+}
+
+// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+inline int FieldOptions::_internal_uninterpreted_option_size() const {
+ return uninterpreted_option_.size();
+}
+inline int FieldOptions::uninterpreted_option_size() const {
+ return _internal_uninterpreted_option_size();
+}
+inline void FieldOptions::clear_uninterpreted_option() {
+ uninterpreted_option_.Clear();
+}
+inline ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* FieldOptions::mutable_uninterpreted_option(int index) {
+ // @@protoc_insertion_point(field_mutable:google.protobuf.FieldOptions.uninterpreted_option)
+ return uninterpreted_option_.Mutable(index);
+}
+inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption >*
+FieldOptions::mutable_uninterpreted_option() {
+ // @@protoc_insertion_point(field_mutable_list:google.protobuf.FieldOptions.uninterpreted_option)
+ return &uninterpreted_option_;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption& FieldOptions::_internal_uninterpreted_option(int index) const {
+ return uninterpreted_option_.Get(index);
+}
+inline const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption& FieldOptions::uninterpreted_option(int index) const {
+ // @@protoc_insertion_point(field_get:google.protobuf.FieldOptions.uninterpreted_option)
+ return _internal_uninterpreted_option(index);
+}
+inline ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* FieldOptions::_internal_add_uninterpreted_option() {
+ return uninterpreted_option_.Add();
+}
+inline ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* FieldOptions::add_uninterpreted_option() {
+ ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* _add = _internal_add_uninterpreted_option();
+ // @@protoc_insertion_point(field_add:google.protobuf.FieldOptions.uninterpreted_option)
+ return _add;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption >&
+FieldOptions::uninterpreted_option() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.FieldOptions.uninterpreted_option)
+ return uninterpreted_option_;
+}
+
+// -------------------------------------------------------------------
+
+// OneofOptions
+
+// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+inline int OneofOptions::_internal_uninterpreted_option_size() const {
+ return uninterpreted_option_.size();
+}
+inline int OneofOptions::uninterpreted_option_size() const {
+ return _internal_uninterpreted_option_size();
+}
+inline void OneofOptions::clear_uninterpreted_option() {
+ uninterpreted_option_.Clear();
+}
+inline ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* OneofOptions::mutable_uninterpreted_option(int index) {
+ // @@protoc_insertion_point(field_mutable:google.protobuf.OneofOptions.uninterpreted_option)
+ return uninterpreted_option_.Mutable(index);
+}
+inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption >*
+OneofOptions::mutable_uninterpreted_option() {
+ // @@protoc_insertion_point(field_mutable_list:google.protobuf.OneofOptions.uninterpreted_option)
+ return &uninterpreted_option_;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption& OneofOptions::_internal_uninterpreted_option(int index) const {
+ return uninterpreted_option_.Get(index);
+}
+inline const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption& OneofOptions::uninterpreted_option(int index) const {
+ // @@protoc_insertion_point(field_get:google.protobuf.OneofOptions.uninterpreted_option)
+ return _internal_uninterpreted_option(index);
+}
+inline ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* OneofOptions::_internal_add_uninterpreted_option() {
+ return uninterpreted_option_.Add();
+}
+inline ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* OneofOptions::add_uninterpreted_option() {
+ ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* _add = _internal_add_uninterpreted_option();
+ // @@protoc_insertion_point(field_add:google.protobuf.OneofOptions.uninterpreted_option)
+ return _add;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption >&
+OneofOptions::uninterpreted_option() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.OneofOptions.uninterpreted_option)
+ return uninterpreted_option_;
+}
+
+// -------------------------------------------------------------------
+
+// EnumOptions
+
+// optional bool allow_alias = 2;
+inline bool EnumOptions::_internal_has_allow_alias() const {
+ bool value = (_has_bits_[0] & 0x00000001u) != 0;
+ return value;
+}
+inline bool EnumOptions::has_allow_alias() const {
+ return _internal_has_allow_alias();
+}
+inline void EnumOptions::clear_allow_alias() {
+ allow_alias_ = false;
+ _has_bits_[0] &= ~0x00000001u;
+}
+inline bool EnumOptions::_internal_allow_alias() const {
+ return allow_alias_;
+}
+inline bool EnumOptions::allow_alias() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.EnumOptions.allow_alias)
+ return _internal_allow_alias();
+}
+inline void EnumOptions::_internal_set_allow_alias(bool value) {
+ _has_bits_[0] |= 0x00000001u;
+ allow_alias_ = value;
+}
+inline void EnumOptions::set_allow_alias(bool value) {
+ _internal_set_allow_alias(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.EnumOptions.allow_alias)
+}
+
+// optional bool deprecated = 3 [default = false];
+inline bool EnumOptions::_internal_has_deprecated() const {
+ bool value = (_has_bits_[0] & 0x00000002u) != 0;
+ return value;
+}
+inline bool EnumOptions::has_deprecated() const {
+ return _internal_has_deprecated();
+}
+inline void EnumOptions::clear_deprecated() {
+ deprecated_ = false;
+ _has_bits_[0] &= ~0x00000002u;
+}
+inline bool EnumOptions::_internal_deprecated() const {
+ return deprecated_;
+}
+inline bool EnumOptions::deprecated() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.EnumOptions.deprecated)
+ return _internal_deprecated();
+}
+inline void EnumOptions::_internal_set_deprecated(bool value) {
+ _has_bits_[0] |= 0x00000002u;
+ deprecated_ = value;
+}
+inline void EnumOptions::set_deprecated(bool value) {
+ _internal_set_deprecated(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.EnumOptions.deprecated)
+}
+
+// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+inline int EnumOptions::_internal_uninterpreted_option_size() const {
+ return uninterpreted_option_.size();
+}
+inline int EnumOptions::uninterpreted_option_size() const {
+ return _internal_uninterpreted_option_size();
+}
+inline void EnumOptions::clear_uninterpreted_option() {
+ uninterpreted_option_.Clear();
+}
+inline ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* EnumOptions::mutable_uninterpreted_option(int index) {
+ // @@protoc_insertion_point(field_mutable:google.protobuf.EnumOptions.uninterpreted_option)
+ return uninterpreted_option_.Mutable(index);
+}
+inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption >*
+EnumOptions::mutable_uninterpreted_option() {
+ // @@protoc_insertion_point(field_mutable_list:google.protobuf.EnumOptions.uninterpreted_option)
+ return &uninterpreted_option_;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption& EnumOptions::_internal_uninterpreted_option(int index) const {
+ return uninterpreted_option_.Get(index);
+}
+inline const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption& EnumOptions::uninterpreted_option(int index) const {
+ // @@protoc_insertion_point(field_get:google.protobuf.EnumOptions.uninterpreted_option)
+ return _internal_uninterpreted_option(index);
+}
+inline ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* EnumOptions::_internal_add_uninterpreted_option() {
+ return uninterpreted_option_.Add();
+}
+inline ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* EnumOptions::add_uninterpreted_option() {
+ ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* _add = _internal_add_uninterpreted_option();
+ // @@protoc_insertion_point(field_add:google.protobuf.EnumOptions.uninterpreted_option)
+ return _add;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption >&
+EnumOptions::uninterpreted_option() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.EnumOptions.uninterpreted_option)
+ return uninterpreted_option_;
+}
+
+// -------------------------------------------------------------------
+
+// EnumValueOptions
+
+// optional bool deprecated = 1 [default = false];
+inline bool EnumValueOptions::_internal_has_deprecated() const {
+ bool value = (_has_bits_[0] & 0x00000001u) != 0;
+ return value;
+}
+inline bool EnumValueOptions::has_deprecated() const {
+ return _internal_has_deprecated();
+}
+inline void EnumValueOptions::clear_deprecated() {
+ deprecated_ = false;
+ _has_bits_[0] &= ~0x00000001u;
+}
+inline bool EnumValueOptions::_internal_deprecated() const {
+ return deprecated_;
+}
+inline bool EnumValueOptions::deprecated() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.EnumValueOptions.deprecated)
+ return _internal_deprecated();
+}
+inline void EnumValueOptions::_internal_set_deprecated(bool value) {
+ _has_bits_[0] |= 0x00000001u;
+ deprecated_ = value;
+}
+inline void EnumValueOptions::set_deprecated(bool value) {
+ _internal_set_deprecated(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.EnumValueOptions.deprecated)
+}
+
+// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+inline int EnumValueOptions::_internal_uninterpreted_option_size() const {
+ return uninterpreted_option_.size();
+}
+inline int EnumValueOptions::uninterpreted_option_size() const {
+ return _internal_uninterpreted_option_size();
+}
+inline void EnumValueOptions::clear_uninterpreted_option() {
+ uninterpreted_option_.Clear();
+}
+inline ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* EnumValueOptions::mutable_uninterpreted_option(int index) {
+ // @@protoc_insertion_point(field_mutable:google.protobuf.EnumValueOptions.uninterpreted_option)
+ return uninterpreted_option_.Mutable(index);
+}
+inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption >*
+EnumValueOptions::mutable_uninterpreted_option() {
+ // @@protoc_insertion_point(field_mutable_list:google.protobuf.EnumValueOptions.uninterpreted_option)
+ return &uninterpreted_option_;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption& EnumValueOptions::_internal_uninterpreted_option(int index) const {
+ return uninterpreted_option_.Get(index);
+}
+inline const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption& EnumValueOptions::uninterpreted_option(int index) const {
+ // @@protoc_insertion_point(field_get:google.protobuf.EnumValueOptions.uninterpreted_option)
+ return _internal_uninterpreted_option(index);
+}
+inline ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* EnumValueOptions::_internal_add_uninterpreted_option() {
+ return uninterpreted_option_.Add();
+}
+inline ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* EnumValueOptions::add_uninterpreted_option() {
+ ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* _add = _internal_add_uninterpreted_option();
+ // @@protoc_insertion_point(field_add:google.protobuf.EnumValueOptions.uninterpreted_option)
+ return _add;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption >&
+EnumValueOptions::uninterpreted_option() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.EnumValueOptions.uninterpreted_option)
+ return uninterpreted_option_;
+}
+
+// -------------------------------------------------------------------
+
+// ServiceOptions
+
+// optional bool deprecated = 33 [default = false];
+inline bool ServiceOptions::_internal_has_deprecated() const {
+ bool value = (_has_bits_[0] & 0x00000001u) != 0;
+ return value;
+}
+inline bool ServiceOptions::has_deprecated() const {
+ return _internal_has_deprecated();
+}
+inline void ServiceOptions::clear_deprecated() {
+ deprecated_ = false;
+ _has_bits_[0] &= ~0x00000001u;
+}
+inline bool ServiceOptions::_internal_deprecated() const {
+ return deprecated_;
+}
+inline bool ServiceOptions::deprecated() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.ServiceOptions.deprecated)
+ return _internal_deprecated();
+}
+inline void ServiceOptions::_internal_set_deprecated(bool value) {
+ _has_bits_[0] |= 0x00000001u;
+ deprecated_ = value;
+}
+inline void ServiceOptions::set_deprecated(bool value) {
+ _internal_set_deprecated(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.ServiceOptions.deprecated)
+}
+
+// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+inline int ServiceOptions::_internal_uninterpreted_option_size() const {
+ return uninterpreted_option_.size();
+}
+inline int ServiceOptions::uninterpreted_option_size() const {
+ return _internal_uninterpreted_option_size();
+}
+inline void ServiceOptions::clear_uninterpreted_option() {
+ uninterpreted_option_.Clear();
+}
+inline ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* ServiceOptions::mutable_uninterpreted_option(int index) {
+ // @@protoc_insertion_point(field_mutable:google.protobuf.ServiceOptions.uninterpreted_option)
+ return uninterpreted_option_.Mutable(index);
+}
+inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption >*
+ServiceOptions::mutable_uninterpreted_option() {
+ // @@protoc_insertion_point(field_mutable_list:google.protobuf.ServiceOptions.uninterpreted_option)
+ return &uninterpreted_option_;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption& ServiceOptions::_internal_uninterpreted_option(int index) const {
+ return uninterpreted_option_.Get(index);
+}
+inline const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption& ServiceOptions::uninterpreted_option(int index) const {
+ // @@protoc_insertion_point(field_get:google.protobuf.ServiceOptions.uninterpreted_option)
+ return _internal_uninterpreted_option(index);
+}
+inline ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* ServiceOptions::_internal_add_uninterpreted_option() {
+ return uninterpreted_option_.Add();
+}
+inline ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* ServiceOptions::add_uninterpreted_option() {
+ ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* _add = _internal_add_uninterpreted_option();
+ // @@protoc_insertion_point(field_add:google.protobuf.ServiceOptions.uninterpreted_option)
+ return _add;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption >&
+ServiceOptions::uninterpreted_option() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.ServiceOptions.uninterpreted_option)
+ return uninterpreted_option_;
+}
+
+// -------------------------------------------------------------------
+
+// MethodOptions
+
+// optional bool deprecated = 33 [default = false];
+inline bool MethodOptions::_internal_has_deprecated() const {
+ bool value = (_has_bits_[0] & 0x00000001u) != 0;
+ return value;
+}
+inline bool MethodOptions::has_deprecated() const {
+ return _internal_has_deprecated();
+}
+inline void MethodOptions::clear_deprecated() {
+ deprecated_ = false;
+ _has_bits_[0] &= ~0x00000001u;
+}
+inline bool MethodOptions::_internal_deprecated() const {
+ return deprecated_;
+}
+inline bool MethodOptions::deprecated() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.MethodOptions.deprecated)
+ return _internal_deprecated();
+}
+inline void MethodOptions::_internal_set_deprecated(bool value) {
+ _has_bits_[0] |= 0x00000001u;
+ deprecated_ = value;
+}
+inline void MethodOptions::set_deprecated(bool value) {
+ _internal_set_deprecated(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.MethodOptions.deprecated)
+}
+
+// optional .google.protobuf.MethodOptions.IdempotencyLevel idempotency_level = 34 [default = IDEMPOTENCY_UNKNOWN];
+inline bool MethodOptions::_internal_has_idempotency_level() const {
+ bool value = (_has_bits_[0] & 0x00000002u) != 0;
+ return value;
+}
+inline bool MethodOptions::has_idempotency_level() const {
+ return _internal_has_idempotency_level();
+}
+inline void MethodOptions::clear_idempotency_level() {
+ idempotency_level_ = 0;
+ _has_bits_[0] &= ~0x00000002u;
+}
+inline ::PROTOBUF_NAMESPACE_ID::MethodOptions_IdempotencyLevel MethodOptions::_internal_idempotency_level() const {
+ return static_cast< ::PROTOBUF_NAMESPACE_ID::MethodOptions_IdempotencyLevel >(idempotency_level_);
+}
+inline ::PROTOBUF_NAMESPACE_ID::MethodOptions_IdempotencyLevel MethodOptions::idempotency_level() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.MethodOptions.idempotency_level)
+ return _internal_idempotency_level();
+}
+inline void MethodOptions::_internal_set_idempotency_level(::PROTOBUF_NAMESPACE_ID::MethodOptions_IdempotencyLevel value) {
+ assert(::PROTOBUF_NAMESPACE_ID::MethodOptions_IdempotencyLevel_IsValid(value));
+ _has_bits_[0] |= 0x00000002u;
+ idempotency_level_ = value;
+}
+inline void MethodOptions::set_idempotency_level(::PROTOBUF_NAMESPACE_ID::MethodOptions_IdempotencyLevel value) {
+ _internal_set_idempotency_level(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.MethodOptions.idempotency_level)
+}
+
+// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+inline int MethodOptions::_internal_uninterpreted_option_size() const {
+ return uninterpreted_option_.size();
+}
+inline int MethodOptions::uninterpreted_option_size() const {
+ return _internal_uninterpreted_option_size();
+}
+inline void MethodOptions::clear_uninterpreted_option() {
+ uninterpreted_option_.Clear();
+}
+inline ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* MethodOptions::mutable_uninterpreted_option(int index) {
+ // @@protoc_insertion_point(field_mutable:google.protobuf.MethodOptions.uninterpreted_option)
+ return uninterpreted_option_.Mutable(index);
+}
+inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption >*
+MethodOptions::mutable_uninterpreted_option() {
+ // @@protoc_insertion_point(field_mutable_list:google.protobuf.MethodOptions.uninterpreted_option)
+ return &uninterpreted_option_;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption& MethodOptions::_internal_uninterpreted_option(int index) const {
+ return uninterpreted_option_.Get(index);
+}
+inline const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption& MethodOptions::uninterpreted_option(int index) const {
+ // @@protoc_insertion_point(field_get:google.protobuf.MethodOptions.uninterpreted_option)
+ return _internal_uninterpreted_option(index);
+}
+inline ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* MethodOptions::_internal_add_uninterpreted_option() {
+ return uninterpreted_option_.Add();
+}
+inline ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* MethodOptions::add_uninterpreted_option() {
+ ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* _add = _internal_add_uninterpreted_option();
+ // @@protoc_insertion_point(field_add:google.protobuf.MethodOptions.uninterpreted_option)
+ return _add;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption >&
+MethodOptions::uninterpreted_option() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.MethodOptions.uninterpreted_option)
+ return uninterpreted_option_;
+}
+
+// -------------------------------------------------------------------
+
+// UninterpretedOption_NamePart
+
+// required string name_part = 1;
+inline bool UninterpretedOption_NamePart::_internal_has_name_part() const {
+ bool value = (_has_bits_[0] & 0x00000001u) != 0;
+ return value;
+}
+inline bool UninterpretedOption_NamePart::has_name_part() const {
+ return _internal_has_name_part();
+}
+inline void UninterpretedOption_NamePart::clear_name_part() {
+ name_part_.ClearToEmpty();
+ _has_bits_[0] &= ~0x00000001u;
+}
+inline const 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) {
+ _has_bits_[0] |= 0x00000001u;
+ name_part_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
+ // @@protoc_insertion_point(field_set:google.protobuf.UninterpretedOption.NamePart.name_part)
+}
+inline 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 name_part_.Get();
+}
+inline void UninterpretedOption_NamePart::_internal_set_name_part(const std::string& value) {
+ _has_bits_[0] |= 0x00000001u;
+ name_part_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation());
+}
+inline std::string* UninterpretedOption_NamePart::_internal_mutable_name_part() {
+ _has_bits_[0] |= 0x00000001u;
+ return name_part_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, 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;
+ }
+ _has_bits_[0] &= ~0x00000001u;
+ auto* p = name_part_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (name_part_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
+ name_part_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ return p;
+}
+inline void UninterpretedOption_NamePart::set_allocated_name_part(std::string* name_part) {
+ if (name_part != nullptr) {
+ _has_bits_[0] |= 0x00000001u;
+ } else {
+ _has_bits_[0] &= ~0x00000001u;
+ }
+ name_part_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), name_part,
+ GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (name_part_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
+ name_part_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.UninterpretedOption.NamePart.name_part)
+}
+
+// required bool is_extension = 2;
+inline bool UninterpretedOption_NamePart::_internal_has_is_extension() const {
+ bool value = (_has_bits_[0] & 0x00000002u) != 0;
+ return value;
+}
+inline bool UninterpretedOption_NamePart::has_is_extension() const {
+ return _internal_has_is_extension();
+}
+inline void UninterpretedOption_NamePart::clear_is_extension() {
+ is_extension_ = false;
+ _has_bits_[0] &= ~0x00000002u;
+}
+inline bool UninterpretedOption_NamePart::_internal_is_extension() const {
+ return is_extension_;
+}
+inline bool UninterpretedOption_NamePart::is_extension() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.UninterpretedOption.NamePart.is_extension)
+ return _internal_is_extension();
+}
+inline void UninterpretedOption_NamePart::_internal_set_is_extension(bool value) {
+ _has_bits_[0] |= 0x00000002u;
+ is_extension_ = value;
+}
+inline void UninterpretedOption_NamePart::set_is_extension(bool value) {
+ _internal_set_is_extension(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.UninterpretedOption.NamePart.is_extension)
+}
+
+// -------------------------------------------------------------------
+
+// UninterpretedOption
+
+// repeated .google.protobuf.UninterpretedOption.NamePart name = 2;
+inline int UninterpretedOption::_internal_name_size() const {
+ return name_.size();
+}
+inline int UninterpretedOption::name_size() const {
+ return _internal_name_size();
+}
+inline void UninterpretedOption::clear_name() {
+ name_.Clear();
+}
+inline ::PROTOBUF_NAMESPACE_ID::UninterpretedOption_NamePart* UninterpretedOption::mutable_name(int index) {
+ // @@protoc_insertion_point(field_mutable:google.protobuf.UninterpretedOption.name)
+ return name_.Mutable(index);
+}
+inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption_NamePart >*
+UninterpretedOption::mutable_name() {
+ // @@protoc_insertion_point(field_mutable_list:google.protobuf.UninterpretedOption.name)
+ return &name_;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption_NamePart& UninterpretedOption::_internal_name(int index) const {
+ return name_.Get(index);
+}
+inline const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption_NamePart& UninterpretedOption::name(int index) const {
+ // @@protoc_insertion_point(field_get:google.protobuf.UninterpretedOption.name)
+ return _internal_name(index);
+}
+inline ::PROTOBUF_NAMESPACE_ID::UninterpretedOption_NamePart* UninterpretedOption::_internal_add_name() {
+ return name_.Add();
+}
+inline ::PROTOBUF_NAMESPACE_ID::UninterpretedOption_NamePart* UninterpretedOption::add_name() {
+ ::PROTOBUF_NAMESPACE_ID::UninterpretedOption_NamePart* _add = _internal_add_name();
+ // @@protoc_insertion_point(field_add:google.protobuf.UninterpretedOption.name)
+ return _add;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption_NamePart >&
+UninterpretedOption::name() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.UninterpretedOption.name)
+ return name_;
+}
+
+// optional string identifier_value = 3;
+inline bool UninterpretedOption::_internal_has_identifier_value() const {
+ bool value = (_has_bits_[0] & 0x00000001u) != 0;
+ return value;
+}
+inline bool UninterpretedOption::has_identifier_value() const {
+ return _internal_has_identifier_value();
+}
+inline void UninterpretedOption::clear_identifier_value() {
+ identifier_value_.ClearToEmpty();
+ _has_bits_[0] &= ~0x00000001u;
+}
+inline const 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) {
+ _has_bits_[0] |= 0x00000001u;
+ identifier_value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
+ // @@protoc_insertion_point(field_set:google.protobuf.UninterpretedOption.identifier_value)
+}
+inline 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 identifier_value_.Get();
+}
+inline void UninterpretedOption::_internal_set_identifier_value(const std::string& value) {
+ _has_bits_[0] |= 0x00000001u;
+ identifier_value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation());
+}
+inline std::string* UninterpretedOption::_internal_mutable_identifier_value() {
+ _has_bits_[0] |= 0x00000001u;
+ return identifier_value_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, 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;
+ }
+ _has_bits_[0] &= ~0x00000001u;
+ auto* p = identifier_value_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (identifier_value_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
+ identifier_value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ return p;
+}
+inline void UninterpretedOption::set_allocated_identifier_value(std::string* identifier_value) {
+ if (identifier_value != nullptr) {
+ _has_bits_[0] |= 0x00000001u;
+ } else {
+ _has_bits_[0] &= ~0x00000001u;
+ }
+ identifier_value_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), identifier_value,
+ GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (identifier_value_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
+ identifier_value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.UninterpretedOption.identifier_value)
+}
+
+// optional uint64 positive_int_value = 4;
+inline bool UninterpretedOption::_internal_has_positive_int_value() const {
+ bool value = (_has_bits_[0] & 0x00000008u) != 0;
+ return value;
+}
+inline bool UninterpretedOption::has_positive_int_value() const {
+ return _internal_has_positive_int_value();
+}
+inline void UninterpretedOption::clear_positive_int_value() {
+ positive_int_value_ = uint64_t{0u};
+ _has_bits_[0] &= ~0x00000008u;
+}
+inline uint64_t UninterpretedOption::_internal_positive_int_value() const {
+ return 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) {
+ _has_bits_[0] |= 0x00000008u;
+ 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 = (_has_bits_[0] & 0x00000010u) != 0;
+ return value;
+}
+inline bool UninterpretedOption::has_negative_int_value() const {
+ return _internal_has_negative_int_value();
+}
+inline void UninterpretedOption::clear_negative_int_value() {
+ negative_int_value_ = int64_t{0};
+ _has_bits_[0] &= ~0x00000010u;
+}
+inline int64_t UninterpretedOption::_internal_negative_int_value() const {
+ return 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) {
+ _has_bits_[0] |= 0x00000010u;
+ 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 = (_has_bits_[0] & 0x00000020u) != 0;
+ return value;
+}
+inline bool UninterpretedOption::has_double_value() const {
+ return _internal_has_double_value();
+}
+inline void UninterpretedOption::clear_double_value() {
+ double_value_ = 0;
+ _has_bits_[0] &= ~0x00000020u;
+}
+inline double UninterpretedOption::_internal_double_value() const {
+ return double_value_;
+}
+inline double UninterpretedOption::double_value() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.UninterpretedOption.double_value)
+ return _internal_double_value();
+}
+inline void UninterpretedOption::_internal_set_double_value(double value) {
+ _has_bits_[0] |= 0x00000020u;
+ double_value_ = value;
+}
+inline void UninterpretedOption::set_double_value(double value) {
+ _internal_set_double_value(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.UninterpretedOption.double_value)
+}
+
+// optional bytes string_value = 7;
+inline bool UninterpretedOption::_internal_has_string_value() const {
+ bool value = (_has_bits_[0] & 0x00000002u) != 0;
+ return value;
+}
+inline bool UninterpretedOption::has_string_value() const {
+ return _internal_has_string_value();
+}
+inline void UninterpretedOption::clear_string_value() {
+ string_value_.ClearToEmpty();
+ _has_bits_[0] &= ~0x00000002u;
+}
+inline const 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) {
+ _has_bits_[0] |= 0x00000002u;
+ string_value_.SetBytes(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
+ // @@protoc_insertion_point(field_set:google.protobuf.UninterpretedOption.string_value)
+}
+inline 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 string_value_.Get();
+}
+inline void UninterpretedOption::_internal_set_string_value(const std::string& value) {
+ _has_bits_[0] |= 0x00000002u;
+ string_value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation());
+}
+inline std::string* UninterpretedOption::_internal_mutable_string_value() {
+ _has_bits_[0] |= 0x00000002u;
+ return string_value_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, 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;
+ }
+ _has_bits_[0] &= ~0x00000002u;
+ auto* p = string_value_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (string_value_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
+ string_value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ return p;
+}
+inline void UninterpretedOption::set_allocated_string_value(std::string* string_value) {
+ if (string_value != nullptr) {
+ _has_bits_[0] |= 0x00000002u;
+ } else {
+ _has_bits_[0] &= ~0x00000002u;
+ }
+ string_value_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), string_value,
+ GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (string_value_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
+ string_value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.UninterpretedOption.string_value)
+}
+
+// optional string aggregate_value = 8;
+inline bool UninterpretedOption::_internal_has_aggregate_value() const {
+ bool value = (_has_bits_[0] & 0x00000004u) != 0;
+ return value;
+}
+inline bool UninterpretedOption::has_aggregate_value() const {
+ return _internal_has_aggregate_value();
+}
+inline void UninterpretedOption::clear_aggregate_value() {
+ aggregate_value_.ClearToEmpty();
+ _has_bits_[0] &= ~0x00000004u;
+}
+inline const 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) {
+ _has_bits_[0] |= 0x00000004u;
+ aggregate_value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
+ // @@protoc_insertion_point(field_set:google.protobuf.UninterpretedOption.aggregate_value)
+}
+inline 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 aggregate_value_.Get();
+}
+inline void UninterpretedOption::_internal_set_aggregate_value(const std::string& value) {
+ _has_bits_[0] |= 0x00000004u;
+ aggregate_value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation());
+}
+inline std::string* UninterpretedOption::_internal_mutable_aggregate_value() {
+ _has_bits_[0] |= 0x00000004u;
+ return aggregate_value_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, 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;
+ }
+ _has_bits_[0] &= ~0x00000004u;
+ auto* p = aggregate_value_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (aggregate_value_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
+ aggregate_value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ return p;
+}
+inline void UninterpretedOption::set_allocated_aggregate_value(std::string* aggregate_value) {
+ if (aggregate_value != nullptr) {
+ _has_bits_[0] |= 0x00000004u;
+ } else {
+ _has_bits_[0] &= ~0x00000004u;
+ }
+ aggregate_value_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), aggregate_value,
+ GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (aggregate_value_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
+ aggregate_value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.UninterpretedOption.aggregate_value)
+}
+
+// -------------------------------------------------------------------
+
+// SourceCodeInfo_Location
+
+// repeated int32 path = 1 [packed = true];
+inline int SourceCodeInfo_Location::_internal_path_size() const {
+ return path_.size();
+}
+inline int SourceCodeInfo_Location::path_size() const {
+ return _internal_path_size();
+}
+inline void SourceCodeInfo_Location::clear_path() {
+ path_.Clear();
+}
+inline int32_t SourceCodeInfo_Location::_internal_path(int index) const {
+ return 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) {
+ path_.Set(index, value);
+ // @@protoc_insertion_point(field_set:google.protobuf.SourceCodeInfo.Location.path)
+}
+inline void SourceCodeInfo_Location::_internal_add_path(int32_t value) {
+ 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 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 &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 span_.size();
+}
+inline int SourceCodeInfo_Location::span_size() const {
+ return _internal_span_size();
+}
+inline void SourceCodeInfo_Location::clear_span() {
+ span_.Clear();
+}
+inline int32_t SourceCodeInfo_Location::_internal_span(int index) const {
+ return 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) {
+ span_.Set(index, value);
+ // @@protoc_insertion_point(field_set:google.protobuf.SourceCodeInfo.Location.span)
+}
+inline void SourceCodeInfo_Location::_internal_add_span(int32_t value) {
+ 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 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 &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 = (_has_bits_[0] & 0x00000001u) != 0;
+ return value;
+}
+inline bool SourceCodeInfo_Location::has_leading_comments() const {
+ return _internal_has_leading_comments();
+}
+inline void SourceCodeInfo_Location::clear_leading_comments() {
+ leading_comments_.ClearToEmpty();
+ _has_bits_[0] &= ~0x00000001u;
+}
+inline const 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) {
+ _has_bits_[0] |= 0x00000001u;
+ leading_comments_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
+ // @@protoc_insertion_point(field_set:google.protobuf.SourceCodeInfo.Location.leading_comments)
+}
+inline 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 leading_comments_.Get();
+}
+inline void SourceCodeInfo_Location::_internal_set_leading_comments(const std::string& value) {
+ _has_bits_[0] |= 0x00000001u;
+ leading_comments_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation());
+}
+inline std::string* SourceCodeInfo_Location::_internal_mutable_leading_comments() {
+ _has_bits_[0] |= 0x00000001u;
+ return leading_comments_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, 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;
+ }
+ _has_bits_[0] &= ~0x00000001u;
+ auto* p = leading_comments_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (leading_comments_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
+ leading_comments_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ return p;
+}
+inline void SourceCodeInfo_Location::set_allocated_leading_comments(std::string* leading_comments) {
+ if (leading_comments != nullptr) {
+ _has_bits_[0] |= 0x00000001u;
+ } else {
+ _has_bits_[0] &= ~0x00000001u;
+ }
+ leading_comments_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), leading_comments,
+ GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (leading_comments_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
+ leading_comments_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.SourceCodeInfo.Location.leading_comments)
+}
+
+// optional string trailing_comments = 4;
+inline bool SourceCodeInfo_Location::_internal_has_trailing_comments() const {
+ bool value = (_has_bits_[0] & 0x00000002u) != 0;
+ return value;
+}
+inline bool SourceCodeInfo_Location::has_trailing_comments() const {
+ return _internal_has_trailing_comments();
+}
+inline void SourceCodeInfo_Location::clear_trailing_comments() {
+ trailing_comments_.ClearToEmpty();
+ _has_bits_[0] &= ~0x00000002u;
+}
+inline const 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) {
+ _has_bits_[0] |= 0x00000002u;
+ trailing_comments_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
+ // @@protoc_insertion_point(field_set:google.protobuf.SourceCodeInfo.Location.trailing_comments)
+}
+inline 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 trailing_comments_.Get();
+}
+inline void SourceCodeInfo_Location::_internal_set_trailing_comments(const std::string& value) {
+ _has_bits_[0] |= 0x00000002u;
+ trailing_comments_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation());
+}
+inline std::string* SourceCodeInfo_Location::_internal_mutable_trailing_comments() {
+ _has_bits_[0] |= 0x00000002u;
+ return trailing_comments_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, 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;
+ }
+ _has_bits_[0] &= ~0x00000002u;
+ auto* p = trailing_comments_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (trailing_comments_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
+ trailing_comments_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ return p;
+}
+inline void SourceCodeInfo_Location::set_allocated_trailing_comments(std::string* trailing_comments) {
+ if (trailing_comments != nullptr) {
+ _has_bits_[0] |= 0x00000002u;
+ } else {
+ _has_bits_[0] &= ~0x00000002u;
+ }
+ trailing_comments_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), trailing_comments,
+ GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (trailing_comments_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
+ trailing_comments_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.SourceCodeInfo.Location.trailing_comments)
+}
+
+// repeated string leading_detached_comments = 6;
+inline int SourceCodeInfo_Location::_internal_leading_detached_comments_size() const {
+ return leading_detached_comments_.size();
+}
+inline int SourceCodeInfo_Location::leading_detached_comments_size() const {
+ return _internal_leading_detached_comments_size();
+}
+inline void SourceCodeInfo_Location::clear_leading_detached_comments() {
+ leading_detached_comments_.Clear();
+}
+inline 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 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 leading_detached_comments_.Mutable(index);
+}
+inline void SourceCodeInfo_Location::set_leading_detached_comments(int index, const std::string& value) {
+ leading_detached_comments_.Mutable(index)->assign(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.SourceCodeInfo.Location.leading_detached_comments)
+}
+inline void SourceCodeInfo_Location::set_leading_detached_comments(int index, std::string&& value) {
+ leading_detached_comments_.Mutable(index)->assign(std::move(value));
+ // @@protoc_insertion_point(field_set:google.protobuf.SourceCodeInfo.Location.leading_detached_comments)
+}
+inline void SourceCodeInfo_Location::set_leading_detached_comments(int index, const char* value) {
+ GOOGLE_DCHECK(value != nullptr);
+ leading_detached_comments_.Mutable(index)->assign(value);
+ // @@protoc_insertion_point(field_set_char:google.protobuf.SourceCodeInfo.Location.leading_detached_comments)
+}
+inline void SourceCodeInfo_Location::set_leading_detached_comments(int index, const char* value, size_t size) {
+ leading_detached_comments_.Mutable(index)->assign(
+ reinterpret_cast<const char*>(value), size);
+ // @@protoc_insertion_point(field_set_pointer:google.protobuf.SourceCodeInfo.Location.leading_detached_comments)
+}
+inline std::string* SourceCodeInfo_Location::_internal_add_leading_detached_comments() {
+ return leading_detached_comments_.Add();
+}
+inline void SourceCodeInfo_Location::add_leading_detached_comments(const std::string& value) {
+ leading_detached_comments_.Add()->assign(value);
+ // @@protoc_insertion_point(field_add:google.protobuf.SourceCodeInfo.Location.leading_detached_comments)
+}
+inline void SourceCodeInfo_Location::add_leading_detached_comments(std::string&& value) {
+ leading_detached_comments_.Add(std::move(value));
+ // @@protoc_insertion_point(field_add:google.protobuf.SourceCodeInfo.Location.leading_detached_comments)
+}
+inline void SourceCodeInfo_Location::add_leading_detached_comments(const char* value) {
+ GOOGLE_DCHECK(value != nullptr);
+ leading_detached_comments_.Add()->assign(value);
+ // @@protoc_insertion_point(field_add_char:google.protobuf.SourceCodeInfo.Location.leading_detached_comments)
+}
+inline void SourceCodeInfo_Location::add_leading_detached_comments(const char* value, size_t size) {
+ leading_detached_comments_.Add()->assign(reinterpret_cast<const char*>(value), size);
+ // @@protoc_insertion_point(field_add_pointer:google.protobuf.SourceCodeInfo.Location.leading_detached_comments)
+}
+inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string>&
+SourceCodeInfo_Location::leading_detached_comments() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.SourceCodeInfo.Location.leading_detached_comments)
+ return leading_detached_comments_;
+}
+inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string>*
+SourceCodeInfo_Location::mutable_leading_detached_comments() {
+ // @@protoc_insertion_point(field_mutable_list:google.protobuf.SourceCodeInfo.Location.leading_detached_comments)
+ return &leading_detached_comments_;
+}
+
+// -------------------------------------------------------------------
+
+// SourceCodeInfo
+
+// repeated .google.protobuf.SourceCodeInfo.Location location = 1;
+inline int SourceCodeInfo::_internal_location_size() const {
+ return location_.size();
+}
+inline int SourceCodeInfo::location_size() const {
+ return _internal_location_size();
+}
+inline void SourceCodeInfo::clear_location() {
+ location_.Clear();
+}
+inline ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location* SourceCodeInfo::mutable_location(int index) {
+ // @@protoc_insertion_point(field_mutable:google.protobuf.SourceCodeInfo.location)
+ return location_.Mutable(index);
+}
+inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location >*
+SourceCodeInfo::mutable_location() {
+ // @@protoc_insertion_point(field_mutable_list:google.protobuf.SourceCodeInfo.location)
+ return &location_;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location& SourceCodeInfo::_internal_location(int index) const {
+ return location_.Get(index);
+}
+inline const ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location& SourceCodeInfo::location(int index) const {
+ // @@protoc_insertion_point(field_get:google.protobuf.SourceCodeInfo.location)
+ return _internal_location(index);
+}
+inline ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location* SourceCodeInfo::_internal_add_location() {
+ return location_.Add();
+}
+inline ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location* SourceCodeInfo::add_location() {
+ ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location* _add = _internal_add_location();
+ // @@protoc_insertion_point(field_add:google.protobuf.SourceCodeInfo.location)
+ return _add;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location >&
+SourceCodeInfo::location() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.SourceCodeInfo.location)
+ return location_;
+}
+
+// -------------------------------------------------------------------
+
+// GeneratedCodeInfo_Annotation
+
+// repeated int32 path = 1 [packed = true];
+inline int GeneratedCodeInfo_Annotation::_internal_path_size() const {
+ return path_.size();
+}
+inline int GeneratedCodeInfo_Annotation::path_size() const {
+ return _internal_path_size();
+}
+inline void GeneratedCodeInfo_Annotation::clear_path() {
+ path_.Clear();
+}
+inline int32_t GeneratedCodeInfo_Annotation::_internal_path(int index) const {
+ return 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) {
+ path_.Set(index, value);
+ // @@protoc_insertion_point(field_set:google.protobuf.GeneratedCodeInfo.Annotation.path)
+}
+inline void GeneratedCodeInfo_Annotation::_internal_add_path(int32_t value) {
+ 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 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 &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 = (_has_bits_[0] & 0x00000001u) != 0;
+ return value;
+}
+inline bool GeneratedCodeInfo_Annotation::has_source_file() const {
+ return _internal_has_source_file();
+}
+inline void GeneratedCodeInfo_Annotation::clear_source_file() {
+ source_file_.ClearToEmpty();
+ _has_bits_[0] &= ~0x00000001u;
+}
+inline const 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) {
+ _has_bits_[0] |= 0x00000001u;
+ source_file_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
+ // @@protoc_insertion_point(field_set:google.protobuf.GeneratedCodeInfo.Annotation.source_file)
+}
+inline 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 source_file_.Get();
+}
+inline void GeneratedCodeInfo_Annotation::_internal_set_source_file(const std::string& value) {
+ _has_bits_[0] |= 0x00000001u;
+ source_file_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation());
+}
+inline std::string* GeneratedCodeInfo_Annotation::_internal_mutable_source_file() {
+ _has_bits_[0] |= 0x00000001u;
+ return source_file_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, 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;
+ }
+ _has_bits_[0] &= ~0x00000001u;
+ auto* p = source_file_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (source_file_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
+ source_file_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ return p;
+}
+inline void GeneratedCodeInfo_Annotation::set_allocated_source_file(std::string* source_file) {
+ if (source_file != nullptr) {
+ _has_bits_[0] |= 0x00000001u;
+ } else {
+ _has_bits_[0] &= ~0x00000001u;
+ }
+ source_file_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), source_file,
+ GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (source_file_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
+ source_file_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.GeneratedCodeInfo.Annotation.source_file)
+}
+
+// optional int32 begin = 3;
+inline bool GeneratedCodeInfo_Annotation::_internal_has_begin() const {
+ bool value = (_has_bits_[0] & 0x00000002u) != 0;
+ return value;
+}
+inline bool GeneratedCodeInfo_Annotation::has_begin() const {
+ return _internal_has_begin();
+}
+inline void GeneratedCodeInfo_Annotation::clear_begin() {
+ begin_ = 0;
+ _has_bits_[0] &= ~0x00000002u;
+}
+inline int32_t GeneratedCodeInfo_Annotation::_internal_begin() const {
+ return 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) {
+ _has_bits_[0] |= 0x00000002u;
+ 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 = (_has_bits_[0] & 0x00000004u) != 0;
+ return value;
+}
+inline bool GeneratedCodeInfo_Annotation::has_end() const {
+ return _internal_has_end();
+}
+inline void GeneratedCodeInfo_Annotation::clear_end() {
+ end_ = 0;
+ _has_bits_[0] &= ~0x00000004u;
+}
+inline int32_t GeneratedCodeInfo_Annotation::_internal_end() const {
+ return 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) {
+ _has_bits_[0] |= 0x00000004u;
+ 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 annotation_.size();
+}
+inline int GeneratedCodeInfo::annotation_size() const {
+ return _internal_annotation_size();
+}
+inline void GeneratedCodeInfo::clear_annotation() {
+ annotation_.Clear();
+}
+inline ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation* GeneratedCodeInfo::mutable_annotation(int index) {
+ // @@protoc_insertion_point(field_mutable:google.protobuf.GeneratedCodeInfo.annotation)
+ return annotation_.Mutable(index);
+}
+inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation >*
+GeneratedCodeInfo::mutable_annotation() {
+ // @@protoc_insertion_point(field_mutable_list:google.protobuf.GeneratedCodeInfo.annotation)
+ return &annotation_;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation& GeneratedCodeInfo::_internal_annotation(int index) const {
+ return annotation_.Get(index);
+}
+inline const ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation& GeneratedCodeInfo::annotation(int index) const {
+ // @@protoc_insertion_point(field_get:google.protobuf.GeneratedCodeInfo.annotation)
+ return _internal_annotation(index);
+}
+inline ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation* GeneratedCodeInfo::_internal_add_annotation() {
+ return annotation_.Add();
+}
+inline ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation* GeneratedCodeInfo::add_annotation() {
+ ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation* _add = _internal_add_annotation();
+ // @@protoc_insertion_point(field_add:google.protobuf.GeneratedCodeInfo.annotation)
+ return _add;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation >&
+GeneratedCodeInfo::annotation() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.GeneratedCodeInfo.annotation)
+ return annotation_;
+}
+
+#ifdef __GNUC__
+ #pragma GCC diagnostic pop
+#endif // __GNUC__
+// -------------------------------------------------------------------
+
+// -------------------------------------------------------------------
+
+// -------------------------------------------------------------------
+
+// -------------------------------------------------------------------
+
+// -------------------------------------------------------------------
+
+// -------------------------------------------------------------------
+
+// -------------------------------------------------------------------
+
+// -------------------------------------------------------------------
+
+// -------------------------------------------------------------------
+
+// -------------------------------------------------------------------
+
+// -------------------------------------------------------------------
+
+// -------------------------------------------------------------------
+
+// -------------------------------------------------------------------
+
+// -------------------------------------------------------------------
+
+// -------------------------------------------------------------------
+
+// -------------------------------------------------------------------
+
+// -------------------------------------------------------------------
+
+// -------------------------------------------------------------------
+
+// -------------------------------------------------------------------
+
+// -------------------------------------------------------------------
+
+// -------------------------------------------------------------------
+
+// -------------------------------------------------------------------
+
+// -------------------------------------------------------------------
+
+// -------------------------------------------------------------------
+
+// -------------------------------------------------------------------
+
+// -------------------------------------------------------------------
+
+
+// @@protoc_insertion_point(namespace_scope)
+
+PROTOBUF_NAMESPACE_CLOSE
+
+PROTOBUF_NAMESPACE_OPEN
+
+template <> struct is_proto_enum< ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto_Type> : ::std::true_type {};
+template <>
+inline const EnumDescriptor* GetEnumDescriptor< ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto_Type>() {
+ return ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto_Type_descriptor();
+}
+template <> struct is_proto_enum< ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto_Label> : ::std::true_type {};
+template <>
+inline const EnumDescriptor* GetEnumDescriptor< ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto_Label>() {
+ return ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto_Label_descriptor();
+}
+template <> struct is_proto_enum< ::PROTOBUF_NAMESPACE_ID::FileOptions_OptimizeMode> : ::std::true_type {};
+template <>
+inline const EnumDescriptor* GetEnumDescriptor< ::PROTOBUF_NAMESPACE_ID::FileOptions_OptimizeMode>() {
+ return ::PROTOBUF_NAMESPACE_ID::FileOptions_OptimizeMode_descriptor();
+}
+template <> struct is_proto_enum< ::PROTOBUF_NAMESPACE_ID::FieldOptions_CType> : ::std::true_type {};
+template <>
+inline const EnumDescriptor* GetEnumDescriptor< ::PROTOBUF_NAMESPACE_ID::FieldOptions_CType>() {
+ return ::PROTOBUF_NAMESPACE_ID::FieldOptions_CType_descriptor();
+}
+template <> struct is_proto_enum< ::PROTOBUF_NAMESPACE_ID::FieldOptions_JSType> : ::std::true_type {};
+template <>
+inline const EnumDescriptor* GetEnumDescriptor< ::PROTOBUF_NAMESPACE_ID::FieldOptions_JSType>() {
+ return ::PROTOBUF_NAMESPACE_ID::FieldOptions_JSType_descriptor();
+}
+template <> struct is_proto_enum< ::PROTOBUF_NAMESPACE_ID::MethodOptions_IdempotencyLevel> : ::std::true_type {};
+template <>
+inline const EnumDescriptor* GetEnumDescriptor< ::PROTOBUF_NAMESPACE_ID::MethodOptions_IdempotencyLevel>() {
+ return ::PROTOBUF_NAMESPACE_ID::MethodOptions_IdempotencyLevel_descriptor();
+}
+
+PROTOBUF_NAMESPACE_CLOSE
+
+// @@protoc_insertion_point(global_scope)
+
+#include <port_undef.inc>
+#endif // GOOGLE_PROTOBUF_INCLUDED_GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fdescriptor_2eproto
diff --git a/NorthstarDedicatedTest/include/protobuf/descriptor.proto b/NorthstarDedicatedTest/include/protobuf/descriptor.proto
new file mode 100644
index 00000000..156e410a
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/descriptor.proto
@@ -0,0 +1,911 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// The messages in this file describe the definitions found in .proto files.
+// A valid .proto file can be translated directly to a FileDescriptorProto
+// without any other information (e.g. without reading its imports).
+
+
+syntax = "proto2";
+
+package google.protobuf;
+
+option go_package = "google.golang.org/protobuf/types/descriptorpb";
+option java_package = "com.google.protobuf";
+option java_outer_classname = "DescriptorProtos";
+option csharp_namespace = "Google.Protobuf.Reflection";
+option objc_class_prefix = "GPB";
+option cc_enable_arenas = true;
+
+// descriptor.proto must be optimized for speed because reflection-based
+// algorithms don't work during bootstrapping.
+option optimize_for = SPEED;
+
+// The protocol compiler can output a FileDescriptorSet containing the .proto
+// files it parses.
+message FileDescriptorSet {
+ repeated FileDescriptorProto file = 1;
+}
+
+// Describes a complete .proto file.
+message FileDescriptorProto {
+ optional string name = 1; // file name, relative to root of source tree
+ optional string package = 2; // e.g. "foo", "foo.bar", etc.
+
+ // Names of files imported by this file.
+ repeated string dependency = 3;
+ // Indexes of the public imported files in the dependency list above.
+ repeated int32 public_dependency = 10;
+ // Indexes of the weak imported files in the dependency list.
+ // For Google-internal migration only. Do not use.
+ repeated int32 weak_dependency = 11;
+
+ // All top-level definitions in this file.
+ repeated DescriptorProto message_type = 4;
+ repeated EnumDescriptorProto enum_type = 5;
+ repeated ServiceDescriptorProto service = 6;
+ repeated FieldDescriptorProto extension = 7;
+
+ optional FileOptions options = 8;
+
+ // This field contains optional information about the original source code.
+ // You may safely remove this entire field without harming runtime
+ // functionality of the descriptors -- the information is needed only by
+ // development tools.
+ optional SourceCodeInfo source_code_info = 9;
+
+ // The syntax of the proto file.
+ // The supported values are "proto2" and "proto3".
+ optional string syntax = 12;
+}
+
+// Describes a message type.
+message DescriptorProto {
+ optional string name = 1;
+
+ repeated FieldDescriptorProto field = 2;
+ repeated FieldDescriptorProto extension = 6;
+
+ repeated DescriptorProto nested_type = 3;
+ repeated EnumDescriptorProto enum_type = 4;
+
+ message ExtensionRange {
+ optional int32 start = 1; // Inclusive.
+ optional int32 end = 2; // Exclusive.
+
+ optional ExtensionRangeOptions options = 3;
+ }
+ repeated ExtensionRange extension_range = 5;
+
+ repeated OneofDescriptorProto oneof_decl = 8;
+
+ optional MessageOptions options = 7;
+
+ // Range of reserved tag numbers. Reserved tag numbers may not be used by
+ // fields or extension ranges in the same message. Reserved ranges may
+ // not overlap.
+ message ReservedRange {
+ optional int32 start = 1; // Inclusive.
+ optional int32 end = 2; // Exclusive.
+ }
+ repeated ReservedRange reserved_range = 9;
+ // Reserved field names, which may not be used by fields in the same message.
+ // A given name may only be reserved once.
+ repeated string reserved_name = 10;
+}
+
+message ExtensionRangeOptions {
+ // The parser stores options it doesn't recognize here. See above.
+ repeated UninterpretedOption uninterpreted_option = 999;
+
+
+ // Clients can define custom options in extensions of this message. See above.
+ extensions 1000 to max;
+}
+
+// Describes a field within a message.
+message FieldDescriptorProto {
+ enum Type {
+ // 0 is reserved for errors.
+ // Order is weird for historical reasons.
+ TYPE_DOUBLE = 1;
+ TYPE_FLOAT = 2;
+ // Not ZigZag encoded. Negative numbers take 10 bytes. Use TYPE_SINT64 if
+ // negative values are likely.
+ TYPE_INT64 = 3;
+ TYPE_UINT64 = 4;
+ // Not ZigZag encoded. Negative numbers take 10 bytes. Use TYPE_SINT32 if
+ // negative values are likely.
+ TYPE_INT32 = 5;
+ TYPE_FIXED64 = 6;
+ TYPE_FIXED32 = 7;
+ TYPE_BOOL = 8;
+ TYPE_STRING = 9;
+ // Tag-delimited aggregate.
+ // Group type is deprecated and not supported in proto3. However, Proto3
+ // implementations should still be able to parse the group wire format and
+ // treat group fields as unknown fields.
+ TYPE_GROUP = 10;
+ TYPE_MESSAGE = 11; // Length-delimited aggregate.
+
+ // New in version 2.
+ TYPE_BYTES = 12;
+ TYPE_UINT32 = 13;
+ TYPE_ENUM = 14;
+ TYPE_SFIXED32 = 15;
+ TYPE_SFIXED64 = 16;
+ TYPE_SINT32 = 17; // Uses ZigZag encoding.
+ TYPE_SINT64 = 18; // Uses ZigZag encoding.
+ }
+
+ enum Label {
+ // 0 is reserved for errors
+ LABEL_OPTIONAL = 1;
+ LABEL_REQUIRED = 2;
+ LABEL_REPEATED = 3;
+ }
+
+ optional string name = 1;
+ optional int32 number = 3;
+ optional Label label = 4;
+
+ // If type_name is set, this need not be set. If both this and type_name
+ // are set, this must be one of TYPE_ENUM, TYPE_MESSAGE or TYPE_GROUP.
+ optional Type type = 5;
+
+ // For message and enum types, this is the name of the type. If the name
+ // starts with a '.', it is fully-qualified. Otherwise, C++-like scoping
+ // rules are used to find the type (i.e. first the nested types within this
+ // message are searched, then within the parent, on up to the root
+ // namespace).
+ optional string type_name = 6;
+
+ // For extensions, this is the name of the type being extended. It is
+ // resolved in the same manner as type_name.
+ optional string extendee = 2;
+
+ // For numeric types, contains the original text representation of the value.
+ // For booleans, "true" or "false".
+ // For strings, contains the default text contents (not escaped in any way).
+ // For bytes, contains the C escaped value. All bytes >= 128 are escaped.
+ // TODO(kenton): Base-64 encode?
+ optional string default_value = 7;
+
+ // If set, gives the index of a oneof in the containing type's oneof_decl
+ // list. This field is a member of that oneof.
+ optional int32 oneof_index = 9;
+
+ // JSON name of this field. The value is set by protocol compiler. If the
+ // user has set a "json_name" option on this field, that option's value
+ // will be used. Otherwise, it's deduced from the field's name by converting
+ // it to camelCase.
+ optional string json_name = 10;
+
+ optional FieldOptions options = 8;
+
+ // If true, this is a proto3 "optional". When a proto3 field is optional, it
+ // tracks presence regardless of field type.
+ //
+ // When proto3_optional is true, this field must be belong to a oneof to
+ // signal to old proto3 clients that presence is tracked for this field. This
+ // oneof is known as a "synthetic" oneof, and this field must be its sole
+ // member (each proto3 optional field gets its own synthetic oneof). Synthetic
+ // oneofs exist in the descriptor only, and do not generate any API. Synthetic
+ // oneofs must be ordered after all "real" oneofs.
+ //
+ // For message fields, proto3_optional doesn't create any semantic change,
+ // since non-repeated message fields always track presence. However it still
+ // indicates the semantic detail of whether the user wrote "optional" or not.
+ // This can be useful for round-tripping the .proto file. For consistency we
+ // give message fields a synthetic oneof also, even though it is not required
+ // to track presence. This is especially important because the parser can't
+ // tell if a field is a message or an enum, so it must always create a
+ // synthetic oneof.
+ //
+ // Proto2 optional fields do not set this flag, because they already indicate
+ // optional with `LABEL_OPTIONAL`.
+ optional bool proto3_optional = 17;
+}
+
+// Describes a oneof.
+message OneofDescriptorProto {
+ optional string name = 1;
+ optional OneofOptions options = 2;
+}
+
+// Describes an enum type.
+message EnumDescriptorProto {
+ optional string name = 1;
+
+ repeated EnumValueDescriptorProto value = 2;
+
+ optional EnumOptions options = 3;
+
+ // Range of reserved numeric values. Reserved values may not be used by
+ // entries in the same enum. Reserved ranges may not overlap.
+ //
+ // Note that this is distinct from DescriptorProto.ReservedRange in that it
+ // is inclusive such that it can appropriately represent the entire int32
+ // domain.
+ message EnumReservedRange {
+ optional int32 start = 1; // Inclusive.
+ optional int32 end = 2; // Inclusive.
+ }
+
+ // Range of reserved numeric values. Reserved numeric values may not be used
+ // by enum values in the same enum declaration. Reserved ranges may not
+ // overlap.
+ repeated EnumReservedRange reserved_range = 4;
+
+ // Reserved enum value names, which may not be reused. A given name may only
+ // be reserved once.
+ repeated string reserved_name = 5;
+}
+
+// Describes a value within an enum.
+message EnumValueDescriptorProto {
+ optional string name = 1;
+ optional int32 number = 2;
+
+ optional EnumValueOptions options = 3;
+}
+
+// Describes a service.
+message ServiceDescriptorProto {
+ optional string name = 1;
+ repeated MethodDescriptorProto method = 2;
+
+ optional ServiceOptions options = 3;
+}
+
+// Describes a method of a service.
+message MethodDescriptorProto {
+ optional string name = 1;
+
+ // Input and output type names. These are resolved in the same way as
+ // FieldDescriptorProto.type_name, but must refer to a message type.
+ optional string input_type = 2;
+ optional string output_type = 3;
+
+ optional MethodOptions options = 4;
+
+ // Identifies if client streams multiple client messages
+ optional bool client_streaming = 5 [default = false];
+ // Identifies if server streams multiple server messages
+ optional bool server_streaming = 6 [default = false];
+}
+
+
+// ===================================================================
+// Options
+
+// Each of the definitions above may have "options" attached. These are
+// just annotations which may cause code to be generated slightly differently
+// or may contain hints for code that manipulates protocol messages.
+//
+// Clients may define custom options as extensions of the *Options messages.
+// These extensions may not yet be known at parsing time, so the parser cannot
+// store the values in them. Instead it stores them in a field in the *Options
+// message called uninterpreted_option. This field must have the same name
+// across all *Options messages. We then use this field to populate the
+// extensions when we build a descriptor, at which point all protos have been
+// parsed and so all extensions are known.
+//
+// Extension numbers for custom options may be chosen as follows:
+// * For options which will only be used within a single application or
+// organization, or for experimental options, use field numbers 50000
+// through 99999. It is up to you to ensure that you do not use the
+// same number for multiple options.
+// * For options which will be published and used publicly by multiple
+// independent entities, e-mail protobuf-global-extension-registry@google.com
+// to reserve extension numbers. Simply provide your project name (e.g.
+// Objective-C plugin) and your project website (if available) -- there's no
+// need to explain how you intend to use them. Usually you only need one
+// extension number. You can declare multiple options with only one extension
+// number by putting them in a sub-message. See the Custom Options section of
+// the docs for examples:
+// https://developers.google.com/protocol-buffers/docs/proto#options
+// If this turns out to be popular, a web service will be set up
+// to automatically assign option numbers.
+
+message FileOptions {
+
+ // Sets the Java package where classes generated from this .proto will be
+ // placed. By default, the proto package is used, but this is often
+ // inappropriate because proto packages do not normally start with backwards
+ // domain names.
+ optional string java_package = 1;
+
+
+ // Controls the name of the wrapper Java class generated for the .proto file.
+ // That class will always contain the .proto file's getDescriptor() method as
+ // well as any top-level extensions defined in the .proto file.
+ // If java_multiple_files is disabled, then all the other classes from the
+ // .proto file will be nested inside the single wrapper outer class.
+ optional string java_outer_classname = 8;
+
+ // If enabled, then the Java code generator will generate a separate .java
+ // file for each top-level message, enum, and service defined in the .proto
+ // file. Thus, these types will *not* be nested inside the wrapper class
+ // named by java_outer_classname. However, the wrapper class will still be
+ // generated to contain the file's getDescriptor() method as well as any
+ // top-level extensions defined in the file.
+ optional bool java_multiple_files = 10 [default = false];
+
+ // This option does nothing.
+ optional bool java_generate_equals_and_hash = 20 [deprecated=true];
+
+ // If set true, then the Java2 code generator will generate code that
+ // throws an exception whenever an attempt is made to assign a non-UTF-8
+ // byte sequence to a string field.
+ // Message reflection will do the same.
+ // However, an extension field still accepts non-UTF-8 byte sequences.
+ // This option has no effect on when used with the lite runtime.
+ optional bool java_string_check_utf8 = 27 [default = false];
+
+
+ // Generated classes can be optimized for speed or code size.
+ enum OptimizeMode {
+ SPEED = 1; // Generate complete code for parsing, serialization,
+ // etc.
+ CODE_SIZE = 2; // Use ReflectionOps to implement these methods.
+ LITE_RUNTIME = 3; // Generate code using MessageLite and the lite runtime.
+ }
+ optional OptimizeMode optimize_for = 9 [default = SPEED];
+
+ // Sets the Go package where structs generated from this .proto will be
+ // placed. If omitted, the Go package will be derived from the following:
+ // - The basename of the package import path, if provided.
+ // - Otherwise, the package statement in the .proto file, if present.
+ // - Otherwise, the basename of the .proto file, without extension.
+ optional string go_package = 11;
+
+
+
+
+ // Should generic services be generated in each language? "Generic" services
+ // are not specific to any particular RPC system. They are generated by the
+ // main code generators in each language (without additional plugins).
+ // Generic services were the only kind of service generation supported by
+ // early versions of google.protobuf.
+ //
+ // Generic services are now considered deprecated in favor of using plugins
+ // that generate code specific to your particular RPC system. Therefore,
+ // these default to false. Old code which depends on generic services should
+ // explicitly set them to true.
+ optional bool cc_generic_services = 16 [default = false];
+ optional bool java_generic_services = 17 [default = false];
+ optional bool py_generic_services = 18 [default = false];
+ optional bool php_generic_services = 42 [default = false];
+
+ // Is this file deprecated?
+ // Depending on the target platform, this can emit Deprecated annotations
+ // for everything in the file, or it will be completely ignored; in the very
+ // least, this is a formalization for deprecating files.
+ optional bool deprecated = 23 [default = false];
+
+ // Enables the use of arenas for the proto messages in this file. This applies
+ // only to generated classes for C++.
+ optional bool cc_enable_arenas = 31 [default = true];
+
+
+ // Sets the objective c class prefix which is prepended to all objective c
+ // generated classes from this .proto. There is no default.
+ optional string objc_class_prefix = 36;
+
+ // Namespace for generated classes; defaults to the package.
+ optional string csharp_namespace = 37;
+
+ // By default Swift generators will take the proto package and CamelCase it
+ // replacing '.' with underscore and use that to prefix the types/symbols
+ // defined. When this options is provided, they will use this value instead
+ // to prefix the types/symbols defined.
+ optional string swift_prefix = 39;
+
+ // Sets the php class prefix which is prepended to all php generated classes
+ // from this .proto. Default is empty.
+ optional string php_class_prefix = 40;
+
+ // Use this option to change the namespace of php generated classes. Default
+ // is empty. When this option is empty, the package name will be used for
+ // determining the namespace.
+ optional string php_namespace = 41;
+
+ // Use this option to change the namespace of php generated metadata classes.
+ // Default is empty. When this option is empty, the proto file name will be
+ // used for determining the namespace.
+ optional string php_metadata_namespace = 44;
+
+ // Use this option to change the package of ruby generated classes. Default
+ // is empty. When this option is not set, the package name will be used for
+ // determining the ruby package.
+ optional string ruby_package = 45;
+
+
+ // The parser stores options it doesn't recognize here.
+ // See the documentation for the "Options" section above.
+ repeated UninterpretedOption uninterpreted_option = 999;
+
+ // Clients can define custom options in extensions of this message.
+ // See the documentation for the "Options" section above.
+ extensions 1000 to max;
+
+ reserved 38;
+}
+
+message MessageOptions {
+ // Set true to use the old proto1 MessageSet wire format for extensions.
+ // This is provided for backwards-compatibility with the MessageSet wire
+ // format. You should not use this for any other reason: It's less
+ // efficient, has fewer features, and is more complicated.
+ //
+ // The message must be defined exactly as follows:
+ // message Foo {
+ // option message_set_wire_format = true;
+ // extensions 4 to max;
+ // }
+ // Note that the message cannot have any defined fields; MessageSets only
+ // have extensions.
+ //
+ // All extensions of your type must be singular messages; e.g. they cannot
+ // be int32s, enums, or repeated messages.
+ //
+ // Because this is an option, the above two restrictions are not enforced by
+ // the protocol compiler.
+ optional bool message_set_wire_format = 1 [default = false];
+
+ // Disables the generation of the standard "descriptor()" accessor, which can
+ // conflict with a field of the same name. This is meant to make migration
+ // from proto1 easier; new code should avoid fields named "descriptor".
+ optional bool no_standard_descriptor_accessor = 2 [default = false];
+
+ // Is this message deprecated?
+ // Depending on the target platform, this can emit Deprecated annotations
+ // for the message, or it will be completely ignored; in the very least,
+ // this is a formalization for deprecating messages.
+ optional bool deprecated = 3 [default = false];
+
+ reserved 4, 5, 6;
+
+ // Whether the message is an automatically generated map entry type for the
+ // maps field.
+ //
+ // For maps fields:
+ // map<KeyType, ValueType> map_field = 1;
+ // The parsed descriptor looks like:
+ // message MapFieldEntry {
+ // option map_entry = true;
+ // optional KeyType key = 1;
+ // optional ValueType value = 2;
+ // }
+ // repeated MapFieldEntry map_field = 1;
+ //
+ // Implementations may choose not to generate the map_entry=true message, but
+ // use a native map in the target language to hold the keys and values.
+ // The reflection APIs in such implementations still need to work as
+ // if the field is a repeated message field.
+ //
+ // NOTE: Do not set the option in .proto files. Always use the maps syntax
+ // instead. The option should only be implicitly set by the proto compiler
+ // parser.
+ optional bool map_entry = 7;
+
+ reserved 8; // javalite_serializable
+ reserved 9; // javanano_as_lite
+
+
+ // The parser stores options it doesn't recognize here. See above.
+ repeated UninterpretedOption uninterpreted_option = 999;
+
+ // Clients can define custom options in extensions of this message. See above.
+ extensions 1000 to max;
+}
+
+message FieldOptions {
+ // The ctype option instructs the C++ code generator to use a different
+ // representation of the field than it normally would. See the specific
+ // options below. This option is not yet implemented in the open source
+ // release -- sorry, we'll try to include it in a future version!
+ optional CType ctype = 1 [default = STRING];
+ enum CType {
+ // Default mode.
+ STRING = 0;
+
+ CORD = 1;
+
+ STRING_PIECE = 2;
+ }
+ // The packed option can be enabled for repeated primitive fields to enable
+ // a more efficient representation on the wire. Rather than repeatedly
+ // writing the tag and type for each element, the entire array is encoded as
+ // a single length-delimited blob. In proto3, only explicit setting it to
+ // false will avoid using packed encoding.
+ optional bool packed = 2;
+
+ // The jstype option determines the JavaScript type used for values of the
+ // field. The option is permitted only for 64 bit integral and fixed types
+ // (int64, uint64, sint64, fixed64, sfixed64). A field with jstype JS_STRING
+ // is represented as JavaScript string, which avoids loss of precision that
+ // can happen when a large value is converted to a floating point JavaScript.
+ // Specifying JS_NUMBER for the jstype causes the generated JavaScript code to
+ // use the JavaScript "number" type. The behavior of the default option
+ // JS_NORMAL is implementation dependent.
+ //
+ // This option is an enum to permit additional types to be added, e.g.
+ // goog.math.Integer.
+ optional JSType jstype = 6 [default = JS_NORMAL];
+ enum JSType {
+ // Use the default type.
+ JS_NORMAL = 0;
+
+ // Use JavaScript strings.
+ JS_STRING = 1;
+
+ // Use JavaScript numbers.
+ JS_NUMBER = 2;
+ }
+
+ // Should this field be parsed lazily? Lazy applies only to message-type
+ // fields. It means that when the outer message is initially parsed, the
+ // inner message's contents will not be parsed but instead stored in encoded
+ // form. The inner message will actually be parsed when it is first accessed.
+ //
+ // This is only a hint. Implementations are free to choose whether to use
+ // eager or lazy parsing regardless of the value of this option. However,
+ // setting this option true suggests that the protocol author believes that
+ // using lazy parsing on this field is worth the additional bookkeeping
+ // overhead typically needed to implement it.
+ //
+ // This option does not affect the public interface of any generated code;
+ // all method signatures remain the same. Furthermore, thread-safety of the
+ // interface is not affected by this option; const methods remain safe to
+ // call from multiple threads concurrently, while non-const methods continue
+ // to require exclusive access.
+ //
+ //
+ // Note that implementations may choose not to check required fields within
+ // a lazy sub-message. That is, calling IsInitialized() on the outer message
+ // may return true even if the inner message has missing required fields.
+ // This is necessary because otherwise the inner message would have to be
+ // parsed in order to perform the check, defeating the purpose of lazy
+ // parsing. An implementation which chooses not to check required fields
+ // must be consistent about it. That is, for any particular sub-message, the
+ // implementation must either *always* check its required fields, or *never*
+ // check its required fields, regardless of whether or not the message has
+ // been parsed.
+ optional bool lazy = 5 [default = false];
+
+ // Is this field deprecated?
+ // Depending on the target platform, this can emit Deprecated annotations
+ // for accessors, or it will be completely ignored; in the very least, this
+ // is a formalization for deprecating fields.
+ optional bool deprecated = 3 [default = false];
+
+ // For Google-internal migration only. Do not use.
+ optional bool weak = 10 [default = false];
+
+
+ // The parser stores options it doesn't recognize here. See above.
+ repeated UninterpretedOption uninterpreted_option = 999;
+
+ // Clients can define custom options in extensions of this message. See above.
+ extensions 1000 to max;
+
+ reserved 4; // removed jtype
+}
+
+message OneofOptions {
+ // The parser stores options it doesn't recognize here. See above.
+ repeated UninterpretedOption uninterpreted_option = 999;
+
+ // Clients can define custom options in extensions of this message. See above.
+ extensions 1000 to max;
+}
+
+message EnumOptions {
+
+ // Set this option to true to allow mapping different tag names to the same
+ // value.
+ optional bool allow_alias = 2;
+
+ // Is this enum deprecated?
+ // Depending on the target platform, this can emit Deprecated annotations
+ // for the enum, or it will be completely ignored; in the very least, this
+ // is a formalization for deprecating enums.
+ optional bool deprecated = 3 [default = false];
+
+ reserved 5; // javanano_as_lite
+
+ // The parser stores options it doesn't recognize here. See above.
+ repeated UninterpretedOption uninterpreted_option = 999;
+
+ // Clients can define custom options in extensions of this message. See above.
+ extensions 1000 to max;
+}
+
+message EnumValueOptions {
+ // Is this enum value deprecated?
+ // Depending on the target platform, this can emit Deprecated annotations
+ // for the enum value, or it will be completely ignored; in the very least,
+ // this is a formalization for deprecating enum values.
+ optional bool deprecated = 1 [default = false];
+
+ // The parser stores options it doesn't recognize here. See above.
+ repeated UninterpretedOption uninterpreted_option = 999;
+
+ // Clients can define custom options in extensions of this message. See above.
+ extensions 1000 to max;
+}
+
+message ServiceOptions {
+
+ // Note: Field numbers 1 through 32 are reserved for Google's internal RPC
+ // framework. We apologize for hoarding these numbers to ourselves, but
+ // we were already using them long before we decided to release Protocol
+ // Buffers.
+
+ // Is this service deprecated?
+ // Depending on the target platform, this can emit Deprecated annotations
+ // for the service, or it will be completely ignored; in the very least,
+ // this is a formalization for deprecating services.
+ optional bool deprecated = 33 [default = false];
+
+ // The parser stores options it doesn't recognize here. See above.
+ repeated UninterpretedOption uninterpreted_option = 999;
+
+ // Clients can define custom options in extensions of this message. See above.
+ extensions 1000 to max;
+}
+
+message MethodOptions {
+
+ // Note: Field numbers 1 through 32 are reserved for Google's internal RPC
+ // framework. We apologize for hoarding these numbers to ourselves, but
+ // we were already using them long before we decided to release Protocol
+ // Buffers.
+
+ // Is this method deprecated?
+ // Depending on the target platform, this can emit Deprecated annotations
+ // for the method, or it will be completely ignored; in the very least,
+ // this is a formalization for deprecating methods.
+ optional bool deprecated = 33 [default = false];
+
+ // Is this method side-effect-free (or safe in HTTP parlance), or idempotent,
+ // or neither? HTTP based RPC implementation may choose GET verb for safe
+ // methods, and PUT verb for idempotent methods instead of the default POST.
+ enum IdempotencyLevel {
+ IDEMPOTENCY_UNKNOWN = 0;
+ NO_SIDE_EFFECTS = 1; // implies idempotent
+ IDEMPOTENT = 2; // idempotent, but may have side effects
+ }
+ optional IdempotencyLevel idempotency_level = 34
+ [default = IDEMPOTENCY_UNKNOWN];
+
+ // The parser stores options it doesn't recognize here. See above.
+ repeated UninterpretedOption uninterpreted_option = 999;
+
+ // Clients can define custom options in extensions of this message. See above.
+ extensions 1000 to max;
+}
+
+
+// A message representing a option the parser does not recognize. This only
+// appears in options protos created by the compiler::Parser class.
+// DescriptorPool resolves these when building Descriptor objects. Therefore,
+// options protos in descriptor objects (e.g. returned by Descriptor::options(),
+// or produced by Descriptor::CopyTo()) will never have UninterpretedOptions
+// in them.
+message UninterpretedOption {
+ // The name of the uninterpreted option. Each string represents a segment in
+ // a dot-separated name. is_extension is true iff a segment represents an
+ // extension (denoted with parentheses in options specs in .proto files).
+ // E.g.,{ ["foo", false], ["bar.baz", true], ["qux", false] } represents
+ // "foo.(bar.baz).qux".
+ message NamePart {
+ required string name_part = 1;
+ required bool is_extension = 2;
+ }
+ repeated NamePart name = 2;
+
+ // The value of the uninterpreted option, in whatever type the tokenizer
+ // identified it as during parsing. Exactly one of these should be set.
+ optional string identifier_value = 3;
+ optional uint64 positive_int_value = 4;
+ optional int64 negative_int_value = 5;
+ optional double double_value = 6;
+ optional bytes string_value = 7;
+ optional string aggregate_value = 8;
+}
+
+// ===================================================================
+// Optional source code info
+
+// Encapsulates information about the original source file from which a
+// FileDescriptorProto was generated.
+message SourceCodeInfo {
+ // A Location identifies a piece of source code in a .proto file which
+ // corresponds to a particular definition. This information is intended
+ // to be useful to IDEs, code indexers, documentation generators, and similar
+ // tools.
+ //
+ // For example, say we have a file like:
+ // message Foo {
+ // optional string foo = 1;
+ // }
+ // Let's look at just the field definition:
+ // optional string foo = 1;
+ // ^ ^^ ^^ ^ ^^^
+ // a bc de f ghi
+ // We have the following locations:
+ // span path represents
+ // [a,i) [ 4, 0, 2, 0 ] The whole field definition.
+ // [a,b) [ 4, 0, 2, 0, 4 ] The label (optional).
+ // [c,d) [ 4, 0, 2, 0, 5 ] The type (string).
+ // [e,f) [ 4, 0, 2, 0, 1 ] The name (foo).
+ // [g,h) [ 4, 0, 2, 0, 3 ] The number (1).
+ //
+ // Notes:
+ // - A location may refer to a repeated field itself (i.e. not to any
+ // particular index within it). This is used whenever a set of elements are
+ // logically enclosed in a single code segment. For example, an entire
+ // extend block (possibly containing multiple extension definitions) will
+ // have an outer location whose path refers to the "extensions" repeated
+ // field without an index.
+ // - Multiple locations may have the same path. This happens when a single
+ // logical declaration is spread out across multiple places. The most
+ // obvious example is the "extend" block again -- there may be multiple
+ // extend blocks in the same scope, each of which will have the same path.
+ // - A location's span is not always a subset of its parent's span. For
+ // example, the "extendee" of an extension declaration appears at the
+ // beginning of the "extend" block and is shared by all extensions within
+ // the block.
+ // - Just because a location's span is a subset of some other location's span
+ // does not mean that it is a descendant. For example, a "group" defines
+ // both a type and a field in a single declaration. Thus, the locations
+ // corresponding to the type and field and their components will overlap.
+ // - Code which tries to interpret locations should probably be designed to
+ // ignore those that it doesn't understand, as more types of locations could
+ // be recorded in the future.
+ repeated Location location = 1;
+ message Location {
+ // Identifies which part of the FileDescriptorProto was defined at this
+ // location.
+ //
+ // Each element is a field number or an index. They form a path from
+ // the root FileDescriptorProto to the place where the definition. For
+ // example, this path:
+ // [ 4, 3, 2, 7, 1 ]
+ // refers to:
+ // file.message_type(3) // 4, 3
+ // .field(7) // 2, 7
+ // .name() // 1
+ // This is because FileDescriptorProto.message_type has field number 4:
+ // repeated DescriptorProto message_type = 4;
+ // and DescriptorProto.field has field number 2:
+ // repeated FieldDescriptorProto field = 2;
+ // and FieldDescriptorProto.name has field number 1:
+ // optional string name = 1;
+ //
+ // Thus, the above path gives the location of a field name. If we removed
+ // the last element:
+ // [ 4, 3, 2, 7 ]
+ // this path refers to the whole field declaration (from the beginning
+ // of the label to the terminating semicolon).
+ repeated int32 path = 1 [packed = true];
+
+ // Always has exactly three or four elements: start line, start column,
+ // end line (optional, otherwise assumed same as start line), end column.
+ // These are packed into a single field for efficiency. Note that line
+ // and column numbers are zero-based -- typically you will want to add
+ // 1 to each before displaying to a user.
+ repeated int32 span = 2 [packed = true];
+
+ // If this SourceCodeInfo represents a complete declaration, these are any
+ // comments appearing before and after the declaration which appear to be
+ // attached to the declaration.
+ //
+ // A series of line comments appearing on consecutive lines, with no other
+ // tokens appearing on those lines, will be treated as a single comment.
+ //
+ // leading_detached_comments will keep paragraphs of comments that appear
+ // before (but not connected to) the current element. Each paragraph,
+ // separated by empty lines, will be one comment element in the repeated
+ // field.
+ //
+ // Only the comment content is provided; comment markers (e.g. //) are
+ // stripped out. For block comments, leading whitespace and an asterisk
+ // will be stripped from the beginning of each line other than the first.
+ // Newlines are included in the output.
+ //
+ // Examples:
+ //
+ // optional int32 foo = 1; // Comment attached to foo.
+ // // Comment attached to bar.
+ // optional int32 bar = 2;
+ //
+ // optional string baz = 3;
+ // // Comment attached to baz.
+ // // Another line attached to baz.
+ //
+ // // Comment attached to qux.
+ // //
+ // // Another line attached to qux.
+ // optional double qux = 4;
+ //
+ // // Detached comment for corge. This is not leading or trailing comments
+ // // to qux or corge because there are blank lines separating it from
+ // // both.
+ //
+ // // Detached comment for corge paragraph 2.
+ //
+ // optional string corge = 5;
+ // /* Block comment attached
+ // * to corge. Leading asterisks
+ // * will be removed. */
+ // /* Block comment attached to
+ // * grault. */
+ // optional int32 grault = 6;
+ //
+ // // ignored detached comments.
+ optional string leading_comments = 3;
+ optional string trailing_comments = 4;
+ repeated string leading_detached_comments = 6;
+ }
+}
+
+// Describes the relationship between generated code and its original source
+// file. A GeneratedCodeInfo message is associated with only one generated
+// source file, but may contain references to different source .proto files.
+message GeneratedCodeInfo {
+ // An Annotation connects some span of text in generated code to an element
+ // of its generating .proto file.
+ repeated Annotation annotation = 1;
+ message Annotation {
+ // Identifies the element in the original source .proto file. This field
+ // is formatted the same as SourceCodeInfo.Location.path.
+ repeated int32 path = 1 [packed = true];
+
+ // Identifies the filesystem path to the original source .proto.
+ optional string source_file = 2;
+
+ // Identifies the starting offset in bytes in the generated code
+ // that relates to the identified object.
+ optional int32 begin = 3;
+
+ // Identifies the ending offset in bytes in the generated code that
+ // relates to the identified offset. The end offset should be one past
+ // the last relevant byte (so the length of the text = end - begin).
+ optional int32 end = 4;
+ }
+}
diff --git a/NorthstarDedicatedTest/include/protobuf/descriptor_database.cc b/NorthstarDedicatedTest/include/protobuf/descriptor_database.cc
new file mode 100644
index 00000000..9a47db6b
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/descriptor_database.cc
@@ -0,0 +1,1031 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <descriptor_database.h>
+
+#include <set>
+
+#include <descriptor.pb.h>
+#include <stubs/map_util.h>
+#include <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;
+}
+
+
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/descriptor_database.h b/NorthstarDedicatedTest/include/protobuf/descriptor_database.h
new file mode 100644
index 00000000..3faa1800
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/descriptor_database.h
@@ -0,0 +1,391 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// Interface for manipulating databases of descriptors.
+
+#ifndef GOOGLE_PROTOBUF_DESCRIPTOR_DATABASE_H__
+#define GOOGLE_PROTOBUF_DESCRIPTOR_DATABASE_H__
+
+#include <map>
+#include <string>
+#include <utility>
+#include <vector>
+#include <stubs/common.h>
+#include <descriptor.h>
+
+#include <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;
+
+
+ private:
+ std::vector<DescriptorDatabase*> sources_;
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MergedDescriptorDatabase);
+};
+
+} // namespace protobuf
+} // namespace google
+
+#include <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_DESCRIPTOR_DATABASE_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/descriptor_database_unittest.cc b/NorthstarDedicatedTest/include/protobuf/descriptor_database_unittest.cc
new file mode 100644
index 00000000..4a9c5642
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/descriptor_database_unittest.cc
@@ -0,0 +1,805 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 makes extensive use of RFC 3092. :)
+
+#include <descriptor_database.h>
+
+#include <algorithm>
+#include <memory>
+
+#include <stubs/logging.h>
+#include <stubs/common.h>
+#include <descriptor.pb.h>
+#include <descriptor.h>
+#include <text_format.h>
+#include <gmock/gmock.h>
+#include <testing/googletest.h>
+#include <gtest/gtest.h>
+
+
+namespace google {
+namespace protobuf {
+namespace {
+
+static void AddToDatabase(SimpleDescriptorDatabase* database,
+ const char* file_text) {
+ FileDescriptorProto file_proto;
+ EXPECT_TRUE(TextFormat::ParseFromString(file_text, &file_proto));
+ database->Add(file_proto);
+}
+
+static void ExpectContainsType(const FileDescriptorProto& proto,
+ const std::string& type_name) {
+ for (int i = 0; i < proto.message_type_size(); i++) {
+ if (proto.message_type(i).name() == type_name) return;
+ }
+ ADD_FAILURE() << "\"" << proto.name() << "\" did not contain expected type \""
+ << type_name << "\".";
+}
+
+// ===================================================================
+
+#if GTEST_HAS_PARAM_TEST
+
+// SimpleDescriptorDatabase, EncodedDescriptorDatabase, and
+// DescriptorPoolDatabase call for very similar tests. Instead of writing
+// three nearly-identical sets of tests, we use parameterized tests to apply
+// the same code to all three.
+
+// The parameterized test runs against a DescriptorDatabaseTestCase. We have
+// implementations for each of the three classes we want to test.
+class DescriptorDatabaseTestCase {
+ public:
+ virtual ~DescriptorDatabaseTestCase() {}
+
+ virtual DescriptorDatabase* GetDatabase() = 0;
+ virtual bool AddToDatabase(const FileDescriptorProto& file) = 0;
+};
+
+// Factory function type.
+typedef DescriptorDatabaseTestCase* DescriptorDatabaseTestCaseFactory();
+
+// Specialization for SimpleDescriptorDatabase.
+class SimpleDescriptorDatabaseTestCase : public DescriptorDatabaseTestCase {
+ public:
+ static DescriptorDatabaseTestCase* New() {
+ return new SimpleDescriptorDatabaseTestCase;
+ }
+
+ virtual ~SimpleDescriptorDatabaseTestCase() {}
+
+ virtual DescriptorDatabase* GetDatabase() { return &database_; }
+ virtual bool AddToDatabase(const FileDescriptorProto& file) {
+ return database_.Add(file);
+ }
+
+ private:
+ SimpleDescriptorDatabase database_;
+};
+
+// Specialization for EncodedDescriptorDatabase.
+class EncodedDescriptorDatabaseTestCase : public DescriptorDatabaseTestCase {
+ public:
+ static DescriptorDatabaseTestCase* New() {
+ return new EncodedDescriptorDatabaseTestCase;
+ }
+
+ virtual ~EncodedDescriptorDatabaseTestCase() {}
+
+ virtual DescriptorDatabase* GetDatabase() { return &database_; }
+ virtual bool AddToDatabase(const FileDescriptorProto& file) {
+ std::string data;
+ file.SerializeToString(&data);
+ return database_.AddCopy(data.data(), data.size());
+ }
+
+ private:
+ EncodedDescriptorDatabase database_;
+};
+
+// Specialization for DescriptorPoolDatabase.
+class DescriptorPoolDatabaseTestCase : public DescriptorDatabaseTestCase {
+ public:
+ static DescriptorDatabaseTestCase* New() {
+ return new EncodedDescriptorDatabaseTestCase;
+ }
+
+ DescriptorPoolDatabaseTestCase() : database_(pool_) {}
+ virtual ~DescriptorPoolDatabaseTestCase() {}
+
+ virtual DescriptorDatabase* GetDatabase() { return &database_; }
+ virtual bool AddToDatabase(const FileDescriptorProto& file) {
+ return pool_.BuildFile(file);
+ }
+
+ private:
+ DescriptorPool pool_;
+ DescriptorPoolDatabase database_;
+};
+
+// -------------------------------------------------------------------
+
+class DescriptorDatabaseTest
+ : public testing::TestWithParam<DescriptorDatabaseTestCaseFactory*> {
+ protected:
+ virtual void SetUp() {
+ test_case_.reset(GetParam()());
+ database_ = test_case_->GetDatabase();
+ }
+
+ void AddToDatabase(const char* file_descriptor_text) {
+ FileDescriptorProto file_proto;
+ EXPECT_TRUE(TextFormat::ParseFromString(file_descriptor_text, &file_proto));
+ EXPECT_TRUE(test_case_->AddToDatabase(file_proto));
+ }
+
+ void AddToDatabaseWithError(const char* file_descriptor_text) {
+ FileDescriptorProto file_proto;
+ EXPECT_TRUE(TextFormat::ParseFromString(file_descriptor_text, &file_proto));
+ EXPECT_FALSE(test_case_->AddToDatabase(file_proto));
+ }
+
+ std::unique_ptr<DescriptorDatabaseTestCase> test_case_;
+ DescriptorDatabase* database_;
+};
+
+TEST_P(DescriptorDatabaseTest, FindFileByName) {
+ AddToDatabase(
+ "name: \"foo.proto\" "
+ "message_type { name:\"Foo\" }");
+ AddToDatabase(
+ "name: \"bar.proto\" "
+ "message_type { name:\"Bar\" }");
+
+ {
+ FileDescriptorProto file;
+ EXPECT_TRUE(database_->FindFileByName("foo.proto", &file));
+ EXPECT_EQ("foo.proto", file.name());
+ ExpectContainsType(file, "Foo");
+ }
+
+ {
+ FileDescriptorProto file;
+ EXPECT_TRUE(database_->FindFileByName("bar.proto", &file));
+ EXPECT_EQ("bar.proto", file.name());
+ ExpectContainsType(file, "Bar");
+ }
+
+ {
+ // Fails to find undefined files.
+ FileDescriptorProto file;
+ EXPECT_FALSE(database_->FindFileByName("baz.proto", &file));
+ }
+}
+
+TEST_P(DescriptorDatabaseTest, FindFileContainingSymbol) {
+ AddToDatabase(
+ "name: \"foo.proto\" "
+ "message_type { "
+ " name: \"Foo\" "
+ " field { name:\"qux\" }"
+ " nested_type { name: \"Grault\" } "
+ " enum_type { name: \"Garply\" } "
+ "} "
+ "enum_type { "
+ " name: \"Waldo\" "
+ " value { name:\"FRED\" } "
+ "} "
+ "extension { name: \"plugh\" } "
+ "service { "
+ " name: \"Xyzzy\" "
+ " method { name: \"Thud\" } "
+ "}");
+ AddToDatabase(
+ "name: \"bar.proto\" "
+ "package: \"corge\" "
+ "message_type { name: \"Bar\" }");
+
+ {
+ FileDescriptorProto file;
+ EXPECT_TRUE(database_->FindFileContainingSymbol("Foo", &file));
+ EXPECT_EQ("foo.proto", file.name());
+ }
+
+ {
+ // Can find fields.
+ FileDescriptorProto file;
+ EXPECT_TRUE(database_->FindFileContainingSymbol("Foo.qux", &file));
+ EXPECT_EQ("foo.proto", file.name());
+ // Non-existent field under a valid top level symbol can also be
+ // found.
+ EXPECT_TRUE(
+ database_->FindFileContainingSymbol("Foo.none_field.none", &file));
+ }
+
+ {
+ // Can find nested types.
+ FileDescriptorProto file;
+ EXPECT_TRUE(database_->FindFileContainingSymbol("Foo.Grault", &file));
+ EXPECT_EQ("foo.proto", file.name());
+ }
+
+ {
+ // Can find nested enums.
+ FileDescriptorProto file;
+ EXPECT_TRUE(database_->FindFileContainingSymbol("Foo.Garply", &file));
+ EXPECT_EQ("foo.proto", file.name());
+ }
+
+ {
+ // Can find enum types.
+ FileDescriptorProto file;
+ EXPECT_TRUE(database_->FindFileContainingSymbol("Waldo", &file));
+ EXPECT_EQ("foo.proto", file.name());
+ }
+
+ {
+ // Can find enum values.
+ FileDescriptorProto file;
+ EXPECT_TRUE(database_->FindFileContainingSymbol("Waldo.FRED", &file));
+ EXPECT_EQ("foo.proto", file.name());
+ }
+
+ {
+ // Can find extensions.
+ FileDescriptorProto file;
+ EXPECT_TRUE(database_->FindFileContainingSymbol("plugh", &file));
+ EXPECT_EQ("foo.proto", file.name());
+ }
+
+ {
+ // Can find services.
+ FileDescriptorProto file;
+ EXPECT_TRUE(database_->FindFileContainingSymbol("Xyzzy", &file));
+ EXPECT_EQ("foo.proto", file.name());
+ }
+
+ {
+ // Can find methods.
+ FileDescriptorProto file;
+ EXPECT_TRUE(database_->FindFileContainingSymbol("Xyzzy.Thud", &file));
+ EXPECT_EQ("foo.proto", file.name());
+ }
+
+ {
+ // Can find things in packages.
+ FileDescriptorProto file;
+ EXPECT_TRUE(database_->FindFileContainingSymbol("corge.Bar", &file));
+ EXPECT_EQ("bar.proto", file.name());
+ }
+
+ {
+ // Fails to find undefined symbols.
+ FileDescriptorProto file;
+ EXPECT_FALSE(database_->FindFileContainingSymbol("Baz", &file));
+ }
+
+ {
+ // Names must be fully-qualified.
+ FileDescriptorProto file;
+ EXPECT_FALSE(database_->FindFileContainingSymbol("Bar", &file));
+ }
+}
+
+TEST_P(DescriptorDatabaseTest, FindFileContainingExtension) {
+ AddToDatabase(
+ "name: \"foo.proto\" "
+ "message_type { "
+ " name: \"Foo\" "
+ " extension_range { start: 1 end: 1000 } "
+ " extension { name:\"qux\" label:LABEL_OPTIONAL type:TYPE_INT32 "
+ "number:5 "
+ " extendee: \".Foo\" }"
+ "}");
+ AddToDatabase(
+ "name: \"bar.proto\" "
+ "package: \"corge\" "
+ "dependency: \"foo.proto\" "
+ "message_type { "
+ " name: \"Bar\" "
+ " extension_range { start: 1 end: 1000 } "
+ "} "
+ "extension { name:\"grault\" extendee: \".Foo\" number:32 } "
+ "extension { name:\"garply\" extendee: \".corge.Bar\" number:70 } "
+ "extension { name:\"waldo\" extendee: \"Bar\" number:56 } ");
+
+ {
+ FileDescriptorProto file;
+ EXPECT_TRUE(database_->FindFileContainingExtension("Foo", 5, &file));
+ EXPECT_EQ("foo.proto", file.name());
+ }
+
+ {
+ FileDescriptorProto file;
+ EXPECT_TRUE(database_->FindFileContainingExtension("Foo", 32, &file));
+ EXPECT_EQ("bar.proto", file.name());
+ }
+
+ {
+ // Can find extensions for qualified type names.
+ FileDescriptorProto file;
+ EXPECT_TRUE(database_->FindFileContainingExtension("corge.Bar", 70, &file));
+ EXPECT_EQ("bar.proto", file.name());
+ }
+
+ {
+ // Can't find extensions whose extendee was not fully-qualified in the
+ // FileDescriptorProto.
+ FileDescriptorProto file;
+ EXPECT_FALSE(database_->FindFileContainingExtension("Bar", 56, &file));
+ EXPECT_FALSE(
+ database_->FindFileContainingExtension("corge.Bar", 56, &file));
+ }
+
+ {
+ // Can't find non-existent extension numbers.
+ FileDescriptorProto file;
+ EXPECT_FALSE(database_->FindFileContainingExtension("Foo", 12, &file));
+ }
+
+ {
+ // Can't find extensions for non-existent types.
+ FileDescriptorProto file;
+ EXPECT_FALSE(
+ database_->FindFileContainingExtension("NoSuchType", 5, &file));
+ }
+
+ {
+ // Can't find extensions for unqualified type names.
+ FileDescriptorProto file;
+ EXPECT_FALSE(database_->FindFileContainingExtension("Bar", 70, &file));
+ }
+}
+
+TEST_P(DescriptorDatabaseTest, FindAllExtensionNumbers) {
+ AddToDatabase(
+ "name: \"foo.proto\" "
+ "message_type { "
+ " name: \"Foo\" "
+ " extension_range { start: 1 end: 1000 } "
+ " extension { name:\"qux\" label:LABEL_OPTIONAL type:TYPE_INT32 "
+ "number:5 "
+ " extendee: \".Foo\" }"
+ "}");
+ AddToDatabase(
+ "name: \"bar.proto\" "
+ "package: \"corge\" "
+ "dependency: \"foo.proto\" "
+ "message_type { "
+ " name: \"Bar\" "
+ " extension_range { start: 1 end: 1000 } "
+ "} "
+ "extension { name:\"grault\" extendee: \".Foo\" number:32 } "
+ "extension { name:\"garply\" extendee: \".corge.Bar\" number:70 } "
+ "extension { name:\"waldo\" extendee: \"Bar\" number:56 } ");
+
+ {
+ std::vector<int> numbers;
+ EXPECT_TRUE(database_->FindAllExtensionNumbers("Foo", &numbers));
+ ASSERT_EQ(2, numbers.size());
+ std::sort(numbers.begin(), numbers.end());
+ EXPECT_EQ(5, numbers[0]);
+ EXPECT_EQ(32, numbers[1]);
+ }
+
+ {
+ std::vector<int> numbers;
+ EXPECT_TRUE(database_->FindAllExtensionNumbers("corge.Bar", &numbers));
+ // Note: won't find extension 56 due to the name not being fully qualified.
+ ASSERT_EQ(1, numbers.size());
+ EXPECT_EQ(70, numbers[0]);
+ }
+
+ {
+ // Can't find extensions for non-existent types.
+ std::vector<int> numbers;
+ EXPECT_FALSE(database_->FindAllExtensionNumbers("NoSuchType", &numbers));
+ }
+
+ {
+ // Can't find extensions for unqualified types.
+ std::vector<int> numbers;
+ EXPECT_FALSE(database_->FindAllExtensionNumbers("Bar", &numbers));
+ }
+}
+
+TEST_P(DescriptorDatabaseTest, ConflictingFileError) {
+ AddToDatabase(
+ "name: \"foo.proto\" "
+ "message_type { "
+ " name: \"Foo\" "
+ "}");
+ AddToDatabaseWithError(
+ "name: \"foo.proto\" "
+ "message_type { "
+ " name: \"Bar\" "
+ "}");
+}
+
+TEST_P(DescriptorDatabaseTest, ConflictingTypeError) {
+ AddToDatabase(
+ "name: \"foo.proto\" "
+ "message_type { "
+ " name: \"Foo\" "
+ "}");
+ AddToDatabaseWithError(
+ "name: \"bar.proto\" "
+ "message_type { "
+ " name: \"Foo\" "
+ "}");
+}
+
+TEST_P(DescriptorDatabaseTest, ConflictingExtensionError) {
+ AddToDatabase(
+ "name: \"foo.proto\" "
+ "extension { name:\"foo\" label:LABEL_OPTIONAL type:TYPE_INT32 number:5 "
+ " extendee: \".Foo\" }");
+ AddToDatabaseWithError(
+ "name: \"bar.proto\" "
+ "extension { name:\"bar\" label:LABEL_OPTIONAL type:TYPE_INT32 number:5 "
+ " extendee: \".Foo\" }");
+}
+
+INSTANTIATE_TEST_CASE_P(
+ Simple, DescriptorDatabaseTest,
+ testing::Values(&SimpleDescriptorDatabaseTestCase::New));
+INSTANTIATE_TEST_CASE_P(
+ MemoryConserving, DescriptorDatabaseTest,
+ testing::Values(&EncodedDescriptorDatabaseTestCase::New));
+INSTANTIATE_TEST_CASE_P(Pool, DescriptorDatabaseTest,
+ testing::Values(&DescriptorPoolDatabaseTestCase::New));
+
+#endif // GTEST_HAS_PARAM_TEST
+
+TEST(EncodedDescriptorDatabaseExtraTest, FindNameOfFileContainingSymbol) {
+ // Create two files, one of which is in two parts.
+ FileDescriptorProto file1, file2a, file2b;
+ file1.set_name("foo.proto");
+ file1.set_package("foo");
+ file1.add_message_type()->set_name("Foo");
+ file2a.set_name("bar.proto");
+ file2b.set_package("bar");
+ file2b.add_message_type()->set_name("Bar");
+
+ // Normal serialization allows our optimization to kick in.
+ std::string data1 = file1.SerializeAsString();
+
+ // Force out-of-order serialization to test slow path.
+ std::string data2 = file2b.SerializeAsString() + file2a.SerializeAsString();
+
+ // Create EncodedDescriptorDatabase containing both files.
+ EncodedDescriptorDatabase db;
+ db.Add(data1.data(), data1.size());
+ db.Add(data2.data(), data2.size());
+
+ // Test!
+ std::string filename;
+ EXPECT_TRUE(db.FindNameOfFileContainingSymbol("foo.Foo", &filename));
+ EXPECT_EQ("foo.proto", filename);
+ EXPECT_TRUE(db.FindNameOfFileContainingSymbol("foo.Foo.Blah", &filename));
+ EXPECT_EQ("foo.proto", filename);
+ EXPECT_TRUE(db.FindNameOfFileContainingSymbol("bar.Bar", &filename));
+ EXPECT_EQ("bar.proto", filename);
+ EXPECT_FALSE(db.FindNameOfFileContainingSymbol("foo", &filename));
+ EXPECT_FALSE(db.FindNameOfFileContainingSymbol("bar", &filename));
+ EXPECT_FALSE(db.FindNameOfFileContainingSymbol("baz.Baz", &filename));
+}
+
+TEST(SimpleDescriptorDatabaseExtraTest, FindAllFileNames) {
+ FileDescriptorProto f;
+ f.set_name("foo.proto");
+ f.set_package("foo");
+ f.add_message_type()->set_name("Foo");
+
+ SimpleDescriptorDatabase db;
+ db.Add(f);
+
+ // Test!
+ std::vector<std::string> all_files;
+ db.FindAllFileNames(&all_files);
+ EXPECT_THAT(all_files, testing::ElementsAre("foo.proto"));
+}
+
+TEST(SimpleDescriptorDatabaseExtraTest, FindAllPackageNames) {
+ FileDescriptorProto f;
+ f.set_name("foo.proto");
+ f.set_package("foo");
+ f.add_message_type()->set_name("Foo");
+
+ FileDescriptorProto b;
+ b.set_name("bar.proto");
+ b.set_package("");
+ b.add_message_type()->set_name("Bar");
+
+ SimpleDescriptorDatabase db;
+ db.Add(f);
+ db.Add(b);
+
+ std::vector<std::string> packages;
+ EXPECT_TRUE(db.FindAllPackageNames(&packages));
+ EXPECT_THAT(packages, ::testing::UnorderedElementsAre("foo", ""));
+}
+
+TEST(SimpleDescriptorDatabaseExtraTest, FindAllMessageNames) {
+ FileDescriptorProto f;
+ f.set_name("foo.proto");
+ f.set_package("foo");
+ f.add_message_type()->set_name("Foo");
+
+ FileDescriptorProto b;
+ b.set_name("bar.proto");
+ b.set_package("");
+ b.add_message_type()->set_name("Bar");
+
+ SimpleDescriptorDatabase db;
+ db.Add(f);
+ db.Add(b);
+
+ std::vector<std::string> messages;
+ EXPECT_TRUE(db.FindAllMessageNames(&messages));
+ EXPECT_THAT(messages, ::testing::UnorderedElementsAre("foo.Foo", "Bar"));
+}
+
+// ===================================================================
+
+class MergedDescriptorDatabaseTest : public testing::Test {
+ protected:
+ MergedDescriptorDatabaseTest()
+ : forward_merged_(&database1_, &database2_),
+ reverse_merged_(&database2_, &database1_) {}
+
+ virtual void SetUp() {
+ AddToDatabase(
+ &database1_,
+ "name: \"foo.proto\" "
+ "message_type { name:\"Foo\" extension_range { start: 1 end: 100 } } "
+ "extension { name:\"foo_ext\" extendee: \".Foo\" number:3 "
+ " label:LABEL_OPTIONAL type:TYPE_INT32 } ");
+ AddToDatabase(
+ &database2_,
+ "name: \"bar.proto\" "
+ "message_type { name:\"Bar\" extension_range { start: 1 end: 100 } } "
+ "extension { name:\"bar_ext\" extendee: \".Bar\" number:5 "
+ " label:LABEL_OPTIONAL type:TYPE_INT32 } ");
+
+ // baz.proto exists in both pools, with different definitions.
+ AddToDatabase(
+ &database1_,
+ "name: \"baz.proto\" "
+ "message_type { name:\"Baz\" extension_range { start: 1 end: 100 } } "
+ "message_type { name:\"FromPool1\" } "
+ "extension { name:\"baz_ext\" extendee: \".Baz\" number:12 "
+ " label:LABEL_OPTIONAL type:TYPE_INT32 } "
+ "extension { name:\"database1_only_ext\" extendee: \".Baz\" number:13 "
+ " label:LABEL_OPTIONAL type:TYPE_INT32 } ");
+ AddToDatabase(
+ &database2_,
+ "name: \"baz.proto\" "
+ "message_type { name:\"Baz\" extension_range { start: 1 end: 100 } } "
+ "message_type { name:\"FromPool2\" } "
+ "extension { name:\"baz_ext\" extendee: \".Baz\" number:12 "
+ " label:LABEL_OPTIONAL type:TYPE_INT32 } ");
+ }
+
+ SimpleDescriptorDatabase database1_;
+ SimpleDescriptorDatabase database2_;
+
+ MergedDescriptorDatabase forward_merged_;
+ MergedDescriptorDatabase reverse_merged_;
+};
+
+TEST_F(MergedDescriptorDatabaseTest, FindFileByName) {
+ {
+ // Can find file that is only in database1_.
+ FileDescriptorProto file;
+ EXPECT_TRUE(forward_merged_.FindFileByName("foo.proto", &file));
+ EXPECT_EQ("foo.proto", file.name());
+ ExpectContainsType(file, "Foo");
+ }
+
+ {
+ // Can find file that is only in database2_.
+ FileDescriptorProto file;
+ EXPECT_TRUE(forward_merged_.FindFileByName("bar.proto", &file));
+ EXPECT_EQ("bar.proto", file.name());
+ ExpectContainsType(file, "Bar");
+ }
+
+ {
+ // In forward_merged_, database1_'s baz.proto takes precedence.
+ FileDescriptorProto file;
+ EXPECT_TRUE(forward_merged_.FindFileByName("baz.proto", &file));
+ EXPECT_EQ("baz.proto", file.name());
+ ExpectContainsType(file, "FromPool1");
+ }
+
+ {
+ // In reverse_merged_, database2_'s baz.proto takes precedence.
+ FileDescriptorProto file;
+ EXPECT_TRUE(reverse_merged_.FindFileByName("baz.proto", &file));
+ EXPECT_EQ("baz.proto", file.name());
+ ExpectContainsType(file, "FromPool2");
+ }
+
+ {
+ // Can't find non-existent file.
+ FileDescriptorProto file;
+ EXPECT_FALSE(forward_merged_.FindFileByName("no_such.proto", &file));
+ }
+}
+
+TEST_F(MergedDescriptorDatabaseTest, FindFileContainingSymbol) {
+ {
+ // Can find file that is only in database1_.
+ FileDescriptorProto file;
+ EXPECT_TRUE(forward_merged_.FindFileContainingSymbol("Foo", &file));
+ EXPECT_EQ("foo.proto", file.name());
+ ExpectContainsType(file, "Foo");
+ }
+
+ {
+ // Can find file that is only in database2_.
+ FileDescriptorProto file;
+ EXPECT_TRUE(forward_merged_.FindFileContainingSymbol("Bar", &file));
+ EXPECT_EQ("bar.proto", file.name());
+ ExpectContainsType(file, "Bar");
+ }
+
+ {
+ // In forward_merged_, database1_'s baz.proto takes precedence.
+ FileDescriptorProto file;
+ EXPECT_TRUE(forward_merged_.FindFileContainingSymbol("Baz", &file));
+ EXPECT_EQ("baz.proto", file.name());
+ ExpectContainsType(file, "FromPool1");
+ }
+
+ {
+ // In reverse_merged_, database2_'s baz.proto takes precedence.
+ FileDescriptorProto file;
+ EXPECT_TRUE(reverse_merged_.FindFileContainingSymbol("Baz", &file));
+ EXPECT_EQ("baz.proto", file.name());
+ ExpectContainsType(file, "FromPool2");
+ }
+
+ {
+ // FromPool1 only shows up in forward_merged_ because it is masked by
+ // database2_'s baz.proto in reverse_merged_.
+ FileDescriptorProto file;
+ EXPECT_TRUE(forward_merged_.FindFileContainingSymbol("FromPool1", &file));
+ EXPECT_FALSE(reverse_merged_.FindFileContainingSymbol("FromPool1", &file));
+ }
+
+ {
+ // Can't find non-existent symbol.
+ FileDescriptorProto file;
+ EXPECT_FALSE(forward_merged_.FindFileContainingSymbol("NoSuchType", &file));
+ }
+}
+
+TEST_F(MergedDescriptorDatabaseTest, FindFileContainingExtension) {
+ {
+ // Can find file that is only in database1_.
+ FileDescriptorProto file;
+ EXPECT_TRUE(forward_merged_.FindFileContainingExtension("Foo", 3, &file));
+ EXPECT_EQ("foo.proto", file.name());
+ ExpectContainsType(file, "Foo");
+ }
+
+ {
+ // Can find file that is only in database2_.
+ FileDescriptorProto file;
+ EXPECT_TRUE(forward_merged_.FindFileContainingExtension("Bar", 5, &file));
+ EXPECT_EQ("bar.proto", file.name());
+ ExpectContainsType(file, "Bar");
+ }
+
+ {
+ // In forward_merged_, database1_'s baz.proto takes precedence.
+ FileDescriptorProto file;
+ EXPECT_TRUE(forward_merged_.FindFileContainingExtension("Baz", 12, &file));
+ EXPECT_EQ("baz.proto", file.name());
+ ExpectContainsType(file, "FromPool1");
+ }
+
+ {
+ // In reverse_merged_, database2_'s baz.proto takes precedence.
+ FileDescriptorProto file;
+ EXPECT_TRUE(reverse_merged_.FindFileContainingExtension("Baz", 12, &file));
+ EXPECT_EQ("baz.proto", file.name());
+ ExpectContainsType(file, "FromPool2");
+ }
+
+ {
+ // Baz's extension 13 only shows up in forward_merged_ because it is
+ // masked by database2_'s baz.proto in reverse_merged_.
+ FileDescriptorProto file;
+ EXPECT_TRUE(forward_merged_.FindFileContainingExtension("Baz", 13, &file));
+ EXPECT_FALSE(reverse_merged_.FindFileContainingExtension("Baz", 13, &file));
+ }
+
+ {
+ // Can't find non-existent extension.
+ FileDescriptorProto file;
+ EXPECT_FALSE(forward_merged_.FindFileContainingExtension("Foo", 6, &file));
+ }
+}
+
+TEST_F(MergedDescriptorDatabaseTest, FindAllExtensionNumbers) {
+ {
+ // Message only has extension in database1_
+ std::vector<int> numbers;
+ EXPECT_TRUE(forward_merged_.FindAllExtensionNumbers("Foo", &numbers));
+ ASSERT_EQ(1, numbers.size());
+ EXPECT_EQ(3, numbers[0]);
+ }
+
+ {
+ // Message only has extension in database2_
+ std::vector<int> numbers;
+ EXPECT_TRUE(forward_merged_.FindAllExtensionNumbers("Bar", &numbers));
+ ASSERT_EQ(1, numbers.size());
+ EXPECT_EQ(5, numbers[0]);
+ }
+
+ {
+ // Merge results from the two databases.
+ std::vector<int> numbers;
+ EXPECT_TRUE(forward_merged_.FindAllExtensionNumbers("Baz", &numbers));
+ ASSERT_EQ(2, numbers.size());
+ std::sort(numbers.begin(), numbers.end());
+ EXPECT_EQ(12, numbers[0]);
+ EXPECT_EQ(13, numbers[1]);
+ }
+
+ {
+ std::vector<int> numbers;
+ EXPECT_TRUE(reverse_merged_.FindAllExtensionNumbers("Baz", &numbers));
+ ASSERT_EQ(2, numbers.size());
+ std::sort(numbers.begin(), numbers.end());
+ EXPECT_EQ(12, numbers[0]);
+ EXPECT_EQ(13, numbers[1]);
+ }
+
+ {
+ // Can't find extensions for a non-existent message.
+ std::vector<int> numbers;
+ EXPECT_FALSE(reverse_merged_.FindAllExtensionNumbers("Blah", &numbers));
+ }
+}
+
+
+} // anonymous namespace
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/descriptor_unittest.cc b/NorthstarDedicatedTest/include/protobuf/descriptor_unittest.cc
new file mode 100644
index 00000000..be94e972
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/descriptor_unittest.cc
@@ -0,0 +1,8336 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 makes extensive use of RFC 3092. :)
+
+#include <limits>
+#include <memory>
+#include <vector>
+
+#include <any.pb.h>
+#include <compiler/importer.h>
+#include <compiler/parser.h>
+#include <unittest.pb.h>
+#include <unittest_custom_options.pb.h>
+#include <stubs/common.h>
+#include <stubs/logging.h>
+#include <stubs/stringprintf.h>
+#include <unittest_lazy_dependencies.pb.h>
+#include <unittest_proto3_arena.pb.h>
+#include <io/tokenizer.h>
+#include <io/zero_copy_stream_impl.h>
+#include <descriptor.pb.h>
+#include <descriptor.h>
+#include <descriptor_database.h>
+#include <dynamic_message.h>
+#include <text_format.h>
+#include <stubs/strutil.h>
+#include <gmock/gmock.h>
+#include <testing/googletest.h>
+#include <gtest/gtest.h>
+#include <stubs/logging.h>
+#include <stubs/substitute.h>
+
+
+#include <port_def.inc>
+
+namespace google {
+namespace protobuf {
+
+// Can't use an anonymous namespace here due to brokenness of Tru64 compiler.
+namespace descriptor_unittest {
+
+// Some helpers to make assembling descriptors faster.
+DescriptorProto* AddMessage(FileDescriptorProto* file,
+ const std::string& name) {
+ DescriptorProto* result = file->add_message_type();
+ result->set_name(name);
+ return result;
+}
+
+DescriptorProto* AddNestedMessage(DescriptorProto* parent,
+ const std::string& name) {
+ DescriptorProto* result = parent->add_nested_type();
+ result->set_name(name);
+ return result;
+}
+
+EnumDescriptorProto* AddEnum(FileDescriptorProto* file,
+ const std::string& name) {
+ EnumDescriptorProto* result = file->add_enum_type();
+ result->set_name(name);
+ return result;
+}
+
+EnumDescriptorProto* AddNestedEnum(DescriptorProto* parent,
+ const std::string& name) {
+ EnumDescriptorProto* result = parent->add_enum_type();
+ result->set_name(name);
+ return result;
+}
+
+ServiceDescriptorProto* AddService(FileDescriptorProto* file,
+ const std::string& name) {
+ ServiceDescriptorProto* result = file->add_service();
+ result->set_name(name);
+ return result;
+}
+
+FieldDescriptorProto* AddField(DescriptorProto* parent, const std::string& name,
+ int number, FieldDescriptorProto::Label label,
+ FieldDescriptorProto::Type type) {
+ FieldDescriptorProto* result = parent->add_field();
+ result->set_name(name);
+ result->set_number(number);
+ result->set_label(label);
+ result->set_type(type);
+ return result;
+}
+
+FieldDescriptorProto* AddExtension(FileDescriptorProto* file,
+ const std::string& extendee,
+ const std::string& name, int number,
+ FieldDescriptorProto::Label label,
+ FieldDescriptorProto::Type type) {
+ FieldDescriptorProto* result = file->add_extension();
+ result->set_name(name);
+ result->set_number(number);
+ result->set_label(label);
+ result->set_type(type);
+ result->set_extendee(extendee);
+ return result;
+}
+
+FieldDescriptorProto* AddNestedExtension(DescriptorProto* parent,
+ const std::string& extendee,
+ const std::string& name, int number,
+ FieldDescriptorProto::Label label,
+ FieldDescriptorProto::Type type) {
+ FieldDescriptorProto* result = parent->add_extension();
+ result->set_name(name);
+ result->set_number(number);
+ result->set_label(label);
+ result->set_type(type);
+ result->set_extendee(extendee);
+ return result;
+}
+
+DescriptorProto::ExtensionRange* AddExtensionRange(DescriptorProto* parent,
+ int start, int end) {
+ DescriptorProto::ExtensionRange* result = parent->add_extension_range();
+ result->set_start(start);
+ result->set_end(end);
+ return result;
+}
+
+DescriptorProto::ReservedRange* AddReservedRange(DescriptorProto* parent,
+ int start, int end) {
+ DescriptorProto::ReservedRange* result = parent->add_reserved_range();
+ result->set_start(start);
+ result->set_end(end);
+ return result;
+}
+
+EnumDescriptorProto::EnumReservedRange* AddReservedRange(
+ EnumDescriptorProto* parent, int start, int end) {
+ EnumDescriptorProto::EnumReservedRange* result = parent->add_reserved_range();
+ result->set_start(start);
+ result->set_end(end);
+ return result;
+}
+
+EnumValueDescriptorProto* AddEnumValue(EnumDescriptorProto* enum_proto,
+ const std::string& name, int number) {
+ EnumValueDescriptorProto* result = enum_proto->add_value();
+ result->set_name(name);
+ result->set_number(number);
+ return result;
+}
+
+MethodDescriptorProto* AddMethod(ServiceDescriptorProto* service,
+ const std::string& name,
+ const std::string& input_type,
+ const std::string& output_type) {
+ MethodDescriptorProto* result = service->add_method();
+ result->set_name(name);
+ result->set_input_type(input_type);
+ result->set_output_type(output_type);
+ return result;
+}
+
+// Empty enums technically aren't allowed. We need to insert a dummy value
+// into them.
+void AddEmptyEnum(FileDescriptorProto* file, const std::string& name) {
+ AddEnumValue(AddEnum(file, name), name + "_DUMMY", 1);
+}
+
+class MockErrorCollector : public DescriptorPool::ErrorCollector {
+ public:
+ MockErrorCollector() {}
+ ~MockErrorCollector() {}
+
+ std::string text_;
+ std::string warning_text_;
+
+ // implements ErrorCollector ---------------------------------------
+ void AddError(const std::string& filename, const std::string& element_name,
+ const Message* descriptor, ErrorLocation location,
+ const std::string& message) override {
+ const char* location_name = nullptr;
+ switch (location) {
+ case NAME:
+ location_name = "NAME";
+ break;
+ case NUMBER:
+ location_name = "NUMBER";
+ break;
+ case TYPE:
+ location_name = "TYPE";
+ break;
+ case EXTENDEE:
+ location_name = "EXTENDEE";
+ break;
+ case DEFAULT_VALUE:
+ location_name = "DEFAULT_VALUE";
+ break;
+ case OPTION_NAME:
+ location_name = "OPTION_NAME";
+ break;
+ case OPTION_VALUE:
+ location_name = "OPTION_VALUE";
+ break;
+ case INPUT_TYPE:
+ location_name = "INPUT_TYPE";
+ break;
+ case OUTPUT_TYPE:
+ location_name = "OUTPUT_TYPE";
+ break;
+ case IMPORT:
+ location_name = "IMPORT";
+ break;
+ case OTHER:
+ location_name = "OTHER";
+ break;
+ }
+
+ strings::SubstituteAndAppend(&text_, "$0: $1: $2: $3\n", filename,
+ element_name, location_name, message);
+ }
+
+ // implements ErrorCollector ---------------------------------------
+ void AddWarning(const std::string& filename, const std::string& element_name,
+ const Message* descriptor, ErrorLocation location,
+ const std::string& message) override {
+ const char* location_name = nullptr;
+ switch (location) {
+ case NAME:
+ location_name = "NAME";
+ break;
+ case NUMBER:
+ location_name = "NUMBER";
+ break;
+ case TYPE:
+ location_name = "TYPE";
+ break;
+ case EXTENDEE:
+ location_name = "EXTENDEE";
+ break;
+ case DEFAULT_VALUE:
+ location_name = "DEFAULT_VALUE";
+ break;
+ case OPTION_NAME:
+ location_name = "OPTION_NAME";
+ break;
+ case OPTION_VALUE:
+ location_name = "OPTION_VALUE";
+ break;
+ case INPUT_TYPE:
+ location_name = "INPUT_TYPE";
+ break;
+ case OUTPUT_TYPE:
+ location_name = "OUTPUT_TYPE";
+ break;
+ case IMPORT:
+ location_name = "IMPORT";
+ break;
+ case OTHER:
+ location_name = "OTHER";
+ break;
+ }
+
+ strings::SubstituteAndAppend(&warning_text_, "$0: $1: $2: $3\n", filename,
+ element_name, location_name, message);
+ }
+};
+
+// ===================================================================
+
+// Test simple files.
+class FileDescriptorTest : public testing::Test {
+ protected:
+ void SetUp() override {
+ // Build descriptors for the following definitions:
+ //
+ // // in "foo.proto"
+ // message FooMessage { extensions 1; }
+ // enum FooEnum {FOO_ENUM_VALUE = 1;}
+ // service FooService {}
+ // extend FooMessage { optional int32 foo_extension = 1; }
+ //
+ // // in "bar.proto"
+ // package bar_package;
+ // message BarMessage { extensions 1; }
+ // enum BarEnum {BAR_ENUM_VALUE = 1;}
+ // service BarService {}
+ // extend BarMessage { optional int32 bar_extension = 1; }
+ //
+ // Also, we have an empty file "baz.proto". This file's purpose is to
+ // make sure that even though it has the same package as foo.proto,
+ // searching it for members of foo.proto won't work.
+
+ FileDescriptorProto foo_file;
+ foo_file.set_name("foo.proto");
+ AddExtensionRange(AddMessage(&foo_file, "FooMessage"), 1, 2);
+ AddEnumValue(AddEnum(&foo_file, "FooEnum"), "FOO_ENUM_VALUE", 1);
+ AddService(&foo_file, "FooService");
+ AddExtension(&foo_file, "FooMessage", "foo_extension", 1,
+ FieldDescriptorProto::LABEL_OPTIONAL,
+ FieldDescriptorProto::TYPE_INT32);
+
+ FileDescriptorProto bar_file;
+ bar_file.set_name("bar.proto");
+ bar_file.set_package("bar_package");
+ bar_file.add_dependency("foo.proto");
+ AddExtensionRange(AddMessage(&bar_file, "BarMessage"), 1, 2);
+ AddEnumValue(AddEnum(&bar_file, "BarEnum"), "BAR_ENUM_VALUE", 1);
+ AddService(&bar_file, "BarService");
+ AddExtension(&bar_file, "bar_package.BarMessage", "bar_extension", 1,
+ FieldDescriptorProto::LABEL_OPTIONAL,
+ FieldDescriptorProto::TYPE_INT32);
+
+ FileDescriptorProto baz_file;
+ baz_file.set_name("baz.proto");
+
+ // Build the descriptors and get the pointers.
+ foo_file_ = pool_.BuildFile(foo_file);
+ ASSERT_TRUE(foo_file_ != nullptr);
+
+ bar_file_ = pool_.BuildFile(bar_file);
+ ASSERT_TRUE(bar_file_ != nullptr);
+
+ baz_file_ = pool_.BuildFile(baz_file);
+ ASSERT_TRUE(baz_file_ != nullptr);
+
+ ASSERT_EQ(1, foo_file_->message_type_count());
+ foo_message_ = foo_file_->message_type(0);
+ ASSERT_EQ(1, foo_file_->enum_type_count());
+ foo_enum_ = foo_file_->enum_type(0);
+ ASSERT_EQ(1, foo_enum_->value_count());
+ foo_enum_value_ = foo_enum_->value(0);
+ ASSERT_EQ(1, foo_file_->service_count());
+ foo_service_ = foo_file_->service(0);
+ ASSERT_EQ(1, foo_file_->extension_count());
+ foo_extension_ = foo_file_->extension(0);
+
+ ASSERT_EQ(1, bar_file_->message_type_count());
+ bar_message_ = bar_file_->message_type(0);
+ ASSERT_EQ(1, bar_file_->enum_type_count());
+ bar_enum_ = bar_file_->enum_type(0);
+ ASSERT_EQ(1, bar_enum_->value_count());
+ bar_enum_value_ = bar_enum_->value(0);
+ ASSERT_EQ(1, bar_file_->service_count());
+ bar_service_ = bar_file_->service(0);
+ ASSERT_EQ(1, bar_file_->extension_count());
+ bar_extension_ = bar_file_->extension(0);
+ }
+
+ DescriptorPool pool_;
+
+ const FileDescriptor* foo_file_;
+ const FileDescriptor* bar_file_;
+ const FileDescriptor* baz_file_;
+
+ const Descriptor* foo_message_;
+ const EnumDescriptor* foo_enum_;
+ const EnumValueDescriptor* foo_enum_value_;
+ const ServiceDescriptor* foo_service_;
+ const FieldDescriptor* foo_extension_;
+
+ const Descriptor* bar_message_;
+ const EnumDescriptor* bar_enum_;
+ const EnumValueDescriptor* bar_enum_value_;
+ const ServiceDescriptor* bar_service_;
+ const FieldDescriptor* bar_extension_;
+};
+
+TEST_F(FileDescriptorTest, Name) {
+ EXPECT_EQ("foo.proto", foo_file_->name());
+ EXPECT_EQ("bar.proto", bar_file_->name());
+ EXPECT_EQ("baz.proto", baz_file_->name());
+}
+
+TEST_F(FileDescriptorTest, Package) {
+ EXPECT_EQ("", foo_file_->package());
+ EXPECT_EQ("bar_package", bar_file_->package());
+}
+
+TEST_F(FileDescriptorTest, Dependencies) {
+ EXPECT_EQ(0, foo_file_->dependency_count());
+ EXPECT_EQ(1, bar_file_->dependency_count());
+ EXPECT_EQ(foo_file_, bar_file_->dependency(0));
+}
+
+TEST_F(FileDescriptorTest, FindMessageTypeByName) {
+ EXPECT_EQ(foo_message_, foo_file_->FindMessageTypeByName("FooMessage"));
+ EXPECT_EQ(bar_message_, bar_file_->FindMessageTypeByName("BarMessage"));
+
+ EXPECT_TRUE(foo_file_->FindMessageTypeByName("BarMessage") == nullptr);
+ EXPECT_TRUE(bar_file_->FindMessageTypeByName("FooMessage") == nullptr);
+ EXPECT_TRUE(baz_file_->FindMessageTypeByName("FooMessage") == nullptr);
+
+ EXPECT_TRUE(foo_file_->FindMessageTypeByName("NoSuchMessage") == nullptr);
+ EXPECT_TRUE(foo_file_->FindMessageTypeByName("FooEnum") == nullptr);
+}
+
+TEST_F(FileDescriptorTest, FindEnumTypeByName) {
+ EXPECT_EQ(foo_enum_, foo_file_->FindEnumTypeByName("FooEnum"));
+ EXPECT_EQ(bar_enum_, bar_file_->FindEnumTypeByName("BarEnum"));
+
+ EXPECT_TRUE(foo_file_->FindEnumTypeByName("BarEnum") == nullptr);
+ EXPECT_TRUE(bar_file_->FindEnumTypeByName("FooEnum") == nullptr);
+ EXPECT_TRUE(baz_file_->FindEnumTypeByName("FooEnum") == nullptr);
+
+ EXPECT_TRUE(foo_file_->FindEnumTypeByName("NoSuchEnum") == nullptr);
+ EXPECT_TRUE(foo_file_->FindEnumTypeByName("FooMessage") == nullptr);
+}
+
+TEST_F(FileDescriptorTest, FindEnumValueByName) {
+ EXPECT_EQ(foo_enum_value_, foo_file_->FindEnumValueByName("FOO_ENUM_VALUE"));
+ EXPECT_EQ(bar_enum_value_, bar_file_->FindEnumValueByName("BAR_ENUM_VALUE"));
+
+ EXPECT_TRUE(foo_file_->FindEnumValueByName("BAR_ENUM_VALUE") == nullptr);
+ EXPECT_TRUE(bar_file_->FindEnumValueByName("FOO_ENUM_VALUE") == nullptr);
+ EXPECT_TRUE(baz_file_->FindEnumValueByName("FOO_ENUM_VALUE") == nullptr);
+
+ EXPECT_TRUE(foo_file_->FindEnumValueByName("NO_SUCH_VALUE") == nullptr);
+ EXPECT_TRUE(foo_file_->FindEnumValueByName("FooMessage") == nullptr);
+}
+
+TEST_F(FileDescriptorTest, FindServiceByName) {
+ EXPECT_EQ(foo_service_, foo_file_->FindServiceByName("FooService"));
+ EXPECT_EQ(bar_service_, bar_file_->FindServiceByName("BarService"));
+
+ EXPECT_TRUE(foo_file_->FindServiceByName("BarService") == nullptr);
+ EXPECT_TRUE(bar_file_->FindServiceByName("FooService") == nullptr);
+ EXPECT_TRUE(baz_file_->FindServiceByName("FooService") == nullptr);
+
+ EXPECT_TRUE(foo_file_->FindServiceByName("NoSuchService") == nullptr);
+ EXPECT_TRUE(foo_file_->FindServiceByName("FooMessage") == nullptr);
+}
+
+TEST_F(FileDescriptorTest, FindExtensionByName) {
+ EXPECT_EQ(foo_extension_, foo_file_->FindExtensionByName("foo_extension"));
+ EXPECT_EQ(bar_extension_, bar_file_->FindExtensionByName("bar_extension"));
+
+ EXPECT_TRUE(foo_file_->FindExtensionByName("bar_extension") == nullptr);
+ EXPECT_TRUE(bar_file_->FindExtensionByName("foo_extension") == nullptr);
+ EXPECT_TRUE(baz_file_->FindExtensionByName("foo_extension") == nullptr);
+
+ EXPECT_TRUE(foo_file_->FindExtensionByName("no_such_extension") == nullptr);
+ EXPECT_TRUE(foo_file_->FindExtensionByName("FooMessage") == nullptr);
+}
+
+TEST_F(FileDescriptorTest, FindExtensionByNumber) {
+ EXPECT_EQ(foo_extension_, pool_.FindExtensionByNumber(foo_message_, 1));
+ EXPECT_EQ(bar_extension_, pool_.FindExtensionByNumber(bar_message_, 1));
+
+ EXPECT_TRUE(pool_.FindExtensionByNumber(foo_message_, 2) == nullptr);
+}
+
+
+TEST_F(FileDescriptorTest, BuildAgain) {
+ // Test that if we call BuildFile again on the same input we get the same
+ // FileDescriptor back.
+ FileDescriptorProto file;
+ foo_file_->CopyTo(&file);
+ EXPECT_EQ(foo_file_, pool_.BuildFile(file));
+
+ // But if we change the file then it won't work.
+ file.set_package("some.other.package");
+ EXPECT_TRUE(pool_.BuildFile(file) == nullptr);
+}
+
+TEST_F(FileDescriptorTest, BuildAgainWithSyntax) {
+ // Test that if we call BuildFile again on the same input we get the same
+ // FileDescriptor back even if syntax param is specified.
+ FileDescriptorProto proto_syntax2;
+ proto_syntax2.set_name("foo_syntax2");
+ proto_syntax2.set_syntax("proto2");
+
+ const FileDescriptor* proto2_descriptor = pool_.BuildFile(proto_syntax2);
+ EXPECT_TRUE(proto2_descriptor != nullptr);
+ EXPECT_EQ(proto2_descriptor, pool_.BuildFile(proto_syntax2));
+
+ FileDescriptorProto implicit_proto2;
+ implicit_proto2.set_name("foo_implicit_syntax2");
+
+ const FileDescriptor* implicit_proto2_descriptor =
+ pool_.BuildFile(implicit_proto2);
+ EXPECT_TRUE(implicit_proto2_descriptor != nullptr);
+ // We get the same FileDescriptor back if syntax param is explicitly
+ // specified.
+ implicit_proto2.set_syntax("proto2");
+ EXPECT_EQ(implicit_proto2_descriptor, pool_.BuildFile(implicit_proto2));
+
+ FileDescriptorProto proto_syntax3;
+ proto_syntax3.set_name("foo_syntax3");
+ proto_syntax3.set_syntax("proto3");
+
+ const FileDescriptor* proto3_descriptor = pool_.BuildFile(proto_syntax3);
+ EXPECT_TRUE(proto3_descriptor != nullptr);
+ EXPECT_EQ(proto3_descriptor, pool_.BuildFile(proto_syntax3));
+}
+
+TEST_F(FileDescriptorTest, Syntax) {
+ FileDescriptorProto proto;
+ proto.set_name("foo");
+ // Enable the test when we also populate the syntax for proto2.
+#if 0
+ {
+ proto.set_syntax("proto2");
+ DescriptorPool pool;
+ const FileDescriptor* file = pool.BuildFile(proto);
+ EXPECT_TRUE(file != nullptr);
+ EXPECT_EQ(FileDescriptor::SYNTAX_PROTO2, file->syntax());
+ FileDescriptorProto other;
+ file->CopyTo(&other);
+ EXPECT_EQ("proto2", other.syntax());
+ }
+#endif
+ {
+ proto.set_syntax("proto3");
+ DescriptorPool pool;
+ const FileDescriptor* file = pool.BuildFile(proto);
+ EXPECT_TRUE(file != nullptr);
+ EXPECT_EQ(FileDescriptor::SYNTAX_PROTO3, file->syntax());
+ FileDescriptorProto other;
+ file->CopyTo(&other);
+ EXPECT_EQ("proto3", other.syntax());
+ }
+}
+
+void ExtractDebugString(
+ const FileDescriptor* file, std::set<std::string>* visited,
+ std::vector<std::pair<std::string, std::string>>* debug_strings) {
+ if (!visited->insert(file->name()).second) {
+ return;
+ }
+ for (int i = 0; i < file->dependency_count(); ++i) {
+ ExtractDebugString(file->dependency(i), visited, debug_strings);
+ }
+ debug_strings->push_back(std::make_pair(file->name(), file->DebugString()));
+}
+
+class SimpleErrorCollector : public io::ErrorCollector {
+ public:
+ // implements ErrorCollector ---------------------------------------
+ void AddError(int line, int column, const std::string& message) override {
+ last_error_ = StringPrintf("%d:%d:", line, column) + message;
+ }
+
+ const std::string& last_error() { return last_error_; }
+
+ private:
+ std::string last_error_;
+};
+// Test that the result of FileDescriptor::DebugString() can be used to create
+// the original descriptors.
+TEST_F(FileDescriptorTest, DebugStringRoundTrip) {
+ std::set<std::string> visited;
+ std::vector<std::pair<std::string, std::string>> debug_strings;
+ ExtractDebugString(protobuf_unittest::TestAllTypes::descriptor()->file(),
+ &visited, &debug_strings);
+ ExtractDebugString(
+ protobuf_unittest::TestMessageWithCustomOptions::descriptor()->file(),
+ &visited, &debug_strings);
+ ExtractDebugString(proto3_arena_unittest::TestAllTypes::descriptor()->file(),
+ &visited, &debug_strings);
+ ASSERT_GE(debug_strings.size(), 3);
+
+ DescriptorPool pool;
+ for (int i = 0; i < debug_strings.size(); ++i) {
+ const std::string& name = debug_strings[i].first;
+ const std::string& content = debug_strings[i].second;
+ io::ArrayInputStream input_stream(content.data(), content.size());
+ SimpleErrorCollector error_collector;
+ io::Tokenizer tokenizer(&input_stream, &error_collector);
+ compiler::Parser parser;
+ parser.RecordErrorsTo(&error_collector);
+ FileDescriptorProto proto;
+ ASSERT_TRUE(parser.Parse(&tokenizer, &proto))
+ << error_collector.last_error() << "\n"
+ << content;
+ ASSERT_EQ("", error_collector.last_error());
+ proto.set_name(name);
+ const FileDescriptor* descriptor = pool.BuildFile(proto);
+ ASSERT_TRUE(descriptor != nullptr) << proto.DebugString();
+ EXPECT_EQ(content, descriptor->DebugString());
+ }
+}
+
+// ===================================================================
+
+// Test simple flat messages and fields.
+class DescriptorTest : public testing::Test {
+ protected:
+ void SetUp() override {
+ // Build descriptors for the following definitions:
+ //
+ // // in "foo.proto"
+ // message TestForeign {}
+ // enum TestEnum {}
+ //
+ // message TestMessage {
+ // required string foo = 1;
+ // optional TestEnum bar = 6;
+ // repeated TestForeign baz = 500000000;
+ // optional group qux = 15 {}
+ // }
+ //
+ // // in "bar.proto"
+ // package corge.grault;
+ // message TestMessage2 {
+ // required string foo = 1;
+ // required string bar = 2;
+ // required string quux = 6;
+ // }
+ //
+ // // in "map.proto"
+ // message TestMessage3 {
+ // map<int32, int32> map_int32_int32 = 1;
+ // }
+ //
+ // // in "json.proto"
+ // message TestMessage4 {
+ // optional int32 field_name1 = 1;
+ // optional int32 fieldName2 = 2;
+ // optional int32 FieldName3 = 3;
+ // optional int32 _field_name4 = 4;
+ // optional int32 FIELD_NAME5 = 5;
+ // optional int32 field_name6 = 6 [json_name = "@type"];
+ // }
+ //
+ // We cheat and use TestForeign as the type for qux rather than create
+ // an actual nested type.
+ //
+ // Since all primitive types (including string) use the same building
+ // code, there's no need to test each one individually.
+ //
+ // TestMessage2 is primarily here to test FindFieldByName and friends.
+ // All messages created from the same DescriptorPool share the same lookup
+ // table, so we need to insure that they don't interfere.
+
+ FileDescriptorProto foo_file;
+ foo_file.set_name("foo.proto");
+ AddMessage(&foo_file, "TestForeign");
+ AddEmptyEnum(&foo_file, "TestEnum");
+
+ DescriptorProto* message = AddMessage(&foo_file, "TestMessage");
+ AddField(message, "foo", 1, FieldDescriptorProto::LABEL_REQUIRED,
+ FieldDescriptorProto::TYPE_STRING);
+ AddField(message, "bar", 6, FieldDescriptorProto::LABEL_OPTIONAL,
+ FieldDescriptorProto::TYPE_ENUM)
+ ->set_type_name("TestEnum");
+ AddField(message, "baz", 500000000, FieldDescriptorProto::LABEL_REPEATED,
+ FieldDescriptorProto::TYPE_MESSAGE)
+ ->set_type_name("TestForeign");
+ AddField(message, "qux", 15, FieldDescriptorProto::LABEL_OPTIONAL,
+ FieldDescriptorProto::TYPE_GROUP)
+ ->set_type_name("TestForeign");
+
+ FileDescriptorProto bar_file;
+ bar_file.set_name("bar.proto");
+ bar_file.set_package("corge.grault");
+
+ DescriptorProto* message2 = AddMessage(&bar_file, "TestMessage2");
+ AddField(message2, "foo", 1, FieldDescriptorProto::LABEL_REQUIRED,
+ FieldDescriptorProto::TYPE_STRING);
+ AddField(message2, "bar", 2, FieldDescriptorProto::LABEL_REQUIRED,
+ FieldDescriptorProto::TYPE_STRING);
+ AddField(message2, "quux", 6, FieldDescriptorProto::LABEL_REQUIRED,
+ FieldDescriptorProto::TYPE_STRING);
+
+ FileDescriptorProto map_file;
+ map_file.set_name("map.proto");
+ DescriptorProto* message3 = AddMessage(&map_file, "TestMessage3");
+
+ DescriptorProto* entry = AddNestedMessage(message3, "MapInt32Int32Entry");
+ AddField(entry, "key", 1, FieldDescriptorProto::LABEL_OPTIONAL,
+ FieldDescriptorProto::TYPE_INT32);
+ AddField(entry, "value", 2, FieldDescriptorProto::LABEL_OPTIONAL,
+ FieldDescriptorProto::TYPE_INT32);
+ entry->mutable_options()->set_map_entry(true);
+
+ AddField(message3, "map_int32_int32", 1,
+ FieldDescriptorProto::LABEL_REPEATED,
+ FieldDescriptorProto::TYPE_MESSAGE)
+ ->set_type_name("MapInt32Int32Entry");
+
+ FileDescriptorProto json_file;
+ json_file.set_name("json.proto");
+ json_file.set_syntax("proto3");
+ DescriptorProto* message4 = AddMessage(&json_file, "TestMessage4");
+ AddField(message4, "field_name1", 1, FieldDescriptorProto::LABEL_OPTIONAL,
+ FieldDescriptorProto::TYPE_INT32);
+ AddField(message4, "fieldName2", 2, FieldDescriptorProto::LABEL_OPTIONAL,
+ FieldDescriptorProto::TYPE_INT32);
+ AddField(message4, "FieldName3", 3, FieldDescriptorProto::LABEL_OPTIONAL,
+ FieldDescriptorProto::TYPE_INT32);
+ AddField(message4, "_field_name4", 4, FieldDescriptorProto::LABEL_OPTIONAL,
+ FieldDescriptorProto::TYPE_INT32);
+ AddField(message4, "FIELD_NAME5", 5, FieldDescriptorProto::LABEL_OPTIONAL,
+ FieldDescriptorProto::TYPE_INT32);
+ AddField(message4, "field_name6", 6, FieldDescriptorProto::LABEL_OPTIONAL,
+ FieldDescriptorProto::TYPE_INT32)
+ ->set_json_name("@type");
+ AddField(message4, "fieldname7", 7, FieldDescriptorProto::LABEL_OPTIONAL,
+ FieldDescriptorProto::TYPE_INT32);
+
+ // Build the descriptors and get the pointers.
+ foo_file_ = pool_.BuildFile(foo_file);
+ ASSERT_TRUE(foo_file_ != nullptr);
+
+ bar_file_ = pool_.BuildFile(bar_file);
+ ASSERT_TRUE(bar_file_ != nullptr);
+
+ map_file_ = pool_.BuildFile(map_file);
+ ASSERT_TRUE(map_file_ != nullptr);
+
+ json_file_ = pool_.BuildFile(json_file);
+ ASSERT_TRUE(json_file_ != nullptr);
+
+ ASSERT_EQ(1, foo_file_->enum_type_count());
+ enum_ = foo_file_->enum_type(0);
+
+ ASSERT_EQ(2, foo_file_->message_type_count());
+ foreign_ = foo_file_->message_type(0);
+ message_ = foo_file_->message_type(1);
+
+ ASSERT_EQ(4, message_->field_count());
+ foo_ = message_->field(0);
+ bar_ = message_->field(1);
+ baz_ = message_->field(2);
+ qux_ = message_->field(3);
+
+ ASSERT_EQ(1, bar_file_->message_type_count());
+ message2_ = bar_file_->message_type(0);
+
+ ASSERT_EQ(3, message2_->field_count());
+ foo2_ = message2_->field(0);
+ bar2_ = message2_->field(1);
+ quux2_ = message2_->field(2);
+
+ ASSERT_EQ(1, map_file_->message_type_count());
+ message3_ = map_file_->message_type(0);
+
+ ASSERT_EQ(1, message3_->field_count());
+ map_ = message3_->field(0);
+
+ ASSERT_EQ(1, json_file_->message_type_count());
+ message4_ = json_file_->message_type(0);
+ }
+
+ void CopyWithJsonName(const Descriptor* message, DescriptorProto* proto) {
+ message->CopyTo(proto);
+ message->CopyJsonNameTo(proto);
+ }
+
+ const EnumValueDescriptor* FindValueByNumberCreatingIfUnknown(
+ const EnumDescriptor* desc, int number) {
+ return desc->FindValueByNumberCreatingIfUnknown(number);
+ }
+
+ DescriptorPool pool_;
+
+ const FileDescriptor* foo_file_;
+ const FileDescriptor* bar_file_;
+ const FileDescriptor* map_file_;
+ const FileDescriptor* json_file_;
+
+ const Descriptor* message_;
+ const Descriptor* message2_;
+ const Descriptor* message3_;
+ const Descriptor* message4_;
+ const Descriptor* foreign_;
+ const EnumDescriptor* enum_;
+
+ const FieldDescriptor* foo_;
+ const FieldDescriptor* bar_;
+ const FieldDescriptor* baz_;
+ const FieldDescriptor* qux_;
+
+ const FieldDescriptor* foo2_;
+ const FieldDescriptor* bar2_;
+ const FieldDescriptor* quux2_;
+
+ const FieldDescriptor* map_;
+};
+
+TEST_F(DescriptorTest, Name) {
+ EXPECT_EQ("TestMessage", message_->name());
+ EXPECT_EQ("TestMessage", message_->full_name());
+ EXPECT_EQ(foo_file_, message_->file());
+
+ EXPECT_EQ("TestMessage2", message2_->name());
+ EXPECT_EQ("corge.grault.TestMessage2", message2_->full_name());
+ EXPECT_EQ(bar_file_, message2_->file());
+}
+
+TEST_F(DescriptorTest, ContainingType) {
+ EXPECT_TRUE(message_->containing_type() == nullptr);
+ EXPECT_TRUE(message2_->containing_type() == nullptr);
+}
+
+TEST_F(DescriptorTest, FieldNamesDedup) {
+ const auto collect_unique_names = [](const FieldDescriptor* field) {
+ std::set<std::string> names{field->name(), field->lowercase_name(),
+ field->camelcase_name(), field->json_name()};
+ // Verify that we have the same number of string objects as we have string
+ // values. That is, duplicate names use the same std::string object.
+ // This is for memory efficiency.
+ EXPECT_EQ(names.size(), (std::set<const std::string*>{
+ &field->name(), &field->lowercase_name(),
+ &field->camelcase_name(), &field->json_name()}
+ .size()))
+ << testing::PrintToString(names);
+ return names;
+ };
+
+ using testing::ElementsAre;
+ // field_name1
+ EXPECT_THAT(collect_unique_names(message4_->field(0)),
+ ElementsAre("fieldName1", "field_name1"));
+ // fieldName2
+ EXPECT_THAT(collect_unique_names(message4_->field(1)),
+ ElementsAre("fieldName2", "fieldname2"));
+ // FieldName3
+ EXPECT_THAT(collect_unique_names(message4_->field(2)),
+ ElementsAre("FieldName3", "fieldName3", "fieldname3"));
+ // _field_name4
+ EXPECT_THAT(collect_unique_names(message4_->field(3)),
+ ElementsAre("FieldName4", "_field_name4", "fieldName4"));
+ // FIELD_NAME5
+ EXPECT_THAT(
+ collect_unique_names(message4_->field(4)),
+ ElementsAre("FIELDNAME5", "FIELD_NAME5", "fIELDNAME5", "field_name5"));
+ // field_name6, with json name @type
+ EXPECT_THAT(collect_unique_names(message4_->field(5)),
+ ElementsAre("@type", "fieldName6", "field_name6"));
+ // fieldname7
+ EXPECT_THAT(collect_unique_names(message4_->field(6)),
+ ElementsAre("fieldname7"));
+}
+
+TEST_F(DescriptorTest, FieldsByIndex) {
+ ASSERT_EQ(4, message_->field_count());
+ EXPECT_EQ(foo_, message_->field(0));
+ EXPECT_EQ(bar_, message_->field(1));
+ EXPECT_EQ(baz_, message_->field(2));
+ EXPECT_EQ(qux_, message_->field(3));
+}
+
+TEST_F(DescriptorTest, FindFieldByName) {
+ // All messages in the same DescriptorPool share a single lookup table for
+ // fields. So, in addition to testing that FindFieldByName finds the fields
+ // of the message, we need to test that it does *not* find the fields of
+ // *other* messages.
+
+ EXPECT_EQ(foo_, message_->FindFieldByName("foo"));
+ EXPECT_EQ(bar_, message_->FindFieldByName("bar"));
+ EXPECT_EQ(baz_, message_->FindFieldByName("baz"));
+ EXPECT_EQ(qux_, message_->FindFieldByName("qux"));
+ EXPECT_TRUE(message_->FindFieldByName("no_such_field") == nullptr);
+ EXPECT_TRUE(message_->FindFieldByName("quux") == nullptr);
+
+ EXPECT_EQ(foo2_, message2_->FindFieldByName("foo"));
+ EXPECT_EQ(bar2_, message2_->FindFieldByName("bar"));
+ EXPECT_EQ(quux2_, message2_->FindFieldByName("quux"));
+ EXPECT_TRUE(message2_->FindFieldByName("baz") == nullptr);
+ EXPECT_TRUE(message2_->FindFieldByName("qux") == nullptr);
+}
+
+TEST_F(DescriptorTest, FindFieldByNumber) {
+ EXPECT_EQ(foo_, message_->FindFieldByNumber(1));
+ EXPECT_EQ(bar_, message_->FindFieldByNumber(6));
+ EXPECT_EQ(baz_, message_->FindFieldByNumber(500000000));
+ EXPECT_EQ(qux_, message_->FindFieldByNumber(15));
+ EXPECT_TRUE(message_->FindFieldByNumber(837592) == nullptr);
+ EXPECT_TRUE(message_->FindFieldByNumber(2) == nullptr);
+
+ EXPECT_EQ(foo2_, message2_->FindFieldByNumber(1));
+ EXPECT_EQ(bar2_, message2_->FindFieldByNumber(2));
+ EXPECT_EQ(quux2_, message2_->FindFieldByNumber(6));
+ EXPECT_TRUE(message2_->FindFieldByNumber(15) == nullptr);
+ EXPECT_TRUE(message2_->FindFieldByNumber(500000000) == nullptr);
+}
+
+TEST_F(DescriptorTest, FieldName) {
+ EXPECT_EQ("foo", foo_->name());
+ EXPECT_EQ("bar", bar_->name());
+ EXPECT_EQ("baz", baz_->name());
+ EXPECT_EQ("qux", qux_->name());
+}
+
+TEST_F(DescriptorTest, FieldFullName) {
+ EXPECT_EQ("TestMessage.foo", foo_->full_name());
+ EXPECT_EQ("TestMessage.bar", bar_->full_name());
+ EXPECT_EQ("TestMessage.baz", baz_->full_name());
+ EXPECT_EQ("TestMessage.qux", qux_->full_name());
+
+ EXPECT_EQ("corge.grault.TestMessage2.foo", foo2_->full_name());
+ EXPECT_EQ("corge.grault.TestMessage2.bar", bar2_->full_name());
+ EXPECT_EQ("corge.grault.TestMessage2.quux", quux2_->full_name());
+}
+
+TEST_F(DescriptorTest, PrintableNameIsFullNameForNonExtensionFields) {
+ EXPECT_EQ("TestMessage.foo", foo_->PrintableNameForExtension());
+ EXPECT_EQ("TestMessage.bar", bar_->PrintableNameForExtension());
+ EXPECT_EQ("TestMessage.baz", baz_->PrintableNameForExtension());
+ EXPECT_EQ("TestMessage.qux", qux_->PrintableNameForExtension());
+
+ EXPECT_EQ("corge.grault.TestMessage2.foo",
+ foo2_->PrintableNameForExtension());
+ EXPECT_EQ("corge.grault.TestMessage2.bar",
+ bar2_->PrintableNameForExtension());
+ EXPECT_EQ("corge.grault.TestMessage2.quux",
+ quux2_->PrintableNameForExtension());
+}
+
+TEST_F(DescriptorTest, PrintableNameIsFullNameForNonMessageSetExtension) {
+ EXPECT_EQ("protobuf_unittest.Aggregate.nested",
+ protobuf_unittest::Aggregate::descriptor()
+ ->FindExtensionByName("nested")
+ ->PrintableNameForExtension());
+}
+
+TEST_F(DescriptorTest, PrintableNameIsExtendingTypeForMessageSetExtension) {
+ EXPECT_EQ("protobuf_unittest.AggregateMessageSetElement",
+ protobuf_unittest::AggregateMessageSetElement::descriptor()
+ ->FindExtensionByName("message_set_extension")
+ ->PrintableNameForExtension());
+}
+
+TEST_F(DescriptorTest, FieldJsonName) {
+ EXPECT_EQ("fieldName1", message4_->field(0)->json_name());
+ EXPECT_EQ("fieldName2", message4_->field(1)->json_name());
+ EXPECT_EQ("FieldName3", message4_->field(2)->json_name());
+ EXPECT_EQ("FieldName4", message4_->field(3)->json_name());
+ EXPECT_EQ("FIELDNAME5", message4_->field(4)->json_name());
+ EXPECT_EQ("@type", message4_->field(5)->json_name());
+
+ DescriptorProto proto;
+ message4_->CopyTo(&proto);
+ ASSERT_EQ(7, proto.field_size());
+ EXPECT_FALSE(proto.field(0).has_json_name());
+ EXPECT_FALSE(proto.field(1).has_json_name());
+ EXPECT_FALSE(proto.field(2).has_json_name());
+ EXPECT_FALSE(proto.field(3).has_json_name());
+ EXPECT_FALSE(proto.field(4).has_json_name());
+ EXPECT_EQ("@type", proto.field(5).json_name());
+ EXPECT_FALSE(proto.field(6).has_json_name());
+
+ proto.Clear();
+ CopyWithJsonName(message4_, &proto);
+ ASSERT_EQ(7, proto.field_size());
+ EXPECT_EQ("fieldName1", proto.field(0).json_name());
+ EXPECT_EQ("fieldName2", proto.field(1).json_name());
+ EXPECT_EQ("FieldName3", proto.field(2).json_name());
+ EXPECT_EQ("FieldName4", proto.field(3).json_name());
+ EXPECT_EQ("FIELDNAME5", proto.field(4).json_name());
+ EXPECT_EQ("@type", proto.field(5).json_name());
+ EXPECT_EQ("fieldname7", proto.field(6).json_name());
+
+ // Test generated descriptor.
+ const Descriptor* generated = protobuf_unittest::TestJsonName::descriptor();
+ ASSERT_EQ(7, generated->field_count());
+ EXPECT_EQ("fieldName1", generated->field(0)->json_name());
+ EXPECT_EQ("fieldName2", generated->field(1)->json_name());
+ EXPECT_EQ("FieldName3", generated->field(2)->json_name());
+ EXPECT_EQ("FieldName4", generated->field(3)->json_name());
+ EXPECT_EQ("FIELDNAME5", generated->field(4)->json_name());
+ EXPECT_EQ("@type", generated->field(5)->json_name());
+ EXPECT_EQ("fieldname7", generated->field(6)->json_name());
+}
+
+TEST_F(DescriptorTest, FieldFile) {
+ EXPECT_EQ(foo_file_, foo_->file());
+ EXPECT_EQ(foo_file_, bar_->file());
+ EXPECT_EQ(foo_file_, baz_->file());
+ EXPECT_EQ(foo_file_, qux_->file());
+
+ EXPECT_EQ(bar_file_, foo2_->file());
+ EXPECT_EQ(bar_file_, bar2_->file());
+ EXPECT_EQ(bar_file_, quux2_->file());
+}
+
+TEST_F(DescriptorTest, FieldIndex) {
+ EXPECT_EQ(0, foo_->index());
+ EXPECT_EQ(1, bar_->index());
+ EXPECT_EQ(2, baz_->index());
+ EXPECT_EQ(3, qux_->index());
+}
+
+TEST_F(DescriptorTest, FieldNumber) {
+ EXPECT_EQ(1, foo_->number());
+ EXPECT_EQ(6, bar_->number());
+ EXPECT_EQ(500000000, baz_->number());
+ EXPECT_EQ(15, qux_->number());
+}
+
+TEST_F(DescriptorTest, FieldType) {
+ EXPECT_EQ(FieldDescriptor::TYPE_STRING, foo_->type());
+ EXPECT_EQ(FieldDescriptor::TYPE_ENUM, bar_->type());
+ EXPECT_EQ(FieldDescriptor::TYPE_MESSAGE, baz_->type());
+ EXPECT_EQ(FieldDescriptor::TYPE_GROUP, qux_->type());
+}
+
+TEST_F(DescriptorTest, FieldLabel) {
+ EXPECT_EQ(FieldDescriptor::LABEL_REQUIRED, foo_->label());
+ EXPECT_EQ(FieldDescriptor::LABEL_OPTIONAL, bar_->label());
+ EXPECT_EQ(FieldDescriptor::LABEL_REPEATED, baz_->label());
+ EXPECT_EQ(FieldDescriptor::LABEL_OPTIONAL, qux_->label());
+
+ EXPECT_TRUE(foo_->is_required());
+ EXPECT_FALSE(foo_->is_optional());
+ EXPECT_FALSE(foo_->is_repeated());
+
+ EXPECT_FALSE(bar_->is_required());
+ EXPECT_TRUE(bar_->is_optional());
+ EXPECT_FALSE(bar_->is_repeated());
+
+ EXPECT_FALSE(baz_->is_required());
+ EXPECT_FALSE(baz_->is_optional());
+ EXPECT_TRUE(baz_->is_repeated());
+}
+
+TEST_F(DescriptorTest, IsMap) {
+ EXPECT_TRUE(map_->is_map());
+ EXPECT_FALSE(baz_->is_map());
+ EXPECT_TRUE(map_->message_type()->options().map_entry());
+}
+
+TEST_F(DescriptorTest, GetMap) {
+ const Descriptor* map_desc = map_->message_type();
+ const FieldDescriptor* map_key = map_desc->map_key();
+ ASSERT_TRUE(map_key != nullptr);
+ EXPECT_EQ(map_key->name(), "key");
+ EXPECT_EQ(map_key->number(), 1);
+
+ const FieldDescriptor* map_value = map_desc->map_value();
+ ASSERT_TRUE(map_value != nullptr);
+ EXPECT_EQ(map_value->name(), "value");
+ EXPECT_EQ(map_value->number(), 2);
+
+ EXPECT_EQ(message_->map_key(), nullptr);
+ EXPECT_EQ(message_->map_value(), nullptr);
+}
+
+TEST_F(DescriptorTest, FieldHasDefault) {
+ EXPECT_FALSE(foo_->has_default_value());
+ EXPECT_FALSE(bar_->has_default_value());
+ EXPECT_FALSE(baz_->has_default_value());
+ EXPECT_FALSE(qux_->has_default_value());
+}
+
+TEST_F(DescriptorTest, FieldContainingType) {
+ EXPECT_EQ(message_, foo_->containing_type());
+ EXPECT_EQ(message_, bar_->containing_type());
+ EXPECT_EQ(message_, baz_->containing_type());
+ EXPECT_EQ(message_, qux_->containing_type());
+
+ EXPECT_EQ(message2_, foo2_->containing_type());
+ EXPECT_EQ(message2_, bar2_->containing_type());
+ EXPECT_EQ(message2_, quux2_->containing_type());
+}
+
+TEST_F(DescriptorTest, FieldMessageType) {
+ EXPECT_TRUE(foo_->message_type() == nullptr);
+ EXPECT_TRUE(bar_->message_type() == nullptr);
+
+ EXPECT_EQ(foreign_, baz_->message_type());
+ EXPECT_EQ(foreign_, qux_->message_type());
+}
+
+TEST_F(DescriptorTest, FieldEnumType) {
+ EXPECT_TRUE(foo_->enum_type() == nullptr);
+ EXPECT_TRUE(baz_->enum_type() == nullptr);
+ EXPECT_TRUE(qux_->enum_type() == nullptr);
+
+ EXPECT_EQ(enum_, bar_->enum_type());
+}
+
+
+// ===================================================================
+
+// Test simple flat messages and fields.
+class OneofDescriptorTest : public testing::Test {
+ protected:
+ void SetUp() override {
+ // Build descriptors for the following definitions:
+ //
+ // package garply;
+ // message TestOneof {
+ // optional int32 a = 1;
+ // oneof foo {
+ // string b = 2;
+ // TestOneof c = 3;
+ // }
+ // oneof bar {
+ // float d = 4;
+ // }
+ // }
+
+ FileDescriptorProto baz_file;
+ baz_file.set_name("baz.proto");
+ baz_file.set_package("garply");
+
+ DescriptorProto* oneof_message = AddMessage(&baz_file, "TestOneof");
+ oneof_message->add_oneof_decl()->set_name("foo");
+ oneof_message->add_oneof_decl()->set_name("bar");
+
+ AddField(oneof_message, "a", 1, FieldDescriptorProto::LABEL_OPTIONAL,
+ FieldDescriptorProto::TYPE_INT32);
+ AddField(oneof_message, "b", 2, FieldDescriptorProto::LABEL_OPTIONAL,
+ FieldDescriptorProto::TYPE_STRING);
+ oneof_message->mutable_field(1)->set_oneof_index(0);
+ AddField(oneof_message, "c", 3, FieldDescriptorProto::LABEL_OPTIONAL,
+ FieldDescriptorProto::TYPE_MESSAGE);
+ oneof_message->mutable_field(2)->set_oneof_index(0);
+ oneof_message->mutable_field(2)->set_type_name("TestOneof");
+
+ AddField(oneof_message, "d", 4, FieldDescriptorProto::LABEL_OPTIONAL,
+ FieldDescriptorProto::TYPE_FLOAT);
+ oneof_message->mutable_field(3)->set_oneof_index(1);
+
+ // Build the descriptors and get the pointers.
+ baz_file_ = pool_.BuildFile(baz_file);
+ ASSERT_TRUE(baz_file_ != nullptr);
+
+ ASSERT_EQ(1, baz_file_->message_type_count());
+ oneof_message_ = baz_file_->message_type(0);
+
+ ASSERT_EQ(2, oneof_message_->oneof_decl_count());
+ oneof_ = oneof_message_->oneof_decl(0);
+ oneof2_ = oneof_message_->oneof_decl(1);
+
+ ASSERT_EQ(4, oneof_message_->field_count());
+ a_ = oneof_message_->field(0);
+ b_ = oneof_message_->field(1);
+ c_ = oneof_message_->field(2);
+ d_ = oneof_message_->field(3);
+ }
+
+ DescriptorPool pool_;
+
+ const FileDescriptor* baz_file_;
+
+ const Descriptor* oneof_message_;
+
+ const OneofDescriptor* oneof_;
+ const OneofDescriptor* oneof2_;
+ const FieldDescriptor* a_;
+ const FieldDescriptor* b_;
+ const FieldDescriptor* c_;
+ const FieldDescriptor* d_;
+};
+
+TEST_F(OneofDescriptorTest, Normal) {
+ EXPECT_EQ("foo", oneof_->name());
+ EXPECT_EQ("garply.TestOneof.foo", oneof_->full_name());
+ EXPECT_EQ(0, oneof_->index());
+ ASSERT_EQ(2, oneof_->field_count());
+ EXPECT_EQ(b_, oneof_->field(0));
+ EXPECT_EQ(c_, oneof_->field(1));
+ EXPECT_TRUE(a_->containing_oneof() == nullptr);
+ EXPECT_EQ(oneof_, b_->containing_oneof());
+ EXPECT_EQ(oneof_, c_->containing_oneof());
+}
+
+TEST_F(OneofDescriptorTest, FindByName) {
+ EXPECT_EQ(oneof_, oneof_message_->FindOneofByName("foo"));
+ EXPECT_EQ(oneof2_, oneof_message_->FindOneofByName("bar"));
+ EXPECT_TRUE(oneof_message_->FindOneofByName("no_such_oneof") == nullptr);
+}
+
+// ===================================================================
+
+class StylizedFieldNamesTest : public testing::Test {
+ protected:
+ void SetUp() override {
+ FileDescriptorProto file;
+ file.set_name("foo.proto");
+
+ AddExtensionRange(AddMessage(&file, "ExtendableMessage"), 1, 1000);
+
+ DescriptorProto* message = AddMessage(&file, "TestMessage");
+ AddField(message, "foo_foo", 1, FieldDescriptorProto::LABEL_OPTIONAL,
+ FieldDescriptorProto::TYPE_INT32);
+ AddField(message, "FooBar", 2, FieldDescriptorProto::LABEL_OPTIONAL,
+ FieldDescriptorProto::TYPE_INT32);
+ AddField(message, "fooBaz", 3, FieldDescriptorProto::LABEL_OPTIONAL,
+ FieldDescriptorProto::TYPE_INT32);
+ AddField(message, "fooFoo", 4, // Camel-case conflict with foo_foo.
+ FieldDescriptorProto::LABEL_OPTIONAL,
+ FieldDescriptorProto::TYPE_INT32);
+ AddField(message, "foobar", 5, // Lower-case conflict with FooBar.
+ FieldDescriptorProto::LABEL_OPTIONAL,
+ FieldDescriptorProto::TYPE_INT32);
+
+ AddNestedExtension(message, "ExtendableMessage", "bar_foo", 1,
+ FieldDescriptorProto::LABEL_OPTIONAL,
+ FieldDescriptorProto::TYPE_INT32);
+ AddNestedExtension(message, "ExtendableMessage", "BarBar", 2,
+ FieldDescriptorProto::LABEL_OPTIONAL,
+ FieldDescriptorProto::TYPE_INT32);
+ AddNestedExtension(message, "ExtendableMessage", "BarBaz", 3,
+ FieldDescriptorProto::LABEL_OPTIONAL,
+ FieldDescriptorProto::TYPE_INT32);
+ AddNestedExtension(message, "ExtendableMessage", "barFoo", 4, // Conflict
+ FieldDescriptorProto::LABEL_OPTIONAL,
+ FieldDescriptorProto::TYPE_INT32);
+ AddNestedExtension(message, "ExtendableMessage", "barbar", 5, // Conflict
+ FieldDescriptorProto::LABEL_OPTIONAL,
+ FieldDescriptorProto::TYPE_INT32);
+
+ AddExtension(&file, "ExtendableMessage", "baz_foo", 11,
+ FieldDescriptorProto::LABEL_OPTIONAL,
+ FieldDescriptorProto::TYPE_INT32);
+ AddExtension(&file, "ExtendableMessage", "BazBar", 12,
+ FieldDescriptorProto::LABEL_OPTIONAL,
+ FieldDescriptorProto::TYPE_INT32);
+ AddExtension(&file, "ExtendableMessage", "BazBaz", 13,
+ FieldDescriptorProto::LABEL_OPTIONAL,
+ FieldDescriptorProto::TYPE_INT32);
+ AddExtension(&file, "ExtendableMessage", "bazFoo", 14, // Conflict
+ FieldDescriptorProto::LABEL_OPTIONAL,
+ FieldDescriptorProto::TYPE_INT32);
+ AddExtension(&file, "ExtendableMessage", "bazbar", 15, // Conflict
+ FieldDescriptorProto::LABEL_OPTIONAL,
+ FieldDescriptorProto::TYPE_INT32);
+
+ file_ = pool_.BuildFile(file);
+ ASSERT_TRUE(file_ != nullptr);
+ ASSERT_EQ(2, file_->message_type_count());
+ message_ = file_->message_type(1);
+ ASSERT_EQ("TestMessage", message_->name());
+ ASSERT_EQ(5, message_->field_count());
+ ASSERT_EQ(5, message_->extension_count());
+ ASSERT_EQ(5, file_->extension_count());
+ }
+
+ DescriptorPool pool_;
+ const FileDescriptor* file_;
+ const Descriptor* message_;
+};
+
+TEST_F(StylizedFieldNamesTest, LowercaseName) {
+ EXPECT_EQ("foo_foo", message_->field(0)->lowercase_name());
+ EXPECT_EQ("foobar", message_->field(1)->lowercase_name());
+ EXPECT_EQ("foobaz", message_->field(2)->lowercase_name());
+ EXPECT_EQ("foofoo", message_->field(3)->lowercase_name());
+ EXPECT_EQ("foobar", message_->field(4)->lowercase_name());
+
+ EXPECT_EQ("bar_foo", message_->extension(0)->lowercase_name());
+ EXPECT_EQ("barbar", message_->extension(1)->lowercase_name());
+ EXPECT_EQ("barbaz", message_->extension(2)->lowercase_name());
+ EXPECT_EQ("barfoo", message_->extension(3)->lowercase_name());
+ EXPECT_EQ("barbar", message_->extension(4)->lowercase_name());
+
+ EXPECT_EQ("baz_foo", file_->extension(0)->lowercase_name());
+ EXPECT_EQ("bazbar", file_->extension(1)->lowercase_name());
+ EXPECT_EQ("bazbaz", file_->extension(2)->lowercase_name());
+ EXPECT_EQ("bazfoo", file_->extension(3)->lowercase_name());
+ EXPECT_EQ("bazbar", file_->extension(4)->lowercase_name());
+}
+
+TEST_F(StylizedFieldNamesTest, CamelcaseName) {
+ EXPECT_EQ("fooFoo", message_->field(0)->camelcase_name());
+ EXPECT_EQ("fooBar", message_->field(1)->camelcase_name());
+ EXPECT_EQ("fooBaz", message_->field(2)->camelcase_name());
+ EXPECT_EQ("fooFoo", message_->field(3)->camelcase_name());
+ EXPECT_EQ("foobar", message_->field(4)->camelcase_name());
+
+ EXPECT_EQ("barFoo", message_->extension(0)->camelcase_name());
+ EXPECT_EQ("barBar", message_->extension(1)->camelcase_name());
+ EXPECT_EQ("barBaz", message_->extension(2)->camelcase_name());
+ EXPECT_EQ("barFoo", message_->extension(3)->camelcase_name());
+ EXPECT_EQ("barbar", message_->extension(4)->camelcase_name());
+
+ EXPECT_EQ("bazFoo", file_->extension(0)->camelcase_name());
+ EXPECT_EQ("bazBar", file_->extension(1)->camelcase_name());
+ EXPECT_EQ("bazBaz", file_->extension(2)->camelcase_name());
+ EXPECT_EQ("bazFoo", file_->extension(3)->camelcase_name());
+ EXPECT_EQ("bazbar", file_->extension(4)->camelcase_name());
+}
+
+TEST_F(StylizedFieldNamesTest, FindByLowercaseName) {
+ EXPECT_EQ(message_->field(0), message_->FindFieldByLowercaseName("foo_foo"));
+ EXPECT_EQ(message_->field(1), message_->FindFieldByLowercaseName("foobar"));
+ EXPECT_EQ(message_->field(2), message_->FindFieldByLowercaseName("foobaz"));
+ EXPECT_TRUE(message_->FindFieldByLowercaseName("FooBar") == nullptr);
+ EXPECT_TRUE(message_->FindFieldByLowercaseName("fooBaz") == nullptr);
+ EXPECT_TRUE(message_->FindFieldByLowercaseName("bar_foo") == nullptr);
+ EXPECT_TRUE(message_->FindFieldByLowercaseName("nosuchfield") == nullptr);
+
+ EXPECT_EQ(message_->extension(0),
+ message_->FindExtensionByLowercaseName("bar_foo"));
+ EXPECT_EQ(message_->extension(1),
+ message_->FindExtensionByLowercaseName("barbar"));
+ EXPECT_EQ(message_->extension(2),
+ message_->FindExtensionByLowercaseName("barbaz"));
+ EXPECT_TRUE(message_->FindExtensionByLowercaseName("BarBar") == nullptr);
+ EXPECT_TRUE(message_->FindExtensionByLowercaseName("barBaz") == nullptr);
+ EXPECT_TRUE(message_->FindExtensionByLowercaseName("foo_foo") == nullptr);
+ EXPECT_TRUE(message_->FindExtensionByLowercaseName("nosuchfield") == nullptr);
+
+ EXPECT_EQ(file_->extension(0),
+ file_->FindExtensionByLowercaseName("baz_foo"));
+ EXPECT_EQ(file_->extension(1), file_->FindExtensionByLowercaseName("bazbar"));
+ EXPECT_EQ(file_->extension(2), file_->FindExtensionByLowercaseName("bazbaz"));
+ EXPECT_TRUE(file_->FindExtensionByLowercaseName("BazBar") == nullptr);
+ EXPECT_TRUE(file_->FindExtensionByLowercaseName("bazBaz") == nullptr);
+ EXPECT_TRUE(file_->FindExtensionByLowercaseName("nosuchfield") == nullptr);
+}
+
+TEST_F(StylizedFieldNamesTest, FindByCamelcaseName) {
+ EXPECT_EQ(message_->field(0), message_->FindFieldByCamelcaseName("fooFoo"));
+ EXPECT_EQ(message_->field(1), message_->FindFieldByCamelcaseName("fooBar"));
+ EXPECT_EQ(message_->field(2), message_->FindFieldByCamelcaseName("fooBaz"));
+ EXPECT_TRUE(message_->FindFieldByCamelcaseName("foo_foo") == nullptr);
+ EXPECT_TRUE(message_->FindFieldByCamelcaseName("FooBar") == nullptr);
+ EXPECT_TRUE(message_->FindFieldByCamelcaseName("barFoo") == nullptr);
+ EXPECT_TRUE(message_->FindFieldByCamelcaseName("nosuchfield") == nullptr);
+
+ EXPECT_EQ(message_->extension(0),
+ message_->FindExtensionByCamelcaseName("barFoo"));
+ EXPECT_EQ(message_->extension(1),
+ message_->FindExtensionByCamelcaseName("barBar"));
+ EXPECT_EQ(message_->extension(2),
+ message_->FindExtensionByCamelcaseName("barBaz"));
+ EXPECT_TRUE(message_->FindExtensionByCamelcaseName("bar_foo") == nullptr);
+ EXPECT_TRUE(message_->FindExtensionByCamelcaseName("BarBar") == nullptr);
+ EXPECT_TRUE(message_->FindExtensionByCamelcaseName("fooFoo") == nullptr);
+ EXPECT_TRUE(message_->FindExtensionByCamelcaseName("nosuchfield") == nullptr);
+
+ EXPECT_EQ(file_->extension(0), file_->FindExtensionByCamelcaseName("bazFoo"));
+ EXPECT_EQ(file_->extension(1), file_->FindExtensionByCamelcaseName("bazBar"));
+ EXPECT_EQ(file_->extension(2), file_->FindExtensionByCamelcaseName("bazBaz"));
+ EXPECT_TRUE(file_->FindExtensionByCamelcaseName("baz_foo") == nullptr);
+ EXPECT_TRUE(file_->FindExtensionByCamelcaseName("BazBar") == nullptr);
+ EXPECT_TRUE(file_->FindExtensionByCamelcaseName("nosuchfield") == nullptr);
+}
+
+// ===================================================================
+
+// Test enum descriptors.
+class EnumDescriptorTest : public testing::Test {
+ protected:
+ void SetUp() override {
+ // Build descriptors for the following definitions:
+ //
+ // // in "foo.proto"
+ // enum TestEnum {
+ // FOO = 1;
+ // BAR = 2;
+ // }
+ //
+ // // in "bar.proto"
+ // package corge.grault;
+ // enum TestEnum2 {
+ // FOO = 1;
+ // BAZ = 3;
+ // }
+ //
+ // TestEnum2 is primarily here to test FindValueByName and friends.
+ // All enums created from the same DescriptorPool share the same lookup
+ // table, so we need to insure that they don't interfere.
+
+ // TestEnum
+ FileDescriptorProto foo_file;
+ foo_file.set_name("foo.proto");
+
+ EnumDescriptorProto* enum_proto = AddEnum(&foo_file, "TestEnum");
+ AddEnumValue(enum_proto, "FOO", 1);
+ AddEnumValue(enum_proto, "BAR", 2);
+
+ // TestEnum2
+ FileDescriptorProto bar_file;
+ bar_file.set_name("bar.proto");
+ bar_file.set_package("corge.grault");
+
+ EnumDescriptorProto* enum2_proto = AddEnum(&bar_file, "TestEnum2");
+ AddEnumValue(enum2_proto, "FOO", 1);
+ AddEnumValue(enum2_proto, "BAZ", 3);
+
+ // Build the descriptors and get the pointers.
+ foo_file_ = pool_.BuildFile(foo_file);
+ ASSERT_TRUE(foo_file_ != nullptr);
+
+ bar_file_ = pool_.BuildFile(bar_file);
+ ASSERT_TRUE(bar_file_ != nullptr);
+
+ ASSERT_EQ(1, foo_file_->enum_type_count());
+ enum_ = foo_file_->enum_type(0);
+
+ ASSERT_EQ(2, enum_->value_count());
+ foo_ = enum_->value(0);
+ bar_ = enum_->value(1);
+
+ ASSERT_EQ(1, bar_file_->enum_type_count());
+ enum2_ = bar_file_->enum_type(0);
+
+ ASSERT_EQ(2, enum2_->value_count());
+ foo2_ = enum2_->value(0);
+ baz2_ = enum2_->value(1);
+ }
+
+ DescriptorPool pool_;
+
+ const FileDescriptor* foo_file_;
+ const FileDescriptor* bar_file_;
+
+ const EnumDescriptor* enum_;
+ const EnumDescriptor* enum2_;
+
+ const EnumValueDescriptor* foo_;
+ const EnumValueDescriptor* bar_;
+
+ const EnumValueDescriptor* foo2_;
+ const EnumValueDescriptor* baz2_;
+};
+
+TEST_F(EnumDescriptorTest, Name) {
+ EXPECT_EQ("TestEnum", enum_->name());
+ EXPECT_EQ("TestEnum", enum_->full_name());
+ EXPECT_EQ(foo_file_, enum_->file());
+
+ EXPECT_EQ("TestEnum2", enum2_->name());
+ EXPECT_EQ("corge.grault.TestEnum2", enum2_->full_name());
+ EXPECT_EQ(bar_file_, enum2_->file());
+}
+
+TEST_F(EnumDescriptorTest, ContainingType) {
+ EXPECT_TRUE(enum_->containing_type() == nullptr);
+ EXPECT_TRUE(enum2_->containing_type() == nullptr);
+}
+
+TEST_F(EnumDescriptorTest, ValuesByIndex) {
+ ASSERT_EQ(2, enum_->value_count());
+ EXPECT_EQ(foo_, enum_->value(0));
+ EXPECT_EQ(bar_, enum_->value(1));
+}
+
+TEST_F(EnumDescriptorTest, FindValueByName) {
+ EXPECT_EQ(foo_, enum_->FindValueByName("FOO"));
+ EXPECT_EQ(bar_, enum_->FindValueByName("BAR"));
+ EXPECT_EQ(foo2_, enum2_->FindValueByName("FOO"));
+ EXPECT_EQ(baz2_, enum2_->FindValueByName("BAZ"));
+
+ EXPECT_TRUE(enum_->FindValueByName("NO_SUCH_VALUE") == nullptr);
+ EXPECT_TRUE(enum_->FindValueByName("BAZ") == nullptr);
+ EXPECT_TRUE(enum2_->FindValueByName("BAR") == nullptr);
+}
+
+TEST_F(EnumDescriptorTest, FindValueByNumber) {
+ EXPECT_EQ(foo_, enum_->FindValueByNumber(1));
+ EXPECT_EQ(bar_, enum_->FindValueByNumber(2));
+ EXPECT_EQ(foo2_, enum2_->FindValueByNumber(1));
+ EXPECT_EQ(baz2_, enum2_->FindValueByNumber(3));
+
+ EXPECT_TRUE(enum_->FindValueByNumber(416) == nullptr);
+ EXPECT_TRUE(enum_->FindValueByNumber(3) == nullptr);
+ EXPECT_TRUE(enum2_->FindValueByNumber(2) == nullptr);
+}
+
+TEST_F(EnumDescriptorTest, ValueName) {
+ EXPECT_EQ("FOO", foo_->name());
+ EXPECT_EQ("BAR", bar_->name());
+}
+
+TEST_F(EnumDescriptorTest, ValueFullName) {
+ EXPECT_EQ("FOO", foo_->full_name());
+ EXPECT_EQ("BAR", bar_->full_name());
+ EXPECT_EQ("corge.grault.FOO", foo2_->full_name());
+ EXPECT_EQ("corge.grault.BAZ", baz2_->full_name());
+}
+
+TEST_F(EnumDescriptorTest, ValueIndex) {
+ EXPECT_EQ(0, foo_->index());
+ EXPECT_EQ(1, bar_->index());
+}
+
+TEST_F(EnumDescriptorTest, ValueNumber) {
+ EXPECT_EQ(1, foo_->number());
+ EXPECT_EQ(2, bar_->number());
+}
+
+TEST_F(EnumDescriptorTest, ValueType) {
+ EXPECT_EQ(enum_, foo_->type());
+ EXPECT_EQ(enum_, bar_->type());
+ EXPECT_EQ(enum2_, foo2_->type());
+ EXPECT_EQ(enum2_, baz2_->type());
+}
+
+// ===================================================================
+
+// Test service descriptors.
+class ServiceDescriptorTest : public testing::Test {
+ protected:
+ void SetUp() override {
+ // Build descriptors for the following messages and service:
+ // // in "foo.proto"
+ // message FooRequest {}
+ // message FooResponse {}
+ // message BarRequest {}
+ // message BarResponse {}
+ // message BazRequest {}
+ // message BazResponse {}
+ //
+ // service TestService {
+ // rpc Foo(FooRequest) returns (FooResponse);
+ // rpc Bar(BarRequest) returns (BarResponse);
+ // }
+ //
+ // // in "bar.proto"
+ // package corge.grault
+ // service TestService2 {
+ // rpc Foo(FooRequest) returns (FooResponse);
+ // rpc Baz(BazRequest) returns (BazResponse);
+ // }
+
+ FileDescriptorProto foo_file;
+ foo_file.set_name("foo.proto");
+
+ AddMessage(&foo_file, "FooRequest");
+ AddMessage(&foo_file, "FooResponse");
+ AddMessage(&foo_file, "BarRequest");
+ AddMessage(&foo_file, "BarResponse");
+ AddMessage(&foo_file, "BazRequest");
+ AddMessage(&foo_file, "BazResponse");
+
+ ServiceDescriptorProto* service = AddService(&foo_file, "TestService");
+ AddMethod(service, "Foo", "FooRequest", "FooResponse");
+ AddMethod(service, "Bar", "BarRequest", "BarResponse");
+
+ FileDescriptorProto bar_file;
+ bar_file.set_name("bar.proto");
+ bar_file.set_package("corge.grault");
+ bar_file.add_dependency("foo.proto");
+
+ ServiceDescriptorProto* service2 = AddService(&bar_file, "TestService2");
+ AddMethod(service2, "Foo", "FooRequest", "FooResponse");
+ AddMethod(service2, "Baz", "BazRequest", "BazResponse");
+
+ // Build the descriptors and get the pointers.
+ foo_file_ = pool_.BuildFile(foo_file);
+ ASSERT_TRUE(foo_file_ != nullptr);
+
+ bar_file_ = pool_.BuildFile(bar_file);
+ ASSERT_TRUE(bar_file_ != nullptr);
+
+ ASSERT_EQ(6, foo_file_->message_type_count());
+ foo_request_ = foo_file_->message_type(0);
+ foo_response_ = foo_file_->message_type(1);
+ bar_request_ = foo_file_->message_type(2);
+ bar_response_ = foo_file_->message_type(3);
+ baz_request_ = foo_file_->message_type(4);
+ baz_response_ = foo_file_->message_type(5);
+
+ ASSERT_EQ(1, foo_file_->service_count());
+ service_ = foo_file_->service(0);
+
+ ASSERT_EQ(2, service_->method_count());
+ foo_ = service_->method(0);
+ bar_ = service_->method(1);
+
+ ASSERT_EQ(1, bar_file_->service_count());
+ service2_ = bar_file_->service(0);
+
+ ASSERT_EQ(2, service2_->method_count());
+ foo2_ = service2_->method(0);
+ baz2_ = service2_->method(1);
+ }
+
+ DescriptorPool pool_;
+
+ const FileDescriptor* foo_file_;
+ const FileDescriptor* bar_file_;
+
+ const Descriptor* foo_request_;
+ const Descriptor* foo_response_;
+ const Descriptor* bar_request_;
+ const Descriptor* bar_response_;
+ const Descriptor* baz_request_;
+ const Descriptor* baz_response_;
+
+ const ServiceDescriptor* service_;
+ const ServiceDescriptor* service2_;
+
+ const MethodDescriptor* foo_;
+ const MethodDescriptor* bar_;
+
+ const MethodDescriptor* foo2_;
+ const MethodDescriptor* baz2_;
+};
+
+TEST_F(ServiceDescriptorTest, Name) {
+ EXPECT_EQ("TestService", service_->name());
+ EXPECT_EQ("TestService", service_->full_name());
+ EXPECT_EQ(foo_file_, service_->file());
+
+ EXPECT_EQ("TestService2", service2_->name());
+ EXPECT_EQ("corge.grault.TestService2", service2_->full_name());
+ EXPECT_EQ(bar_file_, service2_->file());
+}
+
+TEST_F(ServiceDescriptorTest, MethodsByIndex) {
+ ASSERT_EQ(2, service_->method_count());
+ EXPECT_EQ(foo_, service_->method(0));
+ EXPECT_EQ(bar_, service_->method(1));
+}
+
+TEST_F(ServiceDescriptorTest, FindMethodByName) {
+ EXPECT_EQ(foo_, service_->FindMethodByName("Foo"));
+ EXPECT_EQ(bar_, service_->FindMethodByName("Bar"));
+ EXPECT_EQ(foo2_, service2_->FindMethodByName("Foo"));
+ EXPECT_EQ(baz2_, service2_->FindMethodByName("Baz"));
+
+ EXPECT_TRUE(service_->FindMethodByName("NoSuchMethod") == nullptr);
+ EXPECT_TRUE(service_->FindMethodByName("Baz") == nullptr);
+ EXPECT_TRUE(service2_->FindMethodByName("Bar") == nullptr);
+}
+
+TEST_F(ServiceDescriptorTest, MethodName) {
+ EXPECT_EQ("Foo", foo_->name());
+ EXPECT_EQ("Bar", bar_->name());
+}
+
+TEST_F(ServiceDescriptorTest, MethodFullName) {
+ EXPECT_EQ("TestService.Foo", foo_->full_name());
+ EXPECT_EQ("TestService.Bar", bar_->full_name());
+ EXPECT_EQ("corge.grault.TestService2.Foo", foo2_->full_name());
+ EXPECT_EQ("corge.grault.TestService2.Baz", baz2_->full_name());
+}
+
+TEST_F(ServiceDescriptorTest, MethodIndex) {
+ EXPECT_EQ(0, foo_->index());
+ EXPECT_EQ(1, bar_->index());
+}
+
+TEST_F(ServiceDescriptorTest, MethodParent) {
+ EXPECT_EQ(service_, foo_->service());
+ EXPECT_EQ(service_, bar_->service());
+}
+
+TEST_F(ServiceDescriptorTest, MethodInputType) {
+ EXPECT_EQ(foo_request_, foo_->input_type());
+ EXPECT_EQ(bar_request_, bar_->input_type());
+}
+
+TEST_F(ServiceDescriptorTest, MethodOutputType) {
+ EXPECT_EQ(foo_response_, foo_->output_type());
+ EXPECT_EQ(bar_response_, bar_->output_type());
+}
+
+// ===================================================================
+
+// Test nested types.
+class NestedDescriptorTest : public testing::Test {
+ protected:
+ void SetUp() override {
+ // Build descriptors for the following definitions:
+ //
+ // // in "foo.proto"
+ // message TestMessage {
+ // message Foo {}
+ // message Bar {}
+ // enum Baz { A = 1; }
+ // enum Qux { B = 1; }
+ // }
+ //
+ // // in "bar.proto"
+ // package corge.grault;
+ // message TestMessage2 {
+ // message Foo {}
+ // message Baz {}
+ // enum Qux { A = 1; }
+ // enum Quux { C = 1; }
+ // }
+ //
+ // TestMessage2 is primarily here to test FindNestedTypeByName and friends.
+ // All messages created from the same DescriptorPool share the same lookup
+ // table, so we need to insure that they don't interfere.
+ //
+ // We add enum values to the enums in order to test searching for enum
+ // values across a message's scope.
+
+ FileDescriptorProto foo_file;
+ foo_file.set_name("foo.proto");
+
+ DescriptorProto* message = AddMessage(&foo_file, "TestMessage");
+ AddNestedMessage(message, "Foo");
+ AddNestedMessage(message, "Bar");
+ EnumDescriptorProto* baz = AddNestedEnum(message, "Baz");
+ AddEnumValue(baz, "A", 1);
+ EnumDescriptorProto* qux = AddNestedEnum(message, "Qux");
+ AddEnumValue(qux, "B", 1);
+
+ FileDescriptorProto bar_file;
+ bar_file.set_name("bar.proto");
+ bar_file.set_package("corge.grault");
+
+ DescriptorProto* message2 = AddMessage(&bar_file, "TestMessage2");
+ AddNestedMessage(message2, "Foo");
+ AddNestedMessage(message2, "Baz");
+ EnumDescriptorProto* qux2 = AddNestedEnum(message2, "Qux");
+ AddEnumValue(qux2, "A", 1);
+ EnumDescriptorProto* quux2 = AddNestedEnum(message2, "Quux");
+ AddEnumValue(quux2, "C", 1);
+
+ // Build the descriptors and get the pointers.
+ foo_file_ = pool_.BuildFile(foo_file);
+ ASSERT_TRUE(foo_file_ != nullptr);
+
+ bar_file_ = pool_.BuildFile(bar_file);
+ ASSERT_TRUE(bar_file_ != nullptr);
+
+ ASSERT_EQ(1, foo_file_->message_type_count());
+ message_ = foo_file_->message_type(0);
+
+ ASSERT_EQ(2, message_->nested_type_count());
+ foo_ = message_->nested_type(0);
+ bar_ = message_->nested_type(1);
+
+ ASSERT_EQ(2, message_->enum_type_count());
+ baz_ = message_->enum_type(0);
+ qux_ = message_->enum_type(1);
+
+ ASSERT_EQ(1, baz_->value_count());
+ a_ = baz_->value(0);
+ ASSERT_EQ(1, qux_->value_count());
+ b_ = qux_->value(0);
+
+ ASSERT_EQ(1, bar_file_->message_type_count());
+ message2_ = bar_file_->message_type(0);
+
+ ASSERT_EQ(2, message2_->nested_type_count());
+ foo2_ = message2_->nested_type(0);
+ baz2_ = message2_->nested_type(1);
+
+ ASSERT_EQ(2, message2_->enum_type_count());
+ qux2_ = message2_->enum_type(0);
+ quux2_ = message2_->enum_type(1);
+
+ ASSERT_EQ(1, qux2_->value_count());
+ a2_ = qux2_->value(0);
+ ASSERT_EQ(1, quux2_->value_count());
+ c2_ = quux2_->value(0);
+ }
+
+ DescriptorPool pool_;
+
+ const FileDescriptor* foo_file_;
+ const FileDescriptor* bar_file_;
+
+ const Descriptor* message_;
+ const Descriptor* message2_;
+
+ const Descriptor* foo_;
+ const Descriptor* bar_;
+ const EnumDescriptor* baz_;
+ const EnumDescriptor* qux_;
+ const EnumValueDescriptor* a_;
+ const EnumValueDescriptor* b_;
+
+ const Descriptor* foo2_;
+ const Descriptor* baz2_;
+ const EnumDescriptor* qux2_;
+ const EnumDescriptor* quux2_;
+ const EnumValueDescriptor* a2_;
+ const EnumValueDescriptor* c2_;
+};
+
+TEST_F(NestedDescriptorTest, MessageName) {
+ EXPECT_EQ("Foo", foo_->name());
+ EXPECT_EQ("Bar", bar_->name());
+ EXPECT_EQ("Foo", foo2_->name());
+ EXPECT_EQ("Baz", baz2_->name());
+
+ EXPECT_EQ("TestMessage.Foo", foo_->full_name());
+ EXPECT_EQ("TestMessage.Bar", bar_->full_name());
+ EXPECT_EQ("corge.grault.TestMessage2.Foo", foo2_->full_name());
+ EXPECT_EQ("corge.grault.TestMessage2.Baz", baz2_->full_name());
+}
+
+TEST_F(NestedDescriptorTest, MessageContainingType) {
+ EXPECT_EQ(message_, foo_->containing_type());
+ EXPECT_EQ(message_, bar_->containing_type());
+ EXPECT_EQ(message2_, foo2_->containing_type());
+ EXPECT_EQ(message2_, baz2_->containing_type());
+}
+
+TEST_F(NestedDescriptorTest, NestedMessagesByIndex) {
+ ASSERT_EQ(2, message_->nested_type_count());
+ EXPECT_EQ(foo_, message_->nested_type(0));
+ EXPECT_EQ(bar_, message_->nested_type(1));
+}
+
+TEST_F(NestedDescriptorTest, FindFieldByNameDoesntFindNestedTypes) {
+ EXPECT_TRUE(message_->FindFieldByName("Foo") == nullptr);
+ EXPECT_TRUE(message_->FindFieldByName("Qux") == nullptr);
+ EXPECT_TRUE(message_->FindExtensionByName("Foo") == nullptr);
+ EXPECT_TRUE(message_->FindExtensionByName("Qux") == nullptr);
+}
+
+TEST_F(NestedDescriptorTest, FindNestedTypeByName) {
+ EXPECT_EQ(foo_, message_->FindNestedTypeByName("Foo"));
+ EXPECT_EQ(bar_, message_->FindNestedTypeByName("Bar"));
+ EXPECT_EQ(foo2_, message2_->FindNestedTypeByName("Foo"));
+ EXPECT_EQ(baz2_, message2_->FindNestedTypeByName("Baz"));
+
+ EXPECT_TRUE(message_->FindNestedTypeByName("NoSuchType") == nullptr);
+ EXPECT_TRUE(message_->FindNestedTypeByName("Baz") == nullptr);
+ EXPECT_TRUE(message2_->FindNestedTypeByName("Bar") == nullptr);
+
+ EXPECT_TRUE(message_->FindNestedTypeByName("Qux") == nullptr);
+}
+
+TEST_F(NestedDescriptorTest, EnumName) {
+ EXPECT_EQ("Baz", baz_->name());
+ EXPECT_EQ("Qux", qux_->name());
+ EXPECT_EQ("Qux", qux2_->name());
+ EXPECT_EQ("Quux", quux2_->name());
+
+ EXPECT_EQ("TestMessage.Baz", baz_->full_name());
+ EXPECT_EQ("TestMessage.Qux", qux_->full_name());
+ EXPECT_EQ("corge.grault.TestMessage2.Qux", qux2_->full_name());
+ EXPECT_EQ("corge.grault.TestMessage2.Quux", quux2_->full_name());
+}
+
+TEST_F(NestedDescriptorTest, EnumContainingType) {
+ EXPECT_EQ(message_, baz_->containing_type());
+ EXPECT_EQ(message_, qux_->containing_type());
+ EXPECT_EQ(message2_, qux2_->containing_type());
+ EXPECT_EQ(message2_, quux2_->containing_type());
+}
+
+TEST_F(NestedDescriptorTest, NestedEnumsByIndex) {
+ ASSERT_EQ(2, message_->nested_type_count());
+ EXPECT_EQ(foo_, message_->nested_type(0));
+ EXPECT_EQ(bar_, message_->nested_type(1));
+}
+
+TEST_F(NestedDescriptorTest, FindEnumTypeByName) {
+ EXPECT_EQ(baz_, message_->FindEnumTypeByName("Baz"));
+ EXPECT_EQ(qux_, message_->FindEnumTypeByName("Qux"));
+ EXPECT_EQ(qux2_, message2_->FindEnumTypeByName("Qux"));
+ EXPECT_EQ(quux2_, message2_->FindEnumTypeByName("Quux"));
+
+ EXPECT_TRUE(message_->FindEnumTypeByName("NoSuchType") == nullptr);
+ EXPECT_TRUE(message_->FindEnumTypeByName("Quux") == nullptr);
+ EXPECT_TRUE(message2_->FindEnumTypeByName("Baz") == nullptr);
+
+ EXPECT_TRUE(message_->FindEnumTypeByName("Foo") == nullptr);
+}
+
+TEST_F(NestedDescriptorTest, FindEnumValueByName) {
+ EXPECT_EQ(a_, message_->FindEnumValueByName("A"));
+ EXPECT_EQ(b_, message_->FindEnumValueByName("B"));
+ EXPECT_EQ(a2_, message2_->FindEnumValueByName("A"));
+ EXPECT_EQ(c2_, message2_->FindEnumValueByName("C"));
+
+ EXPECT_TRUE(message_->FindEnumValueByName("NO_SUCH_VALUE") == nullptr);
+ EXPECT_TRUE(message_->FindEnumValueByName("C") == nullptr);
+ EXPECT_TRUE(message2_->FindEnumValueByName("B") == nullptr);
+
+ EXPECT_TRUE(message_->FindEnumValueByName("Foo") == nullptr);
+}
+
+// ===================================================================
+
+// Test extensions.
+class ExtensionDescriptorTest : public testing::Test {
+ protected:
+ void SetUp() override {
+ // Build descriptors for the following definitions:
+ //
+ // enum Baz {}
+ // message Qux {}
+ //
+ // message Foo {
+ // extensions 10 to 19;
+ // extensions 30 to 39;
+ // }
+ // extend Foo {
+ // optional int32 foo_int32 = 10;
+ // }
+ // extend Foo {
+ // repeated TestEnum foo_enum = 19;
+ // }
+ // message Bar {
+ // optional int32 non_ext_int32 = 1;
+ // extend Foo {
+ // optional Qux foo_message = 30;
+ // repeated Qux foo_group = 39; // (but internally set to TYPE_GROUP)
+ // }
+ // }
+
+ FileDescriptorProto foo_file;
+ foo_file.set_name("foo.proto");
+
+ AddEmptyEnum(&foo_file, "Baz");
+ AddMessage(&foo_file, "Qux");
+
+ DescriptorProto* foo = AddMessage(&foo_file, "Foo");
+ AddExtensionRange(foo, 10, 20);
+ AddExtensionRange(foo, 30, 40);
+
+ AddExtension(&foo_file, "Foo", "foo_int32", 10,
+ FieldDescriptorProto::LABEL_OPTIONAL,
+ FieldDescriptorProto::TYPE_INT32);
+ AddExtension(&foo_file, "Foo", "foo_enum", 19,
+ FieldDescriptorProto::LABEL_REPEATED,
+ FieldDescriptorProto::TYPE_ENUM)
+ ->set_type_name("Baz");
+
+ DescriptorProto* bar = AddMessage(&foo_file, "Bar");
+ AddField(bar, "non_ext_int32", 1, FieldDescriptorProto::LABEL_OPTIONAL,
+ FieldDescriptorProto::TYPE_INT32);
+ AddNestedExtension(bar, "Foo", "foo_message", 30,
+ FieldDescriptorProto::LABEL_OPTIONAL,
+ FieldDescriptorProto::TYPE_MESSAGE)
+ ->set_type_name("Qux");
+ AddNestedExtension(bar, "Foo", "foo_group", 39,
+ FieldDescriptorProto::LABEL_REPEATED,
+ FieldDescriptorProto::TYPE_GROUP)
+ ->set_type_name("Qux");
+
+ // Build the descriptors and get the pointers.
+ foo_file_ = pool_.BuildFile(foo_file);
+ ASSERT_TRUE(foo_file_ != nullptr);
+
+ ASSERT_EQ(1, foo_file_->enum_type_count());
+ baz_ = foo_file_->enum_type(0);
+
+ ASSERT_EQ(3, foo_file_->message_type_count());
+ qux_ = foo_file_->message_type(0);
+ foo_ = foo_file_->message_type(1);
+ bar_ = foo_file_->message_type(2);
+ }
+
+ DescriptorPool pool_;
+
+ const FileDescriptor* foo_file_;
+
+ const Descriptor* foo_;
+ const Descriptor* bar_;
+ const EnumDescriptor* baz_;
+ const Descriptor* qux_;
+};
+
+TEST_F(ExtensionDescriptorTest, ExtensionRanges) {
+ EXPECT_EQ(0, bar_->extension_range_count());
+ ASSERT_EQ(2, foo_->extension_range_count());
+
+ EXPECT_EQ(10, foo_->extension_range(0)->start);
+ EXPECT_EQ(30, foo_->extension_range(1)->start);
+
+ EXPECT_EQ(20, foo_->extension_range(0)->end);
+ EXPECT_EQ(40, foo_->extension_range(1)->end);
+}
+
+TEST_F(ExtensionDescriptorTest, Extensions) {
+ EXPECT_EQ(0, foo_->extension_count());
+ ASSERT_EQ(2, foo_file_->extension_count());
+ ASSERT_EQ(2, bar_->extension_count());
+
+ EXPECT_TRUE(foo_file_->extension(0)->is_extension());
+ EXPECT_TRUE(foo_file_->extension(1)->is_extension());
+ EXPECT_TRUE(bar_->extension(0)->is_extension());
+ EXPECT_TRUE(bar_->extension(1)->is_extension());
+
+ EXPECT_EQ("foo_int32", foo_file_->extension(0)->name());
+ EXPECT_EQ("foo_enum", foo_file_->extension(1)->name());
+ EXPECT_EQ("foo_message", bar_->extension(0)->name());
+ EXPECT_EQ("foo_group", bar_->extension(1)->name());
+
+ EXPECT_EQ(10, foo_file_->extension(0)->number());
+ EXPECT_EQ(19, foo_file_->extension(1)->number());
+ EXPECT_EQ(30, bar_->extension(0)->number());
+ EXPECT_EQ(39, bar_->extension(1)->number());
+
+ EXPECT_EQ(FieldDescriptor::TYPE_INT32, foo_file_->extension(0)->type());
+ EXPECT_EQ(FieldDescriptor::TYPE_ENUM, foo_file_->extension(1)->type());
+ EXPECT_EQ(FieldDescriptor::TYPE_MESSAGE, bar_->extension(0)->type());
+ EXPECT_EQ(FieldDescriptor::TYPE_GROUP, bar_->extension(1)->type());
+
+ EXPECT_EQ(baz_, foo_file_->extension(1)->enum_type());
+ EXPECT_EQ(qux_, bar_->extension(0)->message_type());
+ EXPECT_EQ(qux_, bar_->extension(1)->message_type());
+
+ EXPECT_EQ(FieldDescriptor::LABEL_OPTIONAL, foo_file_->extension(0)->label());
+ EXPECT_EQ(FieldDescriptor::LABEL_REPEATED, foo_file_->extension(1)->label());
+ EXPECT_EQ(FieldDescriptor::LABEL_OPTIONAL, bar_->extension(0)->label());
+ EXPECT_EQ(FieldDescriptor::LABEL_REPEATED, bar_->extension(1)->label());
+
+ EXPECT_EQ(foo_, foo_file_->extension(0)->containing_type());
+ EXPECT_EQ(foo_, foo_file_->extension(1)->containing_type());
+ EXPECT_EQ(foo_, bar_->extension(0)->containing_type());
+ EXPECT_EQ(foo_, bar_->extension(1)->containing_type());
+
+ EXPECT_TRUE(foo_file_->extension(0)->extension_scope() == nullptr);
+ EXPECT_TRUE(foo_file_->extension(1)->extension_scope() == nullptr);
+ EXPECT_EQ(bar_, bar_->extension(0)->extension_scope());
+ EXPECT_EQ(bar_, bar_->extension(1)->extension_scope());
+}
+
+TEST_F(ExtensionDescriptorTest, IsExtensionNumber) {
+ EXPECT_FALSE(foo_->IsExtensionNumber(9));
+ EXPECT_TRUE(foo_->IsExtensionNumber(10));
+ EXPECT_TRUE(foo_->IsExtensionNumber(19));
+ EXPECT_FALSE(foo_->IsExtensionNumber(20));
+ EXPECT_FALSE(foo_->IsExtensionNumber(29));
+ EXPECT_TRUE(foo_->IsExtensionNumber(30));
+ EXPECT_TRUE(foo_->IsExtensionNumber(39));
+ EXPECT_FALSE(foo_->IsExtensionNumber(40));
+}
+
+TEST_F(ExtensionDescriptorTest, FindExtensionByName) {
+ // Note that FileDescriptor::FindExtensionByName() is tested by
+ // FileDescriptorTest.
+ ASSERT_EQ(2, bar_->extension_count());
+
+ EXPECT_EQ(bar_->extension(0), bar_->FindExtensionByName("foo_message"));
+ EXPECT_EQ(bar_->extension(1), bar_->FindExtensionByName("foo_group"));
+
+ EXPECT_TRUE(bar_->FindExtensionByName("no_such_extension") == nullptr);
+ EXPECT_TRUE(foo_->FindExtensionByName("foo_int32") == nullptr);
+ EXPECT_TRUE(foo_->FindExtensionByName("foo_message") == nullptr);
+}
+
+TEST_F(ExtensionDescriptorTest, FieldVsExtension) {
+ EXPECT_EQ(foo_->FindFieldByName("foo_message"), nullptr);
+ EXPECT_EQ(bar_->FindFieldByName("foo_message"), nullptr);
+ EXPECT_NE(bar_->FindFieldByName("non_ext_int32"), nullptr);
+ EXPECT_EQ(foo_->FindExtensionByName("foo_message"), nullptr);
+ EXPECT_NE(bar_->FindExtensionByName("foo_message"), nullptr);
+ EXPECT_EQ(bar_->FindExtensionByName("non_ext_int32"), nullptr);
+}
+
+TEST_F(ExtensionDescriptorTest, FindExtensionByPrintableName) {
+ EXPECT_TRUE(pool_.FindExtensionByPrintableName(foo_, "no_such_extension") ==
+ nullptr);
+ EXPECT_TRUE(pool_.FindExtensionByPrintableName(bar_, "no_such_extension") ==
+ nullptr);
+
+ ASSERT_FALSE(pool_.FindExtensionByPrintableName(foo_, "Bar.foo_message") ==
+ nullptr);
+ ASSERT_FALSE(pool_.FindExtensionByPrintableName(foo_, "Bar.foo_group") ==
+ nullptr);
+ EXPECT_TRUE(pool_.FindExtensionByPrintableName(bar_, "foo_message") ==
+ nullptr);
+ EXPECT_TRUE(pool_.FindExtensionByPrintableName(bar_, "foo_group") == nullptr);
+ EXPECT_EQ(bar_->FindExtensionByName("foo_message"),
+ pool_.FindExtensionByPrintableName(foo_, "Bar.foo_message"));
+ EXPECT_EQ(bar_->FindExtensionByName("foo_group"),
+ pool_.FindExtensionByPrintableName(foo_, "Bar.foo_group"));
+
+ ASSERT_FALSE(pool_.FindExtensionByPrintableName(foo_, "foo_int32") ==
+ nullptr);
+ ASSERT_FALSE(pool_.FindExtensionByPrintableName(foo_, "foo_enum") == nullptr);
+ EXPECT_TRUE(pool_.FindExtensionByPrintableName(bar_, "foo_int32") == nullptr);
+ EXPECT_TRUE(pool_.FindExtensionByPrintableName(bar_, "foo_enum") == nullptr);
+ EXPECT_EQ(foo_file_->FindExtensionByName("foo_int32"),
+ pool_.FindExtensionByPrintableName(foo_, "foo_int32"));
+ EXPECT_EQ(foo_file_->FindExtensionByName("foo_enum"),
+ pool_.FindExtensionByPrintableName(foo_, "foo_enum"));
+}
+
+TEST_F(ExtensionDescriptorTest, FindAllExtensions) {
+ std::vector<const FieldDescriptor*> extensions;
+ pool_.FindAllExtensions(foo_, &extensions);
+ ASSERT_EQ(4, extensions.size());
+ EXPECT_EQ(10, extensions[0]->number());
+ EXPECT_EQ(19, extensions[1]->number());
+ EXPECT_EQ(30, extensions[2]->number());
+ EXPECT_EQ(39, extensions[3]->number());
+}
+
+
+TEST_F(ExtensionDescriptorTest, DuplicateFieldNumber) {
+ DescriptorPool pool;
+ FileDescriptorProto file_proto;
+ // Add "google/protobuf/descriptor.proto".
+ FileDescriptorProto::descriptor()->file()->CopyTo(&file_proto);
+ ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr);
+ // Add "foo.proto":
+ // import "google/protobuf/descriptor.proto";
+ // extend google.protobuf.FieldOptions {
+ // optional int32 option1 = 1000;
+ // }
+ file_proto.Clear();
+ file_proto.set_name("foo.proto");
+ file_proto.add_dependency("google/protobuf/descriptor.proto");
+ AddExtension(&file_proto, "google.protobuf.FieldOptions", "option1", 1000,
+ FieldDescriptorProto::LABEL_OPTIONAL,
+ FieldDescriptorProto::TYPE_INT32);
+ ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr);
+ // Add "bar.proto":
+ // import "google/protobuf/descriptor.proto";
+ // extend google.protobuf.FieldOptions {
+ // optional int32 option2 = 1000;
+ // }
+ file_proto.Clear();
+ file_proto.set_name("bar.proto");
+ file_proto.add_dependency("google/protobuf/descriptor.proto");
+ AddExtension(&file_proto, "google.protobuf.FieldOptions", "option2", 1000,
+ FieldDescriptorProto::LABEL_OPTIONAL,
+ FieldDescriptorProto::TYPE_INT32);
+ // Currently we only generate a warning for conflicting extension numbers.
+ // TODO(xiaofeng): Change it to an error.
+ ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr);
+}
+
+// ===================================================================
+
+// Ensure that overlapping extension ranges are not allowed.
+TEST(OverlappingExtensionRangeTest, ExtensionRangeInternal) {
+ // Build descriptors for the following definitions:
+ //
+ // message Foo {
+ // extensions 10 to 19;
+ // extensions 15;
+ // }
+ FileDescriptorProto foo_file;
+ foo_file.set_name("foo.proto");
+
+ DescriptorProto* foo = AddMessage(&foo_file, "Foo");
+ AddExtensionRange(foo, 10, 20);
+ AddExtensionRange(foo, 15, 16);
+
+ DescriptorPool pool;
+ MockErrorCollector error_collector;
+ // The extensions ranges are invalid, so the proto shouldn't build.
+ ASSERT_TRUE(pool.BuildFileCollectingErrors(foo_file, &error_collector) ==
+ nullptr);
+ ASSERT_EQ(
+ "foo.proto: Foo: NUMBER: Extension range 15 to 15 overlaps with "
+ "already-defined range 10 to 19.\n",
+ error_collector.text_);
+}
+
+TEST(OverlappingExtensionRangeTest, ExtensionRangeAfter) {
+ // Build descriptors for the following definitions:
+ //
+ // message Foo {
+ // extensions 10 to 19;
+ // extensions 15 to 24;
+ // }
+ FileDescriptorProto foo_file;
+ foo_file.set_name("foo.proto");
+
+ DescriptorProto* foo = AddMessage(&foo_file, "Foo");
+ AddExtensionRange(foo, 10, 20);
+ AddExtensionRange(foo, 15, 25);
+
+ DescriptorPool pool;
+ MockErrorCollector error_collector;
+ // The extensions ranges are invalid, so the proto shouldn't build.
+ ASSERT_TRUE(pool.BuildFileCollectingErrors(foo_file, &error_collector) ==
+ nullptr);
+ ASSERT_EQ(
+ "foo.proto: Foo: NUMBER: Extension range 15 to 24 overlaps with "
+ "already-defined range 10 to 19.\n",
+ error_collector.text_);
+}
+
+TEST(OverlappingExtensionRangeTest, ExtensionRangeBefore) {
+ // Build descriptors for the following definitions:
+ //
+ // message Foo {
+ // extensions 10 to 19;
+ // extensions 5 to 14;
+ // }
+ FileDescriptorProto foo_file;
+ foo_file.set_name("foo.proto");
+
+ DescriptorProto* foo = AddMessage(&foo_file, "Foo");
+ AddExtensionRange(foo, 10, 20);
+ AddExtensionRange(foo, 5, 15);
+
+ DescriptorPool pool;
+ MockErrorCollector error_collector;
+ // The extensions ranges are invalid, so the proto shouldn't build.
+ ASSERT_TRUE(pool.BuildFileCollectingErrors(foo_file, &error_collector) ==
+ nullptr);
+ ASSERT_EQ(
+ "foo.proto: Foo: NUMBER: Extension range 5 to 14 overlaps with "
+ "already-defined range 10 to 19.\n",
+ error_collector.text_);
+}
+
+// ===================================================================
+
+// Test reserved fields.
+class ReservedDescriptorTest : public testing::Test {
+ protected:
+ void SetUp() override {
+ // Build descriptors for the following definitions:
+ //
+ // message Foo {
+ // reserved 2, 9 to 11, 15;
+ // reserved "foo", "bar";
+ // }
+
+ FileDescriptorProto foo_file;
+ foo_file.set_name("foo.proto");
+
+ DescriptorProto* foo = AddMessage(&foo_file, "Foo");
+ AddReservedRange(foo, 2, 3);
+ AddReservedRange(foo, 9, 12);
+ AddReservedRange(foo, 15, 16);
+
+ foo->add_reserved_name("foo");
+ foo->add_reserved_name("bar");
+
+ // Build the descriptors and get the pointers.
+ foo_file_ = pool_.BuildFile(foo_file);
+ ASSERT_TRUE(foo_file_ != nullptr);
+
+ ASSERT_EQ(1, foo_file_->message_type_count());
+ foo_ = foo_file_->message_type(0);
+ }
+
+ DescriptorPool pool_;
+ const FileDescriptor* foo_file_;
+ const Descriptor* foo_;
+};
+
+TEST_F(ReservedDescriptorTest, ReservedRanges) {
+ ASSERT_EQ(3, foo_->reserved_range_count());
+
+ EXPECT_EQ(2, foo_->reserved_range(0)->start);
+ EXPECT_EQ(3, foo_->reserved_range(0)->end);
+
+ EXPECT_EQ(9, foo_->reserved_range(1)->start);
+ EXPECT_EQ(12, foo_->reserved_range(1)->end);
+
+ EXPECT_EQ(15, foo_->reserved_range(2)->start);
+ EXPECT_EQ(16, foo_->reserved_range(2)->end);
+}
+
+TEST_F(ReservedDescriptorTest, IsReservedNumber) {
+ EXPECT_FALSE(foo_->IsReservedNumber(1));
+ EXPECT_TRUE(foo_->IsReservedNumber(2));
+ EXPECT_FALSE(foo_->IsReservedNumber(3));
+ EXPECT_FALSE(foo_->IsReservedNumber(8));
+ EXPECT_TRUE(foo_->IsReservedNumber(9));
+ EXPECT_TRUE(foo_->IsReservedNumber(10));
+ EXPECT_TRUE(foo_->IsReservedNumber(11));
+ EXPECT_FALSE(foo_->IsReservedNumber(12));
+ EXPECT_FALSE(foo_->IsReservedNumber(13));
+ EXPECT_FALSE(foo_->IsReservedNumber(14));
+ EXPECT_TRUE(foo_->IsReservedNumber(15));
+ EXPECT_FALSE(foo_->IsReservedNumber(16));
+}
+
+TEST_F(ReservedDescriptorTest, ReservedNames) {
+ ASSERT_EQ(2, foo_->reserved_name_count());
+
+ EXPECT_EQ("foo", foo_->reserved_name(0));
+ EXPECT_EQ("bar", foo_->reserved_name(1));
+}
+
+TEST_F(ReservedDescriptorTest, IsReservedName) {
+ EXPECT_TRUE(foo_->IsReservedName("foo"));
+ EXPECT_TRUE(foo_->IsReservedName("bar"));
+ EXPECT_FALSE(foo_->IsReservedName("baz"));
+}
+
+// ===================================================================
+
+// Test reserved enum fields.
+class ReservedEnumDescriptorTest : public testing::Test {
+ protected:
+ void SetUp() override {
+ // Build descriptors for the following definitions:
+ //
+ // enum Foo {
+ // BAR = 1;
+ // reserved 2, 9 to 11, 15;
+ // reserved "foo", "bar";
+ // }
+
+ FileDescriptorProto foo_file;
+ foo_file.set_name("foo.proto");
+
+ EnumDescriptorProto* foo = AddEnum(&foo_file, "Foo");
+ EnumDescriptorProto* edge1 = AddEnum(&foo_file, "Edge1");
+ EnumDescriptorProto* edge2 = AddEnum(&foo_file, "Edge2");
+
+ AddEnumValue(foo, "BAR", 4);
+ AddReservedRange(foo, -5, -3);
+ AddReservedRange(foo, -2, 1);
+ AddReservedRange(foo, 2, 3);
+ AddReservedRange(foo, 9, 12);
+ AddReservedRange(foo, 15, 16);
+
+ foo->add_reserved_name("foo");
+ foo->add_reserved_name("bar");
+
+ // Some additional edge cases that cover most or all of the range of enum
+ // values
+
+ // Note: We use INT_MAX as the maximum reserved range upper bound,
+ // inclusive.
+ AddEnumValue(edge1, "EDGE1", 1);
+ AddReservedRange(edge1, 10, INT_MAX);
+ AddEnumValue(edge2, "EDGE2", 15);
+ AddReservedRange(edge2, INT_MIN, 10);
+
+ // Build the descriptors and get the pointers.
+ foo_file_ = pool_.BuildFile(foo_file);
+ ASSERT_TRUE(foo_file_ != nullptr);
+
+ ASSERT_EQ(3, foo_file_->enum_type_count());
+ foo_ = foo_file_->enum_type(0);
+ edge1_ = foo_file_->enum_type(1);
+ edge2_ = foo_file_->enum_type(2);
+ }
+
+ DescriptorPool pool_;
+ const FileDescriptor* foo_file_;
+ const EnumDescriptor* foo_;
+ const EnumDescriptor* edge1_;
+ const EnumDescriptor* edge2_;
+};
+
+TEST_F(ReservedEnumDescriptorTest, ReservedRanges) {
+ ASSERT_EQ(5, foo_->reserved_range_count());
+
+ EXPECT_EQ(-5, foo_->reserved_range(0)->start);
+ EXPECT_EQ(-3, foo_->reserved_range(0)->end);
+
+ EXPECT_EQ(-2, foo_->reserved_range(1)->start);
+ EXPECT_EQ(1, foo_->reserved_range(1)->end);
+
+ EXPECT_EQ(2, foo_->reserved_range(2)->start);
+ EXPECT_EQ(3, foo_->reserved_range(2)->end);
+
+ EXPECT_EQ(9, foo_->reserved_range(3)->start);
+ EXPECT_EQ(12, foo_->reserved_range(3)->end);
+
+ EXPECT_EQ(15, foo_->reserved_range(4)->start);
+ EXPECT_EQ(16, foo_->reserved_range(4)->end);
+
+ ASSERT_EQ(1, edge1_->reserved_range_count());
+ EXPECT_EQ(10, edge1_->reserved_range(0)->start);
+ EXPECT_EQ(INT_MAX, edge1_->reserved_range(0)->end);
+
+ ASSERT_EQ(1, edge2_->reserved_range_count());
+ EXPECT_EQ(INT_MIN, edge2_->reserved_range(0)->start);
+ EXPECT_EQ(10, edge2_->reserved_range(0)->end);
+}
+
+TEST_F(ReservedEnumDescriptorTest, IsReservedNumber) {
+ EXPECT_TRUE(foo_->IsReservedNumber(-5));
+ EXPECT_TRUE(foo_->IsReservedNumber(-4));
+ EXPECT_TRUE(foo_->IsReservedNumber(-3));
+ EXPECT_TRUE(foo_->IsReservedNumber(-2));
+ EXPECT_TRUE(foo_->IsReservedNumber(-1));
+ EXPECT_TRUE(foo_->IsReservedNumber(0));
+ EXPECT_TRUE(foo_->IsReservedNumber(1));
+ EXPECT_TRUE(foo_->IsReservedNumber(2));
+ EXPECT_TRUE(foo_->IsReservedNumber(3));
+ EXPECT_FALSE(foo_->IsReservedNumber(8));
+ EXPECT_TRUE(foo_->IsReservedNumber(9));
+ EXPECT_TRUE(foo_->IsReservedNumber(10));
+ EXPECT_TRUE(foo_->IsReservedNumber(11));
+ EXPECT_TRUE(foo_->IsReservedNumber(12));
+ EXPECT_FALSE(foo_->IsReservedNumber(13));
+ EXPECT_FALSE(foo_->IsReservedNumber(13));
+ EXPECT_FALSE(foo_->IsReservedNumber(14));
+ EXPECT_TRUE(foo_->IsReservedNumber(15));
+ EXPECT_TRUE(foo_->IsReservedNumber(16));
+ EXPECT_FALSE(foo_->IsReservedNumber(17));
+
+ EXPECT_FALSE(edge1_->IsReservedNumber(9));
+ EXPECT_TRUE(edge1_->IsReservedNumber(10));
+ EXPECT_TRUE(edge1_->IsReservedNumber(INT_MAX - 1));
+ EXPECT_TRUE(edge1_->IsReservedNumber(INT_MAX));
+
+ EXPECT_TRUE(edge2_->IsReservedNumber(INT_MIN));
+ EXPECT_TRUE(edge2_->IsReservedNumber(9));
+ EXPECT_TRUE(edge2_->IsReservedNumber(10));
+ EXPECT_FALSE(edge2_->IsReservedNumber(11));
+}
+
+TEST_F(ReservedEnumDescriptorTest, ReservedNames) {
+ ASSERT_EQ(2, foo_->reserved_name_count());
+
+ EXPECT_EQ("foo", foo_->reserved_name(0));
+ EXPECT_EQ("bar", foo_->reserved_name(1));
+}
+
+TEST_F(ReservedEnumDescriptorTest, IsReservedName) {
+ EXPECT_TRUE(foo_->IsReservedName("foo"));
+ EXPECT_TRUE(foo_->IsReservedName("bar"));
+ EXPECT_FALSE(foo_->IsReservedName("baz"));
+}
+
+// ===================================================================
+
+class MiscTest : public testing::Test {
+ protected:
+ // Function which makes a field descriptor of the given type.
+ const FieldDescriptor* GetFieldDescriptorOfType(FieldDescriptor::Type type) {
+ FileDescriptorProto file_proto;
+ file_proto.set_name("foo.proto");
+ AddEmptyEnum(&file_proto, "DummyEnum");
+
+ DescriptorProto* message = AddMessage(&file_proto, "TestMessage");
+ FieldDescriptorProto* field = AddField(
+ message, "foo", 1, FieldDescriptorProto::LABEL_OPTIONAL,
+ static_cast<FieldDescriptorProto::Type>(static_cast<int>(type)));
+
+ if (type == FieldDescriptor::TYPE_MESSAGE ||
+ type == FieldDescriptor::TYPE_GROUP) {
+ field->set_type_name("TestMessage");
+ } else if (type == FieldDescriptor::TYPE_ENUM) {
+ field->set_type_name("DummyEnum");
+ }
+
+ // Build the descriptors and get the pointers.
+ pool_.reset(new DescriptorPool());
+ const FileDescriptor* file = pool_->BuildFile(file_proto);
+
+ if (file != nullptr && file->message_type_count() == 1 &&
+ file->message_type(0)->field_count() == 1) {
+ return file->message_type(0)->field(0);
+ } else {
+ return nullptr;
+ }
+ }
+
+ const char* GetTypeNameForFieldType(FieldDescriptor::Type type) {
+ const FieldDescriptor* field = GetFieldDescriptorOfType(type);
+ return field != nullptr ? field->type_name() : "";
+ }
+
+ FieldDescriptor::CppType GetCppTypeForFieldType(FieldDescriptor::Type type) {
+ const FieldDescriptor* field = GetFieldDescriptorOfType(type);
+ return field != nullptr ? field->cpp_type()
+ : static_cast<FieldDescriptor::CppType>(0);
+ }
+
+ const char* GetCppTypeNameForFieldType(FieldDescriptor::Type type) {
+ const FieldDescriptor* field = GetFieldDescriptorOfType(type);
+ return field != nullptr ? field->cpp_type_name() : "";
+ }
+
+ const Descriptor* GetMessageDescriptorForFieldType(
+ FieldDescriptor::Type type) {
+ const FieldDescriptor* field = GetFieldDescriptorOfType(type);
+ return field != nullptr ? field->message_type() : nullptr;
+ }
+
+ const EnumDescriptor* GetEnumDescriptorForFieldType(
+ FieldDescriptor::Type type) {
+ const FieldDescriptor* field = GetFieldDescriptorOfType(type);
+ return field != nullptr ? field->enum_type() : nullptr;
+ }
+
+ std::unique_ptr<DescriptorPool> pool_;
+};
+
+TEST_F(MiscTest, TypeNames) {
+ // Test that correct type names are returned.
+
+ typedef FieldDescriptor FD; // avoid ugly line wrapping
+
+ EXPECT_STREQ("double", GetTypeNameForFieldType(FD::TYPE_DOUBLE));
+ EXPECT_STREQ("float", GetTypeNameForFieldType(FD::TYPE_FLOAT));
+ EXPECT_STREQ("int64", GetTypeNameForFieldType(FD::TYPE_INT64));
+ EXPECT_STREQ("uint64", GetTypeNameForFieldType(FD::TYPE_UINT64));
+ EXPECT_STREQ("int32", GetTypeNameForFieldType(FD::TYPE_INT32));
+ EXPECT_STREQ("fixed64", GetTypeNameForFieldType(FD::TYPE_FIXED64));
+ EXPECT_STREQ("fixed32", GetTypeNameForFieldType(FD::TYPE_FIXED32));
+ EXPECT_STREQ("bool", GetTypeNameForFieldType(FD::TYPE_BOOL));
+ EXPECT_STREQ("string", GetTypeNameForFieldType(FD::TYPE_STRING));
+ EXPECT_STREQ("group", GetTypeNameForFieldType(FD::TYPE_GROUP));
+ EXPECT_STREQ("message", GetTypeNameForFieldType(FD::TYPE_MESSAGE));
+ EXPECT_STREQ("bytes", GetTypeNameForFieldType(FD::TYPE_BYTES));
+ EXPECT_STREQ("uint32", GetTypeNameForFieldType(FD::TYPE_UINT32));
+ EXPECT_STREQ("enum", GetTypeNameForFieldType(FD::TYPE_ENUM));
+ EXPECT_STREQ("sfixed32", GetTypeNameForFieldType(FD::TYPE_SFIXED32));
+ EXPECT_STREQ("sfixed64", GetTypeNameForFieldType(FD::TYPE_SFIXED64));
+ EXPECT_STREQ("sint32", GetTypeNameForFieldType(FD::TYPE_SINT32));
+ EXPECT_STREQ("sint64", GetTypeNameForFieldType(FD::TYPE_SINT64));
+}
+
+TEST_F(MiscTest, StaticTypeNames) {
+ // Test that correct type names are returned.
+
+ typedef FieldDescriptor FD; // avoid ugly line wrapping
+
+ EXPECT_STREQ("double", FD::TypeName(FD::TYPE_DOUBLE));
+ EXPECT_STREQ("float", FD::TypeName(FD::TYPE_FLOAT));
+ EXPECT_STREQ("int64", FD::TypeName(FD::TYPE_INT64));
+ EXPECT_STREQ("uint64", FD::TypeName(FD::TYPE_UINT64));
+ EXPECT_STREQ("int32", FD::TypeName(FD::TYPE_INT32));
+ EXPECT_STREQ("fixed64", FD::TypeName(FD::TYPE_FIXED64));
+ EXPECT_STREQ("fixed32", FD::TypeName(FD::TYPE_FIXED32));
+ EXPECT_STREQ("bool", FD::TypeName(FD::TYPE_BOOL));
+ EXPECT_STREQ("string", FD::TypeName(FD::TYPE_STRING));
+ EXPECT_STREQ("group", FD::TypeName(FD::TYPE_GROUP));
+ EXPECT_STREQ("message", FD::TypeName(FD::TYPE_MESSAGE));
+ EXPECT_STREQ("bytes", FD::TypeName(FD::TYPE_BYTES));
+ EXPECT_STREQ("uint32", FD::TypeName(FD::TYPE_UINT32));
+ EXPECT_STREQ("enum", FD::TypeName(FD::TYPE_ENUM));
+ EXPECT_STREQ("sfixed32", FD::TypeName(FD::TYPE_SFIXED32));
+ EXPECT_STREQ("sfixed64", FD::TypeName(FD::TYPE_SFIXED64));
+ EXPECT_STREQ("sint32", FD::TypeName(FD::TYPE_SINT32));
+ EXPECT_STREQ("sint64", FD::TypeName(FD::TYPE_SINT64));
+}
+
+TEST_F(MiscTest, CppTypes) {
+ // Test that CPP types are assigned correctly.
+
+ typedef FieldDescriptor FD; // avoid ugly line wrapping
+
+ EXPECT_EQ(FD::CPPTYPE_DOUBLE, GetCppTypeForFieldType(FD::TYPE_DOUBLE));
+ EXPECT_EQ(FD::CPPTYPE_FLOAT, GetCppTypeForFieldType(FD::TYPE_FLOAT));
+ EXPECT_EQ(FD::CPPTYPE_INT64, GetCppTypeForFieldType(FD::TYPE_INT64));
+ EXPECT_EQ(FD::CPPTYPE_UINT64, GetCppTypeForFieldType(FD::TYPE_UINT64));
+ EXPECT_EQ(FD::CPPTYPE_INT32, GetCppTypeForFieldType(FD::TYPE_INT32));
+ EXPECT_EQ(FD::CPPTYPE_UINT64, GetCppTypeForFieldType(FD::TYPE_FIXED64));
+ EXPECT_EQ(FD::CPPTYPE_UINT32, GetCppTypeForFieldType(FD::TYPE_FIXED32));
+ EXPECT_EQ(FD::CPPTYPE_BOOL, GetCppTypeForFieldType(FD::TYPE_BOOL));
+ EXPECT_EQ(FD::CPPTYPE_STRING, GetCppTypeForFieldType(FD::TYPE_STRING));
+ EXPECT_EQ(FD::CPPTYPE_MESSAGE, GetCppTypeForFieldType(FD::TYPE_GROUP));
+ EXPECT_EQ(FD::CPPTYPE_MESSAGE, GetCppTypeForFieldType(FD::TYPE_MESSAGE));
+ EXPECT_EQ(FD::CPPTYPE_STRING, GetCppTypeForFieldType(FD::TYPE_BYTES));
+ EXPECT_EQ(FD::CPPTYPE_UINT32, GetCppTypeForFieldType(FD::TYPE_UINT32));
+ EXPECT_EQ(FD::CPPTYPE_ENUM, GetCppTypeForFieldType(FD::TYPE_ENUM));
+ EXPECT_EQ(FD::CPPTYPE_INT32, GetCppTypeForFieldType(FD::TYPE_SFIXED32));
+ EXPECT_EQ(FD::CPPTYPE_INT64, GetCppTypeForFieldType(FD::TYPE_SFIXED64));
+ EXPECT_EQ(FD::CPPTYPE_INT32, GetCppTypeForFieldType(FD::TYPE_SINT32));
+ EXPECT_EQ(FD::CPPTYPE_INT64, GetCppTypeForFieldType(FD::TYPE_SINT64));
+}
+
+TEST_F(MiscTest, CppTypeNames) {
+ // Test that correct CPP type names are returned.
+
+ typedef FieldDescriptor FD; // avoid ugly line wrapping
+
+ EXPECT_STREQ("double", GetCppTypeNameForFieldType(FD::TYPE_DOUBLE));
+ EXPECT_STREQ("float", GetCppTypeNameForFieldType(FD::TYPE_FLOAT));
+ EXPECT_STREQ("int64", GetCppTypeNameForFieldType(FD::TYPE_INT64));
+ EXPECT_STREQ("uint64", GetCppTypeNameForFieldType(FD::TYPE_UINT64));
+ EXPECT_STREQ("int32", GetCppTypeNameForFieldType(FD::TYPE_INT32));
+ EXPECT_STREQ("uint64", GetCppTypeNameForFieldType(FD::TYPE_FIXED64));
+ EXPECT_STREQ("uint32", GetCppTypeNameForFieldType(FD::TYPE_FIXED32));
+ EXPECT_STREQ("bool", GetCppTypeNameForFieldType(FD::TYPE_BOOL));
+ EXPECT_STREQ("string", GetCppTypeNameForFieldType(FD::TYPE_STRING));
+ EXPECT_STREQ("message", GetCppTypeNameForFieldType(FD::TYPE_GROUP));
+ EXPECT_STREQ("message", GetCppTypeNameForFieldType(FD::TYPE_MESSAGE));
+ EXPECT_STREQ("string", GetCppTypeNameForFieldType(FD::TYPE_BYTES));
+ EXPECT_STREQ("uint32", GetCppTypeNameForFieldType(FD::TYPE_UINT32));
+ EXPECT_STREQ("enum", GetCppTypeNameForFieldType(FD::TYPE_ENUM));
+ EXPECT_STREQ("int32", GetCppTypeNameForFieldType(FD::TYPE_SFIXED32));
+ EXPECT_STREQ("int64", GetCppTypeNameForFieldType(FD::TYPE_SFIXED64));
+ EXPECT_STREQ("int32", GetCppTypeNameForFieldType(FD::TYPE_SINT32));
+ EXPECT_STREQ("int64", GetCppTypeNameForFieldType(FD::TYPE_SINT64));
+}
+
+TEST_F(MiscTest, StaticCppTypeNames) {
+ // Test that correct CPP type names are returned.
+
+ typedef FieldDescriptor FD; // avoid ugly line wrapping
+
+ EXPECT_STREQ("int32", FD::CppTypeName(FD::CPPTYPE_INT32));
+ EXPECT_STREQ("int64", FD::CppTypeName(FD::CPPTYPE_INT64));
+ EXPECT_STREQ("uint32", FD::CppTypeName(FD::CPPTYPE_UINT32));
+ EXPECT_STREQ("uint64", FD::CppTypeName(FD::CPPTYPE_UINT64));
+ EXPECT_STREQ("double", FD::CppTypeName(FD::CPPTYPE_DOUBLE));
+ EXPECT_STREQ("float", FD::CppTypeName(FD::CPPTYPE_FLOAT));
+ EXPECT_STREQ("bool", FD::CppTypeName(FD::CPPTYPE_BOOL));
+ EXPECT_STREQ("enum", FD::CppTypeName(FD::CPPTYPE_ENUM));
+ EXPECT_STREQ("string", FD::CppTypeName(FD::CPPTYPE_STRING));
+ EXPECT_STREQ("message", FD::CppTypeName(FD::CPPTYPE_MESSAGE));
+}
+
+TEST_F(MiscTest, MessageType) {
+ // Test that message_type() is nullptr for non-aggregate fields
+
+ typedef FieldDescriptor FD; // avoid ugly line wrapping
+
+ EXPECT_TRUE(nullptr == GetMessageDescriptorForFieldType(FD::TYPE_DOUBLE));
+ EXPECT_TRUE(nullptr == GetMessageDescriptorForFieldType(FD::TYPE_FLOAT));
+ EXPECT_TRUE(nullptr == GetMessageDescriptorForFieldType(FD::TYPE_INT64));
+ EXPECT_TRUE(nullptr == GetMessageDescriptorForFieldType(FD::TYPE_UINT64));
+ EXPECT_TRUE(nullptr == GetMessageDescriptorForFieldType(FD::TYPE_INT32));
+ EXPECT_TRUE(nullptr == GetMessageDescriptorForFieldType(FD::TYPE_FIXED64));
+ EXPECT_TRUE(nullptr == GetMessageDescriptorForFieldType(FD::TYPE_FIXED32));
+ EXPECT_TRUE(nullptr == GetMessageDescriptorForFieldType(FD::TYPE_BOOL));
+ EXPECT_TRUE(nullptr == GetMessageDescriptorForFieldType(FD::TYPE_STRING));
+ EXPECT_TRUE(nullptr != GetMessageDescriptorForFieldType(FD::TYPE_GROUP));
+ EXPECT_TRUE(nullptr != GetMessageDescriptorForFieldType(FD::TYPE_MESSAGE));
+ EXPECT_TRUE(nullptr == GetMessageDescriptorForFieldType(FD::TYPE_BYTES));
+ EXPECT_TRUE(nullptr == GetMessageDescriptorForFieldType(FD::TYPE_UINT32));
+ EXPECT_TRUE(nullptr == GetMessageDescriptorForFieldType(FD::TYPE_ENUM));
+ EXPECT_TRUE(nullptr == GetMessageDescriptorForFieldType(FD::TYPE_SFIXED32));
+ EXPECT_TRUE(nullptr == GetMessageDescriptorForFieldType(FD::TYPE_SFIXED64));
+ EXPECT_TRUE(nullptr == GetMessageDescriptorForFieldType(FD::TYPE_SINT32));
+ EXPECT_TRUE(nullptr == GetMessageDescriptorForFieldType(FD::TYPE_SINT64));
+}
+
+TEST_F(MiscTest, EnumType) {
+ // Test that enum_type() is nullptr for non-enum fields
+
+ typedef FieldDescriptor FD; // avoid ugly line wrapping
+
+ EXPECT_TRUE(nullptr == GetEnumDescriptorForFieldType(FD::TYPE_DOUBLE));
+ EXPECT_TRUE(nullptr == GetEnumDescriptorForFieldType(FD::TYPE_FLOAT));
+ EXPECT_TRUE(nullptr == GetEnumDescriptorForFieldType(FD::TYPE_INT64));
+ EXPECT_TRUE(nullptr == GetEnumDescriptorForFieldType(FD::TYPE_UINT64));
+ EXPECT_TRUE(nullptr == GetEnumDescriptorForFieldType(FD::TYPE_INT32));
+ EXPECT_TRUE(nullptr == GetEnumDescriptorForFieldType(FD::TYPE_FIXED64));
+ EXPECT_TRUE(nullptr == GetEnumDescriptorForFieldType(FD::TYPE_FIXED32));
+ EXPECT_TRUE(nullptr == GetEnumDescriptorForFieldType(FD::TYPE_BOOL));
+ EXPECT_TRUE(nullptr == GetEnumDescriptorForFieldType(FD::TYPE_STRING));
+ EXPECT_TRUE(nullptr == GetEnumDescriptorForFieldType(FD::TYPE_GROUP));
+ EXPECT_TRUE(nullptr == GetEnumDescriptorForFieldType(FD::TYPE_MESSAGE));
+ EXPECT_TRUE(nullptr == GetEnumDescriptorForFieldType(FD::TYPE_BYTES));
+ EXPECT_TRUE(nullptr == GetEnumDescriptorForFieldType(FD::TYPE_UINT32));
+ EXPECT_TRUE(nullptr != GetEnumDescriptorForFieldType(FD::TYPE_ENUM));
+ EXPECT_TRUE(nullptr == GetEnumDescriptorForFieldType(FD::TYPE_SFIXED32));
+ EXPECT_TRUE(nullptr == GetEnumDescriptorForFieldType(FD::TYPE_SFIXED64));
+ EXPECT_TRUE(nullptr == GetEnumDescriptorForFieldType(FD::TYPE_SINT32));
+ EXPECT_TRUE(nullptr == GetEnumDescriptorForFieldType(FD::TYPE_SINT64));
+}
+
+TEST_F(MiscTest, DefaultValues) {
+ // Test that setting default values works.
+ FileDescriptorProto file_proto;
+ file_proto.set_name("foo.proto");
+
+ EnumDescriptorProto* enum_type_proto = AddEnum(&file_proto, "DummyEnum");
+ AddEnumValue(enum_type_proto, "A", 1);
+ AddEnumValue(enum_type_proto, "B", 2);
+
+ DescriptorProto* message_proto = AddMessage(&file_proto, "TestMessage");
+
+ typedef FieldDescriptorProto FD; // avoid ugly line wrapping
+ const FD::Label label = FD::LABEL_OPTIONAL;
+
+ // Create fields of every CPP type with default values.
+ AddField(message_proto, "int32", 1, label, FD::TYPE_INT32)
+ ->set_default_value("-1");
+ AddField(message_proto, "int64", 2, label, FD::TYPE_INT64)
+ ->set_default_value("-1000000000000");
+ AddField(message_proto, "uint32", 3, label, FD::TYPE_UINT32)
+ ->set_default_value("42");
+ AddField(message_proto, "uint64", 4, label, FD::TYPE_UINT64)
+ ->set_default_value("2000000000000");
+ AddField(message_proto, "float", 5, label, FD::TYPE_FLOAT)
+ ->set_default_value("4.5");
+ AddField(message_proto, "double", 6, label, FD::TYPE_DOUBLE)
+ ->set_default_value("10e100");
+ AddField(message_proto, "bool", 7, label, FD::TYPE_BOOL)
+ ->set_default_value("true");
+ AddField(message_proto, "string", 8, label, FD::TYPE_STRING)
+ ->set_default_value("hello");
+ AddField(message_proto, "data", 9, label, FD::TYPE_BYTES)
+ ->set_default_value("\\001\\002\\003");
+
+ FieldDescriptorProto* enum_field =
+ AddField(message_proto, "enum", 10, label, FD::TYPE_ENUM);
+ enum_field->set_type_name("DummyEnum");
+ enum_field->set_default_value("B");
+
+ // Strings are allowed to have empty defaults. (At one point, due to
+ // a bug, empty defaults for strings were rejected. Oops.)
+ AddField(message_proto, "empty_string", 11, label, FD::TYPE_STRING)
+ ->set_default_value("");
+
+ // Add a second set of fields with implicit default values.
+ AddField(message_proto, "implicit_int32", 21, label, FD::TYPE_INT32);
+ AddField(message_proto, "implicit_int64", 22, label, FD::TYPE_INT64);
+ AddField(message_proto, "implicit_uint32", 23, label, FD::TYPE_UINT32);
+ AddField(message_proto, "implicit_uint64", 24, label, FD::TYPE_UINT64);
+ AddField(message_proto, "implicit_float", 25, label, FD::TYPE_FLOAT);
+ AddField(message_proto, "implicit_double", 26, label, FD::TYPE_DOUBLE);
+ AddField(message_proto, "implicit_bool", 27, label, FD::TYPE_BOOL);
+ AddField(message_proto, "implicit_string", 28, label, FD::TYPE_STRING);
+ AddField(message_proto, "implicit_data", 29, label, FD::TYPE_BYTES);
+ AddField(message_proto, "implicit_enum", 30, label, FD::TYPE_ENUM)
+ ->set_type_name("DummyEnum");
+
+ // Build it.
+ DescriptorPool pool;
+ const FileDescriptor* file = pool.BuildFile(file_proto);
+ ASSERT_TRUE(file != nullptr);
+
+ ASSERT_EQ(1, file->enum_type_count());
+ const EnumDescriptor* enum_type = file->enum_type(0);
+ ASSERT_EQ(2, enum_type->value_count());
+ const EnumValueDescriptor* enum_value_a = enum_type->value(0);
+ const EnumValueDescriptor* enum_value_b = enum_type->value(1);
+
+ ASSERT_EQ(1, file->message_type_count());
+ const Descriptor* message = file->message_type(0);
+
+ ASSERT_EQ(21, message->field_count());
+
+ // Check the default values.
+ ASSERT_TRUE(message->field(0)->has_default_value());
+ ASSERT_TRUE(message->field(1)->has_default_value());
+ ASSERT_TRUE(message->field(2)->has_default_value());
+ ASSERT_TRUE(message->field(3)->has_default_value());
+ ASSERT_TRUE(message->field(4)->has_default_value());
+ ASSERT_TRUE(message->field(5)->has_default_value());
+ ASSERT_TRUE(message->field(6)->has_default_value());
+ ASSERT_TRUE(message->field(7)->has_default_value());
+ ASSERT_TRUE(message->field(8)->has_default_value());
+ ASSERT_TRUE(message->field(9)->has_default_value());
+ ASSERT_TRUE(message->field(10)->has_default_value());
+
+ EXPECT_EQ(-1, message->field(0)->default_value_int32());
+ EXPECT_EQ(int64{-1000000000000}, message->field(1)->default_value_int64());
+ EXPECT_EQ(42, message->field(2)->default_value_uint32());
+ EXPECT_EQ(uint64{2000000000000}, message->field(3)->default_value_uint64());
+ EXPECT_EQ(4.5, message->field(4)->default_value_float());
+ EXPECT_EQ(10e100, message->field(5)->default_value_double());
+ EXPECT_TRUE(message->field(6)->default_value_bool());
+ EXPECT_EQ("hello", message->field(7)->default_value_string());
+ EXPECT_EQ("\001\002\003", message->field(8)->default_value_string());
+ EXPECT_EQ(enum_value_b, message->field(9)->default_value_enum());
+ EXPECT_EQ("", message->field(10)->default_value_string());
+
+ ASSERT_FALSE(message->field(11)->has_default_value());
+ ASSERT_FALSE(message->field(12)->has_default_value());
+ ASSERT_FALSE(message->field(13)->has_default_value());
+ ASSERT_FALSE(message->field(14)->has_default_value());
+ ASSERT_FALSE(message->field(15)->has_default_value());
+ ASSERT_FALSE(message->field(16)->has_default_value());
+ ASSERT_FALSE(message->field(17)->has_default_value());
+ ASSERT_FALSE(message->field(18)->has_default_value());
+ ASSERT_FALSE(message->field(19)->has_default_value());
+ ASSERT_FALSE(message->field(20)->has_default_value());
+
+ EXPECT_EQ(0, message->field(11)->default_value_int32());
+ EXPECT_EQ(0, message->field(12)->default_value_int64());
+ EXPECT_EQ(0, message->field(13)->default_value_uint32());
+ EXPECT_EQ(0, message->field(14)->default_value_uint64());
+ EXPECT_EQ(0.0f, message->field(15)->default_value_float());
+ EXPECT_EQ(0.0, message->field(16)->default_value_double());
+ EXPECT_FALSE(message->field(17)->default_value_bool());
+ EXPECT_EQ("", message->field(18)->default_value_string());
+ EXPECT_EQ("", message->field(19)->default_value_string());
+ EXPECT_EQ(enum_value_a, message->field(20)->default_value_enum());
+}
+
+TEST_F(MiscTest, FieldOptions) {
+ // Try setting field options.
+
+ FileDescriptorProto file_proto;
+ file_proto.set_name("foo.proto");
+
+ DescriptorProto* message_proto = AddMessage(&file_proto, "TestMessage");
+ AddField(message_proto, "foo", 1, FieldDescriptorProto::LABEL_OPTIONAL,
+ FieldDescriptorProto::TYPE_INT32);
+ FieldDescriptorProto* bar_proto =
+ AddField(message_proto, "bar", 2, FieldDescriptorProto::LABEL_OPTIONAL,
+ FieldDescriptorProto::TYPE_INT32);
+
+ FieldOptions* options = bar_proto->mutable_options();
+ options->set_ctype(FieldOptions::CORD);
+
+ // Build the descriptors and get the pointers.
+ DescriptorPool pool;
+ const FileDescriptor* file = pool.BuildFile(file_proto);
+ ASSERT_TRUE(file != nullptr);
+
+ ASSERT_EQ(1, file->message_type_count());
+ const Descriptor* message = file->message_type(0);
+
+ ASSERT_EQ(2, message->field_count());
+ const FieldDescriptor* foo = message->field(0);
+ const FieldDescriptor* bar = message->field(1);
+
+ // "foo" had no options set, so it should return the default options.
+ EXPECT_EQ(&FieldOptions::default_instance(), &foo->options());
+
+ // "bar" had options set.
+ EXPECT_NE(&FieldOptions::default_instance(), options);
+ EXPECT_TRUE(bar->options().has_ctype());
+ EXPECT_EQ(FieldOptions::CORD, bar->options().ctype());
+}
+
+// ===================================================================
+enum DescriptorPoolMode { NO_DATABASE, FALLBACK_DATABASE };
+
+class AllowUnknownDependenciesTest
+ : public testing::TestWithParam<
+ std::tuple<DescriptorPoolMode, const char*>> {
+ protected:
+ DescriptorPoolMode mode() { return std::get<0>(GetParam()); }
+ const char* syntax() { return std::get<1>(GetParam()); }
+
+ void SetUp() override {
+ FileDescriptorProto foo_proto, bar_proto;
+
+ switch (mode()) {
+ case NO_DATABASE:
+ pool_.reset(new DescriptorPool);
+ break;
+ case FALLBACK_DATABASE:
+ pool_.reset(new DescriptorPool(&db_));
+ break;
+ }
+
+ pool_->AllowUnknownDependencies();
+
+ ASSERT_TRUE(TextFormat::ParseFromString(
+ "name: 'foo.proto'"
+ "dependency: 'bar.proto'"
+ "dependency: 'baz.proto'"
+ "message_type {"
+ " name: 'Foo'"
+ " field { name:'bar' number:1 label:LABEL_OPTIONAL type_name:'Bar' }"
+ " field { name:'baz' number:2 label:LABEL_OPTIONAL type_name:'Baz' }"
+ " field { name:'qux' number:3 label:LABEL_OPTIONAL"
+ " type_name: '.corge.Qux'"
+ " type: TYPE_ENUM"
+ " options {"
+ " uninterpreted_option {"
+ " name {"
+ " name_part: 'grault'"
+ " is_extension: true"
+ " }"
+ " positive_int_value: 1234"
+ " }"
+ " }"
+ " }"
+ "}",
+ &foo_proto));
+ foo_proto.set_syntax(syntax());
+
+ ASSERT_TRUE(
+ TextFormat::ParseFromString("name: 'bar.proto'"
+ "message_type { name: 'Bar' }",
+ &bar_proto));
+ bar_proto.set_syntax(syntax());
+
+ // Collect pointers to stuff.
+ bar_file_ = BuildFile(bar_proto);
+ ASSERT_TRUE(bar_file_ != nullptr);
+
+ ASSERT_EQ(1, bar_file_->message_type_count());
+ bar_type_ = bar_file_->message_type(0);
+
+ foo_file_ = BuildFile(foo_proto);
+ ASSERT_TRUE(foo_file_ != nullptr);
+
+ ASSERT_EQ(1, foo_file_->message_type_count());
+ foo_type_ = foo_file_->message_type(0);
+
+ ASSERT_EQ(3, foo_type_->field_count());
+ bar_field_ = foo_type_->field(0);
+ baz_field_ = foo_type_->field(1);
+ qux_field_ = foo_type_->field(2);
+ }
+
+ const FileDescriptor* BuildFile(const FileDescriptorProto& proto) {
+ switch (mode()) {
+ case NO_DATABASE:
+ return pool_->BuildFile(proto);
+ break;
+ case FALLBACK_DATABASE: {
+ EXPECT_TRUE(db_.Add(proto));
+ return pool_->FindFileByName(proto.name());
+ }
+ }
+ GOOGLE_LOG(FATAL) << "Can't get here.";
+ return nullptr;
+ }
+
+ const FileDescriptor* bar_file_;
+ const Descriptor* bar_type_;
+ const FileDescriptor* foo_file_;
+ const Descriptor* foo_type_;
+ const FieldDescriptor* bar_field_;
+ const FieldDescriptor* baz_field_;
+ const FieldDescriptor* qux_field_;
+
+ SimpleDescriptorDatabase db_; // used if in FALLBACK_DATABASE mode.
+ std::unique_ptr<DescriptorPool> pool_;
+};
+
+TEST_P(AllowUnknownDependenciesTest, PlaceholderFile) {
+ ASSERT_EQ(2, foo_file_->dependency_count());
+ EXPECT_EQ(bar_file_, foo_file_->dependency(0));
+ EXPECT_FALSE(bar_file_->is_placeholder());
+
+ const FileDescriptor* baz_file = foo_file_->dependency(1);
+ EXPECT_EQ("baz.proto", baz_file->name());
+ EXPECT_EQ(0, baz_file->message_type_count());
+ EXPECT_TRUE(baz_file->is_placeholder());
+
+ // Placeholder files should not be findable.
+ EXPECT_EQ(bar_file_, pool_->FindFileByName(bar_file_->name()));
+ EXPECT_TRUE(pool_->FindFileByName(baz_file->name()) == nullptr);
+
+ // Copy*To should not crash for placeholder files.
+ FileDescriptorProto baz_file_proto;
+ baz_file->CopyTo(&baz_file_proto);
+ baz_file->CopySourceCodeInfoTo(&baz_file_proto);
+ EXPECT_FALSE(baz_file_proto.has_source_code_info());
+}
+
+TEST_P(AllowUnknownDependenciesTest, PlaceholderTypes) {
+ ASSERT_EQ(FieldDescriptor::TYPE_MESSAGE, bar_field_->type());
+ EXPECT_EQ(bar_type_, bar_field_->message_type());
+ EXPECT_FALSE(bar_type_->is_placeholder());
+
+ ASSERT_EQ(FieldDescriptor::TYPE_MESSAGE, baz_field_->type());
+ const Descriptor* baz_type = baz_field_->message_type();
+ EXPECT_EQ("Baz", baz_type->name());
+ EXPECT_EQ("Baz", baz_type->full_name());
+ EXPECT_EQ(0, baz_type->extension_range_count());
+ EXPECT_TRUE(baz_type->is_placeholder());
+
+ ASSERT_EQ(FieldDescriptor::TYPE_ENUM, qux_field_->type());
+ const EnumDescriptor* qux_type = qux_field_->enum_type();
+ EXPECT_EQ("Qux", qux_type->name());
+ EXPECT_EQ("corge.Qux", qux_type->full_name());
+ EXPECT_TRUE(qux_type->is_placeholder());
+ // Placeholder enum values should not be findable.
+ EXPECT_EQ(qux_type->FindValueByNumber(0), nullptr);
+
+ // Placeholder types should not be findable.
+ EXPECT_EQ(bar_type_, pool_->FindMessageTypeByName(bar_type_->full_name()));
+ EXPECT_TRUE(pool_->FindMessageTypeByName(baz_type->full_name()) == nullptr);
+ EXPECT_TRUE(pool_->FindEnumTypeByName(qux_type->full_name()) == nullptr);
+}
+
+TEST_P(AllowUnknownDependenciesTest, CopyTo) {
+ // FieldDescriptor::CopyTo() should write non-fully-qualified type names
+ // for placeholder types which were not originally fully-qualified.
+ FieldDescriptorProto proto;
+
+ // Bar is not a placeholder, so it is fully-qualified.
+ bar_field_->CopyTo(&proto);
+ EXPECT_EQ(".Bar", proto.type_name());
+ EXPECT_EQ(FieldDescriptorProto::TYPE_MESSAGE, proto.type());
+
+ // Baz is an unqualified placeholder.
+ proto.Clear();
+ baz_field_->CopyTo(&proto);
+ EXPECT_EQ("Baz", proto.type_name());
+ EXPECT_FALSE(proto.has_type());
+
+ // Qux is a fully-qualified placeholder.
+ proto.Clear();
+ qux_field_->CopyTo(&proto);
+ EXPECT_EQ(".corge.Qux", proto.type_name());
+ EXPECT_EQ(FieldDescriptorProto::TYPE_ENUM, proto.type());
+}
+
+TEST_P(AllowUnknownDependenciesTest, CustomOptions) {
+ // Qux should still have the uninterpreted option attached.
+ ASSERT_EQ(1, qux_field_->options().uninterpreted_option_size());
+ const UninterpretedOption& option =
+ qux_field_->options().uninterpreted_option(0);
+ ASSERT_EQ(1, option.name_size());
+ EXPECT_EQ("grault", option.name(0).name_part());
+}
+
+TEST_P(AllowUnknownDependenciesTest, UnknownExtendee) {
+ // Test that we can extend an unknown type. This is slightly tricky because
+ // it means that the placeholder type must have an extension range.
+
+ FileDescriptorProto extension_proto;
+
+ ASSERT_TRUE(TextFormat::ParseFromString(
+ "name: 'extension.proto'"
+ "extension { extendee: 'UnknownType' name:'some_extension' number:123"
+ " label:LABEL_OPTIONAL type:TYPE_INT32 }",
+ &extension_proto));
+ const FileDescriptor* file = BuildFile(extension_proto);
+
+ ASSERT_TRUE(file != nullptr);
+
+ ASSERT_EQ(1, file->extension_count());
+ const Descriptor* extendee = file->extension(0)->containing_type();
+ EXPECT_EQ("UnknownType", extendee->name());
+ EXPECT_TRUE(extendee->is_placeholder());
+ ASSERT_EQ(1, extendee->extension_range_count());
+ EXPECT_EQ(1, extendee->extension_range(0)->start);
+ EXPECT_EQ(FieldDescriptor::kMaxNumber + 1, extendee->extension_range(0)->end);
+}
+
+TEST_P(AllowUnknownDependenciesTest, CustomOption) {
+ // Test that we can use a custom option without having parsed
+ // descriptor.proto.
+
+ FileDescriptorProto option_proto;
+
+ ASSERT_TRUE(TextFormat::ParseFromString(
+ "name: \"unknown_custom_options.proto\" "
+ "dependency: \"google/protobuf/descriptor.proto\" "
+ "extension { "
+ " extendee: \"google.protobuf.FileOptions\" "
+ " name: \"some_option\" "
+ " number: 123456 "
+ " label: LABEL_OPTIONAL "
+ " type: TYPE_INT32 "
+ "} "
+ "options { "
+ " uninterpreted_option { "
+ " name { "
+ " name_part: \"some_option\" "
+ " is_extension: true "
+ " } "
+ " positive_int_value: 1234 "
+ " } "
+ " uninterpreted_option { "
+ " name { "
+ " name_part: \"unknown_option\" "
+ " is_extension: true "
+ " } "
+ " positive_int_value: 1234 "
+ " } "
+ " uninterpreted_option { "
+ " name { "
+ " name_part: \"optimize_for\" "
+ " is_extension: false "
+ " } "
+ " identifier_value: \"SPEED\" "
+ " } "
+ "}",
+ &option_proto));
+
+ const FileDescriptor* file = BuildFile(option_proto);
+ ASSERT_TRUE(file != nullptr);
+
+ // Verify that no extension options were set, but they were left as
+ // uninterpreted_options.
+ std::vector<const FieldDescriptor*> fields;
+ file->options().GetReflection()->ListFields(file->options(), &fields);
+ ASSERT_EQ(2, fields.size());
+ EXPECT_TRUE(file->options().has_optimize_for());
+ EXPECT_EQ(2, file->options().uninterpreted_option_size());
+}
+
+TEST_P(AllowUnknownDependenciesTest,
+ UndeclaredDependencyTriggersBuildOfDependency) {
+ // Crazy case: suppose foo.proto refers to a symbol without declaring the
+ // dependency that finds it. In the event that the pool is backed by a
+ // DescriptorDatabase, the pool will attempt to find the symbol in the
+ // database. If successful, it will build the undeclared dependency to verify
+ // that the file does indeed contain the symbol. If that file fails to build,
+ // then its descriptors must be rolled back. However, we still want foo.proto
+ // to build successfully, since we are allowing unknown dependencies.
+
+ FileDescriptorProto undeclared_dep_proto;
+ // We make this file fail to build by giving it two fields with tag 1.
+ ASSERT_TRUE(TextFormat::ParseFromString(
+ "name: \"invalid_file_as_undeclared_dep.proto\" "
+ "package: \"undeclared\" "
+ "message_type: { "
+ " name: \"Quux\" "
+ " field { "
+ " name:'qux' number:1 label:LABEL_OPTIONAL type: TYPE_INT32 "
+ " }"
+ " field { "
+ " name:'quux' number:1 label:LABEL_OPTIONAL type: TYPE_INT64 "
+ " }"
+ "}",
+ &undeclared_dep_proto));
+ // We can't use the BuildFile() helper because we don't actually want to build
+ // it into the descriptor pool in the fallback database case: it just needs to
+ // be sitting in the database so that it gets built during the building of
+ // test.proto below.
+ switch (mode()) {
+ case NO_DATABASE: {
+ ASSERT_TRUE(pool_->BuildFile(undeclared_dep_proto) == nullptr);
+ break;
+ }
+ case FALLBACK_DATABASE: {
+ ASSERT_TRUE(db_.Add(undeclared_dep_proto));
+ }
+ }
+
+ FileDescriptorProto test_proto;
+ ASSERT_TRUE(TextFormat::ParseFromString(
+ "name: \"test.proto\" "
+ "message_type: { "
+ " name: \"Corge\" "
+ " field { "
+ " name:'quux' number:1 label: LABEL_OPTIONAL "
+ " type_name:'undeclared.Quux' type: TYPE_MESSAGE "
+ " }"
+ "}",
+ &test_proto));
+
+ const FileDescriptor* file = BuildFile(test_proto);
+ ASSERT_TRUE(file != nullptr);
+ GOOGLE_LOG(INFO) << file->DebugString();
+
+ EXPECT_EQ(0, file->dependency_count());
+ ASSERT_EQ(1, file->message_type_count());
+ const Descriptor* corge_desc = file->message_type(0);
+ ASSERT_EQ("Corge", corge_desc->name());
+ ASSERT_EQ(1, corge_desc->field_count());
+ EXPECT_FALSE(corge_desc->is_placeholder());
+
+ const FieldDescriptor* quux_field = corge_desc->field(0);
+ ASSERT_EQ(FieldDescriptor::TYPE_MESSAGE, quux_field->type());
+ ASSERT_EQ("Quux", quux_field->message_type()->name());
+ ASSERT_EQ("undeclared.Quux", quux_field->message_type()->full_name());
+ EXPECT_TRUE(quux_field->message_type()->is_placeholder());
+ // The place holder type should not be findable.
+ ASSERT_TRUE(pool_->FindMessageTypeByName("undeclared.Quux") == nullptr);
+}
+
+INSTANTIATE_TEST_SUITE_P(DatabaseSource, AllowUnknownDependenciesTest,
+ testing::Combine(testing::Values(NO_DATABASE,
+ FALLBACK_DATABASE),
+ testing::Values("proto2", "proto3")));
+
+// ===================================================================
+
+TEST(CustomOptions, OptionLocations) {
+ const Descriptor* message =
+ protobuf_unittest::TestMessageWithCustomOptions::descriptor();
+ const FileDescriptor* file = message->file();
+ const FieldDescriptor* field = message->FindFieldByName("field1");
+ const OneofDescriptor* oneof = message->FindOneofByName("AnOneof");
+ const FieldDescriptor* map_field = message->FindFieldByName("map_field");
+ const EnumDescriptor* enm = message->FindEnumTypeByName("AnEnum");
+ // TODO(benjy): Support EnumValue options, once the compiler does.
+ const ServiceDescriptor* service =
+ file->FindServiceByName("TestServiceWithCustomOptions");
+ const MethodDescriptor* method = service->FindMethodByName("Foo");
+
+ EXPECT_EQ(int64{9876543210},
+ file->options().GetExtension(protobuf_unittest::file_opt1));
+ EXPECT_EQ(-56,
+ message->options().GetExtension(protobuf_unittest::message_opt1));
+ EXPECT_EQ(int64{8765432109},
+ field->options().GetExtension(protobuf_unittest::field_opt1));
+ EXPECT_EQ(42, // Check that we get the default for an option we don't set.
+ field->options().GetExtension(protobuf_unittest::field_opt2));
+ EXPECT_EQ(-99, oneof->options().GetExtension(protobuf_unittest::oneof_opt1));
+ EXPECT_EQ(int64_t{12345},
+ map_field->options().GetExtension(protobuf_unittest::field_opt1));
+ EXPECT_EQ(-789, enm->options().GetExtension(protobuf_unittest::enum_opt1));
+ EXPECT_EQ(123, enm->value(1)->options().GetExtension(
+ protobuf_unittest::enum_value_opt1));
+ EXPECT_EQ(int64{-9876543210},
+ service->options().GetExtension(protobuf_unittest::service_opt1));
+ EXPECT_EQ(protobuf_unittest::METHODOPT1_VAL2,
+ method->options().GetExtension(protobuf_unittest::method_opt1));
+
+ // See that the regular options went through unscathed.
+ EXPECT_TRUE(message->options().has_message_set_wire_format());
+ EXPECT_EQ(FieldOptions::CORD, field->options().ctype());
+}
+
+TEST(CustomOptions, OptionTypes) {
+ const MessageOptions* options = nullptr;
+
+ constexpr int32_t kint32min = std::numeric_limits<int32_t>::min();
+ constexpr int32_t kint32max = std::numeric_limits<int32_t>::max();
+ constexpr uint32_t kuint32max = std::numeric_limits<uint32_t>::max();
+ constexpr int64_t kint64min = std::numeric_limits<int64_t>::min();
+ constexpr int64_t kint64max = std::numeric_limits<int64_t>::max();
+ constexpr uint64_t kuint64max = std::numeric_limits<uint64_t>::max();
+
+ options =
+ &protobuf_unittest::CustomOptionMinIntegerValues::descriptor()->options();
+ EXPECT_EQ(false, options->GetExtension(protobuf_unittest::bool_opt));
+ EXPECT_EQ(kint32min, options->GetExtension(protobuf_unittest::int32_opt));
+ EXPECT_EQ(kint64min, options->GetExtension(protobuf_unittest::int64_opt));
+ EXPECT_EQ(0, options->GetExtension(protobuf_unittest::uint32_opt));
+ EXPECT_EQ(0, options->GetExtension(protobuf_unittest::uint64_opt));
+ EXPECT_EQ(kint32min, options->GetExtension(protobuf_unittest::sint32_opt));
+ EXPECT_EQ(kint64min, options->GetExtension(protobuf_unittest::sint64_opt));
+ EXPECT_EQ(0, options->GetExtension(protobuf_unittest::fixed32_opt));
+ EXPECT_EQ(0, options->GetExtension(protobuf_unittest::fixed64_opt));
+ EXPECT_EQ(kint32min, options->GetExtension(protobuf_unittest::sfixed32_opt));
+ EXPECT_EQ(kint64min, options->GetExtension(protobuf_unittest::sfixed64_opt));
+
+ options =
+ &protobuf_unittest::CustomOptionMaxIntegerValues::descriptor()->options();
+ EXPECT_EQ(true, options->GetExtension(protobuf_unittest::bool_opt));
+ EXPECT_EQ(kint32max, options->GetExtension(protobuf_unittest::int32_opt));
+ EXPECT_EQ(kint64max, options->GetExtension(protobuf_unittest::int64_opt));
+ EXPECT_EQ(kuint32max, options->GetExtension(protobuf_unittest::uint32_opt));
+ EXPECT_EQ(kuint64max, options->GetExtension(protobuf_unittest::uint64_opt));
+ EXPECT_EQ(kint32max, options->GetExtension(protobuf_unittest::sint32_opt));
+ EXPECT_EQ(kint64max, options->GetExtension(protobuf_unittest::sint64_opt));
+ EXPECT_EQ(kuint32max, options->GetExtension(protobuf_unittest::fixed32_opt));
+ EXPECT_EQ(kuint64max, options->GetExtension(protobuf_unittest::fixed64_opt));
+ EXPECT_EQ(kint32max, options->GetExtension(protobuf_unittest::sfixed32_opt));
+ EXPECT_EQ(kint64max, options->GetExtension(protobuf_unittest::sfixed64_opt));
+
+ options = &protobuf_unittest::CustomOptionOtherValues::descriptor()->options();
+ EXPECT_EQ(-100, options->GetExtension(protobuf_unittest::int32_opt));
+ EXPECT_FLOAT_EQ(12.3456789,
+ options->GetExtension(protobuf_unittest::float_opt));
+ EXPECT_DOUBLE_EQ(1.234567890123456789,
+ options->GetExtension(protobuf_unittest::double_opt));
+ EXPECT_EQ("Hello, \"World\"",
+ options->GetExtension(protobuf_unittest::string_opt));
+
+ EXPECT_EQ(std::string("Hello\0World", 11),
+ options->GetExtension(protobuf_unittest::bytes_opt));
+
+ EXPECT_EQ(protobuf_unittest::DummyMessageContainingEnum::TEST_OPTION_ENUM_TYPE2,
+ options->GetExtension(protobuf_unittest::enum_opt));
+
+ options =
+ &protobuf_unittest::SettingRealsFromPositiveInts::descriptor()->options();
+ EXPECT_FLOAT_EQ(12, options->GetExtension(protobuf_unittest::float_opt));
+ EXPECT_DOUBLE_EQ(154, options->GetExtension(protobuf_unittest::double_opt));
+
+ options =
+ &protobuf_unittest::SettingRealsFromNegativeInts::descriptor()->options();
+ EXPECT_FLOAT_EQ(-12, options->GetExtension(protobuf_unittest::float_opt));
+ EXPECT_DOUBLE_EQ(-154, options->GetExtension(protobuf_unittest::double_opt));
+}
+
+TEST(CustomOptions, ComplexExtensionOptions) {
+ const MessageOptions* options =
+ &protobuf_unittest::VariousComplexOptions::descriptor()->options();
+ EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt1).foo(), 42);
+ EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt1)
+ .GetExtension(protobuf_unittest::quux),
+ 324);
+ EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt1)
+ .GetExtension(protobuf_unittest::corge)
+ .qux(),
+ 876);
+ EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt2).baz(), 987);
+ EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt2)
+ .GetExtension(protobuf_unittest::grault),
+ 654);
+ EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt2).bar().foo(),
+ 743);
+ EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt2)
+ .bar()
+ .GetExtension(protobuf_unittest::quux),
+ 1999);
+ EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt2)
+ .bar()
+ .GetExtension(protobuf_unittest::corge)
+ .qux(),
+ 2008);
+ EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt2)
+ .GetExtension(protobuf_unittest::garply)
+ .foo(),
+ 741);
+ EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt2)
+ .GetExtension(protobuf_unittest::garply)
+ .GetExtension(protobuf_unittest::quux),
+ 1998);
+ EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt2)
+ .GetExtension(protobuf_unittest::garply)
+ .GetExtension(protobuf_unittest::corge)
+ .qux(),
+ 2121);
+ EXPECT_EQ(options
+ ->GetExtension(protobuf_unittest::ComplexOptionType2::
+ ComplexOptionType4::complex_opt4)
+ .waldo(),
+ 1971);
+ EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt2).fred().waldo(),
+ 321);
+ EXPECT_EQ(9, options->GetExtension(protobuf_unittest::complex_opt3).qux());
+ EXPECT_EQ(22, options->GetExtension(protobuf_unittest::complex_opt3)
+ .complexoptiontype5()
+ .plugh());
+ EXPECT_EQ(24, options->GetExtension(protobuf_unittest::complexopt6).xyzzy());
+}
+
+TEST(CustomOptions, OptionsFromOtherFile) {
+ // Test that to use a custom option, we only need to import the file
+ // defining the option; we do not also have to import descriptor.proto.
+ DescriptorPool pool;
+
+ FileDescriptorProto file_proto;
+ FileDescriptorProto::descriptor()->file()->CopyTo(&file_proto);
+ ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr);
+
+ // We have to import the Any dependency.
+ FileDescriptorProto any_proto;
+ google::protobuf::Any::descriptor()->file()->CopyTo(&any_proto);
+ ASSERT_TRUE(pool.BuildFile(any_proto) != nullptr);
+
+ protobuf_unittest::TestMessageWithCustomOptions::descriptor()->file()->CopyTo(
+ &file_proto);
+ ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr);
+
+ ASSERT_TRUE(TextFormat::ParseFromString(
+ "name: \"custom_options_import.proto\" "
+ "package: \"protobuf_unittest\" "
+ "dependency: \"google/protobuf/unittest_custom_options.proto\" "
+ "options { "
+ " uninterpreted_option { "
+ " name { "
+ " name_part: \"file_opt1\" "
+ " is_extension: true "
+ " } "
+ " positive_int_value: 1234 "
+ " } "
+ // Test a non-extension option too. (At one point this failed due to a
+ // bug.)
+ " uninterpreted_option { "
+ " name { "
+ " name_part: \"java_package\" "
+ " is_extension: false "
+ " } "
+ " string_value: \"foo\" "
+ " } "
+ // Test that enum-typed options still work too. (At one point this also
+ // failed due to a bug.)
+ " uninterpreted_option { "
+ " name { "
+ " name_part: \"optimize_for\" "
+ " is_extension: false "
+ " } "
+ " identifier_value: \"SPEED\" "
+ " } "
+ "}",
+ &file_proto));
+
+ const FileDescriptor* file = pool.BuildFile(file_proto);
+ ASSERT_TRUE(file != nullptr);
+ EXPECT_EQ(1234, file->options().GetExtension(protobuf_unittest::file_opt1));
+ EXPECT_TRUE(file->options().has_java_package());
+ EXPECT_EQ("foo", file->options().java_package());
+ EXPECT_TRUE(file->options().has_optimize_for());
+ EXPECT_EQ(FileOptions::SPEED, file->options().optimize_for());
+}
+
+TEST(CustomOptions, MessageOptionThreeFieldsSet) {
+ // This tests a bug which previously existed in custom options parsing. The
+ // bug occurred when you defined a custom option with message type and then
+ // set three fields of that option on a single definition (see the example
+ // below). The bug is a bit hard to explain, so check the change history if
+ // you want to know more.
+ DescriptorPool pool;
+
+ FileDescriptorProto file_proto;
+ FileDescriptorProto::descriptor()->file()->CopyTo(&file_proto);
+ ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr);
+
+ FileDescriptorProto any_proto;
+ google::protobuf::Any::descriptor()->file()->CopyTo(&any_proto);
+ ASSERT_TRUE(pool.BuildFile(any_proto) != nullptr);
+
+ protobuf_unittest::TestMessageWithCustomOptions::descriptor()->file()->CopyTo(
+ &file_proto);
+ ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr);
+
+ // The following represents the definition:
+ //
+ // import "google/protobuf/unittest_custom_options.proto"
+ // package protobuf_unittest;
+ // message Foo {
+ // option (complex_opt1).foo = 1234;
+ // option (complex_opt1).foo2 = 1234;
+ // option (complex_opt1).foo3 = 1234;
+ // }
+ ASSERT_TRUE(TextFormat::ParseFromString(
+ "name: \"custom_options_import.proto\" "
+ "package: \"protobuf_unittest\" "
+ "dependency: \"google/protobuf/unittest_custom_options.proto\" "
+ "message_type { "
+ " name: \"Foo\" "
+ " options { "
+ " uninterpreted_option { "
+ " name { "
+ " name_part: \"complex_opt1\" "
+ " is_extension: true "
+ " } "
+ " name { "
+ " name_part: \"foo\" "
+ " is_extension: false "
+ " } "
+ " positive_int_value: 1234 "
+ " } "
+ " uninterpreted_option { "
+ " name { "
+ " name_part: \"complex_opt1\" "
+ " is_extension: true "
+ " } "
+ " name { "
+ " name_part: \"foo2\" "
+ " is_extension: false "
+ " } "
+ " positive_int_value: 1234 "
+ " } "
+ " uninterpreted_option { "
+ " name { "
+ " name_part: \"complex_opt1\" "
+ " is_extension: true "
+ " } "
+ " name { "
+ " name_part: \"foo3\" "
+ " is_extension: false "
+ " } "
+ " positive_int_value: 1234 "
+ " } "
+ " } "
+ "}",
+ &file_proto));
+
+ const FileDescriptor* file = pool.BuildFile(file_proto);
+ ASSERT_TRUE(file != nullptr);
+ ASSERT_EQ(1, file->message_type_count());
+
+ const MessageOptions& options = file->message_type(0)->options();
+ EXPECT_EQ(1234, options.GetExtension(protobuf_unittest::complex_opt1).foo());
+}
+
+TEST(CustomOptions, MessageOptionRepeatedLeafFieldSet) {
+ // This test verifies that repeated fields in custom options can be
+ // given multiple values by repeating the option with a different value.
+ // This test checks repeated leaf values. Each repeated custom value
+ // appears in a different uninterpreted_option, which will be concatenated
+ // when they are merged into the final option value.
+ DescriptorPool pool;
+
+ FileDescriptorProto file_proto;
+ FileDescriptorProto::descriptor()->file()->CopyTo(&file_proto);
+ ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr);
+
+ FileDescriptorProto any_proto;
+ google::protobuf::Any::descriptor()->file()->CopyTo(&any_proto);
+ ASSERT_TRUE(pool.BuildFile(any_proto) != nullptr);
+
+ protobuf_unittest::TestMessageWithCustomOptions::descriptor()->file()->CopyTo(
+ &file_proto);
+ ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr);
+
+ // The following represents the definition:
+ //
+ // import "google/protobuf/unittest_custom_options.proto"
+ // package protobuf_unittest;
+ // message Foo {
+ // option (complex_opt1).foo4 = 12;
+ // option (complex_opt1).foo4 = 34;
+ // option (complex_opt1).foo4 = 56;
+ // }
+ ASSERT_TRUE(TextFormat::ParseFromString(
+ "name: \"custom_options_import.proto\" "
+ "package: \"protobuf_unittest\" "
+ "dependency: \"google/protobuf/unittest_custom_options.proto\" "
+ "message_type { "
+ " name: \"Foo\" "
+ " options { "
+ " uninterpreted_option { "
+ " name { "
+ " name_part: \"complex_opt1\" "
+ " is_extension: true "
+ " } "
+ " name { "
+ " name_part: \"foo4\" "
+ " is_extension: false "
+ " } "
+ " positive_int_value: 12 "
+ " } "
+ " uninterpreted_option { "
+ " name { "
+ " name_part: \"complex_opt1\" "
+ " is_extension: true "
+ " } "
+ " name { "
+ " name_part: \"foo4\" "
+ " is_extension: false "
+ " } "
+ " positive_int_value: 34 "
+ " } "
+ " uninterpreted_option { "
+ " name { "
+ " name_part: \"complex_opt1\" "
+ " is_extension: true "
+ " } "
+ " name { "
+ " name_part: \"foo4\" "
+ " is_extension: false "
+ " } "
+ " positive_int_value: 56 "
+ " } "
+ " } "
+ "}",
+ &file_proto));
+
+ const FileDescriptor* file = pool.BuildFile(file_proto);
+ ASSERT_TRUE(file != nullptr);
+ ASSERT_EQ(1, file->message_type_count());
+
+ const MessageOptions& options = file->message_type(0)->options();
+ EXPECT_EQ(3, options.GetExtension(protobuf_unittest::complex_opt1).foo4_size());
+ EXPECT_EQ(12, options.GetExtension(protobuf_unittest::complex_opt1).foo4(0));
+ EXPECT_EQ(34, options.GetExtension(protobuf_unittest::complex_opt1).foo4(1));
+ EXPECT_EQ(56, options.GetExtension(protobuf_unittest::complex_opt1).foo4(2));
+}
+
+TEST(CustomOptions, MessageOptionRepeatedMsgFieldSet) {
+ // This test verifies that repeated fields in custom options can be
+ // given multiple values by repeating the option with a different value.
+ // This test checks repeated message values. Each repeated custom value
+ // appears in a different uninterpreted_option, which will be concatenated
+ // when they are merged into the final option value.
+ DescriptorPool pool;
+
+ FileDescriptorProto file_proto;
+ FileDescriptorProto::descriptor()->file()->CopyTo(&file_proto);
+ ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr);
+
+ FileDescriptorProto any_proto;
+ google::protobuf::Any::descriptor()->file()->CopyTo(&any_proto);
+ ASSERT_TRUE(pool.BuildFile(any_proto) != nullptr);
+
+ protobuf_unittest::TestMessageWithCustomOptions::descriptor()->file()->CopyTo(
+ &file_proto);
+ ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr);
+
+ // The following represents the definition:
+ //
+ // import "google/protobuf/unittest_custom_options.proto"
+ // package protobuf_unittest;
+ // message Foo {
+ // option (complex_opt2).barney = {waldo: 1};
+ // option (complex_opt2).barney = {waldo: 10};
+ // option (complex_opt2).barney = {waldo: 100};
+ // }
+ ASSERT_TRUE(TextFormat::ParseFromString(
+ "name: \"custom_options_import.proto\" "
+ "package: \"protobuf_unittest\" "
+ "dependency: \"google/protobuf/unittest_custom_options.proto\" "
+ "message_type { "
+ " name: \"Foo\" "
+ " options { "
+ " uninterpreted_option { "
+ " name { "
+ " name_part: \"complex_opt2\" "
+ " is_extension: true "
+ " } "
+ " name { "
+ " name_part: \"barney\" "
+ " is_extension: false "
+ " } "
+ " aggregate_value: \"waldo: 1\" "
+ " } "
+ " uninterpreted_option { "
+ " name { "
+ " name_part: \"complex_opt2\" "
+ " is_extension: true "
+ " } "
+ " name { "
+ " name_part: \"barney\" "
+ " is_extension: false "
+ " } "
+ " aggregate_value: \"waldo: 10\" "
+ " } "
+ " uninterpreted_option { "
+ " name { "
+ " name_part: \"complex_opt2\" "
+ " is_extension: true "
+ " } "
+ " name { "
+ " name_part: \"barney\" "
+ " is_extension: false "
+ " } "
+ " aggregate_value: \"waldo: 100\" "
+ " } "
+ " } "
+ "}",
+ &file_proto));
+
+ const FileDescriptor* file = pool.BuildFile(file_proto);
+ ASSERT_TRUE(file != nullptr);
+ ASSERT_EQ(1, file->message_type_count());
+
+ const MessageOptions& options = file->message_type(0)->options();
+ EXPECT_EQ(3,
+ options.GetExtension(protobuf_unittest::complex_opt2).barney_size());
+ EXPECT_EQ(
+ 1, options.GetExtension(protobuf_unittest::complex_opt2).barney(0).waldo());
+ EXPECT_EQ(
+ 10,
+ options.GetExtension(protobuf_unittest::complex_opt2).barney(1).waldo());
+ EXPECT_EQ(
+ 100,
+ options.GetExtension(protobuf_unittest::complex_opt2).barney(2).waldo());
+}
+
+// Check that aggregate options were parsed and saved correctly in
+// the appropriate descriptors.
+TEST(CustomOptions, AggregateOptions) {
+ const Descriptor* msg = protobuf_unittest::AggregateMessage::descriptor();
+ const FileDescriptor* file = msg->file();
+ const FieldDescriptor* field = msg->FindFieldByName("fieldname");
+ const EnumDescriptor* enumd = file->FindEnumTypeByName("AggregateEnum");
+ const EnumValueDescriptor* enumv = enumd->FindValueByName("VALUE");
+ const ServiceDescriptor* service =
+ file->FindServiceByName("AggregateService");
+ const MethodDescriptor* method = service->FindMethodByName("Method");
+
+ // Tests for the different types of data embedded in fileopt
+ const protobuf_unittest::Aggregate& file_options =
+ file->options().GetExtension(protobuf_unittest::fileopt);
+ EXPECT_EQ(100, file_options.i());
+ EXPECT_EQ("FileAnnotation", file_options.s());
+ EXPECT_EQ("NestedFileAnnotation", file_options.sub().s());
+ EXPECT_EQ("FileExtensionAnnotation",
+ file_options.file().GetExtension(protobuf_unittest::fileopt).s());
+ EXPECT_EQ("EmbeddedMessageSetElement",
+ file_options.mset()
+ .GetExtension(protobuf_unittest::AggregateMessageSetElement ::
+ message_set_extension)
+ .s());
+
+ protobuf_unittest::AggregateMessageSetElement any_payload;
+ ASSERT_TRUE(file_options.any().UnpackTo(&any_payload));
+ EXPECT_EQ("EmbeddedMessageSetElement", any_payload.s());
+
+ // Simple tests for all the other types of annotations
+ EXPECT_EQ("MessageAnnotation",
+ msg->options().GetExtension(protobuf_unittest::msgopt).s());
+ EXPECT_EQ("FieldAnnotation",
+ field->options().GetExtension(protobuf_unittest::fieldopt).s());
+ EXPECT_EQ("EnumAnnotation",
+ enumd->options().GetExtension(protobuf_unittest::enumopt).s());
+ EXPECT_EQ("EnumValueAnnotation",
+ enumv->options().GetExtension(protobuf_unittest::enumvalopt).s());
+ EXPECT_EQ("ServiceAnnotation",
+ service->options().GetExtension(protobuf_unittest::serviceopt).s());
+ EXPECT_EQ("MethodAnnotation",
+ method->options().GetExtension(protobuf_unittest::methodopt).s());
+}
+
+TEST(CustomOptions, UnusedImportError) {
+ DescriptorPool pool;
+
+ FileDescriptorProto file_proto;
+ FileDescriptorProto::descriptor()->file()->CopyTo(&file_proto);
+ ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr);
+
+ FileDescriptorProto any_proto;
+ google::protobuf::Any::descriptor()->file()->CopyTo(&any_proto);
+ ASSERT_TRUE(pool.BuildFile(any_proto) != nullptr);
+
+ protobuf_unittest::TestMessageWithCustomOptions::descriptor()->file()->CopyTo(
+ &file_proto);
+ ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr);
+
+ pool.AddUnusedImportTrackFile("custom_options_import.proto", true);
+ ASSERT_TRUE(TextFormat::ParseFromString(
+ "name: \"custom_options_import.proto\" "
+ "package: \"protobuf_unittest\" "
+ "dependency: \"google/protobuf/unittest_custom_options.proto\" ",
+ &file_proto));
+
+ MockErrorCollector error_collector;
+ EXPECT_FALSE(pool.BuildFileCollectingErrors(file_proto, &error_collector));
+ EXPECT_EQ(
+ "custom_options_import.proto: "
+ "google/protobuf/unittest_custom_options.proto: IMPORT: Import "
+ "google/protobuf/unittest_custom_options.proto is unused.\n",
+ error_collector.text_);
+}
+
+// Verifies that proto files can correctly be parsed, even if the
+// custom options defined in the file are incompatible with those
+// compiled in the binary. See http://b/19276250.
+TEST(CustomOptions, OptionsWithIncompatibleDescriptors) {
+ DescriptorPool pool;
+
+ FileDescriptorProto file_proto;
+ MessageOptions::descriptor()->file()->CopyTo(&file_proto);
+ ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr);
+
+ // Create a new file descriptor proto containing a subset of the
+ // messages defined in google/protobuf/unittest_custom_options.proto.
+ file_proto.Clear();
+ file_proto.set_name("unittest_custom_options.proto");
+ file_proto.set_package("protobuf_unittest");
+ file_proto.add_dependency("google/protobuf/descriptor.proto");
+
+ // Add the "required_enum_opt" extension.
+ FieldDescriptorProto* extension = file_proto.add_extension();
+ protobuf_unittest::OldOptionType::descriptor()
+ ->file()
+ ->FindExtensionByName("required_enum_opt")
+ ->CopyTo(extension);
+
+ // Add a test message that uses the "required_enum_opt" option.
+ DescriptorProto* test_message_type = file_proto.add_message_type();
+ protobuf_unittest::TestMessageWithRequiredEnumOption::descriptor()->CopyTo(
+ test_message_type);
+
+ // Instruct the extension to use NewOptionType instead of
+ // OldOptionType, and add the descriptor of NewOptionType.
+ extension->set_type_name(".protobuf_unittest.NewOptionType");
+ DescriptorProto* new_option_type = file_proto.add_message_type();
+ protobuf_unittest::NewOptionType::descriptor()->CopyTo(new_option_type);
+
+ // Replace the value of the "required_enum_opt" option used in the
+ // test message with an enum value that only exists in NewOptionType.
+ ASSERT_TRUE(
+ TextFormat::ParseFromString("uninterpreted_option { "
+ " name { "
+ " name_part: 'required_enum_opt' "
+ " is_extension: true "
+ " } "
+ " aggregate_value: 'value: NEW_VALUE'"
+ "}",
+ test_message_type->mutable_options()));
+
+ // Adding the file descriptor to the pool should fail.
+ EXPECT_TRUE(pool.BuildFile(file_proto) == nullptr);
+}
+
+// Test that FileDescriptor::DebugString() formats custom options correctly.
+TEST(CustomOptions, DebugString) {
+ DescriptorPool pool;
+
+ FileDescriptorProto file_proto;
+ MessageOptions::descriptor()->file()->CopyTo(&file_proto);
+ ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr);
+
+ // Add "foo.proto":
+ // import "google/protobuf/descriptor.proto";
+ // package "protobuf_unittest";
+ // option (protobuf_unittest.cc_option1) = 1;
+ // option (protobuf_unittest.cc_option2) = 2;
+ // extend google.protobuf.FieldOptions {
+ // optional int32 cc_option1 = 7736974;
+ // optional int32 cc_option2 = 7736975;
+ // }
+ ASSERT_TRUE(TextFormat::ParseFromString(
+ "name: \"foo.proto\" "
+ "package: \"protobuf_unittest\" "
+ "dependency: \"google/protobuf/descriptor.proto\" "
+ "options { "
+ " uninterpreted_option { "
+ " name { "
+ " name_part: \"protobuf_unittest.cc_option1\" "
+ " is_extension: true "
+ " } "
+ " positive_int_value: 1 "
+ " } "
+ " uninterpreted_option { "
+ " name { "
+ " name_part: \"protobuf_unittest.cc_option2\" "
+ " is_extension: true "
+ " } "
+ " positive_int_value: 2 "
+ " } "
+ "} "
+ "extension { "
+ " name: \"cc_option1\" "
+ " extendee: \".google.protobuf.FileOptions\" "
+ // This field number is intentionally chosen to be the same as
+ // (.fileopt1) defined in unittest_custom_options.proto (linked
+ // in this test binary). This is to test whether we are messing
+ // generated pool with custom descriptor pools when dealing with
+ // custom options.
+ " number: 7736974 "
+ " label: LABEL_OPTIONAL "
+ " type: TYPE_INT32 "
+ "}"
+ "extension { "
+ " name: \"cc_option2\" "
+ " extendee: \".google.protobuf.FileOptions\" "
+ " number: 7736975 "
+ " label: LABEL_OPTIONAL "
+ " type: TYPE_INT32 "
+ "}",
+ &file_proto));
+ const FileDescriptor* descriptor = pool.BuildFile(file_proto);
+ ASSERT_TRUE(descriptor != nullptr);
+
+ EXPECT_EQ(2, descriptor->extension_count());
+
+ ASSERT_EQ(
+ "syntax = \"proto2\";\n"
+ "\n"
+ "import \"google/protobuf/descriptor.proto\";\n"
+ "package protobuf_unittest;\n"
+ "\n"
+ "option (.protobuf_unittest.cc_option1) = 1;\n"
+ "option (.protobuf_unittest.cc_option2) = 2;\n"
+ "\n"
+ "extend .google.protobuf.FileOptions {\n"
+ " optional int32 cc_option1 = 7736974;\n"
+ " optional int32 cc_option2 = 7736975;\n"
+ "}\n"
+ "\n",
+ descriptor->DebugString());
+}
+
+// ===================================================================
+
+class ValidationErrorTest : public testing::Test {
+ protected:
+ // Parse file_text as a FileDescriptorProto in text format and add it
+ // to the DescriptorPool. Expect no errors.
+ const FileDescriptor* BuildFile(const std::string& file_text) {
+ FileDescriptorProto file_proto;
+ EXPECT_TRUE(TextFormat::ParseFromString(file_text, &file_proto));
+ return GOOGLE_CHECK_NOTNULL(pool_.BuildFile(file_proto));
+ }
+
+ // Parse file_text as a FileDescriptorProto in text format and add it
+ // to the DescriptorPool. Expect errors to be produced which match the
+ // given error text.
+ void BuildFileWithErrors(const std::string& file_text,
+ const std::string& expected_errors) {
+ FileDescriptorProto file_proto;
+ ASSERT_TRUE(TextFormat::ParseFromString(file_text, &file_proto));
+
+ MockErrorCollector error_collector;
+ EXPECT_TRUE(pool_.BuildFileCollectingErrors(file_proto, &error_collector) ==
+ nullptr);
+ EXPECT_EQ(expected_errors, error_collector.text_);
+ }
+
+ // Parse file_text as a FileDescriptorProto in text format and add it
+ // to the DescriptorPool. Expect errors to be produced which match the
+ // given warning text.
+ void BuildFileWithWarnings(const std::string& file_text,
+ const std::string& expected_warnings) {
+ FileDescriptorProto file_proto;
+ ASSERT_TRUE(TextFormat::ParseFromString(file_text, &file_proto));
+
+ MockErrorCollector error_collector;
+ EXPECT_TRUE(pool_.BuildFileCollectingErrors(file_proto, &error_collector));
+ EXPECT_EQ(expected_warnings, error_collector.warning_text_);
+ }
+
+ // Builds some already-parsed file in our test pool.
+ void BuildFileInTestPool(const FileDescriptor* file) {
+ FileDescriptorProto file_proto;
+ file->CopyTo(&file_proto);
+ ASSERT_TRUE(pool_.BuildFile(file_proto) != nullptr);
+ }
+
+ // Build descriptor.proto in our test pool. This allows us to extend it in
+ // the test pool, so we can test custom options.
+ void BuildDescriptorMessagesInTestPool() {
+ BuildFileInTestPool(DescriptorProto::descriptor()->file());
+ }
+
+ DescriptorPool pool_;
+};
+
+TEST_F(ValidationErrorTest, AlreadyDefined) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "message_type { name: \"Foo\" }"
+ "message_type { name: \"Foo\" }",
+
+ "foo.proto: Foo: NAME: \"Foo\" is already defined.\n");
+}
+
+TEST_F(ValidationErrorTest, AlreadyDefinedInPackage) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "package: \"foo.bar\" "
+ "message_type { name: \"Foo\" }"
+ "message_type { name: \"Foo\" }",
+
+ "foo.proto: foo.bar.Foo: NAME: \"Foo\" is already defined in "
+ "\"foo.bar\".\n");
+}
+
+TEST_F(ValidationErrorTest, AlreadyDefinedInOtherFile) {
+ BuildFile(
+ "name: \"foo.proto\" "
+ "message_type { name: \"Foo\" }");
+
+ BuildFileWithErrors(
+ "name: \"bar.proto\" "
+ "message_type { name: \"Foo\" }",
+
+ "bar.proto: Foo: NAME: \"Foo\" is already defined in file "
+ "\"foo.proto\".\n");
+}
+
+TEST_F(ValidationErrorTest, PackageAlreadyDefined) {
+ BuildFile(
+ "name: \"foo.proto\" "
+ "message_type { name: \"foo\" }");
+ BuildFileWithErrors(
+ "name: \"bar.proto\" "
+ "package: \"foo.bar\"",
+
+ "bar.proto: foo: NAME: \"foo\" is already defined (as something other "
+ "than a package) in file \"foo.proto\".\n");
+}
+
+TEST_F(ValidationErrorTest, EnumValueAlreadyDefinedInParent) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "enum_type { name: \"Foo\" value { name: \"FOO\" number: 1 } } "
+ "enum_type { name: \"Bar\" value { name: \"FOO\" number: 1 } } ",
+
+ "foo.proto: FOO: NAME: \"FOO\" is already defined.\n"
+ "foo.proto: FOO: NAME: Note that enum values use C++ scoping rules, "
+ "meaning that enum values are siblings of their type, not children of "
+ "it. Therefore, \"FOO\" must be unique within the global scope, not "
+ "just within \"Bar\".\n");
+}
+
+TEST_F(ValidationErrorTest, EnumValueAlreadyDefinedInParentNonGlobal) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "package: \"pkg\" "
+ "enum_type { name: \"Foo\" value { name: \"FOO\" number: 1 } } "
+ "enum_type { name: \"Bar\" value { name: \"FOO\" number: 1 } } ",
+
+ "foo.proto: pkg.FOO: NAME: \"FOO\" is already defined in \"pkg\".\n"
+ "foo.proto: pkg.FOO: NAME: Note that enum values use C++ scoping rules, "
+ "meaning that enum values are siblings of their type, not children of "
+ "it. Therefore, \"FOO\" must be unique within \"pkg\", not just within "
+ "\"Bar\".\n");
+}
+
+TEST_F(ValidationErrorTest, MissingName) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "message_type { }",
+
+ "foo.proto: : NAME: Missing name.\n");
+}
+
+TEST_F(ValidationErrorTest, InvalidName) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "message_type { name: \"$\" }",
+
+ "foo.proto: $: NAME: \"$\" is not a valid identifier.\n");
+}
+
+TEST_F(ValidationErrorTest, InvalidPackageName) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "package: \"foo.$\"",
+
+ "foo.proto: foo.$: NAME: \"$\" is not a valid identifier.\n");
+}
+
+// 'str' is a static C-style string that may contain '\0'
+#define STATIC_STR(str) std::string((str), sizeof(str) - 1)
+
+TEST_F(ValidationErrorTest, NullCharSymbolName) {
+ BuildFileWithErrors(
+ "name: \"bar.proto\" "
+ "package: \"foo\""
+ "message_type { "
+ " name: '\\000\\001\\013.Bar' "
+ " field { name: \"foo\" number: 9 label:LABEL_OPTIONAL type:TYPE_INT32 "
+ "} "
+ "}",
+ STATIC_STR("bar.proto: foo.\0\x1\v.Bar: NAME: \"\0\x1\v.Bar\" is not a "
+ "valid identifier.\nbar.proto: foo.\0\x1\v.Bar: NAME: "
+ "\"\0\x1\v.Bar\" is not a valid identifier.\nbar.proto: "
+ "foo.\0\x1\v.Bar: NAME: \"\0\x1\v.Bar\" is not a valid "
+ "identifier.\nbar.proto: foo.\0\x1\v.Bar: NAME: "
+ "\"\0\x1\v.Bar\" is not a valid identifier.\nbar.proto: "
+ "foo.\0\x1\v.Bar.foo: NAME: \"foo.\0\x1\v.Bar.foo\" contains "
+ "null character.\nbar.proto: foo.\0\x1\v.Bar: NAME: "
+ "\"foo.\0\x1\v.Bar\" contains null character.\n"));
+}
+
+TEST_F(ValidationErrorTest, NullCharFileName) {
+ BuildFileWithErrors(
+ "name: \"bar\\000\\001\\013.proto\" "
+ "package: \"outer.foo\"",
+ STATIC_STR("bar\0\x1\v.proto: bar\0\x1\v.proto: NAME: "
+ "\"bar\0\x1\v.proto\" contains null character.\n"));
+}
+
+TEST_F(ValidationErrorTest, NullCharPackageName) {
+ BuildFileWithErrors(
+ "name: \"bar.proto\" "
+ "package: \"\\000\\001\\013.\"",
+ STATIC_STR("bar.proto: \0\x1\v.: NAME: \"\0\x1\v.\" contains null "
+ "character.\n"));
+}
+
+TEST_F(ValidationErrorTest, MissingFileName) {
+ BuildFileWithErrors("",
+
+ ": : OTHER: Missing field: FileDescriptorProto.name.\n");
+}
+
+TEST_F(ValidationErrorTest, DupeDependency) {
+ BuildFile("name: \"foo.proto\"");
+ BuildFileWithErrors(
+ "name: \"bar.proto\" "
+ "dependency: \"foo.proto\" "
+ "dependency: \"foo.proto\" ",
+
+ "bar.proto: foo.proto: IMPORT: Import \"foo.proto\" was listed twice.\n");
+}
+
+TEST_F(ValidationErrorTest, UnknownDependency) {
+ BuildFileWithErrors(
+ "name: \"bar.proto\" "
+ "dependency: \"foo.proto\" ",
+
+ "bar.proto: foo.proto: IMPORT: Import \"foo.proto\" has not been "
+ "loaded.\n");
+}
+
+TEST_F(ValidationErrorTest, InvalidPublicDependencyIndex) {
+ BuildFile("name: \"foo.proto\"");
+ BuildFileWithErrors(
+ "name: \"bar.proto\" "
+ "dependency: \"foo.proto\" "
+ "public_dependency: 1",
+ "bar.proto: bar.proto: OTHER: Invalid public dependency index.\n");
+}
+
+TEST_F(ValidationErrorTest, ForeignUnimportedPackageNoCrash) {
+ // Used to crash: If we depend on a non-existent file and then refer to a
+ // package defined in a file that we didn't import, and that package is
+ // nested within a parent package which this file is also in, and we don't
+ // include that parent package in the name (i.e. we do a relative lookup)...
+ // Yes, really.
+ BuildFile(
+ "name: 'foo.proto' "
+ "package: 'outer.foo' ");
+ BuildFileWithErrors(
+ "name: 'bar.proto' "
+ "dependency: 'baz.proto' "
+ "package: 'outer.bar' "
+ "message_type { "
+ " name: 'Bar' "
+ " field { name:'bar' number:1 label:LABEL_OPTIONAL type_name:'foo.Foo' }"
+ "}",
+
+ "bar.proto: baz.proto: IMPORT: Import \"baz.proto\" has not been "
+ "loaded.\n"
+ "bar.proto: outer.bar.Bar.bar: TYPE: \"outer.foo\" seems to be defined "
+ "in "
+ "\"foo.proto\", which is not imported by \"bar.proto\". To use it here, "
+ "please add the necessary import.\n");
+}
+
+TEST_F(ValidationErrorTest, DupeFile) {
+ BuildFile(
+ "name: \"foo.proto\" "
+ "message_type { name: \"Foo\" }");
+ // Note: We should *not* get redundant errors about "Foo" already being
+ // defined.
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "message_type { name: \"Foo\" } "
+ // Add another type so that the files aren't identical (in which case
+ // there would be no error).
+ "enum_type { name: \"Bar\" }",
+
+ "foo.proto: foo.proto: OTHER: A file with this name is already in the "
+ "pool.\n");
+}
+
+TEST_F(ValidationErrorTest, FieldInExtensionRange) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "message_type {"
+ " name: \"Foo\""
+ " field { name: \"foo\" number: 9 label:LABEL_OPTIONAL type:TYPE_INT32 "
+ "}"
+ " field { name: \"bar\" number: 10 label:LABEL_OPTIONAL type:TYPE_INT32 "
+ "}"
+ " field { name: \"baz\" number: 19 label:LABEL_OPTIONAL type:TYPE_INT32 "
+ "}"
+ " field { name: \"qux\" number: 20 label:LABEL_OPTIONAL type:TYPE_INT32 "
+ "}"
+ " extension_range { start: 10 end: 20 }"
+ "}",
+
+ "foo.proto: Foo.bar: NUMBER: Extension range 10 to 19 includes field "
+ "\"bar\" (10).\n"
+ "foo.proto: Foo.baz: NUMBER: Extension range 10 to 19 includes field "
+ "\"baz\" (19).\n");
+}
+
+TEST_F(ValidationErrorTest, OverlappingExtensionRanges) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "message_type {"
+ " name: \"Foo\""
+ " extension_range { start: 10 end: 20 }"
+ " extension_range { start: 20 end: 30 }"
+ " extension_range { start: 19 end: 21 }"
+ "}",
+
+ "foo.proto: Foo: NUMBER: Extension range 19 to 20 overlaps with "
+ "already-defined range 10 to 19.\n"
+ "foo.proto: Foo: NUMBER: Extension range 19 to 20 overlaps with "
+ "already-defined range 20 to 29.\n");
+}
+
+TEST_F(ValidationErrorTest, ReservedFieldError) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "message_type {"
+ " name: \"Foo\""
+ " field { name: \"foo\" number: 15 label:LABEL_OPTIONAL type:TYPE_INT32 "
+ "}"
+ " reserved_range { start: 10 end: 20 }"
+ "}",
+
+ "foo.proto: Foo.foo: NUMBER: Field \"foo\" uses reserved number 15.\n");
+}
+
+TEST_F(ValidationErrorTest, ReservedExtensionRangeError) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "message_type {"
+ " name: \"Foo\""
+ " extension_range { start: 10 end: 20 }"
+ " reserved_range { start: 5 end: 15 }"
+ "}",
+
+ "foo.proto: Foo: NUMBER: Extension range 10 to 19"
+ " overlaps with reserved range 5 to 14.\n");
+}
+
+TEST_F(ValidationErrorTest, ReservedExtensionRangeAdjacent) {
+ BuildFile(
+ "name: \"foo.proto\" "
+ "message_type {"
+ " name: \"Foo\""
+ " extension_range { start: 10 end: 20 }"
+ " reserved_range { start: 5 end: 10 }"
+ "}");
+}
+
+TEST_F(ValidationErrorTest, ReservedRangeOverlap) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "message_type {"
+ " name: \"Foo\""
+ " reserved_range { start: 10 end: 20 }"
+ " reserved_range { start: 5 end: 15 }"
+ "}",
+
+ "foo.proto: Foo: NUMBER: Reserved range 5 to 14"
+ " overlaps with already-defined range 10 to 19.\n");
+}
+
+TEST_F(ValidationErrorTest, ReservedNameError) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "message_type {"
+ " name: \"Foo\""
+ " field { name: \"foo\" number: 15 label:LABEL_OPTIONAL type:TYPE_INT32 "
+ "}"
+ " field { name: \"bar\" number: 16 label:LABEL_OPTIONAL type:TYPE_INT32 "
+ "}"
+ " field { name: \"baz\" number: 17 label:LABEL_OPTIONAL type:TYPE_INT32 "
+ "}"
+ " reserved_name: \"foo\""
+ " reserved_name: \"bar\""
+ "}",
+
+ "foo.proto: Foo.foo: NAME: Field name \"foo\" is reserved.\n"
+ "foo.proto: Foo.bar: NAME: Field name \"bar\" is reserved.\n");
+}
+
+TEST_F(ValidationErrorTest, ReservedNameRedundant) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "message_type {"
+ " name: \"Foo\""
+ " reserved_name: \"foo\""
+ " reserved_name: \"foo\""
+ "}",
+
+ "foo.proto: foo: NAME: Field name \"foo\" is reserved multiple times.\n");
+}
+
+TEST_F(ValidationErrorTest, ReservedFieldsDebugString) {
+ const FileDescriptor* file = BuildFile(
+ "name: \"foo.proto\" "
+ "message_type {"
+ " name: \"Foo\""
+ " reserved_name: \"foo\""
+ " reserved_name: \"bar\""
+ " reserved_range { start: 5 end: 6 }"
+ " reserved_range { start: 10 end: 20 }"
+ "}");
+
+ ASSERT_EQ(
+ "syntax = \"proto2\";\n\n"
+ "message Foo {\n"
+ " reserved 5, 10 to 19;\n"
+ " reserved \"foo\", \"bar\";\n"
+ "}\n\n",
+ file->DebugString());
+}
+
+TEST_F(ValidationErrorTest, DebugStringReservedRangeMax) {
+ const FileDescriptor* file = BuildFile(strings::Substitute(
+ "name: \"foo.proto\" "
+ "enum_type { "
+ " name: \"Bar\""
+ " value { name:\"BAR\" number:1 }"
+ " reserved_range { start: 5 end: $0 }"
+ "}"
+ "message_type {"
+ " name: \"Foo\""
+ " reserved_range { start: 5 end: $1 }"
+ "}",
+ std::numeric_limits<int>::max(), FieldDescriptor::kMaxNumber + 1));
+
+ ASSERT_EQ(
+ "syntax = \"proto2\";\n\n"
+ "enum Bar {\n"
+ " BAR = 1;\n"
+ " reserved 5 to max;\n"
+ "}\n\n"
+ "message Foo {\n"
+ " reserved 5 to max;\n"
+ "}\n\n",
+ file->DebugString());
+}
+
+TEST_F(ValidationErrorTest, EnumReservedFieldError) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "enum_type {"
+ " name: \"Foo\""
+ " value { name:\"BAR\" number:15 }"
+ " reserved_range { start: 10 end: 20 }"
+ "}",
+
+ "foo.proto: BAR: NUMBER: Enum value \"BAR\" uses reserved number 15.\n");
+}
+
+TEST_F(ValidationErrorTest, EnumNegativeReservedFieldError) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "enum_type {"
+ " name: \"Foo\""
+ " value { name:\"BAR\" number:-15 }"
+ " reserved_range { start: -20 end: -10 }"
+ "}",
+
+ "foo.proto: BAR: NUMBER: Enum value \"BAR\" uses reserved number -15.\n");
+}
+
+TEST_F(ValidationErrorTest, EnumReservedRangeOverlap) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "enum_type {"
+ " name: \"Foo\""
+ " value { name:\"BAR\" number:0 }"
+ " reserved_range { start: 10 end: 20 }"
+ " reserved_range { start: 5 end: 15 }"
+ "}",
+
+ "foo.proto: Foo: NUMBER: Reserved range 5 to 15"
+ " overlaps with already-defined range 10 to 20.\n");
+}
+
+TEST_F(ValidationErrorTest, EnumReservedRangeOverlapByOne) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "enum_type {"
+ " name: \"Foo\""
+ " value { name:\"BAR\" number:0 }"
+ " reserved_range { start: 10 end: 20 }"
+ " reserved_range { start: 5 end: 10 }"
+ "}",
+
+ "foo.proto: Foo: NUMBER: Reserved range 5 to 10"
+ " overlaps with already-defined range 10 to 20.\n");
+}
+
+TEST_F(ValidationErrorTest, EnumNegativeReservedRangeOverlap) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "enum_type {"
+ " name: \"Foo\""
+ " value { name:\"BAR\" number:0 }"
+ " reserved_range { start: -20 end: -10 }"
+ " reserved_range { start: -15 end: -5 }"
+ "}",
+
+ "foo.proto: Foo: NUMBER: Reserved range -15 to -5"
+ " overlaps with already-defined range -20 to -10.\n");
+}
+
+TEST_F(ValidationErrorTest, EnumMixedReservedRangeOverlap) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "enum_type {"
+ " name: \"Foo\""
+ " value { name:\"BAR\" number:20 }"
+ " reserved_range { start: -20 end: 10 }"
+ " reserved_range { start: -15 end: 5 }"
+ "}",
+
+ "foo.proto: Foo: NUMBER: Reserved range -15 to 5"
+ " overlaps with already-defined range -20 to 10.\n");
+}
+
+TEST_F(ValidationErrorTest, EnumMixedReservedRangeOverlap2) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "enum_type {"
+ " name: \"Foo\""
+ " value { name:\"BAR\" number:20 }"
+ " reserved_range { start: -20 end: 10 }"
+ " reserved_range { start: 10 end: 10 }"
+ "}",
+
+ "foo.proto: Foo: NUMBER: Reserved range 10 to 10"
+ " overlaps with already-defined range -20 to 10.\n");
+}
+
+TEST_F(ValidationErrorTest, EnumReservedRangeStartGreaterThanEnd) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "enum_type {"
+ " name: \"Foo\""
+ " value { name:\"BAR\" number:20 }"
+ " reserved_range { start: 11 end: 10 }"
+ "}",
+
+ "foo.proto: Foo: NUMBER: Reserved range end number must be greater"
+ " than start number.\n");
+}
+
+TEST_F(ValidationErrorTest, EnumReservedNameError) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "enum_type {"
+ " name: \"Foo\""
+ " value { name:\"FOO\" number:15 }"
+ " value { name:\"BAR\" number:15 }"
+ " reserved_name: \"FOO\""
+ " reserved_name: \"BAR\""
+ "}",
+
+ "foo.proto: FOO: NAME: Enum value \"FOO\" is reserved.\n"
+ "foo.proto: BAR: NAME: Enum value \"BAR\" is reserved.\n");
+}
+
+TEST_F(ValidationErrorTest, EnumReservedNameRedundant) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "enum_type {"
+ " name: \"Foo\""
+ " value { name:\"FOO\" number:15 }"
+ " reserved_name: \"foo\""
+ " reserved_name: \"foo\""
+ "}",
+
+ "foo.proto: foo: NAME: Enum value \"foo\" is reserved multiple times.\n");
+}
+
+TEST_F(ValidationErrorTest, EnumReservedFieldsDebugString) {
+ const FileDescriptor* file = BuildFile(
+ "name: \"foo.proto\" "
+ "enum_type {"
+ " name: \"Foo\""
+ " value { name:\"FOO\" number:3 }"
+ " reserved_name: \"foo\""
+ " reserved_name: \"bar\""
+ " reserved_range { start: -6 end: -6 }"
+ " reserved_range { start: -5 end: -4 }"
+ " reserved_range { start: -1 end: 1 }"
+ " reserved_range { start: 5 end: 5 }"
+ " reserved_range { start: 10 end: 19 }"
+ "}");
+
+ ASSERT_EQ(
+ "syntax = \"proto2\";\n\n"
+ "enum Foo {\n"
+ " FOO = 3;\n"
+ " reserved -6, -5 to -4, -1 to 1, 5, 10 to 19;\n"
+ " reserved \"foo\", \"bar\";\n"
+ "}\n\n",
+ file->DebugString());
+}
+
+TEST_F(ValidationErrorTest, InvalidDefaults) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "message_type {"
+ " name: \"Foo\""
+
+ // Invalid number.
+ " field { name: \"foo\" number: 1 label: LABEL_OPTIONAL type: TYPE_INT32"
+ " default_value: \"abc\" }"
+
+ // Empty default value.
+ " field { name: \"bar\" number: 2 label: LABEL_OPTIONAL type: TYPE_INT32"
+ " default_value: \"\" }"
+
+ // Invalid boolean.
+ " field { name: \"baz\" number: 3 label: LABEL_OPTIONAL type: TYPE_BOOL"
+ " default_value: \"abc\" }"
+
+ // Messages can't have defaults.
+ " field { name: \"qux\" number: 4 label: LABEL_OPTIONAL type: "
+ "TYPE_MESSAGE"
+ " default_value: \"abc\" type_name: \"Foo\" }"
+
+ // Same thing, but we don't know that this field has message type until
+ // we look up the type name.
+ " field { name: \"quux\" number: 5 label: LABEL_OPTIONAL"
+ " default_value: \"abc\" type_name: \"Foo\" }"
+
+ // Repeateds can't have defaults.
+ " field { name: \"corge\" number: 6 label: LABEL_REPEATED type: "
+ "TYPE_INT32"
+ " default_value: \"1\" }"
+ "}",
+
+ "foo.proto: Foo.foo: DEFAULT_VALUE: Couldn't parse default value "
+ "\"abc\".\n"
+ "foo.proto: Foo.bar: DEFAULT_VALUE: Couldn't parse default value \"\".\n"
+ "foo.proto: Foo.baz: DEFAULT_VALUE: Boolean default must be true or "
+ "false.\n"
+ "foo.proto: Foo.qux: DEFAULT_VALUE: Messages can't have default values.\n"
+ "foo.proto: Foo.corge: DEFAULT_VALUE: Repeated fields can't have default "
+ "values.\n"
+ // This ends up being reported later because the error is detected at
+ // cross-linking time.
+ "foo.proto: Foo.quux: DEFAULT_VALUE: Messages can't have default "
+ "values.\n");
+}
+
+TEST_F(ValidationErrorTest, NegativeFieldNumber) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "message_type {"
+ " name: \"Foo\""
+ " field { name: \"foo\" number: -1 label:LABEL_OPTIONAL type:TYPE_INT32 "
+ "}"
+ "}",
+
+ "foo.proto: Foo.foo: NUMBER: Field numbers must be positive integers.\n");
+}
+
+TEST_F(ValidationErrorTest, HugeFieldNumber) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "message_type {"
+ " name: \"Foo\""
+ " field { name: \"foo\" number: 0x70000000 "
+ " label:LABEL_OPTIONAL type:TYPE_INT32 }"
+ "}",
+
+ "foo.proto: Foo.foo: NUMBER: Field numbers cannot be greater than "
+ "536870911.\n");
+}
+
+TEST_F(ValidationErrorTest, ReservedFieldNumber) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "message_type {"
+ " name: \"Foo\""
+ " field {name:\"foo\" number: 18999 label:LABEL_OPTIONAL "
+ "type:TYPE_INT32 }"
+ " field {name:\"bar\" number: 19000 label:LABEL_OPTIONAL "
+ "type:TYPE_INT32 }"
+ " field {name:\"baz\" number: 19999 label:LABEL_OPTIONAL "
+ "type:TYPE_INT32 }"
+ " field {name:\"qux\" number: 20000 label:LABEL_OPTIONAL "
+ "type:TYPE_INT32 }"
+ "}",
+
+ "foo.proto: Foo.bar: NUMBER: Field numbers 19000 through 19999 are "
+ "reserved for the protocol buffer library implementation.\n"
+ "foo.proto: Foo.baz: NUMBER: Field numbers 19000 through 19999 are "
+ "reserved for the protocol buffer library implementation.\n");
+}
+
+TEST_F(ValidationErrorTest, ExtensionMissingExtendee) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "message_type {"
+ " name: \"Foo\""
+ " extension { name: \"foo\" number: 1 label: LABEL_OPTIONAL"
+ " type_name: \"Foo\" }"
+ "}",
+
+ "foo.proto: Foo.foo: EXTENDEE: FieldDescriptorProto.extendee not set for "
+ "extension field.\n");
+}
+
+TEST_F(ValidationErrorTest, NonExtensionWithExtendee) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "message_type {"
+ " name: \"Bar\""
+ " extension_range { start: 1 end: 2 }"
+ "}"
+ "message_type {"
+ " name: \"Foo\""
+ " field { name: \"foo\" number: 1 label: LABEL_OPTIONAL"
+ " type_name: \"Foo\" extendee: \"Bar\" }"
+ "}",
+
+ "foo.proto: Foo.foo: EXTENDEE: FieldDescriptorProto.extendee set for "
+ "non-extension field.\n");
+}
+
+TEST_F(ValidationErrorTest, FieldOneofIndexTooLarge) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "message_type {"
+ " name: \"Foo\""
+ " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_INT32 "
+ " oneof_index: 1 }"
+ " field { name:\"dummy\" number:2 label:LABEL_OPTIONAL type:TYPE_INT32 "
+ " oneof_index: 0 }"
+ " oneof_decl { name:\"bar\" }"
+ "}",
+
+ "foo.proto: Foo.foo: TYPE: FieldDescriptorProto.oneof_index 1 is out of "
+ "range for type \"Foo\".\n");
+}
+
+TEST_F(ValidationErrorTest, FieldOneofIndexNegative) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "message_type {"
+ " name: \"Foo\""
+ " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_INT32 "
+ " oneof_index: -1 }"
+ " field { name:\"dummy\" number:2 label:LABEL_OPTIONAL type:TYPE_INT32 "
+ " oneof_index: 0 }"
+ " oneof_decl { name:\"bar\" }"
+ "}",
+
+ "foo.proto: Foo.foo: TYPE: FieldDescriptorProto.oneof_index -1 is out "
+ "of "
+ "range for type \"Foo\".\n");
+}
+
+TEST_F(ValidationErrorTest, OneofFieldsConsecutiveDefinition) {
+ // Fields belonging to the same oneof must be defined consecutively.
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "message_type {"
+ " name: \"Foo\""
+ " field { name:\"foo1\" number: 1 label:LABEL_OPTIONAL type:TYPE_INT32 "
+ " oneof_index: 0 }"
+ " field { name:\"bar\" number: 2 label:LABEL_OPTIONAL type:TYPE_INT32 }"
+ " field { name:\"foo2\" number: 3 label:LABEL_OPTIONAL type:TYPE_INT32 "
+ " oneof_index: 0 }"
+ " oneof_decl { name:\"foos\" }"
+ "}",
+
+ "foo.proto: Foo.bar: TYPE: Fields in the same oneof must be defined "
+ "consecutively. \"bar\" cannot be defined before the completion of the "
+ "\"foos\" oneof definition.\n");
+
+ // Prevent interleaved fields, which belong to different oneofs.
+ BuildFileWithErrors(
+ "name: \"foo2.proto\" "
+ "message_type {"
+ " name: \"Foo2\""
+ " field { name:\"foo1\" number: 1 label:LABEL_OPTIONAL type:TYPE_INT32 "
+ " oneof_index: 0 }"
+ " field { name:\"bar1\" number: 2 label:LABEL_OPTIONAL type:TYPE_INT32 "
+ " oneof_index: 1 }"
+ " field { name:\"foo2\" number: 3 label:LABEL_OPTIONAL type:TYPE_INT32 "
+ " oneof_index: 0 }"
+ " field { name:\"bar2\" number: 4 label:LABEL_OPTIONAL type:TYPE_INT32 "
+ " oneof_index: 1 }"
+ " oneof_decl { name:\"foos\" }"
+ " oneof_decl { name:\"bars\" }"
+ "}",
+ "foo2.proto: Foo2.bar1: TYPE: Fields in the same oneof must be defined "
+ "consecutively. \"bar1\" cannot be defined before the completion of the "
+ "\"foos\" oneof definition.\n"
+ "foo2.proto: Foo2.foo2: TYPE: Fields in the same oneof must be defined "
+ "consecutively. \"foo2\" cannot be defined before the completion of the "
+ "\"bars\" oneof definition.\n");
+
+ // Another case for normal fields and different oneof fields interleave.
+ BuildFileWithErrors(
+ "name: \"foo3.proto\" "
+ "message_type {"
+ " name: \"Foo3\""
+ " field { name:\"foo1\" number: 1 label:LABEL_OPTIONAL type:TYPE_INT32 "
+ " oneof_index: 0 }"
+ " field { name:\"bar1\" number: 2 label:LABEL_OPTIONAL type:TYPE_INT32 "
+ " oneof_index: 1 }"
+ " field { name:\"baz\" number: 3 label:LABEL_OPTIONAL type:TYPE_INT32 }"
+ " field { name:\"foo2\" number: 4 label:LABEL_OPTIONAL type:TYPE_INT32 "
+ " oneof_index: 0 }"
+ " oneof_decl { name:\"foos\" }"
+ " oneof_decl { name:\"bars\" }"
+ "}",
+ "foo3.proto: Foo3.baz: TYPE: Fields in the same oneof must be defined "
+ "consecutively. \"baz\" cannot be defined before the completion of the "
+ "\"foos\" oneof definition.\n");
+}
+
+TEST_F(ValidationErrorTest, FieldNumberConflict) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "message_type {"
+ " name: \"Foo\""
+ " field { name: \"foo\" number: 1 label:LABEL_OPTIONAL type:TYPE_INT32 }"
+ " field { name: \"bar\" number: 1 label:LABEL_OPTIONAL type:TYPE_INT32 }"
+ "}",
+
+ "foo.proto: Foo.bar: NUMBER: Field number 1 has already been used in "
+ "\"Foo\" by field \"foo\".\n");
+}
+
+TEST_F(ValidationErrorTest, BadMessageSetExtensionType) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "message_type {"
+ " name: \"MessageSet\""
+ " options { message_set_wire_format: true }"
+ " extension_range { start: 4 end: 5 }"
+ "}"
+ "message_type {"
+ " name: \"Foo\""
+ " extension { name:\"foo\" number:4 label:LABEL_OPTIONAL type:TYPE_INT32"
+ " extendee: \"MessageSet\" }"
+ "}",
+
+ "foo.proto: Foo.foo: TYPE: Extensions of MessageSets must be optional "
+ "messages.\n");
+}
+
+TEST_F(ValidationErrorTest, BadMessageSetExtensionLabel) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "message_type {"
+ " name: \"MessageSet\""
+ " options { message_set_wire_format: true }"
+ " extension_range { start: 4 end: 5 }"
+ "}"
+ "message_type {"
+ " name: \"Foo\""
+ " extension { name:\"foo\" number:4 label:LABEL_REPEATED "
+ "type:TYPE_MESSAGE"
+ " type_name: \"Foo\" extendee: \"MessageSet\" }"
+ "}",
+
+ "foo.proto: Foo.foo: TYPE: Extensions of MessageSets must be optional "
+ "messages.\n");
+}
+
+TEST_F(ValidationErrorTest, FieldInMessageSet) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "message_type {"
+ " name: \"Foo\""
+ " options { message_set_wire_format: true }"
+ " field { name: \"foo\" number: 1 label:LABEL_OPTIONAL type:TYPE_INT32 }"
+ "}",
+
+ "foo.proto: Foo.foo: NAME: MessageSets cannot have fields, only "
+ "extensions.\n");
+}
+
+TEST_F(ValidationErrorTest, NegativeExtensionRangeNumber) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "message_type {"
+ " name: \"Foo\""
+ " extension_range { start: -10 end: -1 }"
+ "}",
+
+ "foo.proto: Foo: NUMBER: Extension numbers must be positive integers.\n");
+}
+
+TEST_F(ValidationErrorTest, HugeExtensionRangeNumber) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "message_type {"
+ " name: \"Foo\""
+ " extension_range { start: 1 end: 0x70000000 }"
+ "}",
+
+ "foo.proto: Foo: NUMBER: Extension numbers cannot be greater than "
+ "536870911.\n");
+}
+
+TEST_F(ValidationErrorTest, ExtensionRangeEndBeforeStart) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "message_type {"
+ " name: \"Foo\""
+ " extension_range { start: 10 end: 10 }"
+ " extension_range { start: 10 end: 5 }"
+ "}",
+
+ "foo.proto: Foo: NUMBER: Extension range end number must be greater than "
+ "start number.\n"
+ "foo.proto: Foo: NUMBER: Extension range end number must be greater than "
+ "start number.\n");
+}
+
+TEST_F(ValidationErrorTest, EmptyEnum) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "enum_type { name: \"Foo\" }"
+ // Also use the empty enum in a message to make sure there are no crashes
+ // during validation (possible if the code attempts to derive a default
+ // value for the field).
+ "message_type {"
+ " name: \"Bar\""
+ " field { name: \"foo\" number: 1 label:LABEL_OPTIONAL "
+ "type_name:\"Foo\" }"
+ " field { name: \"bar\" number: 2 label:LABEL_OPTIONAL "
+ "type_name:\"Foo\" "
+ " default_value: \"NO_SUCH_VALUE\" }"
+ "}",
+
+ "foo.proto: Foo: NAME: Enums must contain at least one value.\n"
+ "foo.proto: Bar.bar: DEFAULT_VALUE: Enum type \"Foo\" has no value named "
+ "\"NO_SUCH_VALUE\".\n");
+}
+
+TEST_F(ValidationErrorTest, UndefinedExtendee) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "message_type {"
+ " name: \"Foo\""
+ " extension { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_INT32"
+ " extendee: \"Bar\" }"
+ "}",
+
+ "foo.proto: Foo.foo: EXTENDEE: \"Bar\" is not defined.\n");
+}
+
+TEST_F(ValidationErrorTest, NonMessageExtendee) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "enum_type { name: \"Bar\" value { name:\"DUMMY\" number:0 } }"
+ "message_type {"
+ " name: \"Foo\""
+ " extension { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_INT32"
+ " extendee: \"Bar\" }"
+ "}",
+
+ "foo.proto: Foo.foo: EXTENDEE: \"Bar\" is not a message type.\n");
+}
+
+TEST_F(ValidationErrorTest, NotAnExtensionNumber) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "message_type {"
+ " name: \"Bar\""
+ "}"
+ "message_type {"
+ " name: \"Foo\""
+ " extension { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_INT32"
+ " extendee: \"Bar\" }"
+ "}",
+
+ "foo.proto: Foo.foo: NUMBER: \"Bar\" does not declare 1 as an extension "
+ "number.\n");
+}
+
+TEST_F(ValidationErrorTest, RequiredExtension) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "message_type {"
+ " name: \"Bar\""
+ " extension_range { start: 1000 end: 10000 }"
+ "}"
+ "message_type {"
+ " name: \"Foo\""
+ " extension {"
+ " name:\"foo\""
+ " number:1000"
+ " label:LABEL_REQUIRED"
+ " type:TYPE_INT32"
+ " extendee: \"Bar\""
+ " }"
+ "}",
+
+ "foo.proto: Foo.foo: TYPE: The extension Foo.foo cannot be required.\n");
+}
+
+TEST_F(ValidationErrorTest, UndefinedFieldType) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "message_type {"
+ " name: \"Foo\""
+ " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\" }"
+ "}",
+
+ "foo.proto: Foo.foo: TYPE: \"Bar\" is not defined.\n");
+}
+
+TEST_F(ValidationErrorTest, UndefinedFieldTypeWithDefault) {
+ // See b/12533582. Previously this failed because the default value was not
+ // accepted by the parser, which assumed an enum type, leading to an unclear
+ // error message. We want this input to yield a validation error instead,
+ // since the unknown type is the primary problem.
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "message_type {"
+ " name: \"Foo\""
+ " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"int\" "
+ " default_value:\"1\" }"
+ "}",
+
+ "foo.proto: Foo.foo: TYPE: \"int\" is not defined.\n");
+}
+
+TEST_F(ValidationErrorTest, UndefinedNestedFieldType) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "message_type {"
+ " name: \"Foo\""
+ " nested_type { name:\"Baz\" }"
+ " field { name:\"foo\" number:1"
+ " label:LABEL_OPTIONAL"
+ " type_name:\"Foo.Baz.Bar\" }"
+ "}",
+
+ "foo.proto: Foo.foo: TYPE: \"Foo.Baz.Bar\" is not defined.\n");
+}
+
+TEST_F(ValidationErrorTest, FieldTypeDefinedInUndeclaredDependency) {
+ BuildFile(
+ "name: \"bar.proto\" "
+ "message_type { name: \"Bar\" } ");
+
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "message_type {"
+ " name: \"Foo\""
+ " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\" }"
+ "}",
+ "foo.proto: Foo.foo: TYPE: \"Bar\" seems to be defined in \"bar.proto\", "
+ "which is not imported by \"foo.proto\". To use it here, please add the "
+ "necessary import.\n");
+}
+
+TEST_F(ValidationErrorTest, FieldTypeDefinedInIndirectDependency) {
+ // Test for hidden dependencies.
+ //
+ // // bar.proto
+ // message Bar{}
+ //
+ // // forward.proto
+ // import "bar.proto"
+ //
+ // // foo.proto
+ // import "forward.proto"
+ // message Foo {
+ // optional Bar foo = 1; // Error, needs to import bar.proto explicitly.
+ // }
+ //
+ BuildFile(
+ "name: \"bar.proto\" "
+ "message_type { name: \"Bar\" }");
+
+ BuildFile(
+ "name: \"forward.proto\""
+ "dependency: \"bar.proto\"");
+
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "dependency: \"forward.proto\" "
+ "message_type {"
+ " name: \"Foo\""
+ " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\" }"
+ "}",
+ "foo.proto: Foo.foo: TYPE: \"Bar\" seems to be defined in \"bar.proto\", "
+ "which is not imported by \"foo.proto\". To use it here, please add the "
+ "necessary import.\n");
+}
+
+TEST_F(ValidationErrorTest, FieldTypeDefinedInPublicDependency) {
+ // Test for public dependencies.
+ //
+ // // bar.proto
+ // message Bar{}
+ //
+ // // forward.proto
+ // import public "bar.proto"
+ //
+ // // foo.proto
+ // import "forward.proto"
+ // message Foo {
+ // optional Bar foo = 1; // Correct. "bar.proto" is public imported into
+ // // forward.proto, so when "foo.proto" imports
+ // // "forward.proto", it imports "bar.proto" too.
+ // }
+ //
+ BuildFile(
+ "name: \"bar.proto\" "
+ "message_type { name: \"Bar\" }");
+
+ BuildFile(
+ "name: \"forward.proto\""
+ "dependency: \"bar.proto\" "
+ "public_dependency: 0");
+
+ BuildFile(
+ "name: \"foo.proto\" "
+ "dependency: \"forward.proto\" "
+ "message_type {"
+ " name: \"Foo\""
+ " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\" }"
+ "}");
+}
+
+TEST_F(ValidationErrorTest, FieldTypeDefinedInTransitivePublicDependency) {
+ // Test for public dependencies.
+ //
+ // // bar.proto
+ // message Bar{}
+ //
+ // // forward.proto
+ // import public "bar.proto"
+ //
+ // // forward2.proto
+ // import public "forward.proto"
+ //
+ // // foo.proto
+ // import "forward2.proto"
+ // message Foo {
+ // optional Bar foo = 1; // Correct, public imports are transitive.
+ // }
+ //
+ BuildFile(
+ "name: \"bar.proto\" "
+ "message_type { name: \"Bar\" }");
+
+ BuildFile(
+ "name: \"forward.proto\""
+ "dependency: \"bar.proto\" "
+ "public_dependency: 0");
+
+ BuildFile(
+ "name: \"forward2.proto\""
+ "dependency: \"forward.proto\" "
+ "public_dependency: 0");
+
+ BuildFile(
+ "name: \"foo.proto\" "
+ "dependency: \"forward2.proto\" "
+ "message_type {"
+ " name: \"Foo\""
+ " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\" }"
+ "}");
+}
+
+TEST_F(ValidationErrorTest,
+ FieldTypeDefinedInPrivateDependencyOfPublicDependency) {
+ // Test for public dependencies.
+ //
+ // // bar.proto
+ // message Bar{}
+ //
+ // // forward.proto
+ // import "bar.proto"
+ //
+ // // forward2.proto
+ // import public "forward.proto"
+ //
+ // // foo.proto
+ // import "forward2.proto"
+ // message Foo {
+ // optional Bar foo = 1; // Error, the "bar.proto" is not public imported
+ // // into "forward.proto", so will not be imported
+ // // into either "forward2.proto" or "foo.proto".
+ // }
+ //
+ BuildFile(
+ "name: \"bar.proto\" "
+ "message_type { name: \"Bar\" }");
+
+ BuildFile(
+ "name: \"forward.proto\""
+ "dependency: \"bar.proto\"");
+
+ BuildFile(
+ "name: \"forward2.proto\""
+ "dependency: \"forward.proto\" "
+ "public_dependency: 0");
+
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "dependency: \"forward2.proto\" "
+ "message_type {"
+ " name: \"Foo\""
+ " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\" }"
+ "}",
+ "foo.proto: Foo.foo: TYPE: \"Bar\" seems to be defined in \"bar.proto\", "
+ "which is not imported by \"foo.proto\". To use it here, please add the "
+ "necessary import.\n");
+}
+
+
+TEST_F(ValidationErrorTest, SearchMostLocalFirst) {
+ // The following should produce an error that Bar.Baz is resolved but
+ // not defined:
+ // message Bar { message Baz {} }
+ // message Foo {
+ // message Bar {
+ // // Placing "message Baz{}" here, or removing Foo.Bar altogether,
+ // // would fix the error.
+ // }
+ // optional Bar.Baz baz = 1;
+ // }
+ // An one point the lookup code incorrectly did not produce an error in this
+ // case, because when looking for Bar.Baz, it would try "Foo.Bar.Baz" first,
+ // fail, and ten try "Bar.Baz" and succeed, even though "Bar" should actually
+ // refer to the inner Bar, not the outer one.
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "message_type {"
+ " name: \"Bar\""
+ " nested_type { name: \"Baz\" }"
+ "}"
+ "message_type {"
+ " name: \"Foo\""
+ " nested_type { name: \"Bar\" }"
+ " field { name:\"baz\" number:1 label:LABEL_OPTIONAL"
+ " type_name:\"Bar.Baz\" }"
+ "}",
+
+ "foo.proto: Foo.baz: TYPE: \"Bar.Baz\" is resolved to \"Foo.Bar.Baz\","
+ " which is not defined. The innermost scope is searched first in name "
+ "resolution. Consider using a leading '.'(i.e., \".Bar.Baz\") to start "
+ "from the outermost scope.\n");
+}
+
+TEST_F(ValidationErrorTest, SearchMostLocalFirst2) {
+ // This test would find the most local "Bar" first, and does, but
+ // proceeds to find the outer one because the inner one's not an
+ // aggregate.
+ BuildFile(
+ "name: \"foo.proto\" "
+ "message_type {"
+ " name: \"Bar\""
+ " nested_type { name: \"Baz\" }"
+ "}"
+ "message_type {"
+ " name: \"Foo\""
+ " field { name: \"Bar\" number:1 type:TYPE_BYTES } "
+ " field { name:\"baz\" number:2 label:LABEL_OPTIONAL"
+ " type_name:\"Bar.Baz\" }"
+ "}");
+}
+
+TEST_F(ValidationErrorTest, PackageOriginallyDeclaredInTransitiveDependent) {
+ // Imagine we have the following:
+ //
+ // foo.proto:
+ // package foo.bar;
+ // bar.proto:
+ // package foo.bar;
+ // import "foo.proto";
+ // message Bar {}
+ // baz.proto:
+ // package foo;
+ // import "bar.proto"
+ // message Baz { optional bar.Bar qux = 1; }
+ //
+ // When validating baz.proto, we will look up "bar.Bar". As part of this
+ // lookup, we first lookup "bar" then try to find "Bar" within it. "bar"
+ // should resolve to "foo.bar". Note, though, that "foo.bar" was originally
+ // defined in foo.proto, which is not a direct dependency of baz.proto. The
+ // implementation of FindSymbol() normally only returns symbols in direct
+ // dependencies, not indirect ones. This test insures that this does not
+ // prevent it from finding "foo.bar".
+
+ BuildFile(
+ "name: \"foo.proto\" "
+ "package: \"foo.bar\" ");
+ BuildFile(
+ "name: \"bar.proto\" "
+ "package: \"foo.bar\" "
+ "dependency: \"foo.proto\" "
+ "message_type { name: \"Bar\" }");
+ BuildFile(
+ "name: \"baz.proto\" "
+ "package: \"foo\" "
+ "dependency: \"bar.proto\" "
+ "message_type { "
+ " name: \"Baz\" "
+ " field { name:\"qux\" number:1 label:LABEL_OPTIONAL "
+ " type_name:\"bar.Bar\" }"
+ "}");
+}
+
+TEST_F(ValidationErrorTest, FieldTypeNotAType) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "message_type {"
+ " name: \"Foo\""
+ " field { name:\"foo\" number:1 label:LABEL_OPTIONAL "
+ " type_name:\".Foo.bar\" }"
+ " field { name:\"bar\" number:2 label:LABEL_OPTIONAL type:TYPE_INT32 }"
+ "}",
+
+ "foo.proto: Foo.foo: TYPE: \".Foo.bar\" is not a type.\n");
+}
+
+TEST_F(ValidationErrorTest, RelativeFieldTypeNotAType) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "message_type {"
+ " nested_type {"
+ " name: \"Bar\""
+ " field { name:\"Baz\" number:2 label:LABEL_OPTIONAL type:TYPE_INT32 }"
+ " }"
+ " name: \"Foo\""
+ " field { name:\"foo\" number:1 label:LABEL_OPTIONAL "
+ " type_name:\"Bar.Baz\" }"
+ "}",
+ "foo.proto: Foo.foo: TYPE: \"Bar.Baz\" is not a type.\n");
+}
+
+TEST_F(ValidationErrorTest, FieldTypeMayBeItsName) {
+ BuildFile(
+ "name: \"foo.proto\" "
+ "message_type {"
+ " name: \"Bar\""
+ "}"
+ "message_type {"
+ " name: \"Foo\""
+ " field { name:\"Bar\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\" }"
+ "}");
+}
+
+TEST_F(ValidationErrorTest, EnumFieldTypeIsMessage) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "message_type { name: \"Bar\" } "
+ "message_type {"
+ " name: \"Foo\""
+ " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_ENUM"
+ " type_name:\"Bar\" }"
+ "}",
+
+ "foo.proto: Foo.foo: TYPE: \"Bar\" is not an enum type.\n");
+}
+
+TEST_F(ValidationErrorTest, MessageFieldTypeIsEnum) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "enum_type { name: \"Bar\" value { name:\"DUMMY\" number:0 } } "
+ "message_type {"
+ " name: \"Foo\""
+ " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_MESSAGE"
+ " type_name:\"Bar\" }"
+ "}",
+
+ "foo.proto: Foo.foo: TYPE: \"Bar\" is not a message type.\n");
+}
+
+TEST_F(ValidationErrorTest, BadEnumDefaultValue) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "enum_type { name: \"Bar\" value { name:\"DUMMY\" number:0 } } "
+ "message_type {"
+ " name: \"Foo\""
+ " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\""
+ " default_value:\"NO_SUCH_VALUE\" }"
+ "}",
+
+ "foo.proto: Foo.foo: DEFAULT_VALUE: Enum type \"Bar\" has no value named "
+ "\"NO_SUCH_VALUE\".\n");
+}
+
+TEST_F(ValidationErrorTest, EnumDefaultValueIsInteger) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "enum_type { name: \"Bar\" value { name:\"DUMMY\" number:0 } } "
+ "message_type {"
+ " name: \"Foo\""
+ " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\""
+ " default_value:\"0\" }"
+ "}",
+
+ "foo.proto: Foo.foo: DEFAULT_VALUE: Default value for an enum field must "
+ "be an identifier.\n");
+}
+
+TEST_F(ValidationErrorTest, PrimitiveWithTypeName) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "message_type {"
+ " name: \"Foo\""
+ " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_INT32"
+ " type_name:\"Foo\" }"
+ "}",
+
+ "foo.proto: Foo.foo: TYPE: Field with primitive type has type_name.\n");
+}
+
+TEST_F(ValidationErrorTest, NonPrimitiveWithoutTypeName) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "message_type {"
+ " name: \"Foo\""
+ " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_MESSAGE }"
+ "}",
+
+ "foo.proto: Foo.foo: TYPE: Field with message or enum type missing "
+ "type_name.\n");
+}
+
+TEST_F(ValidationErrorTest, OneofWithNoFields) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "message_type {"
+ " name: \"Foo\""
+ " oneof_decl { name:\"bar\" }"
+ "}",
+
+ "foo.proto: Foo.bar: NAME: Oneof must have at least one field.\n");
+}
+
+TEST_F(ValidationErrorTest, OneofLabelMismatch) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "message_type {"
+ " name: \"Foo\""
+ " field { name:\"foo\" number:1 label:LABEL_REPEATED type:TYPE_INT32 "
+ " oneof_index:0 }"
+ " oneof_decl { name:\"bar\" }"
+ "}",
+
+ "foo.proto: Foo.foo: NAME: Fields of oneofs must themselves have label "
+ "LABEL_OPTIONAL.\n");
+}
+
+TEST_F(ValidationErrorTest, InputTypeNotDefined) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "message_type { name: \"Foo\" } "
+ "service {"
+ " name: \"TestService\""
+ " method { name: \"A\" input_type: \"Bar\" output_type: \"Foo\" }"
+ "}",
+
+ "foo.proto: TestService.A: INPUT_TYPE: \"Bar\" is not defined.\n"
+ );
+}
+
+TEST_F(ValidationErrorTest, InputTypeNotAMessage) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "message_type { name: \"Foo\" } "
+ "enum_type { name: \"Bar\" value { name:\"DUMMY\" number:0 } } "
+ "service {"
+ " name: \"TestService\""
+ " method { name: \"A\" input_type: \"Bar\" output_type: \"Foo\" }"
+ "}",
+
+ "foo.proto: TestService.A: INPUT_TYPE: \"Bar\" is not a message type.\n"
+ );
+}
+
+TEST_F(ValidationErrorTest, OutputTypeNotDefined) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "message_type { name: \"Foo\" } "
+ "service {"
+ " name: \"TestService\""
+ " method { name: \"A\" input_type: \"Foo\" output_type: \"Bar\" }"
+ "}",
+
+ "foo.proto: TestService.A: OUTPUT_TYPE: \"Bar\" is not defined.\n"
+ );
+}
+
+TEST_F(ValidationErrorTest, OutputTypeNotAMessage) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "message_type { name: \"Foo\" } "
+ "enum_type { name: \"Bar\" value { name:\"DUMMY\" number:0 } } "
+ "service {"
+ " name: \"TestService\""
+ " method { name: \"A\" input_type: \"Foo\" output_type: \"Bar\" }"
+ "}",
+
+ "foo.proto: TestService.A: OUTPUT_TYPE: \"Bar\" is not a message type.\n"
+ );
+}
+
+
+TEST_F(ValidationErrorTest, IllegalPackedField) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "message_type {\n"
+ " name: \"Foo\""
+ " field { name:\"packed_string\" number:1 label:LABEL_REPEATED "
+ " type:TYPE_STRING "
+ " options { uninterpreted_option {"
+ " name { name_part: \"packed\" is_extension: false }"
+ " identifier_value: \"true\" }}}\n"
+ " field { name:\"packed_message\" number:3 label:LABEL_REPEATED "
+ " type_name: \"Foo\""
+ " options { uninterpreted_option {"
+ " name { name_part: \"packed\" is_extension: false }"
+ " identifier_value: \"true\" }}}\n"
+ " field { name:\"optional_int32\" number: 4 label: LABEL_OPTIONAL "
+ " type:TYPE_INT32 "
+ " options { uninterpreted_option {"
+ " name { name_part: \"packed\" is_extension: false }"
+ " identifier_value: \"true\" }}}\n"
+ "}",
+
+ "foo.proto: Foo.packed_string: TYPE: [packed = true] can only be "
+ "specified for repeated primitive fields.\n"
+ "foo.proto: Foo.packed_message: TYPE: [packed = true] can only be "
+ "specified for repeated primitive fields.\n"
+ "foo.proto: Foo.optional_int32: TYPE: [packed = true] can only be "
+ "specified for repeated primitive fields.\n");
+}
+
+TEST_F(ValidationErrorTest, OptionWrongType) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "message_type { "
+ " name: \"TestMessage\" "
+ " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_STRING "
+ " options { uninterpreted_option { name { name_part: \"ctype\" "
+ " is_extension: false }"
+ " positive_int_value: 1 }"
+ " }"
+ " }"
+ "}\n",
+
+ "foo.proto: TestMessage.foo: OPTION_VALUE: Value must be identifier for "
+ "enum-valued option \"google.protobuf.FieldOptions.ctype\".\n");
+}
+
+TEST_F(ValidationErrorTest, OptionExtendsAtomicType) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "message_type { "
+ " name: \"TestMessage\" "
+ " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_STRING "
+ " options { uninterpreted_option { name { name_part: \"ctype\" "
+ " is_extension: false }"
+ " name { name_part: \"foo\" "
+ " is_extension: true }"
+ " positive_int_value: 1 }"
+ " }"
+ " }"
+ "}\n",
+
+ "foo.proto: TestMessage.foo: OPTION_NAME: Option \"ctype\" is an "
+ "atomic type, not a message.\n");
+}
+
+TEST_F(ValidationErrorTest, DupOption) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "message_type { "
+ " name: \"TestMessage\" "
+ " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_UINT32 "
+ " options { uninterpreted_option { name { name_part: \"ctype\" "
+ " is_extension: false }"
+ " identifier_value: \"CORD\" }"
+ " uninterpreted_option { name { name_part: \"ctype\" "
+ " is_extension: false }"
+ " identifier_value: \"CORD\" }"
+ " }"
+ " }"
+ "}\n",
+
+ "foo.proto: TestMessage.foo: OPTION_NAME: Option \"ctype\" was "
+ "already set.\n");
+}
+
+TEST_F(ValidationErrorTest, InvalidOptionName) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "message_type { "
+ " name: \"TestMessage\" "
+ " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_BOOL "
+ " options { uninterpreted_option { "
+ " name { name_part: \"uninterpreted_option\" "
+ " is_extension: false }"
+ " positive_int_value: 1 "
+ " }"
+ " }"
+ " }"
+ "}\n",
+
+ "foo.proto: TestMessage.foo: OPTION_NAME: Option must not use "
+ "reserved name \"uninterpreted_option\".\n");
+}
+
+TEST_F(ValidationErrorTest, RepeatedMessageOption) {
+ BuildDescriptorMessagesInTestPool();
+
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "dependency: \"google/protobuf/descriptor.proto\" "
+ "message_type: { name: \"Bar\" field: { "
+ " name: \"foo\" number: 1 label: LABEL_OPTIONAL type: TYPE_INT32 } "
+ "} "
+ "extension { name: \"bar\" number: 7672757 label: LABEL_REPEATED "
+ " type: TYPE_MESSAGE type_name: \"Bar\" "
+ " extendee: \"google.protobuf.FileOptions\" }"
+ "options { uninterpreted_option { name { name_part: \"bar\" "
+ " is_extension: true } "
+ " name { name_part: \"foo\" "
+ " is_extension: false } "
+ " positive_int_value: 1 } }",
+
+ "foo.proto: foo.proto: OPTION_NAME: Option field \"(bar)\" is a "
+ "repeated message. Repeated message options must be initialized "
+ "using an aggregate value.\n");
+}
+
+TEST_F(ValidationErrorTest, ResolveUndefinedOption) {
+ // The following should produce an error that baz.bar is resolved but not
+ // defined.
+ // foo.proto:
+ // package baz
+ // import google/protobuf/descriptor.proto
+ // message Bar { optional int32 foo = 1; }
+ // extend FileOptions { optional Bar bar = 7672757; }
+ //
+ // qux.proto:
+ // package qux.baz
+ // option (baz.bar).foo = 1;
+ //
+ // Although "baz.bar" is already defined, the lookup code will try
+ // "qux.baz.bar", since it's the match from the innermost scope, which will
+ // cause a symbol not defined error.
+ BuildDescriptorMessagesInTestPool();
+
+ BuildFile(
+ "name: \"foo.proto\" "
+ "package: \"baz\" "
+ "dependency: \"google/protobuf/descriptor.proto\" "
+ "message_type: { name: \"Bar\" field: { "
+ " name: \"foo\" number: 1 label: LABEL_OPTIONAL type: TYPE_INT32 } "
+ "} "
+ "extension { name: \"bar\" number: 7672757 label: LABEL_OPTIONAL "
+ " type: TYPE_MESSAGE type_name: \"Bar\" "
+ " extendee: \"google.protobuf.FileOptions\" }");
+
+ BuildFileWithErrors(
+ "name: \"qux.proto\" "
+ "package: \"qux.baz\" "
+ "options { uninterpreted_option { name { name_part: \"baz.bar\" "
+ " is_extension: true } "
+ " name { name_part: \"foo\" "
+ " is_extension: false } "
+ " positive_int_value: 1 } }",
+
+ "qux.proto: qux.proto: OPTION_NAME: Option \"(baz.bar)\" is resolved to "
+ "\"(qux.baz.bar)\","
+ " which is not defined. The innermost scope is searched first in name "
+ "resolution. Consider using a leading '.'(i.e., \"(.baz.bar)\") to start "
+ "from the outermost scope.\n");
+}
+
+TEST_F(ValidationErrorTest, UnknownOption) {
+ BuildFileWithErrors(
+ "name: \"qux.proto\" "
+ "package: \"qux.baz\" "
+ "options { uninterpreted_option { name { name_part: \"baaz.bar\" "
+ " is_extension: true } "
+ " name { name_part: \"foo\" "
+ " is_extension: false } "
+ " positive_int_value: 1 } }",
+
+ "qux.proto: qux.proto: OPTION_NAME: Option \"(baaz.bar)\" unknown. "
+ "Ensure "
+ "that your proto definition file imports the proto which defines the "
+ "option.\n");
+}
+
+TEST_F(ValidationErrorTest, CustomOptionConflictingFieldNumber) {
+ BuildDescriptorMessagesInTestPool();
+
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "dependency: \"google/protobuf/descriptor.proto\" "
+ "extension { name: \"foo1\" number: 7672757 label: LABEL_OPTIONAL "
+ " type: TYPE_INT32 extendee: \"google.protobuf.FieldOptions\" }"
+ "extension { name: \"foo2\" number: 7672757 label: LABEL_OPTIONAL "
+ " type: TYPE_INT32 extendee: \"google.protobuf.FieldOptions\" }",
+
+ "foo.proto: foo2: NUMBER: Extension number 7672757 has already been used "
+ "in \"google.protobuf.FieldOptions\" by extension \"foo1\".\n");
+}
+
+TEST_F(ValidationErrorTest, Int32OptionValueOutOfPositiveRange) {
+ BuildDescriptorMessagesInTestPool();
+
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "dependency: \"google/protobuf/descriptor.proto\" "
+ "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
+ " type: TYPE_INT32 extendee: \"google.protobuf.FileOptions\" }"
+ "options { uninterpreted_option { name { name_part: \"foo\" "
+ " is_extension: true } "
+ " positive_int_value: 0x80000000 } "
+ "}",
+
+ "foo.proto: foo.proto: OPTION_VALUE: Value out of range "
+ "for int32 option \"foo\".\n");
+}
+
+TEST_F(ValidationErrorTest, Int32OptionValueOutOfNegativeRange) {
+ BuildDescriptorMessagesInTestPool();
+
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "dependency: \"google/protobuf/descriptor.proto\" "
+ "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
+ " type: TYPE_INT32 extendee: \"google.protobuf.FileOptions\" }"
+ "options { uninterpreted_option { name { name_part: \"foo\" "
+ " is_extension: true } "
+ " negative_int_value: -0x80000001 } "
+ "}",
+
+ "foo.proto: foo.proto: OPTION_VALUE: Value out of range "
+ "for int32 option \"foo\".\n");
+}
+
+TEST_F(ValidationErrorTest, Int32OptionValueIsNotPositiveInt) {
+ BuildDescriptorMessagesInTestPool();
+
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "dependency: \"google/protobuf/descriptor.proto\" "
+ "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
+ " type: TYPE_INT32 extendee: \"google.protobuf.FileOptions\" }"
+ "options { uninterpreted_option { name { name_part: \"foo\" "
+ " is_extension: true } "
+ " string_value: \"5\" } }",
+
+ "foo.proto: foo.proto: OPTION_VALUE: Value must be integer "
+ "for int32 option \"foo\".\n");
+}
+
+TEST_F(ValidationErrorTest, Int64OptionValueOutOfRange) {
+ BuildDescriptorMessagesInTestPool();
+
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "dependency: \"google/protobuf/descriptor.proto\" "
+ "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
+ " type: TYPE_INT64 extendee: \"google.protobuf.FileOptions\" }"
+ "options { uninterpreted_option { name { name_part: \"foo\" "
+ " is_extension: true } "
+ " positive_int_value: 0x8000000000000000 "
+ "} "
+ "}",
+
+ "foo.proto: foo.proto: OPTION_VALUE: Value out of range "
+ "for int64 option \"foo\".\n");
+}
+
+TEST_F(ValidationErrorTest, Int64OptionValueIsNotPositiveInt) {
+ BuildDescriptorMessagesInTestPool();
+
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "dependency: \"google/protobuf/descriptor.proto\" "
+ "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
+ " type: TYPE_INT64 extendee: \"google.protobuf.FileOptions\" }"
+ "options { uninterpreted_option { name { name_part: \"foo\" "
+ " is_extension: true } "
+ " identifier_value: \"5\" } }",
+
+ "foo.proto: foo.proto: OPTION_VALUE: Value must be integer "
+ "for int64 option \"foo\".\n");
+}
+
+TEST_F(ValidationErrorTest, UInt32OptionValueOutOfRange) {
+ BuildDescriptorMessagesInTestPool();
+
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "dependency: \"google/protobuf/descriptor.proto\" "
+ "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
+ " type: TYPE_UINT32 extendee: \"google.protobuf.FileOptions\" }"
+ "options { uninterpreted_option { name { name_part: \"foo\" "
+ " is_extension: true } "
+ " positive_int_value: 0x100000000 } }",
+
+ "foo.proto: foo.proto: OPTION_VALUE: Value out of range "
+ "for uint32 option \"foo\".\n");
+}
+
+TEST_F(ValidationErrorTest, UInt32OptionValueIsNotPositiveInt) {
+ BuildDescriptorMessagesInTestPool();
+
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "dependency: \"google/protobuf/descriptor.proto\" "
+ "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
+ " type: TYPE_UINT32 extendee: \"google.protobuf.FileOptions\" }"
+ "options { uninterpreted_option { name { name_part: \"foo\" "
+ " is_extension: true } "
+ " double_value: -5.6 } }",
+
+ "foo.proto: foo.proto: OPTION_VALUE: Value must be non-negative integer "
+ "for uint32 option \"foo\".\n");
+}
+
+TEST_F(ValidationErrorTest, UInt64OptionValueIsNotPositiveInt) {
+ BuildDescriptorMessagesInTestPool();
+
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "dependency: \"google/protobuf/descriptor.proto\" "
+ "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
+ " type: TYPE_UINT64 extendee: \"google.protobuf.FileOptions\" }"
+ "options { uninterpreted_option { name { name_part: \"foo\" "
+ " is_extension: true } "
+ " negative_int_value: -5 } }",
+
+ "foo.proto: foo.proto: OPTION_VALUE: Value must be non-negative integer "
+ "for uint64 option \"foo\".\n");
+}
+
+TEST_F(ValidationErrorTest, FloatOptionValueIsNotNumber) {
+ BuildDescriptorMessagesInTestPool();
+
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "dependency: \"google/protobuf/descriptor.proto\" "
+ "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
+ " type: TYPE_FLOAT extendee: \"google.protobuf.FileOptions\" }"
+ "options { uninterpreted_option { name { name_part: \"foo\" "
+ " is_extension: true } "
+ " string_value: \"bar\" } }",
+
+ "foo.proto: foo.proto: OPTION_VALUE: Value must be number "
+ "for float option \"foo\".\n");
+}
+
+TEST_F(ValidationErrorTest, DoubleOptionValueIsNotNumber) {
+ BuildDescriptorMessagesInTestPool();
+
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "dependency: \"google/protobuf/descriptor.proto\" "
+ "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
+ " type: TYPE_DOUBLE extendee: \"google.protobuf.FileOptions\" }"
+ "options { uninterpreted_option { name { name_part: \"foo\" "
+ " is_extension: true } "
+ " string_value: \"bar\" } }",
+
+ "foo.proto: foo.proto: OPTION_VALUE: Value must be number "
+ "for double option \"foo\".\n");
+}
+
+TEST_F(ValidationErrorTest, BoolOptionValueIsNotTrueOrFalse) {
+ BuildDescriptorMessagesInTestPool();
+
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "dependency: \"google/protobuf/descriptor.proto\" "
+ "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
+ " type: TYPE_BOOL extendee: \"google.protobuf.FileOptions\" }"
+ "options { uninterpreted_option { name { name_part: \"foo\" "
+ " is_extension: true } "
+ " identifier_value: \"bar\" } }",
+
+ "foo.proto: foo.proto: OPTION_VALUE: Value must be \"true\" or \"false\" "
+ "for boolean option \"foo\".\n");
+}
+
+TEST_F(ValidationErrorTest, EnumOptionValueIsNotIdentifier) {
+ BuildDescriptorMessagesInTestPool();
+
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "dependency: \"google/protobuf/descriptor.proto\" "
+ "enum_type { name: \"FooEnum\" value { name: \"BAR\" number: 1 } "
+ " value { name: \"BAZ\" number: 2 } }"
+ "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
+ " type: TYPE_ENUM type_name: \"FooEnum\" "
+ " extendee: \"google.protobuf.FileOptions\" }"
+ "options { uninterpreted_option { name { name_part: \"foo\" "
+ " is_extension: true } "
+ " string_value: \"QUUX\" } }",
+
+ "foo.proto: foo.proto: OPTION_VALUE: Value must be identifier for "
+ "enum-valued option \"foo\".\n");
+}
+
+TEST_F(ValidationErrorTest, EnumOptionValueIsNotEnumValueName) {
+ BuildDescriptorMessagesInTestPool();
+
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "dependency: \"google/protobuf/descriptor.proto\" "
+ "enum_type { name: \"FooEnum\" value { name: \"BAR\" number: 1 } "
+ " value { name: \"BAZ\" number: 2 } }"
+ "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
+ " type: TYPE_ENUM type_name: \"FooEnum\" "
+ " extendee: \"google.protobuf.FileOptions\" }"
+ "options { uninterpreted_option { name { name_part: \"foo\" "
+ " is_extension: true } "
+ " identifier_value: \"QUUX\" } }",
+
+ "foo.proto: foo.proto: OPTION_VALUE: Enum type \"FooEnum\" has no value "
+ "named \"QUUX\" for option \"foo\".\n");
+}
+
+TEST_F(ValidationErrorTest, EnumOptionValueIsSiblingEnumValueName) {
+ BuildDescriptorMessagesInTestPool();
+
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "dependency: \"google/protobuf/descriptor.proto\" "
+ "enum_type { name: \"FooEnum1\" value { name: \"BAR\" number: 1 } "
+ " value { name: \"BAZ\" number: 2 } }"
+ "enum_type { name: \"FooEnum2\" value { name: \"QUX\" number: 1 } "
+ " value { name: \"QUUX\" number: 2 } }"
+ "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
+ " type: TYPE_ENUM type_name: \"FooEnum1\" "
+ " extendee: \"google.protobuf.FileOptions\" }"
+ "options { uninterpreted_option { name { name_part: \"foo\" "
+ " is_extension: true } "
+ " identifier_value: \"QUUX\" } }",
+
+ "foo.proto: foo.proto: OPTION_VALUE: Enum type \"FooEnum1\" has no value "
+ "named \"QUUX\" for option \"foo\". This appears to be a value from a "
+ "sibling type.\n");
+}
+
+TEST_F(ValidationErrorTest, StringOptionValueIsNotString) {
+ BuildDescriptorMessagesInTestPool();
+
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "dependency: \"google/protobuf/descriptor.proto\" "
+ "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
+ " type: TYPE_STRING extendee: \"google.protobuf.FileOptions\" }"
+ "options { uninterpreted_option { name { name_part: \"foo\" "
+ " is_extension: true } "
+ " identifier_value: \"QUUX\" } }",
+
+ "foo.proto: foo.proto: OPTION_VALUE: Value must be quoted string "
+ "for "
+ "string option \"foo\".\n");
+}
+
+TEST_F(ValidationErrorTest, JsonNameOptionOnExtensions) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "package: \"foo\" "
+ "message_type {"
+ " name: \"Foo\""
+ " extension_range { start: 10 end: 20 }"
+ "}"
+ "extension {"
+ " name: \"value\""
+ " number: 10"
+ " label: LABEL_OPTIONAL"
+ " type: TYPE_INT32"
+ " extendee: \"foo.Foo\""
+ " json_name: \"myName\""
+ "}",
+ "foo.proto: foo.value: OPTION_NAME: option json_name is not allowed on "
+ "extension fields.\n");
+}
+
+TEST_F(ValidationErrorTest, DuplicateExtensionFieldNumber) {
+ BuildDescriptorMessagesInTestPool();
+
+ BuildFile(
+ "name: \"foo.proto\" "
+ "dependency: \"google/protobuf/descriptor.proto\" "
+ "extension { name: \"option1\" number: 1000 label: LABEL_OPTIONAL "
+ " type: TYPE_INT32 extendee: \"google.protobuf.FileOptions\" }");
+
+ BuildFileWithWarnings(
+ "name: \"bar.proto\" "
+ "dependency: \"google/protobuf/descriptor.proto\" "
+ "extension { name: \"option2\" number: 1000 label: LABEL_OPTIONAL "
+ " type: TYPE_INT32 extendee: \"google.protobuf.FileOptions\" }",
+ "bar.proto: option2: NUMBER: Extension number 1000 has already been used "
+ "in \"google.protobuf.FileOptions\" by extension \"option1\" defined in "
+ "foo.proto.\n");
+}
+
+// Helper function for tests that check for aggregate value parsing
+// errors. The "value" argument is embedded inside the
+// "uninterpreted_option" portion of the result.
+static std::string EmbedAggregateValue(const char* value) {
+ return strings::Substitute(
+ "name: \"foo.proto\" "
+ "dependency: \"google/protobuf/descriptor.proto\" "
+ "message_type { name: \"Foo\" } "
+ "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
+ " type: TYPE_MESSAGE type_name: \"Foo\" "
+ " extendee: \"google.protobuf.FileOptions\" }"
+ "options { uninterpreted_option { name { name_part: \"foo\" "
+ " is_extension: true } "
+ " $0 } }",
+ value);
+}
+
+TEST_F(ValidationErrorTest, AggregateValueNotFound) {
+ BuildDescriptorMessagesInTestPool();
+
+ BuildFileWithErrors(
+ EmbedAggregateValue("string_value: \"\""),
+ "foo.proto: foo.proto: OPTION_VALUE: Option \"foo\" is a message. "
+ "To set the entire message, use syntax like "
+ "\"foo = { <proto text format> }\". To set fields within it, use "
+ "syntax like \"foo.foo = value\".\n");
+}
+
+TEST_F(ValidationErrorTest, AggregateValueParseError) {
+ BuildDescriptorMessagesInTestPool();
+
+ BuildFileWithErrors(
+ EmbedAggregateValue("aggregate_value: \"1+2\""),
+ "foo.proto: foo.proto: OPTION_VALUE: Error while parsing option "
+ "value for \"foo\": Expected identifier, got: 1\n");
+}
+
+TEST_F(ValidationErrorTest, AggregateValueUnknownFields) {
+ BuildDescriptorMessagesInTestPool();
+
+ BuildFileWithErrors(
+ EmbedAggregateValue("aggregate_value: \"x:100\""),
+ "foo.proto: foo.proto: OPTION_VALUE: Error while parsing option "
+ "value for \"foo\": Message type \"Foo\" has no field named \"x\".\n");
+}
+
+TEST_F(ValidationErrorTest, NotLiteImportsLite) {
+ BuildFile(
+ "name: \"bar.proto\" "
+ "options { optimize_for: LITE_RUNTIME } ");
+
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "dependency: \"bar.proto\" ",
+
+ "foo.proto: bar.proto: 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 \"bar.proto\" which is.\n");
+}
+
+TEST_F(ValidationErrorTest, LiteExtendsNotLite) {
+ BuildFile(
+ "name: \"bar.proto\" "
+ "message_type: {"
+ " name: \"Bar\""
+ " extension_range { start: 1 end: 1000 }"
+ "}");
+
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "dependency: \"bar.proto\" "
+ "options { optimize_for: LITE_RUNTIME } "
+ "extension { name: \"ext\" number: 123 label: LABEL_OPTIONAL "
+ " type: TYPE_INT32 extendee: \"Bar\" }",
+
+ "foo.proto: ext: 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.\n");
+}
+
+TEST_F(ValidationErrorTest, NoLiteServices) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "options {"
+ " optimize_for: LITE_RUNTIME"
+ " cc_generic_services: true"
+ " java_generic_services: true"
+ "} "
+ "service { name: \"Foo\" }",
+
+ "foo.proto: Foo: NAME: Files with optimize_for = LITE_RUNTIME cannot "
+ "define services unless you set both options cc_generic_services and "
+ "java_generic_services to false.\n");
+
+ BuildFile(
+ "name: \"bar.proto\" "
+ "options {"
+ " optimize_for: LITE_RUNTIME"
+ " cc_generic_services: false"
+ " java_generic_services: false"
+ "} "
+ "service { name: \"Bar\" }");
+}
+
+TEST_F(ValidationErrorTest, RollbackAfterError) {
+ // Build a file which contains every kind of construct but references an
+ // undefined type. All these constructs will be added to the symbol table
+ // before the undefined type error is noticed. The DescriptorPool will then
+ // have to roll everything back.
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "message_type {"
+ " name: \"TestMessage\""
+ " field { name:\"foo\" label:LABEL_OPTIONAL type:TYPE_INT32 number:1 }"
+ "} "
+ "enum_type {"
+ " name: \"TestEnum\""
+ " value { name:\"BAR\" number:1 }"
+ "} "
+ "service {"
+ " name: \"TestService\""
+ " method {"
+ " name: \"Baz\""
+ " input_type: \"NoSuchType\"" // error
+ " output_type: \"TestMessage\""
+ " }"
+ "}",
+
+ "foo.proto: TestService.Baz: INPUT_TYPE: \"NoSuchType\" is not defined.\n"
+ );
+
+ // Make sure that if we build the same file again with the error fixed,
+ // it works. If the above rollback was incomplete, then some symbols will
+ // be left defined, and this second attempt will fail since it tries to
+ // re-define the same symbols.
+ BuildFile(
+ "name: \"foo.proto\" "
+ "message_type {"
+ " name: \"TestMessage\""
+ " field { name:\"foo\" label:LABEL_OPTIONAL type:TYPE_INT32 number:1 }"
+ "} "
+ "enum_type {"
+ " name: \"TestEnum\""
+ " value { name:\"BAR\" number:1 }"
+ "} "
+ "service {"
+ " name: \"TestService\""
+ " method { name:\"Baz\""
+ " input_type:\"TestMessage\""
+ " output_type:\"TestMessage\" }"
+ "}");
+}
+
+TEST_F(ValidationErrorTest, ErrorsReportedToLogError) {
+ // Test that errors are reported to GOOGLE_LOG(ERROR) if no error collector is
+ // provided.
+
+ FileDescriptorProto file_proto;
+ ASSERT_TRUE(
+ TextFormat::ParseFromString("name: \"foo.proto\" "
+ "message_type { name: \"Foo\" } "
+ "message_type { name: \"Foo\" } ",
+ &file_proto));
+
+ std::vector<std::string> errors;
+
+ {
+ ScopedMemoryLog log;
+ EXPECT_TRUE(pool_.BuildFile(file_proto) == nullptr);
+ errors = log.GetMessages(ERROR);
+ }
+
+ ASSERT_EQ(2, errors.size());
+
+ EXPECT_EQ("Invalid proto descriptor for file \"foo.proto\":", errors[0]);
+ EXPECT_EQ(" Foo: \"Foo\" is already defined.", errors[1]);
+}
+
+TEST_F(ValidationErrorTest, DisallowEnumAlias) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "enum_type {"
+ " name: \"Bar\""
+ " value { name:\"ENUM_A\" number:0 }"
+ " value { name:\"ENUM_B\" number:0 }"
+ "}",
+ "foo.proto: Bar: NUMBER: "
+ "\"ENUM_B\" uses the same enum value as \"ENUM_A\". "
+ "If this is intended, set 'option allow_alias = true;' to the enum "
+ "definition.\n");
+}
+
+TEST_F(ValidationErrorTest, AllowEnumAlias) {
+ BuildFile(
+ "name: \"foo.proto\" "
+ "enum_type {"
+ " name: \"Bar\""
+ " value { name:\"ENUM_A\" number:0 }"
+ " value { name:\"ENUM_B\" number:0 }"
+ " options { allow_alias: true }"
+ "}");
+}
+
+TEST_F(ValidationErrorTest, UnusedImportWarning) {
+ pool_.AddUnusedImportTrackFile("bar.proto");
+ BuildFile(
+ "name: \"bar.proto\" "
+ "message_type { name: \"Bar\" }");
+
+ pool_.AddUnusedImportTrackFile("base.proto");
+ BuildFile(
+ "name: \"base.proto\" "
+ "message_type { name: \"Base\" }");
+
+ pool_.AddUnusedImportTrackFile("baz.proto");
+ BuildFile(
+ "name: \"baz.proto\" "
+ "message_type { name: \"Baz\" }");
+
+ pool_.AddUnusedImportTrackFile("public.proto");
+ BuildFile(
+ "name: \"public.proto\" "
+ "dependency: \"bar.proto\""
+ "public_dependency: 0");
+
+ // // forward.proto
+ // import "base.proto" // No warning: Base message is used.
+ // import "bar.proto" // Will log a warning.
+ // import public "baz.proto" // No warning: Do not track import public.
+ // import "public.proto" // No warning: public.proto has import public.
+ // message Forward {
+ // optional Base base = 1;
+ // }
+ //
+ pool_.AddUnusedImportTrackFile("forward.proto");
+ BuildFileWithWarnings(
+ "name: \"forward.proto\""
+ "dependency: \"base.proto\""
+ "dependency: \"bar.proto\""
+ "dependency: \"baz.proto\""
+ "dependency: \"public.proto\""
+ "public_dependency: 2 "
+ "message_type {"
+ " name: \"Forward\""
+ " field { name:\"base\" number:1 label:LABEL_OPTIONAL "
+ "type_name:\"Base\" }"
+ "}",
+ "forward.proto: bar.proto: IMPORT: Import bar.proto is unused.\n");
+}
+
+namespace {
+void FillValidMapEntry(FileDescriptorProto* file_proto) {
+ ASSERT_TRUE(TextFormat::ParseFromString(
+ "name: 'foo.proto' "
+ "message_type { "
+ " name: 'Foo' "
+ " field { "
+ " name: 'foo_map' number: 1 label:LABEL_REPEATED "
+ " type_name: 'FooMapEntry' "
+ " } "
+ " nested_type { "
+ " name: 'FooMapEntry' "
+ " options { map_entry: true } "
+ " field { "
+ " name: 'key' number: 1 type:TYPE_INT32 label:LABEL_OPTIONAL "
+ " } "
+ " field { "
+ " name: 'value' number: 2 type:TYPE_INT32 label:LABEL_OPTIONAL "
+ " } "
+ " } "
+ "} "
+ "message_type { "
+ " name: 'Bar' "
+ " extension_range { start: 1 end: 10 }"
+ "} ",
+ file_proto));
+}
+static const char* kMapEntryErrorMessage =
+ "foo.proto: Foo.foo_map: TYPE: map_entry should not be set explicitly. "
+ "Use map<KeyType, ValueType> instead.\n";
+static const char* kMapEntryKeyTypeErrorMessage =
+ "foo.proto: Foo.foo_map: TYPE: Key in map fields cannot be float/double, "
+ "bytes or message types.\n";
+
+} // namespace
+
+TEST_F(ValidationErrorTest, MapEntryBase) {
+ FileDescriptorProto file_proto;
+ FillValidMapEntry(&file_proto);
+ BuildFile(file_proto.DebugString());
+}
+
+TEST_F(ValidationErrorTest, MapEntryExtensionRange) {
+ FileDescriptorProto file_proto;
+ FillValidMapEntry(&file_proto);
+ TextFormat::MergeFromString(
+ "extension_range { "
+ " start: 10 end: 20 "
+ "} ",
+ file_proto.mutable_message_type(0)->mutable_nested_type(0));
+ BuildFileWithErrors(file_proto.DebugString(), kMapEntryErrorMessage);
+}
+
+TEST_F(ValidationErrorTest, MapEntryExtension) {
+ FileDescriptorProto file_proto;
+ FillValidMapEntry(&file_proto);
+ TextFormat::MergeFromString(
+ "extension { "
+ " name: 'foo_ext' extendee: '.Bar' number: 5"
+ "} ",
+ file_proto.mutable_message_type(0)->mutable_nested_type(0));
+ BuildFileWithErrors(file_proto.DebugString(), kMapEntryErrorMessage);
+}
+
+TEST_F(ValidationErrorTest, MapEntryNestedType) {
+ FileDescriptorProto file_proto;
+ FillValidMapEntry(&file_proto);
+ TextFormat::MergeFromString(
+ "nested_type { "
+ " name: 'Bar' "
+ "} ",
+ file_proto.mutable_message_type(0)->mutable_nested_type(0));
+ BuildFileWithErrors(file_proto.DebugString(), kMapEntryErrorMessage);
+}
+
+TEST_F(ValidationErrorTest, MapEntryEnumTypes) {
+ FileDescriptorProto file_proto;
+ FillValidMapEntry(&file_proto);
+ TextFormat::MergeFromString(
+ "enum_type { "
+ " name: 'BarEnum' "
+ " value { name: 'BAR_BAR' number:0 } "
+ "} ",
+ file_proto.mutable_message_type(0)->mutable_nested_type(0));
+ BuildFileWithErrors(file_proto.DebugString(), kMapEntryErrorMessage);
+}
+
+TEST_F(ValidationErrorTest, MapEntryExtraField) {
+ FileDescriptorProto file_proto;
+ FillValidMapEntry(&file_proto);
+ TextFormat::MergeFromString(
+ "field { "
+ " name: 'other_field' "
+ " label: LABEL_OPTIONAL "
+ " type: TYPE_INT32 "
+ " number: 3 "
+ "} ",
+ file_proto.mutable_message_type(0)->mutable_nested_type(0));
+ BuildFileWithErrors(file_proto.DebugString(), kMapEntryErrorMessage);
+}
+
+TEST_F(ValidationErrorTest, MapEntryMessageName) {
+ FileDescriptorProto file_proto;
+ FillValidMapEntry(&file_proto);
+ file_proto.mutable_message_type(0)->mutable_nested_type(0)->set_name(
+ "OtherMapEntry");
+ file_proto.mutable_message_type(0)->mutable_field(0)->set_type_name(
+ "OtherMapEntry");
+ BuildFileWithErrors(file_proto.DebugString(), kMapEntryErrorMessage);
+}
+
+TEST_F(ValidationErrorTest, MapEntryNoneRepeatedMapEntry) {
+ FileDescriptorProto file_proto;
+ FillValidMapEntry(&file_proto);
+ file_proto.mutable_message_type(0)->mutable_field(0)->set_label(
+ FieldDescriptorProto::LABEL_OPTIONAL);
+ BuildFileWithErrors(file_proto.DebugString(), kMapEntryErrorMessage);
+}
+
+TEST_F(ValidationErrorTest, MapEntryDifferentContainingType) {
+ FileDescriptorProto file_proto;
+ FillValidMapEntry(&file_proto);
+ // Move the nested MapEntry message into the top level, which should not pass
+ // the validation.
+ file_proto.mutable_message_type()->AddAllocated(
+ file_proto.mutable_message_type(0)->mutable_nested_type()->ReleaseLast());
+ BuildFileWithErrors(file_proto.DebugString(), kMapEntryErrorMessage);
+}
+
+TEST_F(ValidationErrorTest, MapEntryKeyName) {
+ FileDescriptorProto file_proto;
+ FillValidMapEntry(&file_proto);
+ FieldDescriptorProto* key =
+ file_proto.mutable_message_type(0)->mutable_nested_type(0)->mutable_field(
+ 0);
+ key->set_name("Key");
+ BuildFileWithErrors(file_proto.DebugString(), kMapEntryErrorMessage);
+}
+
+TEST_F(ValidationErrorTest, MapEntryKeyLabel) {
+ FileDescriptorProto file_proto;
+ FillValidMapEntry(&file_proto);
+ FieldDescriptorProto* key =
+ file_proto.mutable_message_type(0)->mutable_nested_type(0)->mutable_field(
+ 0);
+ key->set_label(FieldDescriptorProto::LABEL_REQUIRED);
+ BuildFileWithErrors(file_proto.DebugString(), kMapEntryErrorMessage);
+}
+
+TEST_F(ValidationErrorTest, MapEntryKeyNumber) {
+ FileDescriptorProto file_proto;
+ FillValidMapEntry(&file_proto);
+ FieldDescriptorProto* key =
+ file_proto.mutable_message_type(0)->mutable_nested_type(0)->mutable_field(
+ 0);
+ key->set_number(3);
+ BuildFileWithErrors(file_proto.DebugString(), kMapEntryErrorMessage);
+}
+
+TEST_F(ValidationErrorTest, MapEntryValueName) {
+ FileDescriptorProto file_proto;
+ FillValidMapEntry(&file_proto);
+ FieldDescriptorProto* value =
+ file_proto.mutable_message_type(0)->mutable_nested_type(0)->mutable_field(
+ 1);
+ value->set_name("Value");
+ BuildFileWithErrors(file_proto.DebugString(), kMapEntryErrorMessage);
+}
+
+TEST_F(ValidationErrorTest, MapEntryValueLabel) {
+ FileDescriptorProto file_proto;
+ FillValidMapEntry(&file_proto);
+ FieldDescriptorProto* value =
+ file_proto.mutable_message_type(0)->mutable_nested_type(0)->mutable_field(
+ 1);
+ value->set_label(FieldDescriptorProto::LABEL_REQUIRED);
+ BuildFileWithErrors(file_proto.DebugString(), kMapEntryErrorMessage);
+}
+
+TEST_F(ValidationErrorTest, MapEntryValueNumber) {
+ FileDescriptorProto file_proto;
+ FillValidMapEntry(&file_proto);
+ FieldDescriptorProto* value =
+ file_proto.mutable_message_type(0)->mutable_nested_type(0)->mutable_field(
+ 1);
+ value->set_number(3);
+ BuildFileWithErrors(file_proto.DebugString(), kMapEntryErrorMessage);
+}
+
+TEST_F(ValidationErrorTest, MapEntryKeyTypeFloat) {
+ FileDescriptorProto file_proto;
+ FillValidMapEntry(&file_proto);
+ FieldDescriptorProto* key =
+ file_proto.mutable_message_type(0)->mutable_nested_type(0)->mutable_field(
+ 0);
+ key->set_type(FieldDescriptorProto::TYPE_FLOAT);
+ BuildFileWithErrors(file_proto.DebugString(), kMapEntryKeyTypeErrorMessage);
+}
+
+TEST_F(ValidationErrorTest, MapEntryKeyTypeDouble) {
+ FileDescriptorProto file_proto;
+ FillValidMapEntry(&file_proto);
+ FieldDescriptorProto* key =
+ file_proto.mutable_message_type(0)->mutable_nested_type(0)->mutable_field(
+ 0);
+ key->set_type(FieldDescriptorProto::TYPE_DOUBLE);
+ BuildFileWithErrors(file_proto.DebugString(), kMapEntryKeyTypeErrorMessage);
+}
+
+TEST_F(ValidationErrorTest, MapEntryKeyTypeBytes) {
+ FileDescriptorProto file_proto;
+ FillValidMapEntry(&file_proto);
+ FieldDescriptorProto* key =
+ file_proto.mutable_message_type(0)->mutable_nested_type(0)->mutable_field(
+ 0);
+ key->set_type(FieldDescriptorProto::TYPE_BYTES);
+ BuildFileWithErrors(file_proto.DebugString(), kMapEntryKeyTypeErrorMessage);
+}
+
+TEST_F(ValidationErrorTest, MapEntryKeyTypeEnum) {
+ FileDescriptorProto file_proto;
+ FillValidMapEntry(&file_proto);
+ FieldDescriptorProto* key =
+ file_proto.mutable_message_type(0)->mutable_nested_type(0)->mutable_field(
+ 0);
+ key->clear_type();
+ key->set_type_name("BarEnum");
+ EnumDescriptorProto* enum_proto = file_proto.add_enum_type();
+ enum_proto->set_name("BarEnum");
+ EnumValueDescriptorProto* enum_value_proto = enum_proto->add_value();
+ enum_value_proto->set_name("BAR_VALUE0");
+ enum_value_proto->set_number(0);
+ BuildFileWithErrors(file_proto.DebugString(),
+ "foo.proto: Foo.foo_map: TYPE: Key in map fields cannot "
+ "be enum types.\n");
+ // Enum keys are not allowed in proto3 as well.
+ // Get rid of extensions for proto3 to make it proto3 compatible.
+ file_proto.mutable_message_type()->RemoveLast();
+ file_proto.set_syntax("proto3");
+ BuildFileWithErrors(file_proto.DebugString(),
+ "foo.proto: Foo.foo_map: TYPE: Key in map fields cannot "
+ "be enum types.\n");
+}
+
+TEST_F(ValidationErrorTest, MapEntryKeyTypeMessage) {
+ FileDescriptorProto file_proto;
+ FillValidMapEntry(&file_proto);
+ FieldDescriptorProto* key =
+ file_proto.mutable_message_type(0)->mutable_nested_type(0)->mutable_field(
+ 0);
+ key->clear_type();
+ key->set_type_name(".Bar");
+ BuildFileWithErrors(file_proto.DebugString(), kMapEntryKeyTypeErrorMessage);
+}
+
+TEST_F(ValidationErrorTest, MapEntryConflictsWithField) {
+ FileDescriptorProto file_proto;
+ FillValidMapEntry(&file_proto);
+ TextFormat::MergeFromString(
+ "field { "
+ " name: 'FooMapEntry' "
+ " type: TYPE_INT32 "
+ " label: LABEL_OPTIONAL "
+ " number: 100 "
+ "}",
+ file_proto.mutable_message_type(0));
+ BuildFileWithErrors(
+ file_proto.DebugString(),
+ "foo.proto: Foo.FooMapEntry: NAME: \"FooMapEntry\" is already defined in "
+ "\"Foo\".\n"
+ "foo.proto: Foo.foo_map: TYPE: \"FooMapEntry\" is not defined.\n"
+ "foo.proto: Foo: NAME: Expanded map entry type FooMapEntry conflicts "
+ "with an existing field.\n");
+}
+
+TEST_F(ValidationErrorTest, MapEntryConflictsWithMessage) {
+ FileDescriptorProto file_proto;
+ FillValidMapEntry(&file_proto);
+ TextFormat::MergeFromString(
+ "nested_type { "
+ " name: 'FooMapEntry' "
+ "}",
+ file_proto.mutable_message_type(0));
+ BuildFileWithErrors(
+ file_proto.DebugString(),
+ "foo.proto: Foo.FooMapEntry: NAME: \"FooMapEntry\" is already defined in "
+ "\"Foo\".\n"
+ "foo.proto: Foo: NAME: Expanded map entry type FooMapEntry conflicts "
+ "with an existing nested message type.\n");
+}
+
+TEST_F(ValidationErrorTest, MapEntryConflictsWithEnum) {
+ FileDescriptorProto file_proto;
+ FillValidMapEntry(&file_proto);
+ TextFormat::MergeFromString(
+ "enum_type { "
+ " name: 'FooMapEntry' "
+ " value { name: 'ENTRY_FOO' number: 0 }"
+ "}",
+ file_proto.mutable_message_type(0));
+ BuildFileWithErrors(
+ file_proto.DebugString(),
+ "foo.proto: Foo.FooMapEntry: NAME: \"FooMapEntry\" is already defined in "
+ "\"Foo\".\n"
+ "foo.proto: Foo: NAME: Expanded map entry type FooMapEntry conflicts "
+ "with an existing enum type.\n");
+}
+
+TEST_F(ValidationErrorTest, EnumValuesConflictWithDifferentCasing) {
+ BuildFileWithErrors(
+ "syntax: 'proto3'"
+ "name: 'foo.proto' "
+ "enum_type {"
+ " name: 'FooEnum' "
+ " value { name: 'BAR' number: 0 }"
+ " value { name: 'bar' number: 1 }"
+ "}",
+ "foo.proto: bar: NAME: Enum name bar has the same name as BAR "
+ "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.\n");
+
+ // Not an error because both enums are mapped to the same value.
+ BuildFile(
+ "syntax: 'proto3'"
+ "name: 'foo.proto' "
+ "enum_type {"
+ " name: 'FooEnum' "
+ " options { allow_alias: true }"
+ " value { name: 'UNKNOWN' number: 0 }"
+ " value { name: 'BAR' number: 1 }"
+ " value { name: 'bar' number: 1 }"
+ "}");
+}
+
+TEST_F(ValidationErrorTest, EnumValuesConflictWhenPrefixesStripped) {
+ BuildFileWithErrors(
+ "syntax: 'proto3'"
+ "name: 'foo.proto' "
+ "enum_type {"
+ " name: 'FooEnum' "
+ " value { name: 'FOO_ENUM_BAZ' number: 0 }"
+ " value { name: 'BAZ' number: 1 }"
+ "}",
+ "foo.proto: BAZ: NAME: Enum name BAZ has the same name as FOO_ENUM_BAZ "
+ "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.\n");
+
+ BuildFileWithErrors(
+ "syntax: 'proto3'"
+ "name: 'foo.proto' "
+ "enum_type {"
+ " name: 'FooEnum' "
+ " value { name: 'FOOENUM_BAZ' number: 0 }"
+ " value { name: 'BAZ' number: 1 }"
+ "}",
+ "foo.proto: BAZ: NAME: Enum name BAZ has the same name as FOOENUM_BAZ "
+ "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.\n");
+
+ BuildFileWithErrors(
+ "syntax: 'proto3'"
+ "name: 'foo.proto' "
+ "enum_type {"
+ " name: 'FooEnum' "
+ " value { name: 'FOO_ENUM_BAR_BAZ' number: 0 }"
+ " value { name: 'BAR__BAZ' number: 1 }"
+ "}",
+ "foo.proto: BAR__BAZ: NAME: Enum name BAR__BAZ has the same name as "
+ "FOO_ENUM_BAR_BAZ 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.\n");
+
+ BuildFileWithErrors(
+ "syntax: 'proto3'"
+ "name: 'foo.proto' "
+ "enum_type {"
+ " name: 'FooEnum' "
+ " value { name: 'FOO_ENUM__BAR_BAZ' number: 0 }"
+ " value { name: 'BAR_BAZ' number: 1 }"
+ "}",
+ "foo.proto: BAR_BAZ: NAME: Enum name BAR_BAZ has the same name as "
+ "FOO_ENUM__BAR_BAZ 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.\n");
+
+ // This isn't an error because the underscore will cause the PascalCase to
+ // differ by case (BarBaz vs. Barbaz).
+ BuildFile(
+ "syntax: 'proto3'"
+ "name: 'foo.proto' "
+ "enum_type {"
+ " name: 'FooEnum' "
+ " value { name: 'BAR_BAZ' number: 0 }"
+ " value { name: 'BARBAZ' number: 1 }"
+ "}");
+}
+
+TEST_F(ValidationErrorTest, MapEntryConflictsWithOneof) {
+ FileDescriptorProto file_proto;
+ FillValidMapEntry(&file_proto);
+ TextFormat::MergeFromString(
+ "oneof_decl { "
+ " name: 'FooMapEntry' "
+ "}"
+ "field { "
+ " name: 'int_field' "
+ " type: TYPE_INT32 "
+ " label: LABEL_OPTIONAL "
+ " oneof_index: 0 "
+ " number: 100 "
+ "} ",
+ file_proto.mutable_message_type(0));
+ BuildFileWithErrors(
+ file_proto.DebugString(),
+ "foo.proto: Foo.FooMapEntry: NAME: \"FooMapEntry\" is already defined in "
+ "\"Foo\".\n"
+ "foo.proto: Foo.foo_map: TYPE: \"FooMapEntry\" is not defined.\n"
+ "foo.proto: Foo: NAME: Expanded map entry type FooMapEntry conflicts "
+ "with an existing oneof type.\n");
+}
+
+TEST_F(ValidationErrorTest, MapEntryUsesNoneZeroEnumDefaultValue) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "enum_type {"
+ " name: \"Bar\""
+ " value { name:\"ENUM_A\" number:1 }"
+ " value { name:\"ENUM_B\" number:2 }"
+ "}"
+ "message_type {"
+ " name: 'Foo' "
+ " field { "
+ " name: 'foo_map' number: 1 label:LABEL_REPEATED "
+ " type_name: 'FooMapEntry' "
+ " } "
+ " nested_type { "
+ " name: 'FooMapEntry' "
+ " options { map_entry: true } "
+ " field { "
+ " name: 'key' number: 1 type:TYPE_INT32 label:LABEL_OPTIONAL "
+ " } "
+ " field { "
+ " name: 'value' number: 2 type_name:\"Bar\" label:LABEL_OPTIONAL "
+ " } "
+ " } "
+ "}",
+ "foo.proto: Foo.foo_map: "
+ "TYPE: Enum value in map must define 0 as the first value.\n");
+}
+
+TEST_F(ValidationErrorTest, Proto3RequiredFields) {
+ BuildFileWithErrors(
+ "name: 'foo.proto' "
+ "syntax: 'proto3' "
+ "message_type { "
+ " name: 'Foo' "
+ " field { name:'foo' number:1 label:LABEL_REQUIRED type:TYPE_INT32 } "
+ "}",
+ "foo.proto: Foo.foo: TYPE: Required fields are not allowed in "
+ "proto3.\n");
+
+ // applied to nested types as well.
+ BuildFileWithErrors(
+ "name: 'foo.proto' "
+ "syntax: 'proto3' "
+ "message_type { "
+ " name: 'Foo' "
+ " nested_type { "
+ " name : 'Bar' "
+ " field { name:'bar' number:1 label:LABEL_REQUIRED type:TYPE_INT32 } "
+ " } "
+ "}",
+ "foo.proto: Foo.Bar.bar: TYPE: Required fields are not allowed in "
+ "proto3.\n");
+
+ // optional and repeated fields are OK.
+ BuildFile(
+ "name: 'foo.proto' "
+ "syntax: 'proto3' "
+ "message_type { "
+ " name: 'Foo' "
+ " field { name:'foo' number:1 label:LABEL_OPTIONAL type:TYPE_INT32 } "
+ " field { name:'bar' number:2 label:LABEL_REPEATED type:TYPE_INT32 } "
+ "}");
+}
+
+TEST_F(ValidationErrorTest, ValidateProto3DefaultValue) {
+ BuildFileWithErrors(
+ "name: 'foo.proto' "
+ "syntax: 'proto3' "
+ "message_type { "
+ " name: 'Foo' "
+ " field { name:'foo' number:1 label:LABEL_OPTIONAL type:TYPE_INT32 "
+ " default_value: '1' }"
+ "}",
+ "foo.proto: Foo.foo: DEFAULT_VALUE: Explicit default values are not "
+ "allowed in proto3.\n");
+
+ BuildFileWithErrors(
+ "name: 'foo.proto' "
+ "syntax: 'proto3' "
+ "message_type { "
+ " name: 'Foo' "
+ " nested_type { "
+ " name : 'Bar' "
+ " field { name:'bar' number:1 label:LABEL_OPTIONAL type:TYPE_INT32 "
+ " default_value: '1' }"
+ " } "
+ "}",
+ "foo.proto: Foo.Bar.bar: DEFAULT_VALUE: Explicit default values are not "
+ "allowed in proto3.\n");
+}
+
+TEST_F(ValidationErrorTest, ValidateProto3ExtensionRange) {
+ BuildFileWithErrors(
+ "name: 'foo.proto' "
+ "syntax: 'proto3' "
+ "message_type { "
+ " name: 'Foo' "
+ " field { name:'foo' number:1 label:LABEL_OPTIONAL type:TYPE_INT32 } "
+ " extension_range { start:10 end:100 } "
+ "}",
+ "foo.proto: Foo: NUMBER: Extension ranges are not allowed in "
+ "proto3.\n");
+
+ BuildFileWithErrors(
+ "name: 'foo.proto' "
+ "syntax: 'proto3' "
+ "message_type { "
+ " name: 'Foo' "
+ " nested_type { "
+ " name : 'Bar' "
+ " field { name:'bar' number:1 label:LABEL_OPTIONAL type:TYPE_INT32 } "
+ " extension_range { start:10 end:100 } "
+ " } "
+ "}",
+ "foo.proto: Foo.Bar: NUMBER: Extension ranges are not allowed in "
+ "proto3.\n");
+}
+
+TEST_F(ValidationErrorTest, ValidateProto3MessageSetWireFormat) {
+ BuildFileWithErrors(
+ "name: 'foo.proto' "
+ "syntax: 'proto3' "
+ "message_type { "
+ " name: 'Foo' "
+ " options { message_set_wire_format: true } "
+ "}",
+ "foo.proto: Foo: NAME: MessageSet is not supported "
+ "in proto3.\n");
+}
+
+TEST_F(ValidationErrorTest, ValidateProto3Enum) {
+ BuildFileWithErrors(
+ "name: 'foo.proto' "
+ "syntax: 'proto3' "
+ "enum_type { "
+ " name: 'FooEnum' "
+ " value { name: 'FOO_FOO' number:1 } "
+ "}",
+ "foo.proto: FooEnum: NUMBER: The first enum value must be "
+ "zero in proto3.\n");
+
+ BuildFileWithErrors(
+ "name: 'foo.proto' "
+ "syntax: 'proto3' "
+ "message_type { "
+ " name: 'Foo' "
+ " enum_type { "
+ " name: 'FooEnum' "
+ " value { name: 'FOO_FOO' number:1 } "
+ " } "
+ "}",
+ "foo.proto: Foo.FooEnum: NUMBER: The first enum value must be "
+ "zero in proto3.\n");
+
+ // valid case.
+ BuildFile(
+ "name: 'foo.proto' "
+ "syntax: 'proto3' "
+ "enum_type { "
+ " name: 'FooEnum' "
+ " value { name: 'FOO_FOO' number:0 } "
+ "}");
+}
+
+TEST_F(ValidationErrorTest, ValidateProto3Group) {
+ BuildFileWithErrors(
+ "name: 'foo.proto' "
+ "syntax: 'proto3' "
+ "message_type { "
+ " name: 'Foo' "
+ " nested_type { "
+ " name: 'FooGroup' "
+ " } "
+ " field { name:'foo_group' number: 1 label:LABEL_OPTIONAL "
+ " type: TYPE_GROUP type_name:'FooGroup' } "
+ "}",
+ "foo.proto: Foo.foo_group: TYPE: Groups are not supported in proto3 "
+ "syntax.\n");
+}
+
+
+TEST_F(ValidationErrorTest, ValidateProto3EnumFromProto2) {
+ // Define an enum in a proto2 file.
+ BuildFile(
+ "name: 'foo.proto' "
+ "package: 'foo' "
+ "syntax: 'proto2' "
+ "enum_type { "
+ " name: 'FooEnum' "
+ " value { name: 'DEFAULT_OPTION' number:0 } "
+ "}");
+
+ // Now try to refer to it. (All tests in the fixture use the same pool, so we
+ // can refer to the enum above in this definition.)
+ BuildFileWithErrors(
+ "name: 'bar.proto' "
+ "dependency: 'foo.proto' "
+ "syntax: 'proto3' "
+ "message_type { "
+ " name: 'Foo' "
+ " field { name:'bar' number:1 label:LABEL_OPTIONAL type:TYPE_ENUM "
+ " type_name: 'foo.FooEnum' }"
+ "}",
+ "bar.proto: Foo.bar: TYPE: Enum type \"foo.FooEnum\" is not a proto3 "
+ "enum, but is used in \"Foo\" which is a proto3 message type.\n");
+}
+
+TEST_F(ValidationErrorTest, ValidateProto3Extension) {
+ // Valid for options.
+ DescriptorPool pool;
+ FileDescriptorProto file_proto;
+ // Add "google/protobuf/descriptor.proto".
+ FileDescriptorProto::descriptor()->file()->CopyTo(&file_proto);
+ ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr);
+ // Add "foo.proto":
+ // import "google/protobuf/descriptor.proto";
+ // extend google.protobuf.FieldOptions {
+ // optional int32 option1 = 1000;
+ // }
+ file_proto.Clear();
+ file_proto.set_name("foo.proto");
+ file_proto.set_syntax("proto3");
+ file_proto.add_dependency("google/protobuf/descriptor.proto");
+ AddExtension(&file_proto, "google.protobuf.FieldOptions", "option1", 1000,
+ FieldDescriptorProto::LABEL_OPTIONAL,
+ FieldDescriptorProto::TYPE_INT32);
+ ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr);
+
+ // Copy and change the package of the descriptor.proto
+ BuildFile(
+ "name: 'google.protobuf.proto' "
+ "syntax: 'proto2' "
+ "message_type { "
+ " name: 'Container' extension_range { start: 1 end: 1000 } "
+ "}");
+ BuildFileWithErrors(
+ "name: 'bar.proto' "
+ "syntax: 'proto3' "
+ "dependency: 'google.protobuf.proto' "
+ "extension { "
+ " name: 'bar' number: 1 label: LABEL_OPTIONAL type: TYPE_INT32 "
+ " extendee: 'Container' "
+ "}",
+ "bar.proto: bar: EXTENDEE: Extensions in proto3 are only allowed for "
+ "defining options.\n");
+}
+
+// Test that field names that may conflict in JSON is not allowed by protoc.
+TEST_F(ValidationErrorTest, ValidateProto3JsonName) {
+ // The comparison is case-insensitive.
+ BuildFileWithErrors(
+ "name: 'foo.proto' "
+ "syntax: 'proto3' "
+ "message_type {"
+ " name: 'Foo'"
+ " field { name:'name' number:1 label:LABEL_OPTIONAL type:TYPE_INT32 }"
+ " field { name:'Name' number:2 label:LABEL_OPTIONAL type:TYPE_INT32 }"
+ "}",
+ "foo.proto: Foo: NAME: The JSON camel-case name of field \"Name\" "
+ "conflicts with field \"name\". This is not allowed in proto3.\n");
+ // Underscores are ignored.
+ BuildFileWithErrors(
+ "name: 'foo.proto' "
+ "syntax: 'proto3' "
+ "message_type {"
+ " name: 'Foo'"
+ " field { name:'ab' number:1 label:LABEL_OPTIONAL type:TYPE_INT32 }"
+ " field { name:'_a__b_' number:2 label:LABEL_OPTIONAL type:TYPE_INT32 }"
+ "}",
+ "foo.proto: Foo: NAME: The JSON camel-case name of field \"_a__b_\" "
+ "conflicts with field \"ab\". This is not allowed in proto3.\n");
+}
+
+
+TEST_F(ValidationErrorTest, UnusedImportWithOtherError) {
+ BuildFile(
+ "name: 'bar.proto' "
+ "message_type {"
+ " name: 'Bar'"
+ "}");
+
+ pool_.AddUnusedImportTrackFile("foo.proto", true);
+ BuildFileWithErrors(
+ "name: 'foo.proto' "
+ "dependency: 'bar.proto' "
+ "message_type {"
+ " name: 'Foo'"
+ " extension { name:'foo' number:1 label:LABEL_OPTIONAL type:TYPE_INT32"
+ " extendee: 'Baz' }"
+ "}",
+
+ // Should not also contain unused import error.
+ "foo.proto: Foo.foo: EXTENDEE: \"Baz\" is not defined.\n");
+}
+
+
+// ===================================================================
+// DescriptorDatabase
+
+static void AddToDatabase(SimpleDescriptorDatabase* database,
+ const char* file_text) {
+ FileDescriptorProto file_proto;
+ EXPECT_TRUE(TextFormat::ParseFromString(file_text, &file_proto));
+ database->Add(file_proto);
+}
+
+class DatabaseBackedPoolTest : public testing::Test {
+ protected:
+ DatabaseBackedPoolTest() {}
+
+ SimpleDescriptorDatabase database_;
+
+ void SetUp() override {
+ AddToDatabase(
+ &database_,
+ "name: 'foo.proto' "
+ "message_type { name:'Foo' extension_range { start: 1 end: 100 } } "
+ "enum_type { name:'TestEnum' value { name:'DUMMY' number:0 } } "
+ "service { name:'TestService' } ");
+ AddToDatabase(&database_,
+ "name: 'bar.proto' "
+ "dependency: 'foo.proto' "
+ "message_type { name:'Bar' } "
+ "extension { name:'foo_ext' extendee: '.Foo' number:5 "
+ " label:LABEL_OPTIONAL type:TYPE_INT32 } ");
+ // Baz has an undeclared dependency on Foo.
+ AddToDatabase(
+ &database_,
+ "name: 'baz.proto' "
+ "message_type { "
+ " name:'Baz' "
+ " field { name:'foo' number:1 label:LABEL_OPTIONAL type_name:'Foo' } "
+ "}");
+ }
+
+ // We can't inject a file containing errors into a DescriptorPool, so we
+ // need an actual mock DescriptorDatabase to test errors.
+ class ErrorDescriptorDatabase : public DescriptorDatabase {
+ public:
+ ErrorDescriptorDatabase() {}
+ ~ErrorDescriptorDatabase() {}
+
+ // implements DescriptorDatabase ---------------------------------
+ bool FindFileByName(const std::string& filename,
+ FileDescriptorProto* output) override {
+ // error.proto and error2.proto cyclically import each other.
+ if (filename == "error.proto") {
+ output->Clear();
+ output->set_name("error.proto");
+ output->add_dependency("error2.proto");
+ return true;
+ } else if (filename == "error2.proto") {
+ output->Clear();
+ output->set_name("error2.proto");
+ output->add_dependency("error.proto");
+ return true;
+ } else {
+ return false;
+ }
+ }
+ bool FindFileContainingSymbol(const std::string& symbol_name,
+ FileDescriptorProto* output) override {
+ return false;
+ }
+ bool FindFileContainingExtension(const std::string& containing_type,
+ int field_number,
+ FileDescriptorProto* output) override {
+ return false;
+ }
+ };
+
+ // A DescriptorDatabase that counts how many times each method has been
+ // called and forwards to some other DescriptorDatabase.
+ class CallCountingDatabase : public DescriptorDatabase {
+ public:
+ CallCountingDatabase(DescriptorDatabase* wrapped_db)
+ : wrapped_db_(wrapped_db) {
+ Clear();
+ }
+ ~CallCountingDatabase() {}
+
+ DescriptorDatabase* wrapped_db_;
+
+ int call_count_;
+
+ void Clear() { call_count_ = 0; }
+
+ // implements DescriptorDatabase ---------------------------------
+ bool FindFileByName(const std::string& filename,
+ FileDescriptorProto* output) override {
+ ++call_count_;
+ return wrapped_db_->FindFileByName(filename, output);
+ }
+ bool FindFileContainingSymbol(const std::string& symbol_name,
+ FileDescriptorProto* output) override {
+ ++call_count_;
+ return wrapped_db_->FindFileContainingSymbol(symbol_name, output);
+ }
+ bool FindFileContainingExtension(const std::string& containing_type,
+ int field_number,
+ FileDescriptorProto* output) override {
+ ++call_count_;
+ return wrapped_db_->FindFileContainingExtension(containing_type,
+ field_number, output);
+ }
+ };
+
+ // A DescriptorDatabase which falsely always returns foo.proto when searching
+ // for any symbol or extension number. This shouldn't cause the
+ // DescriptorPool to reload foo.proto if it is already loaded.
+ class FalsePositiveDatabase : public DescriptorDatabase {
+ public:
+ FalsePositiveDatabase(DescriptorDatabase* wrapped_db)
+ : wrapped_db_(wrapped_db) {}
+ ~FalsePositiveDatabase() {}
+
+ DescriptorDatabase* wrapped_db_;
+
+ // implements DescriptorDatabase ---------------------------------
+ bool FindFileByName(const std::string& filename,
+ FileDescriptorProto* output) override {
+ return wrapped_db_->FindFileByName(filename, output);
+ }
+ bool FindFileContainingSymbol(const std::string& symbol_name,
+ FileDescriptorProto* output) override {
+ return FindFileByName("foo.proto", output);
+ }
+ bool FindFileContainingExtension(const std::string& containing_type,
+ int field_number,
+ FileDescriptorProto* output) override {
+ return FindFileByName("foo.proto", output);
+ }
+ };
+};
+
+TEST_F(DatabaseBackedPoolTest, FindFileByName) {
+ DescriptorPool pool(&database_);
+
+ const FileDescriptor* foo = pool.FindFileByName("foo.proto");
+ ASSERT_TRUE(foo != nullptr);
+ EXPECT_EQ("foo.proto", foo->name());
+ ASSERT_EQ(1, foo->message_type_count());
+ EXPECT_EQ("Foo", foo->message_type(0)->name());
+
+ EXPECT_EQ(foo, pool.FindFileByName("foo.proto"));
+
+ EXPECT_TRUE(pool.FindFileByName("no_such_file.proto") == nullptr);
+}
+
+TEST_F(DatabaseBackedPoolTest, FindDependencyBeforeDependent) {
+ DescriptorPool pool(&database_);
+
+ const FileDescriptor* foo = pool.FindFileByName("foo.proto");
+ ASSERT_TRUE(foo != nullptr);
+ EXPECT_EQ("foo.proto", foo->name());
+ ASSERT_EQ(1, foo->message_type_count());
+ EXPECT_EQ("Foo", foo->message_type(0)->name());
+
+ const FileDescriptor* bar = pool.FindFileByName("bar.proto");
+ ASSERT_TRUE(bar != nullptr);
+ EXPECT_EQ("bar.proto", bar->name());
+ ASSERT_EQ(1, bar->message_type_count());
+ EXPECT_EQ("Bar", bar->message_type(0)->name());
+
+ ASSERT_EQ(1, bar->dependency_count());
+ EXPECT_EQ(foo, bar->dependency(0));
+}
+
+TEST_F(DatabaseBackedPoolTest, FindDependentBeforeDependency) {
+ DescriptorPool pool(&database_);
+
+ const FileDescriptor* bar = pool.FindFileByName("bar.proto");
+ ASSERT_TRUE(bar != nullptr);
+ EXPECT_EQ("bar.proto", bar->name());
+ ASSERT_EQ(1, bar->message_type_count());
+ ASSERT_EQ("Bar", bar->message_type(0)->name());
+
+ const FileDescriptor* foo = pool.FindFileByName("foo.proto");
+ ASSERT_TRUE(foo != nullptr);
+ EXPECT_EQ("foo.proto", foo->name());
+ ASSERT_EQ(1, foo->message_type_count());
+ ASSERT_EQ("Foo", foo->message_type(0)->name());
+
+ ASSERT_EQ(1, bar->dependency_count());
+ EXPECT_EQ(foo, bar->dependency(0));
+}
+
+TEST_F(DatabaseBackedPoolTest, FindFileContainingSymbol) {
+ DescriptorPool pool(&database_);
+
+ const FileDescriptor* file = pool.FindFileContainingSymbol("Foo");
+ ASSERT_TRUE(file != nullptr);
+ EXPECT_EQ("foo.proto", file->name());
+ EXPECT_EQ(file, pool.FindFileByName("foo.proto"));
+
+ EXPECT_TRUE(pool.FindFileContainingSymbol("NoSuchSymbol") == nullptr);
+}
+
+TEST_F(DatabaseBackedPoolTest, FindMessageTypeByName) {
+ DescriptorPool pool(&database_);
+
+ const Descriptor* type = pool.FindMessageTypeByName("Foo");
+ ASSERT_TRUE(type != nullptr);
+ EXPECT_EQ("Foo", type->name());
+ EXPECT_EQ(type->file(), pool.FindFileByName("foo.proto"));
+
+ EXPECT_TRUE(pool.FindMessageTypeByName("NoSuchType") == nullptr);
+}
+
+TEST_F(DatabaseBackedPoolTest, FindExtensionByNumber) {
+ DescriptorPool pool(&database_);
+
+ const Descriptor* foo = pool.FindMessageTypeByName("Foo");
+ ASSERT_TRUE(foo != nullptr);
+
+ const FieldDescriptor* extension = pool.FindExtensionByNumber(foo, 5);
+ ASSERT_TRUE(extension != nullptr);
+ EXPECT_EQ("foo_ext", extension->name());
+ EXPECT_EQ(extension->file(), pool.FindFileByName("bar.proto"));
+
+ EXPECT_TRUE(pool.FindExtensionByNumber(foo, 12) == nullptr);
+}
+
+TEST_F(DatabaseBackedPoolTest, FindAllExtensions) {
+ DescriptorPool pool(&database_);
+
+ const Descriptor* foo = pool.FindMessageTypeByName("Foo");
+
+ for (int i = 0; i < 2; ++i) {
+ // Repeat the lookup twice, to check that we get consistent
+ // results despite the fallback database lookup mutating the pool.
+ std::vector<const FieldDescriptor*> extensions;
+ pool.FindAllExtensions(foo, &extensions);
+ ASSERT_EQ(1, extensions.size());
+ EXPECT_EQ(5, extensions[0]->number());
+ }
+}
+
+TEST_F(DatabaseBackedPoolTest, ErrorWithoutErrorCollector) {
+ ErrorDescriptorDatabase error_database;
+ DescriptorPool pool(&error_database);
+
+ std::vector<std::string> errors;
+
+ {
+ ScopedMemoryLog log;
+ EXPECT_TRUE(pool.FindFileByName("error.proto") == nullptr);
+ errors = log.GetMessages(ERROR);
+ }
+
+ EXPECT_FALSE(errors.empty());
+}
+
+TEST_F(DatabaseBackedPoolTest, ErrorWithErrorCollector) {
+ ErrorDescriptorDatabase error_database;
+ MockErrorCollector error_collector;
+ DescriptorPool pool(&error_database, &error_collector);
+
+ EXPECT_TRUE(pool.FindFileByName("error.proto") == nullptr);
+ EXPECT_EQ(
+ "error.proto: error2.proto: IMPORT: File recursively imports itself: "
+ "error.proto -> error2.proto -> error.proto\n"
+ "error2.proto: error.proto: IMPORT: Import \"error.proto\" was not "
+ "found or had errors.\n"
+ "error.proto: error2.proto: IMPORT: Import \"error2.proto\" was not "
+ "found or had errors.\n",
+ error_collector.text_);
+}
+
+TEST_F(DatabaseBackedPoolTest, UndeclaredDependencyOnUnbuiltType) {
+ // Check that we find and report undeclared dependencies on types that exist
+ // in the descriptor database but that have not not been built yet.
+ MockErrorCollector error_collector;
+ DescriptorPool pool(&database_, &error_collector);
+ EXPECT_TRUE(pool.FindMessageTypeByName("Baz") == nullptr);
+ EXPECT_EQ(
+ "baz.proto: Baz.foo: TYPE: \"Foo\" seems to be defined in \"foo.proto\", "
+ "which is not imported by \"baz.proto\". To use it here, please add "
+ "the necessary import.\n",
+ error_collector.text_);
+}
+
+TEST_F(DatabaseBackedPoolTest, RollbackAfterError) {
+ // Make sure that all traces of bad types are removed from the pool. This used
+ // to be b/4529436, due to the fact that a symbol resolution failure could
+ // potentially cause another file to be recursively built, which would trigger
+ // a checkpoint _past_ possibly invalid symbols.
+ // Baz is defined in the database, but the file is invalid because it is
+ // missing a necessary import.
+ DescriptorPool pool(&database_);
+ EXPECT_TRUE(pool.FindMessageTypeByName("Baz") == nullptr);
+ // Make sure that searching again for the file or the type fails.
+ EXPECT_TRUE(pool.FindFileByName("baz.proto") == nullptr);
+ EXPECT_TRUE(pool.FindMessageTypeByName("Baz") == nullptr);
+}
+
+TEST_F(DatabaseBackedPoolTest, UnittestProto) {
+ // Try to load all of unittest.proto from a DescriptorDatabase. This should
+ // thoroughly test all paths through DescriptorBuilder to insure that there
+ // are no deadlocking problems when pool_->mutex_ is non-null.
+ const FileDescriptor* original_file =
+ protobuf_unittest::TestAllTypes::descriptor()->file();
+
+ DescriptorPoolDatabase database(*DescriptorPool::generated_pool());
+ DescriptorPool pool(&database);
+ const FileDescriptor* file_from_database =
+ pool.FindFileByName(original_file->name());
+
+ ASSERT_TRUE(file_from_database != nullptr);
+
+ FileDescriptorProto original_file_proto;
+ original_file->CopyTo(&original_file_proto);
+
+ FileDescriptorProto file_from_database_proto;
+ file_from_database->CopyTo(&file_from_database_proto);
+
+ EXPECT_EQ(original_file_proto.DebugString(),
+ file_from_database_proto.DebugString());
+
+ // Also verify that CopyTo() did not omit any information.
+ EXPECT_EQ(original_file->DebugString(), file_from_database->DebugString());
+}
+
+TEST_F(DatabaseBackedPoolTest, DoesntRetryDbUnnecessarily) {
+ // Searching for a child of an existing descriptor should never fall back
+ // to the DescriptorDatabase even if it isn't found, because we know all
+ // children are already loaded.
+ CallCountingDatabase call_counter(&database_);
+ DescriptorPool pool(&call_counter);
+
+ const FileDescriptor* file = pool.FindFileByName("foo.proto");
+ ASSERT_TRUE(file != nullptr);
+ const Descriptor* foo = pool.FindMessageTypeByName("Foo");
+ ASSERT_TRUE(foo != nullptr);
+ const EnumDescriptor* test_enum = pool.FindEnumTypeByName("TestEnum");
+ ASSERT_TRUE(test_enum != nullptr);
+ const ServiceDescriptor* test_service = pool.FindServiceByName("TestService");
+ ASSERT_TRUE(test_service != nullptr);
+
+ EXPECT_NE(0, call_counter.call_count_);
+ call_counter.Clear();
+
+ EXPECT_TRUE(foo->FindFieldByName("no_such_field") == nullptr);
+ EXPECT_TRUE(foo->FindExtensionByName("no_such_extension") == nullptr);
+ EXPECT_TRUE(foo->FindNestedTypeByName("NoSuchMessageType") == nullptr);
+ EXPECT_TRUE(foo->FindEnumTypeByName("NoSuchEnumType") == nullptr);
+ EXPECT_TRUE(foo->FindEnumValueByName("NO_SUCH_VALUE") == nullptr);
+ EXPECT_TRUE(test_enum->FindValueByName("NO_SUCH_VALUE") == nullptr);
+ EXPECT_TRUE(test_service->FindMethodByName("NoSuchMethod") == nullptr);
+
+ EXPECT_TRUE(file->FindMessageTypeByName("NoSuchMessageType") == nullptr);
+ EXPECT_TRUE(file->FindEnumTypeByName("NoSuchEnumType") == nullptr);
+ EXPECT_TRUE(file->FindEnumValueByName("NO_SUCH_VALUE") == nullptr);
+ EXPECT_TRUE(file->FindServiceByName("NO_SUCH_VALUE") == nullptr);
+ EXPECT_TRUE(file->FindExtensionByName("no_such_extension") == nullptr);
+
+ EXPECT_TRUE(pool.FindFileContainingSymbol("Foo.no.such.field") == nullptr);
+ EXPECT_TRUE(pool.FindFileContainingSymbol("Foo.no_such_field") == nullptr);
+ EXPECT_TRUE(pool.FindMessageTypeByName("Foo.NoSuchMessageType") == nullptr);
+ EXPECT_TRUE(pool.FindFieldByName("Foo.no_such_field") == nullptr);
+ EXPECT_TRUE(pool.FindExtensionByName("Foo.no_such_extension") == nullptr);
+ EXPECT_TRUE(pool.FindEnumTypeByName("Foo.NoSuchEnumType") == nullptr);
+ EXPECT_TRUE(pool.FindEnumValueByName("Foo.NO_SUCH_VALUE") == nullptr);
+ EXPECT_TRUE(pool.FindMethodByName("TestService.NoSuchMethod") == nullptr);
+
+ EXPECT_EQ(0, call_counter.call_count_);
+}
+
+TEST_F(DatabaseBackedPoolTest, DoesntReloadFilesUncesessarily) {
+ // If FindFileContainingSymbol() or FindFileContainingExtension() return a
+ // file that is already in the DescriptorPool, it should not attempt to
+ // reload the file.
+ FalsePositiveDatabase false_positive_database(&database_);
+ MockErrorCollector error_collector;
+ DescriptorPool pool(&false_positive_database, &error_collector);
+
+ // First make sure foo.proto is loaded.
+ const Descriptor* foo = pool.FindMessageTypeByName("Foo");
+ ASSERT_TRUE(foo != nullptr);
+
+ // Try inducing false positives.
+ EXPECT_TRUE(pool.FindMessageTypeByName("NoSuchSymbol") == nullptr);
+ EXPECT_TRUE(pool.FindExtensionByNumber(foo, 22) == nullptr);
+
+ // No errors should have been reported. (If foo.proto was incorrectly
+ // loaded multiple times, errors would have been reported.)
+ EXPECT_EQ("", error_collector.text_);
+}
+
+// DescriptorDatabase that attempts to induce exponentially-bad performance
+// in DescriptorPool. For every positive N, the database contains a file
+// fileN.proto, which defines a message MessageN, which contains fields of
+// type MessageK for all K in [0,N). Message0 is not defined anywhere
+// (file0.proto exists, but is empty), so every other file and message type
+// will fail to build.
+//
+// If the DescriptorPool is not careful to memoize errors, an attempt to
+// build a descriptor for MessageN can require O(2^N) time.
+class ExponentialErrorDatabase : public DescriptorDatabase {
+ public:
+ ExponentialErrorDatabase() {}
+ ~ExponentialErrorDatabase() {}
+
+ // implements DescriptorDatabase ---------------------------------
+ bool FindFileByName(const std::string& filename,
+ FileDescriptorProto* output) override {
+ int file_num = -1;
+ FullMatch(filename, "file", ".proto", &file_num);
+ if (file_num > -1) {
+ return PopulateFile(file_num, output);
+ } else {
+ return false;
+ }
+ }
+ bool FindFileContainingSymbol(const std::string& symbol_name,
+ FileDescriptorProto* output) override {
+ int file_num = -1;
+ FullMatch(symbol_name, "Message", "", &file_num);
+ if (file_num > 0) {
+ return PopulateFile(file_num, output);
+ } else {
+ return false;
+ }
+ }
+ bool FindFileContainingExtension(const std::string& containing_type,
+ int field_number,
+ FileDescriptorProto* output) override {
+ return false;
+ }
+
+ private:
+ void FullMatch(const std::string& name, const std::string& begin_with,
+ const std::string& end_with, int* file_num) {
+ int begin_size = begin_with.size();
+ int end_size = end_with.size();
+ if (name.substr(0, begin_size) != begin_with ||
+ name.substr(name.size() - end_size, end_size) != end_with) {
+ return;
+ }
+ safe_strto32(
+ name.substr(begin_size, name.size() - end_size - begin_size), file_num);
+ }
+
+ bool PopulateFile(int file_num, FileDescriptorProto* output) {
+ GOOGLE_CHECK_GE(file_num, 0);
+ output->Clear();
+ output->set_name(strings::Substitute("file$0.proto", file_num));
+ // file0.proto doesn't define Message0
+ if (file_num > 0) {
+ DescriptorProto* message = output->add_message_type();
+ message->set_name(strings::Substitute("Message$0", file_num));
+ for (int i = 0; i < file_num; ++i) {
+ output->add_dependency(strings::Substitute("file$0.proto", i));
+ FieldDescriptorProto* field = message->add_field();
+ field->set_name(strings::Substitute("field$0", i));
+ field->set_number(i);
+ field->set_label(FieldDescriptorProto::LABEL_OPTIONAL);
+ field->set_type(FieldDescriptorProto::TYPE_MESSAGE);
+ field->set_type_name(strings::Substitute("Message$0", i));
+ }
+ }
+ return true;
+ }
+};
+
+TEST_F(DatabaseBackedPoolTest, DoesntReloadKnownBadFiles) {
+ ExponentialErrorDatabase error_database;
+ DescriptorPool pool(&error_database);
+
+ GOOGLE_LOG(INFO) << "A timeout in this test probably indicates a real bug.";
+
+ EXPECT_TRUE(pool.FindFileByName("file40.proto") == nullptr);
+ EXPECT_TRUE(pool.FindMessageTypeByName("Message40") == nullptr);
+}
+
+TEST_F(DatabaseBackedPoolTest, DoesntFallbackOnWrongType) {
+ // If a lookup finds a symbol of the wrong type (e.g. we pass a type name
+ // to FindFieldByName()), we should fail fast, without checking the fallback
+ // database.
+ CallCountingDatabase call_counter(&database_);
+ DescriptorPool pool(&call_counter);
+
+ const FileDescriptor* file = pool.FindFileByName("foo.proto");
+ ASSERT_TRUE(file != nullptr);
+ const Descriptor* foo = pool.FindMessageTypeByName("Foo");
+ ASSERT_TRUE(foo != nullptr);
+ const EnumDescriptor* test_enum = pool.FindEnumTypeByName("TestEnum");
+ ASSERT_TRUE(test_enum != nullptr);
+
+ EXPECT_NE(0, call_counter.call_count_);
+ call_counter.Clear();
+
+ EXPECT_TRUE(pool.FindMessageTypeByName("TestEnum") == nullptr);
+ EXPECT_TRUE(pool.FindFieldByName("Foo") == nullptr);
+ EXPECT_TRUE(pool.FindExtensionByName("Foo") == nullptr);
+ EXPECT_TRUE(pool.FindEnumTypeByName("Foo") == nullptr);
+ EXPECT_TRUE(pool.FindEnumValueByName("Foo") == nullptr);
+ EXPECT_TRUE(pool.FindServiceByName("Foo") == nullptr);
+ EXPECT_TRUE(pool.FindMethodByName("Foo") == nullptr);
+
+ EXPECT_EQ(0, call_counter.call_count_);
+}
+
+// ===================================================================
+
+class AbortingErrorCollector : public DescriptorPool::ErrorCollector {
+ public:
+ AbortingErrorCollector() {}
+
+ void AddError(const std::string& filename, const std::string& element_name,
+ const Message* message, ErrorLocation location,
+ const std::string& error_message) override {
+ GOOGLE_LOG(FATAL) << "AddError() called unexpectedly: " << filename << " ["
+ << element_name << "]: " << error_message;
+ }
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(AbortingErrorCollector);
+};
+
+// A source tree containing only one file.
+class SingletonSourceTree : public compiler::SourceTree {
+ public:
+ SingletonSourceTree(const std::string& filename, const std::string& contents)
+ : filename_(filename), contents_(contents) {}
+
+ io::ZeroCopyInputStream* Open(const std::string& filename) override {
+ return filename == filename_
+ ? new io::ArrayInputStream(contents_.data(), contents_.size())
+ : nullptr;
+ }
+
+ private:
+ const std::string filename_;
+ const std::string contents_;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(SingletonSourceTree);
+};
+
+const char* const kSourceLocationTestInput =
+ "syntax = \"proto2\";\n"
+ "option java_package = \"com.foo.bar\";\n"
+ "option (test_file_opt) = \"foobar\";\n"
+ "message A {\n"
+ " option (test_msg_opt) = \"foobar\";\n"
+ " optional int32 a = 1 [deprecated = true];\n"
+ " message B {\n"
+ " required double b = 1 [(test_field_opt) = \"foobar\"];\n"
+ " }\n"
+ " oneof c {\n"
+ " option (test_oneof_opt) = \"foobar\";\n"
+ " string d = 2;\n"
+ " string e = 3;\n"
+ " string f = 4;\n"
+ " }\n"
+ "}\n"
+ "enum Indecision {\n"
+ " option (test_enum_opt) = 21;\n"
+ " option (test_enum_opt) = 42;\n"
+ " option (test_enum_opt) = 63;\n"
+ " YES = 1 [(test_enumval_opt).a = 100];\n"
+ " NO = 2 [(test_enumval_opt) = {a:200}];\n"
+ " MAYBE = 3;\n"
+ "}\n"
+ "service S {\n"
+ " option (test_svc_opt) = {a:100};\n"
+ " option (test_svc_opt) = {a:200};\n"
+ " option (test_svc_opt) = {a:300};\n"
+ " rpc Method(A) returns (A.B);\n"
+ // Put an empty line here to make the source location range match.
+ "\n"
+ " rpc OtherMethod(A) returns (A) {\n"
+ " option deprecated = true;\n"
+ " option (test_method_opt) = \"foobar\";\n"
+ " }\n"
+ "}\n"
+ "message MessageWithExtensions {\n"
+ " extensions 1000 to 2000, 2001 to max [(test_ext_opt) = \"foobar\"];\n"
+ "}\n"
+ "extend MessageWithExtensions {\n"
+ " repeated int32 int32_extension = 1001 [packed=true];\n"
+ "}\n"
+ "message C {\n"
+ " extend MessageWithExtensions {\n"
+ " optional C message_extension = 1002;\n"
+ " }\n"
+ "}\n"
+ "import \"google/protobuf/descriptor.proto\";\n"
+ "extend google.protobuf.FileOptions {\n"
+ " optional string test_file_opt = 10101;\n"
+ "}\n"
+ "extend google.protobuf.MessageOptions {\n"
+ " optional string test_msg_opt = 10101;\n"
+ "}\n"
+ "extend google.protobuf.FieldOptions {\n"
+ " optional string test_field_opt = 10101;\n"
+ "}\n"
+ "extend google.protobuf.EnumOptions {\n"
+ " repeated int32 test_enum_opt = 10101;\n"
+ "}\n"
+ "extend google.protobuf.EnumValueOptions {\n"
+ " optional A test_enumval_opt = 10101;\n"
+ "}\n"
+ "extend google.protobuf.ServiceOptions {\n"
+ " repeated A test_svc_opt = 10101;\n"
+ "}\n"
+ "extend google.protobuf.MethodOptions {\n"
+ " optional string test_method_opt = 10101;\n"
+ "}\n"
+ "extend google.protobuf.OneofOptions {\n"
+ " optional string test_oneof_opt = 10101;\n"
+ "}\n"
+ "extend google.protobuf.ExtensionRangeOptions {\n"
+ " optional string test_ext_opt = 10101;\n"
+ "}\n";
+
+class SourceLocationTest : public testing::Test {
+ public:
+ SourceLocationTest()
+ : source_tree_("/test/test.proto", kSourceLocationTestInput),
+ simple_db_(),
+ source_tree_db_(&source_tree_),
+ merged_db_(&simple_db_, &source_tree_db_),
+ pool_(&merged_db_, &collector_) {
+ // we need descriptor.proto to be accessible by the pool
+ // since our test file imports it
+ FileDescriptorProto::descriptor()->file()->CopyTo(&file_proto_);
+ simple_db_.Add(file_proto_);
+ }
+
+ static std::string PrintSourceLocation(const SourceLocation& loc) {
+ return strings::Substitute("$0:$1-$2:$3", 1 + loc.start_line,
+ 1 + loc.start_column, 1 + loc.end_line,
+ 1 + loc.end_column);
+ }
+
+ private:
+ FileDescriptorProto file_proto_;
+ AbortingErrorCollector collector_;
+ SingletonSourceTree source_tree_;
+ SimpleDescriptorDatabase simple_db_; // contains descriptor.proto
+ compiler::SourceTreeDescriptorDatabase source_tree_db_; // loads test.proto
+ MergedDescriptorDatabase merged_db_; // combines above two dbs
+
+ protected:
+ DescriptorPool pool_;
+
+ // tag number of all custom options in above test file
+ static constexpr int kCustomOptionFieldNumber = 10101;
+ // tag number of field "a" in message type "A" in above test file
+ static constexpr int kAFieldNumber = 1;
+};
+
+// TODO(adonovan): implement support for option fields and for
+// subparts of declarations.
+
+TEST_F(SourceLocationTest, GetSourceLocation) {
+ SourceLocation loc;
+
+ const FileDescriptor* file_desc =
+ GOOGLE_CHECK_NOTNULL(pool_.FindFileByName("/test/test.proto"));
+
+ const Descriptor* a_desc = file_desc->FindMessageTypeByName("A");
+ EXPECT_TRUE(a_desc->GetSourceLocation(&loc));
+ EXPECT_EQ("4:1-16:2", PrintSourceLocation(loc));
+
+ const Descriptor* a_b_desc = a_desc->FindNestedTypeByName("B");
+ EXPECT_TRUE(a_b_desc->GetSourceLocation(&loc));
+ EXPECT_EQ("7:3-9:4", PrintSourceLocation(loc));
+
+ const EnumDescriptor* e_desc = file_desc->FindEnumTypeByName("Indecision");
+ EXPECT_TRUE(e_desc->GetSourceLocation(&loc));
+ EXPECT_EQ("17:1-24:2", PrintSourceLocation(loc));
+
+ const EnumValueDescriptor* yes_desc = e_desc->FindValueByName("YES");
+ EXPECT_TRUE(yes_desc->GetSourceLocation(&loc));
+ EXPECT_EQ("21:3-21:42", PrintSourceLocation(loc));
+
+ const ServiceDescriptor* s_desc = file_desc->FindServiceByName("S");
+ EXPECT_TRUE(s_desc->GetSourceLocation(&loc));
+ EXPECT_EQ("25:1-35:2", PrintSourceLocation(loc));
+
+ const MethodDescriptor* m_desc = s_desc->FindMethodByName("Method");
+ EXPECT_TRUE(m_desc->GetSourceLocation(&loc));
+ EXPECT_EQ("29:3-29:31", PrintSourceLocation(loc));
+
+}
+
+TEST_F(SourceLocationTest, ExtensionSourceLocation) {
+ SourceLocation loc;
+
+ const FileDescriptor* file_desc =
+ GOOGLE_CHECK_NOTNULL(pool_.FindFileByName("/test/test.proto"));
+
+ const FieldDescriptor* int32_extension_desc =
+ file_desc->FindExtensionByName("int32_extension");
+ EXPECT_TRUE(int32_extension_desc->GetSourceLocation(&loc));
+ EXPECT_EQ("40:3-40:55", PrintSourceLocation(loc));
+
+ const Descriptor* c_desc = file_desc->FindMessageTypeByName("C");
+ EXPECT_TRUE(c_desc->GetSourceLocation(&loc));
+ EXPECT_EQ("42:1-46:2", PrintSourceLocation(loc));
+
+ const FieldDescriptor* message_extension_desc =
+ c_desc->FindExtensionByName("message_extension");
+ EXPECT_TRUE(message_extension_desc->GetSourceLocation(&loc));
+ EXPECT_EQ("44:5-44:41", PrintSourceLocation(loc));
+}
+TEST_F(SourceLocationTest, InterpretedOptionSourceLocation) {
+ // This one's a doozy. It checks every kind of option, including
+ // extension range options.
+
+ // We are verifying that the file's source info contains correct
+ // info for interpreted options and that it does *not* contain
+ // any info for corresponding uninterpreted option path.
+
+ SourceLocation loc;
+
+ const FileDescriptor* file_desc =
+ GOOGLE_CHECK_NOTNULL(pool_.FindFileByName("/test/test.proto"));
+
+ // File options
+ {
+ int path[] = {FileDescriptorProto::kOptionsFieldNumber,
+ FileOptions::kJavaPackageFieldNumber};
+ int unint[] = {FileDescriptorProto::kOptionsFieldNumber,
+ FileOptions::kUninterpretedOptionFieldNumber, 0};
+
+ std::vector<int> vpath(path, path + 2);
+ EXPECT_TRUE(file_desc->GetSourceLocation(vpath, &loc));
+ EXPECT_EQ("2:1-2:37", PrintSourceLocation(loc));
+
+ std::vector<int> vunint(unint, unint + 3);
+ EXPECT_FALSE(file_desc->GetSourceLocation(vunint, &loc));
+ }
+ {
+ int path[] = {FileDescriptorProto::kOptionsFieldNumber,
+ kCustomOptionFieldNumber};
+ int unint[] = {FileDescriptorProto::kOptionsFieldNumber,
+ FileOptions::kUninterpretedOptionFieldNumber, 1};
+ std::vector<int> vpath(path, path + 2);
+ EXPECT_TRUE(file_desc->GetSourceLocation(vpath, &loc));
+ EXPECT_EQ("3:1-3:35", PrintSourceLocation(loc));
+
+ std::vector<int> vunint(unint, unint + 3);
+ EXPECT_FALSE(file_desc->GetSourceLocation(vunint, &loc));
+ }
+
+ // Message option
+ {
+ int path[] = {FileDescriptorProto::kMessageTypeFieldNumber, 0,
+ DescriptorProto::kOptionsFieldNumber,
+ kCustomOptionFieldNumber};
+ int unint[] = {FileDescriptorProto::kMessageTypeFieldNumber, 0,
+ DescriptorProto::kOptionsFieldNumber,
+ MessageOptions::kUninterpretedOptionFieldNumber, 0};
+ std::vector<int> vpath(path, path + 4);
+ EXPECT_TRUE(file_desc->GetSourceLocation(vpath, &loc));
+ EXPECT_EQ("5:3-5:36", PrintSourceLocation(loc));
+
+ std::vector<int> vunint(unint, unint + 5);
+ EXPECT_FALSE(file_desc->GetSourceLocation(vunint, &loc));
+ }
+
+ // Field option
+ {
+ int path[] = {FileDescriptorProto::kMessageTypeFieldNumber,
+ 0,
+ DescriptorProto::kFieldFieldNumber,
+ 0,
+ FieldDescriptorProto::kOptionsFieldNumber,
+ FieldOptions::kDeprecatedFieldNumber};
+ int unint[] = {FileDescriptorProto::kMessageTypeFieldNumber,
+ 0,
+ DescriptorProto::kFieldFieldNumber,
+ 0,
+ FieldDescriptorProto::kOptionsFieldNumber,
+ FieldOptions::kUninterpretedOptionFieldNumber,
+ 0};
+ std::vector<int> vpath(path, path + 6);
+ EXPECT_TRUE(file_desc->GetSourceLocation(vpath, &loc));
+ EXPECT_EQ("6:25-6:42", PrintSourceLocation(loc));
+
+ std::vector<int> vunint(unint, unint + 7);
+ EXPECT_FALSE(file_desc->GetSourceLocation(vunint, &loc));
+ }
+
+ // Nested message option
+ {
+ int path[] = {
+ FileDescriptorProto::kMessageTypeFieldNumber, 0,
+ DescriptorProto::kNestedTypeFieldNumber, 0,
+ DescriptorProto::kFieldFieldNumber, 0,
+ FieldDescriptorProto::kOptionsFieldNumber, kCustomOptionFieldNumber};
+ int unint[] = {FileDescriptorProto::kMessageTypeFieldNumber,
+ 0,
+ DescriptorProto::kNestedTypeFieldNumber,
+ 0,
+ DescriptorProto::kFieldFieldNumber,
+ 0,
+ FieldDescriptorProto::kOptionsFieldNumber,
+ FieldOptions::kUninterpretedOptionFieldNumber,
+ 0};
+ std::vector<int> vpath(path, path + 8);
+ EXPECT_TRUE(file_desc->GetSourceLocation(vpath, &loc));
+ EXPECT_EQ("8:28-8:55", PrintSourceLocation(loc));
+
+ std::vector<int> vunint(unint, unint + 9);
+ EXPECT_FALSE(file_desc->GetSourceLocation(vunint, &loc));
+ }
+
+ // One-of option
+ {
+ int path[] = {
+ FileDescriptorProto::kMessageTypeFieldNumber, 0,
+ DescriptorProto::kOneofDeclFieldNumber, 0,
+ OneofDescriptorProto::kOptionsFieldNumber, kCustomOptionFieldNumber};
+ int unint[] = {FileDescriptorProto::kMessageTypeFieldNumber,
+ 0,
+ DescriptorProto::kOneofDeclFieldNumber,
+ 0,
+ OneofDescriptorProto::kOptionsFieldNumber,
+ OneofOptions::kUninterpretedOptionFieldNumber,
+ 0};
+ std::vector<int> vpath(path, path + 6);
+ EXPECT_TRUE(file_desc->GetSourceLocation(vpath, &loc));
+ EXPECT_EQ("11:5-11:40", PrintSourceLocation(loc));
+
+ std::vector<int> vunint(unint, unint + 7);
+ EXPECT_FALSE(file_desc->GetSourceLocation(vunint, &loc));
+ }
+
+ // Enum option, repeated options
+ {
+ int path[] = {FileDescriptorProto::kEnumTypeFieldNumber, 0,
+ EnumDescriptorProto::kOptionsFieldNumber,
+ kCustomOptionFieldNumber, 0};
+ int unint[] = {FileDescriptorProto::kEnumTypeFieldNumber, 0,
+ EnumDescriptorProto::kOptionsFieldNumber,
+ EnumOptions::kUninterpretedOptionFieldNumber, 0};
+ std::vector<int> vpath(path, path + 5);
+ EXPECT_TRUE(file_desc->GetSourceLocation(vpath, &loc));
+ EXPECT_EQ("18:3-18:31", PrintSourceLocation(loc));
+
+ std::vector<int> vunint(unint, unint + 5);
+ EXPECT_FALSE(file_desc->GetSourceLocation(vunint, &loc));
+ }
+ {
+ int path[] = {FileDescriptorProto::kEnumTypeFieldNumber, 0,
+ EnumDescriptorProto::kOptionsFieldNumber,
+ kCustomOptionFieldNumber, 1};
+ int unint[] = {FileDescriptorProto::kEnumTypeFieldNumber, 0,
+ EnumDescriptorProto::kOptionsFieldNumber,
+ EnumOptions::kUninterpretedOptionFieldNumber, 1};
+ std::vector<int> vpath(path, path + 5);
+ EXPECT_TRUE(file_desc->GetSourceLocation(vpath, &loc));
+ EXPECT_EQ("19:3-19:31", PrintSourceLocation(loc));
+
+ std::vector<int> vunint(unint, unint + 5);
+ EXPECT_FALSE(file_desc->GetSourceLocation(vunint, &loc));
+ }
+ {
+ int path[] = {FileDescriptorProto::kEnumTypeFieldNumber, 0,
+ EnumDescriptorProto::kOptionsFieldNumber,
+ kCustomOptionFieldNumber, 2};
+ int unint[] = {FileDescriptorProto::kEnumTypeFieldNumber, 0,
+ EnumDescriptorProto::kOptionsFieldNumber,
+ OneofOptions::kUninterpretedOptionFieldNumber, 2};
+ std::vector<int> vpath(path, path + 5);
+ EXPECT_TRUE(file_desc->GetSourceLocation(vpath, &loc));
+ EXPECT_EQ("20:3-20:31", PrintSourceLocation(loc));
+
+ std::vector<int> vunint(unint, unint + 5);
+ EXPECT_FALSE(file_desc->GetSourceLocation(vunint, &loc));
+ }
+
+ // Enum value options
+ {
+ // option w/ message type that directly sets field
+ int path[] = {FileDescriptorProto::kEnumTypeFieldNumber,
+ 0,
+ EnumDescriptorProto::kValueFieldNumber,
+ 0,
+ EnumValueDescriptorProto::kOptionsFieldNumber,
+ kCustomOptionFieldNumber,
+ kAFieldNumber};
+ int unint[] = {FileDescriptorProto::kEnumTypeFieldNumber,
+ 0,
+ EnumDescriptorProto::kValueFieldNumber,
+ 0,
+ EnumValueDescriptorProto::kOptionsFieldNumber,
+ EnumValueOptions::kUninterpretedOptionFieldNumber,
+ 0};
+ std::vector<int> vpath(path, path + 7);
+ EXPECT_TRUE(file_desc->GetSourceLocation(vpath, &loc));
+ EXPECT_EQ("21:14-21:40", PrintSourceLocation(loc));
+
+ std::vector<int> vunint(unint, unint + 7);
+ EXPECT_FALSE(file_desc->GetSourceLocation(vunint, &loc));
+ }
+ {
+ int path[] = {FileDescriptorProto::kEnumTypeFieldNumber,
+ 0,
+ EnumDescriptorProto::kValueFieldNumber,
+ 1,
+ EnumValueDescriptorProto::kOptionsFieldNumber,
+ kCustomOptionFieldNumber};
+ int unint[] = {FileDescriptorProto::kEnumTypeFieldNumber,
+ 0,
+ EnumDescriptorProto::kValueFieldNumber,
+ 1,
+ EnumValueDescriptorProto::kOptionsFieldNumber,
+ EnumValueOptions::kUninterpretedOptionFieldNumber,
+ 0};
+ std::vector<int> vpath(path, path + 6);
+ EXPECT_TRUE(file_desc->GetSourceLocation(vpath, &loc));
+ EXPECT_EQ("22:14-22:42", PrintSourceLocation(loc));
+
+ std::vector<int> vunint(unint, unint + 7);
+ EXPECT_FALSE(file_desc->GetSourceLocation(vunint, &loc));
+ }
+
+ // Service option, repeated options
+ {
+ int path[] = {FileDescriptorProto::kServiceFieldNumber, 0,
+ ServiceDescriptorProto::kOptionsFieldNumber,
+ kCustomOptionFieldNumber, 0};
+ int unint[] = {FileDescriptorProto::kServiceFieldNumber, 0,
+ ServiceDescriptorProto::kOptionsFieldNumber,
+ ServiceOptions::kUninterpretedOptionFieldNumber, 0};
+ std::vector<int> vpath(path, path + 5);
+ EXPECT_TRUE(file_desc->GetSourceLocation(vpath, &loc));
+ EXPECT_EQ("26:3-26:35", PrintSourceLocation(loc));
+
+ std::vector<int> vunint(unint, unint + 5);
+ EXPECT_FALSE(file_desc->GetSourceLocation(vunint, &loc));
+ }
+ {
+ int path[] = {FileDescriptorProto::kServiceFieldNumber, 0,
+ ServiceDescriptorProto::kOptionsFieldNumber,
+ kCustomOptionFieldNumber, 1};
+ int unint[] = {FileDescriptorProto::kServiceFieldNumber, 0,
+ ServiceDescriptorProto::kOptionsFieldNumber,
+ ServiceOptions::kUninterpretedOptionFieldNumber, 1};
+ std::vector<int> vpath(path, path + 5);
+ EXPECT_TRUE(file_desc->GetSourceLocation(vpath, &loc));
+ EXPECT_EQ("27:3-27:35", PrintSourceLocation(loc));
+
+ std::vector<int> vunint(unint, unint + 5);
+ EXPECT_FALSE(file_desc->GetSourceLocation(vunint, &loc));
+ }
+ {
+ int path[] = {FileDescriptorProto::kServiceFieldNumber, 0,
+ ServiceDescriptorProto::kOptionsFieldNumber,
+ kCustomOptionFieldNumber, 2};
+ int unint[] = {FileDescriptorProto::kServiceFieldNumber, 0,
+ ServiceDescriptorProto::kOptionsFieldNumber,
+ ServiceOptions::kUninterpretedOptionFieldNumber, 2};
+ std::vector<int> vpath(path, path + 5);
+ EXPECT_TRUE(file_desc->GetSourceLocation(vpath, &loc));
+ EXPECT_EQ("28:3-28:35", PrintSourceLocation(loc));
+
+ std::vector<int> vunint(unint, unint + 5);
+ EXPECT_FALSE(file_desc->GetSourceLocation(vunint, &loc));
+ }
+
+ // Method options
+ {
+ int path[] = {FileDescriptorProto::kServiceFieldNumber,
+ 0,
+ ServiceDescriptorProto::kMethodFieldNumber,
+ 1,
+ MethodDescriptorProto::kOptionsFieldNumber,
+ MethodOptions::kDeprecatedFieldNumber};
+ int unint[] = {FileDescriptorProto::kServiceFieldNumber,
+ 0,
+ ServiceDescriptorProto::kMethodFieldNumber,
+ 1,
+ MethodDescriptorProto::kOptionsFieldNumber,
+ MethodOptions::kUninterpretedOptionFieldNumber,
+ 0};
+ std::vector<int> vpath(path, path + 6);
+ EXPECT_TRUE(file_desc->GetSourceLocation(vpath, &loc));
+ EXPECT_EQ("32:5-32:30", PrintSourceLocation(loc));
+
+ std::vector<int> vunint(unint, unint + 7);
+ EXPECT_FALSE(file_desc->GetSourceLocation(vunint, &loc));
+ }
+ {
+ int path[] = {
+ FileDescriptorProto::kServiceFieldNumber, 0,
+ ServiceDescriptorProto::kMethodFieldNumber, 1,
+ MethodDescriptorProto::kOptionsFieldNumber, kCustomOptionFieldNumber};
+ int unint[] = {FileDescriptorProto::kServiceFieldNumber,
+ 0,
+ ServiceDescriptorProto::kMethodFieldNumber,
+ 1,
+ MethodDescriptorProto::kOptionsFieldNumber,
+ MethodOptions::kUninterpretedOptionFieldNumber,
+ 1};
+ std::vector<int> vpath(path, path + 6);
+ EXPECT_TRUE(file_desc->GetSourceLocation(vpath, &loc));
+ EXPECT_EQ("33:5-33:41", PrintSourceLocation(loc));
+
+ std::vector<int> vunint(unint, unint + 7);
+ EXPECT_FALSE(file_desc->GetSourceLocation(vunint, &loc));
+ }
+
+ // Extension range options
+ {
+ int path[] = {FileDescriptorProto::kMessageTypeFieldNumber, 1,
+ DescriptorProto::kExtensionRangeFieldNumber, 0,
+ DescriptorProto_ExtensionRange::kOptionsFieldNumber};
+ std::vector<int> vpath(path, path + 5);
+ EXPECT_TRUE(file_desc->GetSourceLocation(vpath, &loc));
+ EXPECT_EQ("37:40-37:67", PrintSourceLocation(loc));
+ }
+ {
+ int path[] = {FileDescriptorProto::kMessageTypeFieldNumber,
+ 1,
+ DescriptorProto::kExtensionRangeFieldNumber,
+ 0,
+ DescriptorProto_ExtensionRange::kOptionsFieldNumber,
+ kCustomOptionFieldNumber};
+ int unint[] = {FileDescriptorProto::kMessageTypeFieldNumber,
+ 1,
+ DescriptorProto::kExtensionRangeFieldNumber,
+ 0,
+ DescriptorProto_ExtensionRange::kOptionsFieldNumber,
+ ExtensionRangeOptions::kUninterpretedOptionFieldNumber,
+ 0};
+ std::vector<int> vpath(path, path + 6);
+ EXPECT_TRUE(file_desc->GetSourceLocation(vpath, &loc));
+ EXPECT_EQ("37:41-37:66", PrintSourceLocation(loc));
+
+ std::vector<int> vunint(unint, unint + 7);
+ EXPECT_FALSE(file_desc->GetSourceLocation(vunint, &loc));
+ }
+ {
+ int path[] = {FileDescriptorProto::kMessageTypeFieldNumber,
+ 1,
+ DescriptorProto::kExtensionRangeFieldNumber,
+ 1,
+ DescriptorProto_ExtensionRange::kOptionsFieldNumber,
+ kCustomOptionFieldNumber};
+ int unint[] = {FileDescriptorProto::kMessageTypeFieldNumber,
+ 1,
+ DescriptorProto::kExtensionRangeFieldNumber,
+ 1,
+ DescriptorProto_ExtensionRange::kOptionsFieldNumber,
+ ExtensionRangeOptions::kUninterpretedOptionFieldNumber,
+ 0};
+ std::vector<int> vpath(path, path + 6);
+ EXPECT_TRUE(file_desc->GetSourceLocation(vpath, &loc));
+ EXPECT_EQ("37:41-37:66", PrintSourceLocation(loc));
+
+ std::vector<int> vunint(unint, unint + 7);
+ EXPECT_FALSE(file_desc->GetSourceLocation(vunint, &loc));
+ }
+
+ // Field option on extension
+ {
+ int path[] = {FileDescriptorProto::kExtensionFieldNumber, 0,
+ FieldDescriptorProto::kOptionsFieldNumber,
+ FieldOptions::kPackedFieldNumber};
+ int unint[] = {FileDescriptorProto::kExtensionFieldNumber, 0,
+ FieldDescriptorProto::kOptionsFieldNumber,
+ FieldOptions::kUninterpretedOptionFieldNumber, 0};
+ std::vector<int> vpath(path, path + 4);
+ EXPECT_TRUE(file_desc->GetSourceLocation(vpath, &loc));
+ EXPECT_EQ("40:42-40:53", PrintSourceLocation(loc));
+
+ std::vector<int> vunint(unint, unint + 5);
+ EXPECT_FALSE(file_desc->GetSourceLocation(vunint, &loc));
+ }
+}
+
+// Missing SourceCodeInfo doesn't cause crash:
+TEST_F(SourceLocationTest, GetSourceLocation_MissingSourceCodeInfo) {
+ SourceLocation loc;
+
+ const FileDescriptor* file_desc =
+ GOOGLE_CHECK_NOTNULL(pool_.FindFileByName("/test/test.proto"));
+
+ FileDescriptorProto proto;
+ file_desc->CopyTo(&proto); // Note, this discards the SourceCodeInfo.
+ EXPECT_FALSE(proto.has_source_code_info());
+
+ DescriptorPool bad1_pool(&pool_);
+ const FileDescriptor* bad1_file_desc =
+ GOOGLE_CHECK_NOTNULL(bad1_pool.BuildFile(proto));
+ const Descriptor* bad1_a_desc = bad1_file_desc->FindMessageTypeByName("A");
+ EXPECT_FALSE(bad1_a_desc->GetSourceLocation(&loc));
+}
+
+// Corrupt SourceCodeInfo doesn't cause crash:
+TEST_F(SourceLocationTest, GetSourceLocation_BogusSourceCodeInfo) {
+ SourceLocation loc;
+
+ const FileDescriptor* file_desc =
+ GOOGLE_CHECK_NOTNULL(pool_.FindFileByName("/test/test.proto"));
+
+ FileDescriptorProto proto;
+ file_desc->CopyTo(&proto); // Note, this discards the SourceCodeInfo.
+ EXPECT_FALSE(proto.has_source_code_info());
+ SourceCodeInfo_Location* loc_msg =
+ proto.mutable_source_code_info()->add_location();
+ loc_msg->add_path(1);
+ loc_msg->add_path(2);
+ loc_msg->add_path(3);
+ loc_msg->add_span(4);
+ loc_msg->add_span(5);
+ loc_msg->add_span(6);
+
+ DescriptorPool bad2_pool(&pool_);
+ const FileDescriptor* bad2_file_desc =
+ GOOGLE_CHECK_NOTNULL(bad2_pool.BuildFile(proto));
+ const Descriptor* bad2_a_desc = bad2_file_desc->FindMessageTypeByName("A");
+ EXPECT_FALSE(bad2_a_desc->GetSourceLocation(&loc));
+}
+
+// ===================================================================
+
+const char* const kCopySourceCodeInfoToTestInput =
+ "syntax = \"proto2\";\n"
+ "message Foo {}\n";
+
+// Required since source code information is not preserved by
+// FileDescriptorTest.
+class CopySourceCodeInfoToTest : public testing::Test {
+ public:
+ CopySourceCodeInfoToTest()
+ : source_tree_("/test/test.proto", kCopySourceCodeInfoToTestInput),
+ db_(&source_tree_),
+ pool_(&db_, &collector_) {}
+
+ private:
+ AbortingErrorCollector collector_;
+ SingletonSourceTree source_tree_;
+ compiler::SourceTreeDescriptorDatabase db_;
+
+ protected:
+ DescriptorPool pool_;
+};
+
+TEST_F(CopySourceCodeInfoToTest, CopyTo_DoesNotCopySourceCodeInfo) {
+ const FileDescriptor* file_desc =
+ GOOGLE_CHECK_NOTNULL(pool_.FindFileByName("/test/test.proto"));
+ FileDescriptorProto file_desc_proto;
+ ASSERT_FALSE(file_desc_proto.has_source_code_info());
+
+ file_desc->CopyTo(&file_desc_proto);
+ EXPECT_FALSE(file_desc_proto.has_source_code_info());
+}
+
+TEST_F(CopySourceCodeInfoToTest, CopySourceCodeInfoTo) {
+ const FileDescriptor* file_desc =
+ GOOGLE_CHECK_NOTNULL(pool_.FindFileByName("/test/test.proto"));
+ FileDescriptorProto file_desc_proto;
+ ASSERT_FALSE(file_desc_proto.has_source_code_info());
+
+ file_desc->CopySourceCodeInfoTo(&file_desc_proto);
+ const SourceCodeInfo& info = file_desc_proto.source_code_info();
+ ASSERT_EQ(4, info.location_size());
+ // Get the Foo message location
+ const SourceCodeInfo_Location& foo_location = info.location(2);
+ ASSERT_EQ(2, foo_location.path_size());
+ EXPECT_EQ(FileDescriptorProto::kMessageTypeFieldNumber, foo_location.path(0));
+ EXPECT_EQ(0, foo_location.path(1)); // Foo is the first message defined
+ ASSERT_EQ(3, foo_location.span_size()); // Foo spans one line
+ EXPECT_EQ(1, foo_location.span(0)); // Foo is declared on line 1
+ EXPECT_EQ(0, foo_location.span(1)); // Foo starts at column 0
+ EXPECT_EQ(14, foo_location.span(2)); // Foo ends on column 14
+}
+
+// ===================================================================
+
+class LazilyBuildDependenciesTest : public testing::Test {
+ public:
+ LazilyBuildDependenciesTest() : pool_(&db_, nullptr) {
+ pool_.InternalSetLazilyBuildDependencies();
+ }
+
+ void ParseProtoAndAddToDb(const char* proto) {
+ FileDescriptorProto tmp;
+ ASSERT_TRUE(TextFormat::ParseFromString(proto, &tmp));
+ db_.Add(tmp);
+ }
+
+ void ParseProtoAndAddToDb(const std::string& proto) {
+ FileDescriptorProto tmp;
+ ASSERT_TRUE(TextFormat::ParseFromString(proto, &tmp));
+ db_.Add(tmp);
+ }
+
+ void AddSimpleMessageProtoFileToDb(const char* file_name,
+ const char* message_name) {
+ ParseProtoAndAddToDb("name: '" + std::string(file_name) +
+ ".proto' "
+ "package: \"protobuf_unittest\" "
+ "message_type { "
+ " name:'" +
+ std::string(message_name) +
+ "' "
+ " field { name:'a' number:1 "
+ " label:LABEL_OPTIONAL "
+ " type_name:'int32' } "
+ "}");
+ }
+
+ void AddSimpleEnumProtoFileToDb(const char* file_name, const char* enum_name,
+ const char* enum_value_name) {
+ ParseProtoAndAddToDb("name: '" + std::string(file_name) +
+ ".proto' "
+ "package: 'protobuf_unittest' "
+ "enum_type { "
+ " name:'" +
+ std::string(enum_name) +
+ "' "
+ " value { name:'" +
+ std::string(enum_value_name) +
+ "' number:1 } "
+ "}");
+ }
+
+ protected:
+ SimpleDescriptorDatabase db_;
+ DescriptorPool pool_;
+};
+
+TEST_F(LazilyBuildDependenciesTest, Message) {
+ ParseProtoAndAddToDb(
+ "name: 'foo.proto' "
+ "package: 'protobuf_unittest' "
+ "dependency: 'bar.proto' "
+ "message_type { "
+ " name:'Foo' "
+ " field { name:'bar' number:1 label:LABEL_OPTIONAL "
+ "type_name:'.protobuf_unittest.Bar' } "
+ "}");
+ AddSimpleMessageProtoFileToDb("bar", "Bar");
+
+ // Verify neither has been built yet.
+ EXPECT_FALSE(pool_.InternalIsFileLoaded("foo.proto"));
+ EXPECT_FALSE(pool_.InternalIsFileLoaded("bar.proto"));
+
+ const FileDescriptor* file = pool_.FindFileByName("foo.proto");
+
+ // Verify only foo gets built when asking for foo.proto
+ EXPECT_TRUE(file != nullptr);
+ EXPECT_TRUE(pool_.InternalIsFileLoaded("foo.proto"));
+ EXPECT_FALSE(pool_.InternalIsFileLoaded("bar.proto"));
+
+ // Verify calling FindFieldBy* works when the type of the field was
+ // not built at cross link time. Verify this doesn't build the file
+ // the field's type is defined in, as well.
+ const Descriptor* desc = file->FindMessageTypeByName("Foo");
+ const FieldDescriptor* field = desc->FindFieldByName("bar");
+ EXPECT_TRUE(field != nullptr);
+ EXPECT_EQ(field, desc->FindFieldByNumber(1));
+ EXPECT_EQ(field, desc->FindFieldByLowercaseName("bar"));
+ EXPECT_EQ(field, desc->FindFieldByCamelcaseName("bar"));
+ EXPECT_FALSE(pool_.InternalIsFileLoaded("bar.proto"));
+
+ // Finally, verify that if we call message_type() on the field, we will
+ // build the file where the message is defined, and get a valid descriptor
+ EXPECT_TRUE(field->message_type() != nullptr);
+ EXPECT_TRUE(pool_.InternalIsFileLoaded("bar.proto"));
+}
+
+TEST_F(LazilyBuildDependenciesTest, Enum) {
+ ParseProtoAndAddToDb(
+ "name: 'foo.proto' "
+ "package: 'protobuf_unittest' "
+ "dependency: 'enum1.proto' "
+ "dependency: 'enum2.proto' "
+ "message_type { "
+ " name:'Lazy' "
+ " field { name:'enum1' number:1 label:LABEL_OPTIONAL "
+ "type_name:'.protobuf_unittest.Enum1' } "
+ " field { name:'enum2' number:1 label:LABEL_OPTIONAL "
+ "type_name:'.protobuf_unittest.Enum2' } "
+ "}");
+ AddSimpleEnumProtoFileToDb("enum1", "Enum1", "ENUM1");
+ AddSimpleEnumProtoFileToDb("enum2", "Enum2", "ENUM2");
+
+ const FileDescriptor* file = pool_.FindFileByName("foo.proto");
+
+ // Verify calling enum_type() on a field whose definition is not
+ // yet built will build the file and return a descriptor.
+ EXPECT_FALSE(pool_.InternalIsFileLoaded("enum1.proto"));
+ const Descriptor* desc = file->FindMessageTypeByName("Lazy");
+ EXPECT_TRUE(desc != nullptr);
+ const FieldDescriptor* field = desc->FindFieldByName("enum1");
+ EXPECT_TRUE(field != nullptr);
+ EXPECT_TRUE(field->enum_type() != nullptr);
+ EXPECT_TRUE(pool_.InternalIsFileLoaded("enum1.proto"));
+
+ // Verify calling default_value_enum() on a field whose definition is not
+ // yet built will build the file and return a descriptor to the value.
+ EXPECT_FALSE(pool_.InternalIsFileLoaded("enum2.proto"));
+ field = desc->FindFieldByName("enum2");
+ EXPECT_TRUE(field != nullptr);
+ EXPECT_TRUE(field->default_value_enum() != nullptr);
+ EXPECT_TRUE(pool_.InternalIsFileLoaded("enum2.proto"));
+}
+
+TEST_F(LazilyBuildDependenciesTest, Type) {
+ ParseProtoAndAddToDb(
+ "name: 'foo.proto' "
+ "package: 'protobuf_unittest' "
+ "dependency: 'message1.proto' "
+ "dependency: 'message2.proto' "
+ "dependency: 'enum1.proto' "
+ "dependency: 'enum2.proto' "
+ "message_type { "
+ " name:'Lazy' "
+ " field { name:'message1' number:1 label:LABEL_OPTIONAL "
+ "type_name:'.protobuf_unittest.Message1' } "
+ " field { name:'message2' number:1 label:LABEL_OPTIONAL "
+ "type_name:'.protobuf_unittest.Message2' } "
+ " field { name:'enum1' number:1 label:LABEL_OPTIONAL "
+ "type_name:'.protobuf_unittest.Enum1' } "
+ " field { name:'enum2' number:1 label:LABEL_OPTIONAL "
+ "type_name:'.protobuf_unittest.Enum2' } "
+ "}");
+ AddSimpleMessageProtoFileToDb("message1", "Message1");
+ AddSimpleMessageProtoFileToDb("message2", "Message2");
+ AddSimpleEnumProtoFileToDb("enum1", "Enum1", "ENUM1");
+ AddSimpleEnumProtoFileToDb("enum2", "Enum2", "ENUM2");
+
+ const FileDescriptor* file = pool_.FindFileByName("foo.proto");
+
+ // Verify calling type() on a field that is a message type will
+ // build the type defined in another file.
+ EXPECT_FALSE(pool_.InternalIsFileLoaded("message1.proto"));
+ const Descriptor* desc = file->FindMessageTypeByName("Lazy");
+ EXPECT_TRUE(desc != nullptr);
+ const FieldDescriptor* field = desc->FindFieldByName("message1");
+ EXPECT_TRUE(field != nullptr);
+ EXPECT_EQ(field->type(), FieldDescriptor::TYPE_MESSAGE);
+ EXPECT_TRUE(pool_.InternalIsFileLoaded("message1.proto"));
+
+ // Verify calling cpp_type() on a field that is a message type will
+ // build the type defined in another file.
+ EXPECT_FALSE(pool_.InternalIsFileLoaded("message2.proto"));
+ field = desc->FindFieldByName("message2");
+ EXPECT_TRUE(field != nullptr);
+ EXPECT_EQ(field->cpp_type(), FieldDescriptor::CPPTYPE_MESSAGE);
+ EXPECT_TRUE(pool_.InternalIsFileLoaded("message2.proto"));
+
+ // Verify calling type() on a field that is an enum type will
+ // build the type defined in another file.
+ EXPECT_FALSE(pool_.InternalIsFileLoaded("enum1.proto"));
+ field = desc->FindFieldByName("enum1");
+ EXPECT_TRUE(field != nullptr);
+ EXPECT_EQ(field->type(), FieldDescriptor::TYPE_ENUM);
+ EXPECT_TRUE(pool_.InternalIsFileLoaded("enum1.proto"));
+
+ // Verify calling cpp_type() on a field that is an enum type will
+ // build the type defined in another file.
+ EXPECT_FALSE(pool_.InternalIsFileLoaded("enum2.proto"));
+ field = desc->FindFieldByName("enum2");
+ EXPECT_TRUE(field != nullptr);
+ EXPECT_EQ(field->cpp_type(), FieldDescriptor::CPPTYPE_ENUM);
+ EXPECT_TRUE(pool_.InternalIsFileLoaded("enum2.proto"));
+}
+
+TEST_F(LazilyBuildDependenciesTest, Extension) {
+ ParseProtoAndAddToDb(
+ "name: 'foo.proto' "
+ "package: 'protobuf_unittest' "
+ "dependency: 'bar.proto' "
+ "dependency: 'baz.proto' "
+ "extension { extendee: '.protobuf_unittest.Bar' name:'bar' number:11"
+ " label:LABEL_OPTIONAL type_name:'.protobuf_unittest.Baz' }");
+ ParseProtoAndAddToDb(
+ "name: 'bar.proto' "
+ "package: 'protobuf_unittest' "
+ "message_type { "
+ " name:'Bar' "
+ " extension_range { start: 10 end: 20 }"
+ "}");
+ AddSimpleMessageProtoFileToDb("baz", "Baz");
+
+ // Verify none have been built yet.
+ EXPECT_FALSE(pool_.InternalIsFileLoaded("foo.proto"));
+ EXPECT_FALSE(pool_.InternalIsFileLoaded("bar.proto"));
+ EXPECT_FALSE(pool_.InternalIsFileLoaded("baz.proto"));
+
+ const FileDescriptor* file = pool_.FindFileByName("foo.proto");
+
+ // Verify foo.bar gets loaded, and bar.proto gets loaded
+ // to register the extension. baz.proto should not get loaded.
+ EXPECT_TRUE(file != nullptr);
+ EXPECT_TRUE(pool_.InternalIsFileLoaded("foo.proto"));
+ EXPECT_TRUE(pool_.InternalIsFileLoaded("bar.proto"));
+ EXPECT_FALSE(pool_.InternalIsFileLoaded("baz.proto"));
+}
+
+TEST_F(LazilyBuildDependenciesTest, Service) {
+ ParseProtoAndAddToDb(
+ "name: 'foo.proto' "
+ "package: 'protobuf_unittest' "
+ "dependency: 'message1.proto' "
+ "dependency: 'message2.proto' "
+ "dependency: 'message3.proto' "
+ "dependency: 'message4.proto' "
+ "service {"
+ " name: 'LazyService'"
+ " method { name: 'A' input_type: '.protobuf_unittest.Message1' "
+ " output_type: '.protobuf_unittest.Message2' }"
+ "}");
+ AddSimpleMessageProtoFileToDb("message1", "Message1");
+ AddSimpleMessageProtoFileToDb("message2", "Message2");
+ AddSimpleMessageProtoFileToDb("message3", "Message3");
+ AddSimpleMessageProtoFileToDb("message4", "Message4");
+
+ const FileDescriptor* file = pool_.FindFileByName("foo.proto");
+
+ // Verify calling FindServiceByName or FindMethodByName doesn't build the
+ // files defining the input and output type, and input_type() and
+ // output_type() does indeed build the appropriate files.
+ const ServiceDescriptor* service = file->FindServiceByName("LazyService");
+ EXPECT_TRUE(service != nullptr);
+ const MethodDescriptor* method = service->FindMethodByName("A");
+ EXPECT_FALSE(pool_.InternalIsFileLoaded("message1.proto"));
+ EXPECT_FALSE(pool_.InternalIsFileLoaded("message2.proto"));
+ EXPECT_TRUE(method != nullptr);
+ EXPECT_TRUE(method->input_type() != nullptr);
+ EXPECT_TRUE(pool_.InternalIsFileLoaded("message1.proto"));
+ EXPECT_FALSE(pool_.InternalIsFileLoaded("message2.proto"));
+ EXPECT_TRUE(method->output_type() != nullptr);
+ EXPECT_TRUE(pool_.InternalIsFileLoaded("message2.proto"));
+}
+
+
+TEST_F(LazilyBuildDependenciesTest, GeneratedFile) {
+ // Most testing is done with custom pools with lazy dependencies forced on,
+ // do some sanity checking that lazy imports is on by default for the
+ // generated pool, and do custom options testing with generated to
+ // be able to use the GetExtension ids for the custom options.
+
+ // Verify none of the files are loaded yet.
+ EXPECT_FALSE(DescriptorPool::generated_pool()->InternalIsFileLoaded(
+ "google/protobuf/unittest_lazy_dependencies.proto"));
+ EXPECT_FALSE(DescriptorPool::generated_pool()->InternalIsFileLoaded(
+ "google/protobuf/unittest_lazy_dependencies_custom_option.proto"));
+ EXPECT_FALSE(DescriptorPool::generated_pool()->InternalIsFileLoaded(
+ "google/protobuf/unittest_lazy_dependencies_enum.proto"));
+
+ // Verify calling autogenerated function to get a descriptor in the base
+ // file will build that file but none of it's imports. This verifies that
+ // lazily_build_dependencies_ is set on the generated pool, and also that
+ // the generated function "descriptor()" doesn't somehow subvert the laziness
+ // by manually loading the dependencies or something.
+ EXPECT_TRUE(protobuf_unittest::lazy_imports::ImportedMessage::descriptor() !=
+ nullptr);
+ EXPECT_TRUE(DescriptorPool::generated_pool()->InternalIsFileLoaded(
+ "google/protobuf/unittest_lazy_dependencies.proto"));
+ EXPECT_FALSE(DescriptorPool::generated_pool()->InternalIsFileLoaded(
+ "google/protobuf/unittest_lazy_dependencies_custom_option.proto"));
+ EXPECT_FALSE(DescriptorPool::generated_pool()->InternalIsFileLoaded(
+ "google/protobuf/unittest_lazy_dependencies_enum.proto"));
+
+ // Verify custom options work when defined in an import that isn't loaded,
+ // and that a non-default value of a custom option doesn't load the file
+ // where that enum is defined.
+ const MessageOptions& options =
+ protobuf_unittest::lazy_imports::MessageCustomOption::descriptor()
+ ->options();
+ protobuf_unittest::lazy_imports::LazyEnum custom_option_value =
+ options.GetExtension(protobuf_unittest::lazy_imports::lazy_enum_option);
+
+ EXPECT_FALSE(DescriptorPool::generated_pool()->InternalIsFileLoaded(
+ "google/protobuf/unittest_lazy_dependencies_custom_option.proto"));
+ EXPECT_FALSE(DescriptorPool::generated_pool()->InternalIsFileLoaded(
+ "google/protobuf/unittest_lazy_dependencies_enum.proto"));
+ EXPECT_EQ(custom_option_value, protobuf_unittest::lazy_imports::LAZY_ENUM_1);
+
+ const MessageOptions& options2 =
+ protobuf_unittest::lazy_imports::MessageCustomOption2::descriptor()
+ ->options();
+ custom_option_value =
+ options2.GetExtension(protobuf_unittest::lazy_imports::lazy_enum_option);
+
+ EXPECT_FALSE(DescriptorPool::generated_pool()->InternalIsFileLoaded(
+ "google/protobuf/unittest_lazy_dependencies_custom_option.proto"));
+ EXPECT_FALSE(DescriptorPool::generated_pool()->InternalIsFileLoaded(
+ "google/protobuf/unittest_lazy_dependencies_enum.proto"));
+ EXPECT_EQ(custom_option_value, protobuf_unittest::lazy_imports::LAZY_ENUM_0);
+}
+
+TEST_F(LazilyBuildDependenciesTest, Dependency) {
+ ParseProtoAndAddToDb(
+ "name: 'foo.proto' "
+ "package: 'protobuf_unittest' "
+ "dependency: 'bar.proto' "
+ "message_type { "
+ " name:'Foo' "
+ " field { name:'bar' number:1 label:LABEL_OPTIONAL "
+ "type_name:'.protobuf_unittest.Bar' } "
+ "}");
+ ParseProtoAndAddToDb(
+ "name: 'bar.proto' "
+ "package: 'protobuf_unittest' "
+ "dependency: 'baz.proto' "
+ "message_type { "
+ " name:'Bar' "
+ " field { name:'baz' number:1 label:LABEL_OPTIONAL "
+ "type_name:'.protobuf_unittest.Baz' } "
+ "}");
+ AddSimpleMessageProtoFileToDb("baz", "Baz");
+
+ const FileDescriptor* foo_file = pool_.FindFileByName("foo.proto");
+ EXPECT_TRUE(foo_file != nullptr);
+ // As expected, requesting foo.proto shouldn't build it's dependencies
+ EXPECT_TRUE(pool_.InternalIsFileLoaded("foo.proto"));
+ EXPECT_FALSE(pool_.InternalIsFileLoaded("bar.proto"));
+ EXPECT_FALSE(pool_.InternalIsFileLoaded("baz.proto"));
+
+ // Verify calling dependency(N) will build the dependency, but
+ // not that file's dependencies.
+ const FileDescriptor* bar_file = foo_file->dependency(0);
+ EXPECT_TRUE(bar_file != nullptr);
+ EXPECT_TRUE(pool_.InternalIsFileLoaded("bar.proto"));
+ EXPECT_FALSE(pool_.InternalIsFileLoaded("baz.proto"));
+}
+
+// ===================================================================
+
+
+} // namespace descriptor_unittest
+} // namespace protobuf
+} // namespace google
+
+#include <port_undef.inc>
diff --git a/NorthstarDedicatedTest/include/protobuf/drop_unknown_fields_test.cc b/NorthstarDedicatedTest/include/protobuf/drop_unknown_fields_test.cc
new file mode 100644
index 00000000..9c6993b8
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/drop_unknown_fields_test.cc
@@ -0,0 +1,83 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <memory>
+
+#include <unittest_drop_unknown_fields.pb.h>
+#include <dynamic_message.h>
+#include <message_lite.h>
+#include <gtest/gtest.h>
+
+using unittest_drop_unknown_fields::Foo;
+using unittest_drop_unknown_fields::FooWithExtraFields;
+
+namespace google {
+namespace protobuf {
+
+TEST(DropUnknownFieldsTest, GeneratedMessage) {
+ FooWithExtraFields foo_with_extra_fields;
+ foo_with_extra_fields.set_int32_value(1);
+ foo_with_extra_fields.set_enum_value(FooWithExtraFields::QUX);
+ foo_with_extra_fields.set_extra_int32_value(2);
+
+ Foo foo;
+ ASSERT_TRUE(foo.ParseFromString(foo_with_extra_fields.SerializeAsString()));
+ EXPECT_EQ(1, foo.int32_value());
+ EXPECT_EQ(static_cast<int>(FooWithExtraFields::QUX),
+ static_cast<int>(foo.enum_value()));
+ EXPECT_FALSE(foo.GetReflection()->GetUnknownFields(foo).empty());
+
+ ASSERT_TRUE(foo_with_extra_fields.ParseFromString(foo.SerializeAsString()));
+ EXPECT_EQ(1, foo_with_extra_fields.int32_value());
+ EXPECT_EQ(FooWithExtraFields::QUX, foo_with_extra_fields.enum_value());
+ // The "extra_int32_value" field should not be lost.
+ EXPECT_EQ(2, foo_with_extra_fields.extra_int32_value());
+}
+
+TEST(DropUnknownFieldsTest, DynamicMessage) {
+ FooWithExtraFields foo_with_extra_fields;
+ foo_with_extra_fields.set_int32_value(1);
+ foo_with_extra_fields.set_enum_value(FooWithExtraFields::QUX);
+ foo_with_extra_fields.set_extra_int32_value(2);
+
+ DynamicMessageFactory factory;
+ std::unique_ptr<Message> foo(factory.GetPrototype(Foo::descriptor())->New());
+ ASSERT_TRUE(foo->ParseFromString(foo_with_extra_fields.SerializeAsString()));
+ EXPECT_FALSE(foo->GetReflection()->GetUnknownFields(*foo).empty());
+
+ ASSERT_TRUE(foo_with_extra_fields.ParseFromString(foo->SerializeAsString()));
+ EXPECT_EQ(1, foo_with_extra_fields.int32_value());
+ EXPECT_EQ(FooWithExtraFields::QUX, foo_with_extra_fields.enum_value());
+ // The "extra_int32_value" field should not be lost.
+ EXPECT_EQ(2, foo_with_extra_fields.extra_int32_value());
+}
+
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/duration.pb.cc b/NorthstarDedicatedTest/include/protobuf/duration.pb.cc
new file mode 100644
index 00000000..77c28728
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/duration.pb.cc
@@ -0,0 +1,300 @@
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+// source: google/protobuf/duration.proto
+
+#include <duration.pb.h>
+
+#include <algorithm>
+
+#include <io/coded_stream.h>
+#include <extension_set.h>
+#include <wire_format_lite.h>
+#include <descriptor.h>
+#include <generated_message_reflection.h>
+#include <reflection_ops.h>
+#include <wire_format.h>
+// @@protoc_insertion_point(includes)
+#include <port_def.inc>
+
+PROTOBUF_PRAGMA_INIT_SEG
+PROTOBUF_NAMESPACE_OPEN
+constexpr Duration::Duration(
+ ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized)
+ : seconds_(int64_t{0})
+ , nanos_(0){}
+struct DurationDefaultTypeInternal {
+ constexpr DurationDefaultTypeInternal()
+ : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {}
+ ~DurationDefaultTypeInternal() {}
+ union {
+ Duration _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT DurationDefaultTypeInternal _Duration_default_instance_;
+PROTOBUF_NAMESPACE_CLOSE
+static ::PROTOBUF_NAMESPACE_ID::Metadata file_level_metadata_google_2fprotobuf_2fduration_2eproto[1];
+static constexpr ::PROTOBUF_NAMESPACE_ID::EnumDescriptor const** file_level_enum_descriptors_google_2fprotobuf_2fduration_2eproto = nullptr;
+static constexpr ::PROTOBUF_NAMESPACE_ID::ServiceDescriptor const** file_level_service_descriptors_google_2fprotobuf_2fduration_2eproto = nullptr;
+
+const 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, seconds_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Duration, nanos_),
+};
+static const ::PROTOBUF_NAMESPACE_ID::internal::MigrationSchema schemas[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = {
+ { 0, -1, -1, sizeof(::PROTOBUF_NAMESPACE_ID::Duration)},
+};
+
+static ::PROTOBUF_NAMESPACE_ID::Message const * const file_default_instances[] = {
+ reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_Duration_default_instance_),
+};
+
+const char descriptor_table_protodef_google_2fprotobuf_2fduration_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) =
+ "\n\036google/protobuf/duration.proto\022\017google"
+ ".protobuf\"*\n\010Duration\022\017\n\007seconds\030\001 \001(\003\022\r"
+ "\n\005nanos\030\002 \001(\005B\203\001\n\023com.google.protobufB\rD"
+ "urationProtoP\001Z1google.golang.org/protob"
+ "uf/types/known/durationpb\370\001\001\242\002\003GPB\252\002\036Goo"
+ "gle.Protobuf.WellKnownTypesb\006proto3"
+ ;
+static ::PROTOBUF_NAMESPACE_ID::internal::once_flag descriptor_table_google_2fprotobuf_2fduration_2eproto_once;
+const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fduration_2eproto = {
+ false, false, 235, descriptor_table_protodef_google_2fprotobuf_2fduration_2eproto, "google/protobuf/duration.proto",
+ &descriptor_table_google_2fprotobuf_2fduration_2eproto_once, nullptr, 0, 1,
+ schemas, file_default_instances, TableStruct_google_2fprotobuf_2fduration_2eproto::offsets,
+ file_level_metadata_google_2fprotobuf_2fduration_2eproto, file_level_enum_descriptors_google_2fprotobuf_2fduration_2eproto, file_level_service_descriptors_google_2fprotobuf_2fduration_2eproto,
+};
+PROTOBUF_ATTRIBUTE_WEAK const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable* descriptor_table_google_2fprotobuf_2fduration_2eproto_getter() {
+ return &descriptor_table_google_2fprotobuf_2fduration_2eproto;
+}
+
+// Force running AddDescriptors() at dynamic initialization time.
+PROTOBUF_ATTRIBUTE_INIT_PRIORITY static ::PROTOBUF_NAMESPACE_ID::internal::AddDescriptorsRunner dynamic_init_dummy_google_2fprotobuf_2fduration_2eproto(&descriptor_table_google_2fprotobuf_2fduration_2eproto);
+PROTOBUF_NAMESPACE_OPEN
+
+// ===================================================================
+
+class Duration::_Internal {
+ public:
+};
+
+Duration::Duration(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned)
+ : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) {
+ SharedCtor();
+ if (!is_message_owned) {
+ RegisterArenaDtor(arena);
+ }
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.Duration)
+}
+Duration::Duration(const Duration& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message() {
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ ::memcpy(&seconds_, &from.seconds_,
+ static_cast<size_t>(reinterpret_cast<char*>(&nanos_) -
+ reinterpret_cast<char*>(&seconds_)) + sizeof(nanos_));
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.Duration)
+}
+
+inline void Duration::SharedCtor() {
+::memset(reinterpret_cast<char*>(this) + static_cast<size_t>(
+ reinterpret_cast<char*>(&seconds_) - reinterpret_cast<char*>(this)),
+ 0, static_cast<size_t>(reinterpret_cast<char*>(&nanos_) -
+ reinterpret_cast<char*>(&seconds_)) + sizeof(nanos_));
+}
+
+Duration::~Duration() {
+ // @@protoc_insertion_point(destructor:google.protobuf.Duration)
+ if (GetArenaForAllocation() != nullptr) return;
+ SharedDtor();
+ _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+inline void Duration::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+}
+
+void Duration::ArenaDtor(void* object) {
+ Duration* _this = reinterpret_cast< Duration* >(object);
+ (void)_this;
+}
+void Duration::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) {
+}
+void Duration::SetCachedSize(int size) const {
+ _cached_size_.Set(size);
+}
+
+void Duration::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.Duration)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ ::memset(&seconds_, 0, static_cast<size_t>(
+ reinterpret_cast<char*>(&nanos_) -
+ reinterpret_cast<char*>(&seconds_)) + sizeof(nanos_));
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* Duration::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag);
+ switch (tag >> 3) {
+ // int64 seconds = 1;
+ case 1:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 8)) {
+ seconds_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr);
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // int32 nanos = 2;
+ case 2:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 16)) {
+ nanos_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint32(&ptr);
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ default:
+ goto handle_unusual;
+ } // switch
+ handle_unusual:
+ if ((tag == 0) || ((tag & 7) == 4)) {
+ CHK_(ptr);
+ ctx->SetLastTag(tag);
+ goto message_done;
+ }
+ ptr = UnknownFieldParse(
+ tag,
+ _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(),
+ ptr, ctx);
+ CHK_(ptr != nullptr);
+ } // while
+message_done:
+ return ptr;
+failure:
+ ptr = nullptr;
+ goto message_done;
+#undef CHK_
+}
+
+uint8_t* Duration::_InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const {
+ // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Duration)
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ // int64 seconds = 1;
+ if (this->_internal_seconds() != 0) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt64ToArray(1, this->_internal_seconds(), target);
+ }
+
+ // int32 nanos = 2;
+ if (this->_internal_nanos() != 0) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32ToArray(2, this->_internal_nanos(), target);
+ }
+
+ if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray(
+ _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Duration)
+ return target;
+}
+
+size_t Duration::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.Duration)
+ size_t total_size = 0;
+
+ 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 += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int64SizePlusOne(this->_internal_seconds());
+ }
+
+ // int32 nanos = 2;
+ if (this->_internal_nanos() != 0) {
+ total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32SizePlusOne(this->_internal_nanos());
+ }
+
+ return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData Duration::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck,
+ Duration::MergeImpl
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*Duration::GetClassData() const { return &_class_data_; }
+
+void Duration::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to,
+ const ::PROTOBUF_NAMESPACE_ID::Message& from) {
+ static_cast<Duration *>(to)->MergeFrom(
+ static_cast<const Duration &>(from));
+}
+
+
+void Duration::MergeFrom(const Duration& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Duration)
+ GOOGLE_DCHECK_NE(&from, this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ if (from._internal_seconds() != 0) {
+ _internal_set_seconds(from._internal_seconds());
+ }
+ if (from._internal_nanos() != 0) {
+ _internal_set_nanos(from._internal_nanos());
+ }
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+}
+
+void Duration::CopyFrom(const Duration& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.Duration)
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+bool Duration::IsInitialized() const {
+ return true;
+}
+
+void Duration::InternalSwap(Duration* other) {
+ using std::swap;
+ _internal_metadata_.InternalSwap(&other->_internal_metadata_);
+ ::PROTOBUF_NAMESPACE_ID::internal::memswap<
+ PROTOBUF_FIELD_OFFSET(Duration, nanos_)
+ + sizeof(Duration::nanos_)
+ - PROTOBUF_FIELD_OFFSET(Duration, seconds_)>(
+ reinterpret_cast<char*>(&seconds_),
+ reinterpret_cast<char*>(&other->seconds_));
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata Duration::GetMetadata() const {
+ return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(
+ &descriptor_table_google_2fprotobuf_2fduration_2eproto_getter, &descriptor_table_google_2fprotobuf_2fduration_2eproto_once,
+ file_level_metadata_google_2fprotobuf_2fduration_2eproto[0]);
+}
+
+// @@protoc_insertion_point(namespace_scope)
+PROTOBUF_NAMESPACE_CLOSE
+PROTOBUF_NAMESPACE_OPEN
+template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::Duration* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::Duration >(Arena* arena) {
+ return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::Duration >(arena);
+}
+PROTOBUF_NAMESPACE_CLOSE
+
+// @@protoc_insertion_point(global_scope)
+#include <port_undef.inc>
diff --git a/NorthstarDedicatedTest/include/protobuf/duration.pb.h b/NorthstarDedicatedTest/include/protobuf/duration.pb.h
new file mode 100644
index 00000000..7d7b52e7
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/duration.pb.h
@@ -0,0 +1,285 @@
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+// source: google/protobuf/duration.proto
+
+#ifndef GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fduration_2eproto
+#define GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fduration_2eproto
+
+#include <limits>
+#include <string>
+
+#include <port_def.inc>
+#if PROTOBUF_VERSION < 3019000
+#error This file was generated by a newer version of protoc which is
+#error incompatible with your Protocol Buffer headers. Please update
+#error your headers.
+#endif
+#if 3019004 < 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 <port_undef.inc>
+#include <io/coded_stream.h>
+#include <arena.h>
+#include <arenastring.h>
+#include <generated_message_table_driven.h>
+#include <generated_message_util.h>
+#include <metadata_lite.h>
+#include <generated_message_reflection.h>
+#include <message.h>
+#include <repeated_field.h> // IWYU pragma: export
+#include <extension_set.h> // IWYU pragma: export
+#include <unknown_field_set.h>
+// @@protoc_insertion_point(includes)
+#include <port_def.inc>
+#define PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fduration_2eproto PROTOBUF_EXPORT
+PROTOBUF_NAMESPACE_OPEN
+namespace internal {
+class AnyMetadata;
+} // namespace internal
+PROTOBUF_NAMESPACE_CLOSE
+
+// Internal implementation detail -- do not use these members.
+struct PROTOBUF_EXPORT TableStruct_google_2fprotobuf_2fduration_2eproto {
+ static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTableField entries[]
+ PROTOBUF_SECTION_VARIABLE(protodesc_cold);
+ static const ::PROTOBUF_NAMESPACE_ID::internal::AuxiliaryParseTableField aux[]
+ PROTOBUF_SECTION_VARIABLE(protodesc_cold);
+ static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTable schema[1]
+ PROTOBUF_SECTION_VARIABLE(protodesc_cold);
+ static const ::PROTOBUF_NAMESPACE_ID::internal::FieldMetadata field_metadata[];
+ static const ::PROTOBUF_NAMESPACE_ID::internal::SerializationTable serialization_table[];
+ static const 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 constexpr Duration(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
+
+ Duration(const Duration& from);
+ Duration(Duration&& from) noexcept
+ : Duration() {
+ *this = ::std::move(from);
+ }
+
+ inline Duration& operator=(const Duration& from) {
+ CopyFrom(from);
+ return *this;
+ }
+ inline Duration& operator=(Duration&& from) noexcept {
+ if (this == &from) return *this;
+ if (GetOwningArena() == from.GetOwningArena()
+ #ifdef PROTOBUF_FORCE_COPY_IN_MOVE
+ && GetOwningArena() != nullptr
+ #endif // !PROTOBUF_FORCE_COPY_IN_MOVE
+ ) {
+ InternalSwap(&from);
+ } else {
+ CopyFrom(from);
+ }
+ return *this;
+ }
+
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
+ return GetDescriptor();
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
+ return default_instance().GetMetadata().descriptor;
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
+ return default_instance().GetMetadata().reflection;
+ }
+ static const Duration& default_instance() {
+ return *internal_default_instance();
+ }
+ static inline const Duration* internal_default_instance() {
+ return reinterpret_cast<const Duration*>(
+ &_Duration_default_instance_);
+ }
+ static constexpr int kIndexInFileMessages =
+ 0;
+
+ friend void swap(Duration& a, Duration& b) {
+ a.Swap(&b);
+ }
+ inline void Swap(Duration* other) {
+ if (other == this) return;
+ #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() != nullptr &&
+ GetOwningArena() == other->GetOwningArena()) {
+ #else // PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() == other->GetOwningArena()) {
+ #endif // !PROTOBUF_FORCE_COPY_IN_SWAP
+ InternalSwap(other);
+ } else {
+ ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
+ }
+ }
+ void UnsafeArenaSwap(Duration* other) {
+ if (other == this) return;
+ GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena());
+ InternalSwap(other);
+ }
+
+ // implements Message ----------------------------------------------
+
+ Duration* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
+ return CreateMaybeMessage<Duration>(arena);
+ }
+ using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
+ void CopyFrom(const Duration& from);
+ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
+ void MergeFrom(const Duration& from);
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from);
+ public:
+ PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+ bool IsInitialized() const final;
+
+ size_t ByteSizeLong() const final;
+ const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
+ uint8_t* _InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
+ int GetCachedSize() const final { return _cached_size_.Get(); }
+
+ private:
+ void SharedCtor();
+ void SharedDtor();
+ void SetCachedSize(int size) const final;
+ void InternalSwap(Duration* other);
+
+ private:
+ friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
+ static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
+ return "google.protobuf.Duration";
+ }
+ protected:
+ explicit Duration(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned = false);
+ private:
+ static void ArenaDtor(void* object);
+ inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
+ public:
+
+ static const ClassData _class_data_;
+ const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;
+
+ ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;
+
+ // nested types ----------------------------------------------------
+
+ // accessors -------------------------------------------------------
+
+ enum : int {
+ kSecondsFieldNumber = 1,
+ kNanosFieldNumber = 2,
+ };
+ // int64 seconds = 1;
+ void clear_seconds();
+ 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_;
+ int64_t seconds_;
+ int32_t nanos_;
+ mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
+ friend struct ::TableStruct_google_2fprotobuf_2fduration_2eproto;
+};
+// ===================================================================
+
+
+// ===================================================================
+
+#ifdef __GNUC__
+ #pragma GCC diagnostic push
+ #pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#endif // __GNUC__
+// Duration
+
+// int64 seconds = 1;
+inline void Duration::clear_seconds() {
+ seconds_ = int64_t{0};
+}
+inline int64_t Duration::_internal_seconds() const {
+ return 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) {
+
+ 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() {
+ nanos_ = 0;
+}
+inline int32_t Duration::_internal_nanos() const {
+ return 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) {
+
+ 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 <port_undef.inc>
+#endif // GOOGLE_PROTOBUF_INCLUDED_GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fduration_2eproto
diff --git a/NorthstarDedicatedTest/include/protobuf/duration.proto b/NorthstarDedicatedTest/include/protobuf/duration.proto
new file mode 100644
index 00000000..81c3e369
--- /dev/null
+++ b/NorthstarDedicatedTest/include/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/NorthstarDedicatedTest/include/protobuf/dynamic_message.cc b/NorthstarDedicatedTest/include/protobuf/dynamic_message.cc
new file mode 100644
index 00000000..3cdc004e
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/dynamic_message.cc
@@ -0,0 +1,859 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// DynamicMessage is implemented by constructing a data structure which
+// has roughly the same memory layout as a generated message would have.
+// Then, we use Reflection to implement our reflection interface. All
+// the other operations we need to implement (e.g. parsing, copying,
+// etc.) are already implemented in terms of Reflection, so the rest is
+// easy.
+//
+// The up side of this strategy is that it's very efficient. We don't
+// need to use hash_maps or generic representations of fields. The
+// down side is that this is a low-level memory management hack which
+// can be tricky to get right.
+//
+// As mentioned in the header, we only expose a DynamicMessageFactory
+// publicly, not the DynamicMessage class itself. This is because
+// GenericMessageReflection wants to have a pointer to a "default"
+// copy of the class, with all fields initialized to their default
+// values. We only want to construct one of these per message type,
+// so DynamicMessageFactory stores a cache of default messages for
+// each type it sees (each unique Descriptor pointer). The code
+// refers to the "default" copy of the class as the "prototype".
+//
+// Note on memory allocation: This module often calls "operator new()"
+// to allocate untyped memory, rather than calling something like
+// "new uint8_t[]". This is because "operator new()" means "Give me some
+// space which I can use as I please." while "new uint8_t[]" means "Give
+// me an array of 8-bit integers.". In practice, the later may return
+// a pointer that is not aligned correctly for general use. I believe
+// Item 8 of "More Effective C++" discusses this in more detail, though
+// I don't have the book on me right now so I'm not sure.
+
+#include <dynamic_message.h>
+
+#include <algorithm>
+#include <cstddef>
+#include <memory>
+#include <new>
+#include <unordered_map>
+
+#include <descriptor.pb.h>
+#include <descriptor.h>
+#include <generated_message_reflection.h>
+#include <generated_message_util.h>
+#include <unknown_field_set.h>
+#include <stubs/hash.h>
+#include <arenastring.h>
+#include <extension_set.h>
+#include <map_field.h>
+#include <map_field_inl.h>
+#include <map_type_handler.h>
+#include <reflection_ops.h>
+#include <repeated_field.h>
+#include <wire_format.h>
+
+#include <port_def.inc> // NOLINT
+
+namespace google {
+namespace protobuf {
+
+using internal::DynamicMapField;
+using internal::ExtensionSet;
+using internal::MapField;
+
+
+using internal::ArenaStringPtr;
+
+// ===================================================================
+// Some helper tables and functions...
+
+class DynamicMessageReflectionHelper {
+ public:
+ static bool IsLazyField(const Reflection* reflection,
+ const FieldDescriptor* field) {
+ return reflection->IsLazyField(field);
+ }
+};
+
+namespace {
+
+bool IsMapFieldInApi(const FieldDescriptor* field) { return field->is_map(); }
+
+// Sync with helpers.h.
+inline bool HasHasbit(const FieldDescriptor* field) {
+ // This predicate includes proto3 message fields only if they have "optional".
+ // Foo submsg1 = 1; // HasHasbit() == false
+ // optional Foo submsg2 = 2; // HasHasbit() == true
+ // This is slightly odd, as adding "optional" to a singular proto3 field does
+ // not change the semantics or API. However whenever any field in a message
+ // has a hasbit, it forces reflection to include hasbit offsets for *all*
+ // fields, even if almost all of them are set to -1 (no hasbit). So to avoid
+ // causing a sudden size regression for ~all proto3 messages, we give proto3
+ // message fields a hasbit only if "optional" is present. If the user is
+ // explicitly writing "optional", it is likely they are writing it on
+ // primitive fields also.
+ return (field->has_optional_keyword() || field->is_required()) &&
+ !field->options().weak();
+}
+
+inline bool InRealOneof(const FieldDescriptor* field) {
+ return field->containing_oneof() &&
+ !field->containing_oneof()->is_synthetic();
+}
+
+// Compute the byte size of the in-memory representation of the field.
+int FieldSpaceUsed(const FieldDescriptor* field) {
+ typedef FieldDescriptor FD; // avoid line wrapping
+ if (field->label() == FD::LABEL_REPEATED) {
+ switch (field->cpp_type()) {
+ case FD::CPPTYPE_INT32:
+ return sizeof(RepeatedField<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();
+
+ // Called on the prototype after construction to initialize message fields.
+ // Cross linking the default instances allows for fast reflection access of
+ // unset message fields. Without it we would have to go to the MessageFactory
+ // to get the prototype, which is a much more expensive operation.
+ //
+ // Generated messages do not cross-link to avoid dynamic initialization of the
+ // global instances.
+ // Instead, they keep the default instances in the FieldDescriptor objects.
+ void CrossLinkPrototypes();
+
+ // implements Message ----------------------------------------------
+
+ Message* New(Arena* arena) const override;
+
+ int GetCachedSize() const override;
+ void SetCachedSize(int size) const override;
+
+ Metadata GetMetadata() const override;
+
+#if defined(__cpp_lib_destroying_delete) && defined(__cpp_sized_deallocation)
+ static void operator delete(DynamicMessage* msg, std::destroying_delete_t);
+#else
+ // We actually allocate more memory than sizeof(*this) when this
+ // class's memory is allocated via the global operator new. Thus, we need to
+ // manually call the global operator delete. Calling the destructor is taken
+ // care of for us. This makes DynamicMessage compatible with -fsized-delete.
+ // It doesn't work for MSVC though.
+#ifndef _MSC_VER
+ static void operator delete(void* ptr) { ::operator delete(ptr); }
+#endif // !_MSC_VER
+#endif
+
+ private:
+ DynamicMessage(const DynamicMessageFactory::TypeInfo* type_info,
+ Arena* arena);
+
+ void SharedCtor(bool lock_factory);
+
+ // Needed to get the offset of the internal metadata member.
+ friend class DynamicMessageFactory;
+
+ bool is_prototype() const;
+
+ inline int OffsetValue(int v, FieldDescriptor::Type type) const {
+ if (type == FieldDescriptor::TYPE_MESSAGE) {
+ return v & ~0x1u;
+ }
+ return v;
+ }
+
+ inline void* OffsetToPointer(int offset) {
+ return reinterpret_cast<uint8_t*>(this) + offset;
+ }
+ inline const void* OffsetToPointer(int offset) const {
+ return reinterpret_cast<const uint8_t*>(this) + offset;
+ }
+
+ void* MutableRaw(int i);
+ void* MutableExtensionsRaw();
+ void* MutableWeakFieldMapRaw();
+ void* MutableOneofCaseRaw(int i);
+ void* MutableOneofFieldRaw(const FieldDescriptor* f);
+
+ const DynamicMessageFactory::TypeInfo* type_info_;
+ mutable std::atomic<int> cached_byte_size_;
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(DynamicMessage);
+};
+
+struct DynamicMessageFactory::TypeInfo {
+ int size;
+ int has_bits_offset;
+ int oneof_case_offset;
+ int extensions_offset;
+
+ // Not owned by the TypeInfo.
+ DynamicMessageFactory* factory; // The factory that created this object.
+ const DescriptorPool* pool; // The factory's DescriptorPool.
+ const Descriptor* type; // Type of this DynamicMessage.
+
+ // Warning: The order in which the following pointers are defined is
+ // important (the prototype must be deleted *before* the offsets).
+ std::unique_ptr<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(
+ OffsetValue(type_info_->offsets[i], type_info_->type->field(i)->type()));
+}
+void* DynamicMessage::MutableExtensionsRaw() {
+ return OffsetToPointer(type_info_->extensions_offset);
+}
+void* DynamicMessage::MutableWeakFieldMapRaw() {
+ return OffsetToPointer(type_info_->weak_field_map_offset);
+}
+void* DynamicMessage::MutableOneofCaseRaw(int i) {
+ return OffsetToPointer(type_info_->oneof_case_offset + sizeof(uint32_t) * i);
+}
+void* DynamicMessage::MutableOneofFieldRaw(const FieldDescriptor* f) {
+ return OffsetToPointer(
+ OffsetValue(type_info_->offsets[type_info_->type->field_count() +
+ f->containing_oneof()->index()],
+ f->type()));
+}
+
+void DynamicMessage::SharedCtor(bool lock_factory) {
+ // We need to call constructors for various fields manually and set
+ // default values where appropriate. We use placement new to call
+ // constructors. If you haven't heard of placement new, I suggest Googling
+ // it now. We use placement new even for primitive types that don't have
+ // constructors for consistency. (In theory, placement new should be used
+ // any time you are trying to convert untyped memory to typed memory, though
+ // in practice that's not strictly necessary for types that don't have a
+ // constructor.)
+
+ const Descriptor* descriptor = type_info_->type;
+ // Initialize oneof cases.
+ int oneof_count = 0;
+ for (int i = 0; i < descriptor->oneof_decl_count(); ++i) {
+ if (descriptor->oneof_decl(i)->is_synthetic()) continue;
+ new (MutableOneofCaseRaw(oneof_count++)) 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()) {
+ const std::string* default_value =
+ field->default_value_string().empty()
+ ? &internal::GetEmptyStringAlreadyInited()
+ : nullptr;
+ ArenaStringPtr* asp = new (field_ptr) ArenaStringPtr();
+ asp->UnsafeSetDefault(default_value);
+ } else {
+ new (field_ptr)
+ RepeatedPtrField<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: {
+ // Oneof string fields are never set as a default instance.
+ // We just need to pass some arbitrary default string to make it
+ // work. This allows us to not have the real default accessible
+ // from reflection.
+ const std::string* default_value = nullptr;
+ reinterpret_cast<ArenaStringPtr*>(field_ptr)->Destroy(
+ default_value, nullptr);
+ break;
+ }
+ }
+ } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+ delete *reinterpret_cast<Message**>(field_ptr);
+ }
+ }
+ continue;
+ }
+ void* field_ptr = MutableRaw(i);
+
+ if (field->is_repeated()) {
+ switch (field->cpp_type()) {
+#define HANDLE_TYPE(UPPERCASE, LOWERCASE) \
+ case FieldDescriptor::CPPTYPE_##UPPERCASE: \
+ reinterpret_cast<RepeatedField<LOWERCASE>*>(field_ptr) \
+ ->~RepeatedField<LOWERCASE>(); \
+ break
+
+ HANDLE_TYPE(INT32, 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: {
+ const std::string* default_value =
+ reinterpret_cast<const ArenaStringPtr*>(
+ type_info_->prototype->OffsetToPointer(
+ type_info_->offsets[i]))
+ ->GetPointer();
+ reinterpret_cast<ArenaStringPtr*>(field_ptr)->Destroy(default_value,
+ nullptr);
+ break;
+ }
+ }
+ } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+ if (!is_prototype()) {
+ Message* message = *reinterpret_cast<Message**>(field_ptr);
+ if (message != nullptr) {
+ delete message;
+ }
+ }
+ }
+ }
+}
+
+void DynamicMessage::CrossLinkPrototypes() {
+ // This should only be called on the prototype message.
+ GOOGLE_CHECK(is_prototype());
+
+ DynamicMessageFactory* factory = type_info_->factory;
+ const Descriptor* descriptor = type_info_->type;
+
+ // Cross-link default messages.
+ for (int i = 0; i < descriptor->field_count(); i++) {
+ const FieldDescriptor* field = descriptor->field(i);
+ if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
+ !field->options().weak() && !InRealOneof(field) &&
+ !field->is_repeated()) {
+ void* field_ptr = MutableRaw(i);
+ // For fields with message types, we need to cross-link with the
+ // prototype for the field's type.
+ // For singular fields, the field is just a pointer which should
+ // point to the prototype.
+ *reinterpret_cast<const Message**>(field_ptr) =
+ factory->GetPrototypeNoLock(field->message_type());
+ }
+ }
+}
+
+Message* DynamicMessage::New(Arena* arena) const {
+ if (arena != nullptr) {
+ void* new_base = Arena::CreateArray<char>(arena, type_info_->size);
+ memset(new_base, 0, type_info_->size);
+ return new (new_base) DynamicMessage(type_info_, arena);
+ } else {
+ void* new_base = operator new(type_info_->size);
+ memset(new_base, 0, type_info_->size);
+ return new (new_base) DynamicMessage(type_info_);
+ }
+}
+
+int DynamicMessage::GetCachedSize() const {
+ return cached_byte_size_.load(std::memory_order_relaxed);
+}
+
+void DynamicMessage::SetCachedSize(int size) const {
+ cached_byte_size_.store(size, std::memory_order_relaxed);
+}
+
+Metadata DynamicMessage::GetMetadata() const {
+ Metadata metadata;
+ metadata.descriptor = type_info_->type;
+ metadata.reflection = type_info_->reflection.get();
+ return metadata;
+}
+
+// ===================================================================
+
+DynamicMessageFactory::DynamicMessageFactory()
+ : pool_(nullptr), delegate_to_generated_factory_(false) {}
+
+DynamicMessageFactory::DynamicMessageFactory(const DescriptorPool* pool)
+ : pool_(pool), delegate_to_generated_factory_(false) {}
+
+DynamicMessageFactory::~DynamicMessageFactory() {
+ for (auto iter = prototypes_.begin(); iter != prototypes_.end(); ++iter) {
+ delete iter->second;
+ }
+}
+
+const Message* DynamicMessageFactory::GetPrototype(const Descriptor* type) {
+ MutexLock lock(&prototypes_mutex_);
+ return GetPrototypeNoLock(type);
+}
+
+const Message* DynamicMessageFactory::GetPrototypeNoLock(
+ const Descriptor* type) {
+ if (delegate_to_generated_factory_ &&
+ type->file()->pool() == DescriptorPool::generated_pool()) {
+ return MessageFactory::generated_factory()->GetPrototype(type);
+ }
+
+ const TypeInfo** target = &prototypes_[type];
+ if (*target != nullptr) {
+ // Already exists.
+ return (*target)->prototype;
+ }
+
+ TypeInfo* type_info = new TypeInfo;
+ *target = type_info;
+
+ type_info->type = type;
+ type_info->pool = (pool_ == nullptr) ? type->file()->pool() : pool_;
+ type_info->factory = this;
+
+ // We need to construct all the structures passed to Reflection's constructor.
+ // This includes:
+ // - A block of memory that contains space for all the message's fields.
+ // - An array of integers indicating the byte offset of each field within
+ // this block.
+ // - A big bitfield containing a bit for each field indicating whether
+ // or not that field is set.
+ int real_oneof_count = 0;
+ for (int i = 0; i < type->oneof_decl_count(); i++) {
+ if (!type->oneof_decl(i)->is_synthetic()) {
+ real_oneof_count++;
+ }
+ }
+
+ // Compute size and offsets.
+ 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 <port_undef.inc> // NOLINT
diff --git a/NorthstarDedicatedTest/include/protobuf/dynamic_message.h b/NorthstarDedicatedTest/include/protobuf/dynamic_message.h
new file mode 100644
index 00000000..f0e384ba
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/dynamic_message.h
@@ -0,0 +1,225 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// Defines an implementation of Message which can emulate types which are not
+// known at compile-time.
+
+#ifndef GOOGLE_PROTOBUF_DYNAMIC_MESSAGE_H__
+#define GOOGLE_PROTOBUF_DYNAMIC_MESSAGE_H__
+
+#include <algorithm>
+#include <memory>
+#include <unordered_map>
+#include <vector>
+
+#include <stubs/common.h>
+#include <message.h>
+#include <stubs/mutex.h>
+#include <reflection.h>
+#include <repeated_field.h>
+
+#ifdef SWIG
+#error "You cannot SWIG proto headers"
+#endif
+
+#include <port_def.inc>
+
+namespace google {
+namespace protobuf {
+
+// Defined in other files.
+class Descriptor; // descriptor.h
+class DescriptorPool; // descriptor.h
+
+// Constructs implementations of Message which can emulate types which are not
+// known at compile-time.
+//
+// Sometimes you want to be able to manipulate protocol types that you don't
+// know about at compile time. It would be nice to be able to construct
+// a Message object which implements the message type given by any arbitrary
+// Descriptor. DynamicMessage provides this.
+//
+// As it turns out, a DynamicMessage needs to construct extra
+// information about its type in order to operate. Most of this information
+// can be shared between all DynamicMessages of the same type. But, caching
+// this information in some sort of global map would be a bad idea, since
+// the cached information for a particular descriptor could outlive the
+// descriptor itself. To avoid this problem, DynamicMessageFactory
+// encapsulates this "cache". All DynamicMessages of the same type created
+// from the same factory will share the same support data. Any Descriptors
+// used with a particular factory must outlive the factory.
+class PROTOBUF_EXPORT DynamicMessageFactory : public MessageFactory {
+ public:
+ // Construct a DynamicMessageFactory that will search for extensions in
+ // the DescriptorPool in which the extendee is defined.
+ DynamicMessageFactory();
+
+ // Construct a DynamicMessageFactory that will search for extensions in
+ // the given DescriptorPool.
+ //
+ // DEPRECATED: Use CodedInputStream::SetExtensionRegistry() to tell the
+ // parser to look for extensions in an alternate pool. However, note that
+ // this is almost never what you want to do. Almost all users should use
+ // the zero-arg constructor.
+ DynamicMessageFactory(const DescriptorPool* pool);
+
+ ~DynamicMessageFactory();
+
+ // Call this to tell the DynamicMessageFactory that if it is given a
+ // Descriptor d for which:
+ // d->file()->pool() == DescriptorPool::generated_pool(),
+ // then it should delegate to MessageFactory::generated_factory() instead
+ // of constructing a dynamic implementation of the message. In theory there
+ // is no down side to doing this, so it may become the default in the future.
+ void SetDelegateToGeneratedFactory(bool enable) {
+ delegate_to_generated_factory_ = enable;
+ }
+
+ // implements MessageFactory ---------------------------------------
+
+ // Given a Descriptor, constructs the default (prototype) Message of that
+ // type. You can then call that message's New() method to construct a
+ // mutable message of that type.
+ //
+ // Calling this method twice with the same Descriptor returns the same
+ // object. The returned object remains property of the factory and will
+ // be destroyed when the factory is destroyed. Also, any objects created
+ // by calling the prototype's New() method share some data with the
+ // prototype, so these must be destroyed before the DynamicMessageFactory
+ // is destroyed.
+ //
+ // The given descriptor must outlive the returned message, and hence must
+ // outlive the DynamicMessageFactory.
+ //
+ // The method is thread-safe.
+ const Message* GetPrototype(const Descriptor* type) override;
+
+ private:
+ const DescriptorPool* pool_;
+ bool delegate_to_generated_factory_;
+
+ struct TypeInfo;
+ std::unordered_map<const Descriptor*, const TypeInfo*> prototypes_;
+ mutable internal::WrappedMutex prototypes_mutex_;
+
+ friend class DynamicMessage;
+ const Message* GetPrototypeNoLock(const Descriptor* type);
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(DynamicMessageFactory);
+};
+
+// Helper for computing a sorted list of map entries via reflection.
+class PROTOBUF_EXPORT DynamicMapSorter {
+ public:
+ static std::vector<const Message*> Sort(const Message& message, int map_size,
+ const Reflection* reflection,
+ const FieldDescriptor* field) {
+ std::vector<const Message*> result;
+ result.reserve(map_size);
+ RepeatedFieldRef<Message> map_field =
+ reflection->GetRepeatedFieldRef<Message>(message, field);
+ for (auto it = map_field.begin(); it != map_field.end(); ++it) {
+ result.push_back(&*it);
+ }
+ MapEntryMessageComparator comparator(field->message_type());
+ std::stable_sort(result.begin(), result.end(), comparator);
+ // Complain if the keys aren't in ascending order.
+#ifndef NDEBUG
+ for (size_t j = 1; j < static_cast<size_t>(map_size); j++) {
+ if (!comparator(result[j - 1], result[j])) {
+ GOOGLE_LOG(ERROR) << (comparator(result[j], result[j - 1])
+ ? "internal error in map key sorting"
+ : "map keys are not unique");
+ }
+ }
+#endif
+ return result;
+ }
+
+ private:
+ class PROTOBUF_EXPORT MapEntryMessageComparator {
+ public:
+ explicit MapEntryMessageComparator(const Descriptor* descriptor)
+ : field_(descriptor->field(0)) {}
+
+ bool operator()(const Message* a, const Message* b) {
+ const Reflection* reflection = a->GetReflection();
+ switch (field_->cpp_type()) {
+ case FieldDescriptor::CPPTYPE_BOOL: {
+ bool first = reflection->GetBool(*a, field_);
+ bool second = reflection->GetBool(*b, field_);
+ return first < second;
+ }
+ case FieldDescriptor::CPPTYPE_INT32: {
+ 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 <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_DYNAMIC_MESSAGE_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/dynamic_message_unittest.cc b/NorthstarDedicatedTest/include/protobuf/dynamic_message_unittest.cc
new file mode 100644
index 00000000..4d30cf3a
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/dynamic_message_unittest.cc
@@ -0,0 +1,327 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// Since the reflection interface for DynamicMessage is implemented by
+// GenericMessageReflection, the only thing we really have to test is
+// that DynamicMessage correctly sets up the information that
+// GenericMessageReflection needs to use. So, we focus on that in this
+// test. Other tests, such as generic_message_reflection_unittest and
+// reflection_ops_unittest, cover the rest of the functionality used by
+// DynamicMessage.
+
+#include <memory>
+
+#include <test_util.h>
+#include <unittest.pb.h>
+#include <unittest_no_field_presence.pb.h>
+#include <descriptor.pb.h>
+#include <descriptor.h>
+#include <dynamic_message.h>
+
+#include <stubs/logging.h>
+#include <stubs/common.h>
+#include <testing/googletest.h>
+#include <gtest/gtest.h>
+
+namespace google {
+namespace protobuf {
+
+class DynamicMessageTest : public ::testing::TestWithParam<bool> {
+ protected:
+ DescriptorPool pool_;
+ DynamicMessageFactory factory_;
+ const Descriptor* descriptor_;
+ const Message* prototype_;
+ const Descriptor* extensions_descriptor_;
+ const Message* extensions_prototype_;
+ const Descriptor* packed_descriptor_;
+ const Message* packed_prototype_;
+ const Descriptor* oneof_descriptor_;
+ const Message* oneof_prototype_;
+ const Descriptor* proto3_descriptor_;
+ const Message* proto3_prototype_;
+
+ DynamicMessageTest() : factory_(&pool_) {}
+
+ void SetUp() override {
+ // We want to make sure that DynamicMessage works (particularly with
+ // extensions) even if we use descriptors that are *not* from compiled-in
+ // types, so we make copies of the descriptors for unittest.proto and
+ // unittest_import.proto.
+ FileDescriptorProto unittest_file;
+ FileDescriptorProto unittest_import_file;
+ FileDescriptorProto unittest_import_public_file;
+ FileDescriptorProto unittest_no_field_presence_file;
+
+ unittest::TestAllTypes::descriptor()->file()->CopyTo(&unittest_file);
+ unittest_import::ImportMessage::descriptor()->file()->CopyTo(
+ &unittest_import_file);
+ unittest_import::PublicImportMessage::descriptor()->file()->CopyTo(
+ &unittest_import_public_file);
+ proto2_nofieldpresence_unittest::TestAllTypes::descriptor()->file()->CopyTo(
+ &unittest_no_field_presence_file);
+
+ ASSERT_TRUE(pool_.BuildFile(unittest_import_public_file) != nullptr);
+ ASSERT_TRUE(pool_.BuildFile(unittest_import_file) != nullptr);
+ ASSERT_TRUE(pool_.BuildFile(unittest_file) != nullptr);
+ ASSERT_TRUE(pool_.BuildFile(unittest_no_field_presence_file) != nullptr);
+
+ descriptor_ = pool_.FindMessageTypeByName("protobuf_unittest.TestAllTypes");
+ ASSERT_TRUE(descriptor_ != nullptr);
+ prototype_ = factory_.GetPrototype(descriptor_);
+
+ extensions_descriptor_ =
+ pool_.FindMessageTypeByName("protobuf_unittest.TestAllExtensions");
+ ASSERT_TRUE(extensions_descriptor_ != nullptr);
+ extensions_prototype_ = factory_.GetPrototype(extensions_descriptor_);
+
+ packed_descriptor_ =
+ pool_.FindMessageTypeByName("protobuf_unittest.TestPackedTypes");
+ ASSERT_TRUE(packed_descriptor_ != nullptr);
+ packed_prototype_ = factory_.GetPrototype(packed_descriptor_);
+
+ oneof_descriptor_ =
+ pool_.FindMessageTypeByName("protobuf_unittest.TestOneof2");
+ ASSERT_TRUE(oneof_descriptor_ != nullptr);
+ oneof_prototype_ = factory_.GetPrototype(oneof_descriptor_);
+
+ proto3_descriptor_ = pool_.FindMessageTypeByName(
+ "proto2_nofieldpresence_unittest.TestAllTypes");
+ ASSERT_TRUE(proto3_descriptor_ != nullptr);
+ proto3_prototype_ = factory_.GetPrototype(proto3_descriptor_);
+ }
+};
+
+TEST_F(DynamicMessageTest, Descriptor) {
+ // Check that the descriptor on the DynamicMessage matches the descriptor
+ // passed to GetPrototype().
+ EXPECT_EQ(prototype_->GetDescriptor(), descriptor_);
+}
+
+TEST_F(DynamicMessageTest, OnePrototype) {
+ // Check that requesting the same prototype twice produces the same object.
+ EXPECT_EQ(prototype_, factory_.GetPrototype(descriptor_));
+}
+
+TEST_F(DynamicMessageTest, Defaults) {
+ // Check that all default values are set correctly in the initial message.
+ TestUtil::ReflectionTester reflection_tester(descriptor_);
+ reflection_tester.ExpectClearViaReflection(*prototype_);
+}
+
+TEST_P(DynamicMessageTest, IndependentOffsets) {
+ // Check that all fields have independent offsets by setting each
+ // one to a unique value then checking that they all still have those
+ // unique values (i.e. they don't stomp each other).
+ Arena arena;
+ Message* message = prototype_->New(GetParam() ? &arena : nullptr);
+ TestUtil::ReflectionTester reflection_tester(descriptor_);
+
+ reflection_tester.SetAllFieldsViaReflection(message);
+ reflection_tester.ExpectAllFieldsSetViaReflection(*message);
+
+ if (!GetParam()) {
+ delete message;
+ }
+}
+
+TEST_P(DynamicMessageTest, Extensions) {
+ // Check that extensions work.
+ Arena arena;
+ Message* message = extensions_prototype_->New(GetParam() ? &arena : nullptr);
+ TestUtil::ReflectionTester reflection_tester(extensions_descriptor_);
+
+ reflection_tester.SetAllFieldsViaReflection(message);
+ reflection_tester.ExpectAllFieldsSetViaReflection(*message);
+
+ if (!GetParam()) {
+ delete message;
+ }
+}
+
+TEST_P(DynamicMessageTest, PackedFields) {
+ // Check that packed fields work properly.
+ Arena arena;
+ Message* message = packed_prototype_->New(GetParam() ? &arena : nullptr);
+ TestUtil::ReflectionTester reflection_tester(packed_descriptor_);
+
+ reflection_tester.SetPackedFieldsViaReflection(message);
+ reflection_tester.ExpectPackedFieldsSetViaReflection(*message);
+
+ if (!GetParam()) {
+ delete message;
+ }
+}
+
+TEST_P(DynamicMessageTest, Oneof) {
+ // Check that oneof fields work properly.
+ Arena arena;
+ Message* message = oneof_prototype_->New(GetParam() ? &arena : nullptr);
+
+ // Check default values.
+ const Descriptor* descriptor = message->GetDescriptor();
+ const Reflection* reflection = message->GetReflection();
+ EXPECT_EQ(0, reflection->GetInt32(*message,
+ descriptor->FindFieldByName("foo_int")));
+ EXPECT_EQ("", reflection->GetString(
+ *message, descriptor->FindFieldByName("foo_string")));
+ EXPECT_EQ("", reflection->GetString(*message,
+ descriptor->FindFieldByName("foo_cord")));
+ EXPECT_EQ("", reflection->GetString(
+ *message, descriptor->FindFieldByName("foo_string_piece")));
+ EXPECT_EQ("", reflection->GetString(
+ *message, descriptor->FindFieldByName("foo_bytes")));
+ EXPECT_EQ(
+ unittest::TestOneof2::FOO,
+ reflection->GetEnum(*message, descriptor->FindFieldByName("foo_enum"))
+ ->number());
+ const Descriptor* nested_descriptor;
+ const Message* nested_prototype;
+ nested_descriptor =
+ pool_.FindMessageTypeByName("protobuf_unittest.TestOneof2.NestedMessage");
+ nested_prototype = factory_.GetPrototype(nested_descriptor);
+ EXPECT_EQ(nested_prototype,
+ &reflection->GetMessage(
+ *message, descriptor->FindFieldByName("foo_message")));
+ const Descriptor* foogroup_descriptor;
+ const Message* foogroup_prototype;
+ foogroup_descriptor =
+ pool_.FindMessageTypeByName("protobuf_unittest.TestOneof2.FooGroup");
+ foogroup_prototype = factory_.GetPrototype(foogroup_descriptor);
+ EXPECT_EQ(foogroup_prototype,
+ &reflection->GetMessage(*message,
+ descriptor->FindFieldByName("foogroup")));
+ EXPECT_NE(foogroup_prototype,
+ &reflection->GetMessage(
+ *message, descriptor->FindFieldByName("foo_lazy_message")));
+ EXPECT_EQ(5, reflection->GetInt32(*message,
+ descriptor->FindFieldByName("bar_int")));
+ EXPECT_EQ("STRING", reflection->GetString(
+ *message, descriptor->FindFieldByName("bar_string")));
+ EXPECT_EQ("CORD", reflection->GetString(
+ *message, descriptor->FindFieldByName("bar_cord")));
+ EXPECT_EQ("SPIECE",
+ reflection->GetString(
+ *message, descriptor->FindFieldByName("bar_string_piece")));
+ EXPECT_EQ("BYTES", reflection->GetString(
+ *message, descriptor->FindFieldByName("bar_bytes")));
+ EXPECT_EQ(
+ unittest::TestOneof2::BAR,
+ reflection->GetEnum(*message, descriptor->FindFieldByName("bar_enum"))
+ ->number());
+
+ // Check set functions.
+ TestUtil::ReflectionTester reflection_tester(oneof_descriptor_);
+ reflection_tester.SetOneofViaReflection(message);
+ reflection_tester.ExpectOneofSetViaReflection(*message);
+
+ if (!GetParam()) {
+ delete message;
+ }
+}
+
+TEST_P(DynamicMessageTest, SpaceUsed) {
+ // Test that SpaceUsedLong() works properly
+
+ // Since we share the implementation with generated messages, we don't need
+ // to test very much here. Just make sure it appears to be working.
+
+ Arena arena;
+ Message* message = prototype_->New(GetParam() ? &arena : nullptr);
+ TestUtil::ReflectionTester reflection_tester(descriptor_);
+
+ size_t initial_space_used = message->SpaceUsedLong();
+
+ reflection_tester.SetAllFieldsViaReflection(message);
+ EXPECT_LT(initial_space_used, message->SpaceUsedLong());
+
+ if (!GetParam()) {
+ delete message;
+ }
+}
+
+TEST_F(DynamicMessageTest, Arena) {
+ Arena arena;
+ Message* message = prototype_->New(&arena);
+ Message* extension_message = extensions_prototype_->New(&arena);
+ Message* packed_message = packed_prototype_->New(&arena);
+ Message* oneof_message = oneof_prototype_->New(&arena);
+
+ // avoid unused-variable error.
+ (void)message;
+ (void)extension_message;
+ (void)packed_message;
+ (void)oneof_message;
+ // Return without freeing: should not leak.
+}
+
+
+TEST_F(DynamicMessageTest, Proto3) {
+ Message* message = proto3_prototype_->New();
+ const Reflection* refl = message->GetReflection();
+ const Descriptor* desc = message->GetDescriptor();
+
+ // Just test a single primitive and single message field here to make sure we
+ // are getting the no-field-presence semantics elsewhere. DynamicMessage uses
+ // GeneratedMessageReflection under the hood, so the rest should be fine as
+ // long as GMR recognizes that we're using a proto3 message.
+ const FieldDescriptor* optional_int32 =
+ desc->FindFieldByName("optional_int32");
+ const FieldDescriptor* optional_msg =
+ desc->FindFieldByName("optional_nested_message");
+ EXPECT_TRUE(optional_int32 != nullptr);
+ EXPECT_TRUE(optional_msg != nullptr);
+
+ EXPECT_EQ(false, refl->HasField(*message, optional_int32));
+ refl->SetInt32(message, optional_int32, 42);
+ EXPECT_EQ(true, refl->HasField(*message, optional_int32));
+ refl->SetInt32(message, optional_int32, 0);
+ EXPECT_EQ(false, refl->HasField(*message, optional_int32));
+
+ EXPECT_EQ(false, refl->HasField(*message, optional_msg));
+ refl->MutableMessage(message, optional_msg);
+ EXPECT_EQ(true, refl->HasField(*message, optional_msg));
+ delete refl->ReleaseMessage(message, optional_msg);
+ EXPECT_EQ(false, refl->HasField(*message, optional_msg));
+
+ // Also ensure that the default instance handles field presence properly.
+ EXPECT_EQ(false, refl->HasField(*proto3_prototype_, optional_msg));
+
+ delete message;
+}
+
+INSTANTIATE_TEST_SUITE_P(UseArena, DynamicMessageTest, ::testing::Bool());
+
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/empty.pb.cc b/NorthstarDedicatedTest/include/protobuf/empty.pb.cc
new file mode 100644
index 00000000..05626aa9
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/empty.pb.cc
@@ -0,0 +1,122 @@
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+// source: google/protobuf/empty.proto
+
+#include <empty.pb.h>
+
+#include <algorithm>
+
+#include <io/coded_stream.h>
+#include <extension_set.h>
+#include <wire_format_lite.h>
+#include <descriptor.h>
+#include <generated_message_reflection.h>
+#include <reflection_ops.h>
+#include <wire_format.h>
+// @@protoc_insertion_point(includes)
+#include <port_def.inc>
+
+PROTOBUF_PRAGMA_INIT_SEG
+PROTOBUF_NAMESPACE_OPEN
+constexpr Empty::Empty(
+ ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized){}
+struct EmptyDefaultTypeInternal {
+ constexpr EmptyDefaultTypeInternal()
+ : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {}
+ ~EmptyDefaultTypeInternal() {}
+ union {
+ Empty _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT EmptyDefaultTypeInternal _Empty_default_instance_;
+PROTOBUF_NAMESPACE_CLOSE
+static ::PROTOBUF_NAMESPACE_ID::Metadata file_level_metadata_google_2fprotobuf_2fempty_2eproto[1];
+static constexpr ::PROTOBUF_NAMESPACE_ID::EnumDescriptor const** file_level_enum_descriptors_google_2fprotobuf_2fempty_2eproto = nullptr;
+static constexpr ::PROTOBUF_NAMESPACE_ID::ServiceDescriptor const** file_level_service_descriptors_google_2fprotobuf_2fempty_2eproto = nullptr;
+
+const 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 ::PROTOBUF_NAMESPACE_ID::internal::MigrationSchema schemas[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = {
+ { 0, -1, -1, sizeof(::PROTOBUF_NAMESPACE_ID::Empty)},
+};
+
+static ::PROTOBUF_NAMESPACE_ID::Message const * const file_default_instances[] = {
+ reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_Empty_default_instance_),
+};
+
+const char descriptor_table_protodef_google_2fprotobuf_2fempty_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) =
+ "\n\033google/protobuf/empty.proto\022\017google.pr"
+ "otobuf\"\007\n\005EmptyB}\n\023com.google.protobufB\n"
+ "EmptyProtoP\001Z.google.golang.org/protobuf"
+ "/types/known/emptypb\370\001\001\242\002\003GPB\252\002\036Google.P"
+ "rotobuf.WellKnownTypesb\006proto3"
+ ;
+static ::PROTOBUF_NAMESPACE_ID::internal::once_flag descriptor_table_google_2fprotobuf_2fempty_2eproto_once;
+const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fempty_2eproto = {
+ false, false, 190, descriptor_table_protodef_google_2fprotobuf_2fempty_2eproto, "google/protobuf/empty.proto",
+ &descriptor_table_google_2fprotobuf_2fempty_2eproto_once, nullptr, 0, 1,
+ schemas, file_default_instances, TableStruct_google_2fprotobuf_2fempty_2eproto::offsets,
+ file_level_metadata_google_2fprotobuf_2fempty_2eproto, file_level_enum_descriptors_google_2fprotobuf_2fempty_2eproto, file_level_service_descriptors_google_2fprotobuf_2fempty_2eproto,
+};
+PROTOBUF_ATTRIBUTE_WEAK const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable* descriptor_table_google_2fprotobuf_2fempty_2eproto_getter() {
+ return &descriptor_table_google_2fprotobuf_2fempty_2eproto;
+}
+
+// Force running AddDescriptors() at dynamic initialization time.
+PROTOBUF_ATTRIBUTE_INIT_PRIORITY static ::PROTOBUF_NAMESPACE_ID::internal::AddDescriptorsRunner dynamic_init_dummy_google_2fprotobuf_2fempty_2eproto(&descriptor_table_google_2fprotobuf_2fempty_2eproto);
+PROTOBUF_NAMESPACE_OPEN
+
+// ===================================================================
+
+class Empty::_Internal {
+ public:
+};
+
+Empty::Empty(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned)
+ : ::PROTOBUF_NAMESPACE_ID::internal::ZeroFieldsBase(arena, is_message_owned) {
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.Empty)
+}
+Empty::Empty(const Empty& from)
+ : ::PROTOBUF_NAMESPACE_ID::internal::ZeroFieldsBase() {
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.Empty)
+}
+
+
+
+
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData Empty::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::internal::ZeroFieldsBase::CopyImpl,
+ ::PROTOBUF_NAMESPACE_ID::internal::ZeroFieldsBase::MergeImpl,
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*Empty::GetClassData() const { return &_class_data_; }
+
+
+
+
+
+
+
+::PROTOBUF_NAMESPACE_ID::Metadata Empty::GetMetadata() const {
+ return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(
+ &descriptor_table_google_2fprotobuf_2fempty_2eproto_getter, &descriptor_table_google_2fprotobuf_2fempty_2eproto_once,
+ file_level_metadata_google_2fprotobuf_2fempty_2eproto[0]);
+}
+
+// @@protoc_insertion_point(namespace_scope)
+PROTOBUF_NAMESPACE_CLOSE
+PROTOBUF_NAMESPACE_OPEN
+template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::Empty* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::Empty >(Arena* arena) {
+ return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::Empty >(arena);
+}
+PROTOBUF_NAMESPACE_CLOSE
+
+// @@protoc_insertion_point(global_scope)
+#include <port_undef.inc>
diff --git a/NorthstarDedicatedTest/include/protobuf/empty.pb.h b/NorthstarDedicatedTest/include/protobuf/empty.pb.h
new file mode 100644
index 00000000..69224d6b
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/empty.pb.h
@@ -0,0 +1,207 @@
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+// source: google/protobuf/empty.proto
+
+#ifndef GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fempty_2eproto
+#define GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fempty_2eproto
+
+#include <limits>
+#include <string>
+
+#include <port_def.inc>
+#if PROTOBUF_VERSION < 3019000
+#error This file was generated by a newer version of protoc which is
+#error incompatible with your Protocol Buffer headers. Please update
+#error your headers.
+#endif
+#if 3019004 < 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 <port_undef.inc>
+#include <io/coded_stream.h>
+#include <arena.h>
+#include <arenastring.h>
+#include <generated_message_bases.h>
+#include <generated_message_table_driven.h>
+#include <generated_message_util.h>
+#include <metadata_lite.h>
+#include <generated_message_reflection.h>
+#include <message.h>
+#include <repeated_field.h> // IWYU pragma: export
+#include <extension_set.h> // IWYU pragma: export
+#include <unknown_field_set.h>
+// @@protoc_insertion_point(includes)
+#include <port_def.inc>
+#define PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fempty_2eproto PROTOBUF_EXPORT
+PROTOBUF_NAMESPACE_OPEN
+namespace internal {
+class AnyMetadata;
+} // namespace internal
+PROTOBUF_NAMESPACE_CLOSE
+
+// Internal implementation detail -- do not use these members.
+struct PROTOBUF_EXPORT TableStruct_google_2fprotobuf_2fempty_2eproto {
+ static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTableField entries[]
+ PROTOBUF_SECTION_VARIABLE(protodesc_cold);
+ static const ::PROTOBUF_NAMESPACE_ID::internal::AuxiliaryParseTableField aux[]
+ PROTOBUF_SECTION_VARIABLE(protodesc_cold);
+ static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTable schema[1]
+ PROTOBUF_SECTION_VARIABLE(protodesc_cold);
+ static const ::PROTOBUF_NAMESPACE_ID::internal::FieldMetadata field_metadata[];
+ static const ::PROTOBUF_NAMESPACE_ID::internal::SerializationTable serialization_table[];
+ static const 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 constexpr Empty(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
+
+ Empty(const Empty& from);
+ Empty(Empty&& from) noexcept
+ : Empty() {
+ *this = ::std::move(from);
+ }
+
+ inline Empty& operator=(const Empty& from) {
+ CopyFrom(from);
+ return *this;
+ }
+ inline Empty& operator=(Empty&& from) noexcept {
+ if (this == &from) return *this;
+ if (GetOwningArena() == from.GetOwningArena()
+ #ifdef PROTOBUF_FORCE_COPY_IN_MOVE
+ && GetOwningArena() != nullptr
+ #endif // !PROTOBUF_FORCE_COPY_IN_MOVE
+ ) {
+ InternalSwap(&from);
+ } else {
+ CopyFrom(from);
+ }
+ return *this;
+ }
+
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
+ return GetDescriptor();
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
+ return default_instance().GetMetadata().descriptor;
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
+ return default_instance().GetMetadata().reflection;
+ }
+ static const Empty& default_instance() {
+ return *internal_default_instance();
+ }
+ static inline const Empty* internal_default_instance() {
+ return reinterpret_cast<const Empty*>(
+ &_Empty_default_instance_);
+ }
+ static constexpr int kIndexInFileMessages =
+ 0;
+
+ friend void swap(Empty& a, Empty& b) {
+ a.Swap(&b);
+ }
+ inline void Swap(Empty* other) {
+ if (other == this) return;
+ #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() != nullptr &&
+ GetOwningArena() == other->GetOwningArena()) {
+ #else // PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() == other->GetOwningArena()) {
+ #endif // !PROTOBUF_FORCE_COPY_IN_SWAP
+ InternalSwap(other);
+ } else {
+ ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
+ }
+ }
+ void UnsafeArenaSwap(Empty* other) {
+ if (other == this) return;
+ GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena());
+ InternalSwap(other);
+ }
+
+ // implements Message ----------------------------------------------
+
+ Empty* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
+ return CreateMaybeMessage<Empty>(arena);
+ }
+ using ::PROTOBUF_NAMESPACE_ID::internal::ZeroFieldsBase::CopyFrom;
+ inline void CopyFrom(const Empty& from) {
+ ::PROTOBUF_NAMESPACE_ID::internal::ZeroFieldsBase::CopyImpl(this, from);
+ }
+ using ::PROTOBUF_NAMESPACE_ID::internal::ZeroFieldsBase::MergeFrom;
+ void MergeFrom(const Empty& from) {
+ ::PROTOBUF_NAMESPACE_ID::internal::ZeroFieldsBase::MergeImpl(this, from);
+ }
+ public:
+
+ private:
+ friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
+ static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
+ return "google.protobuf.Empty";
+ }
+ protected:
+ explicit Empty(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned = false);
+ private:
+ public:
+
+ static const ClassData _class_data_;
+ const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;
+
+ ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;
+
+ // nested types ----------------------------------------------------
+
+ // accessors -------------------------------------------------------
+
+ // @@protoc_insertion_point(class_scope:google.protobuf.Empty)
+ private:
+ class _Internal;
+
+ template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
+ typedef void InternalArenaConstructable_;
+ typedef void DestructorSkippable_;
+ mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
+ friend struct ::TableStruct_google_2fprotobuf_2fempty_2eproto;
+};
+// ===================================================================
+
+
+// ===================================================================
+
+#ifdef __GNUC__
+ #pragma GCC diagnostic push
+ #pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#endif // __GNUC__
+// Empty
+
+#ifdef __GNUC__
+ #pragma GCC diagnostic pop
+#endif // __GNUC__
+
+// @@protoc_insertion_point(namespace_scope)
+
+PROTOBUF_NAMESPACE_CLOSE
+
+// @@protoc_insertion_point(global_scope)
+
+#include <port_undef.inc>
+#endif // GOOGLE_PROTOBUF_INCLUDED_GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fempty_2eproto
diff --git a/NorthstarDedicatedTest/include/protobuf/empty.proto b/NorthstarDedicatedTest/include/protobuf/empty.proto
new file mode 100644
index 00000000..5f992de9
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/empty.proto
@@ -0,0 +1,52 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+syntax = "proto3";
+
+package google.protobuf;
+
+option csharp_namespace = "Google.Protobuf.WellKnownTypes";
+option go_package = "google.golang.org/protobuf/types/known/emptypb";
+option java_package = "com.google.protobuf";
+option java_outer_classname = "EmptyProto";
+option java_multiple_files = true;
+option objc_class_prefix = "GPB";
+option cc_enable_arenas = true;
+
+// A generic empty message that you can re-use to avoid defining duplicated
+// empty messages in your APIs. A typical example is to use it as the request
+// or the response type of an API method. For instance:
+//
+// service Foo {
+// rpc Bar(google.protobuf.Empty) returns (google.protobuf.Empty);
+// }
+//
+// The JSON representation for `Empty` is empty JSON object `{}`.
+message Empty {}
diff --git a/NorthstarDedicatedTest/include/protobuf/explicitly_constructed.h b/NorthstarDedicatedTest/include/protobuf/explicitly_constructed.h
new file mode 100644
index 00000000..2e691256
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/explicitly_constructed.h
@@ -0,0 +1,91 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef GOOGLE_PROTOBUF_EXPLICITLY_CONSTRUCTED_H__
+#define GOOGLE_PROTOBUF_EXPLICITLY_CONSTRUCTED_H__
+
+#include <stdint.h>
+
+#include <utility>
+
+#include <stubs/logging.h>
+#include <stubs/common.h>
+
+// clang-format off
+#include <port_def.inc>
+// clang-format on
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+// Wraps a variable whose constructor and destructor are explicitly
+// called. It is particularly useful for a global variable, without its
+// constructor and destructor run on start and end of the program lifetime.
+// This circumvents the initial construction order fiasco, while keeping
+// the address of the empty string a compile time constant.
+//
+// Pay special attention to the initialization state of the object.
+// 1. The object is "uninitialized" to begin with.
+// 2. Call Construct() or DefaultConstruct() only if the object is
+// uninitialized. After the call, the object becomes "initialized".
+// 3. Call get() and get_mutable() only if the object is initialized.
+// 4. Call Destruct() only if the object is initialized.
+// After the call, the object becomes uninitialized.
+template <typename T>
+class ExplicitlyConstructed {
+ public:
+ void DefaultConstruct() { new (&union_) T(); }
+
+ template <typename... Args>
+ void Construct(Args&&... args) {
+ new (&union_) T(std::forward<Args>(args)...);
+ }
+
+ void Destruct() { get_mutable()->~T(); }
+
+ constexpr const T& get() const { return reinterpret_cast<const T&>(union_); }
+ T* get_mutable() { return reinterpret_cast<T*>(&union_); }
+
+ private:
+ union AlignedUnion {
+ alignas(T) char space[sizeof(T)];
+ int64_t align_to_int64;
+ void* align_to_ptr;
+ } union_;
+};
+
+} // namespace internal
+} // namespace protobuf
+} // namespace google
+
+#include <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_EXPLICITLY_CONSTRUCTED_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/extension_set.cc b/NorthstarDedicatedTest/include/protobuf/extension_set.cc
new file mode 100644
index 00000000..135957b2
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/extension_set.cc
@@ -0,0 +1,2255 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <extension_set.h>
+
+#include <tuple>
+#include <unordered_set>
+#include <utility>
+
+#include <stubs/common.h>
+#include <extension_set_inl.h>
+#include <parse_context.h>
+#include <io/coded_stream.h>
+#include <io/zero_copy_stream_impl_lite.h>
+#include <arena.h>
+#include <message_lite.h>
+#include <metadata_lite.h>
+#include <repeated_field.h>
+#include <stubs/map_util.h>
+#include <stubs/hash.h>
+
+// clang-format off
+#include <port_def.inc> // must be last.
+// clang-format on
+namespace google {
+namespace protobuf {
+namespace internal {
+
+namespace {
+
+inline WireFormatLite::FieldType real_type(FieldType type) {
+ GOOGLE_DCHECK(type > 0 && type <= WireFormatLite::MAX_FIELD_TYPE);
+ return static_cast<WireFormatLite::FieldType>(type);
+}
+
+inline WireFormatLite::CppType cpp_type(FieldType type) {
+ return WireFormatLite::FieldTypeToCppType(real_type(type));
+}
+
+inline bool is_packable(WireFormatLite::WireType type) {
+ switch (type) {
+ case WireFormatLite::WIRETYPE_VARINT:
+ case WireFormatLite::WIRETYPE_FIXED64:
+ case WireFormatLite::WIRETYPE_FIXED32:
+ return true;
+ case WireFormatLite::WIRETYPE_LENGTH_DELIMITED:
+ case WireFormatLite::WIRETYPE_START_GROUP:
+ case WireFormatLite::WIRETYPE_END_GROUP:
+ return false;
+
+ // Do not add a default statement. Let the compiler complain when someone
+ // adds a new wire type.
+ }
+ GOOGLE_LOG(FATAL) << "can't reach here.";
+ return false;
+}
+
+// Registry stuff.
+
+// Note that we cannot use hetererogeneous lookup for std containers since we
+// need to support C++11.
+struct ExtensionEq {
+ bool operator()(const ExtensionInfo& lhs, const ExtensionInfo& rhs) const {
+ return lhs.message == rhs.message && lhs.number == rhs.number;
+ }
+};
+
+struct ExtensionHasher {
+ std::size_t operator()(const ExtensionInfo& info) const {
+ return std::hash<const MessageLite*>{}(info.message) ^
+ std::hash<int>{}(info.number);
+ }
+};
+
+using ExtensionRegistry =
+ std::unordered_set<ExtensionInfo, ExtensionHasher, ExtensionEq>;
+
+static const ExtensionRegistry* global_registry = nullptr;
+
+// This function is only called at startup, so there is no need for thread-
+// safety.
+void Register(const ExtensionInfo& info) {
+ static auto local_static_registry = OnShutdownDelete(new ExtensionRegistry);
+ global_registry = local_static_registry;
+ if (!InsertIfNotPresent(local_static_registry, info)) {
+ GOOGLE_LOG(FATAL) << "Multiple extension registrations for type \""
+ << info.message->GetTypeName() << "\", field number "
+ << info.number << ".";
+ }
+}
+
+const ExtensionInfo* FindRegisteredExtension(const MessageLite* extendee,
+ int number) {
+ if (!global_registry) return nullptr;
+
+ ExtensionInfo info;
+ info.message = extendee;
+ info.number = number;
+
+ auto it = global_registry->find(info);
+ if (it == global_registry->end()) {
+ return nullptr;
+ } else {
+ return &*it;
+ }
+}
+
+} // namespace
+
+ExtensionFinder::~ExtensionFinder() {}
+
+bool GeneratedExtensionFinder::Find(int number, ExtensionInfo* output) {
+ const ExtensionInfo* extension = FindRegisteredExtension(extendee_, number);
+ if (extension == nullptr) {
+ return false;
+ } else {
+ *output = *extension;
+ return true;
+ }
+}
+
+void ExtensionSet::RegisterExtension(const MessageLite* extendee, int number,
+ FieldType type, bool is_repeated,
+ bool is_packed) {
+ GOOGLE_CHECK_NE(type, WireFormatLite::TYPE_ENUM);
+ GOOGLE_CHECK_NE(type, WireFormatLite::TYPE_MESSAGE);
+ GOOGLE_CHECK_NE(type, WireFormatLite::TYPE_GROUP);
+ ExtensionInfo info(extendee, number, type, is_repeated, is_packed);
+ Register(info);
+}
+
+static bool CallNoArgValidityFunc(const void* arg, int number) {
+ // Note: Must use C-style cast here rather than reinterpret_cast because
+ // the C++ standard at one point did not allow casts between function and
+ // data pointers and some compilers enforce this for C++-style casts. No
+ // compiler enforces it for C-style casts since lots of C-style code has
+ // relied on these kinds of casts for a long time, despite being
+ // technically undefined. See:
+ // http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#195
+ // Also note: Some compilers do not allow function pointers to be "const".
+ // Which makes sense, I suppose, because it's meaningless.
+ return ((EnumValidityFunc*)arg)(number);
+}
+
+void ExtensionSet::RegisterEnumExtension(const MessageLite* extendee,
+ int number, FieldType type,
+ bool is_repeated, bool is_packed,
+ EnumValidityFunc* is_valid) {
+ GOOGLE_CHECK_EQ(type, WireFormatLite::TYPE_ENUM);
+ ExtensionInfo info(extendee, number, type, is_repeated, is_packed);
+ info.enum_validity_check.func = CallNoArgValidityFunc;
+ // See comment in CallNoArgValidityFunc() about why we use a c-style cast.
+ info.enum_validity_check.arg = (void*)is_valid;
+ Register(info);
+}
+
+void ExtensionSet::RegisterMessageExtension(const MessageLite* extendee,
+ int number, FieldType type,
+ bool is_repeated, bool is_packed,
+ const MessageLite* prototype) {
+ GOOGLE_CHECK(type == WireFormatLite::TYPE_MESSAGE ||
+ type == WireFormatLite::TYPE_GROUP);
+ ExtensionInfo info(extendee, number, type, is_repeated, is_packed);
+ info.message_info = {prototype};
+ Register(info);
+}
+
+// ===================================================================
+// Constructors and basic methods.
+
+ExtensionSet::ExtensionSet(Arena* arena)
+ : arena_(arena),
+ flat_capacity_(0),
+ flat_size_(0),
+ map_{flat_capacity_ == 0
+ ? nullptr
+ : Arena::CreateArray<KeyValue>(arena_, flat_capacity_)} {}
+
+ExtensionSet::~ExtensionSet() {
+ // Deletes all allocated extensions.
+ if (arena_ == nullptr) {
+ ForEach([](int /* number */, Extension& ext) { ext.Free(); });
+ if (PROTOBUF_PREDICT_FALSE(is_large())) {
+ delete map_.large;
+ } else {
+ DeleteFlatMap(map_.flat, flat_capacity_);
+ }
+ }
+}
+
+void ExtensionSet::DeleteFlatMap(const ExtensionSet::KeyValue* flat,
+ uint16_t flat_capacity) {
+#ifdef __cpp_sized_deallocation
+ // Arena::CreateArray already requires a trivially destructible type, but
+ // ensure this constraint is not violated in the future.
+ static_assert(std::is_trivially_destructible<KeyValue>::value,
+ "CreateArray requires a trivially destructible type");
+ // A const-cast is needed, but this is safe as we are about to deallocate the
+ // array.
+ ::operator delete[](const_cast<ExtensionSet::KeyValue*>(flat),
+ sizeof(*flat) * flat_capacity);
+#else // !__cpp_sized_deallocation
+ delete[] flat;
+#endif // !__cpp_sized_deallocation
+}
+
+// Defined in extension_set_heavy.cc.
+// void ExtensionSet::AppendToList(const Descriptor* extendee,
+// const DescriptorPool* pool,
+// vector<const FieldDescriptor*>* output) const
+
+bool ExtensionSet::Has(int number) const {
+ const Extension* ext = FindOrNull(number);
+ if (ext == nullptr) return false;
+ GOOGLE_DCHECK(!ext->is_repeated);
+ return !ext->is_cleared;
+}
+
+bool ExtensionSet::HasLazy(int number) const {
+ return Has(number) && FindOrNull(number)->is_lazy;
+}
+
+int ExtensionSet::NumExtensions() const {
+ int result = 0;
+ ForEach([&result](int /* number */, const Extension& ext) {
+ if (!ext.is_cleared) {
+ ++result;
+ }
+ });
+ return result;
+}
+
+int ExtensionSet::ExtensionSize(int number) const {
+ const Extension* ext = FindOrNull(number);
+ return ext == nullptr ? 0 : ext->GetSize();
+}
+
+FieldType ExtensionSet::ExtensionType(int number) const {
+ const Extension* ext = FindOrNull(number);
+ if (ext == nullptr) {
+ GOOGLE_LOG(DFATAL) << "Don't lookup extension types if they aren't present (1). ";
+ return 0;
+ }
+ if (ext->is_cleared) {
+ GOOGLE_LOG(DFATAL) << "Don't lookup extension types if they aren't present (2). ";
+ }
+ return ext->type;
+}
+
+void ExtensionSet::ClearExtension(int number) {
+ Extension* ext = FindOrNull(number);
+ if (ext == nullptr) return;
+ ext->Clear();
+}
+
+// ===================================================================
+// Field accessors
+
+namespace {
+
+enum { REPEATED_FIELD, OPTIONAL_FIELD };
+
+} // namespace
+
+#define GOOGLE_DCHECK_TYPE(EXTENSION, LABEL, CPPTYPE) \
+ GOOGLE_DCHECK_EQ((EXTENSION).is_repeated ? REPEATED_FIELD : OPTIONAL_FIELD, LABEL); \
+ GOOGLE_DCHECK_EQ(cpp_type((EXTENSION).type), WireFormatLite::CPPTYPE_##CPPTYPE)
+
+// -------------------------------------------------------------------
+// Primitives
+
+#define PRIMITIVE_ACCESSORS(UPPERCASE, LOWERCASE, CAMELCASE) \
+ \
+ LOWERCASE ExtensionSet::Get##CAMELCASE(int number, LOWERCASE default_value) \
+ const { \
+ const Extension* extension = FindOrNull(number); \
+ if (extension == nullptr || extension->is_cleared) { \
+ return default_value; \
+ } else { \
+ GOOGLE_DCHECK_TYPE(*extension, OPTIONAL_FIELD, UPPERCASE); \
+ return extension->LOWERCASE##_value; \
+ } \
+ } \
+ \
+ const LOWERCASE& ExtensionSet::GetRef##CAMELCASE( \
+ int number, const LOWERCASE& default_value) const { \
+ const Extension* extension = FindOrNull(number); \
+ if (extension == nullptr || extension->is_cleared) { \
+ return default_value; \
+ } else { \
+ GOOGLE_DCHECK_TYPE(*extension, OPTIONAL_FIELD, UPPERCASE); \
+ return extension->LOWERCASE##_value; \
+ } \
+ } \
+ \
+ void ExtensionSet::Set##CAMELCASE(int number, FieldType type, \
+ LOWERCASE value, \
+ const FieldDescriptor* descriptor) { \
+ Extension* extension; \
+ if (MaybeNewExtension(number, descriptor, &extension)) { \
+ extension->type = type; \
+ GOOGLE_DCHECK_EQ(cpp_type(extension->type), \
+ WireFormatLite::CPPTYPE_##UPPERCASE); \
+ extension->is_repeated = false; \
+ } else { \
+ GOOGLE_DCHECK_TYPE(*extension, OPTIONAL_FIELD, UPPERCASE); \
+ } \
+ extension->is_cleared = false; \
+ extension->LOWERCASE##_value = value; \
+ } \
+ \
+ LOWERCASE ExtensionSet::GetRepeated##CAMELCASE(int number, int index) \
+ const { \
+ const Extension* extension = FindOrNull(number); \
+ GOOGLE_CHECK(extension != nullptr) << "Index out-of-bounds (field is empty)."; \
+ GOOGLE_DCHECK_TYPE(*extension, REPEATED_FIELD, UPPERCASE); \
+ return extension->repeated_##LOWERCASE##_value->Get(index); \
+ } \
+ \
+ const LOWERCASE& ExtensionSet::GetRefRepeated##CAMELCASE(int number, \
+ int index) const { \
+ const Extension* extension = FindOrNull(number); \
+ GOOGLE_CHECK(extension != nullptr) << "Index out-of-bounds (field is empty)."; \
+ GOOGLE_DCHECK_TYPE(*extension, REPEATED_FIELD, UPPERCASE); \
+ return extension->repeated_##LOWERCASE##_value->Get(index); \
+ } \
+ \
+ void ExtensionSet::SetRepeated##CAMELCASE(int number, int index, \
+ LOWERCASE value) { \
+ Extension* extension = FindOrNull(number); \
+ GOOGLE_CHECK(extension != nullptr) << "Index out-of-bounds (field is empty)."; \
+ GOOGLE_DCHECK_TYPE(*extension, REPEATED_FIELD, UPPERCASE); \
+ extension->repeated_##LOWERCASE##_value->Set(index, value); \
+ } \
+ \
+ void ExtensionSet::Add##CAMELCASE(int number, FieldType type, bool packed, \
+ LOWERCASE value, \
+ const FieldDescriptor* descriptor) { \
+ Extension* extension; \
+ if (MaybeNewExtension(number, descriptor, &extension)) { \
+ extension->type = type; \
+ GOOGLE_DCHECK_EQ(cpp_type(extension->type), \
+ WireFormatLite::CPPTYPE_##UPPERCASE); \
+ extension->is_repeated = true; \
+ extension->is_packed = packed; \
+ extension->repeated_##LOWERCASE##_value = \
+ Arena::CreateMessage<RepeatedField<LOWERCASE>>(arena_); \
+ } else { \
+ GOOGLE_DCHECK_TYPE(*extension, REPEATED_FIELD, UPPERCASE); \
+ GOOGLE_DCHECK_EQ(extension->is_packed, packed); \
+ } \
+ extension->repeated_##LOWERCASE##_value->Add(value); \
+ }
+
+PRIMITIVE_ACCESSORS(INT32, 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 a std::set_union without constructing the union.
+template <typename ItX, typename ItY>
+size_t SizeOfUnion(ItX it_xs, ItX end_xs, ItY it_ys, ItY end_ys) {
+ size_t result = 0;
+ while (it_xs != end_xs && it_ys != end_ys) {
+ ++result;
+ if (it_xs->first < it_ys->first) {
+ ++it_xs;
+ } else if (it_xs->first == it_ys->first) {
+ ++it_xs;
+ ++it_ys;
+ } else {
+ ++it_ys;
+ }
+ }
+ result += std::distance(it_xs, end_xs);
+ result += std::distance(it_ys, end_ys);
+ return result;
+}
+} // namespace
+
+void ExtensionSet::MergeFrom(const MessageLite* extendee,
+ const ExtensionSet& other) {
+ if (PROTOBUF_PREDICT_TRUE(!is_large())) {
+ if (PROTOBUF_PREDICT_TRUE(!other.is_large())) {
+ GrowCapacity(SizeOfUnion(flat_begin(), flat_end(), other.flat_begin(),
+ other.flat_end()));
+ } else {
+ GrowCapacity(SizeOfUnion(flat_begin(), flat_end(),
+ other.map_.large->begin(),
+ other.map_.large->end()));
+ }
+ }
+ other.ForEach([extendee, this, &other](int number, const Extension& ext) {
+ this->InternalExtensionMergeFrom(extendee, number, ext, other.arena_);
+ });
+}
+
+void ExtensionSet::InternalExtensionMergeFrom(const MessageLite* extendee,
+ int number,
+ const Extension& other_extension,
+ Arena* other_arena) {
+ if (other_extension.is_repeated) {
+ Extension* extension;
+ bool is_new =
+ MaybeNewExtension(number, other_extension.descriptor, &extension);
+ if (is_new) {
+ // Extension did not already exist in set.
+ extension->type = other_extension.type;
+ extension->is_packed = other_extension.is_packed;
+ extension->is_repeated = true;
+ } else {
+ GOOGLE_DCHECK_EQ(extension->type, other_extension.type);
+ GOOGLE_DCHECK_EQ(extension->is_packed, other_extension.is_packed);
+ GOOGLE_DCHECK(extension->is_repeated);
+ }
+
+ switch (cpp_type(other_extension.type)) {
+#define HANDLE_TYPE(UPPERCASE, LOWERCASE, REPEATED_TYPE) \
+ case WireFormatLite::CPPTYPE_##UPPERCASE: \
+ if (is_new) { \
+ extension->repeated_##LOWERCASE##_value = \
+ Arena::CreateMessage<REPEATED_TYPE>(arena_); \
+ } \
+ extension->repeated_##LOWERCASE##_value->MergeFrom( \
+ *other_extension.repeated_##LOWERCASE##_value); \
+ break;
+
+ HANDLE_TYPE(INT32, 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;
+}
+
+bool ExtensionSet::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);
+}
+
+bool ExtensionSet::FindExtensionInfoFromFieldNumber(
+ int wire_type, int field_number, ExtensionFinder* extension_finder,
+ ExtensionInfo* extension, bool* was_packed_on_wire) const {
+ if (!extension_finder->Find(field_number, extension)) {
+ return false;
+ }
+
+ WireFormatLite::WireType expected_wire_type =
+ WireFormatLite::WireTypeForFieldType(real_type(extension->type));
+
+ // Check if this is a packed field.
+ *was_packed_on_wire = false;
+ if (extension->is_repeated &&
+ wire_type == WireFormatLite::WIRETYPE_LENGTH_DELIMITED &&
+ is_packable(expected_wire_type)) {
+ *was_packed_on_wire = true;
+ return true;
+ }
+ // Otherwise the wire type must match.
+ return expected_wire_type == wire_type;
+}
+
+bool ExtensionSet::ParseField(uint32_t tag, io::CodedInputStream* input,
+ ExtensionFinder* extension_finder,
+ FieldSkipper* field_skipper) {
+ int number;
+ bool was_packed_on_wire;
+ ExtensionInfo extension;
+ if (!FindExtensionInfoFromTag(tag, extension_finder, &number, &extension,
+ &was_packed_on_wire)) {
+ return field_skipper->SkipField(input, tag);
+ } else {
+ return ParseFieldWithExtensionInfo(number, was_packed_on_wire, extension,
+ input, field_skipper);
+ }
+}
+
+const char* ExtensionSet::ParseField(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);
+}
+
+bool ExtensionSet::ParseFieldWithExtensionInfo(int number,
+ bool was_packed_on_wire,
+ const ExtensionInfo& extension,
+ io::CodedInputStream* input,
+ FieldSkipper* field_skipper) {
+ // Explicitly not read extension.is_packed, instead check whether the field
+ // was encoded in packed form on the wire.
+ if (was_packed_on_wire) {
+ uint32_t size;
+ if (!input->ReadVarint32(&size)) return false;
+ io::CodedInputStream::Limit limit = input->PushLimit(size);
+
+ switch (extension.type) {
+#define HANDLE_TYPE(UPPERCASE, CPP_CAMELCASE, CPP_LOWERCASE) \
+ case WireFormatLite::TYPE_##UPPERCASE: \
+ while (input->BytesUntilLimit() > 0) { \
+ CPP_LOWERCASE value; \
+ if (!WireFormatLite::ReadPrimitive<CPP_LOWERCASE, \
+ WireFormatLite::TYPE_##UPPERCASE>( \
+ input, &value)) \
+ return false; \
+ Add##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, \
+ extension.is_packed, value, extension.descriptor); \
+ } \
+ break
+
+ HANDLE_TYPE(INT32, Int32, int32_t);
+ HANDLE_TYPE(INT64, Int64, int64_t);
+ HANDLE_TYPE(UINT32, UInt32, uint32_t);
+ HANDLE_TYPE(UINT64, UInt64, uint64_t);
+ HANDLE_TYPE(SINT32, Int32, int32_t);
+ HANDLE_TYPE(SINT64, Int64, int64_t);
+ HANDLE_TYPE(FIXED32, UInt32, uint32_t);
+ HANDLE_TYPE(FIXED64, UInt64, uint64_t);
+ HANDLE_TYPE(SFIXED32, Int32, int32_t);
+ HANDLE_TYPE(SFIXED64, Int64, int64_t);
+ HANDLE_TYPE(FLOAT, Float, float);
+ HANDLE_TYPE(DOUBLE, Double, double);
+ HANDLE_TYPE(BOOL, Bool, bool);
+#undef HANDLE_TYPE
+
+ case WireFormatLite::TYPE_ENUM:
+ while (input->BytesUntilLimit() > 0) {
+ int value;
+ if (!WireFormatLite::ReadPrimitive<int, WireFormatLite::TYPE_ENUM>(
+ input, &value))
+ return false;
+ if (extension.enum_validity_check.func(
+ extension.enum_validity_check.arg, value)) {
+ AddEnum(number, WireFormatLite::TYPE_ENUM, extension.is_packed,
+ value, extension.descriptor);
+ } else {
+ // Invalid value. Treat as unknown.
+ field_skipper->SkipUnknownEnum(number, value);
+ }
+ }
+ break;
+
+ case WireFormatLite::TYPE_STRING:
+ case WireFormatLite::TYPE_BYTES:
+ case WireFormatLite::TYPE_GROUP:
+ case WireFormatLite::TYPE_MESSAGE:
+ GOOGLE_LOG(FATAL) << "Non-primitive types can't be packed.";
+ break;
+ }
+
+ input->PopLimit(limit);
+ } else {
+ switch (extension.type) {
+#define HANDLE_TYPE(UPPERCASE, CPP_CAMELCASE, CPP_LOWERCASE) \
+ case WireFormatLite::TYPE_##UPPERCASE: { \
+ CPP_LOWERCASE value; \
+ if (!WireFormatLite::ReadPrimitive<CPP_LOWERCASE, \
+ WireFormatLite::TYPE_##UPPERCASE>( \
+ input, &value)) \
+ return false; \
+ if (extension.is_repeated) { \
+ Add##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, \
+ extension.is_packed, value, extension.descriptor); \
+ } else { \
+ Set##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, value, \
+ extension.descriptor); \
+ } \
+ } break
+
+ HANDLE_TYPE(INT32, Int32, int32_t);
+ HANDLE_TYPE(INT64, Int64, int64_t);
+ HANDLE_TYPE(UINT32, UInt32, uint32_t);
+ HANDLE_TYPE(UINT64, UInt64, uint64_t);
+ HANDLE_TYPE(SINT32, Int32, int32_t);
+ HANDLE_TYPE(SINT64, Int64, int64_t);
+ HANDLE_TYPE(FIXED32, UInt32, uint32_t);
+ HANDLE_TYPE(FIXED64, UInt64, uint64_t);
+ HANDLE_TYPE(SFIXED32, Int32, int32_t);
+ HANDLE_TYPE(SFIXED64, Int64, int64_t);
+ HANDLE_TYPE(FLOAT, Float, float);
+ HANDLE_TYPE(DOUBLE, Double, double);
+ HANDLE_TYPE(BOOL, Bool, bool);
+#undef HANDLE_TYPE
+
+ case WireFormatLite::TYPE_ENUM: {
+ int value;
+ if (!WireFormatLite::ReadPrimitive<int, WireFormatLite::TYPE_ENUM>(
+ input, &value))
+ return false;
+
+ if (!extension.enum_validity_check.func(
+ extension.enum_validity_check.arg, value)) {
+ // Invalid value. Treat as unknown.
+ field_skipper->SkipUnknownEnum(number, value);
+ } else if (extension.is_repeated) {
+ AddEnum(number, WireFormatLite::TYPE_ENUM, extension.is_packed, value,
+ extension.descriptor);
+ } else {
+ SetEnum(number, WireFormatLite::TYPE_ENUM, value,
+ extension.descriptor);
+ }
+ break;
+ }
+
+ case WireFormatLite::TYPE_STRING: {
+ std::string* value =
+ extension.is_repeated
+ ? AddString(number, WireFormatLite::TYPE_STRING,
+ extension.descriptor)
+ : MutableString(number, WireFormatLite::TYPE_STRING,
+ extension.descriptor);
+ if (!WireFormatLite::ReadString(input, value)) return false;
+ break;
+ }
+
+ case WireFormatLite::TYPE_BYTES: {
+ std::string* value =
+ extension.is_repeated
+ ? AddString(number, WireFormatLite::TYPE_BYTES,
+ extension.descriptor)
+ : MutableString(number, WireFormatLite::TYPE_BYTES,
+ extension.descriptor);
+ if (!WireFormatLite::ReadBytes(input, value)) return false;
+ break;
+ }
+
+ case WireFormatLite::TYPE_GROUP: {
+ MessageLite* value =
+ extension.is_repeated
+ ? AddMessage(number, WireFormatLite::TYPE_GROUP,
+ *extension.message_info.prototype,
+ extension.descriptor)
+ : MutableMessage(number, WireFormatLite::TYPE_GROUP,
+ *extension.message_info.prototype,
+ extension.descriptor);
+ if (!WireFormatLite::ReadGroup(number, input, value)) return false;
+ break;
+ }
+
+ case WireFormatLite::TYPE_MESSAGE: {
+ MessageLite* value =
+ extension.is_repeated
+ ? AddMessage(number, WireFormatLite::TYPE_MESSAGE,
+ *extension.message_info.prototype,
+ extension.descriptor)
+ : MutableMessage(number, WireFormatLite::TYPE_MESSAGE,
+ *extension.message_info.prototype,
+ extension.descriptor);
+ if (!WireFormatLite::ReadMessage(input, value)) return false;
+ break;
+ }
+ }
+ }
+
+ return true;
+}
+
+bool ExtensionSet::ParseField(uint32_t tag, io::CodedInputStream* input,
+ const MessageLite* extendee) {
+ FieldSkipper skipper;
+ GeneratedExtensionFinder finder(extendee);
+ return ParseField(tag, input, &finder, &skipper);
+}
+
+bool ExtensionSet::ParseField(uint32_t tag, io::CodedInputStream* input,
+ const MessageLite* extendee,
+ io::CodedOutputStream* unknown_fields) {
+ CodedOutputStreamFieldSkipper skipper(unknown_fields);
+ GeneratedExtensionFinder finder(extendee);
+ return ParseField(tag, input, &finder, &skipper);
+}
+
+bool ExtensionSet::ParseMessageSetLite(io::CodedInputStream* input,
+ ExtensionFinder* extension_finder,
+ FieldSkipper* field_skipper) {
+ while (true) {
+ const uint32_t tag = input->ReadTag();
+ switch (tag) {
+ case 0:
+ return true;
+ case WireFormatLite::kMessageSetItemStartTag:
+ if (!ParseMessageSetItemLite(input, extension_finder, field_skipper)) {
+ return false;
+ }
+ break;
+ default:
+ if (!ParseField(tag, input, extension_finder, field_skipper)) {
+ return false;
+ }
+ break;
+ }
+ }
+}
+
+bool ExtensionSet::ParseMessageSetItemLite(io::CodedInputStream* input,
+ ExtensionFinder* extension_finder,
+ FieldSkipper* field_skipper) {
+ struct MSLite {
+ bool ParseField(int type_id, io::CodedInputStream* input) {
+ return me->ParseField(
+ WireFormatLite::WIRETYPE_LENGTH_DELIMITED + 8 * type_id, input,
+ extension_finder, field_skipper);
+ }
+
+ bool SkipField(uint32_t tag, io::CodedInputStream* input) {
+ return field_skipper->SkipField(input, tag);
+ }
+
+ ExtensionSet* me;
+ ExtensionFinder* extension_finder;
+ FieldSkipper* field_skipper;
+ };
+
+ return ParseMessageSetItemImpl(input,
+ MSLite{this, extension_finder, field_skipper});
+}
+
+bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input,
+ const MessageLite* extendee,
+ std::string* unknown_fields) {
+ io::StringOutputStream zcis(unknown_fields);
+ io::CodedOutputStream output(&zcis);
+ CodedOutputStreamFieldSkipper skipper(&output);
+ GeneratedExtensionFinder finder(extendee);
+ return ParseMessageSetLite(input, &finder, &skipper);
+}
+
+uint8_t* ExtensionSet::_InternalSerializeImpl(
+ const MessageLite* extendee, int start_field_number, int end_field_number,
+ uint8_t* target, io::EpsCopyOutputStream* stream) const {
+ if (PROTOBUF_PREDICT_FALSE(is_large())) {
+ const auto& end = map_.large->end();
+ for (auto it = map_.large->lower_bound(start_field_number);
+ it != end && it->first < end_field_number; ++it) {
+ target = it->second.InternalSerializeFieldWithCachedSizesToArray(
+ extendee, this, it->first, target, stream);
+ }
+ return target;
+ }
+ const KeyValue* end = flat_end();
+ for (const KeyValue* it = std::lower_bound(
+ flat_begin(), end, start_field_number, KeyValue::FirstComparator());
+ it != end && it->first < end_field_number; ++it) {
+ target = it->second.InternalSerializeFieldWithCachedSizesToArray(
+ extendee, this, it->first, target, stream);
+ }
+ return target;
+}
+
+uint8_t* ExtensionSet::InternalSerializeMessageSetWithCachedSizesToArray(
+ const MessageLite* extendee, uint8_t* target,
+ io::EpsCopyOutputStream* stream) const {
+ const ExtensionSet* extension_set = this;
+ ForEach([&target, extendee, stream, extension_set](int number,
+ const Extension& ext) {
+ target = ext.InternalSerializeMessageSetItemWithCachedSizesToArray(
+ extendee, extension_set, number, target, stream);
+ });
+ return target;
+}
+
+size_t ExtensionSet::ByteSize() const {
+ size_t total_size = 0;
+ ForEach([&total_size](int number, const Extension& ext) {
+ total_size += ext.ByteSize(number);
+ });
+ return total_size;
+}
+
+// Defined in extension_set_heavy.cc.
+// int ExtensionSet::SpaceUsedExcludingSelf() const
+
+bool ExtensionSet::MaybeNewExtension(int number,
+ const FieldDescriptor* descriptor,
+ Extension** result) {
+ bool extension_is_new = false;
+ std::tie(*result, extension_is_new) = Insert(number);
+ (*result)->descriptor = descriptor;
+ return extension_is_new;
+}
+
+// ===================================================================
+// Methods of ExtensionSet::Extension
+
+void ExtensionSet::Extension::Clear() {
+ if (is_repeated) {
+ switch (cpp_type(type)) {
+#define HANDLE_TYPE(UPPERCASE, LOWERCASE) \
+ case WireFormatLite::CPPTYPE_##UPPERCASE: \
+ repeated_##LOWERCASE##_value->Clear(); \
+ break
+
+ HANDLE_TYPE(INT32, 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
+#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \
+ case WireFormatLite::TYPE_##UPPERCASE: \
+ for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) { \
+ target = stream->EnsureSpace(target); \
+ target = WireFormatLite::InternalWrite##CAMELCASE( \
+ number, repeated_##LOWERCASE##_value->Get(i), target, stream); \
+ } \
+ break
+
+ HANDLE_TYPE(GROUP, Group, message);
+ HANDLE_TYPE(MESSAGE, Message, message);
+#undef HANDLE_TYPE
+ }
+ }
+ } else if (!is_cleared) {
+ switch (real_type(type)) {
+#define HANDLE_TYPE(UPPERCASE, CAMELCASE, VALUE) \
+ case WireFormatLite::TYPE_##UPPERCASE: \
+ target = stream->EnsureSpace(target); \
+ target = WireFormatLite::Write##CAMELCASE##ToArray(number, VALUE, target); \
+ break
+
+ HANDLE_TYPE(INT32, Int32, 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 = stream->EnsureSpace(target);
+ target = WireFormatLite::InternalWriteMessage(number, *message_value,
+ target, stream);
+ }
+ break;
+ }
+ }
+ return target;
+}
+
+const MessageLite* ExtensionSet::GetPrototypeForLazyMessage(
+ const MessageLite* extendee, int number) const {
+ GeneratedExtensionFinder finder(extendee);
+ bool was_packed_on_wire = false;
+ ExtensionInfo extension_info;
+ if (!FindExtensionInfoFromFieldNumber(
+ WireFormatLite::WireType::WIRETYPE_LENGTH_DELIMITED, number, &finder,
+ &extension_info, &was_packed_on_wire)) {
+ return nullptr;
+ }
+ return extension_info.message_info.prototype;
+}
+
+uint8_t*
+ExtensionSet::Extension::InternalSerializeMessageSetItemWithCachedSizesToArray(
+ const MessageLite* extendee, const ExtensionSet* extension_set, int number,
+ uint8_t* target, io::EpsCopyOutputStream* stream) const {
+ if (type != WireFormatLite::TYPE_MESSAGE || is_repeated) {
+ // Not a valid MessageSet extension, but serialize it the normal way.
+ GOOGLE_LOG(WARNING) << "Invalid message set extension.";
+ return InternalSerializeFieldWithCachedSizesToArray(extendee, extension_set,
+ number, target, stream);
+ }
+
+ if (is_cleared) return target;
+
+ target = stream->EnsureSpace(target);
+ // Start group.
+ target = io::CodedOutputStream::WriteTagToArray(
+ WireFormatLite::kMessageSetItemStartTag, target);
+ // Write type ID.
+ target = WireFormatLite::WriteUInt32ToArray(
+ WireFormatLite::kMessageSetTypeIdNumber, number, target);
+ // Write message.
+ if (is_lazy) {
+ const auto* prototype =
+ extension_set->GetPrototypeForLazyMessage(extendee, number);
+ target = lazymessage_value->WriteMessageToArray(
+ prototype, WireFormatLite::kMessageSetMessageNumber, target, stream);
+ } else {
+ target = WireFormatLite::InternalWriteMessage(
+ WireFormatLite::kMessageSetMessageNumber, *message_value, target,
+ stream);
+ }
+ // End group.
+ target = stream->EnsureSpace(target);
+ target = io::CodedOutputStream::WriteTagToArray(
+ WireFormatLite::kMessageSetItemEndTag, target);
+ return target;
+}
+
+size_t ExtensionSet::Extension::MessageSetItemByteSize(int number) const {
+ if (type != WireFormatLite::TYPE_MESSAGE || is_repeated) {
+ // Not a valid MessageSet extension, but compute the byte size for it the
+ // normal way.
+ return ByteSize(number);
+ }
+
+ if (is_cleared) return 0;
+
+ size_t our_size = WireFormatLite::kMessageSetItemTagsSize;
+
+ // type_id
+ our_size += io::CodedOutputStream::VarintSize32(number);
+
+ // message
+ size_t message_size = 0;
+ if (is_lazy) {
+ message_size = lazymessage_value->ByteSizeLong();
+ } else {
+ message_size = message_value->ByteSizeLong();
+ }
+
+ our_size += io::CodedOutputStream::VarintSize32(message_size);
+ our_size += message_size;
+
+ return our_size;
+}
+
+size_t ExtensionSet::MessageSetByteSize() const {
+ size_t total_size = 0;
+ ForEach([&total_size](int number, const Extension& ext) {
+ total_size += ext.MessageSetItemByteSize(number);
+ });
+ return total_size;
+}
+
+
+} // namespace internal
+} // namespace protobuf
+} // namespace google
+
+#include <port_undef.inc>
diff --git a/NorthstarDedicatedTest/include/protobuf/extension_set.h b/NorthstarDedicatedTest/include/protobuf/extension_set.h
new file mode 100644
index 00000000..a7159916
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/extension_set.h
@@ -0,0 +1,1560 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// This header is logically internal, but is made public because it is used
+// from protocol-compiler-generated code, which may reside in other components.
+
+#ifndef GOOGLE_PROTOBUF_EXTENSION_SET_H__
+#define GOOGLE_PROTOBUF_EXTENSION_SET_H__
+
+#include <algorithm>
+#include <cassert>
+#include <map>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include <stubs/common.h>
+#include <stubs/logging.h>
+#include <parse_context.h>
+#include <io/coded_stream.h>
+#include <port.h>
+#include <repeated_field.h>
+#include <wire_format_lite.h>
+
+// clang-format off
+#include <port_def.inc> // Must be last
+// clang-format on
+
+#ifdef SWIG
+#error "You cannot SWIG proto headers"
+#endif
+
+namespace google {
+namespace protobuf {
+class Arena;
+class Descriptor; // descriptor.h
+class FieldDescriptor; // descriptor.h
+class DescriptorPool; // descriptor.h
+class MessageLite; // message_lite.h
+class Message; // message.h
+class MessageFactory; // message.h
+class Reflection; // message.h
+class UnknownFieldSet; // unknown_field_set.h
+namespace internal {
+class FieldSkipper; // wire_format_lite.h
+} // namespace internal
+} // namespace protobuf
+} // namespace google
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+class InternalMetadata;
+
+// Used to store values of type WireFormatLite::FieldType without having to
+// #include wire_format_lite.h. Also, ensures that we use only one byte to
+// store these values, which is important to keep the layout of
+// ExtensionSet::Extension small.
+typedef uint8_t FieldType;
+
+// A function which, given an integer value, returns true if the number
+// matches one of the defined values for the corresponding enum type. This
+// is used with RegisterEnumExtension, below.
+typedef bool EnumValidityFunc(int number);
+
+// Version of the above which takes an argument. This is needed to deal with
+// extensions that are not compiled in.
+typedef bool EnumValidityFuncWithArg(const void* arg, int number);
+
+// Information about a registered extension.
+struct ExtensionInfo {
+ constexpr ExtensionInfo() : enum_validity_check() {}
+ constexpr ExtensionInfo(const MessageLite* extendee, int param_number,
+ FieldType type_param, bool isrepeated, bool ispacked)
+ : message(extendee),
+ number(param_number),
+ type(type_param),
+ is_repeated(isrepeated),
+ is_packed(ispacked),
+ enum_validity_check() {}
+
+ const MessageLite* message = nullptr;
+ int number = 0;
+
+ FieldType type = 0;
+ bool is_repeated = false;
+ bool is_packed = false;
+
+ struct EnumValidityCheck {
+ EnumValidityFuncWithArg* func;
+ const void* arg;
+ };
+
+ struct MessageInfo {
+ const MessageLite* prototype;
+ };
+
+ union {
+ EnumValidityCheck enum_validity_check;
+ MessageInfo message_info;
+ };
+
+ // The descriptor for this extension, if one exists and is known. May be
+ // nullptr. Must not be nullptr if the descriptor for the extension does not
+ // live in the same pool as the descriptor for the containing type.
+ const FieldDescriptor* descriptor = nullptr;
+};
+
+// Abstract interface for an object which looks up extension definitions. Used
+// when parsing.
+class PROTOBUF_EXPORT ExtensionFinder {
+ public:
+ virtual ~ExtensionFinder();
+
+ // Find the extension with the given containing type and number.
+ virtual bool Find(int number, ExtensionInfo* output) = 0;
+};
+
+// Implementation of ExtensionFinder which finds extensions defined in .proto
+// files which have been compiled into the binary.
+class PROTOBUF_EXPORT GeneratedExtensionFinder : public ExtensionFinder {
+ public:
+ explicit GeneratedExtensionFinder(const MessageLite* extendee)
+ : extendee_(extendee) {}
+ ~GeneratedExtensionFinder() override {}
+
+ // Returns true and fills in *output if found, otherwise returns false.
+ bool Find(int number, ExtensionInfo* output) override;
+
+ private:
+ const MessageLite* extendee_;
+};
+
+// A FieldSkipper used for parsing MessageSet.
+class MessageSetFieldSkipper;
+
+// Note: extension_set_heavy.cc defines DescriptorPoolExtensionFinder for
+// finding extensions from a DescriptorPool.
+
+// This is an internal helper class intended for use within the protocol buffer
+// library and generated classes. Clients should not use it directly. Instead,
+// use the generated accessors such as GetExtension() of the class being
+// extended.
+//
+// This class manages extensions for a protocol message object. The
+// message's HasExtension(), GetExtension(), MutableExtension(), and
+// ClearExtension() methods are just thin wrappers around the embedded
+// ExtensionSet. When parsing, if a tag number is encountered which is
+// inside one of the message type's extension ranges, the tag is passed
+// off to the ExtensionSet for parsing. Etc.
+class PROTOBUF_EXPORT ExtensionSet {
+ public:
+ constexpr ExtensionSet();
+ explicit ExtensionSet(Arena* arena);
+ ~ExtensionSet();
+
+ // These are called at startup by protocol-compiler-generated code to
+ // register known extensions. The registrations are used by ParseField()
+ // to look up extensions for parsed field numbers. Note that dynamic parsing
+ // does not use ParseField(); only protocol-compiler-generated parsing
+ // methods do.
+ static void RegisterExtension(const MessageLite* extendee, int number,
+ FieldType type, bool is_repeated,
+ bool is_packed);
+ static void RegisterEnumExtension(const MessageLite* extendee, int number,
+ FieldType type, bool is_repeated,
+ bool is_packed, EnumValidityFunc* is_valid);
+ static void RegisterMessageExtension(const MessageLite* extendee, int number,
+ FieldType type, bool is_repeated,
+ bool is_packed,
+ const MessageLite* prototype);
+
+ // =================================================================
+
+ // Add all fields which are currently present to the given vector. This
+ // is useful to implement Reflection::ListFields().
+ void AppendToList(const Descriptor* extendee, const DescriptorPool* pool,
+ std::vector<const FieldDescriptor*>* output) const;
+
+ // =================================================================
+ // Accessors
+ //
+ // Generated message classes include type-safe templated wrappers around
+ // these methods. Generally you should use those rather than call these
+ // directly, unless you are doing low-level memory management.
+ //
+ // When calling any of these accessors, the extension number requested
+ // MUST exist in the DescriptorPool provided to the constructor. Otherwise,
+ // the method will fail an assert. Normally, though, you would not call
+ // these directly; you would either call the generated accessors of your
+ // message class (e.g. GetExtension()) or you would call the accessors
+ // of the reflection interface. In both cases, it is impossible to
+ // trigger this assert failure: the generated accessors only accept
+ // linked-in extension types as parameters, while the Reflection interface
+ // requires you to provide the FieldDescriptor describing the extension.
+ //
+ // When calling any of these accessors, a protocol-compiler-generated
+ // implementation of the extension corresponding to the number MUST
+ // be linked in, and the FieldDescriptor used to refer to it MUST be
+ // the one generated by that linked-in code. Otherwise, the method will
+ // die on an assert failure. The message objects returned by the message
+ // accessors are guaranteed to be of the correct linked-in type.
+ //
+ // These methods pretty much match Reflection except that:
+ // - They're not virtual.
+ // - They identify fields by number rather than FieldDescriptors.
+ // - They identify enum values using integers rather than descriptors.
+ // - Strings provide Mutable() in addition to Set() accessors.
+
+ bool Has(int number) const;
+ int ExtensionSize(int number) const; // Size of a repeated extension.
+ int NumExtensions() const; // The number of extensions
+ FieldType ExtensionType(int number) const;
+ void ClearExtension(int number);
+
+ // singular fields -------------------------------------------------
+
+ 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);
+
+ // -----------------------------------------------------------------
+ // TODO(kenton): Hardcore memory management accessors
+
+ // =================================================================
+ // convenience methods for implementing methods of Message
+ //
+ // These could all be implemented in terms of the other methods of this
+ // class, but providing them here helps keep the generated code size down.
+
+ void Clear();
+ void MergeFrom(const MessageLite* extendee, const ExtensionSet& other);
+ void Swap(const MessageLite* extendee, ExtensionSet* other);
+ void InternalSwap(ExtensionSet* other);
+ void SwapExtension(const MessageLite* extendee, ExtensionSet* other,
+ int number);
+ void UnsafeShallowSwapExtension(ExtensionSet* other, int number);
+ bool IsInitialized() const;
+
+ // Parses a single extension from the input. The input should start out
+ // positioned immediately after the tag.
+ bool ParseField(uint32_t tag, io::CodedInputStream* input,
+ ExtensionFinder* extension_finder,
+ FieldSkipper* field_skipper);
+
+ // Specific versions for lite or full messages (constructs the appropriate
+ // FieldSkipper automatically). |extendee| is the default
+ // instance for the containing message; it is used only to look up the
+ // extension by number. See RegisterExtension(), above. Unlike the other
+ // methods of ExtensionSet, this only works for generated message types --
+ // it looks up extensions registered using RegisterExtension().
+ bool ParseField(uint32_t tag, io::CodedInputStream* input,
+ const MessageLite* extendee);
+ bool ParseField(uint32_t tag, io::CodedInputStream* input,
+ const Message* extendee, UnknownFieldSet* unknown_fields);
+ bool ParseField(uint32_t tag, io::CodedInputStream* input,
+ const MessageLite* extendee,
+ io::CodedOutputStream* unknown_fields);
+
+ // 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;
+ }
+
+ // Parse an entire message in MessageSet format. Such messages have no
+ // fields, only extensions.
+ bool ParseMessageSetLite(io::CodedInputStream* input,
+ ExtensionFinder* extension_finder,
+ FieldSkipper* field_skipper);
+ bool ParseMessageSet(io::CodedInputStream* input,
+ ExtensionFinder* extension_finder,
+ MessageSetFieldSkipper* field_skipper);
+
+ // Specific versions for lite or full messages (constructs the appropriate
+ // FieldSkipper automatically).
+ bool ParseMessageSet(io::CodedInputStream* input, const MessageLite* extendee,
+ std::string* unknown_fields);
+ bool ParseMessageSet(io::CodedInputStream* input, const Message* extendee,
+ UnknownFieldSet* unknown_fields);
+
+ // Write all extension fields with field numbers in the range
+ // [start_field_number, end_field_number)
+ // to the output stream, using the cached sizes computed when ByteSize() was
+ // last called. Note that the range bounds are inclusive-exclusive.
+ void SerializeWithCachedSizes(const MessageLite* extendee,
+ int start_field_number, int end_field_number,
+ io::CodedOutputStream* output) const {
+ output->SetCur(_InternalSerialize(extendee, start_field_number,
+ end_field_number, output->Cur(),
+ output->EpsCopy()));
+ }
+
+ // Same as SerializeWithCachedSizes, but without any bounds checking.
+ // The caller must ensure that target has sufficient capacity for the
+ // serialized extensions.
+ //
+ // Returns a pointer past the last written byte.
+
+ uint8_t* _InternalSerialize(const MessageLite* extendee,
+ int start_field_number, int end_field_number,
+ uint8_t* target,
+ io::EpsCopyOutputStream* stream) const {
+ if (flat_size_ == 0) {
+ assert(!is_large());
+ return target;
+ }
+ return _InternalSerializeImpl(extendee, start_field_number,
+ end_field_number, target, stream);
+ }
+
+ // Like above but serializes in MessageSet format.
+ void SerializeMessageSetWithCachedSizes(const MessageLite* extendee,
+ io::CodedOutputStream* output) const {
+ output->SetCur(InternalSerializeMessageSetWithCachedSizesToArray(
+ extendee, output->Cur(), output->EpsCopy()));
+ }
+ uint8_t* InternalSerializeMessageSetWithCachedSizesToArray(
+ const MessageLite* extendee, uint8_t* target,
+ io::EpsCopyOutputStream* stream) const;
+
+ // For backward-compatibility, versions of two of the above methods that
+ // serialize deterministically iff SetDefaultSerializationDeterministic()
+ // has been called.
+ uint8_t* SerializeWithCachedSizesToArray(int start_field_number,
+ int end_field_number,
+ uint8_t* target) const;
+ uint8_t* SerializeMessageSetWithCachedSizesToArray(
+ const MessageLite* extendee, uint8_t* target) const;
+
+ // Returns the total serialized size of all the extensions.
+ size_t ByteSize() const;
+
+ // Like ByteSize() but uses MessageSet format.
+ size_t MessageSetByteSize() const;
+
+ // Returns (an estimate of) the total number of bytes used for storing the
+ // extensions in memory, excluding sizeof(*this). If the ExtensionSet is
+ // for a lite message (and thus possibly contains lite messages), the results
+ // are undefined (might work, might crash, might corrupt data, might not even
+ // be linked in). It's up to the protocol compiler to avoid calling this on
+ // such ExtensionSets (easy enough since lite messages don't implement
+ // SpaceUsed()).
+ size_t SpaceUsedExcludingSelfLong() const;
+
+ // This method just calls SpaceUsedExcludingSelfLong() but it can not be
+ // inlined because the definition of SpaceUsedExcludingSelfLong() is not
+ // included in lite runtime and when an inline method refers to it MSVC
+ // will complain about unresolved symbols when building the lite runtime
+ // as .dll.
+ int SpaceUsedExcludingSelf() const;
+
+ private:
+ template <typename Type>
+ friend class PrimitiveTypeTraits;
+
+ template <typename Type>
+ friend class RepeatedPrimitiveTypeTraits;
+
+ template <typename Type, bool IsValid(int)>
+ friend class EnumTypeTraits;
+
+ template <typename Type, bool IsValid(int)>
+ friend class RepeatedEnumTypeTraits;
+
+ friend class google::protobuf::Reflection;
+
+ const 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 bool ReadMessage(const MessageLite& prototype,
+ io::CodedInputStream* input) = 0;
+ virtual const char* _InternalParse(const Message& prototype, Arena* arena,
+ const char* ptr, ParseContext* ctx) = 0;
+ virtual uint8_t* WriteMessageToArray(
+ const MessageLite* prototype, int number, uint8_t* target,
+ io::EpsCopyOutputStream* stream) const = 0;
+
+ private:
+ virtual void UnusedKeyMethod(); // Dummy key method to avoid weak vtable.
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(LazyMessageExtension);
+ };
+ // Give access to function defined below to see LazyMessageExtension.
+ friend LazyMessageExtension* MaybeCreateLazyExtension(Arena* arena);
+ struct Extension {
+ // The order of these fields packs Extension into 24 bytes when using 8
+ // byte alignment. Consider this when adding or removing fields here.
+ union {
+ 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);
+
+ // Returns true and fills field_number and extension if extension is found.
+ // Note to support packed repeated field compatibility, it also fills whether
+ // the tag on wire is packed, which can be different from
+ // extension->is_packed (whether packed=true is specified).
+ bool FindExtensionInfoFromTag(uint32_t tag, ExtensionFinder* extension_finder,
+ int* field_number, ExtensionInfo* extension,
+ bool* was_packed_on_wire);
+
+ // Returns true and fills extension if extension is found.
+ // Note to support packed repeated field compatibility, it also fills whether
+ // the tag on wire is packed, which can be different from
+ // extension->is_packed (whether packed=true is specified).
+ bool FindExtensionInfoFromFieldNumber(int wire_type, int field_number,
+ ExtensionFinder* extension_finder,
+ ExtensionInfo* extension,
+ bool* was_packed_on_wire) const;
+
+ // Find the prototype for a LazyMessage from the extension registry. Returns
+ // null if the extension is not found.
+ const MessageLite* GetPrototypeForLazyMessage(const MessageLite* extendee,
+ int number) const;
+
+ // Parses a single extension from the input. The input should start out
+ // positioned immediately after the wire tag. This method is called in
+ // ParseField() after field number and was_packed_on_wire is extracted from
+ // the wire tag and ExtensionInfo is found by the field number.
+ bool ParseFieldWithExtensionInfo(int field_number, bool was_packed_on_wire,
+ const ExtensionInfo& extension,
+ io::CodedInputStream* input,
+ FieldSkipper* field_skipper);
+
+ // Like ParseField(), but this method may parse singular message extensions
+ // lazily depending on the value of FLAGS_eagerly_parse_message_sets.
+ bool ParseFieldMaybeLazily(int wire_type, int field_number,
+ io::CodedInputStream* input,
+ ExtensionFinder* extension_finder,
+ MessageSetFieldSkipper* field_skipper);
+
+ // Returns true if extension is present and lazy.
+ bool HasLazy(int number) const;
+
+ // Gets the extension with the given number, creating it if it does not
+ // already exist. Returns true if the extension did not already exist.
+ bool MaybeNewExtension(int number, const FieldDescriptor* descriptor,
+ Extension** result);
+
+ // Gets the repeated extension for the given descriptor, creating it if
+ // it does not exist.
+ Extension* MaybeNewRepeatedExtension(const FieldDescriptor* descriptor);
+
+ // Parse a single MessageSet item -- called just after the item group start
+ // tag has been read.
+ bool ParseMessageSetItemLite(io::CodedInputStream* input,
+ ExtensionFinder* extension_finder,
+ FieldSkipper* field_skipper);
+ // Parse a single MessageSet item -- called just after the item group start
+ // tag has been read.
+ bool ParseMessageSetItem(io::CodedInputStream* input,
+ ExtensionFinder* extension_finder,
+ MessageSetFieldSkipper* field_skipper);
+
+ bool FindExtension(int wire_type, 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) {
+ ExtensionSet::RegisterExtension(&ExtendeeT::default_instance(), number,
+ type, false, is_packed);
+ }
+};
+
+template <typename Type>
+class RepeatedPrimitiveTypeTraits {
+ public:
+ typedef Type ConstType;
+ typedef Type MutableType;
+ typedef RepeatedPrimitiveTypeTraits<Type> Repeated;
+
+ typedef RepeatedField<Type> RepeatedFieldType;
+
+ static inline Type Get(int number, const ExtensionSet& set, int index);
+ static inline const Type* GetPtr(int number, const ExtensionSet& set,
+ int index);
+ static inline const RepeatedField<ConstType>* GetRepeatedPtr(
+ int number, const ExtensionSet& set);
+ static inline void Set(int number, int index, Type value, ExtensionSet* set);
+ static inline void Add(int number, FieldType field_type, bool is_packed,
+ Type value, ExtensionSet* set);
+
+ static inline const RepeatedField<ConstType>& GetRepeated(
+ int number, const ExtensionSet& set);
+ static inline RepeatedField<Type>* MutableRepeated(int number,
+ FieldType field_type,
+ bool is_packed,
+ ExtensionSet* set);
+
+ static const RepeatedFieldType* GetDefaultRepeatedField();
+ template <typename ExtendeeT>
+ static void Register(int number, FieldType type, bool is_packed) {
+ ExtensionSet::RegisterExtension(&ExtendeeT::default_instance(), number,
+ type, true, is_packed);
+ }
+};
+
+class PROTOBUF_EXPORT RepeatedPrimitiveDefaults {
+ private:
+ template <typename Type>
+ friend class RepeatedPrimitiveTypeTraits;
+ static const RepeatedPrimitiveDefaults* default_instance();
+ RepeatedField<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) {
+ ExtensionSet::RegisterExtension(&ExtendeeT::default_instance(), number,
+ type, false, is_packed);
+ }
+};
+
+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) {
+ ExtensionSet::RegisterExtension(&ExtendeeT::default_instance(), number,
+ type, true, is_packed);
+ }
+
+ private:
+ static void InitializeDefaultRepeatedFields();
+ static void DestroyDefaultRepeatedFields();
+};
+
+// -------------------------------------------------------------------
+// EnumTypeTraits
+
+// ExtensionSet represents enums using integers internally, so we have to
+// static_cast around.
+template <typename Type, bool IsValid(int)>
+class EnumTypeTraits {
+ public:
+ typedef Type ConstType;
+ typedef Type MutableType;
+ typedef EnumTypeTraits<Type, IsValid> Singular;
+
+ static inline ConstType Get(int number, const ExtensionSet& set,
+ ConstType default_value) {
+ return static_cast<Type>(set.GetEnum(number, default_value));
+ }
+ static inline const ConstType* GetPtr(int number, const ExtensionSet& set,
+ const ConstType& default_value) {
+ return reinterpret_cast<const Type*>(
+ &set.GetRefEnum(number, default_value));
+ }
+ static inline void Set(int number, FieldType field_type, ConstType value,
+ ExtensionSet* set) {
+ GOOGLE_DCHECK(IsValid(value));
+ set->SetEnum(number, field_type, value, nullptr);
+ }
+ template <typename ExtendeeT>
+ static void Register(int number, FieldType type, bool is_packed) {
+ ExtensionSet::RegisterEnumExtension(&ExtendeeT::default_instance(), number,
+ type, false, is_packed, IsValid);
+ }
+};
+
+template <typename Type, bool IsValid(int)>
+class RepeatedEnumTypeTraits {
+ public:
+ typedef Type ConstType;
+ typedef Type MutableType;
+ typedef RepeatedEnumTypeTraits<Type, IsValid> Repeated;
+
+ typedef RepeatedField<Type> RepeatedFieldType;
+
+ static inline ConstType Get(int number, const ExtensionSet& set, int index) {
+ return static_cast<Type>(set.GetRepeatedEnum(number, index));
+ }
+ static inline const ConstType* GetPtr(int number, const ExtensionSet& set,
+ int index) {
+ return reinterpret_cast<const Type*>(
+ &set.GetRefRepeatedEnum(number, index));
+ }
+ static inline void Set(int number, int index, ConstType value,
+ ExtensionSet* set) {
+ GOOGLE_DCHECK(IsValid(value));
+ set->SetRepeatedEnum(number, index, value);
+ }
+ static inline void Add(int number, FieldType field_type, bool is_packed,
+ ConstType value, ExtensionSet* set) {
+ GOOGLE_DCHECK(IsValid(value));
+ set->AddEnum(number, field_type, is_packed, value, nullptr);
+ }
+ static inline const RepeatedField<Type>& GetRepeated(
+ int number, const ExtensionSet& set) {
+ // Hack: the `Extension` struct stores a RepeatedField<int> for enums.
+ // RepeatedField<int> cannot implicitly convert to RepeatedField<EnumType>
+ // so we need to do some casting magic. See message.h for similar
+ // contortions for non-extension fields.
+ return *reinterpret_cast<const RepeatedField<Type>*>(
+ set.GetRawRepeatedField(number, GetDefaultRepeatedField()));
+ }
+ static inline const RepeatedField<Type>* GetRepeatedPtr(
+ int number, const ExtensionSet& set) {
+ return &GetRepeated(number, set);
+ }
+ static inline RepeatedField<Type>* MutableRepeated(int number,
+ FieldType field_type,
+ bool is_packed,
+ ExtensionSet* set) {
+ return reinterpret_cast<RepeatedField<Type>*>(
+ set->MutableRawRepeatedField(number, field_type, is_packed, nullptr));
+ }
+
+ static const RepeatedFieldType* GetDefaultRepeatedField() {
+ // Hack: as noted above, repeated enum fields are internally stored as a
+ // RepeatedField<int>. We need to be able to instantiate global static
+ // objects to return as default (empty) repeated fields on non-existent
+ // extensions. We would not be able to know a-priori all of the enum types
+ // (values of |Type|) to instantiate all of these, so we just re-use
+ // 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) {
+ ExtensionSet::RegisterEnumExtension(&ExtendeeT::default_instance(), number,
+ type, true, is_packed, IsValid);
+ }
+};
+
+// -------------------------------------------------------------------
+// MessageTypeTraits
+
+// ExtensionSet guarantees that when manipulating extensions with message
+// types, the implementation used will be the compiled-in class representing
+// that type. So, we can static_cast down to the exact type we expect.
+template <typename Type>
+class MessageTypeTraits {
+ public:
+ typedef const Type& ConstType;
+ typedef Type* MutableType;
+ typedef MessageTypeTraits<Type> Singular;
+
+ static inline ConstType Get(int number, const ExtensionSet& set,
+ ConstType default_value) {
+ return static_cast<const Type&>(set.GetMessage(number, default_value));
+ }
+ static inline std::nullptr_t GetPtr(int /* number */, const ExtensionSet& /* set */,
+ ConstType /* default_value */) {
+ // Cannot be implemented because of forward declared messages?
+ return nullptr;
+ }
+ static inline MutableType Mutable(int number, FieldType field_type,
+ ExtensionSet* set) {
+ return static_cast<Type*>(set->MutableMessage(
+ number, field_type, Type::default_instance(), nullptr));
+ }
+ static inline void SetAllocated(int number, FieldType field_type,
+ MutableType message, ExtensionSet* set) {
+ set->SetAllocatedMessage(number, field_type, nullptr, message);
+ }
+ static inline void UnsafeArenaSetAllocated(int number, FieldType field_type,
+ MutableType message,
+ ExtensionSet* set) {
+ set->UnsafeArenaSetAllocatedMessage(number, field_type, nullptr, message);
+ }
+ PROTOBUF_NODISCARD static inline MutableType Release(
+ int number, FieldType /* field_type */, ExtensionSet* set) {
+ return static_cast<Type*>(
+ set->ReleaseMessage(number, Type::default_instance()));
+ }
+ static inline MutableType UnsafeArenaRelease(int number,
+ FieldType /* field_type */,
+ ExtensionSet* set) {
+ return static_cast<Type*>(
+ set->UnsafeArenaReleaseMessage(number, Type::default_instance()));
+ }
+ template <typename ExtendeeT>
+ static void Register(int number, FieldType type, bool is_packed) {
+ ExtensionSet::RegisterMessageExtension(&ExtendeeT::default_instance(),
+ number, type, false, is_packed,
+ &Type::default_instance());
+ }
+};
+
+// forward declaration.
+class RepeatedMessageGenericTypeTraits;
+
+template <typename Type>
+class RepeatedMessageTypeTraits {
+ public:
+ typedef const Type& ConstType;
+ typedef Type* MutableType;
+ typedef RepeatedMessageTypeTraits<Type> Repeated;
+
+ typedef RepeatedPtrField<Type> RepeatedFieldType;
+
+ static inline ConstType Get(int number, const ExtensionSet& set, int index) {
+ return static_cast<const Type&>(set.GetRepeatedMessage(number, index));
+ }
+ static inline std::nullptr_t GetPtr(int /* number */, const ExtensionSet& /* set */,
+ int /* index */) {
+ // Cannot be implemented because of forward declared messages?
+ return nullptr;
+ }
+ static inline std::nullptr_t GetRepeatedPtr(int /* number */,
+ const ExtensionSet& /* set */) {
+ // Cannot be implemented because of forward declared messages?
+ return nullptr;
+ }
+ static inline MutableType Mutable(int number, int index, ExtensionSet* set) {
+ return static_cast<Type*>(set->MutableRepeatedMessage(number, index));
+ }
+ static inline MutableType Add(int number, FieldType field_type,
+ ExtensionSet* set) {
+ return static_cast<Type*>(
+ set->AddMessage(number, field_type, Type::default_instance(), nullptr));
+ }
+ static inline const RepeatedPtrField<Type>& GetRepeated(
+ int number, const ExtensionSet& set) {
+ // See notes above in RepeatedEnumTypeTraits::GetRepeated(): same
+ // casting hack applies here, because a RepeatedPtrField<MessageLite>
+ // cannot naturally become a RepeatedPtrType<Type> even though Type is
+ // presumably a message. google::protobuf::Message goes through similar contortions
+ // with a reinterpret_cast<>.
+ return *reinterpret_cast<const RepeatedPtrField<Type>*>(
+ set.GetRawRepeatedField(number, GetDefaultRepeatedField()));
+ }
+ static inline RepeatedPtrField<Type>* MutableRepeated(int number,
+ FieldType field_type,
+ bool is_packed,
+ ExtensionSet* set) {
+ return reinterpret_cast<RepeatedPtrField<Type>*>(
+ set->MutableRawRepeatedField(number, field_type, is_packed, nullptr));
+ }
+
+ static const RepeatedFieldType* GetDefaultRepeatedField();
+ template <typename ExtendeeT>
+ static void Register(int number, FieldType type, bool is_packed) {
+ ExtensionSet::RegisterMessageExtension(&ExtendeeT::default_instance(),
+ number, type, true, is_packed,
+ &Type::default_instance());
+ }
+};
+
+template <typename Type>
+inline const typename RepeatedMessageTypeTraits<Type>::RepeatedFieldType*
+RepeatedMessageTypeTraits<Type>::GetDefaultRepeatedField() {
+ static auto instance = OnShutdownDelete(new RepeatedFieldType);
+ return instance;
+}
+
+// -------------------------------------------------------------------
+// ExtensionIdentifier
+
+// This is the type of actual extension objects. E.g. if you have:
+// extend Foo {
+// optional int32 bar = 1234;
+// }
+// then "bar" will be defined in C++ as:
+// ExtensionIdentifier<Foo, PrimitiveTypeTraits<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)
+ : number_(number), default_value_(default_value) {
+ Register(number);
+ }
+ inline int number() const { return number_; }
+ typename TypeTraits::ConstType default_value() const {
+ return default_value_;
+ }
+
+ static void Register(int number) {
+ TypeTraits::template Register<ExtendeeType>(number, field_type, is_packed);
+ }
+
+ typename TypeTraits::ConstType const& default_value_ref() const {
+ return default_value_;
+ }
+
+ private:
+ const int number_;
+ typename TypeTraits::ConstType default_value_;
+};
+
+// -------------------------------------------------------------------
+// Generated accessors
+
+
+// Used to retrieve a lazy extension, may return nullptr in some environments.
+extern PROTOBUF_ATTRIBUTE_WEAK ExtensionSet::LazyMessageExtension*
+MaybeCreateLazyExtension(Arena* arena);
+
+} // namespace internal
+
+// Call this function to ensure that this extensions's reflection is linked into
+// the binary:
+//
+// google::protobuf::LinkExtensionReflection(Foo::my_extension);
+//
+// This will ensure that the following lookup will succeed:
+//
+// DescriptorPool::generated_pool()->FindExtensionByName("Foo.my_extension");
+//
+// This is often relevant for parsing extensions in text mode.
+//
+// As a side-effect, it will also guarantee that anything else from the same
+// .proto file will also be available for lookup in the generated pool.
+//
+// This function does not actually register the extension, so it does not need
+// to be called before the lookup. However it does need to occur in a function
+// that cannot be stripped from the binary (ie. it must be reachable from main).
+//
+// Best practice is to call this function as close as possible to where the
+// reflection is actually needed. This function is very cheap to call, so you
+// should not need to worry about its runtime overhead except in tight loops (on
+// x86-64 it compiles into two "mov" instructions).
+template <typename ExtendeeType, typename TypeTraitsType,
+ internal::FieldType field_type, bool is_packed>
+void LinkExtensionReflection(
+ const google::protobuf::internal::ExtensionIdentifier<
+ ExtendeeType, TypeTraitsType, field_type, is_packed>& extension) {
+ internal::StrongReference(extension);
+}
+
+} // namespace protobuf
+} // namespace google
+
+#include <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_EXTENSION_SET_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/extension_set_heavy.cc b/NorthstarDedicatedTest/include/protobuf/extension_set_heavy.cc
new file mode 100644
index 00000000..21e64bcc
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/extension_set_heavy.cc
@@ -0,0 +1,546 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// Contains methods defined in extension_set.h which cannot be part of the
+// lite library because they use descriptors or reflection.
+
+#include <stubs/casts.h>
+#include <descriptor.pb.h>
+#include <extension_set_inl.h>
+#include <parse_context.h>
+#include <io/coded_stream.h>
+#include <arena.h>
+#include <descriptor.h>
+#include <extension_set.h>
+#include <message.h>
+#include <message_lite.h>
+#include <repeated_field.h>
+#include <unknown_field_set.h>
+#include <wire_format.h>
+#include <wire_format_lite.h>
+
+
+#include <port_def.inc>
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+// A FieldSkipper used to store unknown MessageSet fields into UnknownFieldSet.
+class MessageSetFieldSkipper : public UnknownFieldSetFieldSkipper {
+ public:
+ explicit MessageSetFieldSkipper(UnknownFieldSet* unknown_fields)
+ : UnknownFieldSetFieldSkipper(unknown_fields) {}
+ ~MessageSetFieldSkipper() override {}
+
+ virtual bool SkipMessageSetField(io::CodedInputStream* input,
+ int field_number);
+};
+bool MessageSetFieldSkipper::SkipMessageSetField(io::CodedInputStream* input,
+ int field_number) {
+ uint32_t length;
+ if (!input->ReadVarint32(&length)) return false;
+ if (unknown_fields_ == nullptr) {
+ return input->Skip(length);
+ } else {
+ return input->ReadString(unknown_fields_->AddLengthDelimited(field_number),
+ length);
+ }
+}
+
+
+// Implementation of ExtensionFinder which finds extensions in a given
+// DescriptorPool, using the given MessageFactory to construct sub-objects.
+// This class is implemented in extension_set_heavy.cc.
+class DescriptorPoolExtensionFinder : public ExtensionFinder {
+ public:
+ DescriptorPoolExtensionFinder(const DescriptorPool* pool,
+ MessageFactory* factory,
+ const Descriptor* containing_type)
+ : pool_(pool), factory_(factory), containing_type_(containing_type) {}
+ ~DescriptorPoolExtensionFinder() override {}
+
+ bool Find(int number, ExtensionInfo* output) override;
+
+ private:
+ const DescriptorPool* pool_;
+ MessageFactory* factory_;
+ const Descriptor* containing_type_;
+};
+
+void ExtensionSet::AppendToList(
+ const Descriptor* containing_type, const DescriptorPool* pool,
+ std::vector<const FieldDescriptor*>* output) const {
+ ForEach([containing_type, pool, &output](int number, const Extension& ext) {
+ bool has = false;
+ if (ext.is_repeated) {
+ has = ext.GetSize() > 0;
+ } else {
+ has = !ext.is_cleared;
+ }
+
+ if (has) {
+ // TODO(kenton): Looking up each field by number is somewhat unfortunate.
+ // Is there a better way? The problem is that descriptors are lazily-
+ // initialized, so they might not even be constructed until
+ // AppendToList() is called.
+
+ if (ext.descriptor == nullptr) {
+ output->push_back(pool->FindExtensionByNumber(containing_type, number));
+ } else {
+ output->push_back(ext.descriptor);
+ }
+ }
+ });
+}
+
+inline FieldDescriptor::Type real_type(FieldType type) {
+ GOOGLE_DCHECK(type > 0 && type <= FieldDescriptor::MAX_TYPE);
+ return static_cast<FieldDescriptor::Type>(type);
+}
+
+inline FieldDescriptor::CppType cpp_type(FieldType type) {
+ return FieldDescriptor::TypeToCppType(
+ static_cast<FieldDescriptor::Type>(type));
+}
+
+inline WireFormatLite::FieldType field_type(FieldType type) {
+ GOOGLE_DCHECK(type > 0 && type <= WireFormatLite::MAX_FIELD_TYPE);
+ return static_cast<WireFormatLite::FieldType>(type);
+}
+
+#define GOOGLE_DCHECK_TYPE(EXTENSION, LABEL, CPPTYPE) \
+ GOOGLE_DCHECK_EQ((EXTENSION).is_repeated ? FieldDescriptor::LABEL_REPEATED \
+ : FieldDescriptor::LABEL_OPTIONAL, \
+ FieldDescriptor::LABEL_##LABEL); \
+ GOOGLE_DCHECK_EQ(cpp_type((EXTENSION).type), FieldDescriptor::CPPTYPE_##CPPTYPE)
+
+const MessageLite& ExtensionSet::GetMessage(int number,
+ const Descriptor* message_type,
+ MessageFactory* factory) const {
+ const Extension* extension = FindOrNull(number);
+ if (extension == nullptr || extension->is_cleared) {
+ // Not present. Return the default value.
+ return *factory->GetPrototype(message_type);
+ } else {
+ GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, MESSAGE);
+ if (extension->is_lazy) {
+ return extension->lazymessage_value->GetMessage(
+ *factory->GetPrototype(message_type), arena_);
+ } else {
+ return *extension->message_value;
+ }
+ }
+}
+
+MessageLite* ExtensionSet::MutableMessage(const FieldDescriptor* descriptor,
+ MessageFactory* factory) {
+ Extension* extension;
+ if (MaybeNewExtension(descriptor->number(), descriptor, &extension)) {
+ extension->type = descriptor->type();
+ GOOGLE_DCHECK_EQ(cpp_type(extension->type), FieldDescriptor::CPPTYPE_MESSAGE);
+ extension->is_repeated = false;
+ extension->is_packed = false;
+ const MessageLite* prototype =
+ factory->GetPrototype(descriptor->message_type());
+ extension->is_lazy = false;
+ extension->message_value = prototype->New(arena_);
+ extension->is_cleared = false;
+ return extension->message_value;
+ } else {
+ GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, MESSAGE);
+ extension->is_cleared = false;
+ if (extension->is_lazy) {
+ return extension->lazymessage_value->MutableMessage(
+ *factory->GetPrototype(descriptor->message_type()), arena_);
+ } else {
+ return extension->message_value;
+ }
+ }
+}
+
+MessageLite* ExtensionSet::ReleaseMessage(const FieldDescriptor* descriptor,
+ MessageFactory* factory) {
+ Extension* extension = FindOrNull(descriptor->number());
+ if (extension == nullptr) {
+ // Not present. Return nullptr.
+ return nullptr;
+ } else {
+ GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, MESSAGE);
+ MessageLite* ret = nullptr;
+ if (extension->is_lazy) {
+ ret = extension->lazymessage_value->ReleaseMessage(
+ *factory->GetPrototype(descriptor->message_type()), arena_);
+ if (arena_ == nullptr) {
+ delete extension->lazymessage_value;
+ }
+ } else {
+ if (arena_ != nullptr) {
+ ret = extension->message_value->New();
+ ret->CheckTypeAndMergeFrom(*extension->message_value);
+ } else {
+ ret = extension->message_value;
+ }
+ }
+ Erase(descriptor->number());
+ return ret;
+ }
+}
+
+MessageLite* ExtensionSet::UnsafeArenaReleaseMessage(
+ const FieldDescriptor* descriptor, MessageFactory* factory) {
+ Extension* extension = FindOrNull(descriptor->number());
+ if (extension == nullptr) {
+ // Not present. Return nullptr.
+ return nullptr;
+ } else {
+ GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, MESSAGE);
+ MessageLite* ret = nullptr;
+ if (extension->is_lazy) {
+ ret = extension->lazymessage_value->UnsafeArenaReleaseMessage(
+ *factory->GetPrototype(descriptor->message_type()), arena_);
+ if (arena_ == nullptr) {
+ delete extension->lazymessage_value;
+ }
+ } else {
+ ret = extension->message_value;
+ }
+ Erase(descriptor->number());
+ return ret;
+ }
+}
+
+ExtensionSet::Extension* ExtensionSet::MaybeNewRepeatedExtension(
+ const FieldDescriptor* descriptor) {
+ Extension* extension;
+ if (MaybeNewExtension(descriptor->number(), descriptor, &extension)) {
+ extension->type = descriptor->type();
+ GOOGLE_DCHECK_EQ(cpp_type(extension->type), FieldDescriptor::CPPTYPE_MESSAGE);
+ extension->is_repeated = true;
+ extension->repeated_message_value =
+ Arena::CreateMessage<RepeatedPtrField<MessageLite> >(arena_);
+ } else {
+ GOOGLE_DCHECK_TYPE(*extension, REPEATED, MESSAGE);
+ }
+ return extension;
+}
+
+MessageLite* ExtensionSet::AddMessage(const FieldDescriptor* descriptor,
+ MessageFactory* factory) {
+ Extension* extension = MaybeNewRepeatedExtension(descriptor);
+
+ // RepeatedPtrField<Message> does not know how to Add() since it cannot
+ // allocate an abstract object, so we have to be tricky.
+ MessageLite* result =
+ reinterpret_cast<internal::RepeatedPtrFieldBase*>(
+ extension->repeated_message_value)
+ ->AddFromCleared<GenericTypeHandler<MessageLite> >();
+ if (result == nullptr) {
+ const MessageLite* prototype;
+ if (extension->repeated_message_value->empty()) {
+ prototype = factory->GetPrototype(descriptor->message_type());
+ GOOGLE_CHECK(prototype != nullptr);
+ } else {
+ prototype = &extension->repeated_message_value->Get(0);
+ }
+ result = prototype->New(arena_);
+ extension->repeated_message_value->AddAllocated(result);
+ }
+ return result;
+}
+
+void ExtensionSet::AddAllocatedMessage(const FieldDescriptor* descriptor,
+ MessageLite* new_entry) {
+ Extension* extension = MaybeNewRepeatedExtension(descriptor);
+
+ extension->repeated_message_value->AddAllocated(new_entry);
+}
+
+void ExtensionSet::UnsafeArenaAddAllocatedMessage(
+ const FieldDescriptor* descriptor, MessageLite* new_entry) {
+ Extension* extension = MaybeNewRepeatedExtension(descriptor);
+
+ extension->repeated_message_value->UnsafeArenaAddAllocated(new_entry);
+}
+
+static bool ValidateEnumUsingDescriptor(const void* arg, int number) {
+ return reinterpret_cast<const EnumDescriptor*>(arg)->FindValueByNumber(
+ number) != nullptr;
+}
+
+bool DescriptorPoolExtensionFinder::Find(int number, ExtensionInfo* output) {
+ const FieldDescriptor* extension =
+ pool_->FindExtensionByNumber(containing_type_, number);
+ if (extension == nullptr) {
+ return false;
+ } else {
+ output->type = extension->type();
+ output->is_repeated = extension->is_repeated();
+ output->is_packed = extension->options().packed();
+ output->descriptor = extension;
+ if (extension->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+ output->message_info.prototype =
+ factory_->GetPrototype(extension->message_type());
+ GOOGLE_CHECK(output->message_info.prototype != nullptr)
+ << "Extension factory's GetPrototype() returned nullptr; extension: "
+ << extension->full_name();
+ } else if (extension->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) {
+ output->enum_validity_check.func = ValidateEnumUsingDescriptor;
+ output->enum_validity_check.arg = extension->enum_type();
+ }
+
+ return true;
+ }
+}
+
+
+bool ExtensionSet::FindExtension(int wire_type, 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);
+}
+
+bool ExtensionSet::ParseField(uint32_t tag, io::CodedInputStream* input,
+ const Message* containing_type,
+ UnknownFieldSet* unknown_fields) {
+ UnknownFieldSetFieldSkipper skipper(unknown_fields);
+ if (input->GetExtensionPool() == nullptr) {
+ GeneratedExtensionFinder finder(containing_type);
+ return ParseField(tag, input, &finder, &skipper);
+ } else {
+ DescriptorPoolExtensionFinder finder(input->GetExtensionPool(),
+ input->GetExtensionFactory(),
+ containing_type->GetDescriptor());
+ return ParseField(tag, input, &finder, &skipper);
+ }
+}
+
+bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input,
+ const Message* containing_type,
+ UnknownFieldSet* unknown_fields) {
+ MessageSetFieldSkipper skipper(unknown_fields);
+ if (input->GetExtensionPool() == nullptr) {
+ GeneratedExtensionFinder finder(containing_type);
+ return ParseMessageSet(input, &finder, &skipper);
+ } else {
+ DescriptorPoolExtensionFinder finder(input->GetExtensionPool(),
+ input->GetExtensionFactory(),
+ containing_type->GetDescriptor());
+ return ParseMessageSet(input, &finder, &skipper);
+ }
+}
+
+int ExtensionSet::SpaceUsedExcludingSelf() const {
+ return internal::FromIntSize(SpaceUsedExcludingSelfLong());
+}
+
+size_t ExtensionSet::SpaceUsedExcludingSelfLong() const {
+ size_t total_size = Size() * sizeof(KeyValue);
+ ForEach([&total_size](int /* number */, const Extension& ext) {
+ total_size += ext.SpaceUsedExcludingSelfLong();
+ });
+ return total_size;
+}
+
+inline size_t ExtensionSet::RepeatedMessage_SpaceUsedExcludingSelfLong(
+ RepeatedPtrFieldBase* field) {
+ return field->SpaceUsedExcludingSelfLong<GenericTypeHandler<Message> >();
+}
+
+size_t ExtensionSet::Extension::SpaceUsedExcludingSelfLong() const {
+ size_t total_size = 0;
+ if (is_repeated) {
+ switch (cpp_type(type)) {
+#define HANDLE_TYPE(UPPERCASE, LOWERCASE) \
+ case FieldDescriptor::CPPTYPE_##UPPERCASE: \
+ total_size += sizeof(*repeated_##LOWERCASE##_value) + \
+ repeated_##LOWERCASE##_value->SpaceUsedExcludingSelfLong(); \
+ break
+
+ HANDLE_TYPE(INT32, 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);
+}
+
+bool ExtensionSet::ParseFieldMaybeLazily(
+ int wire_type, int field_number, io::CodedInputStream* input,
+ ExtensionFinder* extension_finder, MessageSetFieldSkipper* field_skipper) {
+ return ParseField(
+ WireFormatLite::MakeTag(field_number,
+ static_cast<WireFormatLite::WireType>(wire_type)),
+ input, extension_finder, field_skipper);
+}
+
+bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input,
+ ExtensionFinder* extension_finder,
+ MessageSetFieldSkipper* field_skipper) {
+ while (true) {
+ const uint32_t tag = input->ReadTag();
+ switch (tag) {
+ case 0:
+ return true;
+ case WireFormatLite::kMessageSetItemStartTag:
+ if (!ParseMessageSetItem(input, extension_finder, field_skipper)) {
+ return false;
+ }
+ break;
+ default:
+ if (!ParseField(tag, input, extension_finder, field_skipper)) {
+ return false;
+ }
+ break;
+ }
+ }
+}
+
+bool ExtensionSet::ParseMessageSetItem(io::CodedInputStream* input,
+ ExtensionFinder* extension_finder,
+ MessageSetFieldSkipper* field_skipper) {
+ struct MSFull {
+ bool ParseField(int type_id, io::CodedInputStream* input) {
+ return me->ParseFieldMaybeLazily(
+ WireFormatLite::WIRETYPE_LENGTH_DELIMITED, type_id, input,
+ extension_finder, field_skipper);
+ }
+
+ bool SkipField(uint32_t tag, io::CodedInputStream* input) {
+ return field_skipper->SkipField(input, tag);
+ }
+
+ ExtensionSet* me;
+ ExtensionFinder* extension_finder;
+ MessageSetFieldSkipper* field_skipper;
+ };
+
+ return ParseMessageSetItemImpl(input,
+ MSFull{this, extension_finder, field_skipper});
+}
+
+} // namespace internal
+} // namespace protobuf
+} // namespace google
+
+#include <port_undef.inc>
diff --git a/NorthstarDedicatedTest/include/protobuf/extension_set_inl.h b/NorthstarDedicatedTest/include/protobuf/extension_set_inl.h
new file mode 100644
index 00000000..b83064b4
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/extension_set_inl.h
@@ -0,0 +1,276 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef GOOGLE_PROTOBUF_EXTENSION_SET_INL_H__
+#define GOOGLE_PROTOBUF_EXTENSION_SET_INL_H__
+
+#include <parse_context.h>
+#include <extension_set.h>
+#include <metadata_lite.h>
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+template <typename T>
+const char* ExtensionSet::ParseFieldWithExtensionInfo(
+ int number, bool was_packed_on_wire, const ExtensionInfo& extension,
+ InternalMetadata* metadata, const char* ptr, internal::ParseContext* ctx) {
+ if (was_packed_on_wire) {
+ switch (extension.type) {
+#define HANDLE_TYPE(UPPERCASE, CPP_CAMELCASE) \
+ case WireFormatLite::TYPE_##UPPERCASE: \
+ return internal::Packed##CPP_CAMELCASE##Parser( \
+ MutableRawRepeatedField(number, extension.type, extension.is_packed, \
+ extension.descriptor), \
+ ptr, ctx);
+ HANDLE_TYPE(INT32, Int32);
+ HANDLE_TYPE(INT64, Int64);
+ HANDLE_TYPE(UINT32, UInt32);
+ HANDLE_TYPE(UINT64, UInt64);
+ HANDLE_TYPE(SINT32, SInt32);
+ HANDLE_TYPE(SINT64, SInt64);
+ HANDLE_TYPE(FIXED32, Fixed32);
+ HANDLE_TYPE(FIXED64, Fixed64);
+ HANDLE_TYPE(SFIXED32, SFixed32);
+ HANDLE_TYPE(SFIXED64, SFixed64);
+ HANDLE_TYPE(FLOAT, Float);
+ HANDLE_TYPE(DOUBLE, Double);
+ HANDLE_TYPE(BOOL, Bool);
+#undef HANDLE_TYPE
+
+ case WireFormatLite::TYPE_ENUM:
+ return internal::PackedEnumParserArg<T>(
+ MutableRawRepeatedField(number, extension.type, extension.is_packed,
+ extension.descriptor),
+ ptr, ctx, extension.enum_validity_check.func,
+ extension.enum_validity_check.arg, metadata, number);
+ case WireFormatLite::TYPE_STRING:
+ case WireFormatLite::TYPE_BYTES:
+ case WireFormatLite::TYPE_GROUP:
+ case WireFormatLite::TYPE_MESSAGE:
+ GOOGLE_LOG(FATAL) << "Non-primitive types can't be packed.";
+ break;
+ }
+ } else {
+ switch (extension.type) {
+#define HANDLE_VARINT_TYPE(UPPERCASE, CPP_CAMELCASE) \
+ case WireFormatLite::TYPE_##UPPERCASE: { \
+ 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 = 0;
+ bool payload_read = false;
+ 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);
+ type_id = tmp;
+ if (payload_read) {
+ ExtensionInfo extension;
+ bool was_packed_on_wire;
+ if (!FindExtension(2, type_id, extendee, ctx, &extension,
+ &was_packed_on_wire)) {
+ WriteLengthDelimited(type_id, payload,
+ metadata->mutable_unknown_fields<T>());
+ } else {
+ MessageLite* value =
+ extension.is_repeated
+ ? AddMessage(type_id, WireFormatLite::TYPE_MESSAGE,
+ *extension.message_info.prototype,
+ extension.descriptor)
+ : MutableMessage(type_id, WireFormatLite::TYPE_MESSAGE,
+ *extension.message_info.prototype,
+ extension.descriptor);
+
+ const char* p;
+ // We can't use regular parse from string as we have to track
+ // proper recursion depth and descriptor pools.
+ ParseContext tmp_ctx(ctx->depth(), false, &p, payload);
+ tmp_ctx.data().pool = ctx->data().pool;
+ tmp_ctx.data().factory = ctx->data().factory;
+ GOOGLE_PROTOBUF_PARSER_ASSERT(value->_InternalParse(p, &tmp_ctx) &&
+ tmp_ctx.EndedAtLimit());
+ }
+ type_id = 0;
+ }
+ } else if (tag == WireFormatLite::kMessageSetMessageTag) {
+ if (type_id != 0) {
+ ptr = ParseFieldMaybeLazily(static_cast<uint64_t>(type_id) * 8 + 2, ptr,
+ extendee, metadata, ctx);
+ GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
+ type_id = 0;
+ } else {
+ int32_t size = ReadSize(&ptr);
+ GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+ ptr = ctx->ReadString(ptr, size, &payload);
+ GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+ payload_read = true;
+ }
+ } else {
+ ptr = ReadTag(ptr - 1, &tag);
+ if (tag == 0 || (tag & 7) == 4) {
+ ctx->SetLastTag(tag);
+ return ptr;
+ }
+ ptr = ParseField(tag, ptr, extendee, metadata, ctx);
+ GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+ }
+ }
+ return ptr;
+}
+
+} // namespace internal
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_EXTENSION_SET_INL_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/extension_set_unittest.cc b/NorthstarDedicatedTest/include/protobuf/extension_set_unittest.cc
new file mode 100644
index 00000000..33f9659b
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/extension_set_unittest.cc
@@ -0,0 +1,1338 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 <stubs/casts.h>
+#include <stubs/strutil.h>
+#include <stubs/logging.h>
+#include <stubs/common.h>
+#include <test_util.h>
+#include <test_util2.h>
+#include <unittest.pb.h>
+#include <unittest_mset.pb.h>
+#include <io/coded_stream.h>
+#include <io/zero_copy_stream_impl.h>
+#include <descriptor.pb.h>
+#include <arena.h>
+#include <descriptor.h>
+#include <dynamic_message.h>
+#include <extension_set.h>
+#include <wire_format.h>
+#include <testing/googletest.h>
+#include <gtest/gtest.h>
+#include <stubs/stl_util.h>
+
+// Must be included last.
+#include <port_def.inc>
+
+
+namespace google {
+namespace protobuf {
+namespace internal {
+namespace {
+
+using TestUtil::EqualsToSerialized;
+
+// This test closely mirrors net/proto2/compiler/cpp/internal/unittest.cc
+// except that it uses extensions rather than regular fields.
+
+TEST(ExtensionSetTest, Defaults) {
+ // Check that all default values are set correctly in the initial message.
+ unittest::TestAllExtensions message;
+
+ TestUtil::ExpectExtensionsClear(message);
+
+ // Messages should return pointers to default instances until first use.
+ // (This is not checked by ExpectClear() since it is not actually true after
+ // the fields have been set and then cleared.)
+ EXPECT_EQ(&unittest::OptionalGroup_extension::default_instance(),
+ &message.GetExtension(unittest::optionalgroup_extension));
+ EXPECT_EQ(&unittest::TestAllTypes::NestedMessage::default_instance(),
+ &message.GetExtension(unittest::optional_nested_message_extension));
+ EXPECT_EQ(
+ &unittest::ForeignMessage::default_instance(),
+ &message.GetExtension(unittest::optional_foreign_message_extension));
+ EXPECT_EQ(&unittest_import::ImportMessage::default_instance(),
+ &message.GetExtension(unittest::optional_import_message_extension));
+}
+
+TEST(ExtensionSetTest, Accessors) {
+ // Set every field to a unique value then go back and check all those
+ // values.
+ unittest::TestAllExtensions message;
+
+ TestUtil::SetAllExtensions(&message);
+ TestUtil::ExpectAllExtensionsSet(message);
+
+ TestUtil::ModifyRepeatedExtensions(&message);
+ TestUtil::ExpectRepeatedExtensionsModified(message);
+}
+
+TEST(ExtensionSetTest, Clear) {
+ // Set every field to a unique value, clear the message, then check that
+ // it is cleared.
+ unittest::TestAllExtensions message;
+
+ TestUtil::SetAllExtensions(&message);
+ message.Clear();
+ TestUtil::ExpectExtensionsClear(message);
+
+ // Unlike with the defaults test, we do NOT expect that requesting embedded
+ // messages will return a pointer to the default instance. Instead, they
+ // should return the objects that were created when mutable_blah() was
+ // called.
+ EXPECT_NE(&unittest::OptionalGroup_extension::default_instance(),
+ &message.GetExtension(unittest::optionalgroup_extension));
+ EXPECT_NE(&unittest::TestAllTypes::NestedMessage::default_instance(),
+ &message.GetExtension(unittest::optional_nested_message_extension));
+ EXPECT_NE(
+ &unittest::ForeignMessage::default_instance(),
+ &message.GetExtension(unittest::optional_foreign_message_extension));
+ EXPECT_NE(&unittest_import::ImportMessage::default_instance(),
+ &message.GetExtension(unittest::optional_import_message_extension));
+
+ // Make sure setting stuff again after clearing works. (This takes slightly
+ // different code paths since the objects are reused.)
+ TestUtil::SetAllExtensions(&message);
+ TestUtil::ExpectAllExtensionsSet(message);
+}
+
+TEST(ExtensionSetTest, ClearOneField) {
+ // Set every field to a unique value, then clear one value and insure that
+ // only that one value is cleared.
+ unittest::TestAllExtensions message;
+
+ TestUtil::SetAllExtensions(&message);
+ int64 original_value =
+ message.GetExtension(unittest::optional_int64_extension);
+
+ // Clear the field and make sure it shows up as cleared.
+ message.ClearExtension(unittest::optional_int64_extension);
+ EXPECT_FALSE(message.HasExtension(unittest::optional_int64_extension));
+ EXPECT_EQ(0, message.GetExtension(unittest::optional_int64_extension));
+
+ // Other adjacent fields should not be cleared.
+ EXPECT_TRUE(message.HasExtension(unittest::optional_int32_extension));
+ EXPECT_TRUE(message.HasExtension(unittest::optional_uint32_extension));
+
+ // Make sure if we set it again, then all fields are set.
+ message.SetExtension(unittest::optional_int64_extension, original_value);
+ TestUtil::ExpectAllExtensionsSet(message);
+}
+
+TEST(ExtensionSetTest, SetAllocatedExtension) {
+ unittest::TestAllExtensions message;
+ EXPECT_FALSE(
+ message.HasExtension(unittest::optional_foreign_message_extension));
+ // Add a extension using SetAllocatedExtension
+ unittest::ForeignMessage* foreign_message = new unittest::ForeignMessage();
+ message.SetAllocatedExtension(unittest::optional_foreign_message_extension,
+ foreign_message);
+ EXPECT_TRUE(
+ message.HasExtension(unittest::optional_foreign_message_extension));
+ EXPECT_EQ(foreign_message, message.MutableExtension(
+ unittest::optional_foreign_message_extension));
+ EXPECT_EQ(foreign_message, &message.GetExtension(
+ unittest::optional_foreign_message_extension));
+
+ // SetAllocatedExtension should delete the previously existing extension.
+ // (We reply on unittest to check memory leaks for this case)
+ message.SetAllocatedExtension(unittest::optional_foreign_message_extension,
+ new unittest::ForeignMessage());
+
+ // SetAllocatedExtension with nullptr is equivalent to ClearExtenion.
+ message.SetAllocatedExtension(unittest::optional_foreign_message_extension,
+ nullptr);
+ EXPECT_FALSE(
+ message.HasExtension(unittest::optional_foreign_message_extension));
+}
+
+TEST(ExtensionSetTest, ReleaseExtension) {
+ proto2_wireformat_unittest::TestMessageSet message;
+ EXPECT_FALSE(message.HasExtension(
+ unittest::TestMessageSetExtension1::message_set_extension));
+ // Add a extension using SetAllocatedExtension
+ unittest::TestMessageSetExtension1* extension =
+ new unittest::TestMessageSetExtension1();
+ message.SetAllocatedExtension(
+ unittest::TestMessageSetExtension1::message_set_extension, extension);
+ EXPECT_TRUE(message.HasExtension(
+ unittest::TestMessageSetExtension1::message_set_extension));
+ // Release the extension using ReleaseExtension
+ unittest::TestMessageSetExtension1* released_extension =
+ message.ReleaseExtension(
+ unittest::TestMessageSetExtension1::message_set_extension);
+ EXPECT_EQ(extension, released_extension);
+ EXPECT_FALSE(message.HasExtension(
+ unittest::TestMessageSetExtension1::message_set_extension));
+ // ReleaseExtension will return the underlying object even after
+ // ClearExtension is called.
+ message.SetAllocatedExtension(
+ unittest::TestMessageSetExtension1::message_set_extension,
+ released_extension);
+ message.ClearExtension(
+ unittest::TestMessageSetExtension1::message_set_extension);
+ released_extension = message.ReleaseExtension(
+ unittest::TestMessageSetExtension1::message_set_extension);
+ EXPECT_TRUE(released_extension != nullptr);
+ delete released_extension;
+}
+
+TEST(ExtensionSetTest, ArenaUnsafeArenaSetAllocatedAndRelease) {
+ Arena arena;
+ unittest::TestAllExtensions* message =
+ Arena::CreateMessage<unittest::TestAllExtensions>(&arena);
+ unittest::ForeignMessage extension;
+ message->UnsafeArenaSetAllocatedExtension(
+ unittest::optional_foreign_message_extension, &extension);
+ // No copy when set.
+ unittest::ForeignMessage* mutable_extension =
+ message->MutableExtension(unittest::optional_foreign_message_extension);
+ EXPECT_EQ(&extension, mutable_extension);
+ // No copy when unsafe released.
+ unittest::ForeignMessage* released_extension =
+ message->UnsafeArenaReleaseExtension(
+ unittest::optional_foreign_message_extension);
+ EXPECT_EQ(&extension, released_extension);
+ EXPECT_FALSE(
+ message->HasExtension(unittest::optional_foreign_message_extension));
+ // Set the ownership back and let the destructors run. It should not take
+ // ownership, so this should not crash.
+ message->UnsafeArenaSetAllocatedExtension(
+ unittest::optional_foreign_message_extension, &extension);
+}
+
+TEST(ExtensionSetTest, UnsafeArenaSetAllocatedAndRelease) {
+ unittest::TestAllExtensions message;
+ unittest::ForeignMessage* extension = new unittest::ForeignMessage();
+ message.UnsafeArenaSetAllocatedExtension(
+ unittest::optional_foreign_message_extension, extension);
+ // No copy when set.
+ unittest::ForeignMessage* mutable_extension =
+ message.MutableExtension(unittest::optional_foreign_message_extension);
+ EXPECT_EQ(extension, mutable_extension);
+ // No copy when unsafe released.
+ unittest::ForeignMessage* released_extension =
+ message.UnsafeArenaReleaseExtension(
+ unittest::optional_foreign_message_extension);
+ EXPECT_EQ(extension, released_extension);
+ EXPECT_FALSE(
+ message.HasExtension(unittest::optional_foreign_message_extension));
+ // Set the ownership back and let the destructors run. It should take
+ // ownership, so this should not leak.
+ message.UnsafeArenaSetAllocatedExtension(
+ unittest::optional_foreign_message_extension, extension);
+}
+
+TEST(ExtensionSetTest, ArenaUnsafeArenaReleaseOfHeapAlloc) {
+ Arena arena;
+ unittest::TestAllExtensions* message =
+ Arena::CreateMessage<unittest::TestAllExtensions>(&arena);
+ unittest::ForeignMessage* extension = new unittest::ForeignMessage;
+ message->SetAllocatedExtension(unittest::optional_foreign_message_extension,
+ extension);
+ // The arena should maintain ownership of the heap allocated proto because we
+ // used UnsafeArenaReleaseExtension. The leak checker will ensure this.
+ unittest::ForeignMessage* released_extension =
+ message->UnsafeArenaReleaseExtension(
+ unittest::optional_foreign_message_extension);
+ EXPECT_EQ(extension, released_extension);
+ EXPECT_FALSE(
+ message->HasExtension(unittest::optional_foreign_message_extension));
+}
+
+
+TEST(ExtensionSetTest, CopyFrom) {
+ unittest::TestAllExtensions message1, message2;
+
+ TestUtil::SetAllExtensions(&message1);
+ message2.CopyFrom(message1);
+ TestUtil::ExpectAllExtensionsSet(message2);
+ message2.CopyFrom(message1); // exercise copy when fields already exist
+ TestUtil::ExpectAllExtensionsSet(message2);
+}
+
+TEST(ExtensionSetTest, CopyFromPacked) {
+ unittest::TestPackedExtensions message1, message2;
+
+ TestUtil::SetPackedExtensions(&message1);
+ message2.CopyFrom(message1);
+ TestUtil::ExpectPackedExtensionsSet(message2);
+ message2.CopyFrom(message1); // exercise copy when fields already exist
+ TestUtil::ExpectPackedExtensionsSet(message2);
+}
+
+TEST(ExtensionSetTest, CopyFromUpcasted) {
+ unittest::TestAllExtensions message1, message2;
+ const Message& upcasted_message = message1;
+
+ TestUtil::SetAllExtensions(&message1);
+ message2.CopyFrom(upcasted_message);
+ TestUtil::ExpectAllExtensionsSet(message2);
+ // exercise copy when fields already exist
+ message2.CopyFrom(upcasted_message);
+ TestUtil::ExpectAllExtensionsSet(message2);
+}
+
+TEST(ExtensionSetTest, SwapWithEmpty) {
+ unittest::TestAllExtensions message1, message2;
+ TestUtil::SetAllExtensions(&message1);
+
+ TestUtil::ExpectAllExtensionsSet(message1);
+ TestUtil::ExpectExtensionsClear(message2);
+ message1.Swap(&message2);
+ TestUtil::ExpectAllExtensionsSet(message2);
+ TestUtil::ExpectExtensionsClear(message1);
+}
+
+TEST(ExtensionSetTest, SwapWithSelf) {
+ unittest::TestAllExtensions message;
+ TestUtil::SetAllExtensions(&message);
+
+ TestUtil::ExpectAllExtensionsSet(message);
+ message.Swap(&message);
+ TestUtil::ExpectAllExtensionsSet(message);
+}
+
+TEST(ExtensionSetTest, SwapExtension) {
+ unittest::TestAllExtensions message1;
+ unittest::TestAllExtensions message2;
+
+ TestUtil::SetAllExtensions(&message1);
+ std::vector<const FieldDescriptor*> fields;
+
+ // Swap empty fields.
+ const Reflection* reflection = message1.GetReflection();
+ reflection->SwapFields(&message1, &message2, fields);
+ TestUtil::ExpectAllExtensionsSet(message1);
+ TestUtil::ExpectExtensionsClear(message2);
+
+ // Swap two extensions.
+ fields.push_back(reflection->FindKnownExtensionByNumber(12));
+ fields.push_back(reflection->FindKnownExtensionByNumber(25));
+ reflection->SwapFields(&message1, &message2, fields);
+
+ EXPECT_TRUE(message1.HasExtension(unittest::optional_int32_extension));
+ EXPECT_FALSE(message1.HasExtension(unittest::optional_double_extension));
+ EXPECT_FALSE(message1.HasExtension(unittest::optional_cord_extension));
+
+ EXPECT_FALSE(message2.HasExtension(unittest::optional_int32_extension));
+ EXPECT_TRUE(message2.HasExtension(unittest::optional_double_extension));
+ EXPECT_TRUE(message2.HasExtension(unittest::optional_cord_extension));
+}
+
+TEST(ExtensionSetTest, SwapExtensionWithEmpty) {
+ unittest::TestAllExtensions message1;
+ unittest::TestAllExtensions message2;
+ unittest::TestAllExtensions message3;
+
+ TestUtil::SetAllExtensions(&message3);
+
+ const Reflection* reflection = message3.GetReflection();
+ std::vector<const FieldDescriptor*> fields;
+ reflection->ListFields(message3, &fields);
+
+ reflection->SwapFields(&message1, &message2, fields);
+
+ TestUtil::ExpectExtensionsClear(message1);
+ TestUtil::ExpectExtensionsClear(message2);
+}
+
+TEST(ExtensionSetTest, SwapExtensionBothFull) {
+ unittest::TestAllExtensions message1;
+ unittest::TestAllExtensions message2;
+
+ TestUtil::SetAllExtensions(&message1);
+ TestUtil::SetAllExtensions(&message2);
+
+ const Reflection* reflection = message1.GetReflection();
+ std::vector<const FieldDescriptor*> fields;
+ reflection->ListFields(message1, &fields);
+
+ reflection->SwapFields(&message1, &message2, fields);
+
+ TestUtil::ExpectAllExtensionsSet(message1);
+ TestUtil::ExpectAllExtensionsSet(message2);
+}
+
+TEST(ExtensionSetTest, ArenaSetAllExtension) {
+ Arena arena1;
+ unittest::TestAllExtensions* message1 =
+ Arena::CreateMessage<unittest::TestAllExtensions>(&arena1);
+ TestUtil::SetAllExtensions(message1);
+ TestUtil::ExpectAllExtensionsSet(*message1);
+}
+
+TEST(ExtensionSetTest, ArenaCopyConstructor) {
+ Arena arena1;
+ unittest::TestAllExtensions* message1 =
+ Arena::CreateMessage<unittest::TestAllExtensions>(&arena1);
+ TestUtil::SetAllExtensions(message1);
+ unittest::TestAllExtensions message2(*message1);
+ arena1.Reset();
+ TestUtil::ExpectAllExtensionsSet(message2);
+}
+
+TEST(ExtensionSetTest, ArenaMergeFrom) {
+ Arena arena1;
+ unittest::TestAllExtensions* message1 =
+ Arena::CreateMessage<unittest::TestAllExtensions>(&arena1);
+ TestUtil::SetAllExtensions(message1);
+ unittest::TestAllExtensions message2;
+ message2.MergeFrom(*message1);
+ arena1.Reset();
+ TestUtil::ExpectAllExtensionsSet(message2);
+}
+
+TEST(ExtensionSetTest, ArenaSetAllocatedMessageAndRelease) {
+ Arena arena;
+ unittest::TestAllExtensions* message =
+ Arena::CreateMessage<unittest::TestAllExtensions>(&arena);
+ EXPECT_FALSE(
+ message->HasExtension(unittest::optional_foreign_message_extension));
+ // Add a extension using SetAllocatedExtension
+ unittest::ForeignMessage* foreign_message = new unittest::ForeignMessage();
+ message->SetAllocatedExtension(unittest::optional_foreign_message_extension,
+ foreign_message);
+ // foreign_message is now owned by the arena.
+ EXPECT_EQ(foreign_message, message->MutableExtension(
+ unittest::optional_foreign_message_extension));
+
+ // Underlying message is copied, and returned.
+ unittest::ForeignMessage* released_message =
+ message->ReleaseExtension(unittest::optional_foreign_message_extension);
+ delete released_message;
+ EXPECT_FALSE(
+ message->HasExtension(unittest::optional_foreign_message_extension));
+}
+
+TEST(ExtensionSetTest, SwapExtensionBothFullWithArena) {
+ Arena arena1;
+ std::unique_ptr<Arena> arena2(new Arena());
+
+ unittest::TestAllExtensions* message1 =
+ Arena::CreateMessage<unittest::TestAllExtensions>(&arena1);
+ unittest::TestAllExtensions* message2 =
+ Arena::CreateMessage<unittest::TestAllExtensions>(arena2.get());
+
+ TestUtil::SetAllExtensions(message1);
+ TestUtil::SetAllExtensions(message2);
+ message1->SetExtension(unittest::optional_int32_extension, 1);
+ message2->SetExtension(unittest::optional_int32_extension, 2);
+ message1->Swap(message2);
+ EXPECT_EQ(2, message1->GetExtension(unittest::optional_int32_extension));
+ EXPECT_EQ(1, message2->GetExtension(unittest::optional_int32_extension));
+ // Re-set the original values so ExpectAllExtensionsSet is happy.
+ message1->SetExtension(unittest::optional_int32_extension, 101);
+ message2->SetExtension(unittest::optional_int32_extension, 101);
+ TestUtil::ExpectAllExtensionsSet(*message1);
+ TestUtil::ExpectAllExtensionsSet(*message2);
+ arena2.reset(nullptr);
+ TestUtil::ExpectAllExtensionsSet(*message1);
+ // Test corner cases, when one is empty and other is not.
+ Arena arena3, arena4;
+
+ unittest::TestAllExtensions* message3 =
+ Arena::CreateMessage<unittest::TestAllExtensions>(&arena3);
+ unittest::TestAllExtensions* message4 =
+ Arena::CreateMessage<unittest::TestAllExtensions>(&arena4);
+ TestUtil::SetAllExtensions(message3);
+ message3->Swap(message4);
+ arena3.Reset();
+ TestUtil::ExpectAllExtensionsSet(*message4);
+}
+
+TEST(ExtensionSetTest, SwapFieldsOfExtensionBothFullWithArena) {
+ Arena arena1;
+ Arena* arena2 = new Arena();
+
+ unittest::TestAllExtensions* message1 =
+ Arena::CreateMessage<unittest::TestAllExtensions>(&arena1);
+ unittest::TestAllExtensions* message2 =
+ Arena::CreateMessage<unittest::TestAllExtensions>(arena2);
+
+ TestUtil::SetAllExtensions(message1);
+ TestUtil::SetAllExtensions(message2);
+
+ const Reflection* reflection = message1->GetReflection();
+ std::vector<const FieldDescriptor*> fields;
+ reflection->ListFields(*message1, &fields);
+ reflection->SwapFields(message1, message2, fields);
+ TestUtil::ExpectAllExtensionsSet(*message1);
+ TestUtil::ExpectAllExtensionsSet(*message2);
+ delete arena2;
+ TestUtil::ExpectAllExtensionsSet(*message1);
+}
+
+TEST(ExtensionSetTest, SwapExtensionWithSelf) {
+ unittest::TestAllExtensions message1;
+
+ TestUtil::SetAllExtensions(&message1);
+
+ std::vector<const FieldDescriptor*> fields;
+ const Reflection* reflection = message1.GetReflection();
+ reflection->ListFields(message1, &fields);
+ reflection->SwapFields(&message1, &message1, fields);
+
+ TestUtil::ExpectAllExtensionsSet(message1);
+}
+
+TEST(ExtensionSetTest, SerializationToArray) {
+ // Serialize as TestAllExtensions and parse as TestAllTypes to insure wire
+ // compatibility of extensions.
+ //
+ // This checks serialization to a flat array by explicitly reserving space in
+ // the string and calling the generated message's
+ // SerializeWithCachedSizesToArray.
+ unittest::TestAllExtensions source;
+ unittest::TestAllTypes destination;
+ TestUtil::SetAllExtensions(&source);
+ size_t size = source.ByteSizeLong();
+ std::string data;
+ data.resize(size);
+ uint8* target = reinterpret_cast<uint8*>(::google::protobuf::string_as_array(&data));
+ uint8* end = source.SerializeWithCachedSizesToArray(target);
+ EXPECT_EQ(size, end - target);
+ EXPECT_TRUE(destination.ParseFromString(data));
+ TestUtil::ExpectAllFieldsSet(destination);
+}
+
+TEST(ExtensionSetTest, SerializationToStream) {
+ // Serialize as TestAllExtensions and parse as TestAllTypes to insure wire
+ // compatibility of extensions.
+ //
+ // This checks serialization to an output stream by creating an array output
+ // stream that can only buffer 1 byte at a time - this prevents the message
+ // from ever jumping to the fast path, ensuring that serialization happens via
+ // the CodedOutputStream.
+ unittest::TestAllExtensions source;
+ unittest::TestAllTypes destination;
+ TestUtil::SetAllExtensions(&source);
+ size_t size = source.ByteSizeLong();
+ std::string data;
+ data.resize(size);
+ {
+ io::ArrayOutputStream array_stream(::google::protobuf::string_as_array(&data), size, 1);
+ io::CodedOutputStream output_stream(&array_stream);
+ source.SerializeWithCachedSizes(&output_stream);
+ ASSERT_FALSE(output_stream.HadError());
+ }
+ EXPECT_TRUE(destination.ParseFromString(data));
+ TestUtil::ExpectAllFieldsSet(destination);
+}
+
+TEST(ExtensionSetTest, PackedSerializationToArray) {
+ // Serialize as TestPackedExtensions and parse as TestPackedTypes to insure
+ // wire compatibility of extensions.
+ //
+ // This checks serialization to a flat array by explicitly reserving space in
+ // the string and calling the generated message's
+ // SerializeWithCachedSizesToArray.
+ unittest::TestPackedExtensions source;
+ unittest::TestPackedTypes destination;
+ TestUtil::SetPackedExtensions(&source);
+ size_t size = source.ByteSizeLong();
+ std::string data;
+ data.resize(size);
+ uint8* target = reinterpret_cast<uint8*>(::google::protobuf::string_as_array(&data));
+ uint8* end = source.SerializeWithCachedSizesToArray(target);
+ EXPECT_EQ(size, end - target);
+ EXPECT_TRUE(destination.ParseFromString(data));
+ TestUtil::ExpectPackedFieldsSet(destination);
+}
+
+TEST(ExtensionSetTest, PackedSerializationToStream) {
+ // Serialize as TestPackedExtensions and parse as TestPackedTypes to insure
+ // wire compatibility of extensions.
+ //
+ // This checks serialization to an output stream by creating an array output
+ // stream that can only buffer 1 byte at a time - this prevents the message
+ // from ever jumping to the fast path, ensuring that serialization happens via
+ // the CodedOutputStream.
+ unittest::TestPackedExtensions source;
+ unittest::TestPackedTypes destination;
+ TestUtil::SetPackedExtensions(&source);
+ size_t size = source.ByteSizeLong();
+ std::string data;
+ data.resize(size);
+ {
+ io::ArrayOutputStream array_stream(::google::protobuf::string_as_array(&data), size, 1);
+ io::CodedOutputStream output_stream(&array_stream);
+ source.SerializeWithCachedSizes(&output_stream);
+ ASSERT_FALSE(output_stream.HadError());
+ }
+ EXPECT_TRUE(destination.ParseFromString(data));
+ TestUtil::ExpectPackedFieldsSet(destination);
+}
+
+TEST(ExtensionSetTest, NestedExtensionGroup) {
+ // Serialize as TestGroup and parse as TestGroupExtension.
+ unittest::TestGroup source;
+ unittest::TestGroupExtension destination;
+ std::string data;
+
+ source.mutable_optionalgroup()->set_a(117);
+ source.set_optional_foreign_enum(unittest::FOREIGN_BAZ);
+ source.SerializeToString(&data);
+ EXPECT_TRUE(destination.ParseFromString(data));
+ EXPECT_TRUE(
+ destination
+ .GetExtension(unittest::TestNestedExtension::optionalgroup_extension)
+ .has_a());
+ EXPECT_EQ(117, destination
+ .GetExtension(
+ unittest::TestNestedExtension::optionalgroup_extension)
+ .a());
+ EXPECT_TRUE(destination.HasExtension(
+ unittest::TestNestedExtension::optional_foreign_enum_extension));
+ EXPECT_EQ(
+ unittest::FOREIGN_BAZ,
+ destination.GetExtension(
+ unittest::TestNestedExtension::optional_foreign_enum_extension));
+}
+
+TEST(ExtensionSetTest, Parsing) {
+ // Serialize as TestAllTypes and parse as TestAllExtensions.
+ unittest::TestAllTypes source;
+ unittest::TestAllExtensions destination;
+ std::string data;
+
+ TestUtil::SetAllFields(&source);
+ source.SerializeToString(&data);
+ EXPECT_TRUE(destination.ParseFromString(data));
+ TestUtil::SetOneofFields(&destination);
+ TestUtil::ExpectAllExtensionsSet(destination);
+}
+
+TEST(ExtensionSetTest, PackedParsing) {
+ // Serialize as TestPackedTypes and parse as TestPackedExtensions.
+ unittest::TestPackedTypes source;
+ unittest::TestPackedExtensions destination;
+ std::string data;
+
+ TestUtil::SetPackedFields(&source);
+ source.SerializeToString(&data);
+ EXPECT_TRUE(destination.ParseFromString(data));
+ TestUtil::ExpectPackedExtensionsSet(destination);
+}
+
+TEST(ExtensionSetTest, PackedToUnpackedParsing) {
+ unittest::TestPackedTypes source;
+ unittest::TestUnpackedExtensions destination;
+ std::string data;
+
+ TestUtil::SetPackedFields(&source);
+ source.SerializeToString(&data);
+ EXPECT_TRUE(destination.ParseFromString(data));
+ TestUtil::ExpectUnpackedExtensionsSet(destination);
+
+ // Reserialize
+ unittest::TestUnpackedTypes unpacked;
+ TestUtil::SetUnpackedFields(&unpacked);
+ // Serialized proto has to be the same size and parsed to the same message.
+ EXPECT_EQ(unpacked.SerializeAsString().size(),
+ destination.SerializeAsString().size());
+ EXPECT_TRUE(EqualsToSerialized(unpacked, destination.SerializeAsString()));
+
+ // Make sure we can add extensions.
+ destination.AddExtension(unittest::unpacked_int32_extension, 1);
+ destination.AddExtension(unittest::unpacked_enum_extension,
+ protobuf_unittest::FOREIGN_BAR);
+}
+
+TEST(ExtensionSetTest, UnpackedToPackedParsing) {
+ unittest::TestUnpackedTypes source;
+ unittest::TestPackedExtensions destination;
+ std::string data;
+
+ TestUtil::SetUnpackedFields(&source);
+ source.SerializeToString(&data);
+ EXPECT_TRUE(destination.ParseFromString(data));
+ TestUtil::ExpectPackedExtensionsSet(destination);
+
+ // Reserialize
+ unittest::TestPackedTypes packed;
+ TestUtil::SetPackedFields(&packed);
+ // Serialized proto has to be the same size and parsed to the same message.
+ EXPECT_EQ(packed.SerializeAsString().size(),
+ destination.SerializeAsString().size());
+ EXPECT_TRUE(EqualsToSerialized(packed, destination.SerializeAsString()));
+
+ // Make sure we can add extensions.
+ destination.AddExtension(unittest::packed_int32_extension, 1);
+ destination.AddExtension(unittest::packed_enum_extension,
+ protobuf_unittest::FOREIGN_BAR);
+}
+
+TEST(ExtensionSetTest, IsInitialized) {
+ // Test that IsInitialized() returns false if required fields in nested
+ // extensions are missing.
+ unittest::TestAllExtensions message;
+
+ EXPECT_TRUE(message.IsInitialized());
+
+ message.MutableExtension(unittest::TestRequired::single);
+ EXPECT_FALSE(message.IsInitialized());
+
+ message.MutableExtension(unittest::TestRequired::single)->set_a(1);
+ EXPECT_FALSE(message.IsInitialized());
+ message.MutableExtension(unittest::TestRequired::single)->set_b(2);
+ EXPECT_FALSE(message.IsInitialized());
+ message.MutableExtension(unittest::TestRequired::single)->set_c(3);
+ EXPECT_TRUE(message.IsInitialized());
+
+ message.AddExtension(unittest::TestRequired::multi);
+ EXPECT_FALSE(message.IsInitialized());
+
+ message.MutableExtension(unittest::TestRequired::multi, 0)->set_a(1);
+ EXPECT_FALSE(message.IsInitialized());
+ message.MutableExtension(unittest::TestRequired::multi, 0)->set_b(2);
+ EXPECT_FALSE(message.IsInitialized());
+ message.MutableExtension(unittest::TestRequired::multi, 0)->set_c(3);
+ EXPECT_TRUE(message.IsInitialized());
+}
+
+TEST(ExtensionSetTest, MutableString) {
+ // Test the mutable string accessors.
+ unittest::TestAllExtensions message;
+
+ message.MutableExtension(unittest::optional_string_extension)->assign("foo");
+ EXPECT_TRUE(message.HasExtension(unittest::optional_string_extension));
+ EXPECT_EQ("foo", message.GetExtension(unittest::optional_string_extension));
+
+ message.AddExtension(unittest::repeated_string_extension)->assign("bar");
+ ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_string_extension));
+ EXPECT_EQ("bar",
+ message.GetExtension(unittest::repeated_string_extension, 0));
+}
+
+TEST(ExtensionSetTest, SpaceUsedExcludingSelf) {
+ // Scalar primitive extensions should increase the extension set size by a
+ // minimum of the size of the primitive type.
+#define TEST_SCALAR_EXTENSIONS_SPACE_USED(type, value) \
+ do { \
+ unittest::TestAllExtensions message; \
+ const int base_size = message.SpaceUsedLong(); \
+ message.SetExtension(unittest::optional_##type##_extension, value); \
+ int min_expected_size = \
+ base_size + \
+ sizeof(message.GetExtension(unittest::optional_##type##_extension)); \
+ EXPECT_LE(min_expected_size, message.SpaceUsedLong()); \
+ } while (0)
+
+ TEST_SCALAR_EXTENSIONS_SPACE_USED(int32, 101);
+ TEST_SCALAR_EXTENSIONS_SPACE_USED(int64, 102);
+ TEST_SCALAR_EXTENSIONS_SPACE_USED(uint32, 103);
+ TEST_SCALAR_EXTENSIONS_SPACE_USED(uint64, 104);
+ TEST_SCALAR_EXTENSIONS_SPACE_USED(sint32, 105);
+ TEST_SCALAR_EXTENSIONS_SPACE_USED(sint64, 106);
+ TEST_SCALAR_EXTENSIONS_SPACE_USED(fixed32, 107);
+ TEST_SCALAR_EXTENSIONS_SPACE_USED(fixed64, 108);
+ TEST_SCALAR_EXTENSIONS_SPACE_USED(sfixed32, 109);
+ TEST_SCALAR_EXTENSIONS_SPACE_USED(sfixed64, 110);
+ TEST_SCALAR_EXTENSIONS_SPACE_USED(float, 111);
+ TEST_SCALAR_EXTENSIONS_SPACE_USED(double, 112);
+ TEST_SCALAR_EXTENSIONS_SPACE_USED(bool, true);
+#undef TEST_SCALAR_EXTENSIONS_SPACE_USED
+ {
+ unittest::TestAllExtensions message;
+ const int base_size = message.SpaceUsedLong();
+ message.SetExtension(unittest::optional_nested_enum_extension,
+ unittest::TestAllTypes::FOO);
+ int min_expected_size =
+ base_size +
+ sizeof(message.GetExtension(unittest::optional_nested_enum_extension));
+ EXPECT_LE(min_expected_size, message.SpaceUsedLong());
+ }
+ {
+ // Strings may cause extra allocations depending on their length; ensure
+ // that gets included as well.
+ unittest::TestAllExtensions message;
+ const int base_size = message.SpaceUsedLong();
+ const std::string s(
+ "this is a fairly large string that will cause some "
+ "allocation in order to store it in the extension");
+ message.SetExtension(unittest::optional_string_extension, s);
+ int min_expected_size = base_size + s.length();
+ EXPECT_LE(min_expected_size, message.SpaceUsedLong());
+ }
+ {
+ // Messages also have additional allocation that need to be counted.
+ unittest::TestAllExtensions message;
+ const int base_size = message.SpaceUsedLong();
+ unittest::ForeignMessage foreign;
+ foreign.set_c(42);
+ message.MutableExtension(unittest::optional_foreign_message_extension)
+ ->CopyFrom(foreign);
+ int min_expected_size = base_size + foreign.SpaceUsedLong();
+ EXPECT_LE(min_expected_size, message.SpaceUsedLong());
+ }
+
+ // Repeated primitive extensions will increase space used by at least a
+ // RepeatedField<T>, and will cause additional allocations when the array
+ // gets too big for the initial space.
+ // This macro:
+ // - Adds a value to the repeated extension, then clears it, establishing
+ // the base size.
+ // - Adds a small number of values, testing that it doesn't increase the
+ // SpaceUsedLong()
+ // - Adds a large number of values (requiring allocation in the repeated
+ // field), and ensures that that allocation is included in SpaceUsedLong()
+#define TEST_REPEATED_EXTENSIONS_SPACE_USED(type, cpptype, value) \
+ do { \
+ unittest::TestAllExtensions message; \
+ const size_t base_size = message.SpaceUsedLong(); \
+ size_t min_expected_size = sizeof(RepeatedField<cpptype>) + base_size; \
+ message.AddExtension(unittest::repeated_##type##_extension, value); \
+ message.ClearExtension(unittest::repeated_##type##_extension); \
+ const size_t empty_repeated_field_size = message.SpaceUsedLong(); \
+ EXPECT_LE(min_expected_size, empty_repeated_field_size) << #type; \
+ message.AddExtension(unittest::repeated_##type##_extension, value); \
+ message.AddExtension(unittest::repeated_##type##_extension, value); \
+ EXPECT_EQ(empty_repeated_field_size, message.SpaceUsedLong()) << #type; \
+ message.ClearExtension(unittest::repeated_##type##_extension); \
+ const size_t old_capacity = \
+ message.GetRepeatedExtension(unittest::repeated_##type##_extension) \
+ .Capacity(); \
+ EXPECT_GE(old_capacity, kRepeatedFieldLowerClampLimit); \
+ for (int i = 0; i < 16; ++i) { \
+ message.AddExtension(unittest::repeated_##type##_extension, value); \
+ } \
+ int expected_size = \
+ sizeof(cpptype) * \
+ (message \
+ .GetRepeatedExtension(unittest::repeated_##type##_extension) \
+ .Capacity() - \
+ old_capacity) + \
+ empty_repeated_field_size; \
+ EXPECT_LE(expected_size, message.SpaceUsedLong()) << #type; \
+ } while (0)
+
+ TEST_REPEATED_EXTENSIONS_SPACE_USED(int32, int32, 101);
+ TEST_REPEATED_EXTENSIONS_SPACE_USED(int64, int64, 102);
+ TEST_REPEATED_EXTENSIONS_SPACE_USED(uint32, uint32, 103);
+ TEST_REPEATED_EXTENSIONS_SPACE_USED(uint64, uint64, 104);
+ TEST_REPEATED_EXTENSIONS_SPACE_USED(sint32, int32, 105);
+ TEST_REPEATED_EXTENSIONS_SPACE_USED(sint64, int64, 106);
+ TEST_REPEATED_EXTENSIONS_SPACE_USED(fixed32, uint32, 107);
+ TEST_REPEATED_EXTENSIONS_SPACE_USED(fixed64, uint64, 108);
+ TEST_REPEATED_EXTENSIONS_SPACE_USED(sfixed32, int32, 109);
+ TEST_REPEATED_EXTENSIONS_SPACE_USED(sfixed64, int64, 110);
+ TEST_REPEATED_EXTENSIONS_SPACE_USED(float, float, 111);
+ TEST_REPEATED_EXTENSIONS_SPACE_USED(double, double, 112);
+ TEST_REPEATED_EXTENSIONS_SPACE_USED(bool, bool, true);
+ TEST_REPEATED_EXTENSIONS_SPACE_USED(nested_enum, int,
+ unittest::TestAllTypes::FOO);
+#undef TEST_REPEATED_EXTENSIONS_SPACE_USED
+ // Repeated strings
+ {
+ unittest::TestAllExtensions message;
+ const size_t base_size = message.SpaceUsedLong();
+ size_t min_expected_size =
+ sizeof(RepeatedPtrField<std::string>) + base_size;
+ const std::string value(256, 'x');
+ // Once items are allocated, they may stick around even when cleared so
+ // without the hardcore memory management accessors there isn't a notion of
+ // the empty repeated field memory usage as there is with primitive types.
+ for (int i = 0; i < 16; ++i) {
+ message.AddExtension(unittest::repeated_string_extension, value);
+ }
+ min_expected_size +=
+ (sizeof(value) + value.size()) * (16 - kRepeatedFieldLowerClampLimit);
+ EXPECT_LE(min_expected_size, message.SpaceUsedLong());
+ }
+ // Repeated messages
+ {
+ unittest::TestAllExtensions message;
+ const size_t base_size = message.SpaceUsedLong();
+ size_t min_expected_size =
+ sizeof(RepeatedPtrField<unittest::ForeignMessage>) + base_size;
+ unittest::ForeignMessage prototype;
+ prototype.set_c(2);
+ for (int i = 0; i < 16; ++i) {
+ message.AddExtension(unittest::repeated_foreign_message_extension)
+ ->CopyFrom(prototype);
+ }
+ min_expected_size +=
+ (16 - kRepeatedFieldLowerClampLimit) * prototype.SpaceUsedLong();
+ EXPECT_LE(min_expected_size, message.SpaceUsedLong());
+ }
+}
+
+// N.B.: We do not test range-based for here because we remain C++03 compatible.
+template <typename T, typename M, typename ID>
+inline T SumAllExtensions(const M& message, ID extension, T zero) {
+ T sum = zero;
+ typename RepeatedField<T>::const_iterator iter =
+ message.GetRepeatedExtension(extension).begin();
+ typename RepeatedField<T>::const_iterator end =
+ message.GetRepeatedExtension(extension).end();
+ for (; iter != end; ++iter) {
+ sum += *iter;
+ }
+ return sum;
+}
+
+template <typename T, typename M, typename ID>
+inline void IncAllExtensions(M* message, ID extension, T val) {
+ typename RepeatedField<T>::iterator iter =
+ message->MutableRepeatedExtension(extension)->begin();
+ typename RepeatedField<T>::iterator end =
+ message->MutableRepeatedExtension(extension)->end();
+ for (; iter != end; ++iter) {
+ *iter += val;
+ }
+}
+
+TEST(ExtensionSetTest, RepeatedFields) {
+ unittest::TestAllExtensions message;
+
+ // Test empty repeated-field case (b/12926163)
+ ASSERT_EQ(
+ 0,
+ message.GetRepeatedExtension(unittest::repeated_int32_extension).size());
+ ASSERT_EQ(
+ 0, message.GetRepeatedExtension(unittest::repeated_nested_enum_extension)
+ .size());
+ ASSERT_EQ(
+ 0,
+ message.GetRepeatedExtension(unittest::repeated_string_extension).size());
+ ASSERT_EQ(
+ 0,
+ message.GetRepeatedExtension(unittest::repeated_nested_message_extension)
+ .size());
+
+ unittest::TestAllTypes::NestedMessage nested_message;
+ nested_message.set_bb(42);
+ unittest::TestAllTypes::NestedEnum nested_enum =
+ unittest::TestAllTypes::NestedEnum_MIN;
+
+ for (int i = 0; i < 10; ++i) {
+ message.AddExtension(unittest::repeated_int32_extension, 1);
+ message.AddExtension(unittest::repeated_int64_extension, 2);
+ message.AddExtension(unittest::repeated_uint32_extension, 3);
+ message.AddExtension(unittest::repeated_uint64_extension, 4);
+ message.AddExtension(unittest::repeated_sint32_extension, 5);
+ message.AddExtension(unittest::repeated_sint64_extension, 6);
+ message.AddExtension(unittest::repeated_fixed32_extension, 7);
+ message.AddExtension(unittest::repeated_fixed64_extension, 8);
+ message.AddExtension(unittest::repeated_sfixed32_extension, 7);
+ message.AddExtension(unittest::repeated_sfixed64_extension, 8);
+ message.AddExtension(unittest::repeated_float_extension, 9.0);
+ message.AddExtension(unittest::repeated_double_extension, 10.0);
+ message.AddExtension(unittest::repeated_bool_extension, true);
+ message.AddExtension(unittest::repeated_nested_enum_extension, nested_enum);
+ message.AddExtension(unittest::repeated_string_extension,
+ std::string("test"));
+ message.AddExtension(unittest::repeated_bytes_extension,
+ std::string("test\xFF"));
+ message.AddExtension(unittest::repeated_nested_message_extension)
+ ->CopyFrom(nested_message);
+ message.AddExtension(unittest::repeated_nested_enum_extension, nested_enum);
+ }
+
+ ASSERT_EQ(10, SumAllExtensions<int32>(message,
+ unittest::repeated_int32_extension, 0));
+ IncAllExtensions<int32>(&message, unittest::repeated_int32_extension, 1);
+ ASSERT_EQ(20, SumAllExtensions<int32>(message,
+ unittest::repeated_int32_extension, 0));
+
+ ASSERT_EQ(20, SumAllExtensions<int64>(message,
+ unittest::repeated_int64_extension, 0));
+ IncAllExtensions<int64>(&message, unittest::repeated_int64_extension, 1);
+ ASSERT_EQ(30, SumAllExtensions<int64>(message,
+ unittest::repeated_int64_extension, 0));
+
+ ASSERT_EQ(30, SumAllExtensions<uint32>(
+ message, unittest::repeated_uint32_extension, 0));
+ IncAllExtensions<uint32>(&message, unittest::repeated_uint32_extension, 1);
+ ASSERT_EQ(40, SumAllExtensions<uint32>(
+ message, unittest::repeated_uint32_extension, 0));
+
+ ASSERT_EQ(40, SumAllExtensions<uint64>(
+ message, unittest::repeated_uint64_extension, 0));
+ IncAllExtensions<uint64>(&message, unittest::repeated_uint64_extension, 1);
+ ASSERT_EQ(50, SumAllExtensions<uint64>(
+ message, unittest::repeated_uint64_extension, 0));
+
+ ASSERT_EQ(50, SumAllExtensions<int32>(
+ message, unittest::repeated_sint32_extension, 0));
+ IncAllExtensions<int32>(&message, unittest::repeated_sint32_extension, 1);
+ ASSERT_EQ(60, SumAllExtensions<int32>(
+ message, unittest::repeated_sint32_extension, 0));
+
+ ASSERT_EQ(60, SumAllExtensions<int64>(
+ message, unittest::repeated_sint64_extension, 0));
+ IncAllExtensions<int64>(&message, unittest::repeated_sint64_extension, 1);
+ ASSERT_EQ(70, SumAllExtensions<int64>(
+ message, unittest::repeated_sint64_extension, 0));
+
+ ASSERT_EQ(70, SumAllExtensions<uint32>(
+ message, unittest::repeated_fixed32_extension, 0));
+ IncAllExtensions<uint32>(&message, unittest::repeated_fixed32_extension, 1);
+ ASSERT_EQ(80, SumAllExtensions<uint32>(
+ message, unittest::repeated_fixed32_extension, 0));
+
+ ASSERT_EQ(80, SumAllExtensions<uint64>(
+ message, unittest::repeated_fixed64_extension, 0));
+ IncAllExtensions<uint64>(&message, unittest::repeated_fixed64_extension, 1);
+ ASSERT_EQ(90, SumAllExtensions<uint64>(
+ message, unittest::repeated_fixed64_extension, 0));
+
+ // Usually, floating-point arithmetic cannot be trusted to be exact, so it is
+ // a Bad Idea to assert equality in a test like this. However, we're dealing
+ // with integers with a small number of significant mantissa bits, so we
+ // should actually have exact precision here.
+ ASSERT_EQ(90, SumAllExtensions<float>(message,
+ unittest::repeated_float_extension, 0));
+ IncAllExtensions<float>(&message, unittest::repeated_float_extension, 1);
+ ASSERT_EQ(100, SumAllExtensions<float>(
+ message, unittest::repeated_float_extension, 0));
+
+ ASSERT_EQ(100, SumAllExtensions<double>(
+ message, unittest::repeated_double_extension, 0));
+ IncAllExtensions<double>(&message, unittest::repeated_double_extension, 1);
+ ASSERT_EQ(110, SumAllExtensions<double>(
+ message, unittest::repeated_double_extension, 0));
+
+ RepeatedPtrField<std::string>::iterator string_iter;
+ RepeatedPtrField<std::string>::iterator string_end;
+ for (string_iter =
+ message
+ .MutableRepeatedExtension(unittest::repeated_string_extension)
+ ->begin(),
+ string_end =
+ message
+ .MutableRepeatedExtension(unittest::repeated_string_extension)
+ ->end();
+ string_iter != string_end; ++string_iter) {
+ *string_iter += "test";
+ }
+ RepeatedPtrField<std::string>::const_iterator string_const_iter;
+ RepeatedPtrField<std::string>::const_iterator string_const_end;
+ for (string_const_iter =
+ message.GetRepeatedExtension(unittest::repeated_string_extension)
+ .begin(),
+ string_const_end =
+ message.GetRepeatedExtension(unittest::repeated_string_extension)
+ .end();
+ string_iter != string_end; ++string_iter) {
+ ASSERT_TRUE(*string_iter == "testtest");
+ }
+
+ RepeatedField<unittest::TestAllTypes_NestedEnum>::iterator enum_iter;
+ RepeatedField<unittest::TestAllTypes_NestedEnum>::iterator enum_end;
+ for (enum_iter = message
+ .MutableRepeatedExtension(
+ unittest::repeated_nested_enum_extension)
+ ->begin(),
+ enum_end = message
+ .MutableRepeatedExtension(
+ unittest::repeated_nested_enum_extension)
+ ->end();
+ enum_iter != enum_end; ++enum_iter) {
+ *enum_iter = unittest::TestAllTypes::NestedEnum_MAX;
+ }
+ RepeatedField<unittest::TestAllTypes_NestedEnum>::const_iterator
+ enum_const_iter;
+ RepeatedField<unittest::TestAllTypes_NestedEnum>::const_iterator
+ enum_const_end;
+ for (enum_const_iter =
+ message
+ .GetRepeatedExtension(unittest::repeated_nested_enum_extension)
+ .begin(),
+ enum_const_end =
+ message
+ .GetRepeatedExtension(unittest::repeated_nested_enum_extension)
+ .end();
+ enum_const_iter != enum_const_end; ++enum_const_iter) {
+ ASSERT_EQ(*enum_const_iter, unittest::TestAllTypes::NestedEnum_MAX);
+ }
+
+ RepeatedPtrField<unittest::TestAllTypes_NestedMessage>::iterator msg_iter;
+ RepeatedPtrField<unittest::TestAllTypes_NestedMessage>::iterator msg_end;
+ for (msg_iter = message
+ .MutableRepeatedExtension(
+ unittest::repeated_nested_message_extension)
+ ->begin(),
+ msg_end = message
+ .MutableRepeatedExtension(
+ unittest::repeated_nested_message_extension)
+ ->end();
+ msg_iter != msg_end; ++msg_iter) {
+ msg_iter->set_bb(1234);
+ }
+ RepeatedPtrField<unittest::TestAllTypes_NestedMessage>::const_iterator
+ msg_const_iter;
+ RepeatedPtrField<unittest::TestAllTypes_NestedMessage>::const_iterator
+ msg_const_end;
+ for (msg_const_iter = message
+ .GetRepeatedExtension(
+ unittest::repeated_nested_message_extension)
+ .begin(),
+ msg_const_end = message
+ .GetRepeatedExtension(
+ unittest::repeated_nested_message_extension)
+ .end();
+ msg_const_iter != msg_const_end; ++msg_const_iter) {
+ ASSERT_EQ(msg_const_iter->bb(), 1234);
+ }
+
+ // Test one primitive field.
+ for (auto& x :
+ *message.MutableRepeatedExtension(unittest::repeated_int32_extension)) {
+ x = 4321;
+ }
+ for (const auto& x :
+ message.GetRepeatedExtension(unittest::repeated_int32_extension)) {
+ ASSERT_EQ(x, 4321);
+ }
+ // Test one string field.
+ for (auto& x :
+ *message.MutableRepeatedExtension(unittest::repeated_string_extension)) {
+ x = "test_range_based_for";
+ }
+ for (const auto& x :
+ message.GetRepeatedExtension(unittest::repeated_string_extension)) {
+ ASSERT_TRUE(x == "test_range_based_for");
+ }
+ // Test one message field.
+ for (auto& x : *message.MutableRepeatedExtension(
+ unittest::repeated_nested_message_extension)) {
+ x.set_bb(4321);
+ }
+ for (const auto& x : *message.MutableRepeatedExtension(
+ unittest::repeated_nested_message_extension)) {
+ ASSERT_EQ(x.bb(), 4321);
+ }
+}
+
+// From b/12926163
+TEST(ExtensionSetTest, AbsentExtension) {
+ unittest::TestAllExtensions message;
+ message.MutableRepeatedExtension(unittest::repeated_nested_message_extension)
+ ->Add()
+ ->set_bb(123);
+ ASSERT_EQ(1,
+ message.ExtensionSize(unittest::repeated_nested_message_extension));
+ EXPECT_EQ(123,
+ message.GetExtension(unittest::repeated_nested_message_extension, 0)
+ .bb());
+}
+
+#ifdef PROTOBUF_HAS_DEATH_TEST
+
+TEST(ExtensionSetTest, InvalidEnumDeath) {
+ unittest::TestAllExtensions message;
+ EXPECT_DEBUG_DEATH(
+ message.SetExtension(unittest::optional_foreign_enum_extension,
+ static_cast<unittest::ForeignEnum>(53)),
+ "IsValid");
+}
+
+#endif // PROTOBUF_HAS_DEATH_TEST
+
+TEST(ExtensionSetTest, DynamicExtensions) {
+ // Test adding a dynamic extension to a compiled-in message object.
+
+ FileDescriptorProto dynamic_proto;
+ dynamic_proto.set_name("dynamic_extensions_test.proto");
+ dynamic_proto.add_dependency(
+ unittest::TestAllExtensions::descriptor()->file()->name());
+ dynamic_proto.set_package("dynamic_extensions");
+
+ // Copy the fields and nested types from TestDynamicExtensions into our new
+ // proto, converting the fields into extensions.
+ const Descriptor* template_descriptor =
+ unittest::TestDynamicExtensions::descriptor();
+ DescriptorProto template_descriptor_proto;
+ template_descriptor->CopyTo(&template_descriptor_proto);
+ dynamic_proto.mutable_message_type()->MergeFrom(
+ template_descriptor_proto.nested_type());
+ dynamic_proto.mutable_enum_type()->MergeFrom(
+ template_descriptor_proto.enum_type());
+ dynamic_proto.mutable_extension()->MergeFrom(
+ template_descriptor_proto.field());
+
+ // For each extension that we added...
+ for (int i = 0; i < dynamic_proto.extension_size(); i++) {
+ // Set its extendee to TestAllExtensions.
+ FieldDescriptorProto* extension = dynamic_proto.mutable_extension(i);
+ extension->set_extendee(
+ unittest::TestAllExtensions::descriptor()->full_name());
+
+ // If the field refers to one of the types nested in TestDynamicExtensions,
+ // make it refer to the type in our dynamic proto instead.
+ std::string prefix = "." + template_descriptor->full_name() + ".";
+ if (extension->has_type_name()) {
+ std::string* type_name = extension->mutable_type_name();
+ if (HasPrefixString(*type_name, prefix)) {
+ type_name->replace(0, prefix.size(), ".dynamic_extensions.");
+ }
+ }
+ }
+
+ // Now build the file, using the generated pool as an underlay.
+ DescriptorPool dynamic_pool(DescriptorPool::generated_pool());
+ const FileDescriptor* file = dynamic_pool.BuildFile(dynamic_proto);
+ ASSERT_TRUE(file != nullptr);
+ DynamicMessageFactory dynamic_factory(&dynamic_pool);
+ dynamic_factory.SetDelegateToGeneratedFactory(true);
+
+ // Construct a message that we can parse with the extensions we defined.
+ // Since the extensions were based off of the fields of TestDynamicExtensions,
+ // we can use that message to create this test message.
+ std::string data;
+ unittest::TestDynamicExtensions dynamic_extension;
+ {
+ unittest::TestDynamicExtensions message;
+ message.set_scalar_extension(123);
+ message.set_enum_extension(unittest::FOREIGN_BAR);
+ message.set_dynamic_enum_extension(
+ unittest::TestDynamicExtensions::DYNAMIC_BAZ);
+ message.mutable_message_extension()->set_c(456);
+ message.mutable_dynamic_message_extension()->set_dynamic_field(789);
+ message.add_repeated_extension("foo");
+ message.add_repeated_extension("bar");
+ message.add_packed_extension(12);
+ message.add_packed_extension(-34);
+ message.add_packed_extension(56);
+ message.add_packed_extension(-78);
+
+ // Also add some unknown fields.
+
+ // An unknown enum value (for a known field).
+ message.mutable_unknown_fields()->AddVarint(
+ unittest::TestDynamicExtensions::kDynamicEnumExtensionFieldNumber,
+ 12345);
+ // A regular unknown field.
+ message.mutable_unknown_fields()->AddLengthDelimited(54321, "unknown");
+
+ message.SerializeToString(&data);
+ dynamic_extension = message;
+ }
+
+ // Now we can parse this using our dynamic extension definitions...
+ unittest::TestAllExtensions message;
+ {
+ io::ArrayInputStream raw_input(data.data(), data.size());
+ io::CodedInputStream input(&raw_input);
+ input.SetExtensionRegistry(&dynamic_pool, &dynamic_factory);
+ ASSERT_TRUE(message.ParseFromCodedStream(&input));
+ ASSERT_TRUE(input.ConsumedEntireMessage());
+ }
+
+ // Can we print it?
+ EXPECT_EQ(
+ "[dynamic_extensions.scalar_extension]: 123\n"
+ "[dynamic_extensions.enum_extension]: FOREIGN_BAR\n"
+ "[dynamic_extensions.dynamic_enum_extension]: DYNAMIC_BAZ\n"
+ "[dynamic_extensions.message_extension] {\n"
+ " c: 456\n"
+ "}\n"
+ "[dynamic_extensions.dynamic_message_extension] {\n"
+ " dynamic_field: 789\n"
+ "}\n"
+ "[dynamic_extensions.repeated_extension]: \"foo\"\n"
+ "[dynamic_extensions.repeated_extension]: \"bar\"\n"
+ "[dynamic_extensions.packed_extension]: 12\n"
+ "[dynamic_extensions.packed_extension]: -34\n"
+ "[dynamic_extensions.packed_extension]: 56\n"
+ "[dynamic_extensions.packed_extension]: -78\n"
+ "2002: 12345\n"
+ "54321: \"unknown\"\n",
+ message.DebugString());
+
+ // Can we serialize it?
+ EXPECT_TRUE(
+ EqualsToSerialized(dynamic_extension, message.SerializeAsString()));
+
+ // What if we parse using the reflection-based parser?
+ {
+ unittest::TestAllExtensions message2;
+ io::ArrayInputStream raw_input(data.data(), data.size());
+ io::CodedInputStream input(&raw_input);
+ input.SetExtensionRegistry(&dynamic_pool, &dynamic_factory);
+ ASSERT_TRUE(WireFormat::ParseAndMergePartial(&input, &message2));
+ ASSERT_TRUE(input.ConsumedEntireMessage());
+ EXPECT_EQ(message.DebugString(), message2.DebugString());
+ }
+
+ // Are the embedded generated types actually using the generated objects?
+ {
+ const FieldDescriptor* message_extension =
+ file->FindExtensionByName("message_extension");
+ ASSERT_TRUE(message_extension != nullptr);
+ const Message& sub_message =
+ message.GetReflection()->GetMessage(message, message_extension);
+ const unittest::ForeignMessage* typed_sub_message =
+#if PROTOBUF_RTTI
+ dynamic_cast<const unittest::ForeignMessage*>(&sub_message);
+#else
+ static_cast<const unittest::ForeignMessage*>(&sub_message);
+#endif
+ ASSERT_TRUE(typed_sub_message != nullptr);
+ EXPECT_EQ(456, typed_sub_message->c());
+ }
+
+ // What does GetMessage() return for the embedded dynamic type if it isn't
+ // present?
+ {
+ const FieldDescriptor* dynamic_message_extension =
+ file->FindExtensionByName("dynamic_message_extension");
+ ASSERT_TRUE(dynamic_message_extension != nullptr);
+ const Message& parent = unittest::TestAllExtensions::default_instance();
+ const Message& sub_message = parent.GetReflection()->GetMessage(
+ parent, dynamic_message_extension, &dynamic_factory);
+ const Message* prototype =
+ dynamic_factory.GetPrototype(dynamic_message_extension->message_type());
+ EXPECT_EQ(prototype, &sub_message);
+ }
+}
+
+TEST(ExtensionSetTest, BoolExtension) {
+ unittest::TestAllExtensions msg;
+ uint8 wire_bytes[2] = {13 * 8, 42 /* out of bounds payload for bool */};
+ EXPECT_TRUE(msg.ParseFromArray(wire_bytes, 2));
+ EXPECT_TRUE(msg.GetExtension(protobuf_unittest::optional_bool_extension));
+}
+
+TEST(ExtensionSetTest, ConstInit) {
+ PROTOBUF_CONSTINIT static ExtensionSet set{};
+ EXPECT_EQ(set.NumExtensions(), 0);
+}
+
+} // namespace
+} // namespace internal
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/field_access_listener.h b/NorthstarDedicatedTest/include/protobuf/field_access_listener.h
new file mode 100644
index 00000000..785f07fd
--- /dev/null
+++ b/NorthstarDedicatedTest/include/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 <stubs/common.h>
+#include <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/NorthstarDedicatedTest/include/protobuf/field_mask.pb.cc b/NorthstarDedicatedTest/include/protobuf/field_mask.pb.cc
new file mode 100644
index 00000000..c1cada1c
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/field_mask.pb.cc
@@ -0,0 +1,276 @@
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+// source: google/protobuf/field_mask.proto
+
+#include <field_mask.pb.h>
+
+#include <algorithm>
+
+#include <io/coded_stream.h>
+#include <extension_set.h>
+#include <wire_format_lite.h>
+#include <descriptor.h>
+#include <generated_message_reflection.h>
+#include <reflection_ops.h>
+#include <wire_format.h>
+// @@protoc_insertion_point(includes)
+#include <port_def.inc>
+
+PROTOBUF_PRAGMA_INIT_SEG
+PROTOBUF_NAMESPACE_OPEN
+constexpr FieldMask::FieldMask(
+ ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized)
+ : paths_(){}
+struct FieldMaskDefaultTypeInternal {
+ constexpr FieldMaskDefaultTypeInternal()
+ : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {}
+ ~FieldMaskDefaultTypeInternal() {}
+ union {
+ FieldMask _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT FieldMaskDefaultTypeInternal _FieldMask_default_instance_;
+PROTOBUF_NAMESPACE_CLOSE
+static ::PROTOBUF_NAMESPACE_ID::Metadata file_level_metadata_google_2fprotobuf_2ffield_5fmask_2eproto[1];
+static constexpr ::PROTOBUF_NAMESPACE_ID::EnumDescriptor const** file_level_enum_descriptors_google_2fprotobuf_2ffield_5fmask_2eproto = nullptr;
+static constexpr ::PROTOBUF_NAMESPACE_ID::ServiceDescriptor const** file_level_service_descriptors_google_2fprotobuf_2ffield_5fmask_2eproto = nullptr;
+
+const 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, paths_),
+};
+static const ::PROTOBUF_NAMESPACE_ID::internal::MigrationSchema schemas[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = {
+ { 0, -1, -1, sizeof(::PROTOBUF_NAMESPACE_ID::FieldMask)},
+};
+
+static ::PROTOBUF_NAMESPACE_ID::Message const * const file_default_instances[] = {
+ reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_FieldMask_default_instance_),
+};
+
+const char descriptor_table_protodef_google_2fprotobuf_2ffield_5fmask_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) =
+ "\n google/protobuf/field_mask.proto\022\017goog"
+ "le.protobuf\"\032\n\tFieldMask\022\r\n\005paths\030\001 \003(\tB"
+ "\205\001\n\023com.google.protobufB\016FieldMaskProtoP"
+ "\001Z2google.golang.org/protobuf/types/know"
+ "n/fieldmaskpb\370\001\001\242\002\003GPB\252\002\036Google.Protobuf"
+ ".WellKnownTypesb\006proto3"
+ ;
+static ::PROTOBUF_NAMESPACE_ID::internal::once_flag descriptor_table_google_2fprotobuf_2ffield_5fmask_2eproto_once;
+const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2ffield_5fmask_2eproto = {
+ false, false, 223, descriptor_table_protodef_google_2fprotobuf_2ffield_5fmask_2eproto, "google/protobuf/field_mask.proto",
+ &descriptor_table_google_2fprotobuf_2ffield_5fmask_2eproto_once, nullptr, 0, 1,
+ schemas, file_default_instances, TableStruct_google_2fprotobuf_2ffield_5fmask_2eproto::offsets,
+ file_level_metadata_google_2fprotobuf_2ffield_5fmask_2eproto, file_level_enum_descriptors_google_2fprotobuf_2ffield_5fmask_2eproto, file_level_service_descriptors_google_2fprotobuf_2ffield_5fmask_2eproto,
+};
+PROTOBUF_ATTRIBUTE_WEAK const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable* descriptor_table_google_2fprotobuf_2ffield_5fmask_2eproto_getter() {
+ return &descriptor_table_google_2fprotobuf_2ffield_5fmask_2eproto;
+}
+
+// Force running AddDescriptors() at dynamic initialization time.
+PROTOBUF_ATTRIBUTE_INIT_PRIORITY static ::PROTOBUF_NAMESPACE_ID::internal::AddDescriptorsRunner dynamic_init_dummy_google_2fprotobuf_2ffield_5fmask_2eproto(&descriptor_table_google_2fprotobuf_2ffield_5fmask_2eproto);
+PROTOBUF_NAMESPACE_OPEN
+
+// ===================================================================
+
+class FieldMask::_Internal {
+ public:
+};
+
+FieldMask::FieldMask(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned)
+ : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned),
+ paths_(arena) {
+ SharedCtor();
+ if (!is_message_owned) {
+ RegisterArenaDtor(arena);
+ }
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.FieldMask)
+}
+FieldMask::FieldMask(const FieldMask& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message(),
+ paths_(from.paths_) {
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.FieldMask)
+}
+
+inline void FieldMask::SharedCtor() {
+}
+
+FieldMask::~FieldMask() {
+ // @@protoc_insertion_point(destructor:google.protobuf.FieldMask)
+ if (GetArenaForAllocation() != nullptr) return;
+ SharedDtor();
+ _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+inline void FieldMask::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+}
+
+void FieldMask::ArenaDtor(void* object) {
+ FieldMask* _this = reinterpret_cast< FieldMask* >(object);
+ (void)_this;
+}
+void FieldMask::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) {
+}
+void FieldMask::SetCachedSize(int size) const {
+ _cached_size_.Set(size);
+}
+
+void FieldMask::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.FieldMask)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ paths_.Clear();
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* FieldMask::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag);
+ switch (tag >> 3) {
+ // repeated string paths = 1;
+ case 1:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 10)) {
+ ptr -= 1;
+ do {
+ ptr += 1;
+ auto str = _internal_add_paths();
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx);
+ CHK_(::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.FieldMask.paths"));
+ CHK_(ptr);
+ if (!ctx->DataAvailable(ptr)) break;
+ } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<10>(ptr));
+ } else
+ goto handle_unusual;
+ continue;
+ default:
+ goto handle_unusual;
+ } // switch
+ handle_unusual:
+ if ((tag == 0) || ((tag & 7) == 4)) {
+ CHK_(ptr);
+ ctx->SetLastTag(tag);
+ goto message_done;
+ }
+ ptr = UnknownFieldParse(
+ tag,
+ _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(),
+ ptr, ctx);
+ CHK_(ptr != nullptr);
+ } // while
+message_done:
+ return ptr;
+failure:
+ ptr = nullptr;
+ goto message_done;
+#undef CHK_
+}
+
+uint8_t* FieldMask::_InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const {
+ // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.FieldMask)
+ 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 = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray(
+ _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.FieldMask)
+ return target;
+}
+
+size_t FieldMask::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.FieldMask)
+ size_t total_size = 0;
+
+ 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(paths_.size());
+ for (int i = 0, n = paths_.size(); i < n; i++) {
+ total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
+ paths_.Get(i));
+ }
+
+ return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData FieldMask::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck,
+ FieldMask::MergeImpl
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*FieldMask::GetClassData() const { return &_class_data_; }
+
+void FieldMask::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to,
+ const ::PROTOBUF_NAMESPACE_ID::Message& from) {
+ static_cast<FieldMask *>(to)->MergeFrom(
+ static_cast<const FieldMask &>(from));
+}
+
+
+void FieldMask::MergeFrom(const FieldMask& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.FieldMask)
+ GOOGLE_DCHECK_NE(&from, this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ paths_.MergeFrom(from.paths_);
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+}
+
+void FieldMask::CopyFrom(const FieldMask& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.FieldMask)
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+bool FieldMask::IsInitialized() const {
+ return true;
+}
+
+void FieldMask::InternalSwap(FieldMask* other) {
+ using std::swap;
+ _internal_metadata_.InternalSwap(&other->_internal_metadata_);
+ paths_.InternalSwap(&other->paths_);
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata FieldMask::GetMetadata() const {
+ return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(
+ &descriptor_table_google_2fprotobuf_2ffield_5fmask_2eproto_getter, &descriptor_table_google_2fprotobuf_2ffield_5fmask_2eproto_once,
+ file_level_metadata_google_2fprotobuf_2ffield_5fmask_2eproto[0]);
+}
+
+// @@protoc_insertion_point(namespace_scope)
+PROTOBUF_NAMESPACE_CLOSE
+PROTOBUF_NAMESPACE_OPEN
+template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::FieldMask* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::FieldMask >(Arena* arena) {
+ return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::FieldMask >(arena);
+}
+PROTOBUF_NAMESPACE_CLOSE
+
+// @@protoc_insertion_point(global_scope)
+#include <port_undef.inc>
diff --git a/NorthstarDedicatedTest/include/protobuf/field_mask.pb.h b/NorthstarDedicatedTest/include/protobuf/field_mask.pb.h
new file mode 100644
index 00000000..20a9eaf7
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/field_mask.pb.h
@@ -0,0 +1,324 @@
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+// source: google/protobuf/field_mask.proto
+
+#ifndef GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2ffield_5fmask_2eproto
+#define GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2ffield_5fmask_2eproto
+
+#include <limits>
+#include <string>
+
+#include <port_def.inc>
+#if PROTOBUF_VERSION < 3019000
+#error This file was generated by a newer version of protoc which is
+#error incompatible with your Protocol Buffer headers. Please update
+#error your headers.
+#endif
+#if 3019004 < 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 <port_undef.inc>
+#include <io/coded_stream.h>
+#include <arena.h>
+#include <arenastring.h>
+#include <generated_message_table_driven.h>
+#include <generated_message_util.h>
+#include <metadata_lite.h>
+#include <generated_message_reflection.h>
+#include <message.h>
+#include <repeated_field.h> // IWYU pragma: export
+#include <extension_set.h> // IWYU pragma: export
+#include <unknown_field_set.h>
+// @@protoc_insertion_point(includes)
+#include <port_def.inc>
+#define PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2ffield_5fmask_2eproto PROTOBUF_EXPORT
+PROTOBUF_NAMESPACE_OPEN
+namespace internal {
+class AnyMetadata;
+} // namespace internal
+PROTOBUF_NAMESPACE_CLOSE
+
+// Internal implementation detail -- do not use these members.
+struct PROTOBUF_EXPORT TableStruct_google_2fprotobuf_2ffield_5fmask_2eproto {
+ static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTableField entries[]
+ PROTOBUF_SECTION_VARIABLE(protodesc_cold);
+ static const ::PROTOBUF_NAMESPACE_ID::internal::AuxiliaryParseTableField aux[]
+ PROTOBUF_SECTION_VARIABLE(protodesc_cold);
+ static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTable schema[1]
+ PROTOBUF_SECTION_VARIABLE(protodesc_cold);
+ static const ::PROTOBUF_NAMESPACE_ID::internal::FieldMetadata field_metadata[];
+ static const ::PROTOBUF_NAMESPACE_ID::internal::SerializationTable serialization_table[];
+ static const 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 constexpr FieldMask(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
+
+ FieldMask(const FieldMask& from);
+ FieldMask(FieldMask&& from) noexcept
+ : FieldMask() {
+ *this = ::std::move(from);
+ }
+
+ inline FieldMask& operator=(const FieldMask& from) {
+ CopyFrom(from);
+ return *this;
+ }
+ inline FieldMask& operator=(FieldMask&& from) noexcept {
+ if (this == &from) return *this;
+ if (GetOwningArena() == from.GetOwningArena()
+ #ifdef PROTOBUF_FORCE_COPY_IN_MOVE
+ && GetOwningArena() != nullptr
+ #endif // !PROTOBUF_FORCE_COPY_IN_MOVE
+ ) {
+ InternalSwap(&from);
+ } else {
+ CopyFrom(from);
+ }
+ return *this;
+ }
+
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
+ return GetDescriptor();
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
+ return default_instance().GetMetadata().descriptor;
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
+ return default_instance().GetMetadata().reflection;
+ }
+ static const FieldMask& default_instance() {
+ return *internal_default_instance();
+ }
+ static inline const FieldMask* internal_default_instance() {
+ return reinterpret_cast<const FieldMask*>(
+ &_FieldMask_default_instance_);
+ }
+ static constexpr int kIndexInFileMessages =
+ 0;
+
+ friend void swap(FieldMask& a, FieldMask& b) {
+ a.Swap(&b);
+ }
+ inline void Swap(FieldMask* other) {
+ if (other == this) return;
+ #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() != nullptr &&
+ GetOwningArena() == other->GetOwningArena()) {
+ #else // PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() == other->GetOwningArena()) {
+ #endif // !PROTOBUF_FORCE_COPY_IN_SWAP
+ InternalSwap(other);
+ } else {
+ ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
+ }
+ }
+ void UnsafeArenaSwap(FieldMask* other) {
+ if (other == this) return;
+ GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena());
+ InternalSwap(other);
+ }
+
+ // implements Message ----------------------------------------------
+
+ FieldMask* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
+ return CreateMaybeMessage<FieldMask>(arena);
+ }
+ using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
+ void CopyFrom(const FieldMask& from);
+ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
+ void MergeFrom(const FieldMask& from);
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from);
+ public:
+ PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+ bool IsInitialized() const final;
+
+ size_t ByteSizeLong() const final;
+ const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
+ uint8_t* _InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
+ int GetCachedSize() const final { return _cached_size_.Get(); }
+
+ private:
+ void SharedCtor();
+ void SharedDtor();
+ void SetCachedSize(int size) const final;
+ void InternalSwap(FieldMask* other);
+
+ private:
+ friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
+ static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
+ return "google.protobuf.FieldMask";
+ }
+ protected:
+ explicit FieldMask(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned = false);
+ private:
+ static void ArenaDtor(void* object);
+ inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
+ public:
+
+ static const ClassData _class_data_;
+ const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;
+
+ ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;
+
+ // nested types ----------------------------------------------------
+
+ // accessors -------------------------------------------------------
+
+ enum : int {
+ kPathsFieldNumber = 1,
+ };
+ // repeated string paths = 1;
+ int paths_size() const;
+ private:
+ int _internal_paths_size() const;
+ public:
+ void clear_paths();
+ const 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_;
+ ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string> paths_;
+ mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
+ friend struct ::TableStruct_google_2fprotobuf_2ffield_5fmask_2eproto;
+};
+// ===================================================================
+
+
+// ===================================================================
+
+#ifdef __GNUC__
+ #pragma GCC diagnostic push
+ #pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#endif // __GNUC__
+// FieldMask
+
+// repeated string paths = 1;
+inline int FieldMask::_internal_paths_size() const {
+ return paths_.size();
+}
+inline int FieldMask::paths_size() const {
+ return _internal_paths_size();
+}
+inline void FieldMask::clear_paths() {
+ paths_.Clear();
+}
+inline 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 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 paths_.Mutable(index);
+}
+inline void FieldMask::set_paths(int index, const std::string& value) {
+ paths_.Mutable(index)->assign(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.FieldMask.paths)
+}
+inline void FieldMask::set_paths(int index, std::string&& value) {
+ paths_.Mutable(index)->assign(std::move(value));
+ // @@protoc_insertion_point(field_set:google.protobuf.FieldMask.paths)
+}
+inline void FieldMask::set_paths(int index, const char* value) {
+ GOOGLE_DCHECK(value != nullptr);
+ paths_.Mutable(index)->assign(value);
+ // @@protoc_insertion_point(field_set_char:google.protobuf.FieldMask.paths)
+}
+inline void FieldMask::set_paths(int index, const char* value, size_t size) {
+ paths_.Mutable(index)->assign(
+ reinterpret_cast<const char*>(value), size);
+ // @@protoc_insertion_point(field_set_pointer:google.protobuf.FieldMask.paths)
+}
+inline std::string* FieldMask::_internal_add_paths() {
+ return paths_.Add();
+}
+inline void FieldMask::add_paths(const std::string& value) {
+ paths_.Add()->assign(value);
+ // @@protoc_insertion_point(field_add:google.protobuf.FieldMask.paths)
+}
+inline void FieldMask::add_paths(std::string&& value) {
+ paths_.Add(std::move(value));
+ // @@protoc_insertion_point(field_add:google.protobuf.FieldMask.paths)
+}
+inline void FieldMask::add_paths(const char* value) {
+ GOOGLE_DCHECK(value != nullptr);
+ paths_.Add()->assign(value);
+ // @@protoc_insertion_point(field_add_char:google.protobuf.FieldMask.paths)
+}
+inline void FieldMask::add_paths(const char* value, size_t size) {
+ paths_.Add()->assign(reinterpret_cast<const char*>(value), size);
+ // @@protoc_insertion_point(field_add_pointer:google.protobuf.FieldMask.paths)
+}
+inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string>&
+FieldMask::paths() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.FieldMask.paths)
+ return paths_;
+}
+inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string>*
+FieldMask::mutable_paths() {
+ // @@protoc_insertion_point(field_mutable_list:google.protobuf.FieldMask.paths)
+ return &paths_;
+}
+
+#ifdef __GNUC__
+ #pragma GCC diagnostic pop
+#endif // __GNUC__
+
+// @@protoc_insertion_point(namespace_scope)
+
+PROTOBUF_NAMESPACE_CLOSE
+
+// @@protoc_insertion_point(global_scope)
+
+#include <port_undef.inc>
+#endif // GOOGLE_PROTOBUF_INCLUDED_GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2ffield_5fmask_2eproto
diff --git a/NorthstarDedicatedTest/include/protobuf/field_mask.proto b/NorthstarDedicatedTest/include/protobuf/field_mask.proto
new file mode 100644
index 00000000..6b5104f1
--- /dev/null
+++ b/NorthstarDedicatedTest/include/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/NorthstarDedicatedTest/include/protobuf/generated_enum_reflection.h b/NorthstarDedicatedTest/include/protobuf/generated_enum_reflection.h
new file mode 100644
index 00000000..5e142df4
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/generated_enum_reflection.h
@@ -0,0 +1,98 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: jasonh@google.com (Jason Hsueh)
+//
+// This header is logically internal, but is made public because it is used
+// from protocol-compiler-generated code, which may reside in other components.
+// It provides reflection support for generated enums, and is included in
+// generated .pb.h files and should have minimal dependencies. The methods are
+// implemented in generated_message_reflection.cc.
+
+#ifndef GOOGLE_PROTOBUF_GENERATED_ENUM_REFLECTION_H__
+#define GOOGLE_PROTOBUF_GENERATED_ENUM_REFLECTION_H__
+
+#include <string>
+
+#include <generated_enum_util.h>
+#include <port.h>
+#include <stubs/strutil.h>
+
+#ifdef SWIG
+#error "You cannot SWIG proto headers"
+#endif
+
+#include <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 <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_GENERATED_ENUM_REFLECTION_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/generated_enum_util.cc b/NorthstarDedicatedTest/include/protobuf/generated_enum_util.cc
new file mode 100644
index 00000000..70c43819
--- /dev/null
+++ b/NorthstarDedicatedTest/include/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 <generated_enum_util.h>
+
+#include <algorithm>
+
+#include <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/NorthstarDedicatedTest/include/protobuf/generated_enum_util.h b/NorthstarDedicatedTest/include/protobuf/generated_enum_util.h
new file mode 100644
index 00000000..e519a6af
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/generated_enum_util.h
@@ -0,0 +1,83 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef GOOGLE_PROTOBUF_GENERATED_ENUM_UTIL_H__
+#define GOOGLE_PROTOBUF_GENERATED_ENUM_UTIL_H__
+
+#include <type_traits>
+
+#include <message_lite.h>
+#include <stubs/strutil.h>
+
+#include <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 <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_GENERATED_ENUM_UTIL_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/generated_message_bases.cc b/NorthstarDedicatedTest/include/protobuf/generated_message_bases.cc
new file mode 100644
index 00000000..16054ef7
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/generated_message_bases.cc
@@ -0,0 +1,125 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <generated_message_bases.h>
+
+#include <parse_context.h>
+#include <io/coded_stream.h>
+#include <io/zero_copy_stream_impl.h>
+#include <unknown_field_set.h>
+#include <wire_format.h>
+#include <wire_format_lite.h>
+
+// Must be last:
+#include <port_def.inc>
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+// =============================================================================
+// ZeroFieldsBase
+
+void ZeroFieldsBase::Clear() {
+ _internal_metadata_.Clear<UnknownFieldSet>(); //
+}
+
+ZeroFieldsBase::~ZeroFieldsBase() {
+ if (GetArenaForAllocation() != nullptr) return;
+ _internal_metadata_.Delete<UnknownFieldSet>();
+}
+
+size_t ZeroFieldsBase::ByteSizeLong() const {
+ return MaybeComputeUnknownFieldsSize(0, &_cached_size_);
+}
+
+const char* ZeroFieldsBase::_InternalParse(const char* ptr,
+ internal::ParseContext* ctx) {
+#define CHK_(x) \
+ if (PROTOBUF_PREDICT_FALSE(!(x))) { \
+ goto failure; \
+ }
+
+ while (!ctx->Done(&ptr)) {
+ 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 <port_undef.inc>
diff --git a/NorthstarDedicatedTest/include/protobuf/generated_message_bases.h b/NorthstarDedicatedTest/include/protobuf/generated_message_bases.h
new file mode 100644
index 00000000..3a54356d
--- /dev/null
+++ b/NorthstarDedicatedTest/include/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 <parse_context.h>
+#include <io/zero_copy_stream_impl.h>
+#include <arena.h>
+#include <generated_message_util.h>
+#include <message.h>
+
+// Must come last:
+#include <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 <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_GENERATED_MESSAGE_BASES_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/generated_message_reflection.cc b/NorthstarDedicatedTest/include/protobuf/generated_message_reflection.cc
new file mode 100644
index 00000000..ba24b157
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/generated_message_reflection.cc
@@ -0,0 +1,3041 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <generated_message_reflection.h>
+
+#include <algorithm>
+#include <set>
+
+#include <stubs/logging.h>
+#include <stubs/common.h>
+#include <descriptor.pb.h>
+#include <descriptor.h>
+#include <extension_set.h>
+#include <generated_message_util.h>
+#include <inlined_string_field.h>
+#include <map_field.h>
+#include <map_field_inl.h>
+#include <stubs/mutex.h>
+#include <repeated_field.h>
+#include <unknown_field_set.h>
+#include <wire_format.h>
+#include <stubs/casts.h>
+#include <stubs/strutil.h>
+
+
+// clang-format off
+#include <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 {
+ return field->options().lazy();
+}
+
+bool Reflection::IsEagerlyVerifiedLazyField(
+ const FieldDescriptor* field) const {
+ return (field->type() == FieldDescriptor::TYPE_MESSAGE &&
+ schema_.IsEagerlyVerifiedLazyField(field));
+}
+
+bool Reflection::IsInlined(const FieldDescriptor* field) const {
+ return schema_.IsFieldInlined(field);
+}
+
+size_t Reflection::SpaceUsedLong(const Message& message) const {
+ // object_size_ already includes the in-memory representation of each field
+ // in the message, so we only need to account for additional memory used by
+ // the fields.
+ size_t total_size = schema_.GetObjectSize();
+
+ total_size += GetUnknownFields(message).SpaceUsedExcludingSelfLong();
+
+ if (schema_.HasExtensionSet()) {
+ total_size += GetExtensionSet(message).SpaceUsedExcludingSelfLong();
+ }
+ for (int i = 0; i <= last_non_weak_field_index_; i++) {
+ const FieldDescriptor* field = descriptor_->field(i);
+ if (field->is_repeated()) {
+ switch (field->cpp_type()) {
+#define HANDLE_TYPE(UPPERCASE, LOWERCASE) \
+ case FieldDescriptor::CPPTYPE_##UPPERCASE: \
+ total_size += GetRaw<RepeatedField<LOWERCASE> >(message, field) \
+ .SpaceUsedExcludingSelfLong(); \
+ break
+
+ HANDLE_TYPE(INT32, 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);
+ break;
+ }
+
+ const std::string* ptr =
+ GetField<ArenaStringPtr>(message, field).GetPointer();
+
+ // Initially, the string points to the default value stored
+ // in the prototype. Only count the string if it has been
+ // changed from the default value.
+ // Except oneof fields, those never point to a default instance,
+ // and there is no default instance to point to.
+ if (schema_.InRealOneof(field) ||
+ ptr != DefaultRaw<ArenaStringPtr>(field).GetPointer()) {
+ // string fields are represented by just a pointer, so also
+ // include sizeof(string) as well.
+ total_size +=
+ sizeof(*ptr) + StringSpaceUsedExcludingSelfLong(*ptr);
+ }
+ break;
+ }
+ }
+ break;
+ }
+
+ case FieldDescriptor::CPPTYPE_MESSAGE:
+ if (schema_.IsDefaultInstance(message)) {
+ // For singular fields, the prototype just stores a pointer to the
+ // external type's prototype, so there is no extra memory usage.
+ } else {
+ const Message* sub_message = GetRaw<const Message*>(message, field);
+ if (sub_message != nullptr) {
+ total_size += sub_message->SpaceUsedLong();
+ }
+ }
+ break;
+ }
+ }
+ }
+ return total_size;
+}
+
+namespace {
+
+template <bool unsafe_shallow_swap>
+struct OneofFieldMover {
+ template <typename FromType, typename ToType>
+ void operator()(const FieldDescriptor* field, FromType* from, ToType* to) {
+ switch (field->cpp_type()) {
+ case FieldDescriptor::CPPTYPE_INT32:
+ to->SetInt32(from->GetInt32());
+ break;
+ case FieldDescriptor::CPPTYPE_INT64:
+ to->SetInt64(from->GetInt64());
+ break;
+ case FieldDescriptor::CPPTYPE_UINT32:
+ to->SetUint32(from->GetUint32());
+ break;
+ case FieldDescriptor::CPPTYPE_UINT64:
+ to->SetUint64(from->GetUint64());
+ break;
+ case FieldDescriptor::CPPTYPE_FLOAT:
+ to->SetFloat(from->GetFloat());
+ break;
+ case FieldDescriptor::CPPTYPE_DOUBLE:
+ to->SetDouble(from->GetDouble());
+ break;
+ case FieldDescriptor::CPPTYPE_BOOL:
+ to->SetBool(from->GetBool());
+ break;
+ case FieldDescriptor::CPPTYPE_ENUM:
+ to->SetEnum(from->GetEnum());
+ break;
+ case FieldDescriptor::CPPTYPE_MESSAGE:
+ if (!unsafe_shallow_swap) {
+ to->SetMessage(from->GetMessage());
+ } else {
+ to->UnsafeSetMessage(from->UnsafeGetMessage());
+ }
+ break;
+ case FieldDescriptor::CPPTYPE_STRING:
+ if (!unsafe_shallow_swap) {
+ to->SetString(from->GetString());
+ break;
+ }
+ switch (field->options().ctype()) {
+ default:
+ case FieldOptions::STRING: {
+ to->SetArenaStringPtr(from->GetArenaStringPtr());
+ break;
+ }
+ }
+ break;
+ default:
+ GOOGLE_LOG(FATAL) << "unimplemented type: " << field->cpp_type();
+ }
+ if (unsafe_shallow_swap) {
+ // Not clearing oneof case after move may cause unwanted "ClearOneof"
+ // where the residual message or string value is deleted and causes
+ // use-after-free (only for unsafe swap).
+ from->ClearOneofCase();
+ }
+ }
+};
+
+} // namespace
+
+namespace internal {
+
+class SwapFieldHelper {
+ public:
+ template <bool unsafe_shallow_swap>
+ static void SwapRepeatedStringField(const Reflection* r, Message* lhs,
+ Message* rhs,
+ const FieldDescriptor* field);
+
+ template <bool unsafe_shallow_swap>
+ static void SwapInlinedStrings(const Reflection* r, Message* lhs,
+ Message* rhs, const FieldDescriptor* field);
+
+ template <bool unsafe_shallow_swap>
+ static void SwapNonInlinedStrings(const Reflection* r, Message* lhs,
+ Message* rhs, const FieldDescriptor* field);
+
+ template <bool unsafe_shallow_swap>
+ static void SwapStringField(const Reflection* r, Message* lhs, Message* rhs,
+ const FieldDescriptor* field);
+
+ static void SwapArenaStringPtr(const std::string* default_ptr,
+ ArenaStringPtr* lhs, Arena* lhs_arena,
+ ArenaStringPtr* rhs, Arena* rhs_arena);
+
+ template <bool unsafe_shallow_swap>
+ static void SwapRepeatedMessageField(const Reflection* r, Message* lhs,
+ Message* rhs,
+ const FieldDescriptor* field);
+
+ template <bool unsafe_shallow_swap>
+ static void SwapMessageField(const Reflection* r, Message* lhs, Message* rhs,
+ const FieldDescriptor* field);
+
+ static void SwapMessage(const Reflection* r, Message* lhs, Arena* lhs_arena,
+ Message* rhs, Arena* rhs_arena,
+ const FieldDescriptor* field);
+};
+
+template <bool unsafe_shallow_swap>
+void SwapFieldHelper::SwapRepeatedStringField(const Reflection* r, Message* lhs,
+ Message* rhs,
+ const FieldDescriptor* field) {
+ switch (field->options().ctype()) {
+ default:
+ case FieldOptions::STRING: {
+ auto* lhs_string = r->MutableRaw<RepeatedPtrFieldBase>(lhs, field);
+ auto* rhs_string = r->MutableRaw<RepeatedPtrFieldBase>(rhs, field);
+ if (unsafe_shallow_swap) {
+ lhs_string->InternalSwap(rhs_string);
+ } else {
+ lhs_string->Swap<GenericTypeHandler<std::string>>(rhs_string);
+ }
+ break;
+ }
+ }
+}
+
+template <bool unsafe_shallow_swap>
+void SwapFieldHelper::SwapInlinedStrings(const Reflection* r, Message* lhs,
+ Message* rhs,
+ const FieldDescriptor* field) {
+ // Inlined string field.
+ Arena* lhs_arena = lhs->GetArenaForAllocation();
+ Arena* rhs_arena = rhs->GetArenaForAllocation();
+ auto* lhs_string = r->MutableRaw<InlinedStringField>(lhs, field);
+ auto* rhs_string = r->MutableRaw<InlinedStringField>(rhs, field);
+ const uint32 index = r->schema_.InlinedStringIndex(field);
+ uint32* lhs_state = &r->MutableInlinedStringDonatedArray(lhs)[index / 32];
+ uint32* rhs_state = &r->MutableInlinedStringDonatedArray(rhs)[index / 32];
+ const uint32 mask = ~(static_cast<uint32>(1) << (index % 32));
+ if (unsafe_shallow_swap || lhs_arena == rhs_arena) {
+ lhs_string->Swap(rhs_string, /*default_value=*/nullptr, lhs_arena,
+ r->IsInlinedStringDonated(*lhs, field),
+ r->IsInlinedStringDonated(*rhs, field),
+ /*donating_states=*/lhs_state, rhs_state, mask);
+ } else {
+ const std::string temp = lhs_string->Get();
+ lhs_string->Set(nullptr, rhs_string->Get(), lhs_arena,
+ r->IsInlinedStringDonated(*lhs, field), lhs_state, mask);
+ rhs_string->Set(nullptr, temp, rhs_arena,
+ r->IsInlinedStringDonated(*rhs, field), rhs_state, mask);
+ }
+}
+
+template <bool unsafe_shallow_swap>
+void SwapFieldHelper::SwapNonInlinedStrings(const Reflection* r, Message* lhs,
+ Message* rhs,
+ const FieldDescriptor* field) {
+ ArenaStringPtr* lhs_string = r->MutableRaw<ArenaStringPtr>(lhs, field);
+ ArenaStringPtr* rhs_string = r->MutableRaw<ArenaStringPtr>(rhs, field);
+ if (unsafe_shallow_swap) {
+ ArenaStringPtr::UnsafeShallowSwap(lhs_string, rhs_string);
+ } else {
+ SwapFieldHelper::SwapArenaStringPtr(
+ r->DefaultRaw<ArenaStringPtr>(field).GetPointer(), //
+ lhs_string, lhs->GetArenaForAllocation(), //
+ rhs_string, rhs->GetArenaForAllocation());
+ }
+}
+
+template <bool unsafe_shallow_swap>
+void SwapFieldHelper::SwapStringField(const Reflection* r, Message* lhs,
+ Message* rhs,
+ const FieldDescriptor* field) {
+ switch (field->options().ctype()) {
+ default:
+ case FieldOptions::STRING: {
+ if (r->IsInlined(field)) {
+ SwapFieldHelper::SwapInlinedStrings<unsafe_shallow_swap>(r, lhs, rhs,
+ field);
+ } else {
+ SwapFieldHelper::SwapNonInlinedStrings<unsafe_shallow_swap>(r, lhs, rhs,
+ field);
+ }
+ break;
+ }
+ }
+}
+
+void SwapFieldHelper::SwapArenaStringPtr(const std::string* default_ptr,
+ ArenaStringPtr* lhs, Arena* lhs_arena,
+ ArenaStringPtr* rhs,
+ Arena* rhs_arena) {
+ if (lhs_arena == rhs_arena) {
+ ArenaStringPtr::InternalSwap(default_ptr, lhs, lhs_arena, rhs, rhs_arena);
+ } else if (lhs->IsDefault(default_ptr) && rhs->IsDefault(default_ptr)) {
+ // Nothing to do.
+ } else if (lhs->IsDefault(default_ptr)) {
+ lhs->Set(default_ptr, rhs->Get(), lhs_arena);
+ // rhs needs to be destroyed before overwritten.
+ rhs->Destroy(default_ptr, rhs_arena);
+ rhs->UnsafeSetDefault(default_ptr);
+ } else if (rhs->IsDefault(default_ptr)) {
+ rhs->Set(default_ptr, lhs->Get(), rhs_arena);
+ // lhs needs to be destroyed before overwritten.
+ lhs->Destroy(default_ptr, lhs_arena);
+ lhs->UnsafeSetDefault(default_ptr);
+ } else {
+ std::string temp = lhs->Get();
+ lhs->Set(default_ptr, rhs->Get(), lhs_arena);
+ rhs->Set(default_ptr, std::move(temp), rhs_arena);
+ }
+}
+
+template <bool unsafe_shallow_swap>
+void SwapFieldHelper::SwapRepeatedMessageField(const Reflection* r,
+ Message* lhs, Message* rhs,
+ const FieldDescriptor* field) {
+ if (IsMapFieldInApi(field)) {
+ auto* lhs_map = r->MutableRaw<MapFieldBase>(lhs, field);
+ auto* rhs_map = r->MutableRaw<MapFieldBase>(rhs, field);
+ if (unsafe_shallow_swap) {
+ lhs_map->UnsafeShallowSwap(rhs_map);
+ } else {
+ lhs_map->Swap(rhs_map);
+ }
+ } else {
+ auto* lhs_rm = r->MutableRaw<RepeatedPtrFieldBase>(lhs, field);
+ auto* rhs_rm = r->MutableRaw<RepeatedPtrFieldBase>(rhs, field);
+ if (unsafe_shallow_swap) {
+ lhs_rm->InternalSwap(rhs_rm);
+ } else {
+ lhs_rm->Swap<GenericTypeHandler<Message>>(rhs_rm);
+ }
+ }
+}
+
+template <bool unsafe_shallow_swap>
+void SwapFieldHelper::SwapMessageField(const Reflection* r, Message* lhs,
+ Message* rhs,
+ const FieldDescriptor* field) {
+ if (unsafe_shallow_swap) {
+ std::swap(*r->MutableRaw<Message*>(lhs, field),
+ *r->MutableRaw<Message*>(rhs, field));
+ } else {
+ SwapMessage(r, lhs, lhs->GetArenaForAllocation(), rhs,
+ rhs->GetArenaForAllocation(), field);
+ }
+}
+
+void SwapFieldHelper::SwapMessage(const Reflection* r, Message* lhs,
+ Arena* lhs_arena, Message* rhs,
+ Arena* rhs_arena,
+ const FieldDescriptor* field) {
+ Message** lhs_sub = r->MutableRaw<Message*>(lhs, field);
+ Message** rhs_sub = r->MutableRaw<Message*>(rhs, field);
+
+ if (*lhs_sub == *rhs_sub) return;
+
+#ifdef PROTOBUF_FORCE_COPY_IN_SWAP
+ if (lhs_arena != nullptr && lhs_arena == rhs_arena) {
+#else // PROTOBUF_FORCE_COPY_IN_SWAP
+ if (lhs_arena == rhs_arena) {
+#endif // !PROTOBUF_FORCE_COPY_IN_SWAP
+ std::swap(*lhs_sub, *rhs_sub);
+ return;
+ }
+
+ if (*lhs_sub != nullptr && *rhs_sub != nullptr) {
+ (*lhs_sub)->GetReflection()->Swap(*lhs_sub, *rhs_sub);
+ } else if (*lhs_sub == nullptr && r->HasBit(*rhs, field)) {
+ *lhs_sub = (*rhs_sub)->New(lhs_arena);
+ (*lhs_sub)->CopyFrom(**rhs_sub);
+ r->ClearField(rhs, field);
+ // Ensures has bit is unchanged after ClearField.
+ r->SetBit(rhs, field);
+ } else if (*rhs_sub == nullptr && r->HasBit(*lhs, field)) {
+ *rhs_sub = (*lhs_sub)->New(rhs_arena);
+ (*rhs_sub)->CopyFrom(**lhs_sub);
+ r->ClearField(lhs, field);
+ // Ensures has bit is unchanged after ClearField.
+ r->SetBit(lhs, field);
+ }
+}
+
+} // namespace internal
+
+void Reflection::SwapField(Message* message1, Message* message2,
+ const FieldDescriptor* field) const {
+ if (field->is_repeated()) {
+ switch (field->cpp_type()) {
+#define SWAP_ARRAYS(CPPTYPE, TYPE) \
+ case FieldDescriptor::CPPTYPE_##CPPTYPE: \
+ MutableRaw<RepeatedField<TYPE> >(message1, field) \
+ ->Swap(MutableRaw<RepeatedField<TYPE> >(message2, field)); \
+ break;
+
+ SWAP_ARRAYS(INT32, 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()) {
+#define SWAP_VALUES(CPPTYPE, TYPE) \
+ case FieldDescriptor::CPPTYPE_##CPPTYPE: \
+ std::swap(*MutableRaw<TYPE>(message1, field), \
+ *MutableRaw<TYPE>(message2, 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
+ case FieldDescriptor::CPPTYPE_MESSAGE:
+ internal::SwapFieldHelper::SwapMessageField<false>(this, message1,
+ message2, field);
+ break;
+
+ case FieldDescriptor::CPPTYPE_STRING:
+ internal::SwapFieldHelper::SwapStringField<false>(this, message1,
+ message2, field);
+ break;
+
+ default:
+ GOOGLE_LOG(FATAL) << "Unimplemented type: " << field->cpp_type();
+ }
+ }
+}
+
+void Reflection::UnsafeShallowSwapField(Message* message1, Message* message2,
+ const FieldDescriptor* field) const {
+ if (!field->is_repeated()) {
+ if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+ internal::SwapFieldHelper::SwapMessageField<true>(this, message1,
+ message2, field);
+ } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING) {
+ internal::SwapFieldHelper::SwapStringField<true>(this, message1, message2,
+ field);
+ } else {
+ SwapField(message1, message2, field);
+ }
+ return;
+ }
+
+ switch (field->cpp_type()) {
+#define SHALLOW_SWAP_ARRAYS(CPPTYPE, TYPE) \
+ case FieldDescriptor::CPPTYPE_##CPPTYPE: \
+ MutableRaw<RepeatedField<TYPE>>(message1, field) \
+ ->InternalSwap(MutableRaw<RepeatedField<TYPE>>(message2, field)); \
+ break;
+
+ SHALLOW_SWAP_ARRAYS(INT32, 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 oneof_case_lhs = GetOneofCase(*lhs, oneof_descriptor);
+ uint32 oneof_case_rhs = GetOneofCase(*rhs, oneof_descriptor);
+
+ LocalVarWrapper temp;
+ MessageWrapper lhs_wrapper, rhs_wrapper;
+ const FieldDescriptor* field_lhs = nullptr;
+ OneofFieldMover<unsafe_shallow_swap> mover;
+ // lhs --> temp
+ if (oneof_case_lhs > 0) {
+ field_lhs = descriptor_->FindFieldByNumber(oneof_case_lhs);
+ lhs_wrapper = {this, lhs, field_lhs};
+ mover(field_lhs, &lhs_wrapper, &temp);
+ }
+ // rhs --> lhs
+ if (oneof_case_rhs > 0) {
+ const FieldDescriptor* f = descriptor_->FindFieldByNumber(oneof_case_rhs);
+ lhs_wrapper = {this, lhs, f};
+ rhs_wrapper = {this, rhs, f};
+ mover(f, &rhs_wrapper, &lhs_wrapper);
+ } else if (!unsafe_shallow_swap) {
+ ClearOneof(lhs, oneof_descriptor);
+ }
+ // temp --> rhs
+ if (oneof_case_lhs > 0) {
+ rhs_wrapper = {this, rhs, field_lhs};
+ mover(field_lhs, &temp, &rhs_wrapper);
+ } else if (!unsafe_shallow_swap) {
+ ClearOneof(rhs, oneof_descriptor);
+ }
+
+ if (unsafe_shallow_swap) {
+ *MutableOneofCase(lhs, oneof_descriptor) = oneof_case_rhs;
+ *MutableOneofCase(rhs, oneof_descriptor) = oneof_case_lhs;
+ }
+}
+
+void Reflection::Swap(Message* message1, Message* message2) const {
+ if (message1 == message2) return;
+
+ // TODO(kenton): Other Reflection methods should probably check this too.
+ GOOGLE_CHECK_EQ(message1->GetReflection(), this)
+ << "First argument to Swap() (of type \""
+ << message1->GetDescriptor()->full_name()
+ << "\") is not compatible with this reflection object (which is for type "
+ "\""
+ << descriptor_->full_name()
+ << "\"). Note that the exact same class is required; not just the same "
+ "descriptor.";
+ GOOGLE_CHECK_EQ(message2->GetReflection(), this)
+ << "Second argument to Swap() (of type \""
+ << message2->GetDescriptor()->full_name()
+ << "\") is not compatible with this reflection object (which is for type "
+ "\""
+ << descriptor_->full_name()
+ << "\"). Note that the exact same class is required; not just the same "
+ "descriptor.";
+
+ // Check that both messages are in the same arena (or both on the heap). We
+ // need to copy all data if not, due to ownership semantics.
+#ifdef PROTOBUF_FORCE_COPY_IN_SWAP
+ if (message1->GetOwningArena() == nullptr ||
+ message1->GetOwningArena() != message2->GetOwningArena()) {
+#else // PROTOBUF_FORCE_COPY_IN_SWAP
+ if (message1->GetOwningArena() != message2->GetOwningArena()) {
+#endif // !PROTOBUF_FORCE_COPY_IN_SWAP
+ // One of the two is guaranteed to have an arena. Switch things around
+ // to guarantee that message1 has an arena.
+ Arena* arena = message1->GetOwningArena();
+ if (arena == nullptr) {
+ arena = message2->GetOwningArena();
+ std::swap(message1, message2); // Swapping names for pointers!
+ }
+
+ Message* temp = message1->New(arena);
+ temp->MergeFrom(*message2);
+ message2->CopyFrom(*message1);
+#ifdef PROTOBUF_FORCE_COPY_IN_SWAP
+ message1->CopyFrom(*temp);
+ if (arena == nullptr) delete temp;
+#else // PROTOBUF_FORCE_COPY_IN_SWAP
+ Swap(message1, temp);
+#endif // !PROTOBUF_FORCE_COPY_IN_SWAP
+ return;
+ }
+
+ GOOGLE_DCHECK_EQ(message1->GetOwningArena(), message2->GetOwningArena());
+
+ UnsafeArenaSwap(message1, message2);
+}
+
+template <bool unsafe_shallow_swap>
+void Reflection::SwapFieldsImpl(
+ Message* message1, Message* message2,
+ const std::vector<const FieldDescriptor*>& fields) const {
+ if (message1 == message2) return;
+
+ // TODO(kenton): Other Reflection methods should probably check this too.
+ GOOGLE_CHECK_EQ(message1->GetReflection(), this)
+ << "First argument to SwapFields() (of type \""
+ << message1->GetDescriptor()->full_name()
+ << "\") is not compatible with this reflection object (which is for type "
+ "\""
+ << descriptor_->full_name()
+ << "\"). Note that the exact same class is required; not just the same "
+ "descriptor.";
+ GOOGLE_CHECK_EQ(message2->GetReflection(), this)
+ << "Second argument to SwapFields() (of type \""
+ << message2->GetDescriptor()->full_name()
+ << "\") is not compatible with this reflection object (which is for type "
+ "\""
+ << descriptor_->full_name()
+ << "\"). Note that the exact same class is required; not just the same "
+ "descriptor.";
+
+ std::set<int> swapped_oneof;
+
+ GOOGLE_DCHECK(!unsafe_shallow_swap || message1->GetArenaForAllocation() ==
+ message2->GetArenaForAllocation());
+
+ const Message* prototype =
+ message_factory_->GetPrototype(message1->GetDescriptor());
+ for (const auto* field : fields) {
+ CheckInvalidAccess(schema_, field);
+ if (field->is_extension()) {
+ if (unsafe_shallow_swap) {
+ MutableExtensionSet(message1)->UnsafeShallowSwapExtension(
+ MutableExtensionSet(message2), field->number());
+ } else {
+ MutableExtensionSet(message1)->SwapExtension(
+ prototype, MutableExtensionSet(message2), field->number());
+ }
+ } else {
+ if (schema_.InRealOneof(field)) {
+ int oneof_index = field->containing_oneof()->index();
+ // Only swap the oneof field once.
+ if (swapped_oneof.find(oneof_index) != swapped_oneof.end()) {
+ continue;
+ }
+ swapped_oneof.insert(oneof_index);
+ SwapOneofField<unsafe_shallow_swap>(message1, message2,
+ field->containing_oneof());
+ } else {
+ // Swap field.
+ if (unsafe_shallow_swap) {
+ UnsafeShallowSwapField(message1, message2, field);
+ } else {
+ SwapField(message1, message2, field);
+ }
+ // Swap has bit for non-repeated fields. We have already checked for
+ // oneof already. This has to be done after SwapField, because SwapField
+ // may depend on the information in has bits.
+ if (!field->is_repeated()) {
+ SwapBit(message1, message2, field);
+ }
+ }
+ }
+ }
+}
+
+void Reflection::SwapFields(
+ Message* message1, Message* message2,
+ const std::vector<const FieldDescriptor*>& fields) const {
+ SwapFieldsImpl<false>(message1, message2, fields);
+}
+
+void Reflection::UnsafeShallowSwapFields(
+ Message* message1, Message* message2,
+ const std::vector<const FieldDescriptor*>& fields) const {
+ SwapFieldsImpl<true>(message1, message2, fields);
+}
+
+void Reflection::UnsafeArenaSwapFields(
+ Message* lhs, Message* rhs,
+ const std::vector<const FieldDescriptor*>& fields) const {
+ GOOGLE_DCHECK_EQ(lhs->GetArenaForAllocation(), rhs->GetArenaForAllocation());
+ UnsafeShallowSwapFields(lhs, rhs, fields);
+}
+
+// -------------------------------------------------------------------
+
+bool Reflection::HasField(const Message& message,
+ const FieldDescriptor* field) const {
+ USAGE_CHECK_MESSAGE_TYPE(HasField);
+ USAGE_CHECK_SINGULAR(HasField);
+ CheckInvalidAccess(schema_, field);
+
+ if (field->is_extension()) {
+ return GetExtensionSet(message).Has(field->number());
+ } else {
+ if (schema_.InRealOneof(field)) {
+ return HasOneofField(message, field);
+ } else {
+ return HasBit(message, field);
+ }
+ }
+}
+
+void Reflection::UnsafeArenaSwap(Message* lhs, Message* rhs) const {
+ if (lhs == rhs) return;
+
+ MutableInternalMetadata(lhs)->InternalSwap(MutableInternalMetadata(rhs));
+
+ for (int i = 0; i <= last_non_weak_field_index_; i++) {
+ const FieldDescriptor* field = descriptor_->field(i);
+ if (schema_.InRealOneof(field)) continue;
+ if (schema_.IsFieldStripped(field)) continue;
+ UnsafeShallowSwapField(lhs, rhs, field);
+ }
+ const int oneof_decl_count = descriptor_->oneof_decl_count();
+ for (int i = 0; i < oneof_decl_count; i++) {
+ const OneofDescriptor* oneof = descriptor_->oneof_decl(i);
+ if (!oneof->is_synthetic()) {
+ SwapOneofField<true>(lhs, rhs, oneof);
+ }
+ }
+
+ // Swapping bits need to happen after swapping fields, because the latter may
+ // depend on the has bit information.
+ if (schema_.HasHasbits()) {
+ uint32* lhs_has_bits = MutableHasBits(lhs);
+ uint32* rhs_has_bits = MutableHasBits(rhs);
+
+ int fields_with_has_bits = 0;
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ const FieldDescriptor* field = descriptor_->field(i);
+ if (field->is_repeated() || schema_.InRealOneof(field)) {
+ continue;
+ }
+ fields_with_has_bits++;
+ }
+
+ int has_bits_size = (fields_with_has_bits + 31) / 32;
+
+ for (int i = 0; i < has_bits_size; i++) {
+ std::swap(lhs_has_bits[i], rhs_has_bits[i]);
+ }
+ }
+
+ if (schema_.HasExtensionSet()) {
+ MutableExtensionSet(lhs)->InternalSwap(MutableExtensionSet(rhs));
+ }
+}
+
+int Reflection::FieldSize(const Message& message,
+ const FieldDescriptor* field) const {
+ USAGE_CHECK_MESSAGE_TYPE(FieldSize);
+ USAGE_CHECK_REPEATED(FieldSize);
+ CheckInvalidAccess(schema_, field);
+
+ if (field->is_extension()) {
+ return GetExtensionSet(message).ExtensionSize(field->number());
+ } else {
+ switch (field->cpp_type()) {
+#define HANDLE_TYPE(UPPERCASE, LOWERCASE) \
+ case FieldDescriptor::CPPTYPE_##UPPERCASE: \
+ return GetRaw<RepeatedField<LOWERCASE> >(message, field).size()
+
+ HANDLE_TYPE(INT32, 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();
+ break;
+ }
+ const std::string* default_ptr =
+ DefaultRaw<ArenaStringPtr>(field).GetPointer();
+ MutableRaw<ArenaStringPtr>(message, field)
+ ->SetAllocated(default_ptr, nullptr,
+ message->GetArenaForAllocation());
+ break;
+ }
+ }
+ break;
+ }
+
+ case FieldDescriptor::CPPTYPE_MESSAGE:
+ if (schema_.HasBitIndex(field) == static_cast<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();
+ }
+
+ if (auto* value =
+ GetField<ArenaStringPtr>(message, field).GetPointer()) {
+ return *value;
+ }
+ return field->default_value_string();
+ }
+ }
+ }
+}
+
+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();
+ }
+
+ if (auto* value =
+ GetField<ArenaStringPtr>(message, field).GetPointer()) {
+ return *value;
+ }
+ return field->default_value_string();
+ }
+ }
+ }
+}
+
+
+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);
+ uint32_t* states =
+ &MutableInlinedStringDonatedArray(message)[index / 32];
+ uint32_t mask = ~(static_cast<uint32_t>(1) << (index % 32));
+ MutableField<InlinedStringField>(message, field)
+ ->Set(nullptr, value, message->GetArenaForAllocation(),
+ IsInlinedStringDonated(*message, field), states, mask);
+ break;
+ }
+
+ // Oneof string fields are never set as a default instance.
+ // We just need to pass some arbitrary default string to make it work.
+ // This allows us to not have the real default accessible from
+ // reflection.
+ const std::string* default_ptr =
+ schema_.InRealOneof(field)
+ ? nullptr
+ : DefaultRaw<ArenaStringPtr>(field).GetPointer();
+ if (schema_.InRealOneof(field) && !HasOneofField(*message, field)) {
+ ClearOneof(message, field->containing_oneof());
+ MutableField<ArenaStringPtr>(message, field)
+ ->UnsafeSetDefault(default_ptr);
+ }
+ MutableField<ArenaStringPtr>(message, field)
+ ->Set(default_ptr, std::move(value),
+ message->GetArenaForAllocation());
+ break;
+ }
+ }
+ }
+}
+
+
+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()->FindFieldByName("value")->cpp_type());
+ return MutableRaw<MapFieldBase>(message, field)
+ ->InsertOrLookupMapValue(key, val);
+}
+
+bool Reflection::LookupMapValue(const Message& message,
+ const FieldDescriptor* field, const MapKey& key,
+ MapValueConstRef* val) const {
+ USAGE_CHECK(IsMapFieldInApi(field), "LookupMapValue",
+ "Field is not a map field.");
+ val->SetType(field->message_type()->FindFieldByName("value")->cpp_type());
+ return GetRaw<MapFieldBase>(message, field).LookupMapValue(key, val);
+}
+
+bool Reflection::DeleteMapValue(Message* message, const FieldDescriptor* field,
+ const MapKey& key) const {
+ USAGE_CHECK(IsMapFieldInApi(field), "DeleteMapValue",
+ "Field is not a map field.");
+ return MutableRaw<MapFieldBase>(message, field)->DeleteMapValue(key);
+}
+
+MapIterator Reflection::MapBegin(Message* message,
+ const FieldDescriptor* field) const {
+ USAGE_CHECK(IsMapFieldInApi(field), "MapBegin", "Field is not a map field.");
+ MapIterator iter(message, field);
+ GetRaw<MapFieldBase>(*message, field).MapBegin(&iter);
+ return iter;
+}
+
+MapIterator Reflection::MapEnd(Message* message,
+ const FieldDescriptor* field) const {
+ USAGE_CHECK(IsMapFieldInApi(field), "MapEnd", "Field is not a map field.");
+ MapIterator iter(message, field);
+ GetRaw<MapFieldBase>(*message, field).MapEnd(&iter);
+ return iter;
+}
+
+int Reflection::MapSize(const Message& message,
+ const FieldDescriptor* field) const {
+ USAGE_CHECK(IsMapFieldInApi(field), "MapSize", "Field is not a map field.");
+ return GetRaw<MapFieldBase>(message, field).size();
+}
+
+// -----------------------------------------------------------------------------
+
+const FieldDescriptor* Reflection::FindKnownExtensionByName(
+ const 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_.HasHasbits());
+ return GetPointerAtOffset<uint32_t>(message,
+ schema_.InlinedStringDonatedOffset());
+}
+
+// Simple accessors for manipulating _inlined_string_donated_;
+bool Reflection::IsInlinedStringDonated(const Message& message,
+ const FieldDescriptor* field) const {
+ return IsIndexInHasBitSet(GetInlinedStringDonatedArray(message),
+ schema_.InlinedStringIndex(field));
+}
+
+// Simple accessors for manipulating has_bits_.
+bool Reflection::HasBit(const Message& message,
+ const FieldDescriptor* field) const {
+ GOOGLE_DCHECK(!field->options().weak());
+ if (schema_.HasBitIndex(field) != static_cast<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(nullptr, message->GetArenaForAllocation());
+ break;
+ }
+ }
+ break;
+ }
+
+ case FieldDescriptor::CPPTYPE_MESSAGE:
+ delete *MutableRaw<Message*>(message, field);
+ break;
+ default:
+ break;
+ }
+ }
+
+ *MutableOneofCase(message, oneof_descriptor) = 0;
+ }
+}
+
+#define HANDLE_TYPE(TYPE, CPPTYPE, CTYPE) \
+ template <> \
+ const RepeatedField<TYPE>& Reflection::GetRepeatedFieldInternal<TYPE>( \
+ const Message& message, const FieldDescriptor* field) const { \
+ return *static_cast<RepeatedField<TYPE>*>(MutableRawRepeatedField( \
+ const_cast<Message*>(&message), field, CPPTYPE, CTYPE, nullptr)); \
+ } \
+ \
+ template <> \
+ RepeatedField<TYPE>* Reflection::MutableRepeatedFieldInternal<TYPE>( \
+ Message * message, const FieldDescriptor* field) const { \
+ return static_cast<RepeatedField<TYPE>*>( \
+ MutableRawRepeatedField(message, field, CPPTYPE, CTYPE, nullptr)); \
+ }
+
+HANDLE_TYPE(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()) {
+ internal::WireFormat::SerializeUnknownFields(
+ metadata->unknown_fields<UnknownFieldSet>(
+ UnknownFieldSet::default_instance),
+ output);
+ }
+}
+
+} // namespace internal
+} // namespace protobuf
+} // namespace google
+
+#include <port_undef.inc>
diff --git a/NorthstarDedicatedTest/include/protobuf/generated_message_reflection.h b/NorthstarDedicatedTest/include/protobuf/generated_message_reflection.h
new file mode 100644
index 00000000..c3a22033
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/generated_message_reflection.h
@@ -0,0 +1,362 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// This header is logically internal, but is made public because it is used
+// from protocol-compiler-generated code, which may reside in other components.
+
+#ifndef GOOGLE_PROTOBUF_GENERATED_MESSAGE_REFLECTION_H__
+#define GOOGLE_PROTOBUF_GENERATED_MESSAGE_REFLECTION_H__
+
+#include <string>
+#include <vector>
+#include <stubs/casts.h>
+#include <stubs/common.h>
+#include <descriptor.h>
+#include <generated_enum_reflection.h>
+#include <stubs/once.h>
+#include <port.h>
+#include <unknown_field_set.h>
+
+
+#include <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;
+ }
+
+ // Returns true if the field's accessor is called by any external code (aka,
+ // non proto library code).
+ bool IsFieldUsed(const FieldDescriptor* field) const {
+ (void)field;
+ return true;
+ }
+
+ bool IsFieldStripped(const FieldDescriptor* field) const {
+ (void)field;
+ return false;
+ }
+
+ bool IsMessageStripped(const Descriptor* descriptor) const {
+ (void)descriptor;
+ return false;
+ }
+
+
+ bool HasWeakFields() const { return weak_field_map_offset_ > 0; }
+
+ // These members are intended to be private, but we cannot actually make them
+ // private because this prevents us from using aggregate initialization of
+ // them, ie.
+ //
+ // ReflectionSchema schema = {a, b, c, d, e, ...};
+ // private:
+ const Message* default_instance_;
+ const 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 & 0x7FFFFFFEu;
+ }
+ return v & 0x7FFFFFFFu;
+ }
+
+ 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 <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_GENERATED_MESSAGE_REFLECTION_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/generated_message_reflection_unittest.cc b/NorthstarDedicatedTest/include/protobuf/generated_message_reflection_unittest.cc
new file mode 100644
index 00000000..1c263ec1
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/generated_message_reflection_unittest.cc
@@ -0,0 +1,1319 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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.
+//
+// To test GeneratedMessageReflection, we actually let the protocol compiler
+// generate a full protocol message implementation and then test its
+// reflection interface. This is much easier and more maintainable than
+// trying to create our own Message class for GeneratedMessageReflection
+// to wrap.
+//
+// The tests here closely mirror some of the tests in
+// compiler/cpp/unittest, except using the reflection interface
+// rather than generated accessors.
+
+#include <generated_message_reflection.h>
+
+#include <memory>
+
+#include <stubs/logging.h>
+#include <stubs/common.h>
+#include <map_test_util.h>
+#include <map_unittest.pb.h>
+#include <test_util.h>
+#include <unittest.pb.h>
+#include <unittest_mset.pb.h>
+#include <unittest_mset_wire_format.pb.h>
+#include <arena.h>
+#include <descriptor.h>
+#include <testing/googletest.h>
+#include <gtest/gtest.h>
+
+// Must be included last.
+#include <port_def.inc>
+
+namespace google {
+namespace protobuf {
+
+class GeneratedMessageReflectionTestHelper {
+ public:
+ static void UnsafeShallowSwapFields(
+ Message* lhs, Message* rhs,
+ const std::vector<const FieldDescriptor*>& fields) {
+ lhs->GetReflection()->UnsafeShallowSwapFields(lhs, rhs, fields);
+ }
+ static bool IsLazyExtension(const Message& msg, const FieldDescriptor* ext) {
+ return msg.GetReflection()->IsLazyExtension(msg, ext);
+ }
+};
+
+namespace {
+
+// Shorthand to get a FieldDescriptor for a field of unittest::TestAllTypes.
+const FieldDescriptor* F(const std::string& name) {
+ const FieldDescriptor* result =
+ unittest::TestAllTypes::descriptor()->FindFieldByName(name);
+ GOOGLE_CHECK(result != nullptr);
+ return result;
+}
+
+TEST(GeneratedMessageReflectionTest, Defaults) {
+ // Check that all default values are set correctly in the initial message.
+ unittest::TestAllTypes message;
+ TestUtil::ReflectionTester reflection_tester(
+ unittest::TestAllTypes::descriptor());
+
+ reflection_tester.ExpectClearViaReflection(message);
+
+ const Reflection* reflection = message.GetReflection();
+
+ // Messages should return pointers to default instances until first use.
+ // (This is not checked by ExpectClear() since it is not actually true after
+ // the fields have been set and then cleared.)
+ EXPECT_EQ(&unittest::TestAllTypes::OptionalGroup::default_instance(),
+ &reflection->GetMessage(message, F("optionalgroup")));
+ EXPECT_EQ(&unittest::TestAllTypes::NestedMessage::default_instance(),
+ &reflection->GetMessage(message, F("optional_nested_message")));
+ EXPECT_EQ(&unittest::ForeignMessage::default_instance(),
+ &reflection->GetMessage(message, F("optional_foreign_message")));
+ EXPECT_EQ(&unittest_import::ImportMessage::default_instance(),
+ &reflection->GetMessage(message, F("optional_import_message")));
+}
+
+TEST(GeneratedMessageReflectionTest, Accessors) {
+ // Set every field to a unique value then go back and check all those
+ // values.
+ unittest::TestAllTypes message;
+ TestUtil::ReflectionTester reflection_tester(
+ unittest::TestAllTypes::descriptor());
+
+ reflection_tester.SetAllFieldsViaReflection(&message);
+ TestUtil::ExpectAllFieldsSet(message);
+ reflection_tester.ExpectAllFieldsSetViaReflection(message);
+
+ reflection_tester.ModifyRepeatedFieldsViaReflection(&message);
+ TestUtil::ExpectRepeatedFieldsModified(message);
+}
+
+TEST(GeneratedMessageReflectionTest, GetStringReference) {
+ // Test that GetStringReference() returns the underlying string when it
+ // is a normal string field.
+ unittest::TestAllTypes message;
+ message.set_optional_string("foo");
+ message.add_repeated_string("foo");
+
+ const Reflection* reflection = message.GetReflection();
+ std::string scratch;
+
+ EXPECT_EQ(
+ &message.optional_string(),
+ &reflection->GetStringReference(message, F("optional_string"), &scratch))
+ << "For simple string fields, GetStringReference() should return a "
+ "reference to the underlying string.";
+ EXPECT_EQ(&message.repeated_string(0),
+ &reflection->GetRepeatedStringReference(
+ message, F("repeated_string"), 0, &scratch))
+ << "For simple string fields, GetRepeatedStringReference() should "
+ "return "
+ "a reference to the underlying string.";
+}
+
+
+TEST(GeneratedMessageReflectionTest, DefaultsAfterClear) {
+ // Check that after setting all fields and then clearing, getting an
+ // embedded message does NOT return the default instance.
+ unittest::TestAllTypes message;
+ TestUtil::ReflectionTester reflection_tester(
+ unittest::TestAllTypes::descriptor());
+
+ TestUtil::SetAllFields(&message);
+ message.Clear();
+
+ const Reflection* reflection = message.GetReflection();
+
+ EXPECT_NE(&unittest::TestAllTypes::OptionalGroup::default_instance(),
+ &reflection->GetMessage(message, F("optionalgroup")));
+ EXPECT_NE(&unittest::TestAllTypes::NestedMessage::default_instance(),
+ &reflection->GetMessage(message, F("optional_nested_message")));
+ EXPECT_NE(&unittest::ForeignMessage::default_instance(),
+ &reflection->GetMessage(message, F("optional_foreign_message")));
+ EXPECT_NE(&unittest_import::ImportMessage::default_instance(),
+ &reflection->GetMessage(message, F("optional_import_message")));
+}
+
+class GeneratedMessageReflectionSwapTest : public testing::TestWithParam<bool> {
+ protected:
+ void Swap(const Reflection* reflection, Message* lhs, Message* rhs) {
+ if (GetParam()) {
+ reflection->UnsafeArenaSwap(lhs, rhs);
+ } else {
+ reflection->Swap(lhs, rhs);
+ }
+ }
+ void SwapFields(const Reflection* reflection, Message* lhs, Message* rhs,
+ const std::vector<const FieldDescriptor*>& fields) {
+ if (GetParam()) {
+ reflection->UnsafeArenaSwapFields(lhs, rhs, fields);
+ } else {
+ reflection->SwapFields(lhs, rhs, fields);
+ }
+ }
+};
+
+// unsafe_shallow_swap: true -> UnsafeArena* API.
+INSTANTIATE_TEST_SUITE_P(ReflectionSwap, GeneratedMessageReflectionSwapTest,
+ testing::Bool());
+
+TEST_P(GeneratedMessageReflectionSwapTest, LhsSet) {
+ unittest::TestAllTypes lhs;
+ unittest::TestAllTypes rhs;
+
+ TestUtil::SetAllFields(&lhs);
+
+ Swap(lhs.GetReflection(), &lhs, &rhs);
+
+ TestUtil::ExpectClear(lhs);
+ TestUtil::ExpectAllFieldsSet(rhs);
+}
+
+TEST_P(GeneratedMessageReflectionSwapTest, BothSet) {
+ unittest::TestAllTypes lhs;
+ unittest::TestAllTypes rhs;
+
+ TestUtil::SetAllFields(&lhs);
+ TestUtil::SetAllFields(&rhs);
+ TestUtil::ModifyRepeatedFields(&rhs);
+
+ const Reflection* reflection = lhs.GetReflection();
+ Swap(reflection, &lhs, &rhs);
+
+ TestUtil::ExpectRepeatedFieldsModified(lhs);
+ TestUtil::ExpectAllFieldsSet(rhs);
+
+ lhs.set_optional_int32(532819);
+
+ Swap(reflection, &lhs, &rhs);
+
+ EXPECT_EQ(532819, rhs.optional_int32());
+}
+
+TEST_P(GeneratedMessageReflectionSwapTest, LhsCleared) {
+ unittest::TestAllTypes lhs;
+ unittest::TestAllTypes rhs;
+
+ TestUtil::SetAllFields(&lhs);
+
+ // For proto2 message, for message field, Clear only reset hasbits, but
+ // doesn't delete the underlying field.
+ lhs.Clear();
+
+ Swap(lhs.GetReflection(), &lhs, &rhs);
+
+ TestUtil::ExpectClear(rhs);
+}
+
+TEST_P(GeneratedMessageReflectionSwapTest, RhsCleared) {
+ unittest::TestAllTypes lhs;
+ unittest::TestAllTypes rhs;
+
+ TestUtil::SetAllFields(&rhs);
+
+ // For proto2 message, for message field, Clear only reset hasbits, but
+ // doesn't delete the underlying field.
+ rhs.Clear();
+
+ Swap(lhs.GetReflection(), &lhs, &rhs);
+
+ TestUtil::ExpectClear(lhs);
+}
+
+TEST_P(GeneratedMessageReflectionSwapTest, Extensions) {
+ unittest::TestAllExtensions lhs;
+ unittest::TestAllExtensions rhs;
+
+ TestUtil::SetAllExtensions(&lhs);
+
+ Swap(lhs.GetReflection(), &lhs, &rhs);
+
+ TestUtil::ExpectExtensionsClear(lhs);
+ TestUtil::ExpectAllExtensionsSet(rhs);
+}
+
+TEST_P(GeneratedMessageReflectionSwapTest, Unknown) {
+ unittest::TestEmptyMessage lhs, rhs;
+
+ lhs.mutable_unknown_fields()->AddVarint(1234, 1);
+
+ EXPECT_EQ(1, lhs.unknown_fields().field_count());
+ EXPECT_EQ(0, rhs.unknown_fields().field_count());
+ Swap(lhs.GetReflection(), &lhs, &rhs);
+ EXPECT_EQ(0, lhs.unknown_fields().field_count());
+ EXPECT_EQ(1, rhs.unknown_fields().field_count());
+}
+
+TEST_P(GeneratedMessageReflectionSwapTest, Oneof) {
+ unittest::TestOneof2 lhs, rhs;
+ TestUtil::SetOneof1(&lhs);
+
+ Swap(lhs.GetReflection(), &lhs, &rhs);
+
+ TestUtil::ExpectOneofClear(lhs);
+ TestUtil::ExpectOneofSet1(rhs);
+}
+
+TEST_P(GeneratedMessageReflectionSwapTest, OneofBothSet) {
+ unittest::TestOneof2 lhs, rhs;
+ TestUtil::SetOneof1(&lhs);
+ TestUtil::SetOneof2(&rhs);
+
+ Swap(lhs.GetReflection(), &lhs, &rhs);
+
+ TestUtil::ExpectOneofSet2(lhs);
+ TestUtil::ExpectOneofSet1(rhs);
+}
+
+TEST_P(GeneratedMessageReflectionSwapTest, SwapFields) {
+ unittest::TestAllTypes lhs, rhs;
+ lhs.set_optional_double(12.3);
+ lhs.mutable_repeated_int32()->Add(10);
+ lhs.mutable_repeated_int32()->Add(20);
+
+ rhs.set_optional_string("hello");
+ rhs.mutable_repeated_int64()->Add(30);
+
+ std::vector<const FieldDescriptor*> fields;
+ const Descriptor* descriptor = lhs.GetDescriptor();
+ fields.push_back(descriptor->FindFieldByName("optional_double"));
+ fields.push_back(descriptor->FindFieldByName("repeated_int32"));
+ fields.push_back(descriptor->FindFieldByName("optional_string"));
+ fields.push_back(descriptor->FindFieldByName("optional_uint64"));
+
+ SwapFields(lhs.GetReflection(), &lhs, &rhs, fields);
+
+ EXPECT_FALSE(lhs.has_optional_double());
+ EXPECT_EQ(0, lhs.repeated_int32_size());
+ EXPECT_TRUE(lhs.has_optional_string());
+ EXPECT_EQ("hello", lhs.optional_string());
+ EXPECT_EQ(0, lhs.repeated_int64_size());
+ EXPECT_FALSE(lhs.has_optional_uint64());
+
+ EXPECT_TRUE(rhs.has_optional_double());
+ EXPECT_EQ(12.3, rhs.optional_double());
+ EXPECT_EQ(2, rhs.repeated_int32_size());
+ EXPECT_EQ(10, rhs.repeated_int32(0));
+ EXPECT_EQ(20, rhs.repeated_int32(1));
+ EXPECT_FALSE(rhs.has_optional_string());
+ EXPECT_EQ(1, rhs.repeated_int64_size());
+ EXPECT_FALSE(rhs.has_optional_uint64());
+}
+
+TEST_P(GeneratedMessageReflectionSwapTest, SwapFieldsAll) {
+ unittest::TestAllTypes lhs;
+ unittest::TestAllTypes rhs;
+
+ TestUtil::SetAllFields(&rhs);
+
+ std::vector<const FieldDescriptor*> fields;
+ const Reflection* reflection = lhs.GetReflection();
+ reflection->ListFields(rhs, &fields);
+ SwapFields(reflection, &lhs, &rhs, fields);
+
+ TestUtil::ExpectAllFieldsSet(lhs);
+ TestUtil::ExpectClear(rhs);
+}
+
+TEST(GeneratedMessageReflectionTest, SwapFieldsAllOnDifferentArena) {
+ Arena arena1, arena2;
+ auto* message1 = Arena::CreateMessage<unittest::TestAllTypes>(&arena1);
+ auto* message2 = Arena::CreateMessage<unittest::TestAllTypes>(&arena2);
+
+ TestUtil::SetAllFields(message2);
+
+ std::vector<const FieldDescriptor*> fields;
+ const Reflection* reflection = message1->GetReflection();
+ reflection->ListFields(*message2, &fields);
+ reflection->SwapFields(message1, message2, fields);
+
+ TestUtil::ExpectAllFieldsSet(*message1);
+ TestUtil::ExpectClear(*message2);
+}
+
+TEST(GeneratedMessageReflectionTest, SwapFieldsAllOnArenaHeap) {
+ Arena arena;
+ auto* message1 = Arena::CreateMessage<unittest::TestAllTypes>(&arena);
+ std::unique_ptr<unittest::TestAllTypes> message2(
+ Arena::CreateMessage<unittest::TestAllTypes>(nullptr));
+
+ TestUtil::SetAllFields(message2.get());
+
+ std::vector<const FieldDescriptor*> fields;
+ const Reflection* reflection = message1->GetReflection();
+ reflection->ListFields(*message2, &fields);
+ reflection->SwapFields(message1, message2.get(), fields);
+
+ TestUtil::ExpectAllFieldsSet(*message1);
+ TestUtil::ExpectClear(*message2);
+}
+
+TEST(GeneratedMessageReflectionTest, SwapFieldsAllExtension) {
+ unittest::TestAllExtensions message1;
+ unittest::TestAllExtensions message2;
+
+ TestUtil::SetAllExtensions(&message1);
+
+ std::vector<const FieldDescriptor*> fields;
+ const Reflection* reflection = message1.GetReflection();
+ reflection->ListFields(message1, &fields);
+ reflection->SwapFields(&message1, &message2, fields);
+
+ TestUtil::ExpectExtensionsClear(message1);
+ TestUtil::ExpectAllExtensionsSet(message2);
+}
+
+TEST(GeneratedMessageReflectionTest, SwapFieldsAllExtensionArenaHeap) {
+ Arena arena;
+
+ std::unique_ptr<unittest::TestAllExtensions> message1(
+ Arena::CreateMessage<unittest::TestAllExtensions>(nullptr));
+ auto* message2 = Arena::CreateMessage<unittest::TestAllExtensions>(&arena);
+
+ TestUtil::SetAllExtensions(message1.get());
+
+ std::vector<const FieldDescriptor*> fields;
+ const Reflection* reflection = message1->GetReflection();
+ reflection->ListFields(*message1, &fields);
+ reflection->SwapFields(message1.get(), message2, fields);
+
+ TestUtil::ExpectExtensionsClear(*message1);
+ TestUtil::ExpectAllExtensionsSet(*message2);
+}
+
+TEST(GeneratedMessageReflectionTest, UnsafeShallowSwapFieldsAll) {
+ Arena arena;
+ auto* message1 = Arena::CreateMessage<unittest::TestAllTypes>(&arena);
+ auto* message2 = Arena::CreateMessage<unittest::TestAllTypes>(&arena);
+
+ TestUtil::SetAllFields(message2);
+
+ auto* kept_nested_message_ptr = message2->mutable_optional_nested_message();
+ auto* kept_foreign_message_ptr = message2->mutable_optional_foreign_message();
+ auto* kept_repeated_nested_message_ptr =
+ message2->mutable_repeated_nested_message(0);
+ auto* kept_repeated_foreign_message_ptr =
+ message2->mutable_repeated_foreign_message(0);
+
+ std::vector<const FieldDescriptor*> fields;
+ const Reflection* reflection = message1->GetReflection();
+ reflection->ListFields(*message2, &fields);
+ GeneratedMessageReflectionTestHelper::UnsafeShallowSwapFields(
+ message1, message2, fields);
+
+ TestUtil::ExpectAllFieldsSet(*message1);
+ TestUtil::ExpectClear(*message2);
+
+ // Expects the swap to be shallow. Expects pointer stability to the element of
+ // the repeated fields (not the container).
+ EXPECT_EQ(kept_nested_message_ptr,
+ message1->mutable_optional_nested_message());
+ EXPECT_EQ(kept_foreign_message_ptr,
+ message1->mutable_optional_foreign_message());
+ EXPECT_EQ(kept_repeated_nested_message_ptr,
+ message1->mutable_repeated_nested_message(0));
+ EXPECT_EQ(kept_repeated_foreign_message_ptr,
+ message1->mutable_repeated_foreign_message(0));
+}
+
+TEST(GeneratedMessageReflectionTest, UnsafeShallowSwapFieldsMap) {
+ Arena arena;
+ auto* message1 = Arena::CreateMessage<unittest::TestMap>(&arena);
+ auto* message2 = Arena::CreateMessage<unittest::TestMap>(&arena);
+
+ MapTestUtil::SetMapFields(message2);
+
+ auto* kept_map_int32_fm_ptr =
+ &(*message2->mutable_map_int32_foreign_message())[0];
+
+ std::vector<const FieldDescriptor*> fields;
+ const Reflection* reflection = message1->GetReflection();
+ reflection->ListFields(*message2, &fields);
+ GeneratedMessageReflectionTestHelper::UnsafeShallowSwapFields(
+ message1, message2, fields);
+
+ MapTestUtil::ExpectMapFieldsSet(*message1);
+ MapTestUtil::ExpectClear(*message2);
+
+ // Expects the swap to be shallow.
+ EXPECT_EQ(kept_map_int32_fm_ptr,
+ &(*message1->mutable_map_int32_foreign_message())[0]);
+}
+
+TEST(GeneratedMessageReflectionTest, UnsafeShallowSwapFieldsAllExtension) {
+ Arena arena;
+ auto* message1 = Arena::CreateMessage<unittest::TestAllExtensions>(&arena);
+ auto* message2 = Arena::CreateMessage<unittest::TestAllExtensions>(&arena);
+
+ TestUtil::SetAllExtensions(message1);
+
+ auto* kept_nested_message_ext_ptr =
+ message1->MutableExtension(unittest::optional_nested_message_extension);
+ auto* kept_foreign_message_ext_ptr =
+ message1->MutableExtension(unittest::optional_foreign_message_extension);
+ auto* kept_repeated_nested_message_ext_ptr =
+ message1->MutableRepeatedExtension(
+ unittest::repeated_nested_message_extension);
+ auto* kept_repeated_foreign_message_ext_ptr =
+ message1->MutableRepeatedExtension(
+ unittest::repeated_foreign_message_extension);
+
+ std::vector<const FieldDescriptor*> fields;
+ const Reflection* reflection = message1->GetReflection();
+ reflection->ListFields(*message1, &fields);
+ GeneratedMessageReflectionTestHelper::UnsafeShallowSwapFields(
+ message1, message2, fields);
+
+ TestUtil::ExpectExtensionsClear(*message1);
+ TestUtil::ExpectAllExtensionsSet(*message2);
+
+ // Expects the swap to be shallow.
+ EXPECT_EQ(
+ kept_nested_message_ext_ptr,
+ message2->MutableExtension(unittest::optional_nested_message_extension));
+ EXPECT_EQ(
+ kept_foreign_message_ext_ptr,
+ message2->MutableExtension(unittest::optional_foreign_message_extension));
+ EXPECT_EQ(kept_repeated_nested_message_ext_ptr,
+ message2->MutableRepeatedExtension(
+ unittest::repeated_nested_message_extension));
+ EXPECT_EQ(kept_repeated_foreign_message_ext_ptr,
+ message2->MutableRepeatedExtension(
+ unittest::repeated_foreign_message_extension));
+}
+
+TEST(GeneratedMessageReflectionTest, SwapFieldsOneof) {
+ unittest::TestOneof2 message1, message2;
+ TestUtil::SetOneof1(&message1);
+
+ std::vector<const FieldDescriptor*> fields;
+ const Descriptor* descriptor = message1.GetDescriptor();
+ for (int i = 0; i < descriptor->field_count(); i++) {
+ fields.push_back(descriptor->field(i));
+ }
+ const Reflection* reflection = message1.GetReflection();
+ reflection->SwapFields(&message1, &message2, fields);
+
+ TestUtil::ExpectOneofClear(message1);
+ TestUtil::ExpectOneofSet1(message2);
+}
+
+TEST(GeneratedMessageReflectionTest, UnsafeShallowSwapFieldsOneof) {
+ Arena arena;
+ auto* message1 = Arena::CreateMessage<unittest::TestOneof2>(&arena);
+ auto* message2 = Arena::CreateMessage<unittest::TestOneof2>(&arena);
+ TestUtil::SetOneof1(message1);
+
+ std::vector<const FieldDescriptor*> fields;
+ const Descriptor* descriptor = message1->GetDescriptor();
+ for (int i = 0; i < descriptor->field_count(); i++) {
+ fields.push_back(descriptor->field(i));
+ }
+ GeneratedMessageReflectionTestHelper::UnsafeShallowSwapFields(
+ message1, message2, fields);
+
+ TestUtil::ExpectOneofClear(*message1);
+ TestUtil::ExpectOneofSet1(*message2);
+}
+
+TEST(GeneratedMessageReflectionTest,
+ UnsafeShallowSwapFieldsOneofExpectShallow) {
+ Arena arena;
+ auto* message1 = Arena::CreateMessage<unittest::TestOneof2>(&arena);
+ auto* message2 = Arena::CreateMessage<unittest::TestOneof2>(&arena);
+ TestUtil::SetOneof1(message1);
+ message1->mutable_foo_message()->set_qux_int(1000);
+ auto* kept_foo_ptr = message1->mutable_foo_message();
+
+ std::vector<const FieldDescriptor*> fields;
+ const Descriptor* descriptor = message1->GetDescriptor();
+ for (int i = 0; i < descriptor->field_count(); i++) {
+ fields.push_back(descriptor->field(i));
+ }
+ GeneratedMessageReflectionTestHelper::UnsafeShallowSwapFields(
+ message1, message2, fields);
+
+ EXPECT_TRUE(message2->has_foo_message());
+ EXPECT_EQ(message2->foo_message().qux_int(), 1000);
+ EXPECT_EQ(kept_foo_ptr, message2->mutable_foo_message());
+}
+
+TEST(GeneratedMessageReflectionTest, RemoveLast) {
+ unittest::TestAllTypes message;
+ TestUtil::ReflectionTester reflection_tester(
+ unittest::TestAllTypes::descriptor());
+
+ TestUtil::SetAllFields(&message);
+
+ reflection_tester.RemoveLastRepeatedsViaReflection(&message);
+
+ TestUtil::ExpectLastRepeatedsRemoved(message);
+}
+
+TEST(GeneratedMessageReflectionTest, RemoveLastExtensions) {
+ unittest::TestAllExtensions message;
+ TestUtil::ReflectionTester reflection_tester(
+ unittest::TestAllExtensions::descriptor());
+
+ TestUtil::SetAllExtensions(&message);
+
+ reflection_tester.RemoveLastRepeatedsViaReflection(&message);
+
+ TestUtil::ExpectLastRepeatedExtensionsRemoved(message);
+}
+
+TEST(GeneratedMessageReflectionTest, ReleaseLast) {
+ unittest::TestAllTypes message;
+ const Descriptor* descriptor = message.GetDescriptor();
+ TestUtil::ReflectionTester reflection_tester(descriptor);
+
+ TestUtil::SetAllFields(&message);
+
+ reflection_tester.ReleaseLastRepeatedsViaReflection(&message, false);
+
+ TestUtil::ExpectLastRepeatedsReleased(message);
+
+ // Now test that we actually release the right message.
+ message.Clear();
+ TestUtil::SetAllFields(&message);
+ ASSERT_EQ(2, message.repeated_foreign_message_size());
+ const protobuf_unittest::ForeignMessage* expected =
+ message.mutable_repeated_foreign_message(1);
+ (void)expected; // unused in somce configurations
+ std::unique_ptr<Message> released(message.GetReflection()->ReleaseLast(
+ &message, descriptor->FindFieldByName("repeated_foreign_message")));
+ EXPECT_EQ(expected, released.get());
+}
+
+TEST(GeneratedMessageReflectionTest, ReleaseLastExtensions) {
+ unittest::TestAllExtensions message;
+ const Descriptor* descriptor = message.GetDescriptor();
+ TestUtil::ReflectionTester reflection_tester(descriptor);
+
+ TestUtil::SetAllExtensions(&message);
+
+ reflection_tester.ReleaseLastRepeatedsViaReflection(&message, true);
+
+ TestUtil::ExpectLastRepeatedExtensionsReleased(message);
+
+ // Now test that we actually release the right message.
+ message.Clear();
+ TestUtil::SetAllExtensions(&message);
+ ASSERT_EQ(
+ 2, message.ExtensionSize(unittest::repeated_foreign_message_extension));
+ const protobuf_unittest::ForeignMessage* expected =
+ message.MutableExtension(unittest::repeated_foreign_message_extension, 1);
+ std::unique_ptr<Message> released(message.GetReflection()->ReleaseLast(
+ &message, descriptor->file()->FindExtensionByName(
+ "repeated_foreign_message_extension")));
+ EXPECT_EQ(expected, released.get());
+}
+
+TEST(GeneratedMessageReflectionTest, SwapRepeatedElements) {
+ unittest::TestAllTypes message;
+ TestUtil::ReflectionTester reflection_tester(
+ unittest::TestAllTypes::descriptor());
+
+ TestUtil::SetAllFields(&message);
+
+ // Swap and test that fields are all swapped.
+ reflection_tester.SwapRepeatedsViaReflection(&message);
+ TestUtil::ExpectRepeatedsSwapped(message);
+
+ // Swap back and test that fields are all back to original values.
+ reflection_tester.SwapRepeatedsViaReflection(&message);
+ TestUtil::ExpectAllFieldsSet(message);
+}
+
+TEST(GeneratedMessageReflectionTest, SwapRepeatedElementsExtension) {
+ unittest::TestAllExtensions message;
+ TestUtil::ReflectionTester reflection_tester(
+ unittest::TestAllExtensions::descriptor());
+
+ TestUtil::SetAllExtensions(&message);
+
+ // Swap and test that fields are all swapped.
+ reflection_tester.SwapRepeatedsViaReflection(&message);
+ TestUtil::ExpectRepeatedExtensionsSwapped(message);
+
+ // Swap back and test that fields are all back to original values.
+ reflection_tester.SwapRepeatedsViaReflection(&message);
+ TestUtil::ExpectAllExtensionsSet(message);
+}
+
+TEST(GeneratedMessageReflectionTest, Extensions) {
+ // Set every extension to a unique value then go back and check all those
+ // values.
+ unittest::TestAllExtensions message;
+ TestUtil::ReflectionTester reflection_tester(
+ unittest::TestAllExtensions::descriptor());
+
+ reflection_tester.SetAllFieldsViaReflection(&message);
+ TestUtil::ExpectAllExtensionsSet(message);
+ reflection_tester.ExpectAllFieldsSetViaReflection(message);
+
+ reflection_tester.ModifyRepeatedFieldsViaReflection(&message);
+ TestUtil::ExpectRepeatedExtensionsModified(message);
+}
+
+TEST(GeneratedMessageReflectionTest, FindExtensionTypeByNumber) {
+ const Reflection* reflection =
+ unittest::TestAllExtensions::default_instance().GetReflection();
+
+ const FieldDescriptor* extension1 =
+ unittest::TestAllExtensions::descriptor()->file()->FindExtensionByName(
+ "optional_int32_extension");
+ const FieldDescriptor* extension2 =
+ unittest::TestAllExtensions::descriptor()->file()->FindExtensionByName(
+ "repeated_string_extension");
+
+ EXPECT_EQ(extension1,
+ reflection->FindKnownExtensionByNumber(extension1->number()));
+ EXPECT_EQ(extension2,
+ reflection->FindKnownExtensionByNumber(extension2->number()));
+
+ // Non-existent extension.
+ EXPECT_TRUE(reflection->FindKnownExtensionByNumber(62341) == nullptr);
+
+ // Extensions of TestAllExtensions should not show up as extensions of
+ // other types.
+ EXPECT_TRUE(unittest::TestAllTypes::default_instance()
+ .GetReflection()
+ ->FindKnownExtensionByNumber(extension1->number()) ==
+ nullptr);
+}
+
+TEST(GeneratedMessageReflectionTest, FindKnownExtensionByName) {
+ const Reflection* reflection =
+ unittest::TestAllExtensions::default_instance().GetReflection();
+
+ const FieldDescriptor* extension1 =
+ unittest::TestAllExtensions::descriptor()->file()->FindExtensionByName(
+ "optional_int32_extension");
+ const FieldDescriptor* extension2 =
+ unittest::TestAllExtensions::descriptor()->file()->FindExtensionByName(
+ "repeated_string_extension");
+
+ EXPECT_EQ(extension1,
+ reflection->FindKnownExtensionByName(extension1->full_name()));
+ EXPECT_EQ(extension2,
+ reflection->FindKnownExtensionByName(extension2->full_name()));
+
+ // Non-existent extension.
+ EXPECT_TRUE(reflection->FindKnownExtensionByName("no_such_ext") == nullptr);
+
+ // Extensions of TestAllExtensions should not show up as extensions of
+ // other types.
+ EXPECT_TRUE(unittest::TestAllTypes::default_instance()
+ .GetReflection()
+ ->FindKnownExtensionByName(extension1->full_name()) ==
+ nullptr);
+}
+
+
+TEST(GeneratedMessageReflectionTest, SetAllocatedMessageTest) {
+ unittest::TestAllTypes from_message1;
+ unittest::TestAllTypes from_message2;
+ unittest::TestAllTypes to_message;
+ TestUtil::ReflectionTester reflection_tester(
+ unittest::TestAllTypes::descriptor());
+ reflection_tester.SetAllFieldsViaReflection(&from_message1);
+ reflection_tester.SetAllFieldsViaReflection(&from_message2);
+
+ // Before moving fields, we expect the nested messages to be nullptr.
+ reflection_tester.ExpectMessagesReleasedViaReflection(
+ &to_message, TestUtil::ReflectionTester::IS_NULL);
+
+ // After fields are moved we should get non-nullptr releases.
+ reflection_tester.SetAllocatedOptionalMessageFieldsToMessageViaReflection(
+ &from_message1, &to_message);
+ reflection_tester.ExpectMessagesReleasedViaReflection(
+ &to_message, TestUtil::ReflectionTester::NOT_NULL);
+
+ // Another move to make sure that we can SetAllocated several times.
+ reflection_tester.SetAllocatedOptionalMessageFieldsToMessageViaReflection(
+ &from_message2, &to_message);
+ reflection_tester.ExpectMessagesReleasedViaReflection(
+ &to_message, TestUtil::ReflectionTester::NOT_NULL);
+
+ // After SetAllocatedOptionalMessageFieldsToNullViaReflection() we expect the
+ // releases to be nullptr again.
+ reflection_tester.SetAllocatedOptionalMessageFieldsToNullViaReflection(
+ &to_message);
+ reflection_tester.ExpectMessagesReleasedViaReflection(
+ &to_message, TestUtil::ReflectionTester::IS_NULL);
+}
+
+TEST(GeneratedMessageReflectionTest, SetAllocatedMessageOnArenaTest) {
+ unittest::TestAllTypes from_message1;
+ unittest::TestAllTypes from_message2;
+ Arena arena;
+ unittest::TestAllTypes* to_message =
+ Arena::CreateMessage<unittest::TestAllTypes>(&arena);
+ TestUtil::ReflectionTester reflection_tester(
+ unittest::TestAllTypes::descriptor());
+ reflection_tester.SetAllFieldsViaReflection(&from_message1);
+ reflection_tester.SetAllFieldsViaReflection(&from_message2);
+
+ // Before moving fields, we expect the nested messages to be nullptr.
+ reflection_tester.ExpectMessagesReleasedViaReflection(
+ to_message, TestUtil::ReflectionTester::IS_NULL);
+
+ // After fields are moved we should get non-nullptr releases.
+ reflection_tester.SetAllocatedOptionalMessageFieldsToMessageViaReflection(
+ &from_message1, to_message);
+ reflection_tester.ExpectMessagesReleasedViaReflection(
+ to_message, TestUtil::ReflectionTester::NOT_NULL);
+
+ // Another move to make sure that we can SetAllocated several times.
+ reflection_tester.SetAllocatedOptionalMessageFieldsToMessageViaReflection(
+ &from_message2, to_message);
+ reflection_tester.ExpectMessagesReleasedViaReflection(
+ to_message, TestUtil::ReflectionTester::NOT_NULL);
+
+ // After SetAllocatedOptionalMessageFieldsToNullViaReflection() we expect the
+ // releases to be nullptr again.
+ reflection_tester.SetAllocatedOptionalMessageFieldsToNullViaReflection(
+ to_message);
+ reflection_tester.ExpectMessagesReleasedViaReflection(
+ to_message, TestUtil::ReflectionTester::IS_NULL);
+}
+
+TEST(GeneratedMessageReflectionTest, SetAllocatedExtensionMessageTest) {
+ unittest::TestAllExtensions from_message1;
+ unittest::TestAllExtensions from_message2;
+ unittest::TestAllExtensions to_message;
+ TestUtil::ReflectionTester reflection_tester(
+ unittest::TestAllExtensions::descriptor());
+ reflection_tester.SetAllFieldsViaReflection(&from_message1);
+ reflection_tester.SetAllFieldsViaReflection(&from_message2);
+
+ // Before moving fields, we expect the nested messages to be nullptr.
+ reflection_tester.ExpectMessagesReleasedViaReflection(
+ &to_message, TestUtil::ReflectionTester::IS_NULL);
+
+ // After fields are moved we should get non-nullptr releases.
+ reflection_tester.SetAllocatedOptionalMessageFieldsToMessageViaReflection(
+ &from_message1, &to_message);
+ reflection_tester.ExpectMessagesReleasedViaReflection(
+ &to_message, TestUtil::ReflectionTester::NOT_NULL);
+
+ // Another move to make sure that we can SetAllocated several times.
+ reflection_tester.SetAllocatedOptionalMessageFieldsToMessageViaReflection(
+ &from_message2, &to_message);
+ reflection_tester.ExpectMessagesReleasedViaReflection(
+ &to_message, TestUtil::ReflectionTester::NOT_NULL);
+
+ // After SetAllocatedOptionalMessageFieldsToNullViaReflection() we expect the
+ // releases to be nullptr again.
+ reflection_tester.SetAllocatedOptionalMessageFieldsToNullViaReflection(
+ &to_message);
+ reflection_tester.ExpectMessagesReleasedViaReflection(
+ &to_message, TestUtil::ReflectionTester::IS_NULL);
+}
+
+TEST(GeneratedMessageReflectionTest, SetAllocatedExtensionMessageOnArenaTest) {
+ Arena arena;
+ unittest::TestAllExtensions* to_message =
+ Arena::CreateMessage<unittest::TestAllExtensions>(&arena);
+ unittest::TestAllExtensions from_message1;
+ unittest::TestAllExtensions from_message2;
+ TestUtil::ReflectionTester reflection_tester(
+ unittest::TestAllExtensions::descriptor());
+ reflection_tester.SetAllFieldsViaReflection(&from_message1);
+ reflection_tester.SetAllFieldsViaReflection(&from_message2);
+
+ // Before moving fields, we expect the nested messages to be nullptr.
+ reflection_tester.ExpectMessagesReleasedViaReflection(
+ to_message, TestUtil::ReflectionTester::IS_NULL);
+
+ // After fields are moved we should get non-nullptr releases.
+ reflection_tester.SetAllocatedOptionalMessageFieldsToMessageViaReflection(
+ &from_message1, to_message);
+ reflection_tester.ExpectMessagesReleasedViaReflection(
+ to_message, TestUtil::ReflectionTester::NOT_NULL);
+
+ // Another move to make sure that we can SetAllocated several times.
+ reflection_tester.SetAllocatedOptionalMessageFieldsToMessageViaReflection(
+ &from_message2, to_message);
+ reflection_tester.ExpectMessagesReleasedViaReflection(
+ to_message, TestUtil::ReflectionTester::NOT_NULL);
+
+ // After SetAllocatedOptionalMessageFieldsToNullViaReflection() we expect the
+ // releases to be nullptr again.
+ reflection_tester.SetAllocatedOptionalMessageFieldsToNullViaReflection(
+ to_message);
+ reflection_tester.ExpectMessagesReleasedViaReflection(
+ to_message, TestUtil::ReflectionTester::IS_NULL);
+}
+
+TEST(GeneratedMessageReflectionTest, AddRepeatedMessage) {
+ unittest::TestAllTypes message;
+
+ const Reflection* reflection = message.GetReflection();
+ const Reflection* nested_reflection =
+ unittest::TestAllTypes::NestedMessage::default_instance().GetReflection();
+
+ const FieldDescriptor* nested_bb =
+ unittest::TestAllTypes::NestedMessage::descriptor()->FindFieldByName(
+ "bb");
+
+ Message* nested =
+ reflection->AddMessage(&message, F("repeated_nested_message"));
+ nested_reflection->SetInt32(nested, nested_bb, 11);
+
+ EXPECT_EQ(11, message.repeated_nested_message(0).bb());
+}
+
+TEST(GeneratedMessageReflectionTest, MutableRepeatedMessage) {
+ unittest::TestAllTypes message;
+
+ const Reflection* reflection = message.GetReflection();
+ const Reflection* nested_reflection =
+ unittest::TestAllTypes::NestedMessage::default_instance().GetReflection();
+
+ const FieldDescriptor* nested_bb =
+ unittest::TestAllTypes::NestedMessage::descriptor()->FindFieldByName(
+ "bb");
+
+ message.add_repeated_nested_message()->set_bb(12);
+
+ Message* nested = reflection->MutableRepeatedMessage(
+ &message, F("repeated_nested_message"), 0);
+ EXPECT_EQ(12, nested_reflection->GetInt32(*nested, nested_bb));
+ nested_reflection->SetInt32(nested, nested_bb, 13);
+ EXPECT_EQ(13, message.repeated_nested_message(0).bb());
+}
+
+TEST(GeneratedMessageReflectionTest, AddAllocatedMessage) {
+ unittest::TestAllTypes message;
+
+ const Reflection* reflection = message.GetReflection();
+
+ unittest::TestAllTypes::NestedMessage* nested =
+ new unittest::TestAllTypes::NestedMessage();
+ nested->set_bb(11);
+ reflection->AddAllocatedMessage(&message, F("repeated_nested_message"),
+ nested);
+ EXPECT_EQ(1, message.repeated_nested_message_size());
+ EXPECT_EQ(11, message.repeated_nested_message(0).bb());
+}
+
+TEST(GeneratedMessageReflectionTest, ListFieldsOneOf) {
+ unittest::TestOneof2 message;
+ TestUtil::SetOneof1(&message);
+
+ const Reflection* reflection = message.GetReflection();
+ std::vector<const FieldDescriptor*> fields;
+ reflection->ListFields(message, &fields);
+ EXPECT_EQ(4, fields.size());
+}
+
+TEST(GeneratedMessageReflectionTest, Oneof) {
+ unittest::TestOneof2 message;
+ const Descriptor* descriptor = message.GetDescriptor();
+ const Reflection* reflection = message.GetReflection();
+
+ // Check default values.
+ EXPECT_EQ(
+ 0, reflection->GetInt32(message, descriptor->FindFieldByName("foo_int")));
+ EXPECT_EQ("", reflection->GetString(
+ message, descriptor->FindFieldByName("foo_string")));
+ EXPECT_EQ("", reflection->GetString(message,
+ descriptor->FindFieldByName("foo_cord")));
+ EXPECT_EQ("", reflection->GetString(
+ message, descriptor->FindFieldByName("foo_string_piece")));
+ EXPECT_EQ("", reflection->GetString(
+ message, descriptor->FindFieldByName("foo_bytes")));
+ EXPECT_EQ(
+ unittest::TestOneof2::FOO,
+ reflection->GetEnum(message, descriptor->FindFieldByName("foo_enum"))
+ ->number());
+ EXPECT_EQ(&unittest::TestOneof2::NestedMessage::default_instance(),
+ &reflection->GetMessage(
+ message, descriptor->FindFieldByName("foo_message")));
+ EXPECT_EQ(&unittest::TestOneof2::FooGroup::default_instance(),
+ &reflection->GetMessage(message,
+ descriptor->FindFieldByName("foogroup")));
+ EXPECT_NE(&unittest::TestOneof2::FooGroup::default_instance(),
+ &reflection->GetMessage(
+ message, descriptor->FindFieldByName("foo_lazy_message")));
+ EXPECT_EQ(
+ 5, reflection->GetInt32(message, descriptor->FindFieldByName("bar_int")));
+ EXPECT_EQ("STRING", reflection->GetString(
+ message, descriptor->FindFieldByName("bar_string")));
+ EXPECT_EQ("CORD", reflection->GetString(
+ message, descriptor->FindFieldByName("bar_cord")));
+ EXPECT_EQ("SPIECE",
+ reflection->GetString(
+ message, descriptor->FindFieldByName("bar_string_piece")));
+ EXPECT_EQ("BYTES", reflection->GetString(
+ message, descriptor->FindFieldByName("bar_bytes")));
+ EXPECT_EQ(
+ unittest::TestOneof2::BAR,
+ reflection->GetEnum(message, descriptor->FindFieldByName("bar_enum"))
+ ->number());
+
+ // Check Set functions.
+ reflection->SetInt32(&message, descriptor->FindFieldByName("foo_int"), 123);
+ EXPECT_EQ(123, reflection->GetInt32(message,
+ descriptor->FindFieldByName("foo_int")));
+ reflection->SetString(&message, descriptor->FindFieldByName("foo_string"),
+ "abc");
+ EXPECT_EQ("abc", reflection->GetString(
+ message, descriptor->FindFieldByName("foo_string")));
+ reflection->SetString(&message, descriptor->FindFieldByName("foo_bytes"),
+ "bytes");
+ EXPECT_EQ("bytes", reflection->GetString(
+ message, descriptor->FindFieldByName("foo_bytes")));
+ reflection->SetString(&message, descriptor->FindFieldByName("bar_cord"),
+ "change_cord");
+ EXPECT_EQ(
+ "change_cord",
+ reflection->GetString(message, descriptor->FindFieldByName("bar_cord")));
+ reflection->SetString(&message,
+ descriptor->FindFieldByName("bar_string_piece"),
+ "change_spiece");
+ EXPECT_EQ("change_spiece",
+ reflection->GetString(
+ message, descriptor->FindFieldByName("bar_string_piece")));
+
+ message.clear_foo();
+ message.clear_bar();
+ TestUtil::ExpectOneofClear(message);
+}
+
+TEST(GeneratedMessageReflectionTest, SetAllocatedOneofMessageTest) {
+ unittest::TestOneof2 from_message1;
+ unittest::TestOneof2 from_message2;
+ unittest::TestOneof2 to_message;
+ const Descriptor* descriptor = unittest::TestOneof2::descriptor();
+ const Reflection* reflection = to_message.GetReflection();
+
+ Message* released = reflection->ReleaseMessage(
+ &to_message, descriptor->FindFieldByName("foo_lazy_message"));
+ EXPECT_TRUE(released == nullptr);
+ released = reflection->ReleaseMessage(
+ &to_message, descriptor->FindFieldByName("foo_message"));
+ EXPECT_TRUE(released == nullptr);
+
+ TestUtil::ReflectionTester::SetOneofViaReflection(&from_message1);
+ TestUtil::ReflectionTester::ExpectOneofSetViaReflection(from_message1);
+
+ TestUtil::ReflectionTester::
+ SetAllocatedOptionalMessageFieldsToMessageViaReflection(&from_message1,
+ &to_message);
+ const Message& sub_message = reflection->GetMessage(
+ to_message, descriptor->FindFieldByName("foo_lazy_message"));
+ (void)sub_message; // unused in somce configurations
+ released = reflection->ReleaseMessage(
+ &to_message, descriptor->FindFieldByName("foo_lazy_message"));
+ EXPECT_TRUE(released != nullptr);
+ EXPECT_EQ(&sub_message, released);
+ delete released;
+
+ TestUtil::ReflectionTester::SetOneofViaReflection(&from_message2);
+
+ reflection->MutableMessage(&from_message2,
+ descriptor->FindFieldByName("foo_message"));
+
+ TestUtil::ReflectionTester::
+ SetAllocatedOptionalMessageFieldsToMessageViaReflection(&from_message2,
+ &to_message);
+
+ const Message& sub_message2 = reflection->GetMessage(
+ to_message, descriptor->FindFieldByName("foo_message"));
+ (void)sub_message2; // unused in somce configurations
+ released = reflection->ReleaseMessage(
+ &to_message, descriptor->FindFieldByName("foo_message"));
+ EXPECT_TRUE(released != nullptr);
+ EXPECT_EQ(&sub_message2, released);
+ delete released;
+}
+
+TEST(GeneratedMessageReflectionTest, SetAllocatedOneofMessageOnArenaTest) {
+ unittest::TestOneof2 from_message1;
+ unittest::TestOneof2 from_message2;
+ Arena arena;
+ unittest::TestOneof2* to_message =
+ Arena::CreateMessage<unittest::TestOneof2>(&arena);
+ const Descriptor* descriptor = unittest::TestOneof2::descriptor();
+ const Reflection* reflection = to_message->GetReflection();
+
+ Message* released = reflection->ReleaseMessage(
+ to_message, descriptor->FindFieldByName("foo_lazy_message"));
+ EXPECT_TRUE(released == nullptr);
+ released = reflection->ReleaseMessage(
+ to_message, descriptor->FindFieldByName("foo_message"));
+ EXPECT_TRUE(released == nullptr);
+
+ TestUtil::ReflectionTester::SetOneofViaReflection(&from_message1);
+ TestUtil::ReflectionTester::ExpectOneofSetViaReflection(from_message1);
+
+ TestUtil::ReflectionTester::
+ SetAllocatedOptionalMessageFieldsToMessageViaReflection(&from_message1,
+ to_message);
+ const Message& sub_message = reflection->GetMessage(
+ *to_message, descriptor->FindFieldByName("foo_lazy_message"));
+ released = reflection->ReleaseMessage(
+ to_message, descriptor->FindFieldByName("foo_lazy_message"));
+ EXPECT_TRUE(released != nullptr);
+ // Since sub_message is arena allocated, releasing it results in copying it
+ // into new heap-allocated memory.
+ EXPECT_NE(&sub_message, released);
+ delete released;
+
+ TestUtil::ReflectionTester::SetOneofViaReflection(&from_message2);
+
+ reflection->MutableMessage(&from_message2,
+ descriptor->FindFieldByName("foo_message"));
+
+ TestUtil::ReflectionTester::
+ SetAllocatedOptionalMessageFieldsToMessageViaReflection(&from_message2,
+ to_message);
+
+ const Message& sub_message2 = reflection->GetMessage(
+ *to_message, descriptor->FindFieldByName("foo_message"));
+ released = reflection->ReleaseMessage(
+ to_message, descriptor->FindFieldByName("foo_message"));
+ EXPECT_TRUE(released != nullptr);
+ // Since sub_message2 is arena allocated, releasing it results in copying it
+ // into new heap-allocated memory.
+ EXPECT_NE(&sub_message2, released);
+ delete released;
+}
+
+TEST(GeneratedMessageReflectionTest, ReleaseMessageTest) {
+ unittest::TestAllTypes message;
+ TestUtil::ReflectionTester reflection_tester(
+ unittest::TestAllTypes::descriptor());
+
+ // When nothing is set, we expect all released messages to be nullptr.
+ reflection_tester.ExpectMessagesReleasedViaReflection(
+ &message, TestUtil::ReflectionTester::IS_NULL);
+
+ // After fields are set we should get non-nullptr releases.
+ reflection_tester.SetAllFieldsViaReflection(&message);
+ reflection_tester.ExpectMessagesReleasedViaReflection(
+ &message, TestUtil::ReflectionTester::NOT_NULL);
+
+ // After Clear() we may or may not get a message from ReleaseMessage().
+ // This is implementation specific.
+ reflection_tester.SetAllFieldsViaReflection(&message);
+ message.Clear();
+ reflection_tester.ExpectMessagesReleasedViaReflection(
+ &message, TestUtil::ReflectionTester::CAN_BE_NULL);
+
+ // Test a different code path for setting after releasing.
+ TestUtil::SetAllFields(&message);
+ TestUtil::ExpectAllFieldsSet(message);
+}
+
+TEST(GeneratedMessageReflectionTest, ReleaseExtensionMessageTest) {
+ unittest::TestAllExtensions message;
+ TestUtil::ReflectionTester reflection_tester(
+ unittest::TestAllExtensions::descriptor());
+
+ // When nothing is set, we expect all released messages to be nullptr.
+ reflection_tester.ExpectMessagesReleasedViaReflection(
+ &message, TestUtil::ReflectionTester::IS_NULL);
+
+ // After fields are set we should get non-nullptr releases.
+ reflection_tester.SetAllFieldsViaReflection(&message);
+ reflection_tester.ExpectMessagesReleasedViaReflection(
+ &message, TestUtil::ReflectionTester::NOT_NULL);
+
+ // After Clear() we may or may not get a message from ReleaseMessage().
+ // This is implementation specific.
+ reflection_tester.SetAllFieldsViaReflection(&message);
+ message.Clear();
+ reflection_tester.ExpectMessagesReleasedViaReflection(
+ &message, TestUtil::ReflectionTester::CAN_BE_NULL);
+
+ // Test a different code path for setting after releasing.
+ TestUtil::SetAllExtensions(&message);
+ TestUtil::ExpectAllExtensionsSet(message);
+}
+
+TEST(GeneratedMessageReflectionTest, ReleaseOneofMessageTest) {
+ unittest::TestOneof2 message;
+ TestUtil::ReflectionTester::SetOneofViaReflection(&message);
+
+ const Descriptor* descriptor = unittest::TestOneof2::descriptor();
+ const Reflection* reflection = message.GetReflection();
+ const Message& sub_message = reflection->GetMessage(
+ message, descriptor->FindFieldByName("foo_lazy_message"));
+ (void)sub_message; // unused in somce configurations
+ Message* released = reflection->ReleaseMessage(
+ &message, descriptor->FindFieldByName("foo_lazy_message"));
+
+ EXPECT_TRUE(released != nullptr);
+ EXPECT_EQ(&sub_message, released);
+ delete released;
+
+ released = reflection->ReleaseMessage(
+ &message, descriptor->FindFieldByName("foo_lazy_message"));
+ EXPECT_TRUE(released == nullptr);
+}
+
+TEST(GeneratedMessageReflectionTest, ArenaReleaseMessageTest) {
+ Arena arena;
+ unittest::TestAllTypes* message =
+ Arena::CreateMessage<unittest::TestAllTypes>(&arena);
+ TestUtil::ReflectionTester reflection_tester(
+ unittest::TestAllTypes::descriptor());
+
+ // When nothing is set, we expect all released messages to be nullptr.
+ reflection_tester.ExpectMessagesReleasedViaReflection(
+ message, TestUtil::ReflectionTester::IS_NULL);
+
+ // After fields are set we should get non-nullptr releases.
+ reflection_tester.SetAllFieldsViaReflection(message);
+ reflection_tester.ExpectMessagesReleasedViaReflection(
+ message, TestUtil::ReflectionTester::NOT_NULL);
+
+ // After Clear() we may or may not get a message from ReleaseMessage().
+ // This is implementation specific.
+ reflection_tester.SetAllFieldsViaReflection(message);
+ message->Clear();
+ reflection_tester.ExpectMessagesReleasedViaReflection(
+ message, TestUtil::ReflectionTester::CAN_BE_NULL);
+}
+
+TEST(GeneratedMessageReflectionTest, ArenaReleaseExtensionMessageTest) {
+ Arena arena;
+ unittest::TestAllExtensions* message =
+ Arena::CreateMessage<unittest::TestAllExtensions>(&arena);
+ TestUtil::ReflectionTester reflection_tester(
+ unittest::TestAllExtensions::descriptor());
+
+ // When nothing is set, we expect all released messages to be nullptr.
+ reflection_tester.ExpectMessagesReleasedViaReflection(
+ message, TestUtil::ReflectionTester::IS_NULL);
+
+ // After fields are set we should get non-nullptr releases.
+ reflection_tester.SetAllFieldsViaReflection(message);
+ reflection_tester.ExpectMessagesReleasedViaReflection(
+ message, TestUtil::ReflectionTester::NOT_NULL);
+
+ // After Clear() we may or may not get a message from ReleaseMessage().
+ // This is implementation specific.
+ reflection_tester.SetAllFieldsViaReflection(message);
+ message->Clear();
+ reflection_tester.ExpectMessagesReleasedViaReflection(
+ message, TestUtil::ReflectionTester::CAN_BE_NULL);
+}
+
+TEST(GeneratedMessageReflectionTest, ArenaReleaseOneofMessageTest) {
+ Arena arena;
+ unittest::TestOneof2* message =
+ Arena::CreateMessage<unittest::TestOneof2>(&arena);
+ TestUtil::ReflectionTester::SetOneofViaReflection(message);
+
+ const Descriptor* descriptor = unittest::TestOneof2::descriptor();
+ const Reflection* reflection = message->GetReflection();
+ Message* released = reflection->ReleaseMessage(
+ message, descriptor->FindFieldByName("foo_lazy_message"));
+
+ EXPECT_TRUE(released != nullptr);
+ delete released;
+
+ released = reflection->ReleaseMessage(
+ message, descriptor->FindFieldByName("foo_lazy_message"));
+ EXPECT_TRUE(released == nullptr);
+}
+
+#ifdef PROTOBUF_HAS_DEATH_TEST
+
+TEST(GeneratedMessageReflectionTest, UsageErrors) {
+ unittest::TestAllTypes message;
+ const Reflection* reflection = message.GetReflection();
+ const Descriptor* descriptor = message.GetDescriptor();
+
+#define f(NAME) descriptor->FindFieldByName(NAME)
+
+ // Testing every single failure mode would be too much work. Let's just
+ // check a few.
+ EXPECT_DEATH(
+ reflection->GetInt32(message,
+ descriptor->FindFieldByName("optional_int64")),
+ "Protocol Buffer reflection usage error:\n"
+ " Method : google::protobuf::Reflection::GetInt32\n"
+ " Message type: protobuf_unittest\\.TestAllTypes\n"
+ " Field : protobuf_unittest\\.TestAllTypes\\.optional_int64\n"
+ " Problem : Field is not the right type for this message:\n"
+ " Expected : CPPTYPE_INT32\n"
+ " Field type: CPPTYPE_INT64");
+ EXPECT_DEATH(reflection->GetInt32(
+ message, descriptor->FindFieldByName("repeated_int32")),
+ "Protocol Buffer reflection usage error:\n"
+ " Method : google::protobuf::Reflection::GetInt32\n"
+ " Message type: protobuf_unittest.TestAllTypes\n"
+ " Field : protobuf_unittest.TestAllTypes.repeated_int32\n"
+ " Problem : Field is repeated; the method requires a "
+ "singular field.");
+ EXPECT_DEATH(
+ reflection->GetInt32(
+ message,
+ unittest::ForeignMessage::descriptor()->FindFieldByName("c")),
+ "Protocol Buffer reflection usage error:\n"
+ " Method : google::protobuf::Reflection::GetInt32\n"
+ " Message type: protobuf_unittest.TestAllTypes\n"
+ " Field : protobuf_unittest.ForeignMessage.c\n"
+ " Problem : Field does not match message type.");
+ EXPECT_DEATH(
+ reflection->HasField(
+ message,
+ unittest::ForeignMessage::descriptor()->FindFieldByName("c")),
+ "Protocol Buffer reflection usage error:\n"
+ " Method : google::protobuf::Reflection::HasField\n"
+ " Message type: protobuf_unittest.TestAllTypes\n"
+ " Field : protobuf_unittest.ForeignMessage.c\n"
+ " Problem : Field does not match message type.");
+
+#undef f
+}
+
+#endif // PROTOBUF_HAS_DEATH_TEST
+
+
+} // namespace
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/generated_message_table_driven.cc b/NorthstarDedicatedTest/include/protobuf/generated_message_table_driven.cc
new file mode 100644
index 00000000..309889ab
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/generated_message_table_driven.cc
@@ -0,0 +1,103 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <generated_message_table_driven.h>
+
+#include <type_traits>
+
+#include <stubs/casts.h>
+#include <generated_message_table_driven_lite.h>
+#include <io/zero_copy_stream_impl_lite.h>
+#include <repeated_field.h>
+#include <wire_format.h>
+#include <wire_format_lite.h>
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+namespace {
+
+UnknownFieldSet* MutableUnknownFields(MessageLite* msg, int64_t arena_offset) {
+ return Raw<InternalMetadata>(msg, arena_offset)
+ ->mutable_unknown_fields<UnknownFieldSet>();
+}
+
+struct UnknownFieldHandler {
+ // TODO(mvels): consider renaming UnknownFieldHandler to (TableDrivenTraits?),
+ // and conflating InternalMetaData into it, simplifying the template.
+ static constexpr bool IsLite() { return false; }
+
+ static bool Skip(MessageLite* msg, const ParseTable& table,
+ io::CodedInputStream* input, int tag) {
+ GOOGLE_DCHECK(table.unknown_field_set);
+
+ return WireFormat::SkipField(input, tag,
+ MutableUnknownFields(msg, table.arena_offset));
+ }
+
+ static void Varint(MessageLite* msg, const ParseTable& table, int tag,
+ int value) {
+ GOOGLE_DCHECK(table.unknown_field_set);
+
+ MutableUnknownFields(msg, table.arena_offset)
+ ->AddVarint(WireFormatLite::GetTagFieldNumber(tag), value);
+ }
+
+ static bool ParseExtension(MessageLite* msg, const ParseTable& table,
+ io::CodedInputStream* input, int tag) {
+ ExtensionSet* extensions = GetExtensionSet(msg, table.extension_offset);
+ if (extensions == nullptr) {
+ return false;
+ }
+
+ const Message* prototype =
+ down_cast<const Message*>(table.default_instance());
+
+ GOOGLE_DCHECK(prototype != nullptr);
+ GOOGLE_DCHECK(table.unknown_field_set);
+ UnknownFieldSet* unknown_fields =
+ MutableUnknownFields(msg, table.arena_offset);
+
+ return extensions->ParseField(tag, input, prototype, unknown_fields);
+ }
+};
+
+} // namespace
+
+bool MergePartialFromCodedStream(MessageLite* msg, const ParseTable& table,
+ io::CodedInputStream* input) {
+ return MergePartialFromCodedStreamImpl<UnknownFieldHandler>(msg, table,
+ input);
+}
+
+} // namespace internal
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/generated_message_table_driven.h b/NorthstarDedicatedTest/include/protobuf/generated_message_table_driven.h
new file mode 100644
index 00000000..fee0e79e
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/generated_message_table_driven.h
@@ -0,0 +1,351 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef GOOGLE_PROTOBUF_GENERATED_MESSAGE_TABLE_DRIVEN_H__
+#define GOOGLE_PROTOBUF_GENERATED_MESSAGE_TABLE_DRIVEN_H__
+
+#include <map.h>
+#include <map_entry_lite.h>
+#include <map_field_lite.h>
+#include <message_lite.h>
+#include <wire_format_lite.h>
+
+// We require C++11 and Clang to use constexpr for variables, as GCC 4.8
+// requires constexpr to be consistent between declarations of variables
+// unnecessarily (see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58541).
+// VS 2017 Update 3 also supports this usage of constexpr.
+#if defined(__clang__) || (defined(_MSC_VER) && _MSC_VER >= 1911)
+#define PROTOBUF_CONSTEXPR_VAR constexpr
+#else // !__clang__
+#define PROTOBUF_CONSTEXPR_VAR
+#endif // !_clang
+
+#ifdef SWIG
+#error "You cannot SWIG proto headers"
+#endif
+
+#include <port_def.inc>
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+// Processing-type masks.
+static constexpr const unsigned char kOneofMask = 0x40;
+static constexpr const unsigned char kRepeatedMask = 0x20;
+// Mask for the raw type: either a WireFormatLite::FieldType or one of the
+// ProcessingTypes below, without the oneof or repeated flag.
+static constexpr const unsigned char kTypeMask = 0x1f;
+
+// Wire type masks.
+static constexpr const unsigned char kNotPackedMask = 0x10;
+static constexpr const unsigned char kInvalidMask = 0x20;
+
+enum ProcessingTypes {
+ TYPE_STRING_CORD = 19,
+ TYPE_STRING_STRING_PIECE = 20,
+ TYPE_BYTES_CORD = 21,
+ TYPE_BYTES_STRING_PIECE = 22,
+ TYPE_STRING_INLINED = 23,
+ TYPE_BYTES_INLINED = 24,
+ TYPE_MAP = 25,
+};
+
+static_assert(TYPE_MAP < kRepeatedMask, "Invalid enum");
+
+struct PROTOBUF_EXPORT FieldMetadata {
+ uint32_t offset; // offset of this field in the struct
+ uint32_t tag; // field * 8 + wire_type
+ // byte offset * 8 + bit_offset;
+ // if the high bit is set then this is the byte offset of the oneof_case
+ // for this field.
+ uint32_t has_offset;
+ uint32_t type; // the type of this field.
+ const void* ptr; // auxiliary data
+
+ // From the serializer point of view each fundamental type can occur in
+ // 4 different ways. For simplicity we treat all combinations as a cartesion
+ // product although not all combinations are allowed.
+ enum FieldTypeClass {
+ kPresence,
+ kNoPresence,
+ kRepeated,
+ kPacked,
+ kOneOf,
+ kNumTypeClasses // must be last enum
+ };
+ // C++ protobuf has 20 fundamental types, were we added Cord and StringPiece
+ // and also distinguish the same types if they have different wire format.
+ enum {
+ kCordType = 19,
+ kStringPieceType = 20,
+ kInlinedType = 21,
+ kNumTypes = 21,
+ kSpecial = kNumTypes * kNumTypeClasses,
+ };
+
+ static int CalculateType(int fundamental_type, FieldTypeClass type_class);
+};
+
+// TODO(ckennelly): Add a static assertion to ensure that these masks do not
+// conflict with wiretypes.
+
+// ParseTableField is kept small to help simplify instructions for computing
+// offsets, as we will always need this information to parse a field.
+// Additional data, needed for some types, is stored in
+// AuxiliaryParseTableField.
+struct ParseTableField {
+ uint32_t offset;
+ // The presence_index ordinarily represents a has_bit index, but for fields
+ // inside a oneof it represents the index in _oneof_case_.
+ uint32_t presence_index;
+ unsigned char normal_wiretype;
+ unsigned char packed_wiretype;
+
+ // processing_type is given by:
+ // (FieldDescriptor->type() << 1) | FieldDescriptor->is_packed()
+ unsigned char processing_type;
+
+ unsigned char tag_size;
+};
+
+struct ParseTable;
+
+union AuxiliaryParseTableField {
+ typedef bool (*EnumValidator)(int);
+
+ // Enums
+ struct enum_aux {
+ EnumValidator validator;
+ };
+ enum_aux enums;
+ // Group, messages
+ struct message_aux {
+ // ExplicitlyInitialized<T> -> T requires a reinterpret_cast, which prevents
+ // the tables from being constructed as a constexpr. We use void to avoid
+ // the cast.
+ const void* default_message_void;
+ const MessageLite* default_message() const {
+ return static_cast<const MessageLite*>(default_message_void);
+ }
+ };
+ message_aux messages;
+ // Strings
+ struct string_aux {
+ const void* default_ptr;
+ const char* field_name;
+ };
+ string_aux strings;
+
+ struct map_aux {
+ bool (*parse_map)(io::CodedInputStream*, void*);
+ };
+ map_aux maps;
+
+ AuxiliaryParseTableField() = default;
+ constexpr AuxiliaryParseTableField(AuxiliaryParseTableField::enum_aux e)
+ : enums(e) {}
+ constexpr AuxiliaryParseTableField(AuxiliaryParseTableField::message_aux m)
+ : messages(m) {}
+ constexpr AuxiliaryParseTableField(AuxiliaryParseTableField::string_aux s)
+ : strings(s) {}
+ constexpr AuxiliaryParseTableField(AuxiliaryParseTableField::map_aux m)
+ : maps(m) {}
+};
+
+struct ParseTable {
+ const ParseTableField* fields;
+ const AuxiliaryParseTableField* aux;
+ int max_field_number;
+ // TODO(ckennelly): Do something with this padding.
+
+ // TODO(ckennelly): Vet these for sign extension.
+ int64_t has_bits_offset;
+ int64_t oneof_case_offset;
+ int64_t extension_offset;
+ int64_t arena_offset;
+
+ // ExplicitlyInitialized<T> -> T requires a reinterpret_cast, which prevents
+ // the tables from being constructed as a constexpr. We use void to avoid
+ // the cast.
+ const void* default_instance_void;
+ const MessageLite* default_instance() const {
+ return static_cast<const MessageLite*>(default_instance_void);
+ }
+
+ bool unknown_field_set;
+};
+
+static_assert(sizeof(ParseTableField) <= 16, "ParseTableField is too large");
+// The tables must be composed of POD components to ensure link-time
+// initialization.
+static_assert(std::is_standard_layout<ParseTableField>::value, "");
+static_assert(std::is_trivial<ParseTableField>::value, "");
+static_assert(std::is_standard_layout<AuxiliaryParseTableField>::value, "");
+static_assert(std::is_trivial<AuxiliaryParseTableField>::value, "");
+static_assert(
+ std::is_standard_layout<AuxiliaryParseTableField::enum_aux>::value, "");
+static_assert(std::is_trivial<AuxiliaryParseTableField::enum_aux>::value, "");
+static_assert(
+ std::is_standard_layout<AuxiliaryParseTableField::message_aux>::value, "");
+static_assert(std::is_trivial<AuxiliaryParseTableField::message_aux>::value,
+ "");
+static_assert(
+ std::is_standard_layout<AuxiliaryParseTableField::string_aux>::value, "");
+static_assert(std::is_trivial<AuxiliaryParseTableField::string_aux>::value, "");
+static_assert(std::is_standard_layout<ParseTable>::value, "");
+static_assert(std::is_trivial<ParseTable>::value, "");
+
+// TODO(ckennelly): Consolidate these implementations into a single one, using
+// dynamic dispatch to the appropriate unknown field handler.
+bool MergePartialFromCodedStream(MessageLite* msg, const ParseTable& table,
+ io::CodedInputStream* input);
+bool MergePartialFromCodedStreamLite(MessageLite* msg, const ParseTable& table,
+ io::CodedInputStream* input);
+
+template <typename Entry>
+bool ParseMap(io::CodedInputStream* input, void* map_field) {
+ typedef typename MapEntryToMapField<Entry>::MapFieldType MapFieldType;
+ typedef Map<typename Entry::EntryKeyType, typename Entry::EntryValueType>
+ MapType;
+ typedef typename Entry::template Parser<MapFieldType, MapType> ParserType;
+
+ ParserType parser(static_cast<MapFieldType*>(map_field));
+ return WireFormatLite::ReadMessageNoVirtual(input, &parser);
+}
+
+struct SerializationTable {
+ int num_fields;
+ const FieldMetadata* field_table;
+};
+
+PROTOBUF_EXPORT void SerializeInternal(const uint8_t* base,
+ const FieldMetadata* table,
+ int32_t num_fields,
+ io::CodedOutputStream* output);
+
+inline void TableSerialize(const MessageLite& msg,
+ const SerializationTable* table,
+ io::CodedOutputStream* output) {
+ const FieldMetadata* field_table = table->field_table;
+ int num_fields = table->num_fields - 1;
+ const uint8_t* base = reinterpret_cast<const uint8_t*>(&msg);
+ // TODO(gerbens) This skips the first test if we could use the fast
+ // array serialization path, we should make this
+ // int cached_size =
+ // *reinterpret_cast<const int32_t*>(base + field_table->offset);
+ // SerializeWithCachedSize(msg, field_table + 1, num_fields, cached_size, ...)
+ // But we keep conformance with the old way for now.
+ SerializeInternal(base, field_table + 1, num_fields, output);
+}
+
+PROTOBUF_EXPORT uint8_t* SerializeInternalToArray(const uint8_t* base,
+ const FieldMetadata* table,
+ int32_t num_fields,
+ bool is_deterministic,
+ uint8_t* buffer);
+
+inline uint8_t* TableSerializeToArray(const MessageLite& msg,
+ const SerializationTable* table,
+ bool is_deterministic, uint8_t* buffer) {
+ const uint8_t* base = reinterpret_cast<const uint8_t*>(&msg);
+ const FieldMetadata* field_table = table->field_table + 1;
+ int num_fields = table->num_fields - 1;
+ return SerializeInternalToArray(base, field_table, num_fields,
+ is_deterministic, buffer);
+}
+
+template <typename T>
+struct CompareHelper {
+ bool operator()(const T& a, const T& b) const { return a < b; }
+};
+
+template <>
+struct CompareHelper<ArenaStringPtr> {
+ bool operator()(const ArenaStringPtr& a, const ArenaStringPtr& b) const {
+ return a.Get() < b.Get();
+ }
+};
+
+struct CompareMapKey {
+ template <typename T>
+ bool operator()(const MapEntryHelper<T>& a,
+ const MapEntryHelper<T>& b) const {
+ return Compare(a.key_, b.key_);
+ }
+ template <typename T>
+ bool Compare(const T& a, const T& b) const {
+ return CompareHelper<T>()(a, b);
+ }
+};
+
+template <typename MapFieldType, const SerializationTable* table>
+void MapFieldSerializer(const uint8_t* base, uint32_t offset, uint32_t tag,
+ uint32_t has_offset, io::CodedOutputStream* output) {
+ typedef MapEntryHelper<typename MapFieldType::EntryTypeTrait> Entry;
+ typedef typename MapFieldType::MapType::const_iterator Iter;
+
+ const MapFieldType& map_field =
+ *reinterpret_cast<const MapFieldType*>(base + offset);
+ const SerializationTable* t =
+ table +
+ has_offset; // has_offset is overloaded for maps to mean table offset
+ if (!output->IsSerializationDeterministic()) {
+ for (Iter it = map_field.GetMap().begin(); it != map_field.GetMap().end();
+ ++it) {
+ Entry map_entry(*it);
+ output->WriteVarint32(tag);
+ output->WriteVarint32(map_entry._cached_size_);
+ SerializeInternal(reinterpret_cast<const uint8_t*>(&map_entry),
+ t->field_table, t->num_fields, output);
+ }
+ } else {
+ std::vector<Entry> v;
+ for (Iter it = map_field.GetMap().begin(); it != map_field.GetMap().end();
+ ++it) {
+ v.push_back(Entry(*it));
+ }
+ std::sort(v.begin(), v.end(), CompareMapKey());
+ for (int i = 0; i < v.size(); i++) {
+ output->WriteVarint32(tag);
+ output->WriteVarint32(v[i]._cached_size_);
+ SerializeInternal(reinterpret_cast<const uint8_t*>(&v[i]), t->field_table,
+ t->num_fields, output);
+ }
+ }
+}
+
+} // namespace internal
+} // namespace protobuf
+} // namespace google
+
+#include <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_GENERATED_MESSAGE_TABLE_DRIVEN_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/generated_message_table_driven_lite.cc b/NorthstarDedicatedTest/include/protobuf/generated_message_table_driven_lite.cc
new file mode 100644
index 00000000..125bbbfc
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/generated_message_table_driven_lite.cc
@@ -0,0 +1,106 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <generated_message_table_driven_lite.h>
+
+#include <type_traits>
+
+#include <io/zero_copy_stream_impl_lite.h>
+#include <metadata_lite.h>
+#include <repeated_field.h>
+#include <wire_format_lite.h>
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+namespace {
+
+std::string* MutableUnknownFields(MessageLite* msg, int64_t arena_offset) {
+ return Raw<InternalMetadata>(msg, arena_offset)
+ ->mutable_unknown_fields<std::string>();
+}
+
+struct UnknownFieldHandlerLite {
+ // TODO(mvels): consider renaming UnknownFieldHandler to (TableDrivenTraits?),
+ // and conflating InternalMetaData into it, simplifying the template.
+ static constexpr bool IsLite() { return true; }
+
+ static bool Skip(MessageLite* msg, const ParseTable& table,
+ io::CodedInputStream* input, int tag) {
+ GOOGLE_DCHECK(!table.unknown_field_set);
+ io::StringOutputStream unknown_fields_string(
+ MutableUnknownFields(msg, table.arena_offset));
+ io::CodedOutputStream unknown_fields_stream(&unknown_fields_string, false);
+
+ return internal::WireFormatLite::SkipField(input, tag,
+ &unknown_fields_stream);
+ }
+
+ static void Varint(MessageLite* msg, const ParseTable& table, int tag,
+ int value) {
+ GOOGLE_DCHECK(!table.unknown_field_set);
+
+ io::StringOutputStream unknown_fields_string(
+ MutableUnknownFields(msg, table.arena_offset));
+ io::CodedOutputStream unknown_fields_stream(&unknown_fields_string, false);
+ unknown_fields_stream.WriteVarint32(tag);
+ unknown_fields_stream.WriteVarint32(value);
+ }
+
+ static bool ParseExtension(MessageLite* msg, const ParseTable& table,
+ io::CodedInputStream* input, int tag) {
+ ExtensionSet* extensions = GetExtensionSet(msg, table.extension_offset);
+ if (extensions == nullptr) {
+ return false;
+ }
+
+ const MessageLite* prototype = table.default_instance();
+
+ GOOGLE_DCHECK(!table.unknown_field_set);
+ io::StringOutputStream unknown_fields_string(
+ MutableUnknownFields(msg, table.arena_offset));
+ io::CodedOutputStream unknown_fields_stream(&unknown_fields_string, false);
+ return extensions->ParseField(tag, input, prototype,
+ &unknown_fields_stream);
+ }
+};
+
+} // namespace
+
+bool MergePartialFromCodedStreamLite(MessageLite* msg, const ParseTable& table,
+ io::CodedInputStream* input) {
+ return MergePartialFromCodedStreamImpl<UnknownFieldHandlerLite>(msg, table,
+ input);
+}
+
+} // namespace internal
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/generated_message_table_driven_lite.h b/NorthstarDedicatedTest/include/protobuf/generated_message_table_driven_lite.h
new file mode 100644
index 00000000..b6fda6fb
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/generated_message_table_driven_lite.h
@@ -0,0 +1,874 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef GOOGLE_PROTOBUF_GENERATED_MESSAGE_TABLE_DRIVEN_LITE_H__
+#define GOOGLE_PROTOBUF_GENERATED_MESSAGE_TABLE_DRIVEN_LITE_H__
+
+#include <io/zero_copy_stream_impl_lite.h>
+#include <extension_set.h>
+#include <generated_message_table_driven.h>
+#include <implicit_weak_message.h>
+#include <inlined_string_field.h>
+#include <repeated_field.h>
+#include <wire_format_lite.h>
+#include <type_traits>
+
+
+#include <port_def.inc>
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+
+enum StringType {
+ StringType_STRING = 0,
+ StringType_INLINED = 3
+};
+
+// Logically a superset of StringType, consisting of all field types that
+// require special initialization.
+enum ProcessingType {
+ ProcessingType_STRING = 0,
+ ProcessingType_CORD = 1,
+ ProcessingType_STRING_PIECE = 2,
+ ProcessingType_INLINED = 3,
+ ProcessingType_MESSAGE = 4,
+};
+
+enum Cardinality {
+ Cardinality_SINGULAR = 0,
+ Cardinality_REPEATED = 1,
+ Cardinality_ONEOF = 3
+};
+
+template <typename Type>
+inline Type* Raw(MessageLite* msg, int64_t offset) {
+ return reinterpret_cast<Type*>(reinterpret_cast<uint8_t*>(msg) + offset);
+}
+
+template <typename Type>
+inline const Type* Raw(const MessageLite* msg, int64_t offset) {
+ return reinterpret_cast<const Type*>(reinterpret_cast<const uint8_t*>(msg) +
+ offset);
+}
+
+inline ExtensionSet* GetExtensionSet(MessageLite* msg,
+ int64_t extension_offset) {
+ if (extension_offset == -1) {
+ return nullptr;
+ }
+
+ return Raw<ExtensionSet>(msg, extension_offset);
+}
+
+template <typename Type>
+inline Type* AddField(MessageLite* msg, int64_t offset) {
+ static_assert(std::is_trivial<Type>::value ||
+ std::is_same<Type, InlinedStringField>::value,
+ "Do not assign");
+
+ RepeatedField<Type>* repeated = Raw<RepeatedField<Type>>(msg, offset);
+ return repeated->Add();
+}
+
+template <>
+inline std::string* AddField<std::string>(MessageLite* msg, int64_t offset) {
+ RepeatedPtrField<std::string>* repeated =
+ Raw<RepeatedPtrField<std::string>>(msg, offset);
+ return repeated->Add();
+}
+
+
+template <typename Type>
+inline void AddField(MessageLite* msg, int64_t offset, Type value) {
+ static_assert(std::is_trivial<Type>::value, "Do not assign");
+ *AddField<Type>(msg, offset) = value;
+}
+
+inline void SetBit(uint32_t* has_bits, uint32_t has_bit_index) {
+ GOOGLE_DCHECK(has_bits != nullptr);
+
+ uint32_t mask = static_cast<uint32_t>(1u) << (has_bit_index % 32);
+ has_bits[has_bit_index / 32u] |= mask;
+}
+
+template <typename Type>
+inline Type* MutableField(MessageLite* msg, uint32_t* has_bits,
+ uint32_t has_bit_index, int64_t offset) {
+ SetBit(has_bits, has_bit_index);
+ return Raw<Type>(msg, offset);
+}
+
+template <typename Type>
+inline void SetField(MessageLite* msg, uint32_t* has_bits,
+ uint32_t has_bit_index, int64_t offset, Type value) {
+ static_assert(std::is_trivial<Type>::value, "Do not assign");
+ *MutableField<Type>(msg, has_bits, has_bit_index, offset) = value;
+}
+
+template <typename Type>
+inline void SetOneofField(MessageLite* msg, uint32_t* oneof_case,
+ uint32_t oneof_case_index, int64_t offset,
+ int field_number, Type value) {
+ oneof_case[oneof_case_index] = field_number;
+ *Raw<Type>(msg, offset) = value;
+}
+
+// Clears a oneof field. The field argument should correspond to the particular
+// field that is currently set in the oneof.
+inline void ClearOneofField(const ParseTableField& field, Arena* arena,
+ MessageLite* msg) {
+ switch (field.processing_type & kTypeMask) {
+ case WireFormatLite::TYPE_MESSAGE:
+ if (arena == nullptr) {
+ delete *Raw<MessageLite*>(msg, field.offset);
+ }
+ break;
+
+ case WireFormatLite::TYPE_STRING:
+ case WireFormatLite::TYPE_BYTES:
+ Raw<ArenaStringPtr>(msg, field.offset)
+ ->Destroy(ArenaStringPtr::EmptyDefault{}, arena);
+ break;
+
+ case TYPE_STRING_INLINED:
+ case TYPE_BYTES_INLINED:
+ Raw<InlinedStringField>(msg, field.offset)->DestroyNoArena(nullptr);
+ break;
+
+ default:
+ // No cleanup needed.
+ break;
+ }
+}
+
+// Clears and reinitializes a oneof field as necessary, in preparation for
+// parsing a new value with type field_type and field number field_number.
+//
+// Note: the oneof_case argument should point directly to the _oneof_case_
+// element corresponding to this particular oneof, not to the beginning of the
+// _oneof_case_ array.
+template <ProcessingType field_type>
+inline void ResetOneofField(const ParseTable& table, int field_number,
+ Arena* arena, MessageLite* msg,
+ uint32_t* oneof_case, int64_t offset,
+ const void* default_ptr) {
+ if (static_cast<int64_t>(*oneof_case) == field_number) {
+ // The oneof is already set to the right type, so there is no need to clear
+ // it.
+ return;
+ }
+
+ if (*oneof_case != 0) {
+ ClearOneofField(table.fields[*oneof_case], arena, msg);
+ }
+ *oneof_case = field_number;
+
+ switch (field_type) {
+ case ProcessingType_STRING:
+ Raw<ArenaStringPtr>(msg, offset)
+ ->UnsafeSetDefault(static_cast<const std::string*>(default_ptr));
+ break;
+ case ProcessingType_INLINED:
+ new (Raw<InlinedStringField>(msg, offset))
+ InlinedStringField(*static_cast<const std::string*>(default_ptr));
+ break;
+ case ProcessingType_MESSAGE:
+ MessageLite** submessage = Raw<MessageLite*>(msg, offset);
+ const MessageLite* prototype =
+ table.aux[field_number].messages.default_message();
+ *submessage = prototype->New(arena);
+ break;
+ }
+}
+
+template <typename UnknownFieldHandler, Cardinality cardinality,
+ bool is_string_type, StringType ctype>
+static inline bool HandleString(io::CodedInputStream* input, MessageLite* msg,
+ Arena* arena, uint32_t* has_bits,
+ uint32_t has_bit_index, int64_t offset,
+ const void* default_ptr,
+ const char* field_name) {
+ StringPiece utf8_string_data;
+#ifdef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
+ constexpr bool kValidateUtf8 = is_string_type;
+#else
+ constexpr bool kValidateUtf8 = false;
+#endif // GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
+
+ switch (ctype) {
+ case StringType_INLINED: {
+ std::string* value = nullptr;
+ switch (cardinality) {
+ case Cardinality_SINGULAR: {
+ // TODO(ckennelly): Is this optimal?
+ InlinedStringField* s = MutableField<InlinedStringField>(
+ msg, has_bits, has_bit_index, offset);
+ value = s->UnsafeMutablePointer();
+ } break;
+ case Cardinality_REPEATED: {
+ value = AddField<std::string>(msg, offset);
+ } break;
+ case Cardinality_ONEOF: {
+ InlinedStringField* s = Raw<InlinedStringField>(msg, offset);
+ value = s->UnsafeMutablePointer();
+ } break;
+ }
+ GOOGLE_DCHECK(value != nullptr);
+ if (PROTOBUF_PREDICT_FALSE(!WireFormatLite::ReadString(input, value))) {
+ return false;
+ }
+ utf8_string_data = *value;
+ break;
+ }
+ case StringType_STRING: {
+ switch (cardinality) {
+ case Cardinality_SINGULAR: {
+ ArenaStringPtr* field = MutableField<ArenaStringPtr>(
+ msg, has_bits, has_bit_index, offset);
+ std::string* value = field->MutableNoCopy(
+ static_cast<const std::string*>(default_ptr), arena);
+ if (PROTOBUF_PREDICT_FALSE(
+ !WireFormatLite::ReadString(input, value))) {
+ return false;
+ }
+ utf8_string_data = field->Get();
+ } break;
+ case Cardinality_REPEATED: {
+ std::string* value = AddField<std::string>(msg, offset);
+ if (PROTOBUF_PREDICT_FALSE(
+ !WireFormatLite::ReadString(input, value))) {
+ return false;
+ }
+ utf8_string_data = *value;
+ } break;
+ case Cardinality_ONEOF: {
+ ArenaStringPtr* field = Raw<ArenaStringPtr>(msg, offset);
+ std::string* value = field->MutableNoCopy(
+ static_cast<const std::string*>(default_ptr), arena);
+ if (PROTOBUF_PREDICT_FALSE(
+ !WireFormatLite::ReadString(input, value))) {
+ return false;
+ }
+ utf8_string_data = field->Get();
+ } break;
+ default:
+ PROTOBUF_ASSUME(false);
+ }
+ break;
+ }
+ default:
+ PROTOBUF_ASSUME(false);
+ }
+
+ if (kValidateUtf8) {
+ // TODO(b/118759213): fail if proto3
+ WireFormatLite::VerifyUtf8String(utf8_string_data.data(),
+ utf8_string_data.length(),
+ WireFormatLite::PARSE, field_name);
+ }
+ return true;
+}
+
+template <typename UnknownFieldHandler, Cardinality cardinality>
+inline bool HandleEnum(const ParseTable& table, io::CodedInputStream* input,
+ MessageLite* msg, uint32_t* presence,
+ uint32_t presence_index, int64_t offset, uint32_t tag,
+ int field_number) {
+ int value;
+ if (PROTOBUF_PREDICT_FALSE(
+ (!WireFormatLite::ReadPrimitive<int, WireFormatLite::TYPE_ENUM>(
+ input, &value)))) {
+ return false;
+ }
+
+ AuxiliaryParseTableField::EnumValidator validator =
+ table.aux[field_number].enums.validator;
+ if (validator == nullptr || validator(value)) {
+ switch (cardinality) {
+ case Cardinality_SINGULAR:
+ SetField(msg, presence, presence_index, offset, value);
+ break;
+ case Cardinality_REPEATED:
+ AddField(msg, offset, value);
+ break;
+ case Cardinality_ONEOF:
+ ClearOneofField(table.fields[presence[presence_index]], msg->GetArena(),
+ msg);
+ SetOneofField(msg, presence, presence_index, offset, field_number,
+ value);
+ break;
+ default:
+ PROTOBUF_ASSUME(false);
+ }
+ } else {
+ UnknownFieldHandler::Varint(msg, table, tag, value);
+ }
+
+ return true;
+}
+
+// RepeatedMessageTypeHandler allows us to operate on RepeatedPtrField fields
+// without instantiating the specific template.
+class RepeatedMessageTypeHandler {
+ public:
+ typedef MessageLite Type;
+ typedef MessageLite WeakType;
+ static Arena* GetArena(Type* t) { return t->GetArena(); }
+ static inline Type* NewFromPrototype(const Type* prototype,
+ Arena* arena = nullptr) {
+ return prototype->New(arena);
+ }
+ static void Delete(Type* t, Arena* arena = nullptr) {
+ if (arena == nullptr) {
+ delete t;
+ }
+ }
+};
+
+class MergePartialFromCodedStreamHelper {
+ public:
+ static MessageLite* Add(RepeatedPtrFieldBase* field,
+ const MessageLite* prototype) {
+ return field->Add<RepeatedMessageTypeHandler>(
+ const_cast<MessageLite*>(prototype));
+ }
+};
+
+template <typename UnknownFieldHandler, uint32_t kMaxTag>
+bool MergePartialFromCodedStreamInlined(MessageLite* msg,
+ const ParseTable& table,
+ io::CodedInputStream* input) {
+ // We require that has_bits are present, as to avoid having to check for them
+ // for every field.
+ //
+ // TODO(ckennelly): Make this a compile-time parameter with templates.
+ GOOGLE_DCHECK_GE(table.has_bits_offset, 0);
+ uint32_t* has_bits = Raw<uint32_t>(msg, table.has_bits_offset);
+ GOOGLE_DCHECK(has_bits != nullptr);
+
+ while (true) {
+ uint32_t tag = input->ReadTagWithCutoffNoLastTag(kMaxTag).first;
+ const WireFormatLite::WireType wire_type =
+ WireFormatLite::GetTagWireType(tag);
+ const int field_number = WireFormatLite::GetTagFieldNumber(tag);
+
+ if (PROTOBUF_PREDICT_FALSE(field_number > table.max_field_number)) {
+ // check for possible extensions
+ if (UnknownFieldHandler::ParseExtension(msg, table, input, tag)) {
+ // successfully parsed
+ continue;
+ }
+
+ if (PROTOBUF_PREDICT_FALSE(
+ !UnknownFieldHandler::Skip(msg, table, input, tag))) {
+ return false;
+ }
+
+ continue;
+ }
+
+ // We implicitly verify that data points to a valid field as we check the
+ // wire types. Entries in table.fields[i] that do not correspond to valid
+ // field numbers have their normal_wiretype and packed_wiretype fields set
+ // with the kInvalidMask value. As wire_type cannot take on that value, we
+ // will never match.
+ const ParseTableField* data = table.fields + field_number;
+
+ // TODO(ckennelly): Avoid sign extension
+ const int64_t presence_index = data->presence_index;
+ const int64_t offset = data->offset;
+ const unsigned char processing_type = data->processing_type;
+
+ if (data->normal_wiretype == static_cast<unsigned char>(wire_type)) {
+ switch (processing_type) {
+#define HANDLE_TYPE(TYPE, CPPTYPE) \
+ case (WireFormatLite::TYPE_##TYPE): { \
+ CPPTYPE value; \
+ if (PROTOBUF_PREDICT_FALSE( \
+ (!WireFormatLite::ReadPrimitive< \
+ CPPTYPE, WireFormatLite::TYPE_##TYPE>(input, &value)))) { \
+ return false; \
+ } \
+ SetField(msg, has_bits, presence_index, offset, value); \
+ break; \
+ } \
+ case (WireFormatLite::TYPE_##TYPE) | kRepeatedMask: { \
+ RepeatedField<CPPTYPE>* values = Raw<RepeatedField<CPPTYPE>>(msg, offset); \
+ if (PROTOBUF_PREDICT_FALSE((!WireFormatLite::ReadRepeatedPrimitive< \
+ CPPTYPE, WireFormatLite::TYPE_##TYPE>( \
+ data->tag_size, tag, input, values)))) { \
+ return false; \
+ } \
+ break; \
+ } \
+ case (WireFormatLite::TYPE_##TYPE) | kOneofMask: { \
+ uint32_t* oneof_case = Raw<uint32_t>(msg, table.oneof_case_offset); \
+ CPPTYPE value; \
+ if (PROTOBUF_PREDICT_FALSE( \
+ (!WireFormatLite::ReadPrimitive< \
+ CPPTYPE, WireFormatLite::TYPE_##TYPE>(input, &value)))) { \
+ return false; \
+ } \
+ ClearOneofField(table.fields[oneof_case[presence_index]], msg->GetArena(), \
+ msg); \
+ SetOneofField(msg, oneof_case, presence_index, offset, field_number, \
+ value); \
+ break; \
+ }
+
+ HANDLE_TYPE(INT32, int32_t)
+ HANDLE_TYPE(INT64, int64_t)
+ HANDLE_TYPE(SINT32, int32_t)
+ HANDLE_TYPE(SINT64, int64_t)
+ HANDLE_TYPE(UINT32, uint32_t)
+ HANDLE_TYPE(UINT64, uint64_t)
+
+ HANDLE_TYPE(FIXED32, uint32_t)
+ HANDLE_TYPE(FIXED64, uint64_t)
+ HANDLE_TYPE(SFIXED32, int32_t)
+ HANDLE_TYPE(SFIXED64, int64_t)
+
+ HANDLE_TYPE(FLOAT, float)
+ HANDLE_TYPE(DOUBLE, double)
+
+ HANDLE_TYPE(BOOL, bool)
+#undef HANDLE_TYPE
+ case WireFormatLite::TYPE_BYTES:
+#ifndef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
+ case WireFormatLite::TYPE_STRING:
+#endif // GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
+ {
+ Arena* const arena = msg->GetArena();
+ const void* default_ptr = table.aux[field_number].strings.default_ptr;
+
+ if (PROTOBUF_PREDICT_FALSE(
+ (!HandleString<UnknownFieldHandler, Cardinality_SINGULAR,
+ false, StringType_STRING>(
+ input, msg, arena, has_bits, presence_index, offset,
+ default_ptr, nullptr)))) {
+ return false;
+ }
+ break;
+ }
+ case TYPE_BYTES_INLINED:
+#ifndef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
+ case TYPE_STRING_INLINED:
+#endif // !GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
+ {
+ Arena* const arena = msg->GetArena();
+ const void* default_ptr = table.aux[field_number].strings.default_ptr;
+
+ if (PROTOBUF_PREDICT_FALSE(
+ (!HandleString<UnknownFieldHandler, Cardinality_SINGULAR,
+ false, StringType_INLINED>(
+ input, msg, arena, has_bits, presence_index, offset,
+ default_ptr, nullptr)))) {
+ return false;
+ }
+ break;
+ }
+ case WireFormatLite::TYPE_BYTES | kOneofMask:
+#ifndef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
+ case WireFormatLite::TYPE_STRING | kOneofMask:
+#endif // !GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
+ {
+ Arena* const arena = msg->GetArena();
+ uint32_t* oneof_case = Raw<uint32_t>(msg, table.oneof_case_offset);
+ const void* default_ptr = table.aux[field_number].strings.default_ptr;
+
+ ResetOneofField<ProcessingType_STRING>(
+ table, field_number, arena, msg, oneof_case + presence_index,
+ offset, default_ptr);
+
+ if (PROTOBUF_PREDICT_FALSE(
+ (!HandleString<UnknownFieldHandler, Cardinality_ONEOF, false,
+ StringType_STRING>(input, msg, arena, has_bits,
+ presence_index, offset,
+ default_ptr, nullptr)))) {
+ return false;
+ }
+ break;
+ }
+ case (WireFormatLite::TYPE_BYTES) | kRepeatedMask:
+ case TYPE_BYTES_INLINED | kRepeatedMask:
+#ifndef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
+ case (WireFormatLite::TYPE_STRING) | kRepeatedMask:
+ case TYPE_STRING_INLINED | kRepeatedMask:
+#endif // !GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
+ {
+ Arena* const arena = msg->GetArena();
+ const void* default_ptr = table.aux[field_number].strings.default_ptr;
+
+ if (PROTOBUF_PREDICT_FALSE(
+ (!HandleString<UnknownFieldHandler, Cardinality_REPEATED,
+ false, StringType_STRING>(
+ input, msg, arena, has_bits, presence_index, offset,
+ default_ptr, nullptr)))) {
+ return false;
+ }
+ break;
+ }
+#ifdef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
+ case (WireFormatLite::TYPE_STRING): {
+ Arena* const arena = msg->GetArena();
+ const void* default_ptr = table.aux[field_number].strings.default_ptr;
+ const char* field_name = table.aux[field_number].strings.field_name;
+
+ if (PROTOBUF_PREDICT_FALSE(
+ (!HandleString<UnknownFieldHandler, Cardinality_SINGULAR,
+ true, StringType_STRING>(
+ input, msg, arena, has_bits, presence_index, offset,
+ default_ptr, field_name)))) {
+ return false;
+ }
+ break;
+ }
+ case TYPE_STRING_INLINED | kRepeatedMask:
+ case (WireFormatLite::TYPE_STRING) | kRepeatedMask: {
+ Arena* const arena = msg->GetArena();
+ const void* default_ptr = table.aux[field_number].strings.default_ptr;
+ const char* field_name = table.aux[field_number].strings.field_name;
+
+ if (PROTOBUF_PREDICT_FALSE(
+ (!HandleString<UnknownFieldHandler, Cardinality_REPEATED,
+ true, StringType_STRING>(
+ input, msg, arena, has_bits, presence_index, offset,
+ default_ptr, field_name)))) {
+ return false;
+ }
+ break;
+ }
+ case (WireFormatLite::TYPE_STRING) | kOneofMask: {
+ Arena* const arena = msg->GetArena();
+ uint32_t* oneof_case = Raw<uint32_t>(msg, table.oneof_case_offset);
+ const void* default_ptr = table.aux[field_number].strings.default_ptr;
+ const char* field_name = table.aux[field_number].strings.field_name;
+
+ ResetOneofField<ProcessingType_STRING>(
+ table, field_number, arena, msg, oneof_case + presence_index,
+ offset, default_ptr);
+
+ if (PROTOBUF_PREDICT_FALSE(
+ (!HandleString<UnknownFieldHandler, Cardinality_ONEOF, true,
+ StringType_STRING>(
+ input, msg, arena, has_bits, presence_index, offset,
+ default_ptr, field_name)))) {
+ return false;
+ }
+ break;
+ }
+#endif // GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
+ case WireFormatLite::TYPE_ENUM: {
+ if (PROTOBUF_PREDICT_FALSE(
+ (!HandleEnum<UnknownFieldHandler, Cardinality_SINGULAR>(
+ table, input, msg, has_bits, presence_index, offset, tag,
+ field_number)))) {
+ return false;
+ }
+ break;
+ }
+ case WireFormatLite::TYPE_ENUM | kRepeatedMask: {
+ if (PROTOBUF_PREDICT_FALSE(
+ (!HandleEnum<UnknownFieldHandler, Cardinality_REPEATED>(
+ table, input, msg, has_bits, presence_index, offset, tag,
+ field_number)))) {
+ return false;
+ }
+ break;
+ }
+ case WireFormatLite::TYPE_ENUM | kOneofMask: {
+ uint32_t* oneof_case = Raw<uint32_t>(msg, table.oneof_case_offset);
+ if (PROTOBUF_PREDICT_FALSE(
+ (!HandleEnum<UnknownFieldHandler, Cardinality_ONEOF>(
+ table, input, msg, oneof_case, presence_index, offset,
+ tag, field_number)))) {
+ return false;
+ }
+ break;
+ }
+ case WireFormatLite::TYPE_GROUP: {
+ MessageLite** submsg_holder =
+ MutableField<MessageLite*>(msg, has_bits, presence_index, offset);
+ MessageLite* submsg = *submsg_holder;
+
+ if (submsg == nullptr) {
+ Arena* const arena = msg->GetArena();
+ const MessageLite* prototype =
+ table.aux[field_number].messages.default_message();
+ submsg = prototype->New(arena);
+ *submsg_holder = submsg;
+ }
+
+ if (PROTOBUF_PREDICT_FALSE(
+ !WireFormatLite::ReadGroup(field_number, input, submsg))) {
+ return false;
+ }
+
+ break;
+ }
+ case WireFormatLite::TYPE_GROUP | kRepeatedMask: {
+ RepeatedPtrFieldBase* field = Raw<RepeatedPtrFieldBase>(msg, offset);
+ const MessageLite* prototype =
+ table.aux[field_number].messages.default_message();
+ GOOGLE_DCHECK(prototype != nullptr);
+
+ MessageLite* submsg =
+ MergePartialFromCodedStreamHelper::Add(field, prototype);
+
+ if (PROTOBUF_PREDICT_FALSE(
+ !WireFormatLite::ReadGroup(field_number, input, submsg))) {
+ return false;
+ }
+
+ break;
+ }
+ case WireFormatLite::TYPE_MESSAGE: {
+ MessageLite** submsg_holder =
+ MutableField<MessageLite*>(msg, has_bits, presence_index, offset);
+ MessageLite* submsg = *submsg_holder;
+
+ if (submsg == nullptr) {
+ Arena* const arena = msg->GetArena();
+ const MessageLite* prototype =
+ table.aux[field_number].messages.default_message();
+ if (prototype == nullptr) {
+ prototype = ImplicitWeakMessage::default_instance();
+ }
+ submsg = prototype->New(arena);
+ *submsg_holder = submsg;
+ }
+
+ if (PROTOBUF_PREDICT_FALSE(
+ !WireFormatLite::ReadMessage(input, submsg))) {
+ return false;
+ }
+
+ break;
+ }
+ // TODO(ckennelly): Adapt ReadMessageNoVirtualNoRecursionDepth and
+ // manage input->IncrementRecursionDepth() here.
+ case WireFormatLite::TYPE_MESSAGE | kRepeatedMask: {
+ RepeatedPtrFieldBase* field = Raw<RepeatedPtrFieldBase>(msg, offset);
+ const MessageLite* prototype =
+ table.aux[field_number].messages.default_message();
+ if (prototype == nullptr) {
+ prototype = ImplicitWeakMessage::default_instance();
+ }
+
+ MessageLite* submsg =
+ MergePartialFromCodedStreamHelper::Add(field, prototype);
+
+ if (PROTOBUF_PREDICT_FALSE(
+ !WireFormatLite::ReadMessage(input, submsg))) {
+ return false;
+ }
+
+ break;
+ }
+ case WireFormatLite::TYPE_MESSAGE | kOneofMask: {
+ Arena* const arena = msg->GetArena();
+ uint32_t* oneof_case = Raw<uint32_t>(msg, table.oneof_case_offset);
+ MessageLite** submsg_holder = Raw<MessageLite*>(msg, offset);
+ ResetOneofField<ProcessingType_MESSAGE>(
+ table, field_number, arena, msg, oneof_case + presence_index,
+ offset, nullptr);
+ MessageLite* submsg = *submsg_holder;
+
+ if (PROTOBUF_PREDICT_FALSE(
+ !WireFormatLite::ReadMessage(input, submsg))) {
+ return false;
+ }
+
+ break;
+ }
+#ifdef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
+ case TYPE_STRING_INLINED: {
+ Arena* const arena = msg->GetArena();
+ const void* default_ptr = table.aux[field_number].strings.default_ptr;
+ const char* field_name = table.aux[field_number].strings.field_name;
+
+ if (PROTOBUF_PREDICT_FALSE(
+ (!HandleString<UnknownFieldHandler, Cardinality_SINGULAR,
+ true, StringType_INLINED>(
+ input, msg, arena, has_bits, presence_index, offset,
+ default_ptr, field_name)))) {
+ return false;
+ }
+ break;
+ }
+#endif // GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
+ case TYPE_MAP: {
+ if (PROTOBUF_PREDICT_FALSE(!(*table.aux[field_number].maps.parse_map)(
+ input, Raw<void>(msg, offset)))) {
+ return false;
+ }
+ break;
+ }
+ case 0: {
+ // Done.
+ input->SetLastTag(tag);
+ return true;
+ }
+ default:
+ PROTOBUF_ASSUME(false);
+ }
+ } else if (data->packed_wiretype == static_cast<unsigned char>(wire_type)) {
+ // Non-packable fields have their packed_wiretype masked with
+ // kNotPackedMask, which is impossible to match here.
+ GOOGLE_DCHECK(processing_type & kRepeatedMask);
+ GOOGLE_DCHECK_NE(processing_type, kRepeatedMask);
+ GOOGLE_DCHECK_EQ(0, processing_type & kOneofMask);
+
+ GOOGLE_DCHECK_NE(TYPE_BYTES_INLINED | kRepeatedMask, processing_type);
+ GOOGLE_DCHECK_NE(TYPE_STRING_INLINED | kRepeatedMask, processing_type);
+
+ // Mask out kRepeatedMask bit, allowing the jump table to be smaller.
+ switch (static_cast<WireFormatLite::FieldType>(processing_type ^
+ kRepeatedMask)) {
+#define HANDLE_PACKED_TYPE(TYPE, CPPTYPE, CPPTYPE_METHOD) \
+ case WireFormatLite::TYPE_##TYPE: { \
+ RepeatedField<CPPTYPE>* values = Raw<RepeatedField<CPPTYPE>>(msg, offset); \
+ if (PROTOBUF_PREDICT_FALSE( \
+ (!WireFormatLite::ReadPackedPrimitive< \
+ CPPTYPE, WireFormatLite::TYPE_##TYPE>(input, values)))) { \
+ return false; \
+ } \
+ break; \
+ }
+
+ HANDLE_PACKED_TYPE(INT32, 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 WireFormatLite::TYPE_ENUM: {
+ // To avoid unnecessarily calling MutableUnknownFields (which mutates
+ // InternalMetadata) when all inputs in the repeated series
+ // are valid, we implement our own parser rather than call
+ // WireFormat::ReadPackedEnumPreserveUnknowns.
+ uint32_t length;
+ if (PROTOBUF_PREDICT_FALSE(!input->ReadVarint32(&length))) {
+ return false;
+ }
+
+ AuxiliaryParseTableField::EnumValidator validator =
+ table.aux[field_number].enums.validator;
+ RepeatedField<int>* values = Raw<RepeatedField<int>>(msg, offset);
+
+ io::CodedInputStream::Limit limit = input->PushLimit(length);
+ while (input->BytesUntilLimit() > 0) {
+ int value;
+ if (PROTOBUF_PREDICT_FALSE(
+ (!WireFormatLite::ReadPrimitive<
+ int, WireFormatLite::TYPE_ENUM>(input, &value)))) {
+ return false;
+ }
+
+ if (validator == nullptr || validator(value)) {
+ values->Add(value);
+ } else {
+ // TODO(ckennelly): Consider caching here.
+ UnknownFieldHandler::Varint(msg, table, tag, value);
+ }
+ }
+ input->PopLimit(limit);
+
+ break;
+ }
+ case WireFormatLite::TYPE_STRING:
+ case WireFormatLite::TYPE_GROUP:
+ case WireFormatLite::TYPE_MESSAGE:
+ case WireFormatLite::TYPE_BYTES:
+ GOOGLE_DCHECK(false);
+ return false;
+ default:
+ PROTOBUF_ASSUME(false);
+ }
+ } else {
+ if (wire_type == WireFormatLite::WIRETYPE_END_GROUP) {
+ // Must be the end of the message.
+ input->SetLastTag(tag);
+ return true;
+ }
+
+ // check for possible extensions
+ if (UnknownFieldHandler::ParseExtension(msg, table, input, tag)) {
+ // successfully parsed
+ continue;
+ }
+
+ // process unknown field.
+ if (PROTOBUF_PREDICT_FALSE(
+ !UnknownFieldHandler::Skip(msg, table, input, tag))) {
+ return false;
+ }
+ }
+ }
+} // NOLINT(readability/fn_size)
+
+template <typename UnknownFieldHandler>
+bool MergePartialFromCodedStreamImpl(MessageLite* msg, const ParseTable& table,
+ io::CodedInputStream* input) {
+ // The main beneficial cutoff values are 1 and 2 byte tags.
+ // Instantiate calls with the appropriate upper tag range
+ if (table.max_field_number <= (0x7F >> 3)) {
+ return MergePartialFromCodedStreamInlined<UnknownFieldHandler, 0x7F>(
+ msg, table, input);
+ } else if (table.max_field_number <= (0x3FFF >> 3)) {
+ return MergePartialFromCodedStreamInlined<UnknownFieldHandler, 0x3FFF>(
+ msg, table, input);
+ } else {
+ return MergePartialFromCodedStreamInlined<
+ UnknownFieldHandler, std::numeric_limits<uint32_t>::max()>(msg, table,
+ input);
+ }
+}
+
+} // namespace internal
+} // namespace protobuf
+} // namespace google
+
+#include <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_GENERATED_MESSAGE_TABLE_DRIVEN_LITE_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/generated_message_tctable_decl.h b/NorthstarDedicatedTest/include/protobuf/generated_message_tctable_decl.h
new file mode 100644
index 00000000..1fe6c04f
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/generated_message_tctable_decl.h
@@ -0,0 +1,139 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// This file contains declarations needed in generated headers for messages
+// that use tail-call table parsing. Everything in this file is for internal
+// use only.
+
+#ifndef GOOGLE_PROTOBUF_GENERATED_MESSAGE_TCTABLE_DECL_H__
+#define GOOGLE_PROTOBUF_GENERATED_MESSAGE_TCTABLE_DECL_H__
+
+#include <cstdint>
+#include <type_traits>
+
+#include <parse_context.h>
+#include <message_lite.h>
+
+// Must come last:
+#include <port_def.inc>
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+// Additional information about this field:
+struct TcFieldData {
+ constexpr TcFieldData() : data(0) {}
+ constexpr TcFieldData(uint16_t coded_tag, uint8_t hasbit_idx, uint16_t offset)
+ : data(static_cast<uint64_t>(offset) << 48 |
+ static_cast<uint64_t>(hasbit_idx) << 16 | coded_tag) {}
+
+ template <typename TagType = uint16_t>
+ TagType coded_tag() const {
+ return static_cast<TagType>(data);
+ }
+ uint8_t hasbit_idx() const { return static_cast<uint8_t>(data >> 16); }
+ uint16_t offset() const { return static_cast<uint16_t>(data >> 48); }
+
+ uint64_t data;
+};
+
+struct TcParseTableBase;
+
+// TailCallParseFunc is the function pointer type used in the tailcall table.
+typedef const char* (*TailCallParseFunc)(PROTOBUF_TC_PARAM_DECL);
+
+#if defined(_MSC_VER) && !defined(_WIN64)
+#pragma warning(push)
+// TcParseTableBase is intentionally overaligned on 32 bit targets.
+#pragma warning(disable : 4324)
+#endif
+
+// Base class for message-level table with info for the tail-call parser.
+struct alignas(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;
+ uint8_t fast_idx_mask;
+ uint8_t reserved;
+ uint16_t num_fields;
+ const MessageLite* default_instance;
+
+ // Handler for fields which are not handled by table dispatch.
+ TailCallParseFunc fallback;
+
+ // Table entry for fast-path tailcall dispatch handling.
+ struct FastFieldEntry {
+ // Target function for dispatch:
+ TailCallParseFunc target;
+ // Field data used during parse:
+ TcFieldData bits;
+ };
+ // There is always at least one table entry.
+ const FastFieldEntry* fast_entry(size_t idx) const {
+ return reinterpret_cast<const FastFieldEntry*>(this + 1) + idx;
+ }
+};
+
+#if defined(_MSC_VER) && !defined(_WIN64)
+#pragma warning(pop)
+#endif
+
+static_assert(sizeof(TcParseTableBase::FastFieldEntry) <= 16,
+ "Field entry is too big.");
+
+template <size_t kFastTableSizeLog2>
+struct TcParseTable {
+ TcParseTableBase header;
+
+ // Entries for each field.
+ //
+ // Fields are indexed by the lowest bits of their field number. The field
+ // number is masked to fit inside the table. Note that the parsing logic
+ // generally calls `TailCallParseTableBase::table()` instead of accessing
+ // this field directly.
+ TcParseTableBase::FastFieldEntry entries[(1 << kFastTableSizeLog2)];
+};
+
+static_assert(std::is_standard_layout<TcParseTable<1>>::value,
+ "TcParseTable must be standard layout.");
+
+static_assert(offsetof(TcParseTable<1>, entries) == sizeof(TcParseTableBase),
+ "Table entries must be laid out after TcParseTableBase.");
+
+} // namespace internal
+} // namespace protobuf
+} // namespace google
+
+#include <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_GENERATED_MESSAGE_TCTABLE_DECL_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/generated_message_tctable_full.cc b/NorthstarDedicatedTest/include/protobuf/generated_message_tctable_full.cc
new file mode 100644
index 00000000..cbea7951
--- /dev/null
+++ b/NorthstarDedicatedTest/include/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 <parse_context.h>
+#include <extension_set.h>
+#include <generated_message_tctable_impl.h>
+#include <message.h>
+#include <unknown_field_set.h>
+
+// clang-format off
+#include <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/NorthstarDedicatedTest/include/protobuf/generated_message_tctable_impl.h b/NorthstarDedicatedTest/include/protobuf/generated_message_tctable_impl.h
new file mode 100644
index 00000000..f2f1dc0c
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/generated_message_tctable_impl.h
@@ -0,0 +1,302 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef GOOGLE_PROTOBUF_GENERATED_MESSAGE_TCTABLE_IMPL_H__
+#define GOOGLE_PROTOBUF_GENERATED_MESSAGE_TCTABLE_IMPL_H__
+
+#include <cstdint>
+#include <type_traits>
+
+#include <parse_context.h>
+#include <extension_set.h>
+#include <generated_message_tctable_decl.h>
+#include <message_lite.h>
+#include <metadata_lite.h>
+#include <port.h>
+#include <wire_format_lite.h>
+
+// Must come last:
+#include <port_def.inc>
+
+namespace google {
+namespace protobuf {
+
+class Message;
+class UnknownFieldSet;
+
+namespace internal {
+
+// PROTOBUF_TC_PARAM_DECL are the parameters for tailcall functions, it is
+// defined in port_def.inc.
+//
+// Note that this is performance sensitive: changing the parameters will change
+// the registers used by the ABI calling convention, which subsequently affects
+// register selection logic inside the function.
+
+// PROTOBUF_TC_PARAM_PASS passes values to match PROTOBUF_TC_PARAM_DECL.
+#define PROTOBUF_TC_PARAM_PASS msg, ptr, ctx, table, hasbits, data
+
+// PROTOBUF_TC_PARSE_* decide which function is used to parse message-typed
+// fields. The guard macros are defined in port_def.inc.
+#if PROTOBUF_TC_STATIC_PARSE_SINGULAR1
+#define PROTOBUF_TC_PARSE_SINGULAR1(MESSAGE) MESSAGE::Tct_ParseS1
+#else
+#define PROTOBUF_TC_PARSE_SINGULAR1(MESSAGE) \
+ ::google::protobuf::internal::TcParser::SingularParseMessage<MESSAGE, uint8_t>
+#endif // PROTOBUF_TC_STATIC_PARSE_SINGULAR1
+
+#if PROTOBUF_TC_STATIC_PARSE_SINGULAR2
+#define PROTOBUF_TC_PARSE_SINGULAR2(MESSAGE) MESSAGE::Tct_ParseS2
+#else
+#define PROTOBUF_TC_PARSE_SINGULAR2(MESSAGE) \
+ ::google::protobuf::internal::TcParser::SingularParseMessage<MESSAGE, uint16_t>
+#endif // PROTOBUF_TC_STATIC_PARSE_SINGULAR2
+
+#if PROTOBUF_TC_STATIC_PARSE_REPEATED1
+#define PROTOBUF_TC_PARSE_REPEATED1(MESSAGE) MESSAGE::Tct_ParseR1
+#else
+#define PROTOBUF_TC_PARSE_REPEATED1(MESSAGE) \
+ ::google::protobuf::internal::TcParser::RepeatedParseMessage<MESSAGE, uint8_t>
+#endif // PROTOBUF_TC_STATIC_PARSE_REPEATED1
+
+#if PROTOBUF_TC_STATIC_PARSE_REPEATED2
+#define PROTOBUF_TC_PARSE_REPEATED2(MESSAGE) MESSAGE::Tct_ParseR2
+#else
+#define PROTOBUF_TC_PARSE_REPEATED2(MESSAGE) \
+ ::google::protobuf::internal::TcParser::RepeatedParseMessage<MESSAGE, uint16_t>
+#endif // PROTOBUF_TC_STATIC_PARSE_REPEATED2
+
+#ifndef NDEBUG
+template <size_t align>
+#ifndef _MSC_VER
+[[noreturn]]
+#endif
+void AlignFail(uintptr_t address) {
+ GOOGLE_LOG(FATAL) << "Unaligned (" << align << ") access at " << address;
+}
+
+extern template void AlignFail<4>(uintptr_t);
+extern template void AlignFail<8>(uintptr_t);
+#endif
+
+// TcParser implements most of the parsing logic for tailcall tables.
+class TcParser final {
+ public:
+ static const char* GenericFallback(PROTOBUF_TC_PARAM_DECL);
+ static const char* GenericFallbackLite(PROTOBUF_TC_PARAM_DECL);
+
+ // Dispatch to the designated parse function
+ inline PROTOBUF_ALWAYS_INLINE static const char* TagDispatch(
+ PROTOBUF_TC_PARAM_DECL) {
+ const auto coded_tag = UnalignedLoad<uint16_t>(ptr);
+ const size_t idx = coded_tag & table->fast_idx_mask;
+ PROTOBUF_ASSUME((idx & 7) == 0);
+ auto* fast_entry = table->fast_entry(idx >> 3);
+ data = fast_entry->bits;
+ data.data ^= coded_tag;
+ PROTOBUF_MUSTTAIL return fast_entry->target(PROTOBUF_TC_PARAM_PASS);
+ }
+
+ // We can only safely call from field to next field if the call is optimized
+ // to a proper tail call. Otherwise we blow through stack. Clang and gcc
+ // reliably do this optimization in opt mode, but do not perform this in debug
+ // mode. Luckily the structure of the algorithm is such that it's always
+ // possible to just return and use the enclosing parse loop as a trampoline.
+ static const char* ToTagDispatch(PROTOBUF_TC_PARAM_DECL) {
+ constexpr bool always_return = !PROTOBUF_TAILCALL;
+ if (always_return || !ctx->DataAvailable(ptr)) {
+ PROTOBUF_MUSTTAIL return ToParseLoop(PROTOBUF_TC_PARAM_PASS);
+ }
+ PROTOBUF_MUSTTAIL return TagDispatch(PROTOBUF_TC_PARAM_PASS);
+ }
+
+ static const char* ParseLoop(MessageLite* msg, const char* ptr,
+ ParseContext* ctx,
+ const TcParseTableBase* table) {
+ ScopedArenaSwap saved(msg, ctx);
+ const uint32_t has_bits_offset = table->has_bits_offset;
+ while (!ctx->Done(&ptr)) {
+ uint64_t hasbits = 0;
+ if (has_bits_offset) hasbits = RefAt<uint32_t>(msg, has_bits_offset);
+ ptr = TagDispatch(msg, ptr, ctx, table, hasbits, {});
+ if (ptr == nullptr) break;
+ if (ctx->LastTag() != 1) break; // Ended on terminating tag
+ }
+ return ptr;
+ }
+
+ template <typename FieldType, typename TagType>
+ PROTOBUF_NOINLINE static const char* SingularParseMessage(
+ PROTOBUF_TC_PARAM_DECL) {
+ if (PROTOBUF_PREDICT_FALSE(data.coded_tag<TagType>() != 0)) {
+ return table->fallback(PROTOBUF_TC_PARAM_PASS);
+ }
+ ptr += sizeof(TagType);
+ hasbits |= (uint64_t{1} << data.hasbit_idx());
+ auto& field = RefAt<FieldType*>(msg, data.offset());
+ if (field == nullptr) {
+ auto arena = ctx->data().arena;
+ if (Arena::is_arena_constructable<FieldType>::value) {
+ field = Arena::CreateMessage<FieldType>(arena);
+ } else {
+ field = Arena::Create<FieldType>(arena);
+ }
+ }
+ SyncHasbits(msg, hasbits, table);
+ return ctx->ParseMessage(field, ptr);
+ }
+
+ template <typename FieldType, typename TagType>
+ PROTOBUF_NOINLINE static const char* RepeatedParseMessage(
+ PROTOBUF_TC_PARAM_DECL) {
+ if (PROTOBUF_PREDICT_FALSE(data.coded_tag<TagType>() != 0)) {
+ return table->fallback(PROTOBUF_TC_PARAM_PASS);
+ }
+ ptr += sizeof(TagType);
+ auto& field = RefAt<RepeatedPtrField<FieldType>>(msg, data.offset());
+ SyncHasbits(msg, hasbits, table);
+ ptr = ctx->ParseMessage(field.Add(), ptr);
+ return ptr;
+ }
+
+ template <typename LayoutType, typename TagType>
+ static const char* SingularFixed(PROTOBUF_TC_PARAM_DECL);
+ template <typename LayoutType, typename TagType>
+ static const char* RepeatedFixed(PROTOBUF_TC_PARAM_DECL);
+ template <typename LayoutType, typename TagType>
+ static const char* PackedFixed(PROTOBUF_TC_PARAM_DECL);
+
+ enum VarintDecode { kNoConversion = 0, kZigZag = 1 };
+ template <typename FieldType, typename TagType, VarintDecode zigzag>
+ static const char* SingularVarint(PROTOBUF_TC_PARAM_DECL);
+ template <typename FieldType, typename TagType, VarintDecode zigzag>
+ static const char* RepeatedVarint(PROTOBUF_TC_PARAM_DECL);
+ template <typename FieldType, typename TagType, VarintDecode zigzag>
+ static const char* PackedVarint(PROTOBUF_TC_PARAM_DECL);
+
+ enum Utf8Type { kNoUtf8 = 0, kUtf8 = 1, kUtf8ValidateOnly = 2 };
+ template <typename TagType, Utf8Type utf8>
+ static const char* SingularString(PROTOBUF_TC_PARAM_DECL);
+ template <typename TagType, Utf8Type utf8>
+ static const char* RepeatedString(PROTOBUF_TC_PARAM_DECL);
+
+ template <typename T>
+ static inline T& RefAt(void* x, size_t offset) {
+ T* target = reinterpret_cast<T*>(static_cast<char*>(x) + offset);
+#ifndef NDEBUG
+ if (PROTOBUF_PREDICT_FALSE(
+ reinterpret_cast<uintptr_t>(target) % alignof(T) != 0)) {
+ AlignFail<alignof(T)>(reinterpret_cast<uintptr_t>(target));
+ }
+#endif
+ return *target;
+ }
+
+ static inline PROTOBUF_ALWAYS_INLINE void SyncHasbits(
+ MessageLite* msg, 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);
+ }
+ }
+
+ protected:
+ static inline PROTOBUF_ALWAYS_INLINE const char* ToParseLoop(
+ PROTOBUF_TC_PARAM_DECL) {
+ (void)data;
+ (void)ctx;
+ SyncHasbits(msg, hasbits, table);
+ return ptr;
+ }
+
+ static inline PROTOBUF_ALWAYS_INLINE const char* Error(
+ PROTOBUF_TC_PARAM_DECL) {
+ (void)data;
+ (void)ctx;
+ (void)ptr;
+ SyncHasbits(msg, hasbits, table);
+ return nullptr;
+ }
+
+ class ScopedArenaSwap final {
+ public:
+ ScopedArenaSwap(MessageLite* msg, ParseContext* ctx)
+ : ctx_(ctx), saved_(ctx->data().arena) {
+ ctx_->data().arena = msg->GetArenaForAllocation();
+ }
+ ScopedArenaSwap(const ScopedArenaSwap&) = delete;
+ ~ScopedArenaSwap() { ctx_->data().arena = saved_; }
+
+ private:
+ ParseContext* const ctx_;
+ Arena* const saved_;
+ };
+
+ template <class MessageBaseT, class UnknownFieldsT>
+ static const char* GenericFallbackImpl(PROTOBUF_TC_PARAM_DECL) {
+#define CHK_(x) \
+ if (PROTOBUF_PREDICT_FALSE(!(x))) return nullptr /* NOLINT */
+
+ SyncHasbits(msg, hasbits, table);
+ uint32_t tag;
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag);
+ CHK_(ptr);
+ if ((tag & 7) == WireFormatLite::WIRETYPE_END_GROUP || tag == 0) {
+ ctx->SetLastTag(tag);
+ return ptr;
+ }
+ (void)data;
+ 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_
+ }
+};
+
+// Declare helper functions:
+#include <generated_message_tctable_impl.inc>
+
+} // namespace internal
+} // namespace protobuf
+} // namespace google
+
+#include <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_GENERATED_MESSAGE_TCTABLE_IMPL_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/generated_message_tctable_impl.inc b/NorthstarDedicatedTest/include/protobuf/generated_message_tctable_impl.inc
new file mode 100644
index 00000000..a6831b53
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/generated_message_tctable_impl.inc
@@ -0,0 +1,92 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// clang-format off
+#ifdef PROTOBUF_TCT_SOURCE
+#define PROTOBUF_TCT_EXTERN
+#else
+#define PROTOBUF_TCT_EXTERN extern
+#endif
+PROTOBUF_TCT_EXTERN template const char* TcParser::SingularFixed<uint64_t, uint8_t>(PROTOBUF_TC_PARAM_DECL);
+PROTOBUF_TCT_EXTERN template const char* TcParser::RepeatedFixed<uint64_t, uint8_t>(PROTOBUF_TC_PARAM_DECL);
+PROTOBUF_TCT_EXTERN template const char* TcParser::PackedFixed<uint64_t, uint8_t>(PROTOBUF_TC_PARAM_DECL);
+PROTOBUF_TCT_EXTERN template const char* TcParser::SingularFixed<uint32_t, uint8_t>(PROTOBUF_TC_PARAM_DECL);
+PROTOBUF_TCT_EXTERN template const char* TcParser::RepeatedFixed<uint32_t, uint8_t>(PROTOBUF_TC_PARAM_DECL);
+PROTOBUF_TCT_EXTERN template const char* TcParser::PackedFixed<uint32_t, uint8_t>(PROTOBUF_TC_PARAM_DECL);
+PROTOBUF_TCT_EXTERN template const char* TcParser::SingularVarint<uint64_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kNoConversion>(PROTOBUF_TC_PARAM_DECL);
+PROTOBUF_TCT_EXTERN template const char* TcParser::RepeatedVarint<uint64_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kNoConversion>(PROTOBUF_TC_PARAM_DECL);
+PROTOBUF_TCT_EXTERN template const char* TcParser::PackedVarint<uint64_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kNoConversion>(PROTOBUF_TC_PARAM_DECL);
+PROTOBUF_TCT_EXTERN template const char* TcParser::SingularVarint<uint32_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kNoConversion>(PROTOBUF_TC_PARAM_DECL);
+PROTOBUF_TCT_EXTERN template const char* TcParser::RepeatedVarint<uint32_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kNoConversion>(PROTOBUF_TC_PARAM_DECL);
+PROTOBUF_TCT_EXTERN template const char* TcParser::PackedVarint<uint32_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kNoConversion>(PROTOBUF_TC_PARAM_DECL);
+PROTOBUF_TCT_EXTERN template const char* TcParser::SingularVarint<int64_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kZigZag>(PROTOBUF_TC_PARAM_DECL);
+PROTOBUF_TCT_EXTERN template const char* TcParser::RepeatedVarint<int64_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kZigZag>(PROTOBUF_TC_PARAM_DECL);
+PROTOBUF_TCT_EXTERN template const char* TcParser::PackedVarint<int64_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kZigZag>(PROTOBUF_TC_PARAM_DECL);
+PROTOBUF_TCT_EXTERN template const char* TcParser::SingularVarint<int32_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kZigZag>(PROTOBUF_TC_PARAM_DECL);
+PROTOBUF_TCT_EXTERN template const char* TcParser::RepeatedVarint<int32_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kZigZag>(PROTOBUF_TC_PARAM_DECL);
+PROTOBUF_TCT_EXTERN template const char* TcParser::PackedVarint<int32_t, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kZigZag>(PROTOBUF_TC_PARAM_DECL);
+PROTOBUF_TCT_EXTERN template const char* TcParser::SingularVarint<bool, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kNoConversion>(PROTOBUF_TC_PARAM_DECL);
+PROTOBUF_TCT_EXTERN template const char* TcParser::RepeatedVarint<bool, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kNoConversion>(PROTOBUF_TC_PARAM_DECL);
+PROTOBUF_TCT_EXTERN template const char* TcParser::PackedVarint<bool, uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kNoConversion>(PROTOBUF_TC_PARAM_DECL);
+PROTOBUF_TCT_EXTERN template const char* TcParser::SingularString<uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kNoUtf8>(PROTOBUF_TC_PARAM_DECL);
+PROTOBUF_TCT_EXTERN template const char* TcParser::RepeatedString<uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kNoUtf8>(PROTOBUF_TC_PARAM_DECL);
+PROTOBUF_TCT_EXTERN template const char* TcParser::SingularString<uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kUtf8>(PROTOBUF_TC_PARAM_DECL);
+PROTOBUF_TCT_EXTERN template const char* TcParser::RepeatedString<uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kUtf8>(PROTOBUF_TC_PARAM_DECL);
+PROTOBUF_TCT_EXTERN template const char* TcParser::SingularString<uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kUtf8ValidateOnly>(PROTOBUF_TC_PARAM_DECL);
+PROTOBUF_TCT_EXTERN template const char* TcParser::RepeatedString<uint8_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kUtf8ValidateOnly>(PROTOBUF_TC_PARAM_DECL);
+PROTOBUF_TCT_EXTERN template const char* TcParser::SingularFixed<uint64_t, uint16_t>(PROTOBUF_TC_PARAM_DECL);
+PROTOBUF_TCT_EXTERN template const char* TcParser::RepeatedFixed<uint64_t, uint16_t>(PROTOBUF_TC_PARAM_DECL);
+PROTOBUF_TCT_EXTERN template const char* TcParser::PackedFixed<uint64_t, uint16_t>(PROTOBUF_TC_PARAM_DECL);
+PROTOBUF_TCT_EXTERN template const char* TcParser::SingularFixed<uint32_t, uint16_t>(PROTOBUF_TC_PARAM_DECL);
+PROTOBUF_TCT_EXTERN template const char* TcParser::RepeatedFixed<uint32_t, uint16_t>(PROTOBUF_TC_PARAM_DECL);
+PROTOBUF_TCT_EXTERN template const char* TcParser::PackedFixed<uint32_t, uint16_t>(PROTOBUF_TC_PARAM_DECL);
+PROTOBUF_TCT_EXTERN template const char* TcParser::SingularVarint<uint64_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kNoConversion>(PROTOBUF_TC_PARAM_DECL);
+PROTOBUF_TCT_EXTERN template const char* TcParser::RepeatedVarint<uint64_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kNoConversion>(PROTOBUF_TC_PARAM_DECL);
+PROTOBUF_TCT_EXTERN template const char* TcParser::PackedVarint<uint64_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kNoConversion>(PROTOBUF_TC_PARAM_DECL);
+PROTOBUF_TCT_EXTERN template const char* TcParser::SingularVarint<uint32_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kNoConversion>(PROTOBUF_TC_PARAM_DECL);
+PROTOBUF_TCT_EXTERN template const char* TcParser::RepeatedVarint<uint32_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kNoConversion>(PROTOBUF_TC_PARAM_DECL);
+PROTOBUF_TCT_EXTERN template const char* TcParser::PackedVarint<uint32_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kNoConversion>(PROTOBUF_TC_PARAM_DECL);
+PROTOBUF_TCT_EXTERN template const char* TcParser::SingularVarint<int64_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kZigZag>(PROTOBUF_TC_PARAM_DECL);
+PROTOBUF_TCT_EXTERN template const char* TcParser::RepeatedVarint<int64_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kZigZag>(PROTOBUF_TC_PARAM_DECL);
+PROTOBUF_TCT_EXTERN template const char* TcParser::PackedVarint<int64_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kZigZag>(PROTOBUF_TC_PARAM_DECL);
+PROTOBUF_TCT_EXTERN template const char* TcParser::SingularVarint<int32_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kZigZag>(PROTOBUF_TC_PARAM_DECL);
+PROTOBUF_TCT_EXTERN template const char* TcParser::RepeatedVarint<int32_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kZigZag>(PROTOBUF_TC_PARAM_DECL);
+PROTOBUF_TCT_EXTERN template const char* TcParser::PackedVarint<int32_t, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kZigZag>(PROTOBUF_TC_PARAM_DECL);
+PROTOBUF_TCT_EXTERN template const char* TcParser::SingularVarint<bool, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kNoConversion>(PROTOBUF_TC_PARAM_DECL);
+PROTOBUF_TCT_EXTERN template const char* TcParser::RepeatedVarint<bool, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kNoConversion>(PROTOBUF_TC_PARAM_DECL);
+PROTOBUF_TCT_EXTERN template const char* TcParser::PackedVarint<bool, uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kNoConversion>(PROTOBUF_TC_PARAM_DECL);
+PROTOBUF_TCT_EXTERN template const char* TcParser::SingularString<uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kNoUtf8>(PROTOBUF_TC_PARAM_DECL);
+PROTOBUF_TCT_EXTERN template const char* TcParser::RepeatedString<uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kNoUtf8>(PROTOBUF_TC_PARAM_DECL);
+PROTOBUF_TCT_EXTERN template const char* TcParser::SingularString<uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kUtf8>(PROTOBUF_TC_PARAM_DECL);
+PROTOBUF_TCT_EXTERN template const char* TcParser::RepeatedString<uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kUtf8>(PROTOBUF_TC_PARAM_DECL);
+PROTOBUF_TCT_EXTERN template const char* TcParser::SingularString<uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kUtf8ValidateOnly>(PROTOBUF_TC_PARAM_DECL);
+PROTOBUF_TCT_EXTERN template const char* TcParser::RepeatedString<uint16_t, ::PROTOBUF_NAMESPACE_ID::internal::TcParser::kUtf8ValidateOnly>(PROTOBUF_TC_PARAM_DECL);
+#undef PROTOBUF_TCT_EXTERN
+// clang-format on
diff --git a/NorthstarDedicatedTest/include/protobuf/generated_message_tctable_lite.cc b/NorthstarDedicatedTest/include/protobuf/generated_message_tctable_lite.cc
new file mode 100644
index 00000000..5f7f1f83
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/generated_message_tctable_lite.cc
@@ -0,0 +1,456 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <cstdint>
+
+#include <parse_context.h>
+#include <extension_set.h>
+#include <generated_message_tctable_decl.h>
+#include <generated_message_tctable_impl.h>
+#include <message_lite.h>
+#include <wire_format_lite.h>
+
+// clang-format off
+#include <port_def.inc>
+// clang-format on
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+#ifndef NDEBUG
+template void AlignFail<4>(uintptr_t);
+template void AlignFail<8>(uintptr_t);
+#endif
+
+const char* TcParser::GenericFallbackLite(PROTOBUF_TC_PARAM_DECL) {
+ return GenericFallbackImpl<MessageLite, std::string>(PROTOBUF_TC_PARAM_PASS);
+}
+
+namespace {
+
+// Offset returns the address `offset` bytes after `base`.
+inline void* Offset(void* base, uint32_t offset) {
+ return static_cast<uint8_t*>(base) + offset;
+}
+
+// InvertPacked changes tag bits from the given wire type to length
+// delimited. This is the difference expected between packed and non-packed
+// repeated fields.
+template <WireFormatLite::WireType Wt>
+inline PROTOBUF_ALWAYS_INLINE void InvertPacked(TcFieldData& data) {
+ data.data ^= Wt ^ WireFormatLite::WIRETYPE_LENGTH_DELIMITED;
+}
+
+} // namespace
+
+//////////////////////////////////////////////////////////////////////////////
+// Fixed fields
+//////////////////////////////////////////////////////////////////////////////
+
+template <typename LayoutType, typename TagType>
+const char* TcParser::SingularFixed(PROTOBUF_TC_PARAM_DECL) {
+ if (PROTOBUF_PREDICT_FALSE(data.coded_tag<TagType>() != 0)) {
+ return table->fallback(PROTOBUF_TC_PARAM_PASS);
+ }
+ ptr += sizeof(TagType); // Consume tag
+ hasbits |= (uint64_t{1} << data.hasbit_idx());
+ std::memcpy(Offset(msg, data.offset()), ptr, sizeof(LayoutType));
+ ptr += sizeof(LayoutType);
+ PROTOBUF_MUSTTAIL return ToTagDispatch(PROTOBUF_TC_PARAM_PASS);
+}
+
+template <typename LayoutType, typename TagType>
+const char* TcParser::RepeatedFixed(PROTOBUF_TC_PARAM_DECL) {
+ if (PROTOBUF_PREDICT_FALSE(data.coded_tag<TagType>() != 0)) {
+ // Check if the field can be parsed as packed repeated:
+ constexpr WireFormatLite::WireType fallback_wt =
+ sizeof(LayoutType) == 4 ? WireFormatLite::WIRETYPE_FIXED32
+ : WireFormatLite::WIRETYPE_FIXED64;
+ InvertPacked<fallback_wt>(data);
+ if (data.coded_tag<TagType>() == 0) {
+ return PackedFixed<LayoutType, TagType>(PROTOBUF_TC_PARAM_PASS);
+ } else {
+ return table->fallback(PROTOBUF_TC_PARAM_PASS);
+ }
+ }
+ auto& field = RefAt<RepeatedField<LayoutType>>(msg, data.offset());
+ int idx = field.size();
+ auto elem = field.Add();
+ int space = field.Capacity() - idx;
+ idx = 0;
+ auto expected_tag = UnalignedLoad<TagType>(ptr);
+ do {
+ ptr += sizeof(TagType);
+ std::memcpy(elem + (idx++), ptr, sizeof(LayoutType));
+ ptr += sizeof(LayoutType);
+ if (idx >= space) break;
+ if (!ctx->DataAvailable(ptr)) break;
+ } while (UnalignedLoad<TagType>(ptr) == expected_tag);
+ field.AddNAlreadyReserved(idx - 1);
+ return ToParseLoop(PROTOBUF_TC_PARAM_PASS);
+}
+
+template <typename LayoutType, typename TagType>
+const char* TcParser::PackedFixed(PROTOBUF_TC_PARAM_DECL) {
+ if (PROTOBUF_PREDICT_FALSE(data.coded_tag<TagType>() != 0)) {
+ // Try parsing as non-packed repeated:
+ constexpr WireFormatLite::WireType fallback_wt =
+ sizeof(LayoutType) == 4 ? WireFormatLite::WIRETYPE_FIXED32
+ : WireFormatLite::WIRETYPE_FIXED64;
+ InvertPacked<fallback_wt>(data);
+ if (data.coded_tag<TagType>() == 0) {
+ return RepeatedFixed<LayoutType, TagType>(PROTOBUF_TC_PARAM_PASS);
+ } else {
+ return table->fallback(PROTOBUF_TC_PARAM_PASS);
+ }
+ }
+ ptr += sizeof(TagType);
+ // Since ctx->ReadPackedFixed does not use TailCall<> or Return<>, sync any
+ // pending hasbits now:
+ SyncHasbits(msg, hasbits, table);
+ auto& field = RefAt<RepeatedField<LayoutType>>(msg, data.offset());
+ int size = ReadSize(&ptr);
+ // TODO(dlj): add a tailcalling variant of ReadPackedFixed.
+ return ctx->ReadPackedFixed(ptr, size,
+ static_cast<RepeatedField<LayoutType>*>(&field));
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// Varint fields
+//////////////////////////////////////////////////////////////////////////////
+
+namespace {
+
+inline PROTOBUF_ALWAYS_INLINE std::pair<const char*, 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)
+ uint64_t byte; // the "next" 7-bit chunk, shifted (result from SHLD)
+ int64_t res2, res3; // accumulated result chunks
+#define SHLD(n) byte = ((byte << (n * 7)) | (ones >> (64 - (n * 7))))
+
+ int sign_bit;
+#if defined(__GCC_ASM_FLAG_OUTPUTS__) && defined(__x86_64__)
+ // For the first two rounds (ptr[1] and ptr[2]), micro benchmarks show a
+ // substantial improvement from capturing the sign from the condition code
+ // register on x86-64.
+#define SHLD_SIGN(n) \
+ asm("shldq %3, %2, %1" \
+ : "=@ccs"(sign_bit), "+r"(byte) \
+ : "r"(ones), "i"(n * 7))
+#else
+ // Generic fallback:
+#define SHLD_SIGN(n) \
+ do { \
+ SHLD(n); \
+ sign_bit = static_cast<int64_t>(byte) < 0; \
+ } while (0)
+#endif
+
+ byte = ptr[1];
+ SHLD_SIGN(1);
+ res2 = byte;
+ if (!sign_bit) goto done2;
+ byte = ptr[2];
+ SHLD_SIGN(2);
+ res3 = byte;
+ if (!sign_bit) goto done3;
+
+#undef SHLD_SIGN
+
+ // For the remainder of the chunks, check the sign of the AND result.
+ byte = ptr[3];
+ SHLD(3);
+ res1 &= byte;
+ if (res1 >= 0) goto done4;
+ byte = ptr[4];
+ SHLD(4);
+ res2 &= byte;
+ if (res2 >= 0) goto done5;
+ byte = ptr[5];
+ SHLD(5);
+ res3 &= byte;
+ if (res3 >= 0) goto done6;
+ byte = ptr[6];
+ SHLD(6);
+ res1 &= byte;
+ if (res1 >= 0) goto done7;
+ byte = ptr[7];
+ SHLD(7);
+ res2 &= byte;
+ if (res2 >= 0) goto done8;
+ byte = ptr[8];
+ SHLD(8);
+ res3 &= byte;
+ if (res3 >= 0) goto done9;
+
+#undef SHLD
+
+ // For valid 64bit varints, the 10th byte/ptr[9] should be exactly 1. In this
+ // case, the continuation bit of ptr[8] already set the top bit of res3
+ // correctly, so all we have to do is check that the expected case is true.
+ byte = ptr[9];
+ if (PROTOBUF_PREDICT_TRUE(byte == 1)) goto done10;
+
+ // A value of 0, however, represents an over-serialized varint. This case
+ // should not happen, but if does (say, due to a nonconforming serializer),
+ // deassert the continuation bit that came from ptr[8].
+ if (byte == 0) {
+ res3 ^= static_cast<uint64_t>(1) << 63;
+ goto done10;
+ }
+
+ // If the 10th byte/ptr[9] itself has any other value, then it is too big to
+ // fit in 64 bits. If the continue bit is set, it is an unterminated varint.
+ return {nullptr, 0};
+
+#define DONE(n) done##n : return {p + n, res1 & res2 & res3};
+done2:
+ return {p + 2, res1 & res2};
+ DONE(3)
+ DONE(4)
+ DONE(5)
+ DONE(6)
+ DONE(7)
+ DONE(8)
+ DONE(9)
+ DONE(10)
+#undef DONE
+}
+
+inline PROTOBUF_ALWAYS_INLINE const char* ParseVarint(const char* p,
+ 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,
+ TcParser::VarintDecode = TcParser::VarintDecode::kNoConversion>
+FieldType ZigZagDecodeHelper(uint64_t value) {
+ return static_cast<FieldType>(value);
+}
+
+template <>
+int32_t ZigZagDecodeHelper<int32_t, TcParser::VarintDecode::kZigZag>(
+ uint64_t value) {
+ return WireFormatLite::ZigZagDecode32(value);
+}
+
+template <>
+int64_t ZigZagDecodeHelper<int64_t, TcParser::VarintDecode::kZigZag>(
+ uint64_t value) {
+ return WireFormatLite::ZigZagDecode64(value);
+}
+
+} // namespace
+
+template <typename FieldType, typename TagType, TcParser::VarintDecode zigzag>
+const char* TcParser::SingularVarint(PROTOBUF_TC_PARAM_DECL) {
+ if (PROTOBUF_PREDICT_FALSE(data.coded_tag<TagType>() != 0)) {
+ return table->fallback(PROTOBUF_TC_PARAM_PASS);
+ }
+ ptr += sizeof(TagType); // Consume tag
+ hasbits |= (uint64_t{1} << data.hasbit_idx());
+ uint64_t tmp;
+ ptr = ParseVarint(ptr, &tmp);
+ if (ptr == nullptr) {
+ return Error(PROTOBUF_TC_PARAM_PASS);
+ }
+ RefAt<FieldType>(msg, data.offset()) =
+ ZigZagDecodeHelper<FieldType, zigzag>(tmp);
+ PROTOBUF_MUSTTAIL return ToTagDispatch(PROTOBUF_TC_PARAM_PASS);
+}
+
+template <typename FieldType, typename TagType, TcParser::VarintDecode zigzag>
+PROTOBUF_NOINLINE const char* TcParser::RepeatedVarint(PROTOBUF_TC_PARAM_DECL) {
+ if (PROTOBUF_PREDICT_FALSE(data.coded_tag<TagType>() != 0)) {
+ // Try parsing as non-packed repeated:
+ InvertPacked<WireFormatLite::WIRETYPE_VARINT>(data);
+ if (data.coded_tag<TagType>() == 0) {
+ return PackedVarint<FieldType, TagType, zigzag>(PROTOBUF_TC_PARAM_PASS);
+ } else {
+ return table->fallback(PROTOBUF_TC_PARAM_PASS);
+ }
+ }
+ auto& field = RefAt<RepeatedField<FieldType>>(msg, data.offset());
+ auto expected_tag = UnalignedLoad<TagType>(ptr);
+ do {
+ ptr += sizeof(TagType);
+ 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);
+}
+
+template <typename FieldType, typename TagType, TcParser::VarintDecode zigzag>
+PROTOBUF_NOINLINE const char* TcParser::PackedVarint(PROTOBUF_TC_PARAM_DECL) {
+ if (PROTOBUF_PREDICT_FALSE(data.coded_tag<TagType>() != 0)) {
+ InvertPacked<WireFormatLite::WIRETYPE_VARINT>(data);
+ if (data.coded_tag<TagType>() == 0) {
+ return RepeatedVarint<FieldType, TagType, zigzag>(PROTOBUF_TC_PARAM_PASS);
+ } else {
+ return table->fallback(PROTOBUF_TC_PARAM_PASS);
+ }
+ }
+ ptr += sizeof(TagType);
+ // Since ctx->ReadPackedVarint does not use TailCall or Return, sync any
+ // pending hasbits now:
+ SyncHasbits(msg, hasbits, table);
+ auto* field = &RefAt<RepeatedField<FieldType>>(msg, data.offset());
+ return ctx->ReadPackedVarint(ptr, [field](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);
+ });
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// String/bytes fields
+//////////////////////////////////////////////////////////////////////////////
+
+// Defined in wire_format_lite.cc
+void PrintUTF8ErrorLog(const char* field_name, const char* operation_str,
+ bool emit_stacktrace);
+
+namespace {
+
+PROTOBUF_NOINLINE
+const char* SingularStringParserFallback(ArenaStringPtr* s, const char* ptr,
+ EpsCopyInputStream* stream) {
+ int size = ReadSize(&ptr);
+ if (!ptr) return nullptr;
+ return stream->ReadString(
+ ptr, size, s->MutableNoArenaNoDefault(&GetEmptyStringAlreadyInited()));
+}
+
+} // namespace
+
+template <typename TagType, TcParser::Utf8Type utf8>
+const char* TcParser::SingularString(PROTOBUF_TC_PARAM_DECL) {
+ if (PROTOBUF_PREDICT_FALSE(data.coded_tag<TagType>() != 0)) {
+ return table->fallback(PROTOBUF_TC_PARAM_PASS);
+ }
+ ptr += sizeof(TagType);
+ hasbits |= (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);
+ }
+ PrintUTF8ErrorLog("unknown", "parsing", false);
+ return utf8 == kUtf8 ? Error(PROTOBUF_TC_PARAM_PASS)
+ : ToParseLoop(PROTOBUF_TC_PARAM_PASS);
+ }
+}
+
+template <typename TagType, TcParser::Utf8Type utf8>
+const char* TcParser::RepeatedString(PROTOBUF_TC_PARAM_DECL) {
+ if (PROTOBUF_PREDICT_FALSE(data.coded_tag<TagType>() != 0)) {
+ return table->fallback(PROTOBUF_TC_PARAM_PASS);
+ }
+ auto expected_tag = UnalignedLoad<TagType>(ptr);
+ auto& field = RefAt<RepeatedPtrField<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);
+ }
+ if (utf8 != kNoUtf8) {
+ if (PROTOBUF_PREDICT_FALSE(!IsStructurallyValidUTF8(*str))) {
+ PrintUTF8ErrorLog("unknown", "parsing", false);
+ if (utf8 == kUtf8) return Error(PROTOBUF_TC_PARAM_PASS);
+ }
+ }
+ if (!ctx->DataAvailable(ptr)) break;
+ } while (UnalignedLoad<TagType>(ptr) == expected_tag);
+ return ToParseLoop(PROTOBUF_TC_PARAM_PASS);
+}
+
+#define PROTOBUF_TCT_SOURCE
+#include <generated_message_tctable_impl.inc>
+
+} // namespace internal
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/generated_message_util.cc b/NorthstarDedicatedTest/include/protobuf/generated_message_util.cc
new file mode 100644
index 00000000..6a85c59e
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/generated_message_util.cc
@@ -0,0 +1,779 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <generated_message_util.h>
+
+#include <atomic>
+#include <limits>
+#include <vector>
+
+#include <io/coded_stream.h>
+#include <io/zero_copy_stream_impl_lite.h>
+#include <arenastring.h>
+#include <extension_set.h>
+#include <generated_message_table_driven.h>
+#include <message_lite.h>
+#include <metadata_lite.h>
+#include <repeated_field.h>
+#include <wire_format_lite.h>
+
+// Must be included last
+#include <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_PRIORITY ExplicitlyConstructed<std::string>
+ fixed_address_empty_string{}; // NOLINT
+
+
+PROTOBUF_CONSTINIT std::atomic<bool> init_protobuf_defaults_state{false};
+static bool InitProtobufDefaultsImpl() {
+ fixed_address_empty_string.DefaultConstruct();
+ OnShutdownDestroyString(fixed_address_empty_string.get_mutable());
+
+
+ init_protobuf_defaults_state.store(true, std::memory_order_release);
+ return true;
+}
+
+void InitProtobufDefaultsSlow() {
+ static bool is_inited = InitProtobufDefaultsImpl();
+ (void)is_inited;
+}
+// Force the initialization of the empty string.
+// Normally, registration would do it, but we don't have any guarantee that
+// there is any object with reflection.
+PROTOBUF_ATTRIBUTE_INIT_PRIORITY static std::true_type init_empty_string =
+ (InitProtobufDefaultsSlow(), std::true_type{});
+
+size_t StringSpaceUsedExcludingSelfLong(const 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> {};
+
+
+template <>
+struct PrimitiveTypeHelper<FieldMetadata::kInlinedType>
+ : PrimitiveTypeHelper<WireFormatLite::TYPE_STRING> {};
+
+// We want to serialize to both CodedOutputStream and directly into byte arrays
+// without duplicating the code. In fact we might want extra output channels in
+// the future.
+template <typename O, int type>
+struct OutputHelper;
+
+template <int type, typename O>
+void SerializeTo(const void* ptr, O* output) {
+ OutputHelper<O, type>::Serialize(ptr, output);
+}
+
+template <typename O>
+void WriteTagTo(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();
+}
+
+// Helper to branch to fast path if possible
+void SerializeMessageDispatch(const MessageLite& msg,
+ const FieldMetadata* field_table, int num_fields,
+ int32_t /*cached_size*/,
+ io::CodedOutputStream* output) {
+ const uint8_t* base = reinterpret_cast<const uint8_t*>(&msg);
+ SerializeInternal(base, field_table, num_fields, output);
+}
+
+// Helper to branch to fast path if possible
+void SerializeMessageDispatch(const MessageLite& msg,
+ const FieldMetadata* field_table, int num_fields,
+ int32_t /*cached_size*/, ArrayOutput* output) {
+ const uint8_t* base = reinterpret_cast<const uint8_t*>(&msg);
+ output->ptr = SerializeInternalToArray(base, field_table, num_fields,
+ output->is_deterministic, output->ptr);
+}
+
+// Serializing messages is special as it's not a primitive type and needs an
+// explicit overload for each output type.
+template <typename O>
+void SerializeMessageTo(const MessageLite* msg, const void* table_ptr,
+ O* output) {
+ const SerializationTable* table =
+ static_cast<const SerializationTable*>(table_ptr);
+ if (!table) {
+ // Proto1
+ WriteLengthTo(msg->GetCachedSize(), output);
+ SerializeMessageNoTable(msg, output);
+ return;
+ }
+ const FieldMetadata* field_table = table->field_table;
+ const uint8_t* base = reinterpret_cast<const uint8_t*>(msg);
+ int cached_size =
+ *reinterpret_cast<const int32_t*>(base + field_table->offset);
+ WriteLengthTo(cached_size, output);
+ int num_fields = table->num_fields - 1;
+ SerializeMessageDispatch(*msg, field_table + 1, num_fields, cached_size,
+ output);
+}
+
+// Almost the same as above only it doesn't output the length field.
+template <typename O>
+void SerializeGroupTo(const MessageLite* msg, const void* table_ptr,
+ O* output) {
+ const SerializationTable* table =
+ static_cast<const SerializationTable*>(table_ptr);
+ if (!table) {
+ // Proto1
+ SerializeMessageNoTable(msg, output);
+ return;
+ }
+ const FieldMetadata* field_table = table->field_table;
+ const uint8_t* base = reinterpret_cast<const uint8_t*>(msg);
+ int cached_size =
+ *reinterpret_cast<const int32_t*>(base + field_table->offset);
+ int num_fields = table->num_fields - 1;
+ SerializeMessageDispatch(*msg, field_table + 1, num_fields, cached_size,
+ output);
+}
+
+template <int type>
+struct SingularFieldHelper {
+ template <typename O>
+ static void Serialize(const void* field, const FieldMetadata& md, O* output) {
+ WriteTagTo(md.tag, output);
+ SerializeTo<type>(field, output);
+ }
+};
+
+template <>
+struct SingularFieldHelper<WireFormatLite::TYPE_STRING> {
+ template <typename O>
+ static void Serialize(const void* field, const FieldMetadata& md, O* output) {
+ WriteTagTo(md.tag, output);
+ SerializeTo<WireFormatLite::TYPE_STRING>(&Get<ArenaStringPtr>(field).Get(),
+ output);
+ }
+};
+
+template <>
+struct SingularFieldHelper<WireFormatLite::TYPE_BYTES>
+ : SingularFieldHelper<WireFormatLite::TYPE_STRING> {};
+
+template <>
+struct SingularFieldHelper<WireFormatLite::TYPE_GROUP> {
+ template <typename O>
+ static void Serialize(const void* field, const FieldMetadata& md, O* output) {
+ WriteTagTo(md.tag, output);
+ SerializeGroupTo(Get<const MessageLite*>(field),
+ static_cast<const SerializationTable*>(md.ptr), output);
+ WriteTagTo(md.tag + 1, output);
+ }
+};
+
+template <>
+struct SingularFieldHelper<WireFormatLite::TYPE_MESSAGE> {
+ template <typename O>
+ static void Serialize(const void* field, const FieldMetadata& md, O* output) {
+ WriteTagTo(md.tag, output);
+ SerializeMessageTo(Get<const MessageLite*>(field),
+ static_cast<const SerializationTable*>(md.ptr), output);
+ }
+};
+
+template <>
+struct SingularFieldHelper<FieldMetadata::kInlinedType> {
+ template <typename O>
+ static void Serialize(const void* field, const FieldMetadata& md, O* output) {
+ WriteTagTo(md.tag, output);
+ SerializeTo<FieldMetadata::kInlinedType>(&Get<std::string>(field), output);
+ }
+};
+
+template <int type>
+struct RepeatedFieldHelper {
+ template <typename O>
+ static void Serialize(const void* field, const FieldMetadata& md, O* output) {
+ typedef typename PrimitiveTypeHelper<type>::Type T;
+ const RepeatedField<T>& array = Get<RepeatedField<T> >(field);
+ for (int i = 0; i < array.size(); i++) {
+ WriteTagTo(md.tag, output);
+ SerializeTo<type>(&array[i], output);
+ }
+ }
+};
+
+// We need to use a helper class to get access to the private members
+class AccessorHelper {
+ public:
+ static int Size(const RepeatedPtrFieldBase& x) { return x.size(); }
+ static void const* Get(const RepeatedPtrFieldBase& x, int idx) {
+ return x.raw_data()[idx];
+ }
+};
+
+template <>
+struct RepeatedFieldHelper<WireFormatLite::TYPE_STRING> {
+ template <typename O>
+ static void Serialize(const void* field, const FieldMetadata& md, O* output) {
+ const internal::RepeatedPtrFieldBase& array =
+ Get<internal::RepeatedPtrFieldBase>(field);
+ for (int i = 0; i < AccessorHelper::Size(array); i++) {
+ WriteTagTo(md.tag, output);
+ SerializeTo<WireFormatLite::TYPE_STRING>(AccessorHelper::Get(array, i),
+ output);
+ }
+ }
+};
+
+template <>
+struct RepeatedFieldHelper<WireFormatLite::TYPE_BYTES>
+ : RepeatedFieldHelper<WireFormatLite::TYPE_STRING> {};
+
+template <>
+struct RepeatedFieldHelper<WireFormatLite::TYPE_GROUP> {
+ template <typename O>
+ static void Serialize(const void* field, const FieldMetadata& md, O* output) {
+ const internal::RepeatedPtrFieldBase& array =
+ Get<internal::RepeatedPtrFieldBase>(field);
+ for (int i = 0; i < AccessorHelper::Size(array); i++) {
+ WriteTagTo(md.tag, output);
+ SerializeGroupTo(
+ static_cast<const MessageLite*>(AccessorHelper::Get(array, i)),
+ static_cast<const SerializationTable*>(md.ptr), output);
+ WriteTagTo(md.tag + 1, output);
+ }
+ }
+};
+
+template <>
+struct RepeatedFieldHelper<WireFormatLite::TYPE_MESSAGE> {
+ template <typename O>
+ static void Serialize(const void* field, const FieldMetadata& md, O* output) {
+ const internal::RepeatedPtrFieldBase& array =
+ Get<internal::RepeatedPtrFieldBase>(field);
+ for (int i = 0; i < AccessorHelper::Size(array); i++) {
+ WriteTagTo(md.tag, output);
+ SerializeMessageTo(
+ static_cast<const MessageLite*>(AccessorHelper::Get(array, i)),
+ md.ptr, output);
+ }
+ }
+};
+
+
+template <>
+struct RepeatedFieldHelper<FieldMetadata::kInlinedType>
+ : RepeatedFieldHelper<WireFormatLite::TYPE_STRING> {};
+
+template <int type>
+struct PackedFieldHelper {
+ template <typename O>
+ static void Serialize(const void* field, const FieldMetadata& md, O* output) {
+ typedef typename PrimitiveTypeHelper<type>::Type T;
+ const RepeatedField<T>& array = Get<RepeatedField<T> >(field);
+ if (array.empty()) return;
+ WriteTagTo(md.tag, output);
+ int cached_size =
+ Get<int>(static_cast<const uint8_t*>(field) + sizeof(RepeatedField<T>));
+ WriteLengthTo(cached_size, output);
+ for (int i = 0; i < array.size(); i++) {
+ SerializeTo<type>(&array[i], output);
+ }
+ }
+};
+
+template <>
+struct PackedFieldHelper<WireFormatLite::TYPE_STRING> {
+ template <typename O>
+ static void Serialize(const void* /*field*/, const FieldMetadata& md,
+ O* /*output*/) {
+ GOOGLE_LOG(FATAL) << "Not implemented field number " << md.tag << " with type "
+ << md.type;
+ }
+};
+
+template <>
+struct PackedFieldHelper<WireFormatLite::TYPE_BYTES>
+ : PackedFieldHelper<WireFormatLite::TYPE_STRING> {};
+template <>
+struct PackedFieldHelper<WireFormatLite::TYPE_GROUP>
+ : PackedFieldHelper<WireFormatLite::TYPE_STRING> {};
+template <>
+struct PackedFieldHelper<WireFormatLite::TYPE_MESSAGE>
+ : PackedFieldHelper<WireFormatLite::TYPE_STRING> {};
+template <>
+struct PackedFieldHelper<FieldMetadata::kInlinedType>
+ : PackedFieldHelper<WireFormatLite::TYPE_STRING> {};
+
+template <int type>
+struct OneOfFieldHelper {
+ template <typename O>
+ static void Serialize(const void* field, const FieldMetadata& md, O* output) {
+ SingularFieldHelper<type>::Serialize(field, md, output);
+ }
+};
+
+
+template <>
+struct OneOfFieldHelper<FieldMetadata::kInlinedType> {
+ template <typename O>
+ static void Serialize(const void* field, const FieldMetadata& md, O* output) {
+ SingularFieldHelper<FieldMetadata::kInlinedType>::Serialize(
+ Get<const std::string*>(field), md, output);
+ }
+};
+
+void SerializeNotImplemented(int field) {
+ GOOGLE_LOG(FATAL) << "Not implemented field number " << field;
+}
+
+// When switching to c++11 we should make these constexpr functions
+#define SERIALIZE_TABLE_OP(type, type_class) \
+ ((type - 1) + static_cast<int>(type_class) * FieldMetadata::kNumTypes)
+
+int FieldMetadata::CalculateType(int type,
+ FieldMetadata::FieldTypeClass type_class) {
+ return SERIALIZE_TABLE_OP(type, type_class);
+}
+
+template <int type>
+bool IsNull(const void* ptr) {
+ return *static_cast<const typename PrimitiveTypeHelper<type>::Type*>(ptr) ==
+ 0;
+}
+
+template <>
+bool IsNull<WireFormatLite::TYPE_STRING>(const void* ptr) {
+ return static_cast<const ArenaStringPtr*>(ptr)->Get().size() == 0;
+}
+
+template <>
+bool IsNull<WireFormatLite::TYPE_BYTES>(const void* ptr) {
+ return static_cast<const ArenaStringPtr*>(ptr)->Get().size() == 0;
+}
+
+template <>
+bool IsNull<WireFormatLite::TYPE_GROUP>(const void* ptr) {
+ return Get<const MessageLite*>(ptr) == nullptr;
+}
+
+template <>
+bool IsNull<WireFormatLite::TYPE_MESSAGE>(const void* ptr) {
+ return Get<const MessageLite*>(ptr) == nullptr;
+}
+
+
+template <>
+bool IsNull<FieldMetadata::kInlinedType>(const void* ptr) {
+ return static_cast<const std::string*>(ptr)->empty();
+}
+
+#define SERIALIZERS_FOR_TYPE(type) \
+ case SERIALIZE_TABLE_OP(type, FieldMetadata::kPresence): \
+ if (!IsPresent(base, field_metadata.has_offset)) continue; \
+ SingularFieldHelper<type>::Serialize(ptr, field_metadata, output); \
+ break; \
+ case SERIALIZE_TABLE_OP(type, FieldMetadata::kNoPresence): \
+ if (IsNull<type>(ptr)) continue; \
+ SingularFieldHelper<type>::Serialize(ptr, field_metadata, output); \
+ break; \
+ case SERIALIZE_TABLE_OP(type, FieldMetadata::kRepeated): \
+ RepeatedFieldHelper<type>::Serialize(ptr, field_metadata, output); \
+ break; \
+ case SERIALIZE_TABLE_OP(type, FieldMetadata::kPacked): \
+ PackedFieldHelper<type>::Serialize(ptr, field_metadata, output); \
+ break; \
+ case SERIALIZE_TABLE_OP(type, FieldMetadata::kOneOf): \
+ if (!IsOneofPresent(base, field_metadata.has_offset, field_metadata.tag)) \
+ continue; \
+ OneOfFieldHelper<type>::Serialize(ptr, field_metadata, output); \
+ break
+
+void SerializeInternal(const uint8_t* base,
+ const FieldMetadata* field_metadata_table,
+ int32_t num_fields, io::CodedOutputStream* output) {
+ SpecialSerializer func = nullptr;
+ for (int i = 0; i < num_fields; i++) {
+ const FieldMetadata& field_metadata = field_metadata_table[i];
+ const uint8_t* ptr = base + field_metadata.offset;
+ switch (field_metadata.type) {
+ SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_DOUBLE);
+ SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_FLOAT);
+ SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_INT64);
+ SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_UINT64);
+ SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_INT32);
+ SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_FIXED64);
+ SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_FIXED32);
+ SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_BOOL);
+ SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_STRING);
+ SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_GROUP);
+ SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_MESSAGE);
+ SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_BYTES);
+ SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_UINT32);
+ SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_ENUM);
+ SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_SFIXED32);
+ SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_SFIXED64);
+ SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_SINT32);
+ SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_SINT64);
+ SERIALIZERS_FOR_TYPE(FieldMetadata::kInlinedType);
+
+ // Special cases
+ case FieldMetadata::kSpecial:
+ func = reinterpret_cast<SpecialSerializer>(
+ const_cast<void*>(field_metadata.ptr));
+ func(base, field_metadata.offset, field_metadata.tag,
+ field_metadata.has_offset, output);
+ break;
+ default:
+ // __builtin_unreachable()
+ SerializeNotImplemented(field_metadata.type);
+ }
+ }
+}
+
+uint8_t* SerializeInternalToArray(const uint8_t* base,
+ const FieldMetadata* field_metadata_table,
+ int32_t num_fields, bool is_deterministic,
+ uint8_t* buffer) {
+ ArrayOutput array_output = {buffer, is_deterministic};
+ ArrayOutput* output = &array_output;
+ SpecialSerializer func = nullptr;
+ for (int i = 0; i < num_fields; i++) {
+ const FieldMetadata& field_metadata = field_metadata_table[i];
+ const uint8_t* ptr = base + field_metadata.offset;
+ switch (field_metadata.type) {
+ SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_DOUBLE);
+ SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_FLOAT);
+ SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_INT64);
+ SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_UINT64);
+ SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_INT32);
+ SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_FIXED64);
+ SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_FIXED32);
+ SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_BOOL);
+ SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_STRING);
+ SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_GROUP);
+ SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_MESSAGE);
+ SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_BYTES);
+ SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_UINT32);
+ SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_ENUM);
+ SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_SFIXED32);
+ SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_SFIXED64);
+ SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_SINT32);
+ SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_SINT64);
+ SERIALIZERS_FOR_TYPE(FieldMetadata::kInlinedType);
+ // Special cases
+ case FieldMetadata::kSpecial: {
+ io::ArrayOutputStream array_stream(array_output.ptr, INT_MAX);
+ io::CodedOutputStream output_stream(&array_stream);
+ output_stream.SetSerializationDeterministic(is_deterministic);
+ func = reinterpret_cast<SpecialSerializer>(
+ const_cast<void*>(field_metadata.ptr));
+ func(base, field_metadata.offset, field_metadata.tag,
+ field_metadata.has_offset, &output_stream);
+ array_output.ptr += output_stream.ByteCount();
+ } break;
+ default:
+ // __builtin_unreachable()
+ SerializeNotImplemented(field_metadata.type);
+ }
+ }
+ return array_output.ptr;
+}
+#undef SERIALIZERS_FOR_TYPE
+
+void ExtensionSerializer(const MessageLite* extendee, const uint8_t* ptr,
+ 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::InternalHelper<MessageLite>::GetOwningArena(submessage) ==
+ submessage_arena);
+ GOOGLE_DCHECK(message_arena != submessage_arena);
+ GOOGLE_DCHECK_EQ(submessage_arena, nullptr);
+ if (message_arena != nullptr && submessage_arena == nullptr) {
+ message_arena->Own(submessage);
+ return submessage;
+ } else {
+ MessageLite* ret = submessage->New(message_arena);
+ ret->CheckTypeAndMergeFrom(*submessage);
+ return ret;
+ }
+}
+
+} // namespace internal
+} // namespace protobuf
+} // namespace google
+
+#include <port_undef.inc>
diff --git a/NorthstarDedicatedTest/include/protobuf/generated_message_util.h b/NorthstarDedicatedTest/include/protobuf/generated_message_util.h
new file mode 100644
index 00000000..623709e9
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/generated_message_util.h
@@ -0,0 +1,213 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// This file contains miscellaneous helper code used by generated code --
+// including lite types -- but which should not be used directly by users.
+
+#ifndef GOOGLE_PROTOBUF_GENERATED_MESSAGE_UTIL_H__
+#define GOOGLE_PROTOBUF_GENERATED_MESSAGE_UTIL_H__
+
+#include <assert.h>
+
+#include <atomic>
+#include <climits>
+#include <string>
+#include <vector>
+
+#include <stubs/common.h>
+#include <any.h>
+#include <has_bits.h>
+#include <implicit_weak_message.h>
+#include <message_lite.h>
+#include <stubs/once.h> // Add direct dep on port for pb.cc
+#include <port.h>
+#include <repeated_field.h>
+#include <wire_format_lite.h>
+#include <stubs/strutil.h>
+#include <stubs/casts.h>
+
+#include <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 <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_GENERATED_MESSAGE_UTIL_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/has_bits.h b/NorthstarDedicatedTest/include/protobuf/has_bits.h
new file mode 100644
index 00000000..f366b15f
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/has_bits.h
@@ -0,0 +1,116 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef GOOGLE_PROTOBUF_HAS_BITS_H__
+#define GOOGLE_PROTOBUF_HAS_BITS_H__
+
+#include <stubs/common.h>
+#include <port.h>
+
+#include <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 <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_HAS_BITS_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/implicit_weak_message.cc b/NorthstarDedicatedTest/include/protobuf/implicit_weak_message.cc
new file mode 100644
index 00000000..83e1e736
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/implicit_weak_message.cc
@@ -0,0 +1,67 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <implicit_weak_message.h>
+
+#include <parse_context.h>
+#include <io/zero_copy_stream_impl_lite.h>
+#include <stubs/once.h>
+#include <wire_format_lite.h>
+
+#include <port_def.inc>
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+const char* ImplicitWeakMessage::_InternalParse(const char* ptr,
+ ParseContext* ctx) {
+ return ctx->AppendString(ptr, &data_);
+}
+
+ExplicitlyConstructed<ImplicitWeakMessage>
+ implicit_weak_message_default_instance;
+internal::once_flag implicit_weak_message_once_init_;
+
+void InitImplicitWeakMessageDefaultInstance() {
+ implicit_weak_message_default_instance.DefaultConstruct();
+}
+
+const ImplicitWeakMessage* ImplicitWeakMessage::default_instance() {
+ internal::call_once(implicit_weak_message_once_init_,
+ InitImplicitWeakMessageDefaultInstance);
+ return &implicit_weak_message_default_instance.get();
+}
+
+} // namespace internal
+} // namespace protobuf
+} // namespace google
+
+#include <port_undef.inc>
diff --git a/NorthstarDedicatedTest/include/protobuf/implicit_weak_message.h b/NorthstarDedicatedTest/include/protobuf/implicit_weak_message.h
new file mode 100644
index 00000000..e7d24493
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/implicit_weak_message.h
@@ -0,0 +1,186 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef GOOGLE_PROTOBUF_IMPLICIT_WEAK_MESSAGE_H__
+#define GOOGLE_PROTOBUF_IMPLICIT_WEAK_MESSAGE_H__
+
+#include <string>
+
+#include <io/coded_stream.h>
+#include <arena.h>
+#include <message_lite.h>
+#include <repeated_field.h>
+
+#ifdef SWIG
+#error "You cannot SWIG proto headers"
+#endif
+
+#include <port_def.inc>
+
+// This file is logically internal-only and should only be used by protobuf
+// generated code.
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+// An implementation of MessageLite that treats all data as unknown. This type
+// acts as a placeholder for an implicit weak field in the case where the true
+// message type does not get linked into the binary.
+class PROTOBUF_EXPORT ImplicitWeakMessage : public MessageLite {
+ public:
+ ImplicitWeakMessage() {}
+ explicit ImplicitWeakMessage(Arena* arena) : MessageLite(arena) {}
+
+ static const ImplicitWeakMessage* default_instance();
+
+ 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 {
+ data_.append(static_cast<const ImplicitWeakMessage&>(other).data_);
+ }
+
+ const char* _InternalParse(const char* ptr, ParseContext* ctx) final;
+
+ size_t ByteSizeLong() const override { return data_.size(); }
+
+ uint8_t* _InternalSerialize(uint8_t* target,
+ io::EpsCopyOutputStream* stream) const final {
+ return stream->WriteRaw(data_.data(), static_cast<int>(data_.size()),
+ target);
+ }
+
+ int GetCachedSize() const override { return static_cast<int>(data_.size()); }
+
+ typedef void InternalArenaConstructable_;
+
+ private:
+ std::string data_;
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImplicitWeakMessage);
+};
+
+// A type handler for use with implicit weak repeated message fields.
+template <typename ImplicitWeakType>
+class ImplicitWeakTypeHandler {
+ public:
+ typedef MessageLite Type;
+ static constexpr bool Moveable = false;
+
+ static inline MessageLite* NewFromPrototype(const MessageLite* prototype,
+ Arena* arena = nullptr) {
+ return prototype->New(arena);
+ }
+
+ static inline void Delete(MessageLite* value, Arena* arena) {
+ if (arena == nullptr) {
+ delete value;
+ }
+ }
+ static inline Arena* GetArena(MessageLite* value) {
+ return value->GetArena();
+ }
+ static inline void Clear(MessageLite* value) { value->Clear(); }
+ static void Merge(const MessageLite& from, MessageLite* to) {
+ to->CheckTypeAndMergeFrom(from);
+ }
+};
+
+} // namespace internal
+
+template <typename T>
+struct WeakRepeatedPtrField {
+ using TypeHandler = internal::ImplicitWeakTypeHandler<T>;
+ constexpr WeakRepeatedPtrField() : weak() {}
+ explicit WeakRepeatedPtrField(Arena* arena) : weak(arena) {}
+ ~WeakRepeatedPtrField() { weak.template Destroy<TypeHandler>(); }
+
+ typedef internal::RepeatedPtrIterator<MessageLite> iterator;
+ typedef internal::RepeatedPtrIterator<const MessageLite> const_iterator;
+ typedef internal::RepeatedPtrOverPtrsIterator<MessageLite*, void*>
+ pointer_iterator;
+ typedef internal::RepeatedPtrOverPtrsIterator<const MessageLite* const,
+ const void* const>
+ const_pointer_iterator;
+
+ iterator begin() { return iterator(base().raw_data()); }
+ const_iterator begin() const { return iterator(base().raw_data()); }
+ const_iterator cbegin() const { return begin(); }
+ iterator end() { return begin() + base().size(); }
+ const_iterator end() const { return begin() + base().size(); }
+ const_iterator cend() const { return end(); }
+ pointer_iterator pointer_begin() {
+ return pointer_iterator(base().raw_mutable_data());
+ }
+ const_pointer_iterator pointer_begin() const {
+ return const_pointer_iterator(base().raw_mutable_data());
+ }
+ pointer_iterator pointer_end() {
+ return pointer_iterator(base().raw_mutable_data() + base().size());
+ }
+ const_pointer_iterator pointer_end() const {
+ return const_pointer_iterator(base().raw_mutable_data() + base().size());
+ }
+
+ MessageLite* AddWeak(const MessageLite* prototype) {
+ return base().AddWeak(prototype);
+ }
+ T* Add() { return weak.Add(); }
+ void Clear() { base().template Clear<TypeHandler>(); }
+ void MergeFrom(const WeakRepeatedPtrField& other) {
+ base().template MergeFrom<TypeHandler>(other.base());
+ }
+ void InternalSwap(WeakRepeatedPtrField* other) {
+ base().InternalSwap(&other->base());
+ }
+
+ const internal::RepeatedPtrFieldBase& base() const { return weak; }
+ internal::RepeatedPtrFieldBase& base() { return weak; }
+ // Union disables running the destructor. Which would create a strong link.
+ // Instead we explicitly destroy the underlying base through the virtual
+ // destructor.
+ union {
+ RepeatedPtrField<T> weak;
+ };
+};
+
+} // namespace protobuf
+} // namespace google
+
+#include <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_IMPLICIT_WEAK_MESSAGE_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/inlined_string_field.cc b/NorthstarDedicatedTest/include/protobuf/inlined_string_field.cc
new file mode 100644
index 00000000..8ae8c454
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/inlined_string_field.cc
@@ -0,0 +1,110 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <inlined_string_field.h>
+
+#include <parse_context.h>
+#include <arena.h>
+#include <arenastring.h>
+#include <generated_message_util.h>
+#include <message_lite.h>
+
+// clang-format off
+#include <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) {
+ if (arena == nullptr || !donated) {
+ return UnsafeMutablePointer();
+ }
+ return MutableSlow(arena, donated, donating_states, mask);
+}
+
+std::string* InlinedStringField::Mutable(ArenaStringPtr::EmptyDefault,
+ Arena* arena, bool donated,
+ uint32_t* donating_states,
+ uint32_t mask) {
+ if (arena == nullptr || !donated) {
+ return UnsafeMutablePointer();
+ }
+ return MutableSlow(arena, donated, donating_states, mask);
+}
+
+std::string* InlinedStringField::MutableSlow(::google::protobuf::Arena* arena,
+ bool donated,
+ uint32_t* donating_states,
+ uint32_t mask) {
+ return UnsafeMutablePointer();
+}
+
+void InlinedStringField::SetAllocated(const std::string* default_value,
+ std::string* value, Arena* arena,
+ bool donated, uint32_t* donating_states,
+ uint32_t mask) {
+ SetAllocatedNoArena(default_value, value);
+}
+
+void InlinedStringField::Set(const std::string* default_value,
+ std::string&& value, Arena* arena, bool donated,
+ uint32_t* donating_states, uint32_t mask) {
+ SetNoArena(default_value, std::move(value));
+}
+
+std::string* InlinedStringField::Release(const std::string* default_value,
+ Arena* arena, bool donated) {
+ if (arena == nullptr && !donated) {
+ return ReleaseNonDefaultNoArena(default_value);
+ }
+ return ReleaseNonDefault(default_value, arena);
+}
+
+std::string* InlinedStringField::ReleaseNonDefault(
+ const std::string* default_value, Arena* arena) {
+ return ReleaseNonDefaultNoArena(default_value);
+}
+
+void InlinedStringField::ClearToDefault(const LazyString& default_value,
+ Arena* arena, bool donated) {
+ (void)arena;
+ get_mutable()->assign(default_value.get());
+}
+
+
+} // namespace internal
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/inlined_string_field.h b/NorthstarDedicatedTest/include/protobuf/inlined_string_field.h
new file mode 100644
index 00000000..264c04fb
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/inlined_string_field.h
@@ -0,0 +1,384 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef GOOGLE_PROTOBUF_INLINED_STRING_FIELD_H__
+#define GOOGLE_PROTOBUF_INLINED_STRING_FIELD_H__
+
+#include <string>
+#include <utility>
+
+#include <stubs/logging.h>
+#include <stubs/common.h>
+#include <arenastring.h>
+#include <message_lite.h>
+#include <port.h>
+#include <stubs/strutil.h>
+
+// Must be included last.
+#include <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(const std::string* default_value, ConstStringParam value,
+ Arena* arena, bool donated, uint32_t* /*donating_states*/,
+ uint32_t /*mask*/) {
+ (void)arena;
+ (void)donated;
+ SetNoArena(default_value, value);
+ }
+
+ // Rvalue Set. If this field is donated, this method will undonate this field
+ // by mutating the `donating_states` according to `mask`.
+ void Set(const std::string* default_value, std::string&& value, Arena* arena,
+ bool donated, uint32_t* donating_states, uint32_t mask);
+
+ template <typename FirstParam>
+ void Set(FirstParam p1, const char* str, ::google::protobuf::Arena* arena, bool donated,
+ uint32_t* donating_states, uint32_t mask) {
+ Set(p1, ConstStringParam(str), arena, donated, donating_states, mask);
+ }
+
+ template <typename FirstParam>
+ void Set(FirstParam p1, const char* str, size_t size, ::google::protobuf::Arena* arena,
+ bool donated, uint32_t* donating_states, uint32_t mask) {
+ ConstStringParam sp{str, size}; // for string_view and `const string &`
+ Set(p1, sp, arena, donated, donating_states, mask);
+ }
+
+ template <typename FirstParam, typename RefWrappedType>
+ void Set(FirstParam p1,
+ std::reference_wrapper<RefWrappedType> const_string_ref,
+ ::google::protobuf::Arena* arena, bool donated, uint32_t* donating_states,
+ uint32_t mask) {
+ Set(p1, const_string_ref.get(), arena, donated, donating_states, mask);
+ }
+
+ template <typename FirstParam, typename SecondParam>
+ void SetBytes(FirstParam p1, SecondParam&& p2, ::google::protobuf::Arena* arena,
+ bool donated, uint32_t* donating_states, uint32_t mask) {
+ Set(p1, static_cast<SecondParam&&>(p2), arena, donated, donating_states,
+ mask);
+ }
+
+ template <typename FirstParam>
+ void SetBytes(FirstParam p1, const void* str, size_t size,
+ ::google::protobuf::Arena* arena, bool donated, uint32_t* donating_states,
+ uint32_t mask) {
+ // Must work whether ConstStringParam is string_view or `const string &`
+ ConstStringParam sp{static_cast<const char*>(str), size};
+ Set(p1, sp, arena, donated, donating_states, mask);
+ }
+
+ PROTOBUF_NDEBUG_INLINE void SetNoArena(const std::string* default_value,
+ StringPiece value);
+ PROTOBUF_NDEBUG_INLINE void SetNoArena(const std::string* default_value,
+ 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(const LazyString& default_value, Arena* arena,
+ bool donated, uint32_t* donating_states, uint32_t mask);
+ std::string* Mutable(ArenaStringPtr::EmptyDefault, Arena* arena, bool donated,
+ uint32_t* donating_states, uint32_t mask);
+
+ // 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(const std::string* default_value,
+ Arena* arena, bool donated);
+ PROTOBUF_NODISCARD std::string* ReleaseNonDefault(
+ const std::string* default_value, Arena* arena);
+ std::string* ReleaseNonDefaultNoArena(const std::string* default_value);
+
+ // 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);
+
+ void SetAllocatedNoArena(const std::string* default_value,
+ std::string* value);
+
+ // When one of `this` and `from` is donated and the other is not donated, this
+ // method will undonate the donated one and swap the two heap-allocated
+ // strings.
+ PROTOBUF_NDEBUG_INLINE void Swap(InlinedStringField* from,
+ const std::string* default_value,
+ Arena* arena, bool donated,
+ bool from_donated, uint32_t* donating_states,
+ uint32_t* from_donating_states,
+ uint32_t mask);
+
+ // 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);
+
+ // Returns a mutable pointer, but doesn't initialize the string to the
+ // default value.
+ PROTOBUF_NDEBUG_INLINE std::string* MutableNoArenaNoDefault(
+ const std::string* /*default_value*/);
+
+ // 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.
+ bool IsDefault(const std::string* /*default_value*/) const { 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);
+
+
+ // 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();
+ if (arena != nullptr) {
+ arena->OwnDestructor(get_mutable());
+ }
+}
+
+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 std::string* InlinedStringField::ReleaseNonDefaultNoArena(
+ const std::string* /*default_value*/) {
+ // Currently, inlined string field can't have non empty default.
+ auto* released = new std::string();
+ get_mutable()->swap(*released);
+ return released;
+}
+
+inline void InlinedStringField::SetNoArena(const std::string* /*default_value*/,
+ StringPiece value) {
+ get_mutable()->assign(value.data(), value.length());
+}
+
+inline void InlinedStringField::SetNoArena(const std::string* /*default_value*/,
+ std::string&& value) {
+ get_mutable()->assign(std::move(value));
+}
+
+inline void InlinedStringField::Swap(
+ InlinedStringField* from, const std::string* /*default_value*/,
+ Arena* arena, bool donated, bool from_donated, uint32_t* donating_states,
+ uint32_t* from_donating_states, uint32_t mask) {
+#if GOOGLE_PROTOBUF_INTERNAL_DONATE_STEAL_INLINE
+ // If one is donated and the other is not, undonate the donated one.
+ if (donated && !from_donated) {
+ MutableSlow(arena, donated, donating_states, mask);
+ } else if (!donated && from_donated) {
+ from->MutableSlow(arena, from_donated, from_donating_states, mask);
+ }
+ // Then, swap the two undonated strings.
+#else
+ (void)arena;
+ (void)donated;
+ (void)from_donated;
+ (void)donating_states;
+ (void)from_donating_states;
+ (void)mask;
+#endif
+ get_mutable()->swap(*from->get_mutable());
+}
+
+inline std::string* InlinedStringField::MutableNoArenaNoDefault(
+ const std::string*) {
+ return get_mutable();
+}
+
+inline std::string* InlinedStringField::UnsafeMutablePointer() {
+ return get_mutable();
+}
+
+} // namespace internal
+} // namespace protobuf
+} // namespace google
+
+#include <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_INLINED_STRING_FIELD_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/inlined_string_field_unittest.cc b/NorthstarDedicatedTest/include/protobuf/inlined_string_field_unittest.cc
new file mode 100644
index 00000000..f97037d1
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/inlined_string_field_unittest.cc
@@ -0,0 +1,286 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <inlined_string_field.h>
+
+#include <algorithm>
+#include <cstdlib>
+#include <cstring>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include <stubs/logging.h>
+#include <stubs/common.h>
+#include <io/coded_stream.h>
+#include <io/zero_copy_stream_impl.h>
+#include <arenastring.h>
+#include <gtest/gtest.h>
+#include <stubs/strutil.h>
+
+
+namespace google {
+namespace protobuf {
+
+using internal::ArenaStringPtr;
+using internal::InlinedStringField;
+
+static std::string WrapString(const char* value) { return value; }
+
+namespace {
+
+const uint32 kMask = ~0x00000001u;
+const uint32 kMask1 = ~0x00000004u;
+const uint32 kMask2 = ~0x00000020u;
+
+TEST(InlinedStringFieldTest, SetOnHeap) {
+ InlinedStringField field;
+ uint32 donating_states = 0;
+ const std::string kDefaultValue = "default";
+ field.Set(&kDefaultValue, WrapString("Test short"), nullptr, false,
+ &donating_states, kMask);
+ EXPECT_EQ(std::string("Test short"), field.Get());
+ field.Set(&kDefaultValue, WrapString("Test long long long long value"),
+ nullptr, false, &donating_states, kMask);
+ EXPECT_EQ(std::string("Test long long long long value"), field.Get());
+}
+
+TEST(InlinedStringFieldTest, SetRvalueOnHeap) {
+ InlinedStringField field;
+ uint32 donating_states = 0;
+ std::string string_moved = "Moved long long long long string 1";
+ field.Set(nullptr, std::move(string_moved), nullptr, false, &donating_states,
+ kMask);
+ EXPECT_EQ("Moved long long long long string 1", field.Get());
+ EXPECT_EQ(donating_states & ~kMask1, 0);
+}
+
+TEST(InlinedStringFieldTest, UnsafeMutablePointerThenRelease) {
+ InlinedStringField field;
+ const std::string kDefaultValue = "default";
+ std::string* mut = field.UnsafeMutablePointer();
+ // The address of inlined string doesn't change behind the scene.
+ EXPECT_EQ(mut, field.UnsafeMutablePointer());
+ EXPECT_EQ(mut, &field.Get());
+ EXPECT_EQ(std::string(""), *mut);
+ *mut = "Test long long long long value"; // ensure string allocates
+ EXPECT_EQ(std::string("Test long long long long value"), field.Get());
+
+ std::string* released = field.ReleaseNonDefaultNoArena(&kDefaultValue);
+ EXPECT_EQ("Test long long long long value", *released);
+ // Default value is ignored.
+ EXPECT_EQ("", field.Get());
+ delete released;
+}
+
+// When donating mechanism is enabled:
+// - Initially, the string is donated.
+// - After lvalue Set: the string is still donated.
+// - After Mutable: the string is undonated. The data buffer of the string is a
+// new buffer on the heap.
+TEST(InlinedStringFieldTest, ArenaSetThenMutable) {
+ Arena arena;
+ auto* field_arena = Arena::CreateMessage<InlinedStringField>(&arena);
+ uint32 donating_states = ~0u;
+ const std::string kDefaultValue = "default";
+ field_arena->Set(&kDefaultValue, WrapString("Test short"), &arena,
+ /*donated=*/true, &donating_states, kMask1);
+ EXPECT_EQ(std::string("Test short"), field_arena->Get());
+ field_arena->Set(&kDefaultValue, "Test long long long long value", &arena,
+ /*donated=*/(donating_states & ~kMask1) != 0,
+ &donating_states, kMask1);
+ EXPECT_EQ(std::string("Test long long long long value"), field_arena->Get());
+#if GOOGLE_PROTOBUF_INTERNAL_DONATE_STEAL_INLINE
+ EXPECT_NE(donating_states & ~kMask1, 0); // donate.
+#endif
+
+ const std::string* old_string = &field_arena->Get();
+ const char* old_data = old_string->data();
+ (void)old_data;
+ std::string* mut = field_arena->Mutable(
+ ArenaStringPtr::EmptyDefault{}, &arena,
+ /*donated=*/(donating_states & ~kMask1) != 0, &donating_states, kMask1);
+ EXPECT_EQ(old_string, mut);
+#if GOOGLE_PROTOBUF_INTERNAL_DONATE_STEAL_INLINE
+ EXPECT_EQ(donating_states & ~kMask1, 0);
+ EXPECT_NE(old_data, mut->data()); // The data buffer of the mutated string is
+ // a new buffer on the heap.
+#endif
+ *mut = "Test an even longer long long long long value";
+ EXPECT_EQ(std::string("Test an even longer long long long long value"),
+ field_arena->Get());
+ EXPECT_EQ(&field_arena->Get(), mut);
+}
+
+// Release doesn't change the donating state.
+// When donating mechanism is enabled:
+// - Initially, the string is donated.
+// - Then lvalue Set: the string is still donated.
+// - Then Release: the string is cleared, and still donated.
+// - Then Mutable: the string is undonated.
+// - Then Release: the string is still undonated.
+TEST(InlinedStringFieldTest, ArenaRelease) {
+ Arena arena;
+ auto* field_arena = Arena::CreateMessage<InlinedStringField>(&arena);
+ uint32 donating_states = ~0u;
+ const std::string kDefaultValue = "default";
+ field_arena->Set(&kDefaultValue, WrapString("Test short"), &arena,
+ /*donated=*/true, &donating_states, kMask1);
+ std::string* released = field_arena->Release(
+ &kDefaultValue, &arena, /*donated=*/(donating_states & ~kMask1) != 0);
+ EXPECT_EQ("Test short", *released);
+ EXPECT_EQ("", field_arena->Get());
+ EXPECT_NE(released, &field_arena->Get());
+#if GOOGLE_PROTOBUF_INTERNAL_DONATE_STEAL_INLINE
+ EXPECT_NE(donating_states & ~kMask1, 0); // still donated.
+#endif
+ delete released;
+
+ std::string* mut = field_arena->Mutable(
+ ArenaStringPtr::EmptyDefault{}, &arena,
+ /*donated=*/(donating_states & ~kMask1) != 0u, &donating_states, kMask1);
+ *mut = "Test long long long long value";
+ std::string* released2 =
+ field_arena->Release(&kDefaultValue, &arena,
+ /*donated=*/(donating_states & ~kMask1) != 0);
+ EXPECT_EQ("Test long long long long value", *released2);
+ EXPECT_EQ("", field_arena->Get());
+#if GOOGLE_PROTOBUF_INTERNAL_DONATE_STEAL_INLINE
+ EXPECT_EQ(donating_states & ~kMask1, 0); // undonated.
+#endif
+ delete released2;
+}
+
+// Rvalue Set always undoantes a donated string.
+TEST(InlinedStringFieldTest, SetRvalueArena) {
+ Arena arena;
+ auto* field1_arena = Arena::CreateMessage<InlinedStringField>(&arena);
+ auto* field2_arena = Arena::CreateMessage<InlinedStringField>(&arena);
+ uint32 donating_states = ~0u;
+ const std::string kDefaultValue = "default";
+
+ std::string string_moved = "Moved long long long long string 1";
+ field1_arena->Set(nullptr, std::move(string_moved), &arena, true,
+ &donating_states, kMask1);
+ EXPECT_EQ("Moved long long long long string 1", field1_arena->Get());
+#if GOOGLE_PROTOBUF_INTERNAL_DONATE_STEAL_INLINE
+ EXPECT_EQ(donating_states & ~kMask1, 0); // Undonate.
+#endif
+
+ field2_arena->Set(nullptr, std::string("string 2 on heap"), &arena, true,
+ &donating_states, kMask);
+ EXPECT_EQ("string 2 on heap", field2_arena->Get());
+#if GOOGLE_PROTOBUF_INTERNAL_DONATE_STEAL_INLINE
+ EXPECT_EQ(donating_states & ~kMask, 0); // Undonated.
+#endif
+}
+
+// Tests SetAllocated for non-arena string fields and arena string fields.
+TEST(InlinedStringFieldTest, SetAllocated) {
+ InlinedStringField field;
+ Arena arena;
+ auto* field1_arena = Arena::CreateMessage<InlinedStringField>(&arena);
+ auto* field2_arena = Arena::CreateMessage<InlinedStringField>(&arena);
+ uint32 donating_states = ~0u;
+ const std::string kDefaultValue = "default";
+
+ // The string in field is on heap.
+ field.Set(&kDefaultValue, WrapString("String on heap"), nullptr, false,
+ &donating_states, kMask);
+ auto* allocated = new std::string("Allocated string on heap");
+ field.SetAllocatedNoArena(&kDefaultValue, allocated);
+ EXPECT_EQ("Allocated string on heap", field.Get());
+
+ // The string in field1_arena is on arena (aka. donated).
+ field1_arena->Set(&kDefaultValue, WrapString("String 1 on arena"), &arena,
+ true, &donating_states, kMask1);
+ *field1_arena->Mutable(ArenaStringPtr::EmptyDefault{}, &arena,
+ (donating_states & ~kMask1) != 0, &donating_states,
+ kMask1) = "Mutated string 1 is now on heap long long";
+ // After Mutable, the string is undonated.
+ allocated = new std::string("Allocated string on heap long long long");
+ field1_arena->SetAllocated(&kDefaultValue, allocated, &arena,
+ (donating_states & ~kMask1) != 0, &donating_states,
+ kMask1);
+ EXPECT_EQ("Allocated string on heap long long long", field1_arena->Get());
+#if GOOGLE_PROTOBUF_INTERNAL_DONATE_STEAL_INLINE
+ EXPECT_EQ(donating_states & ~kMask1, 0); // Still undonated.
+#endif
+
+ // The string in field2_arena is on arena (aka. donated).
+ field2_arena->Set(&kDefaultValue, WrapString("String 2 on arena long long"),
+ &arena, true, &donating_states,
+ kMask2); // Still donated.
+ allocated = new std::string("Allocated string on heap long long long 2");
+ field2_arena->SetAllocated(&kDefaultValue, allocated, &arena, true,
+ &donating_states, kMask2);
+ EXPECT_EQ("Allocated string on heap long long long 2", field2_arena->Get());
+#if GOOGLE_PROTOBUF_INTERNAL_DONATE_STEAL_INLINE
+ EXPECT_EQ(donating_states & ~kMask2, 0); // Undonated.
+#endif
+}
+
+// Tests Swap for non-arena string fields and arena string fields.
+TEST(InlinedStringFieldTest, Swap) {
+ // Swap should only be called when the from and to are on the same arena.
+ InlinedStringField field1;
+ InlinedStringField field2;
+ uint32 donating_states = 0;
+ Arena arena;
+ auto* field1_arena = Arena::CreateMessage<InlinedStringField>(&arena);
+ auto* field2_arena = Arena::CreateMessage<InlinedStringField>(&arena);
+ uint32 donating_states_1 = ~0u;
+ uint32 donating_states_2 = ~0u;
+ const std::string kDefaultValue = "default";
+
+ const std::string& string1_heap = "String 1 on heap";
+ const std::string& string2_heap = "String 2 on heap long long long long";
+ const std::string& string1_arena = "String 1 on arena";
+ const std::string& string2_arena = "String 2 on arena long long long long";
+ field1.SetNoArena(&kDefaultValue, string1_heap);
+ field2.SetNoArena(&kDefaultValue, string2_heap);
+ field1_arena->Set(&kDefaultValue, string1_arena, &arena, true,
+ &donating_states_1, kMask1);
+ field2_arena->Set(&kDefaultValue, string2_arena, &arena, true,
+ &donating_states_2, kMask1);
+
+ field1.Swap(&field2, &kDefaultValue, nullptr, false, false, &donating_states,
+ &donating_states_2, kMask);
+ field1_arena->Swap(field2_arena, &kDefaultValue, &arena, true, true,
+ &donating_states_1, &donating_states_2, kMask1);
+ EXPECT_EQ(field1.Get(), string2_heap);
+ EXPECT_EQ(field2.Get(), string1_heap);
+ EXPECT_EQ(field1_arena->Get(), string2_arena);
+ EXPECT_EQ(field2_arena->Get(), string1_arena);
+}
+
+} // namespace
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/io/coded_stream.cc b/NorthstarDedicatedTest/include/protobuf/io/coded_stream.cc
new file mode 100644
index 00000000..9c50c56e
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/io/coded_stream.cc
@@ -0,0 +1,978 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// This implementation is heavily optimized to make reads and writes
+// of small values (especially varints) as fast as possible. In
+// particular, we optimize for the common case that a read or a write
+// will not cross the end of the buffer, since we can avoid a lot
+// of branching in this case.
+
+#include <io/coded_stream.h>
+
+#include <limits.h>
+
+#include <algorithm>
+#include <cstring>
+#include <utility>
+
+#include <stubs/logging.h>
+#include <stubs/common.h>
+#include <arena.h>
+#include <io/zero_copy_stream.h>
+#include <io/zero_copy_stream_impl_lite.h>
+#include <stubs/stl_util.h>
+
+
+#include <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/src/google/protobuf/io/coded_stream.h.";
+}
+
+bool CodedInputStream::SkipFallback(int count, int original_buffer_size) {
+ if (buffer_size_after_limit_ > 0) {
+ // We hit a limit inside this buffer. Advance to the limit and fail.
+ Advance(original_buffer_size);
+ return false;
+ }
+
+ count -= original_buffer_size;
+ buffer_ = NULL;
+ buffer_end_ = buffer_;
+
+ // Make sure this skip doesn't try to skip past the current limit.
+ int closest_limit = std::min(current_limit_, total_bytes_limit_);
+ int bytes_until_limit = closest_limit - total_bytes_read_;
+ if (bytes_until_limit < count) {
+ // We hit the limit. Skip up to it then fail.
+ if (bytes_until_limit > 0) {
+ total_bytes_read_ = closest_limit;
+ input_->Skip(bytes_until_limit);
+ }
+ return false;
+ }
+
+ if (!input_->Skip(count)) {
+ total_bytes_read_ = input_->ByteCount();
+ return false;
+ }
+ total_bytes_read_ += count;
+ return true;
+}
+
+bool CodedInputStream::GetDirectBufferPointer(const void** data, int* size) {
+ if (BufferSize() == 0 && !Refresh()) return false;
+
+ *data = buffer_;
+ *size = BufferSize();
+ return true;
+}
+
+bool CodedInputStream::ReadRaw(void* buffer, int size) {
+ int current_buffer_size;
+ while ((current_buffer_size = BufferSize()) < size) {
+ // Reading past end of buffer. Copy what we have, then refresh.
+ memcpy(buffer, buffer_, current_buffer_size);
+ buffer = reinterpret_cast<uint8_t*>(buffer) + current_buffer_size;
+ size -= current_buffer_size;
+ Advance(current_buffer_size);
+ if (!Refresh()) return false;
+ }
+
+ memcpy(buffer, buffer_, size);
+ Advance(size);
+
+ return true;
+}
+
+bool CodedInputStream::ReadString(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 irrevelant.
+
+ // If the input is larger than 32 bits, we still need to read it all
+ // and discard the high-order bits.
+ for (int i = 0; i < kMaxVarintBytes - kMaxVarint32Bytes; i++) {
+ b = *(ptr++);
+ if (!(b & 0x80)) goto done;
+ }
+
+ // We have overrun the maximum size of a varint (10 bytes). Assume
+ // the data is corrupt.
+ return std::make_pair(false, ptr);
+
+done:
+ *value = result;
+ return std::make_pair(true, ptr);
+}
+
+PROTOBUF_ALWAYS_INLINE::std::pair<bool, const uint8_t*> ReadVarint64FromArray(
+ const uint8_t* buffer, 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);
+ if (s) stream_->BackUp(s);
+ // Reset to initial state (expecting new buffer)
+ buffer_end_ = end_ = buffer_;
+ return buffer_;
+}
+
+
+uint8_t* EpsCopyOutputStream::FlushAndResetBuffer(uint8_t* ptr) {
+ if (had_error_) return buffer_;
+ int s = Flush(ptr);
+ if (had_error_) return buffer_;
+ return SetInitialBuffer(buffer_end_, s);
+}
+
+bool EpsCopyOutputStream::Skip(int count, uint8_t** pp) {
+ if (count < 0) return false;
+ if (had_error_) {
+ *pp = buffer_;
+ return false;
+ }
+ int size = Flush(*pp);
+ if (had_error_) {
+ *pp = buffer_;
+ return false;
+ }
+ void* data = buffer_end_;
+ while (count > size) {
+ count -= size;
+ if (!stream_->Next(&data, &size)) {
+ *pp = Error();
+ return false;
+ }
+ }
+ *pp = SetInitialBuffer(static_cast<uint8_t*>(data) + count, size - count);
+ return true;
+}
+
+bool EpsCopyOutputStream::GetDirectBufferPointer(void** data, int* size,
+ uint8_t** pp) {
+ if (had_error_) {
+ *pp = buffer_;
+ return false;
+ }
+ *size = Flush(*pp);
+ if (had_error_) {
+ *pp = buffer_;
+ return false;
+ }
+ *data = buffer_end_;
+ while (*size == 0) {
+ if (!stream_->Next(data, size)) {
+ *pp = Error();
+ return false;
+ }
+ }
+ *pp = SetInitialBuffer(*data, *size);
+ return true;
+}
+
+uint8_t* EpsCopyOutputStream::GetDirectBufferForNBytesAndAdvance(int size,
+ uint8_t** pp) {
+ if (had_error_) {
+ *pp = buffer_;
+ return nullptr;
+ }
+ int s = Flush(*pp);
+ if (had_error_) {
+ *pp = buffer_;
+ return nullptr;
+ }
+ if (s >= size) {
+ auto res = buffer_end_;
+ *pp = SetInitialBuffer(buffer_end_ + size, s - size);
+ return res;
+ } else {
+ *pp = SetInitialBuffer(buffer_end_, s);
+ return nullptr;
+ }
+}
+
+uint8_t* EpsCopyOutputStream::Next() {
+ GOOGLE_DCHECK(!had_error_); // NOLINT
+ if (PROTOBUF_PREDICT_FALSE(stream_ == nullptr)) return Error();
+ if (buffer_end_) {
+ // We're in the patch buffer and need to fill up the previous buffer.
+ std::memcpy(buffer_end_, buffer_, end_ - buffer_);
+ uint8_t* ptr;
+ int size;
+ do {
+ void* data;
+ if (PROTOBUF_PREDICT_FALSE(!stream_->Next(&data, &size))) {
+ // Stream has an error, we use the patch buffer to continue to be
+ // able to write.
+ return Error();
+ }
+ ptr = static_cast<uint8_t*>(data);
+ } while (size == 0);
+ if (PROTOBUF_PREDICT_TRUE(size > kSlopBytes)) {
+ std::memcpy(ptr, end_, kSlopBytes);
+ end_ = ptr + size - kSlopBytes;
+ buffer_end_ = nullptr;
+ return ptr;
+ } else {
+ GOOGLE_DCHECK(size > 0); // NOLINT
+ // Buffer to small
+ std::memmove(buffer_, end_, kSlopBytes);
+ buffer_end_ = ptr;
+ end_ = buffer_ + size;
+ return buffer_;
+ }
+ } else {
+ std::memcpy(buffer_, end_, kSlopBytes);
+ buffer_end_ = end_;
+ end_ = buffer_ + kSlopBytes;
+ return buffer_;
+ }
+}
+
+uint8_t* EpsCopyOutputStream::EnsureSpaceFallback(uint8_t* ptr) {
+ do {
+ if (PROTOBUF_PREDICT_FALSE(had_error_)) return buffer_;
+ int overrun = ptr - end_;
+ GOOGLE_DCHECK(overrun >= 0); // NOLINT
+ GOOGLE_DCHECK(overrun <= kSlopBytes); // NOLINT
+ ptr = Next() + overrun;
+ } while (ptr >= end_);
+ GOOGLE_DCHECK(ptr < end_); // NOLINT
+ return ptr;
+}
+
+uint8_t* EpsCopyOutputStream::WriteRawFallback(const void* data, int size,
+ uint8_t* ptr) {
+ int s = GetSize(ptr);
+ while (s < size) {
+ std::memcpy(ptr, data, s);
+ size -= s;
+ data = static_cast<const uint8_t*>(data) + s;
+ ptr = EnsureSpaceFallback(ptr + s);
+ s = GetSize(ptr);
+ }
+ std::memcpy(ptr, data, size);
+ return ptr + size;
+}
+
+uint8_t* EpsCopyOutputStream::WriteAliasedRaw(const void* data, int size,
+ uint8_t* ptr) {
+ if (size < GetSize(ptr)
+ ) {
+ return WriteRaw(data, size, ptr);
+ } else {
+ ptr = Trim(ptr);
+ if (stream_->WriteAliasedRaw(data, size)) return ptr;
+ return Error();
+ }
+}
+
+#ifndef PROTOBUF_LITTLE_ENDIAN
+uint8_t* EpsCopyOutputStream::WriteRawLittleEndian32(const void* data, int size,
+ uint8_t* ptr) {
+ auto p = static_cast<const uint8_t*>(data);
+ auto end = p + size;
+ while (end - p >= kSlopBytes) {
+ ptr = EnsureSpace(ptr);
+ 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(ZeroCopyOutputStream* stream,
+ bool do_eager_refresh)
+ : impl_(stream, IsDefaultSerializationDeterministic(), &cur_),
+ start_count_(stream->ByteCount()) {
+ if (do_eager_refresh) {
+ void* data;
+ int size;
+ if (!stream->Next(&data, &size) || size == 0) return;
+ cur_ = impl_.SetInitialBuffer(data, size);
+ }
+}
+
+CodedOutputStream::~CodedOutputStream() { Trim(); }
+
+
+uint8_t* CodedOutputStream::WriteStringWithSizeToArray(const 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 <port_undef.inc>
diff --git a/NorthstarDedicatedTest/include/protobuf/io/coded_stream.h b/NorthstarDedicatedTest/include/protobuf/io/coded_stream.h
new file mode 100644
index 00000000..99844c69
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/io/coded_stream.h
@@ -0,0 +1,1775 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// This file contains the CodedInputStream and CodedOutputStream classes,
+// which wrap a ZeroCopyInputStream or ZeroCopyOutputStream, respectively,
+// and allow you to read or write individual pieces of data in various
+// formats. In particular, these implement the varint encoding for
+// integers, a simple variable-length encoding in which smaller numbers
+// take fewer bytes.
+//
+// Typically these classes will only be used internally by the protocol
+// buffer library in order to encode and decode protocol buffers. Clients
+// of the library only need to know about this class if they wish to write
+// custom message parsing or serialization procedures.
+//
+// CodedOutputStream example:
+// // Write some data to "myfile". First we write a 4-byte "magic number"
+// // to identify the file type, then write a length-delimited string. The
+// // string is composed of a varint giving the length followed by the raw
+// // bytes.
+// int fd = open("myfile", O_CREAT | O_WRONLY);
+// ZeroCopyOutputStream* raw_output = new FileOutputStream(fd);
+// CodedOutputStream* coded_output = new CodedOutputStream(raw_output);
+//
+// int magic_number = 1234;
+// char text[] = "Hello world!";
+// coded_output->WriteLittleEndian32(magic_number);
+// coded_output->WriteVarint32(strlen(text));
+// coded_output->WriteRaw(text, strlen(text));
+//
+// delete coded_output;
+// delete raw_output;
+// close(fd);
+//
+// CodedInputStream example:
+// // Read a file created by the above code.
+// int fd = open("myfile", O_RDONLY);
+// ZeroCopyInputStream* raw_input = new FileInputStream(fd);
+// CodedInputStream* coded_input = new CodedInputStream(raw_input);
+//
+// coded_input->ReadLittleEndian32(&magic_number);
+// if (magic_number != 1234) {
+// cerr << "File not in expected format." << endl;
+// return;
+// }
+//
+// 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>
+
+#ifdef _WIN32
+// Assuming windows is always little-endian.
+#if !defined(PROTOBUF_DISABLE_LITTLE_ENDIAN_OPT_FOR_TEST)
+#define PROTOBUF_LITTLE_ENDIAN 1
+#endif
+#if defined(_MSC_VER) && _MSC_VER >= 1300 && !defined(__INTEL_COMPILER)
+// If MSVC has "/RTCc" set, it will complain about truncating casts at
+// runtime. This file contains some intentional truncating casts.
+#pragma runtime_checks("c", off)
+#endif
+#else
+#ifdef __APPLE__
+#include <machine/endian.h> // __BYTE_ORDER
+#elif defined(__FreeBSD__)
+#include <sys/endian.h> // __BYTE_ORDER
+#elif (defined(sun) || defined(__sun)) && (defined(__SVR4) || defined(__svr4__))
+#include <sys/isa_defs.h> // __BYTE_ORDER
+#elif defined(_AIX) || defined(__TOS_AIX__)
+#include <sys/machine.h> // BYTE_ORDER
+#else
+#if !defined(__QNX__)
+#include <endian.h> // __BYTE_ORDER
+#endif
+#endif
+#if ((defined(__LITTLE_ENDIAN__) && !defined(__BIG_ENDIAN__)) || \
+ (defined(__BYTE_ORDER) && __BYTE_ORDER == __LITTLE_ENDIAN)) && \
+ !defined(PROTOBUF_DISABLE_LITTLE_ENDIAN_OPT_FOR_TEST)
+#define PROTOBUF_LITTLE_ENDIAN 1
+#endif
+#endif
+#include <stubs/common.h>
+#include <stubs/logging.h>
+#include <stubs/strutil.h>
+#include <port.h>
+#include <stubs/port.h>
+
+
+#include <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_;
+
+ 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);
+#ifndef PROTOBUF_LITTLE_ENDIAN
+ uint8_t* WriteRawLittleEndian32(const void* data, int size, uint8_t* ptr);
+ uint8_t* WriteRawLittleEndian64(const void* data, int size, uint8_t* ptr);
+#endif
+
+ // These methods are for CodedOutputStream. Ideally they should be private
+ // but to match current behavior of CodedOutputStream as close as possible
+ // we allow it some functionality.
+ public:
+ uint8_t* SetInitialBuffer(void* data, int size) {
+ auto ptr = static_cast<uint8_t*>(data);
+ if (size > kSlopBytes) {
+ end_ = ptr + size - kSlopBytes;
+ buffer_end_ = nullptr;
+ return ptr;
+ } else {
+ end_ = buffer_ + size;
+ buffer_end_ = ptr;
+ return buffer_;
+ }
+ }
+
+ private:
+ // Needed by CodedOutputStream HadError. HadError needs to flush the patch
+ // buffers to ensure there is no error as of yet.
+ uint8_t* FlushAndResetBuffer(uint8_t*);
+
+ // The following functions mimic the old CodedOutputStream behavior as close
+ // as possible. They flush the current state to the stream, behave as
+ // the old CodedOutputStream and then return to normal operation.
+ bool Skip(int count, uint8_t** pp);
+ bool GetDirectBufferPointer(void** data, int* size, uint8_t** pp);
+ uint8_t* GetDirectBufferForNBytesAndAdvance(int size, uint8_t** pp);
+
+ friend class CodedOutputStream;
+};
+
+template <>
+inline uint8_t* EpsCopyOutputStream::WriteRawLittleEndian<1>(const void* data,
+ int size,
+ uint8_t* ptr) {
+ return WriteRaw(data, size, ptr);
+}
+template <>
+inline uint8_t* EpsCopyOutputStream::WriteRawLittleEndian<4>(const void* data,
+ int size,
+ uint8_t* ptr) {
+#ifdef PROTOBUF_LITTLE_ENDIAN
+ return WriteRaw(data, size, ptr);
+#else
+ return WriteRawLittleEndian32(data, size, ptr);
+#endif
+}
+template <>
+inline uint8_t* EpsCopyOutputStream::WriteRawLittleEndian<8>(const void* data,
+ int size,
+ uint8_t* ptr) {
+#ifdef PROTOBUF_LITTLE_ENDIAN
+ return WriteRaw(data, size, ptr);
+#else
+ return WriteRawLittleEndian64(data, size, ptr);
+#endif
+}
+
+// Class which encodes and writes binary data which is composed of varint-
+// encoded integers and fixed-width pieces. Wraps a ZeroCopyOutputStream.
+// Most users will not need to deal with CodedOutputStream.
+//
+// Most methods of CodedOutputStream which return a bool return false if an
+// underlying I/O error occurs. Once such a failure occurs, the
+// CodedOutputStream is broken and is no longer useful. The Write* methods do
+// not return the stream status, but will invalidate the stream if an error
+// occurs. The client can probe HadError() to determine the status.
+//
+// Note that every method of CodedOutputStream which writes some data has
+// a corresponding static "ToArray" version. These versions write directly
+// to the provided buffer, returning a pointer past the last written byte.
+// They require that the buffer has sufficient capacity for the encoded data.
+// This allows an optimization where we check if an output stream has enough
+// space for an entire message before we start writing and, if there is, we
+// call only the ToArray methods to avoid doing bound checks for each
+// individual value.
+// i.e., in the example above:
+//
+// CodedOutputStream* coded_output = new CodedOutputStream(raw_output);
+// int magic_number = 1234;
+// char text[] = "Hello world!";
+//
+// int coded_size = sizeof(magic_number) +
+// CodedOutputStream::VarintSize32(strlen(text)) +
+// strlen(text);
+//
+// uint8_t* buffer =
+// coded_output->GetDirectBufferForNBytesAndAdvance(coded_size);
+// if (buffer != nullptr) {
+// // The output stream has enough space in the buffer: write directly to
+// // the array.
+// buffer = CodedOutputStream::WriteLittleEndian32ToArray(magic_number,
+// buffer);
+// buffer = CodedOutputStream::WriteVarint32ToArray(strlen(text), buffer);
+// buffer = CodedOutputStream::WriteRawToArray(text, strlen(text), buffer);
+// } else {
+// // Make bound-checked writes, which will ask the underlying stream for
+// // more space as needed.
+// coded_output->WriteLittleEndian32(magic_number);
+// coded_output->WriteVarint32(strlen(text));
+// coded_output->WriteRaw(text, strlen(text));
+// }
+//
+// delete coded_output;
+class PROTOBUF_EXPORT CodedOutputStream {
+ public:
+ // Create an CodedOutputStream that writes to the given ZeroCopyOutputStream.
+ explicit CodedOutputStream(ZeroCopyOutputStream* stream)
+ : CodedOutputStream(stream, true) {}
+ CodedOutputStream(ZeroCopyOutputStream* stream, bool do_eager_refresh);
+
+ // Destroy the CodedOutputStream and position the underlying
+ // ZeroCopyOutputStream immediately after the last byte written.
+ ~CodedOutputStream();
+
+ // Returns true if there was an underlying I/O error since this object was
+ // created. On should call Trim before this function in order to catch all
+ // errors.
+ bool HadError() {
+ cur_ = impl_.FlushAndResetBuffer(cur_);
+ GOOGLE_DCHECK(cur_);
+ return impl_.HadError();
+ }
+
+ // Trims any unused space in the underlying buffer so that its size matches
+ // the number of bytes written by this stream. The underlying buffer will
+ // automatically be trimmed when this stream is destroyed; this call is only
+ // necessary if the underlying buffer is accessed *before* the stream is
+ // destroyed.
+ void Trim() { cur_ = impl_.Trim(cur_); }
+
+ // Skips a number of bytes, leaving the bytes unmodified in the underlying
+ // buffer. Returns false if an underlying write error occurs. This is
+ // mainly useful with GetDirectBufferPointer().
+ // Note of caution, the skipped bytes may contain uninitialized data. The
+ // caller must make sure that the skipped bytes are properly initialized,
+ // otherwise you might leak bytes from your heap.
+ bool Skip(int count) { return impl_.Skip(count, &cur_); }
+
+ // Sets *data to point directly at the unwritten part of the
+ // CodedOutputStream's underlying buffer, and *size to the size of that
+ // buffer, but does not advance the stream's current position. This will
+ // always either produce a non-empty buffer or return false. If the caller
+ // writes any data to this buffer, it should then call Skip() to skip over
+ // the consumed bytes. This may be useful for implementing external fast
+ // serialization routines for types of data not covered by the
+ // CodedOutputStream interface.
+ bool GetDirectBufferPointer(void** data, int* size) {
+ return impl_.GetDirectBufferPointer(data, size, &cur_);
+ }
+
+ // If there are at least "size" bytes available in the current buffer,
+ // returns a pointer directly into the buffer and advances over these bytes.
+ // The caller may then write directly into this buffer (e.g. using the
+ // *ToArray static methods) rather than go through CodedOutputStream. If
+ // there are not enough bytes available, returns NULL. The return pointer is
+ // invalidated as soon as any other non-const method of CodedOutputStream
+ // is called.
+ inline uint8_t* GetDirectBufferForNBytesAndAdvance(int size) {
+ return impl_.GetDirectBufferForNBytesAndAdvance(size, &cur_);
+ }
+
+ // Write raw bytes, copying them from the given buffer.
+ void WriteRaw(const void* buffer, int size) {
+ cur_ = impl_.WriteRaw(buffer, size, cur_);
+ }
+ // Like WriteRaw() but will try to write aliased data if aliasing is
+ // turned on.
+ void WriteRawMaybeAliased(const void* data, int size);
+ // Like WriteRaw() but writing directly to the target array.
+ // This is _not_ inlined, as the compiler often optimizes memcpy into inline
+ // copy loops. Since this gets called by every field with string or bytes
+ // type, inlining may lead to a significant amount of code bloat, with only a
+ // minor performance gain.
+ static uint8_t* WriteRawToArray(const void* buffer, int size,
+ uint8_t* target);
+
+ // Equivalent to WriteRaw(str.data(), str.size()).
+ void WriteString(const 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 derministic
+ // serialization. The default when this is not called comes from the global
+ // default, controlled by SetDefaultSerializationDeterministic.
+ //
+ // What deterministic serialization means is entirely up to the driver of the
+ // serialization process (i.e. the caller of methods like WriteVarint32). In
+ // the case of serializing a proto buffer message using one of the methods of
+ // MessageLite, this means that for a given binary equal messages will always
+ // be serialized to the same bytes. This implies:
+ //
+ // * Repeated serialization of a message will return the same bytes.
+ //
+ // * Different processes running the same binary (including on different
+ // machines) will serialize equal messages to the same bytes.
+ //
+ // Note that this is *not* canonical across languages. It is also unstable
+ // across different builds with intervening message definition changes, due to
+ // unknown fields. Users who need canonical serialization (e.g. persistent
+ // storage in a canonical form, fingerprinting) should define their own
+ // canonicalization specification and implement the serializer using
+ // reflection APIs rather than relying on this API.
+ void SetSerializationDeterministic(bool value) {
+ impl_.SetSerializationDeterministic(value);
+ }
+
+ // Return whether the user wants deterministic serialization. See above.
+ bool IsSerializationDeterministic() const {
+ return impl_.IsSerializationDeterministic();
+ }
+
+ static bool IsDefaultSerializationDeterministic() {
+ return default_serialization_deterministic_.load(
+ std::memory_order_relaxed) != 0;
+ }
+
+ template <typename Func>
+ void Serialize(const Func& func);
+
+ uint8_t* Cur() const { return cur_; }
+ void SetCur(uint8_t* ptr) { cur_ = ptr; }
+ EpsCopyOutputStream* EpsCopy() { return &impl_; }
+
+ private:
+ EpsCopyOutputStream impl_;
+ uint8_t* cur_;
+ 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)
+ 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)
+ 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)
+ 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)
+ 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);
+}
+
+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)
+ 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)
+ 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 <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_IO_CODED_STREAM_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/io/coded_stream_unittest.cc b/NorthstarDedicatedTest/include/protobuf/io/coded_stream_unittest.cc
new file mode 100644
index 00000000..fffe879a
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/io/coded_stream_unittest.cc
@@ -0,0 +1,1346 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 tests and benchmarks.
+
+#include <io/coded_stream.h>
+
+#include <limits.h>
+
+#include <memory>
+#include <vector>
+
+#include <stubs/common.h>
+#include <stubs/logging.h>
+#include <stubs/logging.h>
+#include <io/zero_copy_stream_impl.h>
+#include <testing/googletest.h>
+#include <gtest/gtest.h>
+#include <stubs/casts.h>
+
+#include <port_def.inc>
+
+
+namespace google {
+namespace protobuf {
+namespace io {
+namespace {
+
+
+// ===================================================================
+// Data-Driven Test Infrastructure
+
+// TEST_1D and TEST_2D are macros I'd eventually like to see added to
+// gTest. These macros can be used to declare tests which should be
+// run multiple times, once for each item in some input array. TEST_1D
+// tests all cases in a single input array. TEST_2D tests all
+// combinations of cases from two arrays. The arrays must be statically
+// defined such that the GOOGLE_ARRAYSIZE() macro works on them. Example:
+//
+// int kCases[] = {1, 2, 3, 4}
+// TEST_1D(MyFixture, MyTest, kCases) {
+// EXPECT_GT(kCases_case, 0);
+// }
+//
+// This test iterates through the numbers 1, 2, 3, and 4 and tests that
+// they are all grater than zero. In case of failure, the exact case
+// which failed will be printed. The case type must be printable using
+// ostream::operator<<.
+
+// TODO(kenton): gTest now supports "parameterized tests" which would be
+// a better way to accomplish this. Rewrite when time permits.
+
+#define TEST_1D(FIXTURE, NAME, CASES) \
+ class FIXTURE##_##NAME##_DD : public FIXTURE { \
+ protected: \
+ template <typename CaseType> \
+ void DoSingleCase(const CaseType& CASES##_case); \
+ }; \
+ \
+ TEST_F(FIXTURE##_##NAME##_DD, NAME) { \
+ for (int i = 0; i < GOOGLE_ARRAYSIZE(CASES); i++) { \
+ SCOPED_TRACE(testing::Message() \
+ << #CASES " case #" << i << ": " << CASES[i]); \
+ DoSingleCase(CASES[i]); \
+ } \
+ } \
+ \
+ template <typename CaseType> \
+ void FIXTURE##_##NAME##_DD::DoSingleCase(const CaseType& CASES##_case)
+
+#define TEST_2D(FIXTURE, NAME, CASES1, CASES2) \
+ class FIXTURE##_##NAME##_DD : public FIXTURE { \
+ protected: \
+ template <typename CaseType1, typename CaseType2> \
+ void DoSingleCase(const CaseType1& CASES1##_case, \
+ const CaseType2& CASES2##_case); \
+ }; \
+ \
+ TEST_F(FIXTURE##_##NAME##_DD, NAME) { \
+ for (int i = 0; i < GOOGLE_ARRAYSIZE(CASES1); i++) { \
+ for (int j = 0; j < GOOGLE_ARRAYSIZE(CASES2); j++) { \
+ SCOPED_TRACE(testing::Message() \
+ << #CASES1 " case #" << i << ": " << CASES1[i] << ", " \
+ << #CASES2 " case #" << j << ": " << CASES2[j]); \
+ DoSingleCase(CASES1[i], CASES2[j]); \
+ } \
+ } \
+ } \
+ \
+ template <typename CaseType1, typename CaseType2> \
+ void FIXTURE##_##NAME##_DD::DoSingleCase(const CaseType1& CASES1##_case, \
+ const CaseType2& CASES2##_case)
+
+// ===================================================================
+
+class CodedStreamTest : public testing::Test {
+ protected:
+ // Buffer used during most of the tests. This assumes tests run sequentially.
+ static constexpr int kBufferSize = 1024 * 64;
+ static uint8 buffer_[kBufferSize];
+};
+
+uint8 CodedStreamTest::buffer_[CodedStreamTest::kBufferSize];
+
+// We test each operation over a variety of block sizes to insure that
+// we test cases where reads or writes cross buffer boundaries, cases
+// where they don't, and cases where there is so much buffer left that
+// we can use special optimized paths that don't worry about bounds
+// checks.
+const int kBlockSizes[] = {1, 2, 3, 5, 7, 13, 32, 1024};
+
+
+// -------------------------------------------------------------------
+// Varint tests.
+
+struct VarintCase {
+ uint8 bytes[10]; // Encoded bytes.
+ int size; // Encoded size, in bytes.
+ uint64 value; // Parsed value.
+};
+
+inline std::ostream& operator<<(std::ostream& os, const VarintCase& c) {
+ return os << c.value;
+}
+
+VarintCase kVarintCases[] = {
+ // 32-bit values
+ {{0x00}, 1, 0},
+ {{0x01}, 1, 1},
+ {{0x7f}, 1, 127},
+ {{0xa2, 0x74}, 2, (0x22 << 0) | (0x74 << 7)}, // 14882
+ {{0xbe, 0xf7, 0x92, 0x84, 0x0b},
+ 5, // 2961488830
+ (0x3e << 0) | (0x77 << 7) | (0x12 << 14) | (0x04 << 21) |
+ (uint64_t{0x0bu} << 28)},
+
+ // 64-bit
+ {{0xbe, 0xf7, 0x92, 0x84, 0x1b},
+ 5, // 7256456126
+ (0x3e << 0) | (0x77 << 7) | (0x12 << 14) | (0x04 << 21) |
+ (uint64_t{0x1bu} << 28)},
+ {{0x80, 0xe6, 0xeb, 0x9c, 0xc3, 0xc9, 0xa4, 0x49},
+ 8, // 41256202580718336
+ (0x00 << 0) | (0x66 << 7) | (0x6b << 14) | (0x1c << 21) |
+ (uint64_t{0x43u} << 28) | (uint64_t{0x49u} << 35) |
+ (uint64_t{0x24u} << 42) | (uint64_t{0x49u} << 49)},
+ // 11964378330978735131
+ {{0x9b, 0xa8, 0xf9, 0xc2, 0xbb, 0xd6, 0x80, 0x85, 0xa6, 0x01},
+ 10,
+ (0x1b << 0) | (0x28 << 7) | (0x79 << 14) | (0x42 << 21) |
+ (uint64_t{0x3bu} << 28) | (uint64_t{0x56u} << 35) |
+ (uint64_t{0x00u} << 42) | (uint64_t{0x05u} << 49) |
+ (uint64_t{0x26u} << 56) | (uint64_t{0x01u} << 63)},
+};
+
+TEST_2D(CodedStreamTest, ReadVarint32, kVarintCases, kBlockSizes) {
+ memcpy(buffer_, kVarintCases_case.bytes, kVarintCases_case.size);
+ ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case);
+
+ {
+ CodedInputStream coded_input(&input);
+
+ uint32 value;
+ EXPECT_TRUE(coded_input.ReadVarint32(&value));
+ EXPECT_EQ(static_cast<uint32>(kVarintCases_case.value), value);
+ }
+
+ EXPECT_EQ(kVarintCases_case.size, input.ByteCount());
+}
+
+TEST_2D(CodedStreamTest, ReadTag, kVarintCases, kBlockSizes) {
+ memcpy(buffer_, kVarintCases_case.bytes, kVarintCases_case.size);
+ ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case);
+
+ {
+ CodedInputStream coded_input(&input);
+
+ uint32 expected_value = static_cast<uint32>(kVarintCases_case.value);
+ EXPECT_EQ(expected_value, coded_input.ReadTag());
+
+ EXPECT_TRUE(coded_input.LastTagWas(expected_value));
+ EXPECT_FALSE(coded_input.LastTagWas(expected_value + 1));
+ }
+
+ EXPECT_EQ(kVarintCases_case.size, input.ByteCount());
+}
+
+// This is the regression test that verifies that there is no issues
+// with the empty input buffers handling.
+TEST_F(CodedStreamTest, EmptyInputBeforeEos) {
+ class In : public ZeroCopyInputStream {
+ public:
+ In() : count_(0) {}
+
+ private:
+ bool Next(const void** data, int* size) override {
+ *data = NULL;
+ *size = 0;
+ return count_++ < 2;
+ }
+ void BackUp(int count) override { GOOGLE_LOG(FATAL) << "Tests never call this."; }
+ bool Skip(int count) override {
+ GOOGLE_LOG(FATAL) << "Tests never call this.";
+ return false;
+ }
+ int64_t ByteCount() const override { return 0; }
+ int count_;
+ } in;
+ CodedInputStream input(&in);
+ input.ReadTagNoLastTag();
+ EXPECT_TRUE(input.ConsumedEntireMessage());
+}
+
+TEST_1D(CodedStreamTest, ExpectTag, kVarintCases) {
+ // Leave one byte at the beginning of the buffer so we can read it
+ // to force the first buffer to be loaded.
+ buffer_[0] = '\0';
+ memcpy(buffer_ + 1, kVarintCases_case.bytes, kVarintCases_case.size);
+ ArrayInputStream input(buffer_, sizeof(buffer_));
+
+ {
+ CodedInputStream coded_input(&input);
+
+ // Read one byte to force coded_input.Refill() to be called. Otherwise,
+ // ExpectTag() will return a false negative.
+ uint8 dummy;
+ coded_input.ReadRaw(&dummy, 1);
+ EXPECT_EQ((uint)'\0', (uint)dummy);
+
+ uint32 expected_value = static_cast<uint32>(kVarintCases_case.value);
+
+ // ExpectTag() produces false negatives for large values.
+ if (kVarintCases_case.size <= 2) {
+ EXPECT_FALSE(coded_input.ExpectTag(expected_value + 1));
+ EXPECT_TRUE(coded_input.ExpectTag(expected_value));
+ } else {
+ EXPECT_FALSE(coded_input.ExpectTag(expected_value));
+ }
+ }
+
+ if (kVarintCases_case.size <= 2) {
+ EXPECT_EQ(kVarintCases_case.size + 1, input.ByteCount());
+ } else {
+ EXPECT_EQ(1, input.ByteCount());
+ }
+}
+
+TEST_1D(CodedStreamTest, ExpectTagFromArray, kVarintCases) {
+ memcpy(buffer_, kVarintCases_case.bytes, kVarintCases_case.size);
+
+ const uint32 expected_value = static_cast<uint32>(kVarintCases_case.value);
+
+ // If the expectation succeeds, it should return a pointer past the tag.
+ if (kVarintCases_case.size <= 2) {
+ EXPECT_TRUE(NULL == CodedInputStream::ExpectTagFromArray(
+ buffer_, expected_value + 1));
+ EXPECT_TRUE(buffer_ + kVarintCases_case.size ==
+ CodedInputStream::ExpectTagFromArray(buffer_, expected_value));
+ } else {
+ EXPECT_TRUE(NULL ==
+ CodedInputStream::ExpectTagFromArray(buffer_, expected_value));
+ }
+}
+
+TEST_2D(CodedStreamTest, ReadVarint64, kVarintCases, kBlockSizes) {
+ memcpy(buffer_, kVarintCases_case.bytes, kVarintCases_case.size);
+ ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case);
+
+ {
+ CodedInputStream coded_input(&input);
+
+ uint64 value;
+ EXPECT_TRUE(coded_input.ReadVarint64(&value));
+ EXPECT_EQ(kVarintCases_case.value, value);
+ }
+
+ EXPECT_EQ(kVarintCases_case.size, input.ByteCount());
+}
+
+TEST_2D(CodedStreamTest, WriteVarint32, kVarintCases, kBlockSizes) {
+ if (kVarintCases_case.value > uint64_t{0x00000000FFFFFFFFu}) {
+ // Skip this test for the 64-bit values.
+ return;
+ }
+
+ ArrayOutputStream output(buffer_, sizeof(buffer_), kBlockSizes_case);
+
+ {
+ CodedOutputStream coded_output(&output);
+
+ coded_output.WriteVarint32(static_cast<uint32>(kVarintCases_case.value));
+ EXPECT_FALSE(coded_output.HadError());
+
+ EXPECT_EQ(kVarintCases_case.size, coded_output.ByteCount());
+ }
+
+ EXPECT_EQ(kVarintCases_case.size, output.ByteCount());
+ EXPECT_EQ(0,
+ memcmp(buffer_, kVarintCases_case.bytes, kVarintCases_case.size));
+}
+
+TEST_2D(CodedStreamTest, WriteVarint64, kVarintCases, kBlockSizes) {
+ ArrayOutputStream output(buffer_, sizeof(buffer_), kBlockSizes_case);
+
+ {
+ CodedOutputStream coded_output(&output);
+
+ coded_output.WriteVarint64(kVarintCases_case.value);
+ EXPECT_FALSE(coded_output.HadError());
+
+ EXPECT_EQ(kVarintCases_case.size, coded_output.ByteCount());
+ }
+
+ EXPECT_EQ(kVarintCases_case.size, output.ByteCount());
+ EXPECT_EQ(0,
+ memcmp(buffer_, kVarintCases_case.bytes, kVarintCases_case.size));
+}
+
+// This test causes gcc 3.3.5 (and earlier?) to give the cryptic error:
+// "sorry, unimplemented: `method_call_expr' not supported by dump_expr"
+#if !defined(__GNUC__) || __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 3)
+
+int32 kSignExtendedVarintCases[] = {0, 1, -1, 1237894, -37895138};
+
+TEST_2D(CodedStreamTest, WriteVarint32SignExtended, kSignExtendedVarintCases,
+ kBlockSizes) {
+ ArrayOutputStream output(buffer_, sizeof(buffer_), kBlockSizes_case);
+
+ {
+ CodedOutputStream coded_output(&output);
+
+ coded_output.WriteVarint32SignExtended(kSignExtendedVarintCases_case);
+ EXPECT_FALSE(coded_output.HadError());
+
+ if (kSignExtendedVarintCases_case < 0) {
+ EXPECT_EQ(10, coded_output.ByteCount());
+ } else {
+ EXPECT_LE(coded_output.ByteCount(), 5);
+ }
+ }
+
+ if (kSignExtendedVarintCases_case < 0) {
+ EXPECT_EQ(10, output.ByteCount());
+ } else {
+ EXPECT_LE(output.ByteCount(), 5);
+ }
+
+ // Read value back in as a varint64 and insure it matches.
+ ArrayInputStream input(buffer_, sizeof(buffer_));
+
+ {
+ CodedInputStream coded_input(&input);
+
+ uint64 value;
+ EXPECT_TRUE(coded_input.ReadVarint64(&value));
+
+ EXPECT_EQ(kSignExtendedVarintCases_case, static_cast<int64>(value));
+ }
+
+ EXPECT_EQ(output.ByteCount(), input.ByteCount());
+}
+
+#endif
+
+
+// -------------------------------------------------------------------
+// Varint failure test.
+
+struct VarintErrorCase {
+ uint8 bytes[12];
+ int size;
+ bool can_parse;
+};
+
+inline std::ostream& operator<<(std::ostream& os, const VarintErrorCase& c) {
+ return os << "size " << c.size;
+}
+
+const VarintErrorCase kVarintErrorCases[] = {
+ // Control case. (Insures that there isn't something else wrong that
+ // makes parsing always fail.)
+ {{0x00}, 1, true},
+
+ // No input data.
+ {{}, 0, false},
+
+ // Input ends unexpectedly.
+ {{0xf0, 0xab}, 2, false},
+
+ // Input ends unexpectedly after 32 bits.
+ {{0xf0, 0xab, 0xc9, 0x9a, 0xf8, 0xb2}, 6, false},
+
+ // Longer than 10 bytes.
+ {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01},
+ 11,
+ false},
+};
+
+TEST_2D(CodedStreamTest, ReadVarint32Error, kVarintErrorCases, kBlockSizes) {
+ memcpy(buffer_, kVarintErrorCases_case.bytes, kVarintErrorCases_case.size);
+ ArrayInputStream input(buffer_, kVarintErrorCases_case.size,
+ kBlockSizes_case);
+ CodedInputStream coded_input(&input);
+
+ uint32 value;
+ EXPECT_EQ(kVarintErrorCases_case.can_parse, coded_input.ReadVarint32(&value));
+}
+
+TEST_2D(CodedStreamTest, ReadVarint32Error_LeavesValueInInitializedState,
+ kVarintErrorCases, kBlockSizes) {
+ memcpy(buffer_, kVarintErrorCases_case.bytes, kVarintErrorCases_case.size);
+ ArrayInputStream input(buffer_, kVarintErrorCases_case.size,
+ kBlockSizes_case);
+ CodedInputStream coded_input(&input);
+
+ uint32 value = 0;
+ EXPECT_EQ(kVarintErrorCases_case.can_parse, coded_input.ReadVarint32(&value));
+ // While the specific value following a failure is not critical, we do want to
+ // ensure that it doesn't get set to an uninitialized value. (This check fails
+ // in MSAN mode if value has been set to an uninitialized value.)
+ EXPECT_EQ(value, value);
+}
+
+TEST_2D(CodedStreamTest, ReadVarint64Error, kVarintErrorCases, kBlockSizes) {
+ memcpy(buffer_, kVarintErrorCases_case.bytes, kVarintErrorCases_case.size);
+ ArrayInputStream input(buffer_, kVarintErrorCases_case.size,
+ kBlockSizes_case);
+ CodedInputStream coded_input(&input);
+
+ uint64 value;
+ EXPECT_EQ(kVarintErrorCases_case.can_parse, coded_input.ReadVarint64(&value));
+}
+
+TEST_2D(CodedStreamTest, ReadVarint64Error_LeavesValueInInitializedState,
+ kVarintErrorCases, kBlockSizes) {
+ memcpy(buffer_, kVarintErrorCases_case.bytes, kVarintErrorCases_case.size);
+ ArrayInputStream input(buffer_, kVarintErrorCases_case.size,
+ kBlockSizes_case);
+ CodedInputStream coded_input(&input);
+
+ uint64 value = 0;
+ EXPECT_EQ(kVarintErrorCases_case.can_parse, coded_input.ReadVarint64(&value));
+ // While the specific value following a failure is not critical, we do want to
+ // ensure that it doesn't get set to an uninitialized value. (This check fails
+ // in MSAN mode if value has been set to an uninitialized value.)
+ EXPECT_EQ(value, value);
+}
+
+// -------------------------------------------------------------------
+// VarintSize
+
+struct VarintSizeCase {
+ uint64 value;
+ int size;
+};
+
+inline std::ostream& operator<<(std::ostream& os, const VarintSizeCase& c) {
+ return os << c.value;
+}
+
+VarintSizeCase kVarintSizeCases[] = {
+ {0u, 1},
+ {1u, 1},
+ {127u, 1},
+ {128u, 2},
+ {758923u, 3},
+ {4000000000u, 5},
+ {uint64_t{41256202580718336u}, 8},
+ {uint64_t{11964378330978735131u}, 10},
+};
+
+TEST_1D(CodedStreamTest, VarintSize32, kVarintSizeCases) {
+ if (kVarintSizeCases_case.value > 0xffffffffu) {
+ // Skip 64-bit values.
+ return;
+ }
+
+ EXPECT_EQ(kVarintSizeCases_case.size,
+ CodedOutputStream::VarintSize32(
+ static_cast<uint32>(kVarintSizeCases_case.value)));
+}
+
+TEST_1D(CodedStreamTest, VarintSize64, kVarintSizeCases) {
+ EXPECT_EQ(kVarintSizeCases_case.size,
+ CodedOutputStream::VarintSize64(kVarintSizeCases_case.value));
+}
+
+TEST_F(CodedStreamTest, VarintSize32PowersOfTwo) {
+ int expected = 1;
+ for (int i = 1; i < 32; i++) {
+ if (i % 7 == 0) {
+ expected += 1;
+ }
+ EXPECT_EQ(expected,
+ CodedOutputStream::VarintSize32(static_cast<uint32>(0x1u << i)));
+ }
+}
+
+TEST_F(CodedStreamTest, VarintSize64PowersOfTwo) {
+ int expected = 1;
+ for (int i = 1; i < 64; i++) {
+ if (i % 7 == 0) {
+ expected += 1;
+ }
+ EXPECT_EQ(expected, CodedOutputStream::VarintSize64(
+ static_cast<uint64>(0x1ull << i)));
+ }
+}
+
+// -------------------------------------------------------------------
+// Fixed-size int tests
+
+struct Fixed32Case {
+ uint8 bytes[sizeof(uint32)]; // Encoded bytes.
+ uint32 value; // Parsed value.
+};
+
+struct Fixed64Case {
+ uint8 bytes[sizeof(uint64)]; // Encoded bytes.
+ uint64 value; // Parsed value.
+};
+
+inline std::ostream& operator<<(std::ostream& os, const Fixed32Case& c) {
+ return os << "0x" << std::hex << c.value << std::dec;
+}
+
+inline std::ostream& operator<<(std::ostream& os, const Fixed64Case& c) {
+ return os << "0x" << std::hex << c.value << std::dec;
+}
+
+Fixed32Case kFixed32Cases[] = {
+ {{0xef, 0xcd, 0xab, 0x90}, 0x90abcdefu},
+ {{0x12, 0x34, 0x56, 0x78}, 0x78563412u},
+};
+
+Fixed64Case kFixed64Cases[] = {
+ {{0xef, 0xcd, 0xab, 0x90, 0x12, 0x34, 0x56, 0x78},
+ uint64_t{0x7856341290abcdefu}},
+ {{0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88},
+ uint64_t{0x8877665544332211u}},
+};
+
+TEST_2D(CodedStreamTest, ReadLittleEndian32, kFixed32Cases, kBlockSizes) {
+ memcpy(buffer_, kFixed32Cases_case.bytes, sizeof(kFixed32Cases_case.bytes));
+ ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case);
+
+ {
+ CodedInputStream coded_input(&input);
+
+ uint32 value;
+ EXPECT_TRUE(coded_input.ReadLittleEndian32(&value));
+ EXPECT_EQ(kFixed32Cases_case.value, value);
+ }
+
+ EXPECT_EQ(sizeof(uint32), input.ByteCount());
+}
+
+TEST_2D(CodedStreamTest, ReadLittleEndian64, kFixed64Cases, kBlockSizes) {
+ memcpy(buffer_, kFixed64Cases_case.bytes, sizeof(kFixed64Cases_case.bytes));
+ ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case);
+
+ {
+ CodedInputStream coded_input(&input);
+
+ uint64 value;
+ EXPECT_TRUE(coded_input.ReadLittleEndian64(&value));
+ EXPECT_EQ(kFixed64Cases_case.value, value);
+ }
+
+ EXPECT_EQ(sizeof(uint64), input.ByteCount());
+}
+
+TEST_2D(CodedStreamTest, WriteLittleEndian32, kFixed32Cases, kBlockSizes) {
+ ArrayOutputStream output(buffer_, sizeof(buffer_), kBlockSizes_case);
+
+ {
+ CodedOutputStream coded_output(&output);
+
+ coded_output.WriteLittleEndian32(kFixed32Cases_case.value);
+ EXPECT_FALSE(coded_output.HadError());
+
+ EXPECT_EQ(sizeof(uint32), coded_output.ByteCount());
+ }
+
+ EXPECT_EQ(sizeof(uint32), output.ByteCount());
+ EXPECT_EQ(0, memcmp(buffer_, kFixed32Cases_case.bytes, sizeof(uint32)));
+}
+
+TEST_2D(CodedStreamTest, WriteLittleEndian64, kFixed64Cases, kBlockSizes) {
+ ArrayOutputStream output(buffer_, sizeof(buffer_), kBlockSizes_case);
+
+ {
+ CodedOutputStream coded_output(&output);
+
+ coded_output.WriteLittleEndian64(kFixed64Cases_case.value);
+ EXPECT_FALSE(coded_output.HadError());
+
+ EXPECT_EQ(sizeof(uint64), coded_output.ByteCount());
+ }
+
+ EXPECT_EQ(sizeof(uint64), output.ByteCount());
+ EXPECT_EQ(0, memcmp(buffer_, kFixed64Cases_case.bytes, sizeof(uint64)));
+}
+
+// Tests using the static methods to read fixed-size values from raw arrays.
+
+TEST_1D(CodedStreamTest, ReadLittleEndian32FromArray, kFixed32Cases) {
+ memcpy(buffer_, kFixed32Cases_case.bytes, sizeof(kFixed32Cases_case.bytes));
+
+ uint32 value;
+ const uint8* end =
+ CodedInputStream::ReadLittleEndian32FromArray(buffer_, &value);
+ EXPECT_EQ(kFixed32Cases_case.value, value);
+ EXPECT_TRUE(end == buffer_ + sizeof(value));
+}
+
+TEST_1D(CodedStreamTest, ReadLittleEndian64FromArray, kFixed64Cases) {
+ memcpy(buffer_, kFixed64Cases_case.bytes, sizeof(kFixed64Cases_case.bytes));
+
+ uint64 value;
+ const uint8* end =
+ CodedInputStream::ReadLittleEndian64FromArray(buffer_, &value);
+ EXPECT_EQ(kFixed64Cases_case.value, value);
+ EXPECT_TRUE(end == buffer_ + sizeof(value));
+}
+
+// -------------------------------------------------------------------
+// Raw reads and writes
+
+const char kRawBytes[] = "Some bytes which will be written and read raw.";
+
+TEST_1D(CodedStreamTest, ReadRaw, kBlockSizes) {
+ memcpy(buffer_, kRawBytes, sizeof(kRawBytes));
+ ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case);
+ char read_buffer[sizeof(kRawBytes)];
+
+ {
+ CodedInputStream coded_input(&input);
+
+ EXPECT_TRUE(coded_input.ReadRaw(read_buffer, sizeof(kRawBytes)));
+ EXPECT_EQ(0, memcmp(kRawBytes, read_buffer, sizeof(kRawBytes)));
+ }
+
+ EXPECT_EQ(sizeof(kRawBytes), input.ByteCount());
+}
+
+TEST_1D(CodedStreamTest, WriteRaw, kBlockSizes) {
+ ArrayOutputStream output(buffer_, sizeof(buffer_), kBlockSizes_case);
+
+ {
+ CodedOutputStream coded_output(&output);
+
+ coded_output.WriteRaw(kRawBytes, sizeof(kRawBytes));
+ EXPECT_FALSE(coded_output.HadError());
+
+ EXPECT_EQ(sizeof(kRawBytes), coded_output.ByteCount());
+ }
+
+ EXPECT_EQ(sizeof(kRawBytes), output.ByteCount());
+ EXPECT_EQ(0, memcmp(buffer_, kRawBytes, sizeof(kRawBytes)));
+}
+
+TEST_1D(CodedStreamTest, ReadString, kBlockSizes) {
+ memcpy(buffer_, kRawBytes, sizeof(kRawBytes));
+ ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case);
+
+ {
+ CodedInputStream coded_input(&input);
+
+ std::string str;
+ EXPECT_TRUE(coded_input.ReadString(&str, strlen(kRawBytes)));
+ EXPECT_EQ(kRawBytes, str);
+ }
+
+ EXPECT_EQ(strlen(kRawBytes), input.ByteCount());
+}
+
+// Check to make sure ReadString doesn't crash on impossibly large strings.
+TEST_1D(CodedStreamTest, ReadStringImpossiblyLarge, kBlockSizes) {
+ ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case);
+
+ {
+ CodedInputStream coded_input(&input);
+
+ std::string str;
+ // Try to read a gigabyte.
+ EXPECT_FALSE(coded_input.ReadString(&str, 1 << 30));
+ }
+}
+
+TEST_F(CodedStreamTest, ReadStringImpossiblyLargeFromStringOnStack) {
+ // Same test as above, except directly use a buffer. This used to cause
+ // crashes while the above did not.
+ uint8 buffer[8];
+ CodedInputStream coded_input(buffer, 8);
+ std::string str;
+ EXPECT_FALSE(coded_input.ReadString(&str, 1 << 30));
+}
+
+TEST_F(CodedStreamTest, ReadStringImpossiblyLargeFromStringOnHeap) {
+ std::unique_ptr<uint8[]> buffer(new uint8[8]);
+ CodedInputStream coded_input(buffer.get(), 8);
+ std::string str;
+ EXPECT_FALSE(coded_input.ReadString(&str, 1 << 30));
+}
+
+TEST_1D(CodedStreamTest, ReadStringReservesMemoryOnTotalLimit, kBlockSizes) {
+ memcpy(buffer_, kRawBytes, sizeof(kRawBytes));
+ ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case);
+
+ {
+ CodedInputStream coded_input(&input);
+ coded_input.SetTotalBytesLimit(sizeof(kRawBytes));
+ EXPECT_EQ(sizeof(kRawBytes), coded_input.BytesUntilTotalBytesLimit());
+
+ std::string str;
+ EXPECT_TRUE(coded_input.ReadString(&str, strlen(kRawBytes)));
+ EXPECT_EQ(sizeof(kRawBytes) - strlen(kRawBytes),
+ coded_input.BytesUntilTotalBytesLimit());
+ EXPECT_EQ(kRawBytes, str);
+ // TODO(liujisi): Replace with a more meaningful test (see cl/60966023).
+ EXPECT_GE(str.capacity(), strlen(kRawBytes));
+ }
+
+ EXPECT_EQ(strlen(kRawBytes), input.ByteCount());
+}
+
+TEST_1D(CodedStreamTest, ReadStringReservesMemoryOnPushedLimit, kBlockSizes) {
+ memcpy(buffer_, kRawBytes, sizeof(kRawBytes));
+ ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case);
+
+ {
+ CodedInputStream coded_input(&input);
+ coded_input.PushLimit(sizeof(buffer_));
+
+ std::string str;
+ EXPECT_TRUE(coded_input.ReadString(&str, strlen(kRawBytes)));
+ EXPECT_EQ(kRawBytes, str);
+ // TODO(liujisi): Replace with a more meaningful test (see cl/60966023).
+ EXPECT_GE(str.capacity(), strlen(kRawBytes));
+ }
+
+ EXPECT_EQ(strlen(kRawBytes), input.ByteCount());
+}
+
+TEST_F(CodedStreamTest, ReadStringNoReservationIfLimitsNotSet) {
+ memcpy(buffer_, kRawBytes, sizeof(kRawBytes));
+ // Buffer size in the input must be smaller than sizeof(kRawBytes),
+ // otherwise check against capacity will fail as ReadStringInline()
+ // will handle the reading and will reserve the memory as needed.
+ ArrayInputStream input(buffer_, sizeof(buffer_), 32);
+
+ {
+ CodedInputStream coded_input(&input);
+
+ std::string str;
+ EXPECT_TRUE(coded_input.ReadString(&str, strlen(kRawBytes)));
+ EXPECT_EQ(kRawBytes, str);
+ // Note: this check depends on string class implementation. It
+ // expects that string will allocate more than strlen(kRawBytes)
+ // if the content of kRawBytes is appended to string in small
+ // chunks.
+ // TODO(liujisi): Replace with a more meaningful test (see cl/60966023).
+ EXPECT_GE(str.capacity(), strlen(kRawBytes));
+ }
+
+ EXPECT_EQ(strlen(kRawBytes), input.ByteCount());
+}
+
+TEST_F(CodedStreamTest, ReadStringNoReservationSizeIsNegative) {
+ memcpy(buffer_, kRawBytes, sizeof(kRawBytes));
+ // Buffer size in the input must be smaller than sizeof(kRawBytes),
+ // otherwise check against capacity will fail as ReadStringInline()
+ // will handle the reading and will reserve the memory as needed.
+ ArrayInputStream input(buffer_, sizeof(buffer_), 32);
+
+ {
+ CodedInputStream coded_input(&input);
+ coded_input.PushLimit(sizeof(buffer_));
+
+ std::string str;
+ EXPECT_FALSE(coded_input.ReadString(&str, -1));
+ // Note: this check depends on string class implementation. It
+ // expects that string will always allocate the same amount of
+ // memory for an empty string.
+ EXPECT_EQ(std::string().capacity(), str.capacity());
+ }
+}
+
+TEST_F(CodedStreamTest, ReadStringNoReservationSizeIsLarge) {
+ memcpy(buffer_, kRawBytes, sizeof(kRawBytes));
+ // Buffer size in the input must be smaller than sizeof(kRawBytes),
+ // otherwise check against capacity will fail as ReadStringInline()
+ // will handle the reading and will reserve the memory as needed.
+ ArrayInputStream input(buffer_, sizeof(buffer_), 32);
+
+ {
+ CodedInputStream coded_input(&input);
+ coded_input.PushLimit(sizeof(buffer_));
+
+ std::string str;
+ EXPECT_FALSE(coded_input.ReadString(&str, 1 << 30));
+ EXPECT_GT(1 << 30, str.capacity());
+ }
+}
+
+TEST_F(CodedStreamTest, ReadStringNoReservationSizeIsOverTheLimit) {
+ memcpy(buffer_, kRawBytes, sizeof(kRawBytes));
+ // Buffer size in the input must be smaller than sizeof(kRawBytes),
+ // otherwise check against capacity will fail as ReadStringInline()
+ // will handle the reading and will reserve the memory as needed.
+ ArrayInputStream input(buffer_, sizeof(buffer_), 32);
+
+ {
+ CodedInputStream coded_input(&input);
+ coded_input.PushLimit(16);
+
+ std::string str;
+ EXPECT_FALSE(coded_input.ReadString(&str, strlen(kRawBytes)));
+ // Note: this check depends on string class implementation. It
+ // expects that string will allocate less than strlen(kRawBytes)
+ // for an empty string.
+ EXPECT_GT(strlen(kRawBytes), str.capacity());
+ }
+}
+
+TEST_F(CodedStreamTest, ReadStringNoReservationSizeIsOverTheTotalBytesLimit) {
+ memcpy(buffer_, kRawBytes, sizeof(kRawBytes));
+ // Buffer size in the input must be smaller than sizeof(kRawBytes),
+ // otherwise check against capacity will fail as ReadStringInline()
+ // will handle the reading and will reserve the memory as needed.
+ ArrayInputStream input(buffer_, sizeof(buffer_), 32);
+
+ {
+ CodedInputStream coded_input(&input);
+ coded_input.SetTotalBytesLimit(16);
+
+ std::string str;
+ EXPECT_FALSE(coded_input.ReadString(&str, strlen(kRawBytes)));
+ // Note: this check depends on string class implementation. It
+ // expects that string will allocate less than strlen(kRawBytes)
+ // for an empty string.
+ EXPECT_GT(strlen(kRawBytes), str.capacity());
+ }
+}
+
+TEST_F(CodedStreamTest,
+ ReadStringNoReservationSizeIsOverTheClosestLimit_GlobalLimitIsCloser) {
+ memcpy(buffer_, kRawBytes, sizeof(kRawBytes));
+ // Buffer size in the input must be smaller than sizeof(kRawBytes),
+ // otherwise check against capacity will fail as ReadStringInline()
+ // will handle the reading and will reserve the memory as needed.
+ ArrayInputStream input(buffer_, sizeof(buffer_), 32);
+
+ {
+ CodedInputStream coded_input(&input);
+ coded_input.PushLimit(sizeof(buffer_));
+ coded_input.SetTotalBytesLimit(16);
+
+ std::string str;
+ EXPECT_FALSE(coded_input.ReadString(&str, strlen(kRawBytes)));
+ // Note: this check depends on string class implementation. It
+ // expects that string will allocate less than strlen(kRawBytes)
+ // for an empty string.
+ EXPECT_GT(strlen(kRawBytes), str.capacity());
+ }
+}
+
+TEST_F(CodedStreamTest,
+ ReadStringNoReservationSizeIsOverTheClosestLimit_LocalLimitIsCloser) {
+ memcpy(buffer_, kRawBytes, sizeof(kRawBytes));
+ // Buffer size in the input must be smaller than sizeof(kRawBytes),
+ // otherwise check against capacity will fail as ReadStringInline()
+ // will handle the reading and will reserve the memory as needed.
+ ArrayInputStream input(buffer_, sizeof(buffer_), 32);
+
+ {
+ CodedInputStream coded_input(&input);
+ coded_input.PushLimit(16);
+ coded_input.SetTotalBytesLimit(sizeof(buffer_));
+ EXPECT_EQ(sizeof(buffer_), coded_input.BytesUntilTotalBytesLimit());
+
+ std::string str;
+ EXPECT_FALSE(coded_input.ReadString(&str, strlen(kRawBytes)));
+ // Note: this check depends on string class implementation. It
+ // expects that string will allocate less than strlen(kRawBytes)
+ // for an empty string.
+ EXPECT_GT(strlen(kRawBytes), str.capacity());
+ }
+}
+
+
+// -------------------------------------------------------------------
+// Skip
+
+const char kSkipTestBytes[] =
+ "<Before skipping><To be skipped><After skipping>";
+
+TEST_1D(CodedStreamTest, SkipInput, kBlockSizes) {
+ memcpy(buffer_, kSkipTestBytes, sizeof(kSkipTestBytes));
+ ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case);
+
+ {
+ CodedInputStream coded_input(&input);
+
+ std::string str;
+ EXPECT_TRUE(coded_input.ReadString(&str, strlen("<Before skipping>")));
+ EXPECT_EQ("<Before skipping>", str);
+ EXPECT_TRUE(coded_input.Skip(strlen("<To be skipped>")));
+ EXPECT_TRUE(coded_input.ReadString(&str, strlen("<After skipping>")));
+ EXPECT_EQ("<After skipping>", str);
+ }
+
+ EXPECT_EQ(strlen(kSkipTestBytes), input.ByteCount());
+}
+
+// -------------------------------------------------------------------
+// GetDirectBufferPointer
+
+TEST_F(CodedStreamTest, GetDirectBufferPointerInput) {
+ ArrayInputStream input(buffer_, sizeof(buffer_), 8);
+ CodedInputStream coded_input(&input);
+
+ const void* ptr;
+ int size;
+
+ EXPECT_TRUE(coded_input.GetDirectBufferPointer(&ptr, &size));
+ EXPECT_EQ(buffer_, ptr);
+ EXPECT_EQ(8, size);
+
+ // Peeking again should return the same pointer.
+ EXPECT_TRUE(coded_input.GetDirectBufferPointer(&ptr, &size));
+ EXPECT_EQ(buffer_, ptr);
+ EXPECT_EQ(8, size);
+
+ // Skip forward in the same buffer then peek again.
+ EXPECT_TRUE(coded_input.Skip(3));
+ EXPECT_TRUE(coded_input.GetDirectBufferPointer(&ptr, &size));
+ EXPECT_EQ(buffer_ + 3, ptr);
+ EXPECT_EQ(5, size);
+
+ // Skip to end of buffer and peek -- should get next buffer.
+ EXPECT_TRUE(coded_input.Skip(5));
+ EXPECT_TRUE(coded_input.GetDirectBufferPointer(&ptr, &size));
+ EXPECT_EQ(buffer_ + 8, ptr);
+ EXPECT_EQ(8, size);
+}
+
+TEST_F(CodedStreamTest, GetDirectBufferPointerInlineInput) {
+ ArrayInputStream input(buffer_, sizeof(buffer_), 8);
+ CodedInputStream coded_input(&input);
+
+ const void* ptr;
+ int size;
+
+ coded_input.GetDirectBufferPointerInline(&ptr, &size);
+ EXPECT_EQ(buffer_, ptr);
+ EXPECT_EQ(8, size);
+
+ // Peeking again should return the same pointer.
+ coded_input.GetDirectBufferPointerInline(&ptr, &size);
+ EXPECT_EQ(buffer_, ptr);
+ EXPECT_EQ(8, size);
+
+ // Skip forward in the same buffer then peek again.
+ EXPECT_TRUE(coded_input.Skip(3));
+ coded_input.GetDirectBufferPointerInline(&ptr, &size);
+ EXPECT_EQ(buffer_ + 3, ptr);
+ EXPECT_EQ(5, size);
+
+ // Skip to end of buffer and peek -- should return false and provide an empty
+ // buffer. It does not try to Refresh().
+ EXPECT_TRUE(coded_input.Skip(5));
+ coded_input.GetDirectBufferPointerInline(&ptr, &size);
+ EXPECT_EQ(buffer_ + 8, ptr);
+ EXPECT_EQ(0, size);
+}
+
+// -------------------------------------------------------------------
+// Limits
+
+TEST_1D(CodedStreamTest, BasicLimit, kBlockSizes) {
+ ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case);
+
+ {
+ CodedInputStream coded_input(&input);
+
+ EXPECT_EQ(-1, coded_input.BytesUntilLimit());
+ CodedInputStream::Limit limit = coded_input.PushLimit(8);
+
+ // Read until we hit the limit.
+ uint32 value;
+ EXPECT_EQ(8, coded_input.BytesUntilLimit());
+ EXPECT_TRUE(coded_input.ReadLittleEndian32(&value));
+ EXPECT_EQ(4, coded_input.BytesUntilLimit());
+ EXPECT_TRUE(coded_input.ReadLittleEndian32(&value));
+ EXPECT_EQ(0, coded_input.BytesUntilLimit());
+ EXPECT_FALSE(coded_input.ReadLittleEndian32(&value));
+ EXPECT_EQ(0, coded_input.BytesUntilLimit());
+
+ coded_input.PopLimit(limit);
+
+ EXPECT_EQ(-1, coded_input.BytesUntilLimit());
+ EXPECT_TRUE(coded_input.ReadLittleEndian32(&value));
+ }
+
+ EXPECT_EQ(12, input.ByteCount());
+}
+
+// Test what happens when we push two limits where the second (top) one is
+// shorter.
+TEST_1D(CodedStreamTest, SmallLimitOnTopOfBigLimit, kBlockSizes) {
+ ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case);
+
+ {
+ CodedInputStream coded_input(&input);
+
+ EXPECT_EQ(-1, coded_input.BytesUntilLimit());
+ CodedInputStream::Limit limit1 = coded_input.PushLimit(8);
+ EXPECT_EQ(8, coded_input.BytesUntilLimit());
+ CodedInputStream::Limit limit2 = coded_input.PushLimit(4);
+
+ uint32 value;
+
+ // Read until we hit limit2, the top and shortest limit.
+ EXPECT_EQ(4, coded_input.BytesUntilLimit());
+ EXPECT_TRUE(coded_input.ReadLittleEndian32(&value));
+ EXPECT_EQ(0, coded_input.BytesUntilLimit());
+ EXPECT_FALSE(coded_input.ReadLittleEndian32(&value));
+ EXPECT_EQ(0, coded_input.BytesUntilLimit());
+
+ coded_input.PopLimit(limit2);
+
+ // Read until we hit limit1.
+ EXPECT_EQ(4, coded_input.BytesUntilLimit());
+ EXPECT_TRUE(coded_input.ReadLittleEndian32(&value));
+ EXPECT_EQ(0, coded_input.BytesUntilLimit());
+ EXPECT_FALSE(coded_input.ReadLittleEndian32(&value));
+ EXPECT_EQ(0, coded_input.BytesUntilLimit());
+
+ coded_input.PopLimit(limit1);
+
+ // No more limits.
+ EXPECT_EQ(-1, coded_input.BytesUntilLimit());
+ EXPECT_TRUE(coded_input.ReadLittleEndian32(&value));
+ }
+
+ EXPECT_EQ(12, input.ByteCount());
+}
+
+// Test what happens when we push two limits where the second (top) one is
+// longer. In this case, the top limit is shortened to match the previous
+// limit.
+TEST_1D(CodedStreamTest, BigLimitOnTopOfSmallLimit, kBlockSizes) {
+ ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case);
+
+ {
+ CodedInputStream coded_input(&input);
+
+ EXPECT_EQ(-1, coded_input.BytesUntilLimit());
+ CodedInputStream::Limit limit1 = coded_input.PushLimit(4);
+ EXPECT_EQ(4, coded_input.BytesUntilLimit());
+ CodedInputStream::Limit limit2 = coded_input.PushLimit(8);
+
+ uint32 value;
+
+ // Read until we hit limit2. Except, wait! limit1 is shorter, so
+ // we end up hitting that first, despite having 4 bytes to go on
+ // limit2.
+ EXPECT_EQ(4, coded_input.BytesUntilLimit());
+ EXPECT_TRUE(coded_input.ReadLittleEndian32(&value));
+ EXPECT_EQ(0, coded_input.BytesUntilLimit());
+ EXPECT_FALSE(coded_input.ReadLittleEndian32(&value));
+ EXPECT_EQ(0, coded_input.BytesUntilLimit());
+
+ coded_input.PopLimit(limit2);
+
+ // OK, popped limit2, now limit1 is on top, which we've already hit.
+ EXPECT_EQ(0, coded_input.BytesUntilLimit());
+ EXPECT_FALSE(coded_input.ReadLittleEndian32(&value));
+ EXPECT_EQ(0, coded_input.BytesUntilLimit());
+
+ coded_input.PopLimit(limit1);
+
+ // No more limits.
+ EXPECT_EQ(-1, coded_input.BytesUntilLimit());
+ EXPECT_TRUE(coded_input.ReadLittleEndian32(&value));
+ }
+
+ EXPECT_EQ(8, input.ByteCount());
+}
+
+TEST_F(CodedStreamTest, ExpectAtEnd) {
+ // Test ExpectAtEnd(), which is based on limits.
+ ArrayInputStream input(buffer_, sizeof(buffer_));
+ CodedInputStream coded_input(&input);
+
+ EXPECT_FALSE(coded_input.ExpectAtEnd());
+
+ CodedInputStream::Limit limit = coded_input.PushLimit(4);
+
+ uint32 value;
+ EXPECT_TRUE(coded_input.ReadLittleEndian32(&value));
+ EXPECT_TRUE(coded_input.ExpectAtEnd());
+
+ coded_input.PopLimit(limit);
+ EXPECT_FALSE(coded_input.ExpectAtEnd());
+}
+
+TEST_F(CodedStreamTest, NegativeLimit) {
+ // Check what happens when we push a negative limit.
+ ArrayInputStream input(buffer_, sizeof(buffer_));
+ CodedInputStream coded_input(&input);
+
+ CodedInputStream::Limit limit = coded_input.PushLimit(-1234);
+ // BytesUntilLimit() returns -1 to mean "no limit", which actually means
+ // "the limit is INT_MAX relative to the beginning of the stream".
+ EXPECT_EQ(-1, coded_input.BytesUntilLimit());
+ coded_input.PopLimit(limit);
+}
+
+TEST_F(CodedStreamTest, NegativeLimitAfterReading) {
+ // Check what happens when we push a negative limit.
+ ArrayInputStream input(buffer_, sizeof(buffer_));
+ CodedInputStream coded_input(&input);
+ ASSERT_TRUE(coded_input.Skip(128));
+
+ CodedInputStream::Limit limit = coded_input.PushLimit(-64);
+ // BytesUntilLimit() returns -1 to mean "no limit", which actually means
+ // "the limit is INT_MAX relative to the beginning of the stream".
+ EXPECT_EQ(-1, coded_input.BytesUntilLimit());
+ coded_input.PopLimit(limit);
+}
+
+TEST_F(CodedStreamTest, OverflowLimit) {
+ // Check what happens when we push a limit large enough that its absolute
+ // position is more than 2GB into the stream.
+ ArrayInputStream input(buffer_, sizeof(buffer_));
+ CodedInputStream coded_input(&input);
+ ASSERT_TRUE(coded_input.Skip(128));
+
+ CodedInputStream::Limit limit = coded_input.PushLimit(INT_MAX);
+ // BytesUntilLimit() returns -1 to mean "no limit", which actually means
+ // "the limit is INT_MAX relative to the beginning of the stream".
+ EXPECT_EQ(-1, coded_input.BytesUntilLimit());
+ coded_input.PopLimit(limit);
+}
+
+TEST_F(CodedStreamTest, TotalBytesLimit) {
+ ArrayInputStream input(buffer_, sizeof(buffer_));
+ CodedInputStream coded_input(&input);
+ coded_input.SetTotalBytesLimit(16);
+ EXPECT_EQ(16, coded_input.BytesUntilTotalBytesLimit());
+
+ std::string str;
+ EXPECT_TRUE(coded_input.ReadString(&str, 16));
+ EXPECT_EQ(0, coded_input.BytesUntilTotalBytesLimit());
+
+ std::vector<std::string> errors;
+
+ {
+ ScopedMemoryLog error_log;
+ EXPECT_FALSE(coded_input.ReadString(&str, 1));
+ errors = error_log.GetMessages(ERROR);
+ }
+
+ ASSERT_EQ(1, errors.size());
+ EXPECT_PRED_FORMAT2(testing::IsSubstring,
+ "A protocol message was rejected because it was too big",
+ errors[0]);
+
+ coded_input.SetTotalBytesLimit(32);
+ EXPECT_EQ(16, coded_input.BytesUntilTotalBytesLimit());
+ EXPECT_TRUE(coded_input.ReadString(&str, 16));
+ EXPECT_EQ(0, coded_input.BytesUntilTotalBytesLimit());
+}
+
+TEST_F(CodedStreamTest, TotalBytesLimitNotValidMessageEnd) {
+ // total_bytes_limit_ is not a valid place for a message to end.
+
+ ArrayInputStream input(buffer_, sizeof(buffer_));
+ CodedInputStream coded_input(&input);
+
+ // Set both total_bytes_limit and a regular limit at 16 bytes.
+ coded_input.SetTotalBytesLimit(16);
+ CodedInputStream::Limit limit = coded_input.PushLimit(16);
+
+ // Read 16 bytes.
+ std::string str;
+ EXPECT_TRUE(coded_input.ReadString(&str, 16));
+
+ // Read a tag. Should fail, but report being a valid endpoint since it's
+ // a regular limit.
+ EXPECT_EQ(0, coded_input.ReadTagNoLastTag());
+ EXPECT_TRUE(coded_input.ConsumedEntireMessage());
+
+ // Pop the limit.
+ coded_input.PopLimit(limit);
+
+ // Read a tag. Should fail, and report *not* being a valid endpoint, since
+ // this time we're hitting the total bytes limit.
+ EXPECT_EQ(0, coded_input.ReadTagNoLastTag());
+ EXPECT_FALSE(coded_input.ConsumedEntireMessage());
+}
+
+TEST_F(CodedStreamTest, RecursionLimit) {
+ ArrayInputStream input(buffer_, sizeof(buffer_));
+ CodedInputStream coded_input(&input);
+ coded_input.SetRecursionLimit(4);
+
+ // This is way too much testing for a counter.
+ EXPECT_TRUE(coded_input.IncrementRecursionDepth()); // 1
+ EXPECT_TRUE(coded_input.IncrementRecursionDepth()); // 2
+ EXPECT_TRUE(coded_input.IncrementRecursionDepth()); // 3
+ EXPECT_TRUE(coded_input.IncrementRecursionDepth()); // 4
+ EXPECT_FALSE(coded_input.IncrementRecursionDepth()); // 5
+ EXPECT_FALSE(coded_input.IncrementRecursionDepth()); // 6
+ coded_input.DecrementRecursionDepth(); // 5
+ EXPECT_FALSE(coded_input.IncrementRecursionDepth()); // 6
+ coded_input.DecrementRecursionDepth(); // 5
+ coded_input.DecrementRecursionDepth(); // 4
+ coded_input.DecrementRecursionDepth(); // 3
+ EXPECT_TRUE(coded_input.IncrementRecursionDepth()); // 4
+ EXPECT_FALSE(coded_input.IncrementRecursionDepth()); // 5
+ coded_input.DecrementRecursionDepth(); // 4
+ coded_input.DecrementRecursionDepth(); // 3
+ coded_input.DecrementRecursionDepth(); // 2
+ coded_input.DecrementRecursionDepth(); // 1
+ coded_input.DecrementRecursionDepth(); // 0
+ coded_input.DecrementRecursionDepth(); // 0
+ coded_input.DecrementRecursionDepth(); // 0
+ EXPECT_TRUE(coded_input.IncrementRecursionDepth()); // 1
+ EXPECT_TRUE(coded_input.IncrementRecursionDepth()); // 2
+ EXPECT_TRUE(coded_input.IncrementRecursionDepth()); // 3
+ EXPECT_TRUE(coded_input.IncrementRecursionDepth()); // 4
+ EXPECT_FALSE(coded_input.IncrementRecursionDepth()); // 5
+
+ coded_input.SetRecursionLimit(6);
+ EXPECT_TRUE(coded_input.IncrementRecursionDepth()); // 6
+ EXPECT_FALSE(coded_input.IncrementRecursionDepth()); // 7
+}
+
+
+class ReallyBigInputStream : public ZeroCopyInputStream {
+ public:
+ ReallyBigInputStream() : backup_amount_(0), buffer_count_(0) {}
+ ~ReallyBigInputStream() {}
+
+ // implements ZeroCopyInputStream ----------------------------------
+ bool Next(const void** data, int* size) override {
+ // We only expect BackUp() to be called at the end.
+ EXPECT_EQ(0, backup_amount_);
+
+ switch (buffer_count_++) {
+ case 0:
+ *data = buffer_;
+ *size = sizeof(buffer_);
+ return true;
+ case 1:
+ // Return an enormously large buffer that, when combined with the 1k
+ // returned already, should overflow the total_bytes_read_ counter in
+ // CodedInputStream. Note that we'll only read the first 1024 bytes
+ // of this buffer so it's OK that we have it point at buffer_.
+ *data = buffer_;
+ *size = INT_MAX;
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ void BackUp(int count) override { backup_amount_ = count; }
+
+ bool Skip(int count) override {
+ GOOGLE_LOG(FATAL) << "Not implemented.";
+ return false;
+ }
+ int64_t ByteCount() const override {
+ GOOGLE_LOG(FATAL) << "Not implemented.";
+ return 0;
+ }
+
+ int backup_amount_;
+
+ private:
+ char buffer_[1024];
+ int64 buffer_count_;
+};
+
+TEST_F(CodedStreamTest, InputOver2G) {
+ // CodedInputStream should gracefully handle input over 2G and call
+ // input.BackUp() with the correct number of bytes on destruction.
+ ReallyBigInputStream input;
+
+ std::vector<std::string> errors;
+
+ {
+ ScopedMemoryLog error_log;
+ CodedInputStream coded_input(&input);
+ std::string str;
+ EXPECT_TRUE(coded_input.ReadString(&str, 512));
+ EXPECT_TRUE(coded_input.ReadString(&str, 1024));
+ errors = error_log.GetMessages(ERROR);
+ }
+
+ EXPECT_EQ(INT_MAX - 512, input.backup_amount_);
+ EXPECT_EQ(0, errors.size());
+}
+
+} // namespace
+} // namespace io
+} // namespace protobuf
+} // namespace google
+
+#include <port_undef.inc>
diff --git a/NorthstarDedicatedTest/include/protobuf/io/gzip_stream.cc b/NorthstarDedicatedTest/include/protobuf/io/gzip_stream.cc
new file mode 100644
index 00000000..a8dd889a
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/io/gzip_stream.cc
@@ -0,0 +1,333 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: brianolson@google.com (Brian Olson)
+//
+// This file contains the implementation of classes GzipInputStream and
+// GzipOutputStream.
+
+
+#if HAVE_ZLIB
+#include <io/gzip_stream.h>
+
+#include <stubs/common.h>
+#include <stubs/logging.h>
+
+namespace google {
+namespace protobuf {
+namespace io {
+
+static const int kDefaultBufferSize = 65536;
+
+GzipInputStream::GzipInputStream(ZeroCopyInputStream* sub_stream, Format format,
+ int buffer_size)
+ : format_(format), sub_stream_(sub_stream), zerror_(Z_OK), byte_count_(0) {
+ zcontext_.state = Z_NULL;
+ zcontext_.zalloc = Z_NULL;
+ zcontext_.zfree = Z_NULL;
+ zcontext_.opaque = Z_NULL;
+ zcontext_.total_out = 0;
+ zcontext_.next_in = NULL;
+ zcontext_.avail_in = 0;
+ zcontext_.total_in = 0;
+ zcontext_.msg = NULL;
+ if (buffer_size == -1) {
+ output_buffer_length_ = kDefaultBufferSize;
+ } else {
+ output_buffer_length_ = buffer_size;
+ }
+ output_buffer_ = operator new(output_buffer_length_);
+ GOOGLE_CHECK(output_buffer_ != NULL);
+ zcontext_.next_out = static_cast<Bytef*>(output_buffer_);
+ zcontext_.avail_out = output_buffer_length_;
+ output_position_ = output_buffer_;
+}
+GzipInputStream::~GzipInputStream() {
+ operator delete(output_buffer_);
+ zerror_ = inflateEnd(&zcontext_);
+}
+
+static inline int internalInflateInit2(z_stream* zcontext,
+ GzipInputStream::Format format) {
+ int windowBitsFormat = 0;
+ switch (format) {
+ case GzipInputStream::GZIP:
+ windowBitsFormat = 16;
+ break;
+ case GzipInputStream::AUTO:
+ windowBitsFormat = 32;
+ break;
+ case GzipInputStream::ZLIB:
+ windowBitsFormat = 0;
+ break;
+ }
+ return inflateInit2(zcontext, /* windowBits */ 15 | windowBitsFormat);
+}
+
+int GzipInputStream::Inflate(int flush) {
+ if ((zerror_ == Z_OK) && (zcontext_.avail_out == 0)) {
+ // previous inflate filled output buffer. don't change input params yet.
+ } else if (zcontext_.avail_in == 0) {
+ const void* in;
+ int in_size;
+ bool first = zcontext_.next_in == NULL;
+ bool ok = sub_stream_->Next(&in, &in_size);
+ if (!ok) {
+ zcontext_.next_out = NULL;
+ zcontext_.avail_out = 0;
+ return Z_STREAM_END;
+ }
+ zcontext_.next_in = static_cast<Bytef*>(const_cast<void*>(in));
+ zcontext_.avail_in = in_size;
+ if (first) {
+ int error = internalInflateInit2(&zcontext_, format_);
+ if (error != Z_OK) {
+ return error;
+ }
+ }
+ }
+ zcontext_.next_out = static_cast<Bytef*>(output_buffer_);
+ zcontext_.avail_out = output_buffer_length_;
+ output_position_ = output_buffer_;
+ int error = inflate(&zcontext_, flush);
+ return error;
+}
+
+void GzipInputStream::DoNextOutput(const void** data, int* size) {
+ *data = output_position_;
+ *size = ((uintptr_t)zcontext_.next_out) - ((uintptr_t)output_position_);
+ output_position_ = zcontext_.next_out;
+}
+
+// implements ZeroCopyInputStream ----------------------------------
+bool GzipInputStream::Next(const void** data, int* size) {
+ bool ok = (zerror_ == Z_OK) || (zerror_ == Z_STREAM_END) ||
+ (zerror_ == Z_BUF_ERROR);
+ if ((!ok) || (zcontext_.next_out == NULL)) {
+ return false;
+ }
+ if (zcontext_.next_out != output_position_) {
+ DoNextOutput(data, size);
+ return true;
+ }
+ if (zerror_ == Z_STREAM_END) {
+ if (zcontext_.next_out != NULL) {
+ // sub_stream_ may have concatenated streams to follow
+ zerror_ = inflateEnd(&zcontext_);
+ byte_count_ += zcontext_.total_out;
+ if (zerror_ != Z_OK) {
+ return false;
+ }
+ zerror_ = internalInflateInit2(&zcontext_, format_);
+ if (zerror_ != Z_OK) {
+ return false;
+ }
+ } else {
+ *data = NULL;
+ *size = 0;
+ return false;
+ }
+ }
+ zerror_ = Inflate(Z_NO_FLUSH);
+ if ((zerror_ == Z_STREAM_END) && (zcontext_.next_out == NULL)) {
+ // The underlying stream's Next returned false inside Inflate.
+ return false;
+ }
+ ok = (zerror_ == Z_OK) || (zerror_ == Z_STREAM_END) ||
+ (zerror_ == Z_BUF_ERROR);
+ if (!ok) {
+ return false;
+ }
+ DoNextOutput(data, size);
+ return true;
+}
+void GzipInputStream::BackUp(int count) {
+ output_position_ = reinterpret_cast<void*>(
+ reinterpret_cast<uintptr_t>(output_position_) - count);
+}
+bool GzipInputStream::Skip(int count) {
+ const void* data;
+ int size = 0;
+ bool ok = Next(&data, &size);
+ while (ok && (size < count)) {
+ count -= size;
+ ok = Next(&data, &size);
+ }
+ if (size > count) {
+ BackUp(size - count);
+ }
+ return ok;
+}
+int64_t GzipInputStream::ByteCount() const {
+ 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();
+ operator delete(input_buffer_);
+}
+
+// private
+int GzipOutputStream::Deflate(int flush) {
+ int error = Z_OK;
+ do {
+ if ((sub_data_ == NULL) || (zcontext_.avail_out == 0)) {
+ bool ok = sub_stream_->Next(&sub_data_, &sub_data_size_);
+ if (!ok) {
+ sub_data_ = NULL;
+ sub_data_size_ = 0;
+ return Z_BUF_ERROR;
+ }
+ GOOGLE_CHECK_GT(sub_data_size_, 0);
+ zcontext_.next_out = static_cast<Bytef*>(sub_data_);
+ zcontext_.avail_out = sub_data_size_;
+ }
+ error = deflate(&zcontext_, flush);
+ } while (error == Z_OK && zcontext_.avail_out == 0);
+ if ((flush == Z_FULL_FLUSH) || (flush == Z_FINISH)) {
+ // Notify lower layer of data.
+ sub_stream_->BackUp(zcontext_.avail_out);
+ // We don't own the buffer anymore.
+ sub_data_ = NULL;
+ sub_data_size_ = 0;
+ }
+ return error;
+}
+
+// implements ZeroCopyOutputStream ---------------------------------
+bool GzipOutputStream::Next(void** data, int* size) {
+ if ((zerror_ != Z_OK) && (zerror_ != Z_BUF_ERROR)) {
+ return false;
+ }
+ if (zcontext_.avail_in != 0) {
+ zerror_ = Deflate(Z_NO_FLUSH);
+ if (zerror_ != Z_OK) {
+ return false;
+ }
+ }
+ if (zcontext_.avail_in == 0) {
+ // all input was consumed. reset the buffer.
+ zcontext_.next_in = static_cast<Bytef*>(input_buffer_);
+ zcontext_.avail_in = input_buffer_length_;
+ *data = input_buffer_;
+ *size = input_buffer_length_;
+ } else {
+ // The loop in Deflate should consume all avail_in
+ GOOGLE_LOG(DFATAL) << "Deflate left bytes unconsumed";
+ }
+ return true;
+}
+void GzipOutputStream::BackUp(int count) {
+ GOOGLE_CHECK_GE(zcontext_.avail_in, static_cast<uInt>(count));
+ zcontext_.avail_in -= count;
+}
+int64_t GzipOutputStream::ByteCount() const {
+ return zcontext_.total_in + zcontext_.avail_in;
+}
+
+bool GzipOutputStream::Flush() {
+ zerror_ = Deflate(Z_FULL_FLUSH);
+ // Return true if the flush succeeded or if it was a no-op.
+ return (zerror_ == Z_OK) ||
+ (zerror_ == Z_BUF_ERROR && zcontext_.avail_in == 0 &&
+ zcontext_.avail_out != 0);
+}
+
+bool GzipOutputStream::Close() {
+ if ((zerror_ != Z_OK) && (zerror_ != Z_BUF_ERROR)) {
+ return false;
+ }
+ do {
+ zerror_ = Deflate(Z_FINISH);
+ } while (zerror_ == Z_OK);
+ zerror_ = deflateEnd(&zcontext_);
+ bool ok = zerror_ == Z_OK;
+ zerror_ = Z_STREAM_END;
+ return ok;
+}
+
+} // namespace io
+} // namespace protobuf
+} // namespace google
+
+#endif // HAVE_ZLIB
diff --git a/NorthstarDedicatedTest/include/protobuf/io/gzip_stream.h b/NorthstarDedicatedTest/include/protobuf/io/gzip_stream.h
new file mode 100644
index 00000000..1cea18fc
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/io/gzip_stream.h
@@ -0,0 +1,202 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: brianolson@google.com (Brian Olson)
+//
+// This file contains the definition for classes GzipInputStream and
+// GzipOutputStream.
+//
+// GzipInputStream decompresses data from an underlying
+// ZeroCopyInputStream and provides the decompressed data as a
+// ZeroCopyInputStream.
+//
+// GzipOutputStream is an ZeroCopyOutputStream that compresses data to
+// an underlying ZeroCopyOutputStream.
+
+#ifndef GOOGLE_PROTOBUF_IO_GZIP_STREAM_H__
+#define GOOGLE_PROTOBUF_IO_GZIP_STREAM_H__
+
+
+#include <stubs/common.h>
+#include <io/zero_copy_stream.h>
+#include <port.h>
+#include <zlib.h>
+
+#include <port_def.inc>
+
+namespace google {
+namespace protobuf {
+namespace io {
+
+// A ZeroCopyInputStream that reads compressed data through zlib
+class PROTOBUF_EXPORT GzipInputStream : public ZeroCopyInputStream {
+ public:
+ // Format key for constructor
+ enum Format {
+ // zlib will autodetect gzip header or deflate stream
+ AUTO = 0,
+
+ // GZIP streams have some extra header data for file attributes.
+ GZIP = 1,
+
+ // Simpler zlib stream format.
+ ZLIB = 2,
+ };
+
+ // buffer_size and format may be -1 for default of 64kB and GZIP format
+ explicit GzipInputStream(ZeroCopyInputStream* sub_stream,
+ Format format = AUTO, int buffer_size = -1);
+ virtual ~GzipInputStream();
+
+ // Return last error message or NULL if no error.
+ inline const char* ZlibErrorMessage() const { return zcontext_.msg; }
+ inline int ZlibErrorCode() const { return zerror_; }
+
+ // implements ZeroCopyInputStream ----------------------------------
+ bool Next(const void** data, int* size) override;
+ void BackUp(int count) override;
+ bool Skip(int count) override;
+ int64_t ByteCount() const override;
+
+ private:
+ Format format_;
+
+ ZeroCopyInputStream* sub_stream_;
+
+ z_stream zcontext_;
+ int zerror_;
+
+ void* output_buffer_;
+ void* output_position_;
+ size_t output_buffer_length_;
+ int64_t byte_count_;
+
+ int Inflate(int flush);
+ void DoNextOutput(const void** data, int* size);
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(GzipInputStream);
+};
+
+class PROTOBUF_EXPORT GzipOutputStream : public ZeroCopyOutputStream {
+ public:
+ // Format key for constructor
+ enum Format {
+ // GZIP streams have some extra header data for file attributes.
+ GZIP = 1,
+
+ // Simpler zlib stream format.
+ ZLIB = 2,
+ };
+
+ struct PROTOBUF_EXPORT Options {
+ // Defaults to GZIP.
+ Format format;
+
+ // What size buffer to use internally. Defaults to 64kB.
+ int buffer_size;
+
+ // A number between 0 and 9, where 0 is no compression and 9 is best
+ // compression. Defaults to Z_DEFAULT_COMPRESSION (see zlib.h).
+ int compression_level;
+
+ // Defaults to Z_DEFAULT_STRATEGY. Can also be set to Z_FILTERED,
+ // Z_HUFFMAN_ONLY, or Z_RLE. See the documentation for deflateInit2 in
+ // zlib.h for definitions of these constants.
+ int compression_strategy;
+
+ Options(); // Initializes with default values.
+ };
+
+ // Create a GzipOutputStream with default options.
+ explicit GzipOutputStream(ZeroCopyOutputStream* sub_stream);
+
+ // Create a GzipOutputStream with the given options.
+ GzipOutputStream(ZeroCopyOutputStream* sub_stream, const Options& options);
+
+ virtual ~GzipOutputStream();
+
+ // Return last error message or NULL if no error.
+ inline const char* ZlibErrorMessage() const { return zcontext_.msg; }
+ inline int ZlibErrorCode() const { return zerror_; }
+
+ // Flushes data written so far to zipped data in the underlying stream.
+ // It is the caller's responsibility to flush the underlying stream if
+ // necessary.
+ // Compression may be less efficient stopping and starting around flushes.
+ // Returns true if no error.
+ //
+ // Please ensure that block size is > 6. Here is an excerpt from the zlib
+ // doc that explains why:
+ //
+ // In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that avail_out
+ // is greater than six to avoid repeated flush markers due to
+ // avail_out == 0 on return.
+ bool Flush();
+
+ // Writes out all data and closes the gzip stream.
+ // It is the caller's responsibility to close the underlying stream if
+ // necessary.
+ // Returns true if no error.
+ bool Close();
+
+ // implements ZeroCopyOutputStream ---------------------------------
+ bool Next(void** data, int* size) override;
+ void BackUp(int count) override;
+ int64_t ByteCount() const override;
+
+ private:
+ ZeroCopyOutputStream* sub_stream_;
+ // Result from calling Next() on sub_stream_
+ void* sub_data_;
+ int sub_data_size_;
+
+ z_stream zcontext_;
+ int zerror_;
+ void* input_buffer_;
+ size_t input_buffer_length_;
+
+ // Shared constructor code.
+ void Init(ZeroCopyOutputStream* sub_stream, const Options& options);
+
+ // Do some compression.
+ // Takes zlib flush mode.
+ // Returns zlib error code.
+ int Deflate(int flush);
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(GzipOutputStream);
+};
+
+} // namespace io
+} // namespace protobuf
+} // namespace google
+
+#include <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_IO_GZIP_STREAM_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/io/gzip_stream_unittest.sh b/NorthstarDedicatedTest/include/protobuf/io/gzip_stream_unittest.sh
new file mode 100644
index 00000000..16251a94
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/io/gzip_stream_unittest.sh
@@ -0,0 +1,44 @@
+#!/bin/sh -x
+#
+# Protocol Buffers - Google's data interchange format
+# Copyright 2009 Google Inc. All rights reserved.
+# https://developers.google.com/protocol-buffers/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (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)
+#
+# Test compatibility between command line gzip/gunzip binaries and
+# ZeroCopyStream versions.
+
+TESTFILE=Makefile
+
+(./zcgzip < ${TESTFILE} | gunzip | cmp - ${TESTFILE}) && \
+(gzip < ${TESTFILE} | ./zcgunzip | cmp - ${TESTFILE})
+
+# Result of "(cmd) && (cmd)" implicitly becomes result of this script
+# and thus the test.
diff --git a/NorthstarDedicatedTest/include/protobuf/io/io_win32.cc b/NorthstarDedicatedTest/include/protobuf/io/io_win32.cc
new file mode 100644
index 00000000..9edceed3
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/io/io_win32.cc
@@ -0,0 +1,470 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: laszlocsomor@google.com (Laszlo Csomor)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+// Implementation for long-path-aware open/mkdir/access/etc. on Windows, as well
+// as for the supporting utility functions.
+//
+// These functions convert the input path to an absolute Windows path
+// with "\\?\" prefix, then pass that to _wopen/_wmkdir/_waccess/etc.
+// (declared in <io.h>) respectively. This allows working with files/directories
+// whose paths are longer than MAX_PATH (260 chars).
+//
+// This file is only used on Windows, it's empty on other platforms.
+
+#if defined(_WIN32) && !defined(_XBOX_ONE)
+
+// Comment this out to fall back to using the ANSI versions (open, mkdir, ...)
+// instead of the Unicode ones (_wopen, _wmkdir, ...). Doing so can be useful to
+// debug failing tests if that's caused by the long path support.
+#define SUPPORT_LONGPATHS
+
+#include <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)) {
+ return ExpandWildcardsResult::kErrorOutputPathConversion;
+ }
+
+ if (dirname.empty()) {
+ consume(filename);
+ } else {
+ consume(dirname + filename);
+ }
+ }
+ } while (::FindNextFileW(handle, &metadata));
+ FindClose(handle);
+ return matched;
+}
+
+namespace strings {
+
+bool wcs_to_mbs(const WCHAR* s, string* out, bool outUtf8) {
+ if (null_or_empty(s)) {
+ out->clear();
+ return true;
+ }
+ BOOL usedDefaultChar = FALSE;
+ SetLastError(0);
+ int size = WideCharToMultiByte(
+ outUtf8 ? CP_UTF8 : CP_ACP, 0, s, -1, nullptr, 0, nullptr,
+ outUtf8 ? nullptr : &usedDefaultChar);
+ if ((size == 0 && GetLastError() != ERROR_INSUFFICIENT_BUFFER)
+ || usedDefaultChar) {
+ return false;
+ }
+ std::unique_ptr<CHAR[]> astr(new CHAR[size]);
+ WideCharToMultiByte(
+ outUtf8 ? CP_UTF8 : CP_ACP, 0, s, -1, astr.get(), size, nullptr, nullptr);
+ out->assign(astr.get());
+ return true;
+}
+
+bool mbs_to_wcs(const char* s, wstring* out, bool inUtf8) {
+ if (null_or_empty(s)) {
+ out->clear();
+ return true;
+ }
+
+ SetLastError(0);
+ int size =
+ MultiByteToWideChar(inUtf8 ? CP_UTF8 : CP_ACP, 0, s, -1, nullptr, 0);
+ if (size == 0 && GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
+ return false;
+ }
+ std::unique_ptr<WCHAR[]> wstr(new WCHAR[size]);
+ MultiByteToWideChar(
+ inUtf8 ? CP_UTF8 : CP_ACP, 0, s, -1, wstr.get(), size + 1);
+ out->assign(wstr.get());
+ return true;
+}
+
+bool utf8_to_wcs(const char* input, wstring* out) {
+ return mbs_to_wcs(input, out, true);
+}
+
+bool wcs_to_utf8(const wchar_t* input, string* out) {
+ return wcs_to_mbs(input, out, true);
+}
+
+} // namespace strings
+} // namespace win32
+} // namespace io
+} // namespace protobuf
+} // namespace google
+
+#endif // defined(_WIN32)
diff --git a/NorthstarDedicatedTest/include/protobuf/io/io_win32.h b/NorthstarDedicatedTest/include/protobuf/io/io_win32.h
new file mode 100644
index 00000000..0423736a
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/io/io_win32.h
@@ -0,0 +1,139 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// 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 <port.h>
+#include <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 <port_undef.inc>
+
+#endif // defined(_WIN32)
+
+#endif // GOOGLE_PROTOBUF_IO_IO_WIN32_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/io/io_win32_unittest.cc b/NorthstarDedicatedTest/include/protobuf/io/io_win32_unittest.cc
new file mode 100644
index 00000000..8fd4667d
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/io/io_win32_unittest.cc
@@ -0,0 +1,631 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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.
+
+// Unit tests for long-path-aware open/mkdir/access/etc. on Windows, as well as
+// for the supporting utility functions.
+//
+// This file is only used on Windows, it's empty on other platforms.
+
+#if defined(_WIN32)
+
+#define WIN32_LEAN_AND_MEAN
+#include <io/io_win32.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <wchar.h>
+#include <windows.h>
+
+#include <memory>
+#include <sstream>
+#include <string>
+#include <vector>
+
+#include <gtest/gtest.h>
+
+namespace google {
+namespace protobuf {
+namespace io {
+namespace win32 {
+namespace {
+
+const char kUtf8Text[] = {
+ 'h', 'i', ' ',
+ // utf-8: 11010000 10011111, utf-16: 100 0001 1111 = 0x041F
+ static_cast<char>(0xd0), static_cast<char>(0x9f),
+ // utf-8: 11010001 10000000, utf-16: 100 0100 0000 = 0x0440
+ static_cast<char>(0xd1), static_cast<char>(0x80),
+ // utf-8: 11010000 10111000, utf-16: 100 0011 1000 = 0x0438
+ static_cast<char>(0xd0), static_cast<char>(0xb8),
+ // utf-8: 11010000 10110010, utf-16: 100 0011 0010 = 0x0432
+ static_cast<char>(0xd0), static_cast<char>(0xb2),
+ // utf-8: 11010000 10110101, utf-16: 100 0011 0101 = 0x0435
+ static_cast<char>(0xd0), static_cast<char>(0xb5),
+ // utf-8: 11010001 10000010, utf-16: 100 0100 0010 = 0x0442
+ static_cast<char>(0xd1), static_cast<char>(0x82), 0
+};
+
+const wchar_t kUtf16Text[] = {
+ L'h', L'i', L' ',
+ L'\x41f', L'\x440', L'\x438', L'\x432', L'\x435', L'\x442', 0
+};
+
+using std::string;
+using std::vector;
+using std::wstring;
+
+class IoWin32Test : public ::testing::Test {
+ public:
+ void SetUp();
+ void TearDown();
+
+ protected:
+ bool CreateAllUnder(wstring path);
+ bool DeleteAllUnder(wstring path);
+
+ WCHAR working_directory[MAX_PATH];
+ string test_tmpdir;
+ wstring wtest_tmpdir;
+};
+
+#define ASSERT_INITIALIZED \
+ { \
+ EXPECT_FALSE(test_tmpdir.empty()); \
+ EXPECT_FALSE(wtest_tmpdir.empty()); \
+ }
+
+namespace {
+void StripTrailingSlashes(string* str) {
+ int i = str->size() - 1;
+ for (; i >= 0 && ((*str)[i] == '/' || (*str)[i] == '\\'); --i) {}
+ str->resize(i+1);
+}
+
+bool GetEnvVarAsUtf8(const WCHAR* name, string* result) {
+ DWORD size = ::GetEnvironmentVariableW(name, nullptr, 0);
+ if (size > 0 && GetLastError() != ERROR_ENVVAR_NOT_FOUND) {
+ std::unique_ptr<WCHAR[]> wcs(new WCHAR[size]);
+ ::GetEnvironmentVariableW(name, wcs.get(), size);
+ // GetEnvironmentVariableA retrieves an Active-Code-Page-encoded text which
+ // we'd first need to convert to UTF-16 then to UTF-8, because there seems
+ // to be no API function to do that conversion directly.
+ // GetEnvironmentVariableW retrieves an UTF-16-encoded text, which we need
+ // to convert to UTF-8.
+ return strings::wcs_to_utf8(wcs.get(), result);
+ } else {
+ return false;
+ }
+}
+
+bool GetCwdAsUtf8(string* result) {
+ DWORD size = ::GetCurrentDirectoryW(0, nullptr);
+ if (size > 0) {
+ std::unique_ptr<WCHAR[]> wcs(new WCHAR[size]);
+ ::GetCurrentDirectoryW(size, wcs.get());
+ // GetCurrentDirectoryA retrieves an Active-Code-Page-encoded text which
+ // we'd first need to convert to UTF-16 then to UTF-8, because there seems
+ // to be no API function to do that conversion directly.
+ // GetCurrentDirectoryW retrieves an UTF-16-encoded text, which we need
+ // to convert to UTF-8.
+ return strings::wcs_to_utf8(wcs.get(), result);
+ } else {
+ return false;
+ }
+}
+
+bool CreateEmptyFile(const wstring& path) {
+ HANDLE h = CreateFileW(path.c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL, NULL);
+ if (h == INVALID_HANDLE_VALUE) {
+ return false;
+ }
+ CloseHandle(h);
+ return true;
+}
+
+} // namespace
+
+void IoWin32Test::SetUp() {
+ test_tmpdir.clear();
+ wtest_tmpdir.clear();
+ DWORD size = ::GetCurrentDirectoryW(MAX_PATH, working_directory);
+ EXPECT_GT(size, 0);
+ EXPECT_LT(size, MAX_PATH);
+
+ string tmp;
+ bool ok = false;
+ if (!ok) {
+ // Bazel sets this environment variable when it runs tests.
+ ok = GetEnvVarAsUtf8(L"TEST_TMPDIR", &tmp);
+ }
+ if (!ok) {
+ // Bazel 0.8.0 sets this environment for every build and test action.
+ ok = GetEnvVarAsUtf8(L"TEMP", &tmp);
+ }
+ if (!ok) {
+ // Bazel 0.8.0 sets this environment for every build and test action.
+ ok = GetEnvVarAsUtf8(L"TMP", &tmp);
+ }
+ if (!ok) {
+ // Fall back to using the current directory.
+ ok = GetCwdAsUtf8(&tmp);
+ }
+ if (!ok || tmp.empty()) {
+ FAIL() << "Cannot find a temp directory.";
+ }
+
+ StripTrailingSlashes(&tmp);
+ std::stringstream result;
+ // Deleting files and directories is asynchronous on Windows, and if TearDown
+ // just deleted the previous temp directory, sometimes we cannot recreate the
+ // same directory.
+ // Use a counter so every test method gets its own temp directory.
+ static unsigned int counter = 0;
+ result << tmp << "\\w32tst" << counter++ << ".tmp";
+ test_tmpdir = result.str();
+ wtest_tmpdir = testonly_utf8_to_winpath(test_tmpdir.c_str());
+ ASSERT_FALSE(wtest_tmpdir.empty());
+ ASSERT_TRUE(DeleteAllUnder(wtest_tmpdir));
+ ASSERT_TRUE(CreateAllUnder(wtest_tmpdir));
+}
+
+void IoWin32Test::TearDown() {
+ if (!wtest_tmpdir.empty()) {
+ DeleteAllUnder(wtest_tmpdir);
+ }
+ ::SetCurrentDirectoryW(working_directory);
+}
+
+bool IoWin32Test::CreateAllUnder(wstring path) {
+ // Prepend UNC prefix if the path doesn't have it already. Don't bother
+ // checking if the path is shorter than MAX_PATH, let's just do it
+ // unconditionally.
+ if (path.find(L"\\\\?\\") != 0) {
+ path = wstring(L"\\\\?\\") + path;
+ }
+ if (::CreateDirectoryW(path.c_str(), nullptr) ||
+ GetLastError() == ERROR_ALREADY_EXISTS ||
+ GetLastError() == ERROR_ACCESS_DENIED) {
+ return true;
+ }
+ if (GetLastError() == ERROR_PATH_NOT_FOUND) {
+ size_t pos = path.find_last_of(L'\\');
+ if (pos != wstring::npos) {
+ wstring parent(path, 0, pos);
+ if (CreateAllUnder(parent) && CreateDirectoryW(path.c_str(), nullptr)) {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+bool IoWin32Test::DeleteAllUnder(wstring path) {
+ static const wstring kDot(L".");
+ static const wstring kDotDot(L"..");
+
+ // Prepend UNC prefix if the path doesn't have it already. Don't bother
+ // checking if the path is shorter than MAX_PATH, let's just do it
+ // unconditionally.
+ if (path.find(L"\\\\?\\") != 0) {
+ path = wstring(L"\\\\?\\") + path;
+ }
+ // Append "\" if necessary.
+ if (path[path.size() - 1] != L'\\') {
+ path.push_back(L'\\');
+ }
+
+ WIN32_FIND_DATAW metadata;
+ HANDLE handle = ::FindFirstFileW((path + L"*").c_str(), &metadata);
+ if (handle == INVALID_HANDLE_VALUE) {
+ return true; // directory doesn't exist
+ }
+
+ bool result = true;
+ do {
+ wstring childname = metadata.cFileName;
+ if (kDot != childname && kDotDot != childname) {
+ wstring childpath = path + childname;
+ if ((metadata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0) {
+ // If this is not a junction, delete its contents recursively.
+ // Finally delete this directory/junction too.
+ if (((metadata.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) == 0 &&
+ !DeleteAllUnder(childpath)) ||
+ !::RemoveDirectoryW(childpath.c_str())) {
+ result = false;
+ break;
+ }
+ } else {
+ if (!::DeleteFileW(childpath.c_str())) {
+ result = false;
+ break;
+ }
+ }
+ }
+ } while (::FindNextFileW(handle, &metadata));
+ ::FindClose(handle);
+ return result;
+}
+
+TEST_F(IoWin32Test, AccessTest) {
+ ASSERT_INITIALIZED;
+
+ string path = test_tmpdir;
+ while (path.size() < MAX_PATH - 30) {
+ path += "\\accesstest";
+ EXPECT_EQ(mkdir(path.c_str(), 0644), 0);
+ }
+ string file = path + "\\file.txt";
+ int fd = open(file.c_str(), O_CREAT | O_WRONLY, 0644);
+ if (fd > 0) {
+ EXPECT_EQ(close(fd), 0);
+ } else {
+ EXPECT_TRUE(false);
+ }
+
+ EXPECT_EQ(access(test_tmpdir.c_str(), F_OK), 0);
+ EXPECT_EQ(access(path.c_str(), F_OK), 0);
+ EXPECT_EQ(access(path.c_str(), W_OK), 0);
+ EXPECT_EQ(access(file.c_str(), F_OK | W_OK), 0);
+ EXPECT_NE(access((file + ".blah").c_str(), F_OK), 0);
+ EXPECT_NE(access((file + ".blah").c_str(), W_OK), 0);
+
+ EXPECT_EQ(access(".", F_OK), 0);
+ EXPECT_EQ(access(".", W_OK), 0);
+ EXPECT_EQ(access((test_tmpdir + "/accesstest").c_str(), F_OK | W_OK), 0);
+ ASSERT_EQ(access((test_tmpdir + "/./normalize_me/.././accesstest").c_str(),
+ F_OK | W_OK),
+ 0);
+ EXPECT_NE(access("io_win32_unittest.AccessTest.nonexistent", F_OK), 0);
+ EXPECT_NE(access("io_win32_unittest.AccessTest.nonexistent", W_OK), 0);
+
+ ASSERT_EQ(access("c:bad", F_OK), -1);
+ ASSERT_EQ(errno, ENOENT);
+ ASSERT_EQ(access("/tmp/bad", F_OK), -1);
+ ASSERT_EQ(errno, ENOENT);
+ ASSERT_EQ(access("\\bad", F_OK), -1);
+ ASSERT_EQ(errno, ENOENT);
+}
+
+TEST_F(IoWin32Test, OpenTest) {
+ ASSERT_INITIALIZED;
+
+ string path = test_tmpdir;
+ while (path.size() < MAX_PATH) {
+ path += "\\opentest";
+ EXPECT_EQ(mkdir(path.c_str(), 0644), 0);
+ }
+ string file = path + "\\file.txt";
+ int fd = open(file.c_str(), O_CREAT | O_WRONLY, 0644);
+ if (fd > 0) {
+ EXPECT_EQ(write(fd, "hello", 5), 5);
+ EXPECT_EQ(close(fd), 0);
+ } else {
+ EXPECT_TRUE(false);
+ }
+
+ ASSERT_EQ(open("c:bad.txt", O_CREAT | O_WRONLY, 0644), -1);
+ ASSERT_EQ(errno, ENOENT);
+ ASSERT_EQ(open("/tmp/bad.txt", O_CREAT | O_WRONLY, 0644), -1);
+ ASSERT_EQ(errno, ENOENT);
+ ASSERT_EQ(open("\\bad.txt", O_CREAT | O_WRONLY, 0644), -1);
+ ASSERT_EQ(errno, ENOENT);
+}
+
+TEST_F(IoWin32Test, MkdirTest) {
+ ASSERT_INITIALIZED;
+
+ string path = test_tmpdir;
+ do {
+ path += "\\mkdirtest";
+ ASSERT_EQ(mkdir(path.c_str(), 0644), 0);
+ } while (path.size() <= MAX_PATH);
+
+ ASSERT_EQ(mkdir("c:bad", 0644), -1);
+ ASSERT_EQ(errno, ENOENT);
+ ASSERT_EQ(mkdir("/tmp/bad", 0644), -1);
+ ASSERT_EQ(errno, ENOENT);
+ ASSERT_EQ(mkdir("\\bad", 0644), -1);
+ ASSERT_EQ(errno, ENOENT);
+}
+
+TEST_F(IoWin32Test, MkdirTestNonAscii) {
+ ASSERT_INITIALIZED;
+
+ // Create a non-ASCII path.
+ // Ensure that we can create the directory using CreateDirectoryW.
+ EXPECT_TRUE(CreateDirectoryW((wtest_tmpdir + L"\\1").c_str(), nullptr));
+ EXPECT_TRUE(CreateDirectoryW((wtest_tmpdir + L"\\1\\" + kUtf16Text).c_str(), nullptr));
+ // Ensure that we can create a very similarly named directory using mkdir.
+ // We don't attempt to delete and recreate the same directory, because on
+ // Windows, deleting files and directories seems to be asynchronous.
+ EXPECT_EQ(mkdir((test_tmpdir + "\\2").c_str(), 0644), 0);
+ EXPECT_EQ(mkdir((test_tmpdir + "\\2\\" + kUtf8Text).c_str(), 0644), 0);
+}
+
+TEST_F(IoWin32Test, ChdirTest) {
+ string path("C:\\");
+ EXPECT_EQ(access(path.c_str(), F_OK), 0);
+ ASSERT_EQ(chdir(path.c_str()), 0);
+
+ // Do not try to chdir into the test_tmpdir, it may already contain directory
+ // names with trailing dots.
+ // Instead test here with an obviously dot-trailed path. If the win32_chdir
+ // function would not convert the path to absolute and prefix with "\\?\" then
+ // the Win32 API would ignore the trailing dot, but because of the prefixing
+ // there'll be no path processing done, so we'll actually attempt to chdir
+ // into "C:\some\path\foo."
+ path = test_tmpdir + "/foo.";
+ EXPECT_EQ(mkdir(path.c_str(), 644), 0);
+ EXPECT_EQ(access(path.c_str(), F_OK), 0);
+ ASSERT_NE(chdir(path.c_str()), 0);
+}
+
+TEST_F(IoWin32Test, ChdirTestNonAscii) {
+ ASSERT_INITIALIZED;
+
+ // Create a directory with a non-ASCII path and ensure we can cd into it.
+ wstring wNonAscii(wtest_tmpdir + L"\\" + kUtf16Text);
+ string nonAscii;
+ EXPECT_TRUE(strings::wcs_to_utf8(wNonAscii.c_str(), &nonAscii));
+ EXPECT_TRUE(CreateDirectoryW(wNonAscii.c_str(), nullptr));
+ WCHAR cwd[MAX_PATH];
+ EXPECT_TRUE(GetCurrentDirectoryW(MAX_PATH, cwd));
+ // Ensure that we can cd into the path using SetCurrentDirectoryW.
+ EXPECT_TRUE(SetCurrentDirectoryW(wNonAscii.c_str()));
+ EXPECT_TRUE(SetCurrentDirectoryW(cwd));
+ // Ensure that we can cd into the path using chdir.
+ ASSERT_EQ(chdir(nonAscii.c_str()), 0);
+ // Ensure that the GetCurrentDirectoryW returns the desired path.
+ EXPECT_TRUE(GetCurrentDirectoryW(MAX_PATH, cwd));
+ ASSERT_EQ(wNonAscii, cwd);
+}
+
+TEST_F(IoWin32Test, ExpandWildcardsInRelativePathTest) {
+ wstring wNonAscii(wtest_tmpdir + L"\\" + kUtf16Text);
+ EXPECT_TRUE(CreateDirectoryW(wNonAscii.c_str(), nullptr));
+ // Create mock files we will test pattern matching on.
+ EXPECT_TRUE(CreateEmptyFile(wNonAscii + L"\\foo_a.proto"));
+ EXPECT_TRUE(CreateEmptyFile(wNonAscii + L"\\foo_b.proto"));
+ EXPECT_TRUE(CreateEmptyFile(wNonAscii + L"\\bar.proto"));
+ // `cd` into `wtest_tmpdir`.
+ EXPECT_TRUE(SetCurrentDirectoryW(wtest_tmpdir.c_str()));
+
+ int found_a = 0;
+ int found_b = 0;
+ vector<string> found_bad;
+ // Assert matching a relative path pattern. Results should also be relative.
+ ExpandWildcardsResult result =
+ ExpandWildcards(string(kUtf8Text) + "\\foo*.proto",
+ [&found_a, &found_b, &found_bad](const string& p) {
+ if (p == string(kUtf8Text) + "\\foo_a.proto") {
+ found_a++;
+ } else if (p == string(kUtf8Text) + "\\foo_b.proto") {
+ found_b++;
+ } else {
+ found_bad.push_back(p);
+ }
+ });
+ EXPECT_EQ(result, ExpandWildcardsResult::kSuccess);
+ EXPECT_EQ(found_a, 1);
+ EXPECT_EQ(found_b, 1);
+ if (!found_bad.empty()) {
+ FAIL() << found_bad[0];
+ }
+
+ // Assert matching the exact filename.
+ found_a = 0;
+ found_bad.clear();
+ result = ExpandWildcards(string(kUtf8Text) + "\\foo_a.proto",
+ [&found_a, &found_bad](const string& p) {
+ if (p == string(kUtf8Text) + "\\foo_a.proto") {
+ found_a++;
+ } else {
+ found_bad.push_back(p);
+ }
+ });
+ EXPECT_EQ(result, ExpandWildcardsResult::kSuccess);
+ EXPECT_EQ(found_a, 1);
+ if (!found_bad.empty()) {
+ FAIL() << found_bad[0];
+ }
+}
+
+TEST_F(IoWin32Test, ExpandWildcardsInAbsolutePathTest) {
+ wstring wNonAscii(wtest_tmpdir + L"\\" + kUtf16Text);
+ EXPECT_TRUE(CreateDirectoryW(wNonAscii.c_str(), nullptr));
+ // Create mock files we will test pattern matching on.
+ EXPECT_TRUE(CreateEmptyFile(wNonAscii + L"\\foo_a.proto"));
+ EXPECT_TRUE(CreateEmptyFile(wNonAscii + L"\\foo_b.proto"));
+ EXPECT_TRUE(CreateEmptyFile(wNonAscii + L"\\bar.proto"));
+
+ int found_a = 0;
+ int found_b = 0;
+ vector<string> found_bad;
+ // Assert matching an absolute path. The results should also use absolute
+ // path.
+ ExpandWildcardsResult result =
+ ExpandWildcards(string(test_tmpdir) + "\\" + kUtf8Text + "\\foo*.proto",
+ [this, &found_a, &found_b, &found_bad](const string& p) {
+ if (p == string(this->test_tmpdir) + "\\" + kUtf8Text +
+ "\\foo_a.proto") {
+ found_a++;
+ } else if (p == string(this->test_tmpdir) + "\\" +
+ kUtf8Text + "\\foo_b.proto") {
+ found_b++;
+ } else {
+ found_bad.push_back(p);
+ }
+ });
+ EXPECT_EQ(result, ExpandWildcardsResult::kSuccess);
+ EXPECT_EQ(found_a, 1);
+ EXPECT_EQ(found_b, 1);
+ if (!found_bad.empty()) {
+ FAIL() << found_bad[0];
+ }
+
+ // Assert matching the exact filename.
+ found_a = 0;
+ found_bad.clear();
+ result =
+ ExpandWildcards(string(test_tmpdir) + "\\" + kUtf8Text + "\\foo_a.proto",
+ [this, &found_a, &found_bad](const string& p) {
+ if (p == string(this->test_tmpdir) + "\\" + kUtf8Text +
+ "\\foo_a.proto") {
+ found_a++;
+ } else {
+ found_bad.push_back(p);
+ }
+ });
+ EXPECT_EQ(result, ExpandWildcardsResult::kSuccess);
+ EXPECT_EQ(found_a, 1);
+ if (!found_bad.empty()) {
+ FAIL() << found_bad[0];
+ }
+}
+
+TEST_F(IoWin32Test, ExpandWildcardsIgnoresDirectoriesTest) {
+ wstring wNonAscii(wtest_tmpdir + L"\\" + kUtf16Text);
+ EXPECT_TRUE(CreateDirectoryW(wNonAscii.c_str(), nullptr));
+ // Create mock files we will test pattern matching on.
+ EXPECT_TRUE(CreateEmptyFile(wNonAscii + L"\\foo_a.proto"));
+ EXPECT_TRUE(
+ CreateDirectoryW((wNonAscii + L"\\foo_b.proto").c_str(), nullptr));
+ EXPECT_TRUE(CreateEmptyFile(wNonAscii + L"\\foo_c.proto"));
+ // `cd` into `wtest_tmpdir`.
+ EXPECT_TRUE(SetCurrentDirectoryW(wtest_tmpdir.c_str()));
+
+ int found_a = 0;
+ int found_c = 0;
+ vector<string> found_bad;
+ // Assert that the pattern matches exactly the expected files, and using the
+ // absolute path as did the input pattern.
+ ExpandWildcardsResult result =
+ ExpandWildcards(string(kUtf8Text) + "\\foo*.proto",
+ [&found_a, &found_c, &found_bad](const string& p) {
+ if (p == string(kUtf8Text) + "\\foo_a.proto") {
+ found_a++;
+ } else if (p == string(kUtf8Text) + "\\foo_c.proto") {
+ found_c++;
+ } else {
+ found_bad.push_back(p);
+ }
+ });
+ EXPECT_EQ(result, ExpandWildcardsResult::kSuccess);
+ EXPECT_EQ(found_a, 1);
+ EXPECT_EQ(found_c, 1);
+ if (!found_bad.empty()) {
+ FAIL() << found_bad[0];
+ }
+}
+
+TEST_F(IoWin32Test, ExpandWildcardsFailsIfNoFileMatchesTest) {
+ wstring wNonAscii(wtest_tmpdir + L"\\" + kUtf16Text);
+ EXPECT_TRUE(CreateDirectoryW(wNonAscii.c_str(), nullptr));
+ // Create mock files we will test pattern matching on.
+ EXPECT_TRUE(CreateEmptyFile(wNonAscii + L"\\foo_a.proto"));
+ // `cd` into `wtest_tmpdir`.
+ EXPECT_TRUE(SetCurrentDirectoryW(wtest_tmpdir.c_str()));
+
+ // Control test: should match foo*.proto
+ ExpandWildcardsResult result =
+ ExpandWildcards(string(kUtf8Text) + "\\foo*.proto", [](const string&) {});
+ EXPECT_EQ(result, ExpandWildcardsResult::kSuccess);
+
+ // Control test: should match foo_a.proto
+ result = ExpandWildcards(string(kUtf8Text) + "\\foo_a.proto",
+ [](const string&) {});
+ EXPECT_EQ(result, ExpandWildcardsResult::kSuccess);
+
+ // Actual test: should not match anything.
+ result =
+ ExpandWildcards(string(kUtf8Text) + "\\bar*.proto", [](const string&) {});
+ ASSERT_EQ(result, ExpandWildcardsResult::kErrorNoMatchingFile);
+}
+
+TEST_F(IoWin32Test, AsWindowsPathTest) {
+ DWORD size = GetCurrentDirectoryW(0, nullptr);
+ std::unique_ptr<wchar_t[]> cwd_str(new wchar_t[size]);
+ EXPECT_GT(GetCurrentDirectoryW(size, cwd_str.get()), 0);
+ wstring cwd = wstring(L"\\\\?\\") + cwd_str.get();
+
+ ASSERT_EQ(testonly_utf8_to_winpath("relative_mkdirtest"),
+ cwd + L"\\relative_mkdirtest");
+ ASSERT_EQ(testonly_utf8_to_winpath("preserve//\\trailing///"),
+ cwd + L"\\preserve\\trailing\\");
+ ASSERT_EQ(testonly_utf8_to_winpath("./normalize_me\\/../blah"),
+ cwd + L"\\blah");
+ std::ostringstream relpath;
+ for (wchar_t* p = cwd_str.get(); *p; ++p) {
+ if (*p == '/' || *p == '\\') {
+ relpath << "../";
+ }
+ }
+ relpath << ".\\/../\\./beyond-toplevel";
+ ASSERT_EQ(testonly_utf8_to_winpath(relpath.str().c_str()),
+ wstring(L"\\\\?\\") + cwd_str.get()[0] + L":\\beyond-toplevel");
+
+ // Absolute unix paths lack drive letters, driveless absolute windows paths
+ // do too. Neither can be converted to a drive-specifying absolute Windows
+ // path.
+ ASSERT_EQ(testonly_utf8_to_winpath("/absolute/unix/path"), L"");
+ // Though valid on Windows, we also don't support UNC paths (\\UNC\\blah).
+ ASSERT_EQ(testonly_utf8_to_winpath("\\driveless\\absolute"), L"");
+ // Though valid in cmd.exe, drive-relative paths are not supported.
+ ASSERT_EQ(testonly_utf8_to_winpath("c:foo"), L"");
+ ASSERT_EQ(testonly_utf8_to_winpath("c:/foo"), L"\\\\?\\c:\\foo");
+ ASSERT_EQ(testonly_utf8_to_winpath("\\\\?\\C:\\foo"), L"\\\\?\\C:\\foo");
+}
+
+TEST_F(IoWin32Test, Utf8Utf16ConversionTest) {
+ string mbs;
+ wstring wcs;
+ ASSERT_TRUE(strings::utf8_to_wcs(kUtf8Text, &wcs));
+ ASSERT_TRUE(strings::wcs_to_utf8(kUtf16Text, &mbs));
+ ASSERT_EQ(wcs, kUtf16Text);
+ ASSERT_EQ(mbs, kUtf8Text);
+}
+
+} // namespace
+} // namespace win32
+} // namespace io
+} // namespace protobuf
+} // namespace google
+
+#endif // defined(_WIN32)
+
diff --git a/NorthstarDedicatedTest/include/protobuf/io/package_info.h b/NorthstarDedicatedTest/include/protobuf/io/package_info.h
new file mode 100644
index 00000000..46c3dac9
--- /dev/null
+++ b/NorthstarDedicatedTest/include/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/NorthstarDedicatedTest/include/protobuf/io/printer.cc b/NorthstarDedicatedTest/include/protobuf/io/printer.cc
new file mode 100644
index 00000000..1764ed9b
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/io/printer.cc
@@ -0,0 +1,400 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <io/printer.h>
+
+#include <cctype>
+
+#include <stubs/logging.h>
+#include <stubs/common.h>
+#include <io/zero_copy_stream.h>
+
+namespace google {
+namespace protobuf {
+namespace io {
+
+Printer::Printer(ZeroCopyOutputStream* output, char variable_delimiter)
+ : variable_delimiter_(variable_delimiter),
+ output_(output),
+ buffer_(NULL),
+ buffer_size_(0),
+ offset_(0),
+ at_start_of_line_(true),
+ failed_(false),
+ annotation_collector_(NULL) {}
+
+Printer::Printer(ZeroCopyOutputStream* output, char variable_delimiter,
+ AnnotationCollector* annotation_collector)
+ : variable_delimiter_(variable_delimiter),
+ output_(output),
+ buffer_(NULL),
+ buffer_size_(0),
+ offset_(0),
+ at_start_of_line_(true),
+ failed_(false),
+ annotation_collector_(annotation_collector) {}
+
+Printer::~Printer() {
+ // Only BackUp() if we have called Next() at least once and never failed.
+ if (buffer_size_ > 0 && !failed_) {
+ output_->BackUp(buffer_size_);
+ }
+}
+
+bool Printer::GetSubstitutionRange(const char* varname,
+ std::pair<size_t, size_t>* range) {
+ std::map<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/NorthstarDedicatedTest/include/protobuf/io/printer.h b/NorthstarDedicatedTest/include/protobuf/io/printer.h
new file mode 100644
index 00000000..15e19855
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/io/printer.h
@@ -0,0 +1,385 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// Utility class for writing text to a ZeroCopyOutputStream.
+
+#ifndef GOOGLE_PROTOBUF_IO_PRINTER_H__
+#define GOOGLE_PROTOBUF_IO_PRINTER_H__
+
+
+#include <map>
+#include <string>
+#include <vector>
+
+#include <stubs/common.h>
+#include <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 <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_IO_PRINTER_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/io/printer_unittest.cc b/NorthstarDedicatedTest/include/protobuf/io/printer_unittest.cc
new file mode 100644
index 00000000..1652703b
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/io/printer_unittest.cc
@@ -0,0 +1,735 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 <io/printer.h>
+
+#include <vector>
+
+#include <stubs/logging.h>
+#include <stubs/common.h>
+#include <descriptor.pb.h>
+#include <testing/googletest.h>
+#include <gtest/gtest.h>
+#include <io/zero_copy_stream_impl.h>
+
+namespace google {
+namespace protobuf {
+namespace io {
+
+// Each test repeats over several block sizes in order to test both cases
+// where particular writes cross a buffer boundary and cases where they do
+// not.
+
+TEST(Printer, EmptyPrinter) {
+ char buffer[8192];
+ const int block_size = 100;
+ ArrayOutputStream output(buffer, GOOGLE_ARRAYSIZE(buffer), block_size);
+ Printer printer(&output, '\0');
+ EXPECT_TRUE(!printer.failed());
+}
+
+TEST(Printer, BasicPrinting) {
+ char buffer[8192];
+
+ for (int block_size = 1; block_size < 512; block_size *= 2) {
+ ArrayOutputStream output(buffer, sizeof(buffer), block_size);
+
+ {
+ Printer printer(&output, '\0');
+
+ printer.Print("Hello World!");
+ printer.Print(" This is the same line.\n");
+ printer.Print("But this is a new one.\nAnd this is another one.");
+
+ EXPECT_FALSE(printer.failed());
+ }
+
+ buffer[output.ByteCount()] = '\0';
+
+ EXPECT_STREQ(
+ "Hello World! This is the same line.\n"
+ "But this is a new one.\n"
+ "And this is another one.",
+ buffer);
+ }
+}
+
+TEST(Printer, WriteRaw) {
+ char buffer[8192];
+
+ for (int block_size = 1; block_size < 512; block_size *= 2) {
+ ArrayOutputStream output(buffer, sizeof(buffer), block_size);
+
+ {
+ std::string string_obj = "From an object\n";
+ Printer printer(&output, '$');
+ printer.WriteRaw("Hello World!", 12);
+ printer.PrintRaw(" This is the same line.\n");
+ printer.PrintRaw("But this is a new one.\nAnd this is another one.");
+ printer.WriteRaw("\n", 1);
+ printer.PrintRaw(string_obj);
+ EXPECT_FALSE(printer.failed());
+ }
+
+ buffer[output.ByteCount()] = '\0';
+
+ EXPECT_STREQ(
+ "Hello World! This is the same line.\n"
+ "But this is a new one.\n"
+ "And this is another one."
+ "\n"
+ "From an object\n",
+ buffer);
+ }
+}
+
+TEST(Printer, VariableSubstitution) {
+ char buffer[8192];
+
+ for (int block_size = 1; block_size < 512; block_size *= 2) {
+ ArrayOutputStream output(buffer, sizeof(buffer), block_size);
+
+ {
+ Printer printer(&output, '$');
+ std::map<std::string, std::string> vars;
+
+ vars["foo"] = "World";
+ vars["bar"] = "$foo$";
+ vars["abcdefg"] = "1234";
+
+ printer.Print(vars, "Hello $foo$!\nbar = $bar$\n");
+ printer.PrintRaw("RawBit\n");
+ printer.Print(vars, "$abcdefg$\nA literal dollar sign: $$");
+
+ vars["foo"] = "blah";
+ printer.Print(vars, "\nNow foo = $foo$.");
+
+ EXPECT_FALSE(printer.failed());
+ }
+
+ buffer[output.ByteCount()] = '\0';
+
+ EXPECT_STREQ(
+ "Hello World!\n"
+ "bar = $foo$\n"
+ "RawBit\n"
+ "1234\n"
+ "A literal dollar sign: $\n"
+ "Now foo = blah.",
+ buffer);
+ }
+}
+
+TEST(Printer, InlineVariableSubstitution) {
+ char buffer[8192];
+
+ ArrayOutputStream output(buffer, sizeof(buffer));
+
+ {
+ Printer printer(&output, '$');
+ printer.Print("Hello $foo$!\n", "foo", "World");
+ printer.PrintRaw("RawBit\n");
+ printer.Print("$foo$ $bar$\n", "foo", "one", "bar", "two");
+ EXPECT_FALSE(printer.failed());
+ }
+
+ buffer[output.ByteCount()] = '\0';
+
+ EXPECT_STREQ(
+ "Hello World!\n"
+ "RawBit\n"
+ "one two\n",
+ buffer);
+}
+
+// MockDescriptorFile defines only those members that Printer uses to write out
+// annotations.
+class MockDescriptorFile {
+ public:
+ explicit MockDescriptorFile(const std::string& file) : file_(file) {}
+
+ // The mock filename for this file.
+ const std::string& name() const { return file_; }
+
+ private:
+ std::string file_;
+};
+
+// MockDescriptor defines only those members that Printer uses to write out
+// annotations.
+class MockDescriptor {
+ public:
+ MockDescriptor(const std::string& file, const std::vector<int>& path)
+ : file_(file), path_(path) {}
+
+ // The mock file in which this descriptor was defined.
+ const MockDescriptorFile* file() const { return &file_; }
+
+ private:
+ // Allows access to GetLocationPath.
+ friend class Printer;
+
+ // Copies the pre-stored path to output.
+ void GetLocationPath(std::vector<int>* output) const { *output = path_; }
+
+ MockDescriptorFile file_;
+ std::vector<int> path_;
+};
+
+TEST(Printer, AnnotateMap) {
+ char buffer[8192];
+ ArrayOutputStream output(buffer, sizeof(buffer));
+ GeneratedCodeInfo info;
+ AnnotationProtoCollector<GeneratedCodeInfo> info_collector(&info);
+ {
+ Printer printer(&output, '$', &info_collector);
+ std::map<std::string, std::string> vars;
+ vars["foo"] = "3";
+ vars["bar"] = "5";
+ printer.Print(vars, "012$foo$4$bar$\n");
+ std::vector<int> path_1;
+ path_1.push_back(33);
+ std::vector<int> path_2;
+ path_2.push_back(11);
+ path_2.push_back(22);
+ MockDescriptor descriptor_1("path_1", path_1);
+ MockDescriptor descriptor_2("path_2", path_2);
+ printer.Annotate("foo", "foo", &descriptor_1);
+ printer.Annotate("bar", "bar", &descriptor_2);
+ }
+ buffer[output.ByteCount()] = '\0';
+ EXPECT_STREQ("012345\n", buffer);
+ ASSERT_EQ(2, info.annotation_size());
+ const GeneratedCodeInfo::Annotation* foo = info.annotation(0).path_size() == 1
+ ? &info.annotation(0)
+ : &info.annotation(1);
+ const GeneratedCodeInfo::Annotation* bar = info.annotation(0).path_size() == 1
+ ? &info.annotation(1)
+ : &info.annotation(0);
+ ASSERT_EQ(1, foo->path_size());
+ ASSERT_EQ(2, bar->path_size());
+ EXPECT_EQ(33, foo->path(0));
+ EXPECT_EQ(11, bar->path(0));
+ EXPECT_EQ(22, bar->path(1));
+ EXPECT_EQ("path_1", foo->source_file());
+ EXPECT_EQ("path_2", bar->source_file());
+ EXPECT_EQ(3, foo->begin());
+ EXPECT_EQ(4, foo->end());
+ EXPECT_EQ(5, bar->begin());
+ EXPECT_EQ(6, bar->end());
+}
+
+TEST(Printer, AnnotateInline) {
+ char buffer[8192];
+ ArrayOutputStream output(buffer, sizeof(buffer));
+ GeneratedCodeInfo info;
+ AnnotationProtoCollector<GeneratedCodeInfo> info_collector(&info);
+ {
+ Printer printer(&output, '$', &info_collector);
+ printer.Print("012$foo$4$bar$\n", "foo", "3", "bar", "5");
+ std::vector<int> path_1;
+ path_1.push_back(33);
+ std::vector<int> path_2;
+ path_2.push_back(11);
+ path_2.push_back(22);
+ MockDescriptor descriptor_1("path_1", path_1);
+ MockDescriptor descriptor_2("path_2", path_2);
+ printer.Annotate("foo", "foo", &descriptor_1);
+ printer.Annotate("bar", "bar", &descriptor_2);
+ }
+ buffer[output.ByteCount()] = '\0';
+ EXPECT_STREQ("012345\n", buffer);
+ ASSERT_EQ(2, info.annotation_size());
+ const GeneratedCodeInfo::Annotation* foo = info.annotation(0).path_size() == 1
+ ? &info.annotation(0)
+ : &info.annotation(1);
+ const GeneratedCodeInfo::Annotation* bar = info.annotation(0).path_size() == 1
+ ? &info.annotation(1)
+ : &info.annotation(0);
+ ASSERT_EQ(1, foo->path_size());
+ ASSERT_EQ(2, bar->path_size());
+ EXPECT_EQ(33, foo->path(0));
+ EXPECT_EQ(11, bar->path(0));
+ EXPECT_EQ(22, bar->path(1));
+ EXPECT_EQ("path_1", foo->source_file());
+ EXPECT_EQ("path_2", bar->source_file());
+ EXPECT_EQ(3, foo->begin());
+ EXPECT_EQ(4, foo->end());
+ EXPECT_EQ(5, bar->begin());
+ EXPECT_EQ(6, bar->end());
+}
+
+TEST(Printer, AnnotateRange) {
+ char buffer[8192];
+ ArrayOutputStream output(buffer, sizeof(buffer));
+ GeneratedCodeInfo info;
+ AnnotationProtoCollector<GeneratedCodeInfo> info_collector(&info);
+ {
+ Printer printer(&output, '$', &info_collector);
+ printer.Print("012$foo$4$bar$\n", "foo", "3", "bar", "5");
+ std::vector<int> path;
+ path.push_back(33);
+ MockDescriptor descriptor("path", path);
+ printer.Annotate("foo", "bar", &descriptor);
+ }
+ buffer[output.ByteCount()] = '\0';
+ EXPECT_STREQ("012345\n", buffer);
+ ASSERT_EQ(1, info.annotation_size());
+ const GeneratedCodeInfo::Annotation* foobar = &info.annotation(0);
+ ASSERT_EQ(1, foobar->path_size());
+ EXPECT_EQ(33, foobar->path(0));
+ EXPECT_EQ("path", foobar->source_file());
+ EXPECT_EQ(3, foobar->begin());
+ EXPECT_EQ(6, foobar->end());
+}
+
+TEST(Printer, AnnotateEmptyRange) {
+ char buffer[8192];
+ ArrayOutputStream output(buffer, sizeof(buffer));
+ GeneratedCodeInfo info;
+ AnnotationProtoCollector<GeneratedCodeInfo> info_collector(&info);
+ {
+ Printer printer(&output, '$', &info_collector);
+ printer.Print("012$foo$4$baz$$bam$$bar$\n", "foo", "3", "bar", "5", "baz",
+ "", "bam", "");
+ std::vector<int> path;
+ path.push_back(33);
+ MockDescriptor descriptor("path", path);
+ printer.Annotate("baz", "bam", &descriptor);
+ }
+ buffer[output.ByteCount()] = '\0';
+ EXPECT_STREQ("012345\n", buffer);
+ ASSERT_EQ(1, info.annotation_size());
+ const GeneratedCodeInfo::Annotation* bazbam = &info.annotation(0);
+ ASSERT_EQ(1, bazbam->path_size());
+ EXPECT_EQ(33, bazbam->path(0));
+ EXPECT_EQ("path", bazbam->source_file());
+ EXPECT_EQ(5, bazbam->begin());
+ EXPECT_EQ(5, bazbam->end());
+}
+
+TEST(Printer, AnnotateDespiteUnrelatedMultipleUses) {
+ char buffer[8192];
+ ArrayOutputStream output(buffer, sizeof(buffer));
+ GeneratedCodeInfo info;
+ AnnotationProtoCollector<GeneratedCodeInfo> info_collector(&info);
+ {
+ Printer printer(&output, '$', &info_collector);
+ printer.Print("012$foo$4$foo$$bar$\n", "foo", "3", "bar", "5");
+ std::vector<int> path;
+ path.push_back(33);
+ MockDescriptor descriptor("path", path);
+ printer.Annotate("bar", "bar", &descriptor);
+ }
+ buffer[output.ByteCount()] = '\0';
+ EXPECT_STREQ("0123435\n", buffer);
+ ASSERT_EQ(1, info.annotation_size());
+ const GeneratedCodeInfo::Annotation* bar = &info.annotation(0);
+ ASSERT_EQ(1, bar->path_size());
+ EXPECT_EQ(33, bar->path(0));
+ EXPECT_EQ("path", bar->source_file());
+ EXPECT_EQ(6, bar->begin());
+ EXPECT_EQ(7, bar->end());
+}
+
+TEST(Printer, AnnotateIndent) {
+ char buffer[8192];
+ ArrayOutputStream output(buffer, sizeof(buffer));
+ GeneratedCodeInfo info;
+ AnnotationProtoCollector<GeneratedCodeInfo> info_collector(&info);
+ {
+ Printer printer(&output, '$', &info_collector);
+ printer.Print("0\n");
+ printer.Indent();
+ printer.Print("$foo$", "foo", "4");
+ std::vector<int> path;
+ path.push_back(44);
+ MockDescriptor descriptor("path", path);
+ printer.Annotate("foo", &descriptor);
+ printer.Print(",\n");
+ printer.Print("$bar$", "bar", "9");
+ path[0] = 99;
+ MockDescriptor descriptor_two("path", path);
+ printer.Annotate("bar", &descriptor_two);
+ printer.Print("\n${$$D$$}$\n", "{", "", "}", "", "D", "d");
+ path[0] = 1313;
+ MockDescriptor descriptor_three("path", path);
+ printer.Annotate("{", "}", &descriptor_three);
+ printer.Outdent();
+ printer.Print("\n");
+ }
+ buffer[output.ByteCount()] = '\0';
+ EXPECT_STREQ("0\n 4,\n 9\n d\n\n", buffer);
+ ASSERT_EQ(3, info.annotation_size());
+ const GeneratedCodeInfo::Annotation* foo = &info.annotation(0);
+ ASSERT_EQ(1, foo->path_size());
+ EXPECT_EQ(44, foo->path(0));
+ EXPECT_EQ("path", foo->source_file());
+ EXPECT_EQ(4, foo->begin());
+ EXPECT_EQ(5, foo->end());
+ const GeneratedCodeInfo::Annotation* bar = &info.annotation(1);
+ ASSERT_EQ(1, bar->path_size());
+ EXPECT_EQ(99, bar->path(0));
+ EXPECT_EQ("path", bar->source_file());
+ EXPECT_EQ(9, bar->begin());
+ EXPECT_EQ(10, bar->end());
+ const GeneratedCodeInfo::Annotation* braces = &info.annotation(2);
+ ASSERT_EQ(1, braces->path_size());
+ EXPECT_EQ(1313, braces->path(0));
+ EXPECT_EQ("path", braces->source_file());
+ EXPECT_EQ(13, braces->begin());
+ EXPECT_EQ(14, braces->end());
+}
+
+TEST(Printer, AnnotateIndentNewline) {
+ char buffer[8192];
+ ArrayOutputStream output(buffer, sizeof(buffer));
+ GeneratedCodeInfo info;
+ AnnotationProtoCollector<GeneratedCodeInfo> info_collector(&info);
+ {
+ Printer printer(&output, '$', &info_collector);
+ printer.Indent();
+ printer.Print("$A$$N$$B$C\n", "A", "", "N", "\nz", "B", "");
+ std::vector<int> path;
+ path.push_back(0);
+ MockDescriptor descriptor("path", path);
+ printer.Annotate("A", "B", &descriptor);
+ printer.Outdent();
+ printer.Print("\n");
+ }
+ buffer[output.ByteCount()] = '\0';
+ EXPECT_STREQ("\nz C\n\n", buffer);
+ ASSERT_EQ(1, info.annotation_size());
+ const GeneratedCodeInfo::Annotation* ab = &info.annotation(0);
+ ASSERT_EQ(1, ab->path_size());
+ EXPECT_EQ(0, ab->path(0));
+ EXPECT_EQ("path", ab->source_file());
+ EXPECT_EQ(0, ab->begin());
+ EXPECT_EQ(4, ab->end());
+}
+
+TEST(Printer, Indenting) {
+ char buffer[8192];
+
+ for (int block_size = 1; block_size < 512; block_size *= 2) {
+ ArrayOutputStream output(buffer, sizeof(buffer), block_size);
+
+ {
+ Printer printer(&output, '$');
+ std::map<std::string, std::string> vars;
+
+ vars["newline"] = "\n";
+
+ printer.Print("This is not indented.\n");
+ printer.Indent();
+ printer.Print("This is indented\nAnd so is this\n");
+ printer.Outdent();
+ printer.Print("But this is not.");
+ printer.Indent();
+ printer.Print(
+ " And this is still the same line.\n"
+ "But this is indented.\n");
+ printer.PrintRaw("RawBit has indent at start\n");
+ printer.PrintRaw("but not after a raw newline\n");
+ printer.Print(vars,
+ "Note that a newline in a variable will break "
+ "indenting, as we see$newline$here.\n");
+ printer.Indent();
+ printer.Print("And this");
+ printer.Outdent();
+ printer.Outdent();
+ printer.Print(" is double-indented\nBack to normal.");
+
+ EXPECT_FALSE(printer.failed());
+ }
+
+ buffer[output.ByteCount()] = '\0';
+
+ EXPECT_STREQ(
+ "This is not indented.\n"
+ " This is indented\n"
+ " And so is this\n"
+ "But this is not. And this is still the same line.\n"
+ " But this is indented.\n"
+ " RawBit has indent at start\n"
+ "but not after a raw newline\n"
+ "Note that a newline in a variable will break indenting, as we see\n"
+ "here.\n"
+ " And this is double-indented\n"
+ "Back to normal.",
+ buffer);
+ }
+}
+
+// Death tests do not work on Windows as of yet.
+#ifdef PROTOBUF_HAS_DEATH_TEST
+TEST(Printer, Death) {
+ char buffer[8192];
+
+ ArrayOutputStream output(buffer, sizeof(buffer));
+ Printer printer(&output, '$');
+
+ EXPECT_DEBUG_DEATH(printer.Print("$nosuchvar$"), "Undefined variable");
+ EXPECT_DEBUG_DEATH(printer.Print("$unclosed"), "Unclosed variable name");
+ EXPECT_DEBUG_DEATH(printer.Outdent(), "without matching Indent");
+}
+
+TEST(Printer, AnnotateMultipleUsesDeath) {
+ char buffer[8192];
+ ArrayOutputStream output(buffer, sizeof(buffer));
+ GeneratedCodeInfo info;
+ AnnotationProtoCollector<GeneratedCodeInfo> info_collector(&info);
+ {
+ Printer printer(&output, '$', &info_collector);
+ printer.Print("012$foo$4$foo$\n", "foo", "3");
+ std::vector<int> path;
+ path.push_back(33);
+ MockDescriptor descriptor("path", path);
+ EXPECT_DEBUG_DEATH(printer.Annotate("foo", "foo", &descriptor), "multiple");
+ }
+}
+
+TEST(Printer, AnnotateNegativeLengthDeath) {
+ char buffer[8192];
+ ArrayOutputStream output(buffer, sizeof(buffer));
+ GeneratedCodeInfo info;
+ AnnotationProtoCollector<GeneratedCodeInfo> info_collector(&info);
+ {
+ Printer printer(&output, '$', &info_collector);
+ printer.Print("012$foo$4$bar$\n", "foo", "3", "bar", "5");
+ std::vector<int> path;
+ path.push_back(33);
+ MockDescriptor descriptor("path", path);
+ EXPECT_DEBUG_DEATH(printer.Annotate("bar", "foo", &descriptor), "negative");
+ }
+}
+
+TEST(Printer, AnnotateUndefinedDeath) {
+ char buffer[8192];
+ ArrayOutputStream output(buffer, sizeof(buffer));
+ GeneratedCodeInfo info;
+ AnnotationProtoCollector<GeneratedCodeInfo> info_collector(&info);
+ {
+ Printer printer(&output, '$', &info_collector);
+ printer.Print("012$foo$4$foo$\n", "foo", "3");
+ std::vector<int> path;
+ path.push_back(33);
+ MockDescriptor descriptor("path", path);
+ EXPECT_DEBUG_DEATH(printer.Annotate("bar", "bar", &descriptor),
+ "Undefined");
+ }
+}
+#endif // PROTOBUF_HAS_DEATH_TEST
+
+TEST(Printer, WriteFailurePartial) {
+ char buffer[17];
+
+ ArrayOutputStream output(buffer, sizeof(buffer));
+ Printer printer(&output, '$');
+
+ // Print 16 bytes to almost fill the buffer (should not fail).
+ printer.Print("0123456789abcdef");
+ EXPECT_FALSE(printer.failed());
+
+ // Try to print 2 chars. Only one fits.
+ printer.Print("<>");
+ EXPECT_TRUE(printer.failed());
+
+ // Anything else should fail too.
+ printer.Print(" ");
+ EXPECT_TRUE(printer.failed());
+ printer.Print("blah");
+ EXPECT_TRUE(printer.failed());
+
+ // Buffer should contain the first 17 bytes written.
+ EXPECT_EQ("0123456789abcdef<", std::string(buffer, sizeof(buffer)));
+}
+
+TEST(Printer, WriteFailureExact) {
+ char buffer[16];
+
+ ArrayOutputStream output(buffer, sizeof(buffer));
+ Printer printer(&output, '$');
+
+ // Print 16 bytes to fill the buffer exactly (should not fail).
+ printer.Print("0123456789abcdef");
+ EXPECT_FALSE(printer.failed());
+
+ // Try to print one more byte (should fail).
+ printer.Print(" ");
+ EXPECT_TRUE(printer.failed());
+
+ // Should not crash
+ printer.Print("blah");
+ EXPECT_TRUE(printer.failed());
+
+ // Buffer should contain the first 16 bytes written.
+ EXPECT_EQ("0123456789abcdef", std::string(buffer, sizeof(buffer)));
+}
+
+TEST(Printer, FormatInternal) {
+ std::vector<std::string> args{"arg1", "arg2"};
+ std::map<std::string, std::string> vars{
+ {"foo", "bar"}, {"baz", "bla"}, {"empty", ""}};
+ // Substitution tests
+ {
+ // Direct arg substitution
+ std::string s;
+ {
+ StringOutputStream output(&s);
+ Printer printer(&output, '$');
+ printer.FormatInternal(args, vars, "$1$ $2$");
+ }
+ EXPECT_EQ("arg1 arg2", s);
+ }
+ {
+ // Variable substitution including spaces left
+ std::string s;
+ {
+ StringOutputStream output(&s);
+ Printer printer(&output, '$');
+ printer.FormatInternal({}, vars, "$foo$$ baz$$ empty$");
+ }
+ EXPECT_EQ("bar bla", s);
+ }
+ {
+ // Variable substitution including spaces right
+ std::string s;
+ {
+ StringOutputStream output(&s);
+ Printer printer(&output, '$');
+ printer.FormatInternal({}, vars, "$empty $$foo $$baz$");
+ }
+ EXPECT_EQ("bar bla", s);
+ }
+ {
+ // Mixed variable substitution
+ std::string s;
+ {
+ StringOutputStream output(&s);
+ Printer printer(&output, '$');
+ printer.FormatInternal(args, vars, "$empty $$1$ $foo $$2$ $baz$");
+ }
+ EXPECT_EQ("arg1 bar arg2 bla", s);
+ }
+
+ // Indentation tests
+ {
+ // Empty lines shouldn't indent.
+ std::string s;
+ {
+ StringOutputStream output(&s);
+ Printer printer(&output, '$');
+ printer.Indent();
+ printer.FormatInternal(args, vars, "$empty $\n\n$1$ $foo $$2$\n$baz$");
+ printer.Outdent();
+ }
+ EXPECT_EQ("\n\n arg1 bar arg2\n bla", s);
+ }
+ {
+ // Annotations should respect indentation.
+ std::string s;
+ GeneratedCodeInfo info;
+ {
+ StringOutputStream output(&s);
+ AnnotationProtoCollector<GeneratedCodeInfo> info_collector(&info);
+ Printer printer(&output, '$', &info_collector);
+ printer.Indent();
+ GeneratedCodeInfo::Annotation annotation;
+ annotation.set_source_file("file.proto");
+ annotation.add_path(33);
+ std::vector<std::string> args{annotation.SerializeAsString(), "arg1",
+ "arg2"};
+ printer.FormatInternal(args, vars, "$empty $\n\n${1$$2$$}$ $3$\n$baz$");
+ printer.Outdent();
+ }
+ EXPECT_EQ("\n\n arg1 arg2\n bla", s);
+ ASSERT_EQ(1, info.annotation_size());
+ const GeneratedCodeInfo::Annotation* arg1 = &info.annotation(0);
+ ASSERT_EQ(1, arg1->path_size());
+ EXPECT_EQ(33, arg1->path(0));
+ EXPECT_EQ("file.proto", arg1->source_file());
+ EXPECT_EQ(4, arg1->begin());
+ EXPECT_EQ(8, arg1->end());
+ }
+#ifdef PROTOBUF_HAS_DEATH_TEST
+ // Death tests in case of illegal format strings.
+ {
+ // Unused arguments
+ std::string s;
+ StringOutputStream output(&s);
+ Printer printer(&output, '$');
+ EXPECT_DEATH(printer.FormatInternal(args, vars, "$empty $$1$"), "Unused");
+ }
+ {
+ // Wrong order arguments
+ std::string s;
+ StringOutputStream output(&s);
+ Printer printer(&output, '$');
+ EXPECT_DEATH(printer.FormatInternal(args, vars, "$2$ $1$"), "order");
+ }
+ {
+ // Zero is illegal argument
+ std::string s;
+ StringOutputStream output(&s);
+ Printer printer(&output, '$');
+ EXPECT_DEATH(printer.FormatInternal(args, vars, "$0$"), "failed");
+ }
+ {
+ // Argument out of bounds
+ std::string s;
+ StringOutputStream output(&s);
+ Printer printer(&output, '$');
+ EXPECT_DEATH(printer.FormatInternal(args, vars, "$1$ $2$ $3$"), "bounds");
+ }
+ {
+ // Unknown variable
+ std::string s;
+ StringOutputStream output(&s);
+ Printer printer(&output, '$');
+ EXPECT_DEATH(printer.FormatInternal(args, vars, "$huh$ $1$$2$"), "Unknown");
+ }
+ {
+ // Illegal variable
+ std::string s;
+ StringOutputStream output(&s);
+ Printer printer(&output, '$');
+ EXPECT_DEATH(printer.FormatInternal({}, vars, "$ $"), "Empty");
+ }
+#endif // PROTOBUF_HAS_DEATH_TEST
+}
+
+} // namespace io
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/io/strtod.cc b/NorthstarDedicatedTest/include/protobuf/io/strtod.cc
new file mode 100644
index 00000000..427a0761
--- /dev/null
+++ b/NorthstarDedicatedTest/include/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 <io/strtod.h>
+
+#include <cstdio>
+#include <cstring>
+#include <limits>
+#include <string>
+
+#include <stubs/logging.h>
+#include <stubs/common.h>
+
+#include <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/NorthstarDedicatedTest/include/protobuf/io/strtod.h b/NorthstarDedicatedTest/include/protobuf/io/strtod.h
new file mode 100644
index 00000000..38f544af
--- /dev/null
+++ b/NorthstarDedicatedTest/include/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/NorthstarDedicatedTest/include/protobuf/io/tokenizer.cc b/NorthstarDedicatedTest/include/protobuf/io/tokenizer.cc
new file mode 100644
index 00000000..712368f5
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/io/tokenizer.cc
@@ -0,0 +1,1185 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 <io/tokenizer.h>
+
+#include <stubs/common.h>
+#include <stubs/logging.h>
+#include <stubs/stringprintf.h>
+#include <stubs/strutil.h>
+#include <io/strtod.h>
+#include <io/zero_copy_stream.h>
+#include <stubs/stl_util.h>
+
+namespace google {
+namespace protobuf {
+namespace io {
+namespace {
+
+// As mentioned above, I don't trust ctype.h due to the presence of "locales".
+// So, I have written replacement functions here. Someone please smack me if
+// this is a bad idea or if there is some way around this.
+//
+// These "character classes" are designed to be used in template methods.
+// For instance, Tokenizer::ConsumeZeroOrMore<Whitespace>() will eat
+// whitespace.
+
+// Note: No class is allowed to contain '\0', since this is used to mark end-
+// of-input and is handled specially.
+
+#define CHARACTER_CLASS(NAME, EXPRESSION) \
+ class NAME { \
+ public: \
+ static inline bool InClass(char c) { return EXPRESSION; } \
+ }
+
+CHARACTER_CLASS(Whitespace, c == ' ' || c == '\n' || c == '\t' || c == '\r' ||
+ c == '\v' || c == '\f');
+CHARACTER_CLASS(WhitespaceNoNewline,
+ c == ' ' || c == '\t' || c == '\r' || c == '\v' || c == '\f');
+
+CHARACTER_CLASS(Unprintable, c<' ' && c> '\0');
+
+CHARACTER_CLASS(Digit, '0' <= c && c <= '9');
+CHARACTER_CLASS(OctalDigit, '0' <= c && c <= '7');
+CHARACTER_CLASS(HexDigit, ('0' <= c && c <= '9') || ('a' <= c && c <= 'f') ||
+ ('A' <= c && c <= 'F'));
+
+CHARACTER_CLASS(Letter,
+ ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || (c == '_'));
+
+CHARACTER_CLASS(Alphanumeric, ('a' <= c && c <= 'z') ||
+ ('A' <= c && c <= 'Z') ||
+ ('0' <= c && c <= '9') || (c == '_'));
+
+CHARACTER_CLASS(Escape, c == 'a' || c == 'b' || c == 'f' || c == 'n' ||
+ c == 'r' || c == 't' || c == 'v' || c == '\\' ||
+ c == '?' || c == '\'' || c == '\"');
+
+#undef CHARACTER_CLASS
+
+// Given a char, interpret it as a numeric digit and return its value.
+// This supports any number base up to 36.
+inline int DigitValue(char digit) {
+ if ('0' <= digit && digit <= '9') return digit - '0';
+ if ('a' <= digit && digit <= 'z') return digit - 'a' + 10;
+ if ('A' <= digit && digit <= 'Z') return digit - 'A' + 10;
+ return -1;
+}
+
+// Inline because it's only used in one place.
+inline char TranslateEscape(char c) {
+ switch (c) {
+ case 'a':
+ return '\a';
+ case 'b':
+ return '\b';
+ case 'f':
+ return '\f';
+ case 'n':
+ return '\n';
+ case 'r':
+ return '\r';
+ case 't':
+ return '\t';
+ case 'v':
+ return '\v';
+ case '\\':
+ return '\\';
+ case '?':
+ return '\?'; // Trigraphs = :(
+ case '\'':
+ return '\'';
+ case '"':
+ return '\"';
+
+ // We expect escape sequences to have been validated separately.
+ default:
+ return '?';
+ }
+}
+
+} // anonymous namespace
+
+ErrorCollector::~ErrorCollector() {}
+
+// ===================================================================
+
+Tokenizer::Tokenizer(ZeroCopyInputStream* input,
+ ErrorCollector* error_collector)
+ : input_(input),
+ error_collector_(error_collector),
+ buffer_(NULL),
+ buffer_size_(0),
+ buffer_pos_(0),
+ read_error_(false),
+ line_(0),
+ column_(0),
+ record_target_(NULL),
+ record_start_(-1),
+ allow_f_after_float_(false),
+ comment_style_(CPP_COMMENT_STYLE),
+ require_space_after_number_(true),
+ allow_multiline_strings_(false) {
+ current_.line = 0;
+ current_.column = 0;
+ current_.end_column = 0;
+ current_.type = TYPE_START;
+
+ Refresh();
+}
+
+Tokenizer::~Tokenizer() {
+ // If we had any buffer left unread, return it to the underlying stream
+ // so that someone else can read it.
+ if (buffer_size_ > buffer_pos_) {
+ input_->BackUp(buffer_size_ - buffer_pos_);
+ }
+}
+
+bool Tokenizer::report_whitespace() const { return report_whitespace_; }
+// Note: `set_report_whitespace(false)` implies `set_report_newlines(false)`.
+void Tokenizer::set_report_whitespace(bool report) {
+ report_whitespace_ = report;
+ report_newlines_ &= report;
+}
+
+// If true, newline tokens are reported by Next().
+bool Tokenizer::report_newlines() const { return report_newlines_; }
+// Note: `set_report_newlines(true)` implies `set_report_whitespace(true)`.
+void Tokenizer::set_report_newlines(bool report) {
+ report_newlines_ = report;
+ report_whitespace_ |= report; // enable report_whitespace if necessary
+}
+
+// -------------------------------------------------------------------
+// Internal helpers.
+
+void Tokenizer::NextChar() {
+ // Update our line and column counters based on the character being
+ // consumed.
+ if (current_char_ == '\n') {
+ ++line_;
+ column_ = 0;
+ } else if (current_char_ == '\t') {
+ column_ += kTabWidth - column_ % kTabWidth;
+ } else {
+ ++column_;
+ }
+
+ // Advance to the next character.
+ ++buffer_pos_;
+ if (buffer_pos_ < buffer_size_) {
+ current_char_ = buffer_[buffer_pos_];
+ } else {
+ Refresh();
+ }
+}
+
+void Tokenizer::Refresh() {
+ if (read_error_) {
+ current_char_ = '\0';
+ return;
+ }
+
+ // If we're in a token, append the rest of the buffer to it.
+ if (record_target_ != NULL && record_start_ < buffer_size_) {
+ record_target_->append(buffer_ + record_start_,
+ buffer_size_ - record_start_);
+ record_start_ = 0;
+ }
+
+ const void* data = NULL;
+ buffer_ = NULL;
+ buffer_pos_ = 0;
+ do {
+ if (!input_->Next(&data, &buffer_size_)) {
+ // end of stream (or read error)
+ buffer_size_ = 0;
+ read_error_ = true;
+ current_char_ = '\0';
+ return;
+ }
+ } while (buffer_size_ == 0);
+
+ buffer_ = static_cast<const char*>(data);
+
+ current_char_ = buffer_[0];
+}
+
+inline void Tokenizer::RecordTo(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) {
+ // Sadly, we can't just use strtoul() since it is only 32-bit and strtoull()
+ // is non-standard. I hate the C standard library. :(
+
+ // return strtoull(text.c_str(), NULL, 0);
+
+ const char* ptr = text.c_str();
+ int base = 10;
+ if (ptr[0] == '0') {
+ if (ptr[1] == 'x' || ptr[1] == 'X') {
+ // This is hex.
+ base = 16;
+ ptr += 2;
+ } else {
+ // This is octal.
+ base = 8;
+ }
+ }
+
+ uint64_t result = 0;
+ for (; *ptr != '\0'; ptr++) {
+ int digit = DigitValue(*ptr);
+ if (digit < 0 || digit >= base) {
+ // The token provided by Tokenizer is invalid. i.e., 099 is an invalid
+ // token, but Tokenizer still think it's integer.
+ return false;
+ }
+ if (static_cast<uint64_t>(digit) > max_value ||
+ result > (max_value - digit) / base) {
+ // Overflow.
+ return false;
+ }
+ result = result * base + digit;
+ }
+
+ *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
diff --git a/NorthstarDedicatedTest/include/protobuf/io/tokenizer.h b/NorthstarDedicatedTest/include/protobuf/io/tokenizer.h
new file mode 100644
index 00000000..a4059081
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/io/tokenizer.h
@@ -0,0 +1,440 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// Class for parsing tokenized text from a ZeroCopyInputStream.
+
+#ifndef GOOGLE_PROTOBUF_IO_TOKENIZER_H__
+#define GOOGLE_PROTOBUF_IO_TOKENIZER_H__
+
+
+#include <string>
+#include <vector>
+
+#include <stubs/common.h>
+#include <stubs/logging.h>
+#include <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 <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_IO_TOKENIZER_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/io/tokenizer_unittest.cc b/NorthstarDedicatedTest/include/protobuf/io/tokenizer_unittest.cc
new file mode 100644
index 00000000..87e23677
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/io/tokenizer_unittest.cc
@@ -0,0 +1,1073 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 <io/tokenizer.h>
+
+#include <limits.h>
+#include <math.h>
+
+#include <vector>
+
+#include <stubs/common.h>
+#include <stubs/logging.h>
+#include <stubs/strutil.h>
+#include <stubs/substitute.h>
+#include <io/zero_copy_stream_impl.h>
+#include <testing/googletest.h>
+#include <gtest/gtest.h>
+
+namespace google {
+namespace protobuf {
+namespace io {
+namespace {
+
+// ===================================================================
+// Data-Driven Test Infrastructure
+
+// TODO(kenton): This is copied from coded_stream_unittest. This is
+// temporary until these features are integrated into gTest itself.
+
+// TEST_1D and TEST_2D are macros I'd eventually like to see added to
+// gTest. These macros can be used to declare tests which should be
+// run multiple times, once for each item in some input array. TEST_1D
+// tests all cases in a single input array. TEST_2D tests all
+// combinations of cases from two arrays. The arrays must be statically
+// defined such that the GOOGLE_ARRAYSIZE() macro works on them. Example:
+//
+// int kCases[] = {1, 2, 3, 4}
+// TEST_1D(MyFixture, MyTest, kCases) {
+// EXPECT_GT(kCases_case, 0);
+// }
+//
+// This test iterates through the numbers 1, 2, 3, and 4 and tests that
+// they are all grater than zero. In case of failure, the exact case
+// which failed will be printed. The case type must be printable using
+// ostream::operator<<.
+
+#define TEST_1D(FIXTURE, NAME, CASES) \
+ class FIXTURE##_##NAME##_DD : public FIXTURE { \
+ protected: \
+ template <typename CaseType> \
+ void DoSingleCase(const CaseType& CASES##_case); \
+ }; \
+ \
+ TEST_F(FIXTURE##_##NAME##_DD, NAME) { \
+ for (int i = 0; i < GOOGLE_ARRAYSIZE(CASES); i++) { \
+ SCOPED_TRACE(testing::Message() \
+ << #CASES " case #" << i << ": " << CASES[i]); \
+ DoSingleCase(CASES[i]); \
+ } \
+ } \
+ \
+ template <typename CaseType> \
+ void FIXTURE##_##NAME##_DD::DoSingleCase(const CaseType& CASES##_case)
+
+#define TEST_2D(FIXTURE, NAME, CASES1, CASES2) \
+ class FIXTURE##_##NAME##_DD : public FIXTURE { \
+ protected: \
+ template <typename CaseType1, typename CaseType2> \
+ void DoSingleCase(const CaseType1& CASES1##_case, \
+ const CaseType2& CASES2##_case); \
+ }; \
+ \
+ TEST_F(FIXTURE##_##NAME##_DD, NAME) { \
+ for (int i = 0; i < GOOGLE_ARRAYSIZE(CASES1); i++) { \
+ for (int j = 0; j < GOOGLE_ARRAYSIZE(CASES2); j++) { \
+ SCOPED_TRACE(testing::Message() \
+ << #CASES1 " case #" << i << ": " << CASES1[i] << ", " \
+ << #CASES2 " case #" << j << ": " << CASES2[j]); \
+ DoSingleCase(CASES1[i], CASES2[j]); \
+ } \
+ } \
+ } \
+ \
+ template <typename CaseType1, typename CaseType2> \
+ void FIXTURE##_##NAME##_DD::DoSingleCase(const CaseType1& CASES1##_case, \
+ const CaseType2& CASES2##_case)
+
+// -------------------------------------------------------------------
+
+// An input stream that is basically like an ArrayInputStream but sometimes
+// returns empty buffers, just to throw us off.
+class TestInputStream : public ZeroCopyInputStream {
+ public:
+ TestInputStream(const void* data, int size, int block_size)
+ : array_stream_(data, size, block_size), counter_(0) {}
+ ~TestInputStream() {}
+
+ // implements ZeroCopyInputStream ----------------------------------
+ bool Next(const void** data, int* size) override {
+ // We'll return empty buffers starting with the first buffer, and every
+ // 3 and 5 buffers after that.
+ if (counter_ % 3 == 0 || counter_ % 5 == 0) {
+ *data = NULL;
+ *size = 0;
+ ++counter_;
+ return true;
+ } else {
+ ++counter_;
+ return array_stream_.Next(data, size);
+ }
+ }
+
+ void BackUp(int count) override { return array_stream_.BackUp(count); }
+ bool Skip(int count) override { return array_stream_.Skip(count); }
+ int64_t ByteCount() const override { return array_stream_.ByteCount(); }
+
+ private:
+ ArrayInputStream array_stream_;
+ int counter_;
+};
+
+// -------------------------------------------------------------------
+
+// An error collector which simply concatenates all its errors into a big
+// block of text which can be checked.
+class TestErrorCollector : public ErrorCollector {
+ public:
+ TestErrorCollector() {}
+ ~TestErrorCollector() {}
+
+ std::string text_;
+
+ // implements ErrorCollector ---------------------------------------
+ void AddError(int line, int column, const std::string& message) {
+ strings::SubstituteAndAppend(&text_, "$0:$1: $2\n", line, column, message);
+ }
+};
+
+// -------------------------------------------------------------------
+
+// We test each operation over a variety of block sizes to insure that
+// we test cases where reads cross buffer boundaries as well as cases
+// where they don't. This is sort of a brute-force approach to this,
+// but it's easy to write and easy to understand.
+const int kBlockSizes[] = {1, 2, 3, 5, 7, 13, 32, 1024};
+
+class TokenizerTest : public testing::Test {
+ protected:
+ // For easy testing.
+ uint64 ParseInteger(const std::string& text) {
+ uint64 result;
+ EXPECT_TRUE(Tokenizer::ParseInteger(text, kuint64max, &result));
+ return result;
+ }
+};
+
+// ===================================================================
+
+// These tests causes gcc 3.3.5 (and earlier?) to give the cryptic error:
+// "sorry, unimplemented: `method_call_expr' not supported by dump_expr"
+#if !defined(__GNUC__) || __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 3)
+
+// In each test case, the entire input text should parse as a single token
+// of the given type.
+struct SimpleTokenCase {
+ std::string input;
+ Tokenizer::TokenType type;
+};
+
+inline std::ostream& operator<<(std::ostream& out,
+ const SimpleTokenCase& test_case) {
+ return out << CEscape(test_case.input);
+}
+
+SimpleTokenCase kSimpleTokenCases[] = {
+ // Test identifiers.
+ {"hello", Tokenizer::TYPE_IDENTIFIER},
+
+ // Test integers.
+ {"123", Tokenizer::TYPE_INTEGER},
+ {"0xab6", Tokenizer::TYPE_INTEGER},
+ {"0XAB6", Tokenizer::TYPE_INTEGER},
+ {"0X1234567", Tokenizer::TYPE_INTEGER},
+ {"0x89abcdef", Tokenizer::TYPE_INTEGER},
+ {"0x89ABCDEF", Tokenizer::TYPE_INTEGER},
+ {"01234567", Tokenizer::TYPE_INTEGER},
+
+ // Test floats.
+ {"123.45", Tokenizer::TYPE_FLOAT},
+ {"1.", Tokenizer::TYPE_FLOAT},
+ {"1e3", Tokenizer::TYPE_FLOAT},
+ {"1E3", Tokenizer::TYPE_FLOAT},
+ {"1e-3", Tokenizer::TYPE_FLOAT},
+ {"1e+3", Tokenizer::TYPE_FLOAT},
+ {"1.e3", Tokenizer::TYPE_FLOAT},
+ {"1.2e3", Tokenizer::TYPE_FLOAT},
+ {".1", Tokenizer::TYPE_FLOAT},
+ {".1e3", Tokenizer::TYPE_FLOAT},
+ {".1e-3", Tokenizer::TYPE_FLOAT},
+ {".1e+3", Tokenizer::TYPE_FLOAT},
+
+ // Test strings.
+ {"'hello'", Tokenizer::TYPE_STRING},
+ {"\"foo\"", Tokenizer::TYPE_STRING},
+ {"'a\"b'", Tokenizer::TYPE_STRING},
+ {"\"a'b\"", Tokenizer::TYPE_STRING},
+ {"'a\\'b'", Tokenizer::TYPE_STRING},
+ {"\"a\\\"b\"", Tokenizer::TYPE_STRING},
+ {"'\\xf'", Tokenizer::TYPE_STRING},
+ {"'\\0'", Tokenizer::TYPE_STRING},
+
+ // Test symbols.
+ {"+", Tokenizer::TYPE_SYMBOL},
+ {".", Tokenizer::TYPE_SYMBOL},
+};
+
+TEST_2D(TokenizerTest, SimpleTokens, kSimpleTokenCases, kBlockSizes) {
+ // Set up the tokenizer.
+ TestInputStream input(kSimpleTokenCases_case.input.data(),
+ kSimpleTokenCases_case.input.size(), kBlockSizes_case);
+ TestErrorCollector error_collector;
+ Tokenizer tokenizer(&input, &error_collector);
+
+ // Before Next() is called, the initial token should always be TYPE_START.
+ EXPECT_EQ(Tokenizer::TYPE_START, tokenizer.current().type);
+ EXPECT_EQ("", tokenizer.current().text);
+ EXPECT_EQ(0, tokenizer.current().line);
+ EXPECT_EQ(0, tokenizer.current().column);
+ EXPECT_EQ(0, tokenizer.current().end_column);
+
+ // Parse the token.
+ ASSERT_TRUE(tokenizer.Next());
+
+ // Check that it has the right type.
+ EXPECT_EQ(kSimpleTokenCases_case.type, tokenizer.current().type);
+ // Check that it contains the complete input text.
+ EXPECT_EQ(kSimpleTokenCases_case.input, tokenizer.current().text);
+ // Check that it is located at the beginning of the input
+ EXPECT_EQ(0, tokenizer.current().line);
+ EXPECT_EQ(0, tokenizer.current().column);
+ EXPECT_EQ(kSimpleTokenCases_case.input.size(),
+ tokenizer.current().end_column);
+
+ // There should be no more input.
+ EXPECT_FALSE(tokenizer.Next());
+
+ // After Next() returns false, the token should have type TYPE_END.
+ EXPECT_EQ(Tokenizer::TYPE_END, tokenizer.current().type);
+ EXPECT_EQ("", tokenizer.current().text);
+ EXPECT_EQ(0, tokenizer.current().line);
+ EXPECT_EQ(kSimpleTokenCases_case.input.size(), tokenizer.current().column);
+ EXPECT_EQ(kSimpleTokenCases_case.input.size(),
+ tokenizer.current().end_column);
+
+ // There should be no errors.
+ EXPECT_TRUE(error_collector.text_.empty());
+}
+
+TEST_1D(TokenizerTest, FloatSuffix, kBlockSizes) {
+ // Test the "allow_f_after_float" option.
+
+ // Set up the tokenizer.
+ const char* text = "1f 2.5f 6e3f 7F";
+ TestInputStream input(text, strlen(text), kBlockSizes_case);
+ TestErrorCollector error_collector;
+ Tokenizer tokenizer(&input, &error_collector);
+ tokenizer.set_allow_f_after_float(true);
+
+ // Advance through tokens and check that they are parsed as expected.
+ ASSERT_TRUE(tokenizer.Next());
+ EXPECT_EQ(tokenizer.current().text, "1f");
+ EXPECT_EQ(tokenizer.current().type, Tokenizer::TYPE_FLOAT);
+ ASSERT_TRUE(tokenizer.Next());
+ EXPECT_EQ(tokenizer.current().text, "2.5f");
+ EXPECT_EQ(tokenizer.current().type, Tokenizer::TYPE_FLOAT);
+ ASSERT_TRUE(tokenizer.Next());
+ EXPECT_EQ(tokenizer.current().text, "6e3f");
+ EXPECT_EQ(tokenizer.current().type, Tokenizer::TYPE_FLOAT);
+ ASSERT_TRUE(tokenizer.Next());
+ EXPECT_EQ(tokenizer.current().text, "7F");
+ EXPECT_EQ(tokenizer.current().type, Tokenizer::TYPE_FLOAT);
+
+ // There should be no more input.
+ EXPECT_FALSE(tokenizer.Next());
+ // There should be no errors.
+ EXPECT_TRUE(error_collector.text_.empty());
+}
+
+SimpleTokenCase kWhitespaceTokenCases[] = {
+ {" ", Tokenizer::TYPE_WHITESPACE},
+ {" ", Tokenizer::TYPE_WHITESPACE},
+ {"\t", Tokenizer::TYPE_WHITESPACE},
+ {"\v", Tokenizer::TYPE_WHITESPACE},
+ {"\t ", Tokenizer::TYPE_WHITESPACE},
+ {"\v\t", Tokenizer::TYPE_WHITESPACE},
+ {" \t\r", Tokenizer::TYPE_WHITESPACE},
+ // Newlines:
+ {"\n", Tokenizer::TYPE_NEWLINE},
+};
+
+TEST_2D(TokenizerTest, Whitespace, kWhitespaceTokenCases, kBlockSizes) {
+ {
+ TestInputStream input(kWhitespaceTokenCases_case.input.data(),
+ kWhitespaceTokenCases_case.input.size(),
+ kBlockSizes_case);
+ TestErrorCollector error_collector;
+ Tokenizer tokenizer(&input, &error_collector);
+
+ EXPECT_FALSE(tokenizer.Next());
+ }
+ {
+ TestInputStream input(kWhitespaceTokenCases_case.input.data(),
+ kWhitespaceTokenCases_case.input.size(),
+ kBlockSizes_case);
+ TestErrorCollector error_collector;
+ Tokenizer tokenizer(&input, &error_collector);
+ tokenizer.set_report_whitespace(true);
+ tokenizer.set_report_newlines(true);
+
+ ASSERT_TRUE(tokenizer.Next());
+ EXPECT_EQ(tokenizer.current().text, kWhitespaceTokenCases_case.input);
+ EXPECT_EQ(tokenizer.current().type, kWhitespaceTokenCases_case.type);
+
+ EXPECT_FALSE(tokenizer.Next());
+ }
+}
+
+#endif
+
+// -------------------------------------------------------------------
+
+// In each case, the input is parsed to produce a list of tokens. The
+// last token in "output" must have type TYPE_END.
+struct MultiTokenCase {
+ std::string input;
+ std::vector<Tokenizer::Token> output;
+};
+
+inline std::ostream& operator<<(std::ostream& out,
+ const MultiTokenCase& test_case) {
+ return out << CEscape(test_case.input);
+}
+
+MultiTokenCase kMultiTokenCases[] = {
+ // Test empty input.
+ {"",
+ {
+ {Tokenizer::TYPE_END, "", 0, 0, 0},
+ }},
+
+ // Test all token types at the same time.
+ {"foo 1 1.2 + 'bar'",
+ {
+ {Tokenizer::TYPE_IDENTIFIER, "foo", 0, 0, 3},
+ {Tokenizer::TYPE_INTEGER, "1", 0, 4, 5},
+ {Tokenizer::TYPE_FLOAT, "1.2", 0, 6, 9},
+ {Tokenizer::TYPE_SYMBOL, "+", 0, 10, 11},
+ {Tokenizer::TYPE_STRING, "'bar'", 0, 12, 17},
+ {Tokenizer::TYPE_END, "", 0, 17, 17},
+ }},
+
+ // Test that consecutive symbols are parsed as separate tokens.
+ {"!@+%",
+ {
+ {Tokenizer::TYPE_SYMBOL, "!", 0, 0, 1},
+ {Tokenizer::TYPE_SYMBOL, "@", 0, 1, 2},
+ {Tokenizer::TYPE_SYMBOL, "+", 0, 2, 3},
+ {Tokenizer::TYPE_SYMBOL, "%", 0, 3, 4},
+ {Tokenizer::TYPE_END, "", 0, 4, 4},
+ }},
+
+ // Test that newlines affect line numbers correctly.
+ {"foo bar\nrab oof",
+ {
+ {Tokenizer::TYPE_IDENTIFIER, "foo", 0, 0, 3},
+ {Tokenizer::TYPE_IDENTIFIER, "bar", 0, 4, 7},
+ {Tokenizer::TYPE_IDENTIFIER, "rab", 1, 0, 3},
+ {Tokenizer::TYPE_IDENTIFIER, "oof", 1, 4, 7},
+ {Tokenizer::TYPE_END, "", 1, 7, 7},
+ }},
+
+ // Test that tabs affect column numbers correctly.
+ {"foo\tbar \tbaz",
+ {
+ {Tokenizer::TYPE_IDENTIFIER, "foo", 0, 0, 3},
+ {Tokenizer::TYPE_IDENTIFIER, "bar", 0, 8, 11},
+ {Tokenizer::TYPE_IDENTIFIER, "baz", 0, 16, 19},
+ {Tokenizer::TYPE_END, "", 0, 19, 19},
+ }},
+
+ // Test that tabs in string literals affect column numbers correctly.
+ {"\"foo\tbar\" baz",
+ {
+ {Tokenizer::TYPE_STRING, "\"foo\tbar\"", 0, 0, 12},
+ {Tokenizer::TYPE_IDENTIFIER, "baz", 0, 13, 16},
+ {Tokenizer::TYPE_END, "", 0, 16, 16},
+ }},
+
+ // Test that line comments are ignored.
+ {"foo // This is a comment\n"
+ "bar // This is another comment",
+ {
+ {Tokenizer::TYPE_IDENTIFIER, "foo", 0, 0, 3},
+ {Tokenizer::TYPE_IDENTIFIER, "bar", 1, 0, 3},
+ {Tokenizer::TYPE_END, "", 1, 30, 30},
+ }},
+
+ // Test that block comments are ignored.
+ {"foo /* This is a block comment */ bar",
+ {
+ {Tokenizer::TYPE_IDENTIFIER, "foo", 0, 0, 3},
+ {Tokenizer::TYPE_IDENTIFIER, "bar", 0, 34, 37},
+ {Tokenizer::TYPE_END, "", 0, 37, 37},
+ }},
+
+ // Test that sh-style comments are not ignored by default.
+ {"foo # bar\n"
+ "baz",
+ {
+ {Tokenizer::TYPE_IDENTIFIER, "foo", 0, 0, 3},
+ {Tokenizer::TYPE_SYMBOL, "#", 0, 4, 5},
+ {Tokenizer::TYPE_IDENTIFIER, "bar", 0, 6, 9},
+ {Tokenizer::TYPE_IDENTIFIER, "baz", 1, 0, 3},
+ {Tokenizer::TYPE_END, "", 1, 3, 3},
+ }},
+
+ // Test all whitespace chars
+ {"foo\n\t\r\v\fbar",
+ {
+ {Tokenizer::TYPE_IDENTIFIER, "foo", 0, 0, 3},
+ {Tokenizer::TYPE_IDENTIFIER, "bar", 1, 11, 14},
+ {Tokenizer::TYPE_END, "", 1, 14, 14},
+ }},
+};
+
+TEST_2D(TokenizerTest, MultipleTokens, kMultiTokenCases, kBlockSizes) {
+ // Set up the tokenizer.
+ TestInputStream input(kMultiTokenCases_case.input.data(),
+ kMultiTokenCases_case.input.size(), kBlockSizes_case);
+ TestErrorCollector error_collector;
+ Tokenizer tokenizer(&input, &error_collector);
+
+ // Before Next() is called, the initial token should always be TYPE_START.
+ EXPECT_EQ(Tokenizer::TYPE_START, tokenizer.current().type);
+ EXPECT_EQ("", tokenizer.current().text);
+ EXPECT_EQ(0, tokenizer.current().line);
+ EXPECT_EQ(0, tokenizer.current().column);
+ EXPECT_EQ(0, tokenizer.current().end_column);
+
+ // Loop through all expected tokens.
+ int i = 0;
+ Tokenizer::Token token;
+ do {
+ token = kMultiTokenCases_case.output[i++];
+
+ SCOPED_TRACE(testing::Message() << "Token #" << i << ": " << token.text);
+
+ Tokenizer::Token previous = tokenizer.current();
+
+ // Next() should only return false when it hits the end token.
+ if (token.type != Tokenizer::TYPE_END) {
+ ASSERT_TRUE(tokenizer.Next());
+ } else {
+ ASSERT_FALSE(tokenizer.Next());
+ }
+
+ // Check that the previous token is set correctly.
+ EXPECT_EQ(previous.type, tokenizer.previous().type);
+ EXPECT_EQ(previous.text, tokenizer.previous().text);
+ EXPECT_EQ(previous.line, tokenizer.previous().line);
+ EXPECT_EQ(previous.column, tokenizer.previous().column);
+ EXPECT_EQ(previous.end_column, tokenizer.previous().end_column);
+
+ // Check that the token matches the expected one.
+ EXPECT_EQ(token.type, tokenizer.current().type);
+ EXPECT_EQ(token.text, tokenizer.current().text);
+ EXPECT_EQ(token.line, tokenizer.current().line);
+ EXPECT_EQ(token.column, tokenizer.current().column);
+ EXPECT_EQ(token.end_column, tokenizer.current().end_column);
+
+ } while (token.type != Tokenizer::TYPE_END);
+
+ // There should be no errors.
+ EXPECT_TRUE(error_collector.text_.empty());
+}
+
+MultiTokenCase kMultiWhitespaceTokenCases[] = {
+ // Test all token types at the same time.
+ {"foo 1 \t1.2 \n +\v'bar'",
+ {
+ {Tokenizer::TYPE_IDENTIFIER, "foo", 0, 0, 3},
+ {Tokenizer::TYPE_WHITESPACE, " ", 0, 3, 4},
+ {Tokenizer::TYPE_INTEGER, "1", 0, 4, 5},
+ {Tokenizer::TYPE_WHITESPACE, " \t", 0, 5, 8},
+ {Tokenizer::TYPE_FLOAT, "1.2", 0, 8, 11},
+ {Tokenizer::TYPE_WHITESPACE, " ", 0, 11, 13},
+ {Tokenizer::TYPE_NEWLINE, "\n", 0, 13, 0},
+ {Tokenizer::TYPE_WHITESPACE, " ", 1, 0, 3},
+ {Tokenizer::TYPE_SYMBOL, "+", 1, 3, 4},
+ {Tokenizer::TYPE_WHITESPACE, "\v", 1, 4, 5},
+ {Tokenizer::TYPE_STRING, "'bar'", 1, 5, 10},
+ {Tokenizer::TYPE_END, "", 1, 10, 10},
+ }},
+
+};
+
+TEST_2D(TokenizerTest, MultipleWhitespaceTokens, kMultiWhitespaceTokenCases,
+ kBlockSizes) {
+ // Set up the tokenizer.
+ TestInputStream input(kMultiWhitespaceTokenCases_case.input.data(),
+ kMultiWhitespaceTokenCases_case.input.size(),
+ kBlockSizes_case);
+ TestErrorCollector error_collector;
+ Tokenizer tokenizer(&input, &error_collector);
+ tokenizer.set_report_whitespace(true);
+ tokenizer.set_report_newlines(true);
+
+ // Before Next() is called, the initial token should always be TYPE_START.
+ EXPECT_EQ(Tokenizer::TYPE_START, tokenizer.current().type);
+ EXPECT_EQ("", tokenizer.current().text);
+ EXPECT_EQ(0, tokenizer.current().line);
+ EXPECT_EQ(0, tokenizer.current().column);
+ EXPECT_EQ(0, tokenizer.current().end_column);
+
+ // Loop through all expected tokens.
+ int i = 0;
+ Tokenizer::Token token;
+ do {
+ token = kMultiWhitespaceTokenCases_case.output[i++];
+
+ SCOPED_TRACE(testing::Message() << "Token #" << i << ": " << token.text);
+
+ Tokenizer::Token previous = tokenizer.current();
+
+ // Next() should only return false when it hits the end token.
+ if (token.type != Tokenizer::TYPE_END) {
+ ASSERT_TRUE(tokenizer.Next());
+ } else {
+ ASSERT_FALSE(tokenizer.Next());
+ }
+
+ // Check that the previous token is set correctly.
+ EXPECT_EQ(previous.type, tokenizer.previous().type);
+ EXPECT_EQ(previous.text, tokenizer.previous().text);
+ EXPECT_EQ(previous.line, tokenizer.previous().line);
+ EXPECT_EQ(previous.column, tokenizer.previous().column);
+ EXPECT_EQ(previous.end_column, tokenizer.previous().end_column);
+
+ // Check that the token matches the expected one.
+ EXPECT_EQ(token.type, tokenizer.current().type);
+ EXPECT_EQ(token.text, tokenizer.current().text);
+ EXPECT_EQ(token.line, tokenizer.current().line);
+ EXPECT_EQ(token.column, tokenizer.current().column);
+ EXPECT_EQ(token.end_column, tokenizer.current().end_column);
+
+ } while (token.type != Tokenizer::TYPE_END);
+
+ // There should be no errors.
+ EXPECT_TRUE(error_collector.text_.empty());
+}
+
+// This test causes gcc 3.3.5 (and earlier?) to give the cryptic error:
+// "sorry, unimplemented: `method_call_expr' not supported by dump_expr"
+#if !defined(__GNUC__) || __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 3)
+
+TEST_1D(TokenizerTest, ShCommentStyle, kBlockSizes) {
+ // Test the "comment_style" option.
+
+ const char* text =
+ "foo # bar\n"
+ "baz // qux\n"
+ "corge /* grault */\n"
+ "garply";
+ const char* const kTokens[] = {"foo", // "# bar" is ignored
+ "baz", "/", "/", "qux", "corge", "/",
+ "*", "grault", "*", "/", "garply"};
+
+ // Set up the tokenizer.
+ TestInputStream input(text, strlen(text), kBlockSizes_case);
+ TestErrorCollector error_collector;
+ Tokenizer tokenizer(&input, &error_collector);
+ tokenizer.set_comment_style(Tokenizer::SH_COMMENT_STYLE);
+
+ // Advance through tokens and check that they are parsed as expected.
+ for (int i = 0; i < GOOGLE_ARRAYSIZE(kTokens); i++) {
+ EXPECT_TRUE(tokenizer.Next());
+ EXPECT_EQ(tokenizer.current().text, kTokens[i]);
+ }
+
+ // There should be no more input.
+ EXPECT_FALSE(tokenizer.Next());
+ // There should be no errors.
+ EXPECT_TRUE(error_collector.text_.empty());
+}
+
+#endif
+
+// -------------------------------------------------------------------
+
+// In each case, the input is expected to have two tokens named "prev" and
+// "next" with comments in between.
+struct DocCommentCase {
+ std::string input;
+
+ const char* prev_trailing_comments;
+ const char* detached_comments[10];
+ const char* next_leading_comments;
+};
+
+inline std::ostream& operator<<(std::ostream& out,
+ const DocCommentCase& test_case) {
+ return out << CEscape(test_case.input);
+}
+
+DocCommentCase kDocCommentCases[] = {
+ {"prev next",
+
+ "",
+ {},
+ ""},
+
+ {"prev /* ignored */ next",
+
+ "",
+ {},
+ ""},
+
+ {"prev // trailing comment\n"
+ "next",
+
+ " trailing comment\n",
+ {},
+ ""},
+
+ {"prev\n"
+ "// leading comment\n"
+ "// line 2\n"
+ "next",
+
+ "",
+ {},
+ " leading comment\n"
+ " line 2\n"},
+
+ {"prev\n"
+ "// trailing comment\n"
+ "// line 2\n"
+ "\n"
+ "next",
+
+ " trailing comment\n"
+ " line 2\n",
+ {},
+ ""},
+
+ {"prev // trailing comment\n"
+ "// leading comment\n"
+ "// line 2\n"
+ "next",
+
+ " trailing comment\n",
+ {},
+ " leading comment\n"
+ " line 2\n"},
+
+ {"prev /* trailing block comment */\n"
+ "/* leading block comment\n"
+ " * line 2\n"
+ " * line 3 */"
+ "next",
+
+ " trailing block comment ",
+ {},
+ " leading block comment\n"
+ " line 2\n"
+ " line 3 "},
+
+ {"prev\n"
+ "/* trailing block comment\n"
+ " * line 2\n"
+ " * line 3\n"
+ " */\n"
+ "/* leading block comment\n"
+ " * line 2\n"
+ " * line 3 */"
+ "next",
+
+ " trailing block comment\n"
+ " line 2\n"
+ " line 3\n",
+ {},
+ " leading block comment\n"
+ " line 2\n"
+ " line 3 "},
+
+ {"prev\n"
+ "// trailing comment\n"
+ "\n"
+ "// detached comment\n"
+ "// line 2\n"
+ "\n"
+ "// second detached comment\n"
+ "/* third detached comment\n"
+ " * line 2 */\n"
+ "// leading comment\n"
+ "next",
+
+ " trailing comment\n",
+ {" detached comment\n"
+ " line 2\n",
+ " second detached comment\n",
+ " third detached comment\n"
+ " line 2 "},
+ " leading comment\n"},
+
+ {"prev /**/\n"
+ "\n"
+ "// detached comment\n"
+ "\n"
+ "// leading comment\n"
+ "next",
+
+ "",
+ {" detached comment\n"},
+ " leading comment\n"},
+
+ {"prev /**/\n"
+ "// leading comment\n"
+ "next",
+
+ "",
+ {},
+ " leading comment\n"},
+};
+
+TEST_2D(TokenizerTest, DocComments, kDocCommentCases, kBlockSizes) {
+ // Set up the tokenizer.
+ TestInputStream input(kDocCommentCases_case.input.data(),
+ kDocCommentCases_case.input.size(), kBlockSizes_case);
+ TestErrorCollector error_collector;
+ Tokenizer tokenizer(&input, &error_collector);
+
+ // Set up a second tokenizer where we'll pass all NULLs to NextWithComments().
+ TestInputStream input2(kDocCommentCases_case.input.data(),
+ kDocCommentCases_case.input.size(), kBlockSizes_case);
+ Tokenizer tokenizer2(&input2, &error_collector);
+
+ tokenizer.Next();
+ tokenizer2.Next();
+
+ EXPECT_EQ("prev", tokenizer.current().text);
+ EXPECT_EQ("prev", tokenizer2.current().text);
+
+ std::string prev_trailing_comments;
+ std::vector<std::string> detached_comments;
+ std::string next_leading_comments;
+ tokenizer.NextWithComments(&prev_trailing_comments, &detached_comments,
+ &next_leading_comments);
+ tokenizer2.NextWithComments(NULL, NULL, NULL);
+ EXPECT_EQ("next", tokenizer.current().text);
+ EXPECT_EQ("next", tokenizer2.current().text);
+
+ EXPECT_EQ(kDocCommentCases_case.prev_trailing_comments,
+ prev_trailing_comments);
+
+ for (int i = 0; i < detached_comments.size(); i++) {
+ ASSERT_LT(i, GOOGLE_ARRAYSIZE(kDocCommentCases));
+ ASSERT_TRUE(kDocCommentCases_case.detached_comments[i] != NULL);
+ EXPECT_EQ(kDocCommentCases_case.detached_comments[i], detached_comments[i]);
+ }
+
+ // Verify that we matched all the detached comments.
+ EXPECT_EQ(NULL,
+ kDocCommentCases_case.detached_comments[detached_comments.size()]);
+
+ EXPECT_EQ(kDocCommentCases_case.next_leading_comments, next_leading_comments);
+}
+
+// -------------------------------------------------------------------
+
+// Test parse helpers. It's not really worth setting up a full data-driven
+// test here.
+TEST_F(TokenizerTest, ParseInteger) {
+ EXPECT_EQ(0, ParseInteger("0"));
+ EXPECT_EQ(123, ParseInteger("123"));
+ EXPECT_EQ(0xabcdef12u, ParseInteger("0xabcdef12"));
+ EXPECT_EQ(0xabcdef12u, ParseInteger("0xABCDEF12"));
+ EXPECT_EQ(kuint64max, ParseInteger("0xFFFFFFFFFFFFFFFF"));
+ EXPECT_EQ(01234567, ParseInteger("01234567"));
+ EXPECT_EQ(0X123, ParseInteger("0X123"));
+
+ // Test invalid integers that may still be tokenized as integers.
+ EXPECT_EQ(0, ParseInteger("0x"));
+
+ uint64 i;
+
+ // Test invalid integers that will never be tokenized as integers.
+ EXPECT_FALSE(Tokenizer::ParseInteger("zxy", kuint64max, &i));
+ EXPECT_FALSE(Tokenizer::ParseInteger("1.2", kuint64max, &i));
+ EXPECT_FALSE(Tokenizer::ParseInteger("08", kuint64max, &i));
+ EXPECT_FALSE(Tokenizer::ParseInteger("0xg", kuint64max, &i));
+ EXPECT_FALSE(Tokenizer::ParseInteger("-1", kuint64max, &i));
+
+ // Test overflows.
+ EXPECT_TRUE(Tokenizer::ParseInteger("0", 0, &i));
+ EXPECT_FALSE(Tokenizer::ParseInteger("1", 0, &i));
+ EXPECT_TRUE(Tokenizer::ParseInteger("1", 1, &i));
+ EXPECT_TRUE(Tokenizer::ParseInteger("12345", 12345, &i));
+ EXPECT_FALSE(Tokenizer::ParseInteger("12346", 12345, &i));
+ EXPECT_TRUE(Tokenizer::ParseInteger("0xFFFFFFFFFFFFFFFF", kuint64max, &i));
+ EXPECT_FALSE(Tokenizer::ParseInteger("0x10000000000000000", kuint64max, &i));
+}
+
+TEST_F(TokenizerTest, ParseFloat) {
+ EXPECT_DOUBLE_EQ(1, Tokenizer::ParseFloat("1."));
+ EXPECT_DOUBLE_EQ(1e3, Tokenizer::ParseFloat("1e3"));
+ EXPECT_DOUBLE_EQ(1e3, Tokenizer::ParseFloat("1E3"));
+ EXPECT_DOUBLE_EQ(1.5e3, Tokenizer::ParseFloat("1.5e3"));
+ EXPECT_DOUBLE_EQ(.1, Tokenizer::ParseFloat(".1"));
+ EXPECT_DOUBLE_EQ(.25, Tokenizer::ParseFloat(".25"));
+ EXPECT_DOUBLE_EQ(.1e3, Tokenizer::ParseFloat(".1e3"));
+ EXPECT_DOUBLE_EQ(.25e3, Tokenizer::ParseFloat(".25e3"));
+ EXPECT_DOUBLE_EQ(.1e+3, Tokenizer::ParseFloat(".1e+3"));
+ EXPECT_DOUBLE_EQ(.1e-3, Tokenizer::ParseFloat(".1e-3"));
+ EXPECT_DOUBLE_EQ(5, Tokenizer::ParseFloat("5"));
+ EXPECT_DOUBLE_EQ(6e-12, Tokenizer::ParseFloat("6e-12"));
+ EXPECT_DOUBLE_EQ(1.2, Tokenizer::ParseFloat("1.2"));
+ EXPECT_DOUBLE_EQ(1.e2, Tokenizer::ParseFloat("1.e2"));
+
+ // Test invalid integers that may still be tokenized as integers.
+ EXPECT_DOUBLE_EQ(1, Tokenizer::ParseFloat("1e"));
+ EXPECT_DOUBLE_EQ(1, Tokenizer::ParseFloat("1e-"));
+ EXPECT_DOUBLE_EQ(1, Tokenizer::ParseFloat("1.e"));
+
+ // Test 'f' suffix.
+ EXPECT_DOUBLE_EQ(1, Tokenizer::ParseFloat("1f"));
+ EXPECT_DOUBLE_EQ(1, Tokenizer::ParseFloat("1.0f"));
+ EXPECT_DOUBLE_EQ(1, Tokenizer::ParseFloat("1F"));
+
+ // These should parse successfully even though they are out of range.
+ // Overflows become infinity and underflows become zero.
+ EXPECT_EQ(0.0, Tokenizer::ParseFloat("1e-9999999999999999999999999999"));
+ EXPECT_EQ(HUGE_VAL, Tokenizer::ParseFloat("1e+9999999999999999999999999999"));
+
+#ifdef PROTOBUF_HAS_DEATH_TEST // death tests do not work on Windows yet
+ // Test invalid integers that will never be tokenized as integers.
+ EXPECT_DEBUG_DEATH(
+ Tokenizer::ParseFloat("zxy"),
+ "passed text that could not have been tokenized as a float");
+ EXPECT_DEBUG_DEATH(
+ Tokenizer::ParseFloat("1-e0"),
+ "passed text that could not have been tokenized as a float");
+ EXPECT_DEBUG_DEATH(
+ Tokenizer::ParseFloat("-1.0"),
+ "passed text that could not have been tokenized as a float");
+#endif // PROTOBUF_HAS_DEATH_TEST
+}
+
+TEST_F(TokenizerTest, ParseString) {
+ std::string output;
+ Tokenizer::ParseString("'hello'", &output);
+ EXPECT_EQ("hello", output);
+ Tokenizer::ParseString("\"blah\\nblah2\"", &output);
+ EXPECT_EQ("blah\nblah2", output);
+ Tokenizer::ParseString("'\\1x\\1\\123\\739\\52\\334n\\3'", &output);
+ EXPECT_EQ("\1x\1\123\739\52\334n\3", output);
+ Tokenizer::ParseString("'\\x20\\x4'", &output);
+ EXPECT_EQ("\x20\x4", output);
+
+ // Test invalid strings that may still be tokenized as strings.
+ Tokenizer::ParseString("\"\\a\\l\\v\\t", &output); // \l is invalid
+ EXPECT_EQ("\a?\v\t", output);
+ Tokenizer::ParseString("'", &output);
+ EXPECT_EQ("", output);
+ Tokenizer::ParseString("'\\", &output);
+ EXPECT_EQ("\\", output);
+
+ // Experiment with Unicode escapes. Here are one-, two- and three-byte Unicode
+ // characters.
+ Tokenizer::ParseString("'\\u0024\\u00a2\\u20ac\\U00024b62XX'", &output);
+ EXPECT_EQ("$¢€𤭢XX", output);
+ // Same thing encoded using UTF16.
+ Tokenizer::ParseString("'\\u0024\\u00a2\\u20ac\\ud852\\udf62XX'", &output);
+ EXPECT_EQ("$¢€𤭢XX", output);
+ // Here's some broken UTF16; there's a head surrogate with no tail surrogate.
+ // We just output this as if it were UTF8; it's not a defined code point, but
+ // it has a defined encoding.
+ Tokenizer::ParseString("'\\ud852XX'", &output);
+ EXPECT_EQ("\xed\xa1\x92XX", output);
+ // Malformed escape: Demons may fly out of the nose.
+ Tokenizer::ParseString("'\\u0'", &output);
+ EXPECT_EQ("u0", output);
+ // Beyond the range of valid UTF-32 code units.
+ Tokenizer::ParseString("'\\U00110000\\U00200000\\UFFFFFFFF'", &output);
+ EXPECT_EQ("\\U00110000\\U00200000\\Uffffffff", output);
+
+ // Test invalid strings that will never be tokenized as strings.
+#ifdef PROTOBUF_HAS_DEATH_TEST // death tests do not work on Windows yet
+ EXPECT_DEBUG_DEATH(
+ Tokenizer::ParseString("", &output),
+ "passed text that could not have been tokenized as a string");
+#endif // PROTOBUF_HAS_DEATH_TEST
+}
+
+TEST_F(TokenizerTest, ParseStringAppend) {
+ // Check that ParseString and ParseStringAppend differ.
+ std::string output("stuff+");
+ Tokenizer::ParseStringAppend("'hello'", &output);
+ EXPECT_EQ("stuff+hello", output);
+ Tokenizer::ParseString("'hello'", &output);
+ EXPECT_EQ("hello", output);
+}
+
+// -------------------------------------------------------------------
+
+// Each case parses some input text, ignoring the tokens produced, and
+// checks that the error output matches what is expected.
+struct ErrorCase {
+ std::string input;
+ bool recoverable; // True if the tokenizer should be able to recover and
+ // parse more tokens after seeing this error. Cases
+ // for which this is true must end with "foo" as
+ // the last token, which the test will check for.
+ const char* errors;
+};
+
+inline std::ostream& operator<<(std::ostream& out, const ErrorCase& test_case) {
+ return out << CEscape(test_case.input);
+}
+
+ErrorCase kErrorCases[] = {
+ // String errors.
+ {"'\\l' foo", true, "0:2: Invalid escape sequence in string literal.\n"},
+ {"'\\X' foo", true, "0:2: Invalid escape sequence in string literal.\n"},
+ {"'\\x' foo", true, "0:3: Expected hex digits for escape sequence.\n"},
+ {"'foo", false, "0:4: Unexpected end of string.\n"},
+ {"'bar\nfoo", true, "0:4: String literals cannot cross line boundaries.\n"},
+ {"'\\u01' foo", true,
+ "0:5: Expected four hex digits for \\u escape sequence.\n"},
+ {"'\\u01' foo", true,
+ "0:5: Expected four hex digits for \\u escape sequence.\n"},
+ {"'\\uXYZ' foo", true,
+ "0:3: Expected four hex digits for \\u escape sequence.\n"},
+
+ // Integer errors.
+ {"123foo", true, "0:3: Need space between number and identifier.\n"},
+
+ // Hex/octal errors.
+ {"0x foo", true, "0:2: \"0x\" must be followed by hex digits.\n"},
+ {"0541823 foo", true,
+ "0:4: Numbers starting with leading zero must be in octal.\n"},
+ {"0x123z foo", true, "0:5: Need space between number and identifier.\n"},
+ {"0x123.4 foo", true, "0:5: Hex and octal numbers must be integers.\n"},
+ {"0123.4 foo", true, "0:4: Hex and octal numbers must be integers.\n"},
+
+ // Float errors.
+ {"1e foo", true, "0:2: \"e\" must be followed by exponent.\n"},
+ {"1e- foo", true, "0:3: \"e\" must be followed by exponent.\n"},
+ {"1.2.3 foo", true,
+ "0:3: Already saw decimal point or exponent; can't have another one.\n"},
+ {"1e2.3 foo", true,
+ "0:3: Already saw decimal point or exponent; can't have another one.\n"},
+ {"a.1 foo", true,
+ "0:1: Need space between identifier and decimal point.\n"},
+ // allow_f_after_float not enabled, so this should be an error.
+ {"1.0f foo", true, "0:3: Need space between number and identifier.\n"},
+
+ // Block comment errors.
+ {"/*", false,
+ "0:2: End-of-file inside block comment.\n"
+ "0:0: Comment started here.\n"},
+ {"/*/*/ foo", true,
+ "0:3: \"/*\" inside block comment. Block comments cannot be nested.\n"},
+
+ // Control characters. Multiple consecutive control characters should only
+ // produce one error.
+ {"\b foo", true, "0:0: Invalid control characters encountered in text.\n"},
+ {"\b\b foo", true,
+ "0:0: Invalid control characters encountered in text.\n"},
+
+ // Check that control characters at end of input don't result in an
+ // infinite loop.
+ {"\b", false, "0:0: Invalid control characters encountered in text.\n"},
+
+ // Check recovery from '\0'. We have to explicitly specify the length of
+ // these strings because otherwise the string constructor will just call
+ // strlen() which will see the first '\0' and think that is the end of the
+ // string.
+ {std::string("\0foo", 4), true,
+ "0:0: Invalid control characters encountered in text.\n"},
+ {std::string("\0\0foo", 5), true,
+ "0:0: Invalid control characters encountered in text.\n"},
+
+ // Check error from high order bits set
+ {"\300foo", true, "0:0: Interpreting non ascii codepoint 192.\n"},
+};
+
+TEST_2D(TokenizerTest, Errors, kErrorCases, kBlockSizes) {
+ // Set up the tokenizer.
+ TestInputStream input(kErrorCases_case.input.data(),
+ kErrorCases_case.input.size(), kBlockSizes_case);
+ TestErrorCollector error_collector;
+ Tokenizer tokenizer(&input, &error_collector);
+
+ // Ignore all input, except remember if the last token was "foo".
+ bool last_was_foo = false;
+ while (tokenizer.Next()) {
+ last_was_foo = tokenizer.current().text == "foo";
+ }
+
+ // Check that the errors match what was expected.
+ EXPECT_EQ(kErrorCases_case.errors, error_collector.text_);
+
+ // If the error was recoverable, make sure we saw "foo" after it.
+ if (kErrorCases_case.recoverable) {
+ EXPECT_TRUE(last_was_foo);
+ }
+}
+
+// -------------------------------------------------------------------
+
+TEST_1D(TokenizerTest, BackUpOnDestruction, kBlockSizes) {
+ std::string text = "foo bar";
+ TestInputStream input(text.data(), text.size(), kBlockSizes_case);
+
+ // Create a tokenizer, read one token, then destroy it.
+ {
+ TestErrorCollector error_collector;
+ Tokenizer tokenizer(&input, &error_collector);
+
+ tokenizer.Next();
+ }
+
+ // Only "foo" should have been read.
+ EXPECT_EQ(strlen("foo"), input.ByteCount());
+}
+
+
+} // namespace
+} // namespace io
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/io/zero_copy_stream.cc b/NorthstarDedicatedTest/include/protobuf/io/zero_copy_stream.cc
new file mode 100644
index 00000000..a44c87b6
--- /dev/null
+++ b/NorthstarDedicatedTest/include/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 <io/zero_copy_stream.h>
+
+#include <stubs/logging.h>
+#include <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/NorthstarDedicatedTest/include/protobuf/io/zero_copy_stream.h b/NorthstarDedicatedTest/include/protobuf/io/zero_copy_stream.h
new file mode 100644
index 00000000..a29f75c0
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/io/zero_copy_stream.h
@@ -0,0 +1,253 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// This file contains the ZeroCopyInputStream and ZeroCopyOutputStream
+// interfaces, which represent abstract I/O streams to and from which
+// protocol buffers can be read and written. For a few simple
+// implementations of these interfaces, see zero_copy_stream_impl.h.
+//
+// These interfaces are different from classic I/O streams in that they
+// try to minimize the amount of data copying that needs to be done.
+// To accomplish this, responsibility for allocating buffers is moved to
+// the stream object, rather than being the responsibility of the caller.
+// So, the stream can return a buffer which actually points directly into
+// the final data structure where the bytes are to be stored, and the caller
+// can interact directly with that buffer, eliminating an intermediate copy
+// operation.
+//
+// As an example, consider the common case in which you are reading bytes
+// from an array that is already in memory (or perhaps an mmap()ed file).
+// With classic I/O streams, you would do something like:
+// char buffer[BUFFER_SIZE];
+// input->Read(buffer, BUFFER_SIZE);
+// DoSomething(buffer, BUFFER_SIZE);
+// Then, the stream basically just calls memcpy() to copy the data from
+// the array into your buffer. With a ZeroCopyInputStream, you would do
+// this instead:
+// const void* buffer;
+// int size;
+// input->Next(&buffer, &size);
+// DoSomething(buffer, size);
+// Here, no copy is performed. The input stream returns a pointer directly
+// into the backing array, and the caller ends up reading directly from it.
+//
+// If you want to be able to read the old-fashion way, you can create
+// a CodedInputStream or CodedOutputStream wrapping these objects and use
+// their ReadRaw()/WriteRaw() methods. These will, of course, add a copy
+// step, but Coded*Stream will handle buffering so at least it will be
+// reasonably efficient.
+//
+// ZeroCopyInputStream example:
+// // Read in a file and print its contents to stdout.
+// int fd = open("myfile", O_RDONLY);
+// ZeroCopyInputStream* input = new FileInputStream(fd);
+//
+// const void* buffer;
+// int size;
+// while (input->Next(&buffer, &size)) {
+// cout.write(buffer, size);
+// }
+//
+// delete input;
+// close(fd);
+//
+// ZeroCopyOutputStream example:
+// // Copy the contents of "infile" to "outfile", using plain read() for
+// // "infile" but a ZeroCopyOutputStream for "outfile".
+// int infd = open("infile", O_RDONLY);
+// int outfd = open("outfile", O_WRONLY);
+// ZeroCopyOutputStream* output = new FileOutputStream(outfd);
+//
+// void* buffer;
+// int size;
+// while (output->Next(&buffer, &size)) {
+// int bytes = read(infd, buffer, size);
+// if (bytes < size) {
+// // Reached EOF.
+// output->BackUp(size - bytes);
+// break;
+// }
+// }
+//
+// delete output;
+// close(infd);
+// close(outfd);
+
+#ifndef GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_H__
+#define GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_H__
+
+
+#include <string>
+
+#include <stubs/common.h>
+#include <port_def.inc>
+
+
+namespace google {
+namespace protobuf {
+namespace io {
+
+// Defined in this file.
+class ZeroCopyInputStream;
+class ZeroCopyOutputStream;
+
+// Abstract interface similar to an input stream but designed to minimize
+// copying.
+class PROTOBUF_EXPORT ZeroCopyInputStream {
+ public:
+ ZeroCopyInputStream() {}
+ virtual ~ZeroCopyInputStream() {}
+
+ // Obtains a chunk of data from the stream.
+ //
+ // Preconditions:
+ // * "size" and "data" are not NULL.
+ //
+ // Postconditions:
+ // * If the returned value is false, there is no more data to return or
+ // an error occurred. All errors are permanent.
+ // * Otherwise, "size" points to the actual number of bytes read and "data"
+ // points to a pointer to a buffer containing these bytes.
+ // * Ownership of this buffer remains with the stream, and the buffer
+ // remains valid only until some other method of the stream is called
+ // or the stream is destroyed.
+ // * It is legal for the returned buffer to have zero size, as long
+ // as repeatedly calling Next() eventually yields a buffer with non-zero
+ // size.
+ virtual bool Next(const void** data, int* size) = 0;
+
+ // Backs up a number of bytes, so that the next call to Next() returns
+ // data again that was already returned by the last call to Next(). This
+ // is useful when writing procedures that are only supposed to read up
+ // to a certain point in the input, then return. If Next() returns a
+ // buffer that goes beyond what you wanted to read, you can use BackUp()
+ // to return to the point where you intended to finish.
+ //
+ // Preconditions:
+ // * The last method called must have been Next().
+ // * count must be less than or equal to the size of the last buffer
+ // returned by Next().
+ //
+ // Postconditions:
+ // * The last "count" bytes of the last buffer returned by Next() will be
+ // pushed back into the stream. Subsequent calls to Next() will return
+ // the same data again before producing new data.
+ virtual void BackUp(int count) = 0;
+
+ // Skips a number of bytes. Returns false if the end of the stream is
+ // reached or some input error occurred. In the end-of-stream case, the
+ // stream is advanced to the end of the stream (so ByteCount() will return
+ // the total size of the stream).
+ virtual bool Skip(int count) = 0;
+
+ // Returns the total number of bytes read since this object was created.
+ virtual int64_t ByteCount() const = 0;
+
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ZeroCopyInputStream);
+};
+
+// Abstract interface similar to an output stream but designed to minimize
+// copying.
+class PROTOBUF_EXPORT ZeroCopyOutputStream {
+ public:
+ ZeroCopyOutputStream() {}
+ virtual ~ZeroCopyOutputStream() {}
+
+ // Obtains a buffer into which data can be written. Any data written
+ // into this buffer will eventually (maybe instantly, maybe later on)
+ // be written to the output.
+ //
+ // Preconditions:
+ // * "size" and "data" are not NULL.
+ //
+ // Postconditions:
+ // * If the returned value is false, an error occurred. All errors are
+ // permanent.
+ // * Otherwise, "size" points to the actual number of bytes in the buffer
+ // and "data" points to the buffer.
+ // * Ownership of this buffer remains with the stream, and the buffer
+ // remains valid only until some other method of the stream is called
+ // or the stream is destroyed.
+ // * Any data which the caller stores in this buffer will eventually be
+ // written to the output (unless BackUp() is called).
+ // * It is legal for the returned buffer to have zero size, as long
+ // as repeatedly calling Next() eventually yields a buffer with non-zero
+ // size.
+ virtual bool Next(void** data, int* size) = 0;
+
+ // Backs up a number of bytes, so that the end of the last buffer returned
+ // by Next() is not actually written. This is needed when you finish
+ // writing all the data you want to write, but the last buffer was bigger
+ // than you needed. You don't want to write a bunch of garbage after the
+ // end of your data, so you use BackUp() to back up.
+ //
+ // Preconditions:
+ // * The last method called must have been Next().
+ // * count must be less than or equal to the size of the last buffer
+ // returned by Next().
+ // * The caller must not have written anything to the last "count" bytes
+ // of that buffer.
+ //
+ // Postconditions:
+ // * The last "count" bytes of the last buffer returned by Next() will be
+ // ignored.
+ virtual void BackUp(int count) = 0;
+
+ // Returns the total number of bytes written since this object was created.
+ virtual int64_t ByteCount() const = 0;
+
+ // Write a given chunk of data to the output. Some output streams may
+ // implement this in a way that avoids copying. Check AllowsAliasing() before
+ // calling WriteAliasedRaw(). It will GOOGLE_CHECK fail if WriteAliasedRaw() is
+ // called on a stream that does not allow aliasing.
+ //
+ // NOTE: It is caller's responsibility to ensure that the chunk of memory
+ // remains live until all of the data has been consumed from the stream.
+ virtual bool WriteAliasedRaw(const void* data, int size);
+ virtual bool AllowsAliasing() const { return false; }
+
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ZeroCopyOutputStream);
+};
+
+} // namespace io
+} // namespace protobuf
+} // namespace google
+
+#include <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/io/zero_copy_stream_impl.cc b/NorthstarDedicatedTest/include/protobuf/io/zero_copy_stream_impl.cc
new file mode 100644
index 00000000..fffa3b5d
--- /dev/null
+++ b/NorthstarDedicatedTest/include/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 <stubs/common.h>
+#include <stubs/logging.h>
+#include <io/io_win32.h>
+#include <io/zero_copy_stream_impl.h>
+#include <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/NorthstarDedicatedTest/include/protobuf/io/zero_copy_stream_impl.h b/NorthstarDedicatedTest/include/protobuf/io/zero_copy_stream_impl.h
new file mode 100644
index 00000000..c7d34c61
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/io/zero_copy_stream_impl.h
@@ -0,0 +1,327 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// This file contains common implementations of the interfaces defined in
+// zero_copy_stream.h which are only included in the full (non-lite)
+// protobuf library. These implementations include Unix file descriptors
+// and C++ iostreams. See also: zero_copy_stream_impl_lite.h
+
+#ifndef GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_IMPL_H__
+#define GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_IMPL_H__
+
+
+#include <iosfwd>
+#include <string>
+
+#include <stubs/common.h>
+#include <io/zero_copy_stream.h>
+#include <io/zero_copy_stream_impl_lite.h>
+
+#include <port_def.inc>
+
+namespace google {
+namespace protobuf {
+namespace io {
+
+// ===================================================================
+
+// A ZeroCopyInputStream which reads from a file descriptor.
+//
+// FileInputStream is preferred over using an ifstream with IstreamInputStream.
+// The latter will introduce an extra layer of buffering, harming performance.
+// Also, it's conceivable that FileInputStream could someday be enhanced
+// to use zero-copy file descriptors on OSs which support them.
+class PROTOBUF_EXPORT FileInputStream : public ZeroCopyInputStream {
+ public:
+ // Creates a stream that reads from the given Unix file descriptor.
+ // If a block_size is given, it specifies the number of bytes that
+ // should be read and returned with each call to Next(). Otherwise,
+ // a reasonable default is used.
+ explicit FileInputStream(int file_descriptor, int block_size = -1);
+
+ // Flushes any buffers and closes the underlying file. Returns false if
+ // an error occurs during the process; use GetErrno() to examine the error.
+ // Even if an error occurs, the file descriptor is closed when this returns.
+ bool Close();
+
+ // By default, the file descriptor is not closed when the stream is
+ // destroyed. Call SetCloseOnDelete(true) to change that. WARNING:
+ // This leaves no way for the caller to detect if close() fails. If
+ // detecting close() errors is important to you, you should arrange
+ // to close the descriptor yourself.
+ void SetCloseOnDelete(bool value) { copying_input_.SetCloseOnDelete(value); }
+
+ // If an I/O error has occurred on this file descriptor, this is the
+ // errno from that error. Otherwise, this is zero. Once an error
+ // occurs, the stream is broken and all subsequent operations will
+ // fail.
+ int GetErrno() const { return copying_input_.GetErrno(); }
+
+ // implements ZeroCopyInputStream ----------------------------------
+ bool Next(const void** data, int* size) override;
+ void BackUp(int count) override;
+ bool Skip(int count) override;
+ int64_t ByteCount() const override;
+
+ private:
+ class PROTOBUF_EXPORT CopyingFileInputStream : public CopyingInputStream {
+ public:
+ CopyingFileInputStream(int file_descriptor);
+ ~CopyingFileInputStream() override;
+
+ bool Close();
+ void SetCloseOnDelete(bool value) { close_on_delete_ = value; }
+ int GetErrno() const { return errno_; }
+
+ // implements CopyingInputStream ---------------------------------
+ int Read(void* buffer, int size) override;
+ int Skip(int count) override;
+
+ private:
+ // The file descriptor.
+ const int file_;
+ bool close_on_delete_;
+ bool is_closed_;
+
+ // The errno of the I/O error, if one has occurred. Otherwise, zero.
+ int errno_;
+
+ // Did we try to seek once and fail? If so, we assume this file descriptor
+ // doesn't support seeking and won't try again.
+ bool previous_seek_failed_;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CopyingFileInputStream);
+ };
+
+ CopyingFileInputStream copying_input_;
+ CopyingInputStreamAdaptor impl_;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FileInputStream);
+};
+
+// ===================================================================
+
+// A ZeroCopyOutputStream which writes to a file descriptor.
+//
+// FileOutputStream is preferred over using an ofstream with
+// OstreamOutputStream. The latter will introduce an extra layer of buffering,
+// harming performance. Also, it's conceivable that FileOutputStream could
+// someday be enhanced to use zero-copy file descriptors on OSs which
+// support them.
+class PROTOBUF_EXPORT FileOutputStream : public CopyingOutputStreamAdaptor {
+ public:
+ // Creates a stream that writes to the given Unix file descriptor.
+ // If a block_size is given, it specifies the size of the buffers
+ // that should be returned by Next(). Otherwise, a reasonable default
+ // is used.
+ explicit FileOutputStream(int file_descriptor, int block_size = -1);
+
+ ~FileOutputStream() override;
+
+ // Flushes any buffers and closes the underlying file. Returns false if
+ // an error occurs during the process; use GetErrno() to examine the error.
+ // Even if an error occurs, the file descriptor is closed when this returns.
+ bool Close();
+
+ // By default, the file descriptor is not closed when the stream is
+ // destroyed. Call SetCloseOnDelete(true) to change that. WARNING:
+ // This leaves no way for the caller to detect if close() fails. If
+ // detecting close() errors is important to you, you should arrange
+ // to close the descriptor yourself.
+ void SetCloseOnDelete(bool value) { copying_output_.SetCloseOnDelete(value); }
+
+ // If an I/O error has occurred on this file descriptor, this is the
+ // errno from that error. Otherwise, this is zero. Once an error
+ // occurs, the stream is broken and all subsequent operations will
+ // fail.
+ int GetErrno() const { return copying_output_.GetErrno(); }
+
+ private:
+ class PROTOBUF_EXPORT CopyingFileOutputStream : public CopyingOutputStream {
+ public:
+ CopyingFileOutputStream(int file_descriptor);
+ ~CopyingFileOutputStream() override;
+
+ bool Close();
+ void SetCloseOnDelete(bool value) { close_on_delete_ = value; }
+ int GetErrno() const { return errno_; }
+
+ // implements CopyingOutputStream --------------------------------
+ bool Write(const void* buffer, int size) override;
+
+ private:
+ // The file descriptor.
+ const int file_;
+ bool close_on_delete_;
+ bool is_closed_;
+
+ // The errno of the I/O error, if one has occurred. Otherwise, zero.
+ int errno_;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CopyingFileOutputStream);
+ };
+
+ CopyingFileOutputStream copying_output_;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FileOutputStream);
+};
+
+// ===================================================================
+
+// A ZeroCopyInputStream which reads from a C++ istream.
+//
+// Note that for reading files (or anything represented by a file descriptor),
+// FileInputStream is more efficient.
+class PROTOBUF_EXPORT IstreamInputStream : public ZeroCopyInputStream {
+ public:
+ // Creates a stream that reads from the given C++ istream.
+ // If a block_size is given, it specifies the number of bytes that
+ // should be read and returned with each call to Next(). Otherwise,
+ // a reasonable default is used.
+ explicit IstreamInputStream(std::istream* stream, int block_size = -1);
+
+ // implements ZeroCopyInputStream ----------------------------------
+ bool Next(const void** data, int* size) override;
+ void BackUp(int count) override;
+ bool Skip(int count) override;
+ int64_t ByteCount() const override;
+
+ private:
+ class PROTOBUF_EXPORT CopyingIstreamInputStream : public CopyingInputStream {
+ public:
+ CopyingIstreamInputStream(std::istream* input);
+ ~CopyingIstreamInputStream() override;
+
+ // implements CopyingInputStream ---------------------------------
+ int Read(void* buffer, int size) override;
+ // (We use the default implementation of Skip().)
+
+ private:
+ // The stream.
+ std::istream* input_;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CopyingIstreamInputStream);
+ };
+
+ CopyingIstreamInputStream copying_input_;
+ CopyingInputStreamAdaptor impl_;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(IstreamInputStream);
+};
+
+// ===================================================================
+
+// A ZeroCopyOutputStream which writes to a C++ ostream.
+//
+// Note that for writing files (or anything represented by a file descriptor),
+// FileOutputStream is more efficient.
+class PROTOBUF_EXPORT OstreamOutputStream : public ZeroCopyOutputStream {
+ public:
+ // Creates a stream that writes to the given C++ ostream.
+ // If a block_size is given, it specifies the size of the buffers
+ // that should be returned by Next(). Otherwise, a reasonable default
+ // is used.
+ explicit OstreamOutputStream(std::ostream* stream, int block_size = -1);
+ ~OstreamOutputStream() override;
+
+ // implements ZeroCopyOutputStream ---------------------------------
+ bool Next(void** data, int* size) override;
+ void BackUp(int count) override;
+ int64_t ByteCount() const override;
+
+ private:
+ class PROTOBUF_EXPORT CopyingOstreamOutputStream
+ : public CopyingOutputStream {
+ public:
+ CopyingOstreamOutputStream(std::ostream* output);
+ ~CopyingOstreamOutputStream() override;
+
+ // implements CopyingOutputStream --------------------------------
+ bool Write(const void* buffer, int size) override;
+
+ private:
+ // The stream.
+ std::ostream* output_;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CopyingOstreamOutputStream);
+ };
+
+ CopyingOstreamOutputStream copying_output_;
+ CopyingOutputStreamAdaptor impl_;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(OstreamOutputStream);
+};
+
+// ===================================================================
+
+// A ZeroCopyInputStream which reads from several other streams in sequence.
+// ConcatenatingInputStream is unable to distinguish between end-of-stream
+// and read errors in the underlying streams, so it assumes any errors mean
+// end-of-stream. So, if the underlying streams fail for any other reason,
+// ConcatenatingInputStream may do odd things. It is suggested that you do
+// not use ConcatenatingInputStream on streams that might produce read errors
+// other than end-of-stream.
+class PROTOBUF_EXPORT ConcatenatingInputStream : public ZeroCopyInputStream {
+ public:
+ // All streams passed in as well as the array itself must remain valid
+ // until the ConcatenatingInputStream is destroyed.
+ ConcatenatingInputStream(ZeroCopyInputStream* const streams[], int count);
+ ~ConcatenatingInputStream() override = default;
+
+ // implements ZeroCopyInputStream ----------------------------------
+ bool Next(const void** data, int* size) override;
+ void BackUp(int count) override;
+ bool Skip(int count) override;
+ int64_t ByteCount() const override;
+
+
+ private:
+ // As streams are retired, streams_ is incremented and count_ is
+ // decremented.
+ ZeroCopyInputStream* const* streams_;
+ int stream_count_;
+ int64_t bytes_retired_; // Bytes read from previous streams.
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ConcatenatingInputStream);
+};
+
+// ===================================================================
+
+} // namespace io
+} // namespace protobuf
+} // namespace google
+
+#include <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_IMPL_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/io/zero_copy_stream_impl_lite.cc b/NorthstarDedicatedTest/include/protobuf/io/zero_copy_stream_impl_lite.cc
new file mode 100644
index 00000000..8f5e5373
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/io/zero_copy_stream_impl_lite.cc
@@ -0,0 +1,467 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <io/zero_copy_stream_impl_lite.h>
+
+#include <algorithm>
+#include <limits>
+
+#include <stubs/common.h>
+#include <stubs/logging.h>
+#include <stubs/casts.h>
+#include <stubs/stl_util.h>
+
+namespace google {
+namespace protobuf {
+namespace io {
+
+namespace {
+
+// Default block size for Copying{In,Out}putStreamAdaptor.
+static const int kDefaultBlockSize = 8192;
+
+} // namespace
+
+// ===================================================================
+
+ArrayInputStream::ArrayInputStream(const void* data, int size, int block_size)
+ : data_(reinterpret_cast<const uint8_t*>(data)),
+ size_(size),
+ block_size_(block_size > 0 ? block_size : size),
+ position_(0),
+ last_returned_size_(0) {}
+
+bool ArrayInputStream::Next(const void** data, int* size) {
+ if (position_ < size_) {
+ last_returned_size_ = std::min(block_size_, size_ - position_);
+ *data = data_ + position_;
+ *size = last_returned_size_;
+ position_ += last_returned_size_;
+ return true;
+ } else {
+ // We're at the end of the array.
+ last_returned_size_ = 0; // Don't let caller back up.
+ return false;
+ }
+}
+
+void ArrayInputStream::BackUp(int count) {
+ GOOGLE_CHECK_GT(last_returned_size_, 0)
+ << "BackUp() can only be called after a successful Next().";
+ GOOGLE_CHECK_LE(count, last_returned_size_);
+ GOOGLE_CHECK_GE(count, 0);
+ position_ -= count;
+ last_returned_size_ = 0; // Don't let caller back up further.
+}
+
+bool ArrayInputStream::Skip(int count) {
+ GOOGLE_CHECK_GE(count, 0);
+ last_returned_size_ = 0; // Don't let caller back up.
+ if (count > size_ - position_) {
+ position_ = size_;
+ return false;
+ } else {
+ position_ += count;
+ return true;
+ }
+}
+
+int64_t ArrayInputStream::ByteCount() const { return position_; }
+
+
+// ===================================================================
+
+ArrayOutputStream::ArrayOutputStream(void* data, int size, int block_size)
+ : data_(reinterpret_cast<uint8_t*>(data)),
+ size_(size),
+ block_size_(block_size > 0 ? block_size : size),
+ position_(0),
+ last_returned_size_(0) {}
+
+bool ArrayOutputStream::Next(void** data, int* size) {
+ if (position_ < size_) {
+ last_returned_size_ = std::min(block_size_, size_ - position_);
+ *data = data_ + position_;
+ *size = last_returned_size_;
+ position_ += last_returned_size_;
+ return true;
+ } else {
+ // We're at the end of the array.
+ last_returned_size_ = 0; // Don't let caller back up.
+ return false;
+ }
+}
+
+void ArrayOutputStream::BackUp(int count) {
+ GOOGLE_CHECK_GT(last_returned_size_, 0)
+ << "BackUp() can only be called after a successful Next().";
+ GOOGLE_CHECK_LE(count, last_returned_size_);
+ GOOGLE_CHECK_GE(count, 0);
+ position_ -= count;
+ last_returned_size_ = 0; // Don't let caller back up further.
+}
+
+int64_t ArrayOutputStream::ByteCount() const { return position_; }
+
+// ===================================================================
+
+StringOutputStream::StringOutputStream(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) {
+ 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/NorthstarDedicatedTest/include/protobuf/io/zero_copy_stream_impl_lite.h b/NorthstarDedicatedTest/include/protobuf/io/zero_copy_stream_impl_lite.h
new file mode 100644
index 00000000..25d9750a
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/io/zero_copy_stream_impl_lite.h
@@ -0,0 +1,408 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// This file contains common implementations of the interfaces defined in
+// zero_copy_stream.h which are included in the "lite" protobuf library.
+// These implementations cover I/O on raw arrays and strings, as well as
+// adaptors which make it easy to implement streams based on traditional
+// streams. Of course, many users will probably want to write their own
+// implementations of these interfaces specific to the particular I/O
+// abstractions they prefer to use, but these should cover the most common
+// cases.
+
+#ifndef GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_IMPL_LITE_H__
+#define GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_IMPL_LITE_H__
+
+
+#include <iosfwd>
+#include <memory>
+#include <string>
+
+#include <stubs/callback.h>
+#include <stubs/common.h>
+#include <io/zero_copy_stream.h>
+#include <stubs/stl_util.h>
+
+
+#include <port_def.inc>
+
+namespace google {
+namespace protobuf {
+namespace io {
+
+// ===================================================================
+
+// A ZeroCopyInputStream backed by an in-memory array of bytes.
+class PROTOBUF_EXPORT ArrayInputStream : public ZeroCopyInputStream {
+ public:
+ // Create an InputStream that returns the bytes pointed to by "data".
+ // "data" remains the property of the caller but must remain valid until
+ // the stream is destroyed. If a block_size is given, calls to Next()
+ // will return data blocks no larger than the given size. Otherwise, the
+ // first call to Next() returns the entire array. block_size is mainly
+ // useful for testing; in production you would probably never want to set
+ // it.
+ ArrayInputStream(const void* data, int size, int block_size = -1);
+ ~ArrayInputStream() override = default;
+
+ // implements ZeroCopyInputStream ----------------------------------
+ bool Next(const void** data, int* size) override;
+ void BackUp(int count) override;
+ bool Skip(int count) override;
+ int64_t ByteCount() const override;
+
+
+ private:
+ const uint8_t* const data_; // The byte array.
+ const int size_; // Total size of the array.
+ const int block_size_; // How many bytes to return at a time.
+
+ int position_;
+ int last_returned_size_; // How many bytes we returned last time Next()
+ // was called (used for error checking only).
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ArrayInputStream);
+};
+
+// ===================================================================
+
+// A ZeroCopyOutputStream backed by an in-memory array of bytes.
+class PROTOBUF_EXPORT ArrayOutputStream : public ZeroCopyOutputStream {
+ public:
+ // Create an OutputStream that writes to the bytes pointed to by "data".
+ // "data" remains the property of the caller but must remain valid until
+ // the stream is destroyed. If a block_size is given, calls to Next()
+ // will return data blocks no larger than the given size. Otherwise, the
+ // first call to Next() returns the entire array. block_size is mainly
+ // useful for testing; in production you would probably never want to set
+ // it.
+ ArrayOutputStream(void* data, int size, int block_size = -1);
+ ~ArrayOutputStream() override = default;
+
+ // implements ZeroCopyOutputStream ---------------------------------
+ bool Next(void** data, int* size) override;
+ void BackUp(int count) override;
+ int64_t ByteCount() const override;
+
+ private:
+ uint8_t* const data_; // The byte array.
+ const int size_; // Total size of the array.
+ const int block_size_; // How many bytes to return at a time.
+
+ int position_;
+ int last_returned_size_; // How many bytes we returned last time Next()
+ // was called (used for error checking only).
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ArrayOutputStream);
+};
+
+// ===================================================================
+
+// A ZeroCopyOutputStream which appends bytes to a string.
+class PROTOBUF_EXPORT StringOutputStream : public ZeroCopyOutputStream {
+ public:
+ // Create a StringOutputStream which appends bytes to the given string.
+ // The string remains property of the caller, but it is mutated in arbitrary
+ // ways and MUST NOT be accessed in any way until you're done with the
+ // stream. Either be sure there's no further usage, or (safest) destroy the
+ // stream before using the contents.
+ //
+ // Hint: If you call target->reserve(n) before creating the stream,
+ // the first call to Next() will return at least n bytes of buffer
+ // space.
+ explicit StringOutputStream(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 : 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 <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_IMPL_LITE_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/io/zero_copy_stream_unittest.cc b/NorthstarDedicatedTest/include/protobuf/io/zero_copy_stream_unittest.cc
new file mode 100644
index 00000000..149fa881
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/io/zero_copy_stream_unittest.cc
@@ -0,0 +1,1088 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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.
+//
+// Testing strategy: For each type of I/O (array, string, file, etc.) we
+// create an output stream and write some data to it, then create a
+// corresponding input stream to read the same data back and expect it to
+// match. When the data is written, it is written in several small chunks
+// of varying sizes, with a BackUp() after each chunk. It is read back
+// similarly, but with chunks separated at different points. The whole
+// process is run with a variety of block sizes for both the input and
+// the output.
+//
+// TODO(kenton): Rewrite this test to bring it up to the standards of all
+// the other proto2 tests. May want to wait for gTest to implement
+// "parametized tests" so that one set of tests can be used on all the
+// implementations.
+
+#include <chrono>
+#include <thread>
+
+#ifndef _MSC_VER
+#include <sys/socket.h>
+#include <unistd.h>
+#endif
+#include <errno.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include <memory>
+#include <sstream>
+
+#include <testing/file.h>
+#include <test_util2.h>
+#include <io/coded_stream.h>
+#include <io/io_win32.h>
+#include <io/zero_copy_stream_impl.h>
+
+#if HAVE_ZLIB
+#include <io/gzip_stream.h>
+#endif
+
+#include <stubs/common.h>
+#include <stubs/logging.h>
+#include <testing/file.h>
+#include <testing/googletest.h>
+#include <gtest/gtest.h>
+
+namespace google {
+namespace protobuf {
+namespace io {
+namespace {
+
+#ifdef _WIN32
+#define pipe(fds) _pipe(fds, 4096, O_BINARY)
+// 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::mkdir;
+using google::protobuf::io::win32::open;
+#endif
+
+#ifndef O_BINARY
+#ifdef _O_BINARY
+#define O_BINARY _O_BINARY
+#else
+#define O_BINARY 0 // If this isn't defined, the platform doesn't need it.
+#endif
+#endif
+
+class IoTest : public testing::Test {
+ protected:
+ // Test helpers.
+
+ // Helper to write an array of data to an output stream.
+ bool WriteToOutput(ZeroCopyOutputStream* output, const void* data, int size);
+ // Helper to read a fixed-length array of data from an input stream.
+ int ReadFromInput(ZeroCopyInputStream* input, void* data, int size);
+ // Write a string to the output stream.
+ void WriteString(ZeroCopyOutputStream* output, const std::string& str);
+ // Read a number of bytes equal to the size of the given string and checks
+ // that it matches the string.
+ void ReadString(ZeroCopyInputStream* input, const std::string& str);
+ // Writes some text to the output stream in a particular order. Returns
+ // the number of bytes written, in case the caller needs that to set up an
+ // input stream.
+ int WriteStuff(ZeroCopyOutputStream* output);
+ // Reads text from an input stream and expects it to match what
+ // WriteStuff() writes.
+ void ReadStuff(ZeroCopyInputStream* input, bool read_eof = true);
+
+ // Similar to WriteStuff, but performs more sophisticated testing.
+ int WriteStuffLarge(ZeroCopyOutputStream* output);
+ // Reads and tests a stream that should have been written to
+ // via WriteStuffLarge().
+ void ReadStuffLarge(ZeroCopyInputStream* input);
+
+#if HAVE_ZLIB
+ std::string Compress(const std::string& data,
+ const GzipOutputStream::Options& options);
+ std::string Uncompress(const std::string& data);
+#endif
+
+ static const int kBlockSizes[];
+ static const int kBlockSizeCount;
+};
+
+const int IoTest::kBlockSizes[] = {-1, 1, 2, 5, 7, 10, 23, 64};
+const int IoTest::kBlockSizeCount = GOOGLE_ARRAYSIZE(IoTest::kBlockSizes);
+
+bool IoTest::WriteToOutput(ZeroCopyOutputStream* output, const void* data,
+ int size) {
+ const uint8* in = reinterpret_cast<const uint8*>(data);
+ int in_size = size;
+
+ void* out;
+ int out_size;
+
+ while (true) {
+ if (!output->Next(&out, &out_size)) {
+ return false;
+ }
+ EXPECT_GT(out_size, 0);
+
+ if (in_size <= out_size) {
+ memcpy(out, in, in_size);
+ output->BackUp(out_size - in_size);
+ return true;
+ }
+
+ memcpy(out, in, out_size);
+ in += out_size;
+ in_size -= out_size;
+ }
+}
+
+#define MAX_REPEATED_ZEROS 100
+
+int IoTest::ReadFromInput(ZeroCopyInputStream* input, void* data, int size) {
+ uint8* out = reinterpret_cast<uint8*>(data);
+ int out_size = size;
+
+ const void* in;
+ int in_size = 0;
+
+ int repeated_zeros = 0;
+
+ while (true) {
+ if (!input->Next(&in, &in_size)) {
+ return size - out_size;
+ }
+ EXPECT_GT(in_size, -1);
+ if (in_size == 0) {
+ repeated_zeros++;
+ } else {
+ repeated_zeros = 0;
+ }
+ EXPECT_LT(repeated_zeros, MAX_REPEATED_ZEROS);
+
+ if (out_size <= in_size) {
+ memcpy(out, in, out_size);
+ if (in_size > out_size) {
+ input->BackUp(in_size - out_size);
+ }
+ return size; // Copied all of it.
+ }
+
+ memcpy(out, in, in_size);
+ out += in_size;
+ out_size -= in_size;
+ }
+}
+
+void IoTest::WriteString(ZeroCopyOutputStream* output, const std::string& str) {
+ EXPECT_TRUE(WriteToOutput(output, str.c_str(), str.size()));
+}
+
+void IoTest::ReadString(ZeroCopyInputStream* input, const std::string& str) {
+ std::unique_ptr<char[]> buffer(new char[str.size() + 1]);
+ buffer[str.size()] = '\0';
+ EXPECT_EQ(ReadFromInput(input, buffer.get(), str.size()), str.size());
+ EXPECT_STREQ(str.c_str(), buffer.get());
+}
+
+int IoTest::WriteStuff(ZeroCopyOutputStream* output) {
+ WriteString(output, "Hello world!\n");
+ WriteString(output, "Some te");
+ WriteString(output, "xt. Blah blah.");
+ WriteString(output, "abcdefg");
+ WriteString(output, "01234567890123456789");
+ WriteString(output, "foobar");
+
+ EXPECT_EQ(output->ByteCount(), 68);
+
+ int result = output->ByteCount();
+ return result;
+}
+
+// Reads text from an input stream and expects it to match what WriteStuff()
+// writes.
+void IoTest::ReadStuff(ZeroCopyInputStream* input, bool read_eof) {
+ ReadString(input, "Hello world!\n");
+ ReadString(input, "Some text. ");
+ ReadString(input, "Blah ");
+ ReadString(input, "blah.");
+ ReadString(input, "abcdefg");
+ EXPECT_TRUE(input->Skip(20));
+ ReadString(input, "foo");
+ ReadString(input, "bar");
+
+ EXPECT_EQ(input->ByteCount(), 68);
+
+ if (read_eof) {
+ uint8 byte;
+ EXPECT_EQ(ReadFromInput(input, &byte, 1), 0);
+ }
+}
+
+int IoTest::WriteStuffLarge(ZeroCopyOutputStream* output) {
+ WriteString(output, "Hello world!\n");
+ WriteString(output, "Some te");
+ WriteString(output, "xt. Blah blah.");
+ WriteString(output, std::string(100000, 'x')); // A very long string
+ WriteString(output, std::string(100000, 'y')); // A very long string
+ WriteString(output, "01234567890123456789");
+
+ EXPECT_EQ(output->ByteCount(), 200055);
+
+ int result = output->ByteCount();
+ return result;
+}
+
+// Reads text from an input stream and expects it to match what WriteStuff()
+// writes.
+void IoTest::ReadStuffLarge(ZeroCopyInputStream* input) {
+ ReadString(input, "Hello world!\nSome text. ");
+ EXPECT_TRUE(input->Skip(5));
+ ReadString(input, "blah.");
+ EXPECT_TRUE(input->Skip(100000 - 10));
+ ReadString(input, std::string(10, 'x') + std::string(100000 - 20000, 'y'));
+ EXPECT_TRUE(input->Skip(20000 - 10));
+ ReadString(input, "yyyyyyyyyy01234567890123456789");
+
+ EXPECT_EQ(input->ByteCount(), 200055);
+
+ uint8 byte;
+ EXPECT_EQ(ReadFromInput(input, &byte, 1), 0);
+}
+
+// ===================================================================
+
+TEST_F(IoTest, ArrayIo) {
+ const int kBufferSize = 256;
+ uint8 buffer[kBufferSize];
+
+ for (int i = 0; i < kBlockSizeCount; i++) {
+ for (int j = 0; j < kBlockSizeCount; j++) {
+ int size;
+ {
+ ArrayOutputStream output(buffer, kBufferSize, kBlockSizes[i]);
+ size = WriteStuff(&output);
+ }
+ {
+ ArrayInputStream input(buffer, size, kBlockSizes[j]);
+ ReadStuff(&input);
+ }
+ }
+ }
+}
+
+TEST_F(IoTest, TwoSessionWrite) {
+ // Test that two concatenated write sessions read correctly
+
+ static const char* strA = "0123456789";
+ static const char* strB = "WhirledPeas";
+ const int kBufferSize = 2 * 1024;
+ uint8* buffer = new uint8[kBufferSize];
+ char* temp_buffer = new char[40];
+
+ for (int i = 0; i < kBlockSizeCount; i++) {
+ for (int j = 0; j < kBlockSizeCount; j++) {
+ ArrayOutputStream* output =
+ new ArrayOutputStream(buffer, kBufferSize, kBlockSizes[i]);
+ CodedOutputStream* coded_output = new CodedOutputStream(output);
+ coded_output->WriteVarint32(strlen(strA));
+ coded_output->WriteRaw(strA, strlen(strA));
+ delete coded_output; // flush
+ int64 pos = output->ByteCount();
+ delete output;
+ output = new ArrayOutputStream(buffer + pos, kBufferSize - pos,
+ kBlockSizes[i]);
+ coded_output = new CodedOutputStream(output);
+ coded_output->WriteVarint32(strlen(strB));
+ coded_output->WriteRaw(strB, strlen(strB));
+ delete coded_output; // flush
+ int64 size = pos + output->ByteCount();
+ delete output;
+
+ ArrayInputStream* input =
+ new ArrayInputStream(buffer, size, kBlockSizes[j]);
+ CodedInputStream* coded_input = new CodedInputStream(input);
+ uint32 insize;
+ EXPECT_TRUE(coded_input->ReadVarint32(&insize));
+ EXPECT_EQ(strlen(strA), insize);
+ EXPECT_TRUE(coded_input->ReadRaw(temp_buffer, insize));
+ EXPECT_EQ(0, memcmp(temp_buffer, strA, insize));
+
+ EXPECT_TRUE(coded_input->ReadVarint32(&insize));
+ EXPECT_EQ(strlen(strB), insize);
+ EXPECT_TRUE(coded_input->ReadRaw(temp_buffer, insize));
+ EXPECT_EQ(0, memcmp(temp_buffer, strB, insize));
+
+ delete coded_input;
+ delete input;
+ }
+ }
+
+ delete[] temp_buffer;
+ delete[] buffer;
+}
+
+#if HAVE_ZLIB
+TEST_F(IoTest, GzipIo) {
+ const int kBufferSize = 2 * 1024;
+ uint8* buffer = new uint8[kBufferSize];
+ for (int i = 0; i < kBlockSizeCount; i++) {
+ for (int j = 0; j < kBlockSizeCount; j++) {
+ for (int z = 0; z < kBlockSizeCount; z++) {
+ int gzip_buffer_size = kBlockSizes[z];
+ int size;
+ {
+ ArrayOutputStream output(buffer, kBufferSize, kBlockSizes[i]);
+ GzipOutputStream::Options options;
+ options.format = GzipOutputStream::GZIP;
+ if (gzip_buffer_size != -1) {
+ options.buffer_size = gzip_buffer_size;
+ }
+ GzipOutputStream gzout(&output, options);
+ WriteStuff(&gzout);
+ gzout.Close();
+ size = output.ByteCount();
+ }
+ {
+ ArrayInputStream input(buffer, size, kBlockSizes[j]);
+ GzipInputStream gzin(&input, GzipInputStream::GZIP, gzip_buffer_size);
+ ReadStuff(&gzin);
+ }
+ }
+ }
+ }
+ delete[] buffer;
+}
+
+TEST_F(IoTest, GzipIoWithFlush) {
+ const int kBufferSize = 2 * 1024;
+ uint8* buffer = new uint8[kBufferSize];
+ // We start with i = 4 as we want a block size > 6. With block size <= 6
+ // Flush() fills up the entire 2K buffer with flush markers and the test
+ // fails. See documentation for Flush() for more detail.
+ for (int i = 4; i < kBlockSizeCount; i++) {
+ for (int j = 0; j < kBlockSizeCount; j++) {
+ for (int z = 0; z < kBlockSizeCount; z++) {
+ int gzip_buffer_size = kBlockSizes[z];
+ int size;
+ {
+ ArrayOutputStream output(buffer, kBufferSize, kBlockSizes[i]);
+ GzipOutputStream::Options options;
+ options.format = GzipOutputStream::GZIP;
+ if (gzip_buffer_size != -1) {
+ options.buffer_size = gzip_buffer_size;
+ }
+ GzipOutputStream gzout(&output, options);
+ WriteStuff(&gzout);
+ EXPECT_TRUE(gzout.Flush());
+ gzout.Close();
+ size = output.ByteCount();
+ }
+ {
+ ArrayInputStream input(buffer, size, kBlockSizes[j]);
+ GzipInputStream gzin(&input, GzipInputStream::GZIP, gzip_buffer_size);
+ ReadStuff(&gzin);
+ }
+ }
+ }
+ }
+ delete[] buffer;
+}
+
+TEST_F(IoTest, GzipIoContiguousFlushes) {
+ const int kBufferSize = 2 * 1024;
+ uint8* buffer = new uint8[kBufferSize];
+
+ int block_size = kBlockSizes[4];
+ int gzip_buffer_size = block_size;
+ int size;
+
+ ArrayOutputStream output(buffer, kBufferSize, block_size);
+ GzipOutputStream::Options options;
+ options.format = GzipOutputStream::GZIP;
+ if (gzip_buffer_size != -1) {
+ options.buffer_size = gzip_buffer_size;
+ }
+ GzipOutputStream gzout(&output, options);
+ WriteStuff(&gzout);
+ EXPECT_TRUE(gzout.Flush());
+ EXPECT_TRUE(gzout.Flush());
+ gzout.Close();
+ size = output.ByteCount();
+
+ ArrayInputStream input(buffer, size, block_size);
+ GzipInputStream gzin(&input, GzipInputStream::GZIP, gzip_buffer_size);
+ ReadStuff(&gzin);
+
+ delete[] buffer;
+}
+
+TEST_F(IoTest, GzipIoReadAfterFlush) {
+ const int kBufferSize = 2 * 1024;
+ uint8* buffer = new uint8[kBufferSize];
+
+ int block_size = kBlockSizes[4];
+ int gzip_buffer_size = block_size;
+ int size;
+ ArrayOutputStream output(buffer, kBufferSize, block_size);
+ GzipOutputStream::Options options;
+ options.format = GzipOutputStream::GZIP;
+ if (gzip_buffer_size != -1) {
+ options.buffer_size = gzip_buffer_size;
+ }
+
+ GzipOutputStream gzout(&output, options);
+ WriteStuff(&gzout);
+ EXPECT_TRUE(gzout.Flush());
+ size = output.ByteCount();
+
+ ArrayInputStream input(buffer, size, block_size);
+ GzipInputStream gzin(&input, GzipInputStream::GZIP, gzip_buffer_size);
+ ReadStuff(&gzin);
+
+ gzout.Close();
+
+ delete[] buffer;
+}
+
+TEST_F(IoTest, ZlibIo) {
+ const int kBufferSize = 2 * 1024;
+ uint8* buffer = new uint8[kBufferSize];
+ for (int i = 0; i < kBlockSizeCount; i++) {
+ for (int j = 0; j < kBlockSizeCount; j++) {
+ for (int z = 0; z < kBlockSizeCount; z++) {
+ int gzip_buffer_size = kBlockSizes[z];
+ int size;
+ {
+ ArrayOutputStream output(buffer, kBufferSize, kBlockSizes[i]);
+ GzipOutputStream::Options options;
+ options.format = GzipOutputStream::ZLIB;
+ if (gzip_buffer_size != -1) {
+ options.buffer_size = gzip_buffer_size;
+ }
+ GzipOutputStream gzout(&output, options);
+ WriteStuff(&gzout);
+ gzout.Close();
+ size = output.ByteCount();
+ }
+ {
+ ArrayInputStream input(buffer, size, kBlockSizes[j]);
+ GzipInputStream gzin(&input, GzipInputStream::ZLIB, gzip_buffer_size);
+ ReadStuff(&gzin);
+ }
+ }
+ }
+ }
+ delete[] buffer;
+}
+
+TEST_F(IoTest, ZlibIoInputAutodetect) {
+ const int kBufferSize = 2 * 1024;
+ uint8* buffer = new uint8[kBufferSize];
+ int size;
+ {
+ ArrayOutputStream output(buffer, kBufferSize);
+ GzipOutputStream::Options options;
+ options.format = GzipOutputStream::ZLIB;
+ GzipOutputStream gzout(&output, options);
+ WriteStuff(&gzout);
+ gzout.Close();
+ size = output.ByteCount();
+ }
+ {
+ ArrayInputStream input(buffer, size);
+ GzipInputStream gzin(&input, GzipInputStream::AUTO);
+ ReadStuff(&gzin);
+ }
+ {
+ ArrayOutputStream output(buffer, kBufferSize);
+ GzipOutputStream::Options options;
+ options.format = GzipOutputStream::GZIP;
+ GzipOutputStream gzout(&output, options);
+ WriteStuff(&gzout);
+ gzout.Close();
+ size = output.ByteCount();
+ }
+ {
+ ArrayInputStream input(buffer, size);
+ GzipInputStream gzin(&input, GzipInputStream::AUTO);
+ ReadStuff(&gzin);
+ }
+ delete[] buffer;
+}
+
+std::string IoTest::Compress(const std::string& data,
+ const GzipOutputStream::Options& options) {
+ std::string result;
+ {
+ StringOutputStream output(&result);
+ GzipOutputStream gzout(&output, options);
+ WriteToOutput(&gzout, data.data(), data.size());
+ }
+ return result;
+}
+
+std::string IoTest::Uncompress(const std::string& data) {
+ std::string result;
+ {
+ ArrayInputStream input(data.data(), data.size());
+ GzipInputStream gzin(&input);
+ const void* buffer;
+ int size;
+ while (gzin.Next(&buffer, &size)) {
+ result.append(reinterpret_cast<const char*>(buffer), size);
+ }
+ }
+ return result;
+}
+
+TEST_F(IoTest, CompressionOptions) {
+ // Some ad-hoc testing of compression options.
+
+ std::string golden_filename =
+ TestUtil::GetTestDataPath("net/proto2/internal/testdata/golden_message");
+ std::string golden;
+ GOOGLE_CHECK_OK(File::GetContents(golden_filename, &golden, true));
+
+ GzipOutputStream::Options options;
+ std::string gzip_compressed = Compress(golden, options);
+
+ options.compression_level = 0;
+ std::string not_compressed = Compress(golden, options);
+
+ // Try zlib compression for fun.
+ options = GzipOutputStream::Options();
+ options.format = GzipOutputStream::ZLIB;
+ std::string zlib_compressed = Compress(golden, options);
+
+ // Uncompressed should be bigger than the original since it should have some
+ // sort of header.
+ EXPECT_GT(not_compressed.size(), golden.size());
+
+ // Higher compression levels should result in smaller sizes.
+ EXPECT_LT(zlib_compressed.size(), not_compressed.size());
+
+ // ZLIB format should differ from GZIP format.
+ EXPECT_TRUE(zlib_compressed != gzip_compressed);
+
+ // Everything should decompress correctly.
+ EXPECT_TRUE(Uncompress(not_compressed) == golden);
+ EXPECT_TRUE(Uncompress(gzip_compressed) == golden);
+ EXPECT_TRUE(Uncompress(zlib_compressed) == golden);
+}
+
+TEST_F(IoTest, TwoSessionWriteGzip) {
+ // Test that two concatenated gzip streams can be read correctly
+
+ static const char* strA = "0123456789";
+ static const char* strB = "QuickBrownFox";
+ const int kBufferSize = 2 * 1024;
+ uint8* buffer = new uint8[kBufferSize];
+ char* temp_buffer = new char[40];
+
+ for (int i = 0; i < kBlockSizeCount; i++) {
+ for (int j = 0; j < kBlockSizeCount; j++) {
+ ArrayOutputStream* output =
+ new ArrayOutputStream(buffer, kBufferSize, kBlockSizes[i]);
+ GzipOutputStream* gzout = new GzipOutputStream(output);
+ CodedOutputStream* coded_output = new CodedOutputStream(gzout);
+ int32 outlen = strlen(strA) + 1;
+ coded_output->WriteVarint32(outlen);
+ coded_output->WriteRaw(strA, outlen);
+ delete coded_output; // flush
+ delete gzout; // flush
+ int64 pos = output->ByteCount();
+ delete output;
+ output = new ArrayOutputStream(buffer + pos, kBufferSize - pos,
+ kBlockSizes[i]);
+ gzout = new GzipOutputStream(output);
+ coded_output = new CodedOutputStream(gzout);
+ outlen = strlen(strB) + 1;
+ coded_output->WriteVarint32(outlen);
+ coded_output->WriteRaw(strB, outlen);
+ delete coded_output; // flush
+ delete gzout; // flush
+ int64 size = pos + output->ByteCount();
+ delete output;
+
+ ArrayInputStream* input =
+ new ArrayInputStream(buffer, size, kBlockSizes[j]);
+ GzipInputStream* gzin = new GzipInputStream(input);
+ CodedInputStream* coded_input = new CodedInputStream(gzin);
+ uint32 insize;
+ EXPECT_TRUE(coded_input->ReadVarint32(&insize));
+ EXPECT_EQ(strlen(strA) + 1, insize);
+ EXPECT_TRUE(coded_input->ReadRaw(temp_buffer, insize));
+ EXPECT_EQ(0, memcmp(temp_buffer, strA, insize))
+ << "strA=" << strA << " in=" << temp_buffer;
+
+ EXPECT_TRUE(coded_input->ReadVarint32(&insize));
+ EXPECT_EQ(strlen(strB) + 1, insize);
+ EXPECT_TRUE(coded_input->ReadRaw(temp_buffer, insize));
+ EXPECT_EQ(0, memcmp(temp_buffer, strB, insize))
+ << " out_block_size=" << kBlockSizes[i]
+ << " in_block_size=" << kBlockSizes[j] << " pos=" << pos
+ << " size=" << size << " strB=" << strB << " in=" << temp_buffer;
+
+ delete coded_input;
+ delete gzin;
+ delete input;
+ }
+ }
+
+ delete[] temp_buffer;
+ delete[] buffer;
+}
+
+TEST_F(IoTest, GzipInputByteCountAfterClosed) {
+ std::string golden = "abcdefghijklmnopqrstuvwxyz";
+ std::string compressed = Compress(golden, GzipOutputStream::Options());
+
+ for (int i = 0; i < kBlockSizeCount; i++) {
+ ArrayInputStream arr_input(compressed.data(), compressed.size(),
+ kBlockSizes[i]);
+ GzipInputStream gz_input(&arr_input);
+ const void* buffer;
+ int size;
+ while (gz_input.Next(&buffer, &size)) {
+ EXPECT_LE(gz_input.ByteCount(), golden.size());
+ }
+ EXPECT_EQ(golden.size(), gz_input.ByteCount());
+ }
+}
+
+TEST_F(IoTest, GzipInputByteCountAfterClosedConcatenatedStreams) {
+ std::string golden1 = "abcdefghijklmnopqrstuvwxyz";
+ std::string golden2 = "the quick brown fox jumps over the lazy dog";
+ const size_t total_size = golden1.size() + golden2.size();
+ std::string compressed = Compress(golden1, GzipOutputStream::Options()) +
+ Compress(golden2, GzipOutputStream::Options());
+
+ for (int i = 0; i < kBlockSizeCount; i++) {
+ ArrayInputStream arr_input(compressed.data(), compressed.size(),
+ kBlockSizes[i]);
+ GzipInputStream gz_input(&arr_input);
+ const void* buffer;
+ int size;
+ while (gz_input.Next(&buffer, &size)) {
+ EXPECT_LE(gz_input.ByteCount(), total_size);
+ }
+ EXPECT_EQ(total_size, gz_input.ByteCount());
+ }
+}
+#endif
+
+// There is no string input, only string output. Also, it doesn't support
+// explicit block sizes. So, we'll only run one test and we'll use
+// ArrayInput to read back the results.
+TEST_F(IoTest, StringIo) {
+ std::string str;
+ {
+ StringOutputStream output(&str);
+ WriteStuff(&output);
+ }
+ {
+ ArrayInputStream input(str.data(), str.size());
+ ReadStuff(&input);
+ }
+}
+
+// Verifies that outputs up to kint32max can be created.
+TEST_F(IoTest, LargeOutput) {
+ std::string str;
+ StringOutputStream output(&str);
+ void* unused_data;
+ int size;
+ // Repeatedly calling Next should eventually grow the buffer to kint32max.
+ do {
+ EXPECT_TRUE(output.Next(&unused_data, &size));
+ } while (str.size() < std::numeric_limits<int>::max());
+ // Further increases should be possible.
+ output.Next(&unused_data, &size);
+ EXPECT_GT(size, 0);
+}
+
+
+// To test files, we create a temporary file, write, read, truncate, repeat.
+TEST_F(IoTest, FileIo) {
+ std::string filename = TestTempDir() + "/zero_copy_stream_test_file";
+
+ for (int i = 0; i < kBlockSizeCount; i++) {
+ for (int j = 0; j < kBlockSizeCount; j++) {
+ // Make a temporary file.
+ int file =
+ open(filename.c_str(), O_RDWR | O_CREAT | O_TRUNC | O_BINARY, 0777);
+ ASSERT_GE(file, 0);
+
+ {
+ FileOutputStream output(file, kBlockSizes[i]);
+ WriteStuff(&output);
+ EXPECT_EQ(0, output.GetErrno());
+ }
+
+ // Rewind.
+ ASSERT_NE(lseek(file, 0, SEEK_SET), (off_t)-1);
+
+ {
+ FileInputStream input(file, kBlockSizes[j]);
+ ReadStuff(&input);
+ EXPECT_EQ(0, input.GetErrno());
+ }
+
+ close(file);
+ }
+ }
+}
+
+#ifndef _MSC_VER
+// This tests the FileInputStream with a non blocking file. It opens a pipe in
+// non blocking mode, then starts reading it. The writing thread starts writing
+// 100ms after that.
+TEST_F(IoTest, NonBlockingFileIo) {
+ for (int i = 0; i < kBlockSizeCount; i++) {
+ for (int j = 0; j < kBlockSizeCount; j++) {
+ int fd[2];
+ // On Linux we could use pipe2 to make the pipe non-blocking in one step,
+ // but we instead use pipe and fcntl because pipe2 is not available on
+ // Mac OS.
+ ASSERT_EQ(pipe(fd), 0);
+ ASSERT_EQ(fcntl(fd[0], F_SETFL, O_NONBLOCK), 0);
+ ASSERT_EQ(fcntl(fd[1], F_SETFL, O_NONBLOCK), 0);
+
+ std::mutex go_write;
+ go_write.lock();
+
+ bool done_reading = false;
+
+ std::thread write_thread([this, fd, &go_write, i]() {
+ go_write.lock();
+ go_write.unlock();
+ FileOutputStream output(fd[1], kBlockSizes[i]);
+ WriteStuff(&output);
+ EXPECT_EQ(0, output.GetErrno());
+ });
+
+ std::thread read_thread([this, fd, &done_reading, j]() {
+ FileInputStream input(fd[0], kBlockSizes[j]);
+ ReadStuff(&input, false /* read_eof */);
+ done_reading = true;
+ close(fd[0]);
+ close(fd[1]);
+ EXPECT_EQ(0, input.GetErrno());
+ });
+
+ // Sleeping is not necessary but makes the next expectation relevant: the
+ // reading thread waits for the data to be available before returning.
+ std::this_thread::sleep_for(std::chrono::milliseconds(100));
+ EXPECT_FALSE(done_reading);
+ go_write.unlock();
+ write_thread.join();
+ read_thread.join();
+ EXPECT_TRUE(done_reading);
+ }
+ }
+}
+
+TEST_F(IoTest, BlockingFileIoWithTimeout) {
+ int fd[2];
+
+ for (int i = 0; i < kBlockSizeCount; i++) {
+ ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, fd), 0);
+ struct timeval tv {
+ .tv_sec = 0, .tv_usec = 5000
+ };
+ ASSERT_EQ(setsockopt(fd[0], SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)), 0);
+ FileInputStream input(fd[0], kBlockSizes[i]);
+ uint8 byte;
+ EXPECT_EQ(ReadFromInput(&input, &byte, 1), 0);
+ EXPECT_EQ(EAGAIN, input.GetErrno());
+ }
+}
+#endif
+
+#if HAVE_ZLIB
+TEST_F(IoTest, GzipFileIo) {
+ std::string filename = TestTempDir() + "/zero_copy_stream_test_file";
+
+ for (int i = 0; i < kBlockSizeCount; i++) {
+ for (int j = 0; j < kBlockSizeCount; j++) {
+ // Make a temporary file.
+ int file =
+ open(filename.c_str(), O_RDWR | O_CREAT | O_TRUNC | O_BINARY, 0777);
+ ASSERT_GE(file, 0);
+ {
+ FileOutputStream output(file, kBlockSizes[i]);
+ GzipOutputStream gzout(&output);
+ WriteStuffLarge(&gzout);
+ gzout.Close();
+ output.Flush();
+ EXPECT_EQ(0, output.GetErrno());
+ }
+
+ // Rewind.
+ ASSERT_NE(lseek(file, 0, SEEK_SET), (off_t)-1);
+
+ {
+ FileInputStream input(file, kBlockSizes[j]);
+ GzipInputStream gzin(&input);
+ ReadStuffLarge(&gzin);
+ EXPECT_EQ(0, input.GetErrno());
+ }
+
+ close(file);
+ }
+ }
+}
+#endif
+
+// MSVC raises various debugging exceptions if we try to use a file
+// descriptor of -1, defeating our tests below. This class will disable
+// these debug assertions while in scope.
+class MsvcDebugDisabler {
+ public:
+#if defined(_MSC_VER) && _MSC_VER >= 1400
+ MsvcDebugDisabler() {
+ old_handler_ = _set_invalid_parameter_handler(MyHandler);
+ old_mode_ = _CrtSetReportMode(_CRT_ASSERT, 0);
+ }
+ ~MsvcDebugDisabler() {
+ old_handler_ = _set_invalid_parameter_handler(old_handler_);
+ old_mode_ = _CrtSetReportMode(_CRT_ASSERT, old_mode_);
+ }
+
+ static void MyHandler(const wchar_t* expr, const wchar_t* func,
+ const wchar_t* file, unsigned int line,
+ uintptr_t pReserved) {
+ // do nothing
+ }
+
+ _invalid_parameter_handler old_handler_;
+ int old_mode_;
+#else
+ // Dummy constructor and destructor to ensure that GCC doesn't complain
+ // that debug_disabler is an unused variable.
+ MsvcDebugDisabler() {}
+ ~MsvcDebugDisabler() {}
+#endif
+};
+
+// Test that FileInputStreams report errors correctly.
+TEST_F(IoTest, FileReadError) {
+ MsvcDebugDisabler debug_disabler;
+
+ // -1 = invalid file descriptor.
+ FileInputStream input(-1);
+
+ const void* buffer;
+ int size;
+ EXPECT_FALSE(input.Next(&buffer, &size));
+ EXPECT_EQ(EBADF, input.GetErrno());
+}
+
+// Test that FileOutputStreams report errors correctly.
+TEST_F(IoTest, FileWriteError) {
+ MsvcDebugDisabler debug_disabler;
+
+ // -1 = invalid file descriptor.
+ FileOutputStream input(-1);
+
+ void* buffer;
+ int size;
+
+ // The first call to Next() succeeds because it doesn't have anything to
+ // write yet.
+ EXPECT_TRUE(input.Next(&buffer, &size));
+
+ // Second call fails.
+ EXPECT_FALSE(input.Next(&buffer, &size));
+
+ EXPECT_EQ(EBADF, input.GetErrno());
+}
+
+// Pipes are not seekable, so File{Input,Output}Stream ends up doing some
+// different things to handle them. We'll test by writing to a pipe and
+// reading back from it.
+TEST_F(IoTest, PipeIo) {
+ int files[2];
+
+ for (int i = 0; i < kBlockSizeCount; i++) {
+ for (int j = 0; j < kBlockSizeCount; j++) {
+ // Need to create a new pipe each time because ReadStuff() expects
+ // to see EOF at the end.
+ ASSERT_EQ(pipe(files), 0);
+
+ {
+ FileOutputStream output(files[1], kBlockSizes[i]);
+ WriteStuff(&output);
+ EXPECT_EQ(0, output.GetErrno());
+ }
+ close(files[1]); // Send EOF.
+
+ {
+ FileInputStream input(files[0], kBlockSizes[j]);
+ ReadStuff(&input);
+ EXPECT_EQ(0, input.GetErrno());
+ }
+ close(files[0]);
+ }
+ }
+}
+
+// Test using C++ iostreams.
+TEST_F(IoTest, IostreamIo) {
+ for (int i = 0; i < kBlockSizeCount; i++) {
+ for (int j = 0; j < kBlockSizeCount; j++) {
+ {
+ std::stringstream stream;
+
+ {
+ OstreamOutputStream output(&stream, kBlockSizes[i]);
+ WriteStuff(&output);
+ EXPECT_FALSE(stream.fail());
+ }
+
+ {
+ IstreamInputStream input(&stream, kBlockSizes[j]);
+ ReadStuff(&input);
+ EXPECT_TRUE(stream.eof());
+ }
+ }
+
+ {
+ std::stringstream stream;
+
+ {
+ OstreamOutputStream output(&stream, kBlockSizes[i]);
+ WriteStuffLarge(&output);
+ EXPECT_FALSE(stream.fail());
+ }
+
+ {
+ IstreamInputStream input(&stream, kBlockSizes[j]);
+ ReadStuffLarge(&input);
+ EXPECT_TRUE(stream.eof());
+ }
+ }
+ }
+ }
+}
+
+// To test ConcatenatingInputStream, we create several ArrayInputStreams
+// covering a buffer and then concatenate them.
+TEST_F(IoTest, ConcatenatingInputStream) {
+ const int kBufferSize = 256;
+ uint8 buffer[kBufferSize];
+
+ // Fill the buffer.
+ ArrayOutputStream output(buffer, kBufferSize);
+ WriteStuff(&output);
+
+ // Now split it up into multiple streams of varying sizes.
+ ASSERT_EQ(68, output.ByteCount()); // Test depends on this.
+ ArrayInputStream input1(buffer, 12);
+ ArrayInputStream input2(buffer + 12, 7);
+ ArrayInputStream input3(buffer + 19, 6);
+ ArrayInputStream input4(buffer + 25, 15);
+ ArrayInputStream input5(buffer + 40, 0);
+ // Note: We want to make sure we have a stream boundary somewhere between
+ // bytes 42 and 62, which is the range that it Skip()ed by ReadStuff(). This
+ // tests that a bug that existed in the original code for Skip() is fixed.
+ ArrayInputStream input6(buffer + 40, 10);
+ ArrayInputStream input7(buffer + 50, 18); // Total = 68 bytes.
+
+ ZeroCopyInputStream* streams[] = {&input1, &input2, &input3, &input4,
+ &input5, &input6, &input7};
+
+ // Create the concatenating stream and read.
+ ConcatenatingInputStream input(streams, GOOGLE_ARRAYSIZE(streams));
+ ReadStuff(&input);
+}
+
+// To test LimitingInputStream, we write our golden text to a buffer, then
+// create an ArrayInputStream that contains the whole buffer (not just the
+// bytes written), then use a LimitingInputStream to limit it just to the
+// bytes written.
+TEST_F(IoTest, LimitingInputStream) {
+ const int kBufferSize = 256;
+ uint8 buffer[kBufferSize];
+
+ // Fill the buffer.
+ ArrayOutputStream output(buffer, kBufferSize);
+ WriteStuff(&output);
+
+ // Set up input.
+ ArrayInputStream array_input(buffer, kBufferSize);
+ LimitingInputStream input(&array_input, output.ByteCount());
+
+ ReadStuff(&input);
+}
+
+// Checks that ByteCount works correctly for LimitingInputStreams where the
+// underlying stream has already been read.
+TEST_F(IoTest, LimitingInputStreamByteCount) {
+ const int kHalfBufferSize = 128;
+ const int kBufferSize = kHalfBufferSize * 2;
+ uint8 buffer[kBufferSize];
+
+ // Set up input. Only allow half to be read at once.
+ ArrayInputStream array_input(buffer, kBufferSize, kHalfBufferSize);
+ const void* data;
+ int size;
+ EXPECT_TRUE(array_input.Next(&data, &size));
+ EXPECT_EQ(kHalfBufferSize, array_input.ByteCount());
+ // kHalfBufferSize - 1 to test limiting logic as well.
+ LimitingInputStream input(&array_input, kHalfBufferSize - 1);
+ EXPECT_EQ(0, input.ByteCount());
+ EXPECT_TRUE(input.Next(&data, &size));
+ EXPECT_EQ(kHalfBufferSize - 1, input.ByteCount());
+}
+
+// Check that a zero-size array doesn't confuse the code.
+TEST(ZeroSizeArray, Input) {
+ ArrayInputStream input(NULL, 0);
+ const void* data;
+ int size;
+ EXPECT_FALSE(input.Next(&data, &size));
+}
+
+TEST(ZeroSizeArray, Output) {
+ ArrayOutputStream output(NULL, 0);
+ void* data;
+ int size;
+ EXPECT_FALSE(output.Next(&data, &size));
+}
+
+} // namespace
+} // namespace io
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/libprotobuf.vcxproj b/NorthstarDedicatedTest/include/protobuf/libprotobuf.vcxproj
new file mode 100644
index 00000000..c9886695
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/libprotobuf.vcxproj
@@ -0,0 +1,192 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <VCProjectVersion>16.0</VCProjectVersion>
+ <Keyword>Win32Proj</Keyword>
+ <ProjectGuid>{b273a875-6618-49fe-8ca4-0b693ba264d5}</ProjectGuid>
+ <RootNamespace>libprotobuf</RootNamespace>
+ <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v143</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ <UseOfMfc>Static</UseOfMfc>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>v143</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>Unicode</CharacterSet>
+ <UseOfMfc>Static</UseOfMfc>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="Shared">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <LinkIncremental>true</LinkIncremental>
+ <IncludePath>$(IncludePath)</IncludePath>
+ <IntDir>$(Platform)\$(Configuration)\</IntDir>
+ <OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
+ <TargetName>libprotobuf_x64</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <LinkIncremental>false</LinkIncremental>
+ <IncludePath>$(IncludePath)</IncludePath>
+ <IntDir>$(Platform)\$(Configuration)\</IntDir>
+ <OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
+ <TargetName>libprotobuf_x64</TargetName>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <WarningLevel>Level3</WarningLevel>
+ <SDLCheck>true</SDLCheck>
+ <PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ConformanceMode>true</ConformanceMode>
+ <AdditionalOptions>%(AdditionalOptions) /utf-8 /bigobj /D _CRT_SECURE_NO_WARNINGS </AdditionalOptions>
+ <LanguageStandard>stdcpp17</LanguageStandard>
+ <AdditionalIncludeDirectories>$(ProjectDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <WarningLevel>Level3</WarningLevel>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <SDLCheck>true</SDLCheck>
+ <PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ConformanceMode>true</ConformanceMode>
+ <AdditionalOptions>%(AdditionalOptions) /utf-8 /bigobj /D _CRT_SECURE_NO_WARNINGS </AdditionalOptions>
+ <LanguageStandard>stdcpp17</LanguageStandard>
+ <AdditionalIncludeDirectories>$(ProjectDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ResourceCompile Include="version.rc" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="any_lite.cc" />
+ <ClCompile Include="arena.cc" />
+ <ClCompile Include="arenastring.cc" />
+ <ClCompile Include="extension_set.cc" />
+ <ClCompile Include="generated_enum_util.cc" />
+ <ClCompile Include="generated_message_table_driven_lite.cc" />
+ <ClCompile Include="generated_message_tctable_lite.cc" />
+ <ClCompile Include="generated_message_util.cc" />
+ <ClCompile Include="implicit_weak_message.cc" />
+ <ClCompile Include="inlined_string_field.cc" />
+ <ClCompile Include="io\coded_stream.cc" />
+ <ClCompile Include="io\io_win32.cc" />
+ <ClCompile Include="io\strtod.cc" />
+ <ClCompile Include="io\zero_copy_stream.cc" />
+ <ClCompile Include="io\zero_copy_stream_impl.cc" />
+ <ClCompile Include="io\zero_copy_stream_impl_lite.cc" />
+ <ClCompile Include="map.cc" />
+ <ClCompile Include="message_lite.cc" />
+ <ClCompile Include="parse_context.cc" />
+ <ClCompile Include="repeated_field.cc" />
+ <ClCompile Include="repeated_ptr_field.cc" />
+ <ClCompile Include="stubs\bytestream.cc" />
+ <ClCompile Include="stubs\common.cc" />
+ <ClCompile Include="stubs\int128.cc" />
+ <ClCompile Include="stubs\status.cc" />
+ <ClCompile Include="stubs\statusor.cc" />
+ <ClCompile Include="stubs\stringpiece.cc" />
+ <ClCompile Include="stubs\stringprintf.cc" />
+ <ClCompile Include="stubs\structurally_valid.cc" />
+ <ClCompile Include="stubs\strutil.cc" />
+ <ClCompile Include="stubs\time.cc" />
+ <ClCompile Include="wire_format_lite.cc" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="any.h" />
+ <ClInclude Include="arena.h" />
+ <ClInclude Include="arenastring.h" />
+ <ClInclude Include="arena_impl.h" />
+ <ClInclude Include="explicitly_constructed.h" />
+ <ClInclude Include="extension_set.h" />
+ <ClInclude Include="extension_set_inl.h" />
+ <ClInclude Include="generated_enum_util.h" />
+ <ClInclude Include="generated_message_table_driven.h" />
+ <ClInclude Include="generated_message_table_driven_lite.h" />
+ <ClInclude Include="generated_message_tctable_decl.h" />
+ <ClInclude Include="generated_message_tctable_impl.h" />
+ <ClInclude Include="generated_message_util.h" />
+ <ClInclude Include="has_bits.h" />
+ <ClInclude Include="implicit_weak_message.h" />
+ <ClInclude Include="inlined_string_field.h" />
+ <ClInclude Include="io\coded_stream.h" />
+ <ClInclude Include="io\io_win32.h" />
+ <ClInclude Include="io\strtod.h" />
+ <ClInclude Include="io\zero_copy_stream.h" />
+ <ClInclude Include="io\zero_copy_stream_impl.h" />
+ <ClInclude Include="io\zero_copy_stream_impl_lite.h" />
+ <ClInclude Include="map.h" />
+ <ClInclude Include="map_entry_lite.h" />
+ <ClInclude Include="map_field_lite.h" />
+ <ClInclude Include="message_lite.h" />
+ <ClInclude Include="parse_context.h" />
+ <ClInclude Include="port.h" />
+ <ClInclude Include="repeated_field.h" />
+ <ClInclude Include="repeated_ptr_field.h" />
+ <ClInclude Include="stubs\bytestream.h" />
+ <ClInclude Include="stubs\callback.h" />
+ <ClInclude Include="stubs\casts.h" />
+ <ClInclude Include="stubs\common.h" />
+ <ClInclude Include="stubs\hash.h" />
+ <ClInclude Include="stubs\int128.h" />
+ <ClInclude Include="stubs\logging.h" />
+ <ClInclude Include="stubs\macros.h" />
+ <ClInclude Include="stubs\map_util.h" />
+ <ClInclude Include="stubs\mutex.h" />
+ <ClInclude Include="stubs\once.h" />
+ <ClInclude Include="stubs\platform_macros.h" />
+ <ClInclude Include="stubs\port.h" />
+ <ClInclude Include="stubs\status.h" />
+ <ClInclude Include="stubs\statusor.h" />
+ <ClInclude Include="stubs\stl_util.h" />
+ <ClInclude Include="stubs\stringpiece.h" />
+ <ClInclude Include="stubs\stringprintf.h" />
+ <ClInclude Include="stubs\strutil.h" />
+ <ClInclude Include="stubs\template_util.h" />
+ <ClInclude Include="stubs\time.h" />
+ <ClInclude Include="wire_format_lite.h" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/NorthstarDedicatedTest/include/protobuf/libprotobuf.vcxproj.filters b/NorthstarDedicatedTest/include/protobuf/libprotobuf.vcxproj.filters
new file mode 100644
index 00000000..c2897e4d
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/libprotobuf.vcxproj.filters
@@ -0,0 +1,294 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="stubs">
+ <UniqueIdentifier>{d60db004-45fa-4ae3-b74d-47b327b69c2e}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="stubs\include">
+ <UniqueIdentifier>{87c48269-0f18-42b5-b7be-b0ccb26a5f76}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="include">
+ <UniqueIdentifier>{b464f51d-733d-4b4e-8441-b6cabdecd127}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="io">
+ <UniqueIdentifier>{d80f3bd1-5ff7-4d05-a301-b391f6396dea}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="io\include">
+ <UniqueIdentifier>{1f4012c2-e2e2-48f9-b2f3-2ffe80c9a912}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="util">
+ <UniqueIdentifier>{e42972f8-3b4a-4e5f-8bf5-cc88ae71b499}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="util\internal">
+ <UniqueIdentifier>{4cd49ba1-876f-42de-b9e1-fccab9db185e}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="util\internal\include">
+ <UniqueIdentifier>{01b23346-904d-4495-b48c-e04281bfda22}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="util\include">
+ <UniqueIdentifier>{8647c75c-0fa4-49fc-a30c-193a45680c43}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="source">
+ <UniqueIdentifier>{23955e3f-a0de-4045-952a-188b5c12144e}</UniqueIdentifier>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="version.rc" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="any_lite.cc">
+ <Filter>source</Filter>
+ </ClCompile>
+ <ClCompile Include="arena.cc">
+ <Filter>source</Filter>
+ </ClCompile>
+ <ClCompile Include="arenastring.cc">
+ <Filter>source</Filter>
+ </ClCompile>
+ <ClCompile Include="stubs\bytestream.cc">
+ <Filter>stubs</Filter>
+ </ClCompile>
+ <ClCompile Include="io\coded_stream.cc">
+ <Filter>io</Filter>
+ </ClCompile>
+ <ClCompile Include="stubs\common.cc">
+ <Filter>stubs</Filter>
+ </ClCompile>
+ <ClCompile Include="extension_set.cc">
+ <Filter>source</Filter>
+ </ClCompile>
+ <ClCompile Include="generated_enum_util.cc">
+ <Filter>source</Filter>
+ </ClCompile>
+ <ClCompile Include="generated_message_table_driven_lite.cc">
+ <Filter>source</Filter>
+ </ClCompile>
+ <ClCompile Include="generated_message_tctable_lite.cc">
+ <Filter>source</Filter>
+ </ClCompile>
+ <ClCompile Include="generated_message_util.cc">
+ <Filter>source</Filter>
+ </ClCompile>
+ <ClCompile Include="implicit_weak_message.cc">
+ <Filter>source</Filter>
+ </ClCompile>
+ <ClCompile Include="inlined_string_field.cc">
+ <Filter>source</Filter>
+ </ClCompile>
+ <ClCompile Include="stubs\int128.cc">
+ <Filter>stubs</Filter>
+ </ClCompile>
+ <ClCompile Include="io\io_win32.cc">
+ <Filter>io</Filter>
+ </ClCompile>
+ <ClCompile Include="map.cc">
+ <Filter>source</Filter>
+ </ClCompile>
+ <ClCompile Include="message_lite.cc">
+ <Filter>source</Filter>
+ </ClCompile>
+ <ClCompile Include="parse_context.cc">
+ <Filter>source</Filter>
+ </ClCompile>
+ <ClCompile Include="repeated_field.cc">
+ <Filter>source</Filter>
+ </ClCompile>
+ <ClCompile Include="repeated_ptr_field.cc">
+ <Filter>source</Filter>
+ </ClCompile>
+ <ClCompile Include="stubs\status.cc">
+ <Filter>stubs</Filter>
+ </ClCompile>
+ <ClCompile Include="stubs\statusor.cc">
+ <Filter>stubs</Filter>
+ </ClCompile>
+ <ClCompile Include="stubs\stringpiece.cc">
+ <Filter>stubs</Filter>
+ </ClCompile>
+ <ClCompile Include="stubs\stringprintf.cc">
+ <Filter>stubs</Filter>
+ </ClCompile>
+ <ClCompile Include="stubs\strutil.cc">
+ <Filter>stubs</Filter>
+ </ClCompile>
+ <ClCompile Include="stubs\time.cc">
+ <Filter>stubs</Filter>
+ </ClCompile>
+ <ClCompile Include="io\strtod.cc">
+ <Filter>io</Filter>
+ </ClCompile>
+ <ClCompile Include="io\zero_copy_stream.cc">
+ <Filter>io</Filter>
+ </ClCompile>
+ <ClCompile Include="io\zero_copy_stream_impl.cc">
+ <Filter>io</Filter>
+ </ClCompile>
+ <ClCompile Include="io\zero_copy_stream_impl_lite.cc">
+ <Filter>io</Filter>
+ </ClCompile>
+ <ClCompile Include="wire_format_lite.cc">
+ <Filter>source</Filter>
+ </ClCompile>
+ <ClCompile Include="stubs\structurally_valid.cc">
+ <Filter>stubs</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="any.h">
+ <Filter>include</Filter>
+ </ClInclude>
+ <ClInclude Include="arena.h">
+ <Filter>include</Filter>
+ </ClInclude>
+ <ClInclude Include="arenastring.h">
+ <Filter>include</Filter>
+ </ClInclude>
+ <ClInclude Include="stubs\bytestream.h">
+ <Filter>stubs\include</Filter>
+ </ClInclude>
+ <ClInclude Include="io\coded_stream.h">
+ <Filter>io\include</Filter>
+ </ClInclude>
+ <ClInclude Include="stubs\common.h">
+ <Filter>stubs\include</Filter>
+ </ClInclude>
+ <ClInclude Include="extension_set.h">
+ <Filter>include</Filter>
+ </ClInclude>
+ <ClInclude Include="generated_enum_util.h">
+ <Filter>include</Filter>
+ </ClInclude>
+ <ClInclude Include="generated_message_table_driven_lite.h">
+ <Filter>include</Filter>
+ </ClInclude>
+ <ClInclude Include="generated_message_tctable_decl.h">
+ <Filter>include</Filter>
+ </ClInclude>
+ <ClInclude Include="generated_message_tctable_impl.h">
+ <Filter>include</Filter>
+ </ClInclude>
+ <ClInclude Include="generated_message_util.h">
+ <Filter>include</Filter>
+ </ClInclude>
+ <ClInclude Include="implicit_weak_message.h">
+ <Filter>include</Filter>
+ </ClInclude>
+ <ClInclude Include="arena_impl.h">
+ <Filter>include</Filter>
+ </ClInclude>
+ <ClInclude Include="stubs\callback.h">
+ <Filter>stubs\include</Filter>
+ </ClInclude>
+ <ClInclude Include="stubs\casts.h">
+ <Filter>stubs\include</Filter>
+ </ClInclude>
+ <ClInclude Include="explicitly_constructed.h">
+ <Filter>include</Filter>
+ </ClInclude>
+ <ClInclude Include="extension_set_inl.h">
+ <Filter>include</Filter>
+ </ClInclude>
+ <ClInclude Include="generated_message_table_driven.h">
+ <Filter>include</Filter>
+ </ClInclude>
+ <ClInclude Include="has_bits.h">
+ <Filter>include</Filter>
+ </ClInclude>
+ <ClInclude Include="stubs\hash.h">
+ <Filter>stubs\include</Filter>
+ </ClInclude>
+ <ClInclude Include="inlined_string_field.h">
+ <Filter>include</Filter>
+ </ClInclude>
+ <ClInclude Include="stubs\logging.h">
+ <Filter>stubs\include</Filter>
+ </ClInclude>
+ <ClInclude Include="stubs\macros.h">
+ <Filter>stubs\include</Filter>
+ </ClInclude>
+ <ClInclude Include="stubs\map_util.h">
+ <Filter>stubs\include</Filter>
+ </ClInclude>
+ <ClInclude Include="map.h">
+ <Filter>include</Filter>
+ </ClInclude>
+ <ClInclude Include="map_entry_lite.h">
+ <Filter>include</Filter>
+ </ClInclude>
+ <ClInclude Include="map_field_lite.h">
+ <Filter>include</Filter>
+ </ClInclude>
+ <ClInclude Include="stubs\mutex.h">
+ <Filter>stubs\include</Filter>
+ </ClInclude>
+ <ClInclude Include="stubs\once.h">
+ <Filter>stubs\include</Filter>
+ </ClInclude>
+ <ClInclude Include="parse_context.h">
+ <Filter>include</Filter>
+ </ClInclude>
+ <ClInclude Include="stubs\platform_macros.h">
+ <Filter>stubs\include</Filter>
+ </ClInclude>
+ <ClInclude Include="stubs\port.h">
+ <Filter>stubs\include</Filter>
+ </ClInclude>
+ <ClInclude Include="port.h">
+ <Filter>include</Filter>
+ </ClInclude>
+ <ClInclude Include="repeated_field.h">
+ <Filter>include</Filter>
+ </ClInclude>
+ <ClInclude Include="repeated_ptr_field.h">
+ <Filter>include</Filter>
+ </ClInclude>
+ <ClInclude Include="stubs\status.h">
+ <Filter>stubs\include</Filter>
+ </ClInclude>
+ <ClInclude Include="stubs\stl_util.h">
+ <Filter>stubs\include</Filter>
+ </ClInclude>
+ <ClInclude Include="stubs\stringpiece.h">
+ <Filter>stubs\include</Filter>
+ </ClInclude>
+ <ClInclude Include="stubs\strutil.h">
+ <Filter>stubs\include</Filter>
+ </ClInclude>
+ <ClInclude Include="io\strtod.h">
+ <Filter>io\include</Filter>
+ </ClInclude>
+ <ClInclude Include="stubs\template_util.h">
+ <Filter>stubs\include</Filter>
+ </ClInclude>
+ <ClInclude Include="io\zero_copy_stream.h">
+ <Filter>io\include</Filter>
+ </ClInclude>
+ <ClInclude Include="io\zero_copy_stream_impl.h">
+ <Filter>io\include</Filter>
+ </ClInclude>
+ <ClInclude Include="io\zero_copy_stream_impl_lite.h">
+ <Filter>io\include</Filter>
+ </ClInclude>
+ <ClInclude Include="stubs\int128.h">
+ <Filter>stubs\include</Filter>
+ </ClInclude>
+ <ClInclude Include="io\io_win32.h">
+ <Filter>io\include</Filter>
+ </ClInclude>
+ <ClInclude Include="message_lite.h">
+ <Filter>include</Filter>
+ </ClInclude>
+ <ClInclude Include="stubs\statusor.h">
+ <Filter>stubs\include</Filter>
+ </ClInclude>
+ <ClInclude Include="stubs\stringprintf.h">
+ <Filter>stubs\include</Filter>
+ </ClInclude>
+ <ClInclude Include="stubs\time.h">
+ <Filter>stubs\include</Filter>
+ </ClInclude>
+ <ClInclude Include="wire_format_lite.h">
+ <Filter>include</Filter>
+ </ClInclude>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/NorthstarDedicatedTest/include/protobuf/lite_arena_unittest.cc b/NorthstarDedicatedTest/include/protobuf/lite_arena_unittest.cc
new file mode 100644
index 00000000..3e5eee58
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/lite_arena_unittest.cc
@@ -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.
+
+#include <arena_test_util.h>
+#include <map_lite_test_util.h>
+#include <gtest/gtest.h>
+
+namespace google {
+namespace protobuf {
+namespace {
+
+class LiteArenaTest : public testing::Test {
+ protected:
+ LiteArenaTest() {
+ ArenaOptions options;
+ options.start_block_size = 128 * 1024;
+ options.max_block_size = 128 * 1024;
+ arena_.reset(new Arena(options));
+ // Trigger the allocation of the first arena block, so that further use of
+ // the arena will not require any heap allocations.
+ Arena::CreateArray<char>(arena_.get(), 1);
+ }
+
+ std::unique_ptr<Arena> arena_;
+};
+
+TEST_F(LiteArenaTest, MapNoHeapAllocation) {
+ std::string data;
+ data.reserve(128 * 1024);
+
+ {
+ // TODO(teboring): Enable no heap check when ArenaStringPtr is used in
+ // Map.
+ // internal::NoHeapChecker no_heap;
+
+ protobuf_unittest::TestArenaMapLite* from =
+ Arena::CreateMessage<protobuf_unittest::TestArenaMapLite>(arena_.get());
+ MapLiteTestUtil::SetArenaMapFields(from);
+ from->SerializeToString(&data);
+
+ protobuf_unittest::TestArenaMapLite* to =
+ Arena::CreateMessage<protobuf_unittest::TestArenaMapLite>(arena_.get());
+ to->ParseFromString(data);
+ MapLiteTestUtil::ExpectArenaMapFieldsSet(*to);
+ }
+}
+
+TEST_F(LiteArenaTest, UnknownFieldMemLeak) {
+ protobuf_unittest::ForeignMessageArenaLite* message =
+ Arena::CreateMessage<protobuf_unittest::ForeignMessageArenaLite>(
+ arena_.get());
+ std::string data = "\012\000";
+ int original_capacity = data.capacity();
+ while (data.capacity() <= original_capacity) {
+ data.append("a");
+ }
+ data[1] = data.size() - 2;
+ message->ParseFromString(data);
+}
+
+} // namespace
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/lite_unittest.cc b/NorthstarDedicatedTest/include/protobuf/lite_unittest.cc
new file mode 100644
index 00000000..09daaae9
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/lite_unittest.cc
@@ -0,0 +1,1272 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 <iostream>
+#include <string>
+
+#include <stubs/logging.h>
+#include <stubs/common.h>
+#include <arena_test_util.h>
+#include <map_lite_test_util.h>
+#include <map_lite_unittest.pb.h>
+#include <test_util_lite.h>
+#include <unittest_lite.pb.h>
+#include <io/coded_stream.h>
+#include <io/zero_copy_stream.h>
+#include <io/zero_copy_stream_impl.h>
+#include <io/zero_copy_stream_impl_lite.h>
+#include <wire_format_lite.h>
+#include <gtest/gtest.h>
+#include <stubs/strutil.h>
+
+namespace google {
+namespace protobuf {
+
+// Helper methods to test parsing merge behavior.
+void ExpectMessageMerged(const unittest::TestAllTypesLite& message) {
+ EXPECT_EQ(message.optional_int32(), 3);
+ EXPECT_EQ(message.optional_int64(), 2);
+ EXPECT_EQ(message.optional_string(), "hello");
+}
+
+void AssignParsingMergeMessages(unittest::TestAllTypesLite* msg1,
+ unittest::TestAllTypesLite* msg2,
+ unittest::TestAllTypesLite* msg3) {
+ msg1->set_optional_int32(1);
+ msg2->set_optional_int64(2);
+ msg3->set_optional_int32(3);
+ msg3->set_optional_string("hello");
+}
+
+void SetAllTypesInEmptyMessageUnknownFields(
+ unittest::TestEmptyMessageLite* empty_message) {
+ protobuf_unittest::TestAllTypesLite message;
+ TestUtilLite::ExpectClear(message);
+ TestUtilLite::SetAllFields(&message);
+ std::string data = message.SerializeAsString();
+ empty_message->ParseFromString(data);
+}
+
+void SetSomeTypesInEmptyMessageUnknownFields(
+ unittest::TestEmptyMessageLite* empty_message) {
+ protobuf_unittest::TestAllTypesLite message;
+ TestUtilLite::ExpectClear(message);
+ message.set_optional_int32(101);
+ message.set_optional_int64(102);
+ message.set_optional_uint32(103);
+ message.set_optional_uint64(104);
+ std::string data = message.SerializeAsString();
+ empty_message->ParseFromString(data);
+}
+
+TEST(Lite, AllLite1) {
+ std::string data;
+
+ {
+ protobuf_unittest::TestAllTypesLite message, message2, message3;
+ TestUtilLite::ExpectClear(message);
+ TestUtilLite::SetAllFields(&message);
+ message2.CopyFrom(message);
+ data = message.SerializeAsString();
+ message3.ParseFromString(data);
+ TestUtilLite::ExpectAllFieldsSet(message);
+ TestUtilLite::ExpectAllFieldsSet(message2);
+ TestUtilLite::ExpectAllFieldsSet(message3);
+ TestUtilLite::ModifyRepeatedFields(&message);
+ TestUtilLite::ExpectRepeatedFieldsModified(message);
+ message.Clear();
+ TestUtilLite::ExpectClear(message);
+ }
+}
+
+TEST(Lite, AllLite2) {
+ std::string data;
+ {
+ protobuf_unittest::TestAllExtensionsLite message, message2, message3;
+ TestUtilLite::ExpectExtensionsClear(message);
+ TestUtilLite::SetAllExtensions(&message);
+ message2.CopyFrom(message);
+ std::string extensions_data = message.SerializeAsString();
+ message3.ParseFromString(extensions_data);
+ TestUtilLite::ExpectAllExtensionsSet(message);
+ TestUtilLite::ExpectAllExtensionsSet(message2);
+ TestUtilLite::ExpectAllExtensionsSet(message3);
+ TestUtilLite::ModifyRepeatedExtensions(&message);
+ TestUtilLite::ExpectRepeatedExtensionsModified(message);
+ message.Clear();
+ TestUtilLite::ExpectExtensionsClear(message);
+ }
+}
+
+TEST(Lite, AllLite3) {
+ std::string data, packed_data;
+
+ {
+ protobuf_unittest::TestPackedTypesLite message, message2, message3;
+ TestUtilLite::ExpectPackedClear(message);
+ TestUtilLite::SetPackedFields(&message);
+ message2.CopyFrom(message);
+ packed_data = message.SerializeAsString();
+ message3.ParseFromString(packed_data);
+ TestUtilLite::ExpectPackedFieldsSet(message);
+ TestUtilLite::ExpectPackedFieldsSet(message2);
+ TestUtilLite::ExpectPackedFieldsSet(message3);
+ TestUtilLite::ModifyPackedFields(&message);
+ TestUtilLite::ExpectPackedFieldsModified(message);
+ message.Clear();
+ TestUtilLite::ExpectPackedClear(message);
+ }
+
+ {
+ protobuf_unittest::TestPackedExtensionsLite message, message2, message3;
+ TestUtilLite::ExpectPackedExtensionsClear(message);
+ TestUtilLite::SetPackedExtensions(&message);
+ message2.CopyFrom(message);
+ std::string packed_extensions_data = message.SerializeAsString();
+ EXPECT_EQ(packed_extensions_data, packed_data);
+ message3.ParseFromString(packed_extensions_data);
+ TestUtilLite::ExpectPackedExtensionsSet(message);
+ TestUtilLite::ExpectPackedExtensionsSet(message2);
+ TestUtilLite::ExpectPackedExtensionsSet(message3);
+ TestUtilLite::ModifyPackedExtensions(&message);
+ TestUtilLite::ExpectPackedExtensionsModified(message);
+ message.Clear();
+ TestUtilLite::ExpectPackedExtensionsClear(message);
+ }
+}
+
+TEST(Lite, AllLite5) {
+ std::string data;
+
+ {
+ // Test that if an optional or required message/group field appears multiple
+ // times in the input, they need to be merged.
+ unittest::TestParsingMergeLite::RepeatedFieldsGenerator generator;
+ unittest::TestAllTypesLite* msg1;
+ unittest::TestAllTypesLite* msg2;
+ unittest::TestAllTypesLite* msg3;
+
+#define ASSIGN_REPEATED_FIELD(FIELD) \
+ msg1 = generator.add_##FIELD(); \
+ msg2 = generator.add_##FIELD(); \
+ msg3 = generator.add_##FIELD(); \
+ AssignParsingMergeMessages(msg1, msg2, msg3)
+
+ ASSIGN_REPEATED_FIELD(field1);
+ ASSIGN_REPEATED_FIELD(field2);
+ ASSIGN_REPEATED_FIELD(field3);
+ ASSIGN_REPEATED_FIELD(ext1);
+ ASSIGN_REPEATED_FIELD(ext2);
+
+#undef ASSIGN_REPEATED_FIELD
+#define ASSIGN_REPEATED_GROUP(FIELD) \
+ msg1 = generator.add_##FIELD()->mutable_field1(); \
+ msg2 = generator.add_##FIELD()->mutable_field1(); \
+ msg3 = generator.add_##FIELD()->mutable_field1(); \
+ AssignParsingMergeMessages(msg1, msg2, msg3)
+
+ ASSIGN_REPEATED_GROUP(group1);
+ ASSIGN_REPEATED_GROUP(group2);
+
+#undef ASSIGN_REPEATED_GROUP
+
+ std::string buffer;
+ generator.SerializeToString(&buffer);
+ unittest::TestParsingMergeLite parsing_merge;
+ parsing_merge.ParseFromString(buffer);
+
+ // Required and optional fields should be merged.
+ ExpectMessageMerged(parsing_merge.required_all_types());
+ ExpectMessageMerged(parsing_merge.optional_all_types());
+ ExpectMessageMerged(
+ parsing_merge.optionalgroup().optional_group_all_types());
+ ExpectMessageMerged(parsing_merge.GetExtension(
+ unittest::TestParsingMergeLite::optional_ext));
+
+ // Repeated fields should not be merged.
+ EXPECT_EQ(parsing_merge.repeated_all_types_size(), 3);
+ EXPECT_EQ(parsing_merge.repeatedgroup_size(), 3);
+ EXPECT_EQ(parsing_merge.ExtensionSize(
+ unittest::TestParsingMergeLite::repeated_ext),
+ 3);
+ }
+}
+
+TEST(Lite, AllLite6) {
+ std::string data;
+
+ // Test unknown fields support for lite messages.
+ {
+ protobuf_unittest::TestAllTypesLite message, message2;
+ protobuf_unittest::TestEmptyMessageLite empty_message;
+ TestUtilLite::ExpectClear(message);
+ TestUtilLite::SetAllFields(&message);
+ data = message.SerializeAsString();
+ ASSERT_TRUE(empty_message.ParseFromString(data));
+ data.clear();
+ data = empty_message.SerializeAsString();
+ EXPECT_TRUE(message2.ParseFromString(data));
+ data = message2.SerializeAsString();
+ TestUtilLite::ExpectAllFieldsSet(message2);
+ message.Clear();
+ TestUtilLite::ExpectClear(message);
+ }
+}
+
+TEST(Lite, AllLite7) {
+ std::string data;
+
+ {
+ protobuf_unittest::TestAllExtensionsLite message, message2;
+ protobuf_unittest::TestEmptyMessageLite empty_message;
+ TestUtilLite::ExpectExtensionsClear(message);
+ TestUtilLite::SetAllExtensions(&message);
+ data = message.SerializeAsString();
+ empty_message.ParseFromString(data);
+ data.clear();
+ data = empty_message.SerializeAsString();
+ message2.ParseFromString(data);
+ data = message2.SerializeAsString();
+ TestUtilLite::ExpectAllExtensionsSet(message2);
+ message.Clear();
+ TestUtilLite::ExpectExtensionsClear(message);
+ }
+}
+
+TEST(Lite, AllLite8) {
+ std::string data;
+
+ {
+ protobuf_unittest::TestPackedTypesLite message, message2;
+ protobuf_unittest::TestEmptyMessageLite empty_message;
+ TestUtilLite::ExpectPackedClear(message);
+ TestUtilLite::SetPackedFields(&message);
+ data = message.SerializeAsString();
+ empty_message.ParseFromString(data);
+ data.clear();
+ data = empty_message.SerializeAsString();
+ message2.ParseFromString(data);
+ data = message2.SerializeAsString();
+ TestUtilLite::ExpectPackedFieldsSet(message2);
+ message.Clear();
+ TestUtilLite::ExpectPackedClear(message);
+ }
+}
+
+TEST(Lite, AllLite9) {
+ std::string data;
+
+ {
+ protobuf_unittest::TestPackedExtensionsLite message, message2;
+ protobuf_unittest::TestEmptyMessageLite empty_message;
+ TestUtilLite::ExpectPackedExtensionsClear(message);
+ TestUtilLite::SetPackedExtensions(&message);
+ data = message.SerializeAsString();
+ empty_message.ParseFromString(data);
+ data.clear();
+ data = empty_message.SerializeAsString();
+ message2.ParseFromString(data);
+ data = message2.SerializeAsString();
+ TestUtilLite::ExpectPackedExtensionsSet(message2);
+ message.Clear();
+ TestUtilLite::ExpectPackedExtensionsClear(message);
+ }
+}
+
+TEST(Lite, AllLite10) {
+ std::string data;
+
+ {
+ // Test Unknown fields swap
+ protobuf_unittest::TestEmptyMessageLite empty_message, empty_message2;
+ SetAllTypesInEmptyMessageUnknownFields(&empty_message);
+ SetSomeTypesInEmptyMessageUnknownFields(&empty_message2);
+ data = empty_message.SerializeAsString();
+ std::string data2 = empty_message2.SerializeAsString();
+ empty_message.Swap(&empty_message2);
+ EXPECT_EQ(data, empty_message2.SerializeAsString());
+ EXPECT_EQ(data2, empty_message.SerializeAsString());
+ }
+}
+
+TEST(Lite, AllLite11) {
+ std::string data;
+
+ {
+ // Test unknown fields swap with self
+ protobuf_unittest::TestEmptyMessageLite empty_message;
+ SetAllTypesInEmptyMessageUnknownFields(&empty_message);
+ data = empty_message.SerializeAsString();
+ empty_message.Swap(&empty_message);
+ EXPECT_EQ(data, empty_message.SerializeAsString());
+ }
+}
+
+TEST(Lite, AllLite12) {
+ std::string data;
+
+ {
+ // Test MergeFrom with unknown fields
+ protobuf_unittest::TestAllTypesLite message, message2;
+ protobuf_unittest::TestEmptyMessageLite empty_message, empty_message2;
+ message.set_optional_int32(101);
+ message.add_repeated_int32(201);
+ message.set_optional_nested_enum(unittest::TestAllTypesLite::BAZ);
+ message2.set_optional_int64(102);
+ message2.add_repeated_int64(202);
+ message2.set_optional_foreign_enum(unittest::FOREIGN_LITE_BAZ);
+
+ data = message.SerializeAsString();
+ empty_message.ParseFromString(data);
+ data = message2.SerializeAsString();
+ empty_message2.ParseFromString(data);
+ message.MergeFrom(message2);
+ empty_message.MergeFrom(empty_message2);
+
+ data = empty_message.SerializeAsString();
+ message2.ParseFromString(data);
+ // We do not compare the serialized output of a normal message and a lite
+ // message because the order of fields do not match. We convert lite message
+ // back into normal message, then compare.
+ EXPECT_EQ(message.SerializeAsString(), message2.SerializeAsString());
+ }
+}
+
+TEST(Lite, AllLite13) {
+ std::string data;
+
+ {
+ // Test unknown enum value
+ protobuf_unittest::TestAllTypesLite message;
+ std::string buffer;
+ {
+ io::StringOutputStream output_stream(&buffer);
+ io::CodedOutputStream coded_output(&output_stream);
+ internal::WireFormatLite::WriteTag(
+ protobuf_unittest::TestAllTypesLite::kOptionalNestedEnumFieldNumber,
+ internal::WireFormatLite::WIRETYPE_VARINT, &coded_output);
+ coded_output.WriteVarint32(10);
+ internal::WireFormatLite::WriteTag(
+ protobuf_unittest::TestAllTypesLite::kRepeatedNestedEnumFieldNumber,
+ internal::WireFormatLite::WIRETYPE_VARINT, &coded_output);
+ coded_output.WriteVarint32(20);
+ }
+ message.ParseFromString(buffer);
+ data = message.SerializeAsString();
+ EXPECT_EQ(data, buffer);
+ }
+}
+
+TEST(Lite, AllLite14) {
+ std::string data;
+
+ {
+ // Test Clear with unknown fields
+ protobuf_unittest::TestEmptyMessageLite empty_message;
+ SetAllTypesInEmptyMessageUnknownFields(&empty_message);
+ empty_message.Clear();
+ EXPECT_EQ(0, empty_message.unknown_fields().size());
+ }
+}
+
+// Tests for map lite =============================================
+
+TEST(Lite, AllLite15) {
+ std::string data;
+
+ {
+ // Accessors
+ protobuf_unittest::TestMapLite message;
+
+ MapLiteTestUtil::SetMapFields(&message);
+ MapLiteTestUtil::ExpectMapFieldsSet(message);
+
+ MapLiteTestUtil::ModifyMapFields(&message);
+ MapLiteTestUtil::ExpectMapFieldsModified(message);
+ }
+}
+
+TEST(Lite, AllLite16) {
+ std::string data;
+
+ {
+ // SetMapFieldsInitialized
+ protobuf_unittest::TestMapLite message;
+
+ MapLiteTestUtil::SetMapFieldsInitialized(&message);
+ MapLiteTestUtil::ExpectMapFieldsSetInitialized(message);
+ }
+}
+
+TEST(Lite, AllLite17) {
+ std::string data;
+
+ {
+ // Clear
+ protobuf_unittest::TestMapLite message;
+
+ MapLiteTestUtil::SetMapFields(&message);
+ message.Clear();
+ MapLiteTestUtil::ExpectClear(message);
+ }
+}
+
+TEST(Lite, AllLite18) {
+ std::string data;
+
+ {
+ // ClearMessageMap
+ protobuf_unittest::TestMessageMapLite message;
+
+ // Creates a TestAllTypes with default value
+ TestUtilLite::ExpectClear((*message.mutable_map_int32_message())[0]);
+ }
+}
+
+TEST(Lite, AllLite19) {
+ std::string data;
+
+ {
+ // CopyFrom
+ protobuf_unittest::TestMapLite message1, message2;
+
+ MapLiteTestUtil::SetMapFields(&message1);
+ message2.CopyFrom(message1);
+ MapLiteTestUtil::ExpectMapFieldsSet(message2);
+
+ // Copying from self should be a no-op.
+ message2.CopyFrom(message2);
+ MapLiteTestUtil::ExpectMapFieldsSet(message2);
+ }
+}
+
+TEST(Lite, AllLite20) {
+ std::string data;
+
+ {
+ // CopyFromMessageMap
+ protobuf_unittest::TestMessageMapLite message1, message2;
+
+ (*message1.mutable_map_int32_message())[0].add_repeated_int32(100);
+ (*message2.mutable_map_int32_message())[0].add_repeated_int32(101);
+
+ message1.CopyFrom(message2);
+
+ // Checks repeated field is overwritten.
+ EXPECT_EQ(1, message1.map_int32_message().at(0).repeated_int32_size());
+ EXPECT_EQ(101, message1.map_int32_message().at(0).repeated_int32(0));
+ }
+}
+
+TEST(Lite, AllLite21) {
+ std::string data;
+
+ {
+ // SwapWithEmpty
+ protobuf_unittest::TestMapLite message1, message2;
+
+ MapLiteTestUtil::SetMapFields(&message1);
+ MapLiteTestUtil::ExpectMapFieldsSet(message1);
+ MapLiteTestUtil::ExpectClear(message2);
+
+ message1.Swap(&message2);
+ MapLiteTestUtil::ExpectMapFieldsSet(message2);
+ MapLiteTestUtil::ExpectClear(message1);
+ }
+}
+
+TEST(Lite, AllLite22) {
+ std::string data;
+
+ {
+ // SwapWithSelf
+ protobuf_unittest::TestMapLite message;
+
+ MapLiteTestUtil::SetMapFields(&message);
+ MapLiteTestUtil::ExpectMapFieldsSet(message);
+
+ message.Swap(&message);
+ MapLiteTestUtil::ExpectMapFieldsSet(message);
+ }
+}
+
+TEST(Lite, AllLite23) {
+ std::string data;
+
+ {
+ // SwapWithOther
+ protobuf_unittest::TestMapLite message1, message2;
+
+ MapLiteTestUtil::SetMapFields(&message1);
+ MapLiteTestUtil::SetMapFields(&message2);
+ MapLiteTestUtil::ModifyMapFields(&message2);
+
+ message1.Swap(&message2);
+ MapLiteTestUtil::ExpectMapFieldsModified(message1);
+ MapLiteTestUtil::ExpectMapFieldsSet(message2);
+ }
+}
+
+TEST(Lite, AllLite24) {
+ std::string data;
+
+ {
+ // CopyConstructor
+ protobuf_unittest::TestMapLite message1;
+ MapLiteTestUtil::SetMapFields(&message1);
+
+ protobuf_unittest::TestMapLite message2(message1);
+ MapLiteTestUtil::ExpectMapFieldsSet(message2);
+ }
+}
+
+TEST(Lite, AllLite25) {
+ std::string data;
+
+ {
+ // CopyAssignmentOperator
+ protobuf_unittest::TestMapLite message1;
+ MapLiteTestUtil::SetMapFields(&message1);
+
+ protobuf_unittest::TestMapLite message2;
+ message2 = message1;
+ MapLiteTestUtil::ExpectMapFieldsSet(message2);
+
+ // Make sure that self-assignment does something sane.
+ message2.operator=(message2);
+ MapLiteTestUtil::ExpectMapFieldsSet(message2);
+ }
+}
+
+TEST(Lite, AllLite26) {
+ std::string data;
+
+ {
+ // NonEmptyMergeFrom
+ protobuf_unittest::TestMapLite message1, message2;
+
+ MapLiteTestUtil::SetMapFields(&message1);
+
+ // This field will test merging into an empty spot.
+ (*message2.mutable_map_int32_int32())[1] = 1;
+ message1.mutable_map_int32_int32()->erase(1);
+
+ // This tests overwriting.
+ (*message2.mutable_map_int32_double())[1] = 1;
+ (*message1.mutable_map_int32_double())[1] = 2;
+
+ message1.MergeFrom(message2);
+ MapLiteTestUtil::ExpectMapFieldsSet(message1);
+ }
+}
+
+TEST(Lite, AllLite27) {
+ std::string data;
+
+ {
+ // MergeFromMessageMap
+ protobuf_unittest::TestMessageMapLite message1, message2;
+
+ (*message1.mutable_map_int32_message())[0].add_repeated_int32(100);
+ (*message2.mutable_map_int32_message())[0].add_repeated_int32(101);
+
+ message1.MergeFrom(message2);
+
+ // Checks repeated field is overwritten.
+ EXPECT_EQ(1, message1.map_int32_message().at(0).repeated_int32_size());
+ EXPECT_EQ(101, message1.map_int32_message().at(0).repeated_int32(0));
+ }
+}
+
+TEST(Lite, AllLite28) {
+ std::string data;
+
+ {
+ // Test the generated SerializeWithCachedSizesToArray()
+ protobuf_unittest::TestMapLite message1, message2;
+ std::string data;
+ MapLiteTestUtil::SetMapFields(&message1);
+ size_t size = message1.ByteSizeLong();
+ data.resize(size);
+ ::google::protobuf::uint8* start = reinterpret_cast<::google::protobuf::uint8*>(::google::protobuf::string_as_array(&data));
+ ::google::protobuf::uint8* end = message1.SerializeWithCachedSizesToArray(start);
+ EXPECT_EQ(size, end - start);
+ EXPECT_TRUE(message2.ParseFromString(data));
+ MapLiteTestUtil::ExpectMapFieldsSet(message2);
+ }
+}
+
+TEST(Lite, AllLite29) {
+ std::string data;
+
+ {
+ // Test the generated SerializeWithCachedSizes()
+ protobuf_unittest::TestMapLite message1, message2;
+ MapLiteTestUtil::SetMapFields(&message1);
+ size_t size = message1.ByteSizeLong();
+ std::string data;
+ data.resize(size);
+ {
+ // Allow the output stream to buffer only one byte at a time.
+ io::ArrayOutputStream array_stream(::google::protobuf::string_as_array(&data), size, 1);
+ io::CodedOutputStream output_stream(&array_stream);
+ message1.SerializeWithCachedSizes(&output_stream);
+ EXPECT_FALSE(output_stream.HadError());
+ EXPECT_EQ(size, output_stream.ByteCount());
+ }
+ EXPECT_TRUE(message2.ParseFromString(data));
+ MapLiteTestUtil::ExpectMapFieldsSet(message2);
+ }
+}
+
+
+TEST(Lite, AllLite32) {
+ std::string data;
+
+ {
+ // Proto2UnknownEnum
+ protobuf_unittest::TestEnumMapPlusExtraLite from;
+ (*from.mutable_known_map_field())[0] =
+ protobuf_unittest::E_PROTO2_MAP_ENUM_FOO_LITE;
+ (*from.mutable_unknown_map_field())[0] =
+ protobuf_unittest::E_PROTO2_MAP_ENUM_EXTRA_LITE;
+ std::string data;
+ from.SerializeToString(&data);
+
+ protobuf_unittest::TestEnumMapLite to;
+ EXPECT_TRUE(to.ParseFromString(data));
+ EXPECT_EQ(0, to.unknown_map_field().size());
+ EXPECT_FALSE(to.mutable_unknown_fields()->empty());
+ ASSERT_EQ(1, to.known_map_field().size());
+ EXPECT_EQ(protobuf_unittest::PROTO2_MAP_ENUM_FOO_LITE,
+ to.known_map_field().at(0));
+
+ data.clear();
+ from.Clear();
+ to.SerializeToString(&data);
+ EXPECT_TRUE(from.ParseFromString(data));
+ ASSERT_EQ(1, from.known_map_field().size());
+ EXPECT_EQ(protobuf_unittest::E_PROTO2_MAP_ENUM_FOO_LITE,
+ from.known_map_field().at(0));
+ ASSERT_EQ(1, from.unknown_map_field().size());
+ EXPECT_EQ(protobuf_unittest::E_PROTO2_MAP_ENUM_EXTRA_LITE,
+ from.unknown_map_field().at(0));
+ }
+}
+
+TEST(Lite, AllLite33) {
+ std::string data;
+
+ {
+ // StandardWireFormat
+ protobuf_unittest::TestMapLite message;
+ std::string data = "\x0A\x04\x08\x01\x10\x01";
+
+ EXPECT_TRUE(message.ParseFromString(data));
+ ASSERT_EQ(1, message.map_int32_int32().size());
+ EXPECT_EQ(1, message.map_int32_int32().at(1));
+ }
+}
+
+TEST(Lite, AllLite34) {
+ std::string data;
+
+ {
+ // UnorderedWireFormat
+ protobuf_unittest::TestMapLite message;
+
+ // put value before key in wire format
+ std::string data = "\x0A\x04\x10\x01\x08\x02";
+
+ EXPECT_TRUE(message.ParseFromString(data));
+ ASSERT_EQ(1, message.map_int32_int32().size());
+ ASSERT_NE(message.map_int32_int32().find(2),
+ message.map_int32_int32().end());
+ EXPECT_EQ(1, message.map_int32_int32().at(2));
+ }
+}
+
+TEST(Lite, AllLite35) {
+ std::string data;
+
+ {
+ // DuplicatedKeyWireFormat
+ protobuf_unittest::TestMapLite message;
+
+ // Two key fields in wire format
+ std::string data = "\x0A\x06\x08\x01\x08\x02\x10\x01";
+
+ EXPECT_TRUE(message.ParseFromString(data));
+ ASSERT_EQ(1, message.map_int32_int32().size());
+ EXPECT_EQ(1, message.map_int32_int32().at(2));
+ }
+}
+
+TEST(Lite, AllLite36) {
+ std::string data;
+
+ {
+ // DuplicatedValueWireFormat
+ protobuf_unittest::TestMapLite message;
+
+ // Two value fields in wire format
+ std::string data = "\x0A\x06\x08\x01\x10\x01\x10\x02";
+
+ EXPECT_TRUE(message.ParseFromString(data));
+ ASSERT_EQ(1, message.map_int32_int32().size());
+ EXPECT_EQ(2, message.map_int32_int32().at(1));
+ }
+}
+
+TEST(Lite, AllLite37) {
+ std::string data;
+
+ {
+ // MissedKeyWireFormat
+ protobuf_unittest::TestMapLite message;
+
+ // No key field in wire format
+ std::string data = "\x0A\x02\x10\x01";
+
+ EXPECT_TRUE(message.ParseFromString(data));
+ ASSERT_EQ(1, message.map_int32_int32().size());
+ ASSERT_NE(message.map_int32_int32().find(0),
+ message.map_int32_int32().end());
+ EXPECT_EQ(1, message.map_int32_int32().at(0));
+ }
+}
+
+TEST(Lite, AllLite38) {
+ std::string data;
+
+ {
+ // MissedValueWireFormat
+ protobuf_unittest::TestMapLite message;
+
+ // No value field in wire format
+ std::string data = "\x0A\x02\x08\x01";
+
+ EXPECT_TRUE(message.ParseFromString(data));
+ ASSERT_EQ(1, message.map_int32_int32().size());
+ ASSERT_NE(message.map_int32_int32().find(1),
+ message.map_int32_int32().end());
+ EXPECT_EQ(0, message.map_int32_int32().at(1));
+ }
+}
+
+TEST(Lite, AllLite39) {
+ std::string data;
+
+ {
+ // UnknownFieldWireFormat
+ protobuf_unittest::TestMapLite message;
+
+ // Unknown field in wire format
+ std::string data = "\x0A\x06\x08\x02\x10\x03\x18\x01";
+
+ EXPECT_TRUE(message.ParseFromString(data));
+ ASSERT_EQ(1, message.map_int32_int32().size());
+ EXPECT_EQ(3, message.map_int32_int32().at(2));
+ }
+}
+
+TEST(Lite, AllLite40) {
+ std::string data;
+
+ {
+ // CorruptedWireFormat
+ protobuf_unittest::TestMapLite message;
+
+ // corrupted data in wire format
+ std::string data = "\x0A\x06\x08\x02\x11\x03";
+
+ EXPECT_FALSE(message.ParseFromString(data));
+ }
+}
+
+TEST(Lite, AllLite41) {
+ std::string data;
+
+ {
+ // IsInitialized
+ protobuf_unittest::TestRequiredMessageMapLite map_message;
+
+ // Add an uninitialized message.
+ (*map_message.mutable_map_field())[0];
+ EXPECT_FALSE(map_message.IsInitialized());
+
+ // Initialize uninitialized message
+ (*map_message.mutable_map_field())[0].set_a(0);
+ (*map_message.mutable_map_field())[0].set_b(0);
+ (*map_message.mutable_map_field())[0].set_c(0);
+ EXPECT_TRUE(map_message.IsInitialized());
+ }
+}
+
+TEST(Lite, AllLite42) {
+ std::string data;
+
+ {
+ // Check that adding more values to enum does not corrupt message
+ // when passed through an old client.
+ protobuf_unittest::V2MessageLite v2_message;
+ v2_message.set_int_field(800);
+ // Set enum field to the value not understood by the old client.
+ v2_message.set_enum_field(protobuf_unittest::V2_SECOND);
+ std::string v2_bytes = v2_message.SerializeAsString();
+
+ protobuf_unittest::V1MessageLite v1_message;
+ v1_message.ParseFromString(v2_bytes);
+ EXPECT_TRUE(v1_message.IsInitialized());
+ EXPECT_EQ(v1_message.int_field(), v2_message.int_field());
+ // V1 client does not understand V2_SECOND value, so it discards it and
+ // uses default value instead.
+ EXPECT_EQ(v1_message.enum_field(), protobuf_unittest::V1_FIRST);
+
+ // However, when re-serialized, it should preserve enum value.
+ std::string v1_bytes = v1_message.SerializeAsString();
+
+ protobuf_unittest::V2MessageLite same_v2_message;
+ same_v2_message.ParseFromString(v1_bytes);
+
+ EXPECT_EQ(v2_message.int_field(), same_v2_message.int_field());
+ EXPECT_EQ(v2_message.enum_field(), same_v2_message.enum_field());
+ }
+}
+
+// Test that when parsing a oneof, we can successfully clear whatever already
+// happened to be stored in the oneof.
+TEST(Lite, AllLite43) {
+ protobuf_unittest::TestOneofParsingLite message1;
+
+ message1.set_oneof_int32(17);
+ std::string serialized;
+ EXPECT_TRUE(message1.SerializeToString(&serialized));
+
+ // Submessage
+ {
+ protobuf_unittest::TestOneofParsingLite message2;
+ message2.mutable_oneof_submessage();
+ io::CodedInputStream input_stream(
+ reinterpret_cast<const ::google::protobuf::uint8*>(serialized.data()), serialized.size());
+ EXPECT_TRUE(message2.MergeFromCodedStream(&input_stream));
+ EXPECT_EQ(17, message2.oneof_int32());
+ }
+
+ // String
+ {
+ protobuf_unittest::TestOneofParsingLite message2;
+ message2.set_oneof_string("string");
+ io::CodedInputStream input_stream(
+ reinterpret_cast<const ::google::protobuf::uint8*>(serialized.data()), serialized.size());
+ EXPECT_TRUE(message2.MergeFromCodedStream(&input_stream));
+ EXPECT_EQ(17, message2.oneof_int32());
+ }
+
+ // Bytes
+ {
+ protobuf_unittest::TestOneofParsingLite message2;
+ message2.set_oneof_bytes("bytes");
+ io::CodedInputStream input_stream(
+ reinterpret_cast<const ::google::protobuf::uint8*>(serialized.data()), serialized.size());
+ EXPECT_TRUE(message2.MergeFromCodedStream(&input_stream));
+ EXPECT_EQ(17, message2.oneof_int32());
+ }
+}
+
+// Verify that we can successfully parse fields of various types within oneof
+// fields. We also verify that we can parse the same data twice into the same
+// message.
+TEST(Lite, AllLite44) {
+ // Int32
+ {
+ protobuf_unittest::TestOneofParsingLite original;
+ original.set_oneof_int32(17);
+ std::string serialized;
+ EXPECT_TRUE(original.SerializeToString(&serialized));
+ protobuf_unittest::TestOneofParsingLite parsed;
+ for (int i = 0; i < 2; ++i) {
+ io::CodedInputStream input_stream(
+ reinterpret_cast<const ::google::protobuf::uint8*>(serialized.data()),
+ serialized.size());
+ EXPECT_TRUE(parsed.MergeFromCodedStream(&input_stream));
+ EXPECT_EQ(17, parsed.oneof_int32());
+ }
+ }
+
+ // Submessage
+ {
+ protobuf_unittest::TestOneofParsingLite original;
+ original.mutable_oneof_submessage()->set_optional_int32(5);
+ std::string serialized;
+ EXPECT_TRUE(original.SerializeToString(&serialized));
+ protobuf_unittest::TestOneofParsingLite parsed;
+ for (int i = 0; i < 2; ++i) {
+ io::CodedInputStream input_stream(
+ reinterpret_cast<const ::google::protobuf::uint8*>(serialized.data()),
+ serialized.size());
+ EXPECT_TRUE(parsed.MergeFromCodedStream(&input_stream));
+ EXPECT_EQ(5, parsed.oneof_submessage().optional_int32());
+ }
+ }
+
+ // String
+ {
+ protobuf_unittest::TestOneofParsingLite original;
+ original.set_oneof_string("string");
+ std::string serialized;
+ EXPECT_TRUE(original.SerializeToString(&serialized));
+ protobuf_unittest::TestOneofParsingLite parsed;
+ for (int i = 0; i < 2; ++i) {
+ io::CodedInputStream input_stream(
+ reinterpret_cast<const ::google::protobuf::uint8*>(serialized.data()),
+ serialized.size());
+ EXPECT_TRUE(parsed.MergeFromCodedStream(&input_stream));
+ EXPECT_EQ("string", parsed.oneof_string());
+ }
+ }
+
+ // Bytes
+ {
+ protobuf_unittest::TestOneofParsingLite original;
+ original.set_oneof_bytes("bytes");
+ std::string serialized;
+ EXPECT_TRUE(original.SerializeToString(&serialized));
+ protobuf_unittest::TestOneofParsingLite parsed;
+ for (int i = 0; i < 2; ++i) {
+ io::CodedInputStream input_stream(
+ reinterpret_cast<const ::google::protobuf::uint8*>(serialized.data()),
+ serialized.size());
+ EXPECT_TRUE(parsed.MergeFromCodedStream(&input_stream));
+ EXPECT_EQ("bytes", parsed.oneof_bytes());
+ }
+ }
+
+ // Enum
+ {
+ protobuf_unittest::TestOneofParsingLite original;
+ original.set_oneof_enum(protobuf_unittest::V2_SECOND);
+ std::string serialized;
+ EXPECT_TRUE(original.SerializeToString(&serialized));
+ protobuf_unittest::TestOneofParsingLite parsed;
+ for (int i = 0; i < 2; ++i) {
+ io::CodedInputStream input_stream(
+ reinterpret_cast<const ::google::protobuf::uint8*>(serialized.data()),
+ serialized.size());
+ EXPECT_TRUE(parsed.MergeFromCodedStream(&input_stream));
+ EXPECT_EQ(protobuf_unittest::V2_SECOND, parsed.oneof_enum());
+ }
+ }
+
+ std::cout << "PASS" << std::endl;
+}
+
+TEST(Lite, AllLite45) {
+ // Test unknown fields are not discarded upon parsing.
+ std::string data = "\20\1"; // varint 1 with field number 2
+
+ protobuf_unittest::ForeignMessageLite a;
+ EXPECT_TRUE(a.ParseFromString(data));
+ io::CodedInputStream input_stream(
+ reinterpret_cast<const ::google::protobuf::uint8*>(data.data()), data.size());
+ EXPECT_TRUE(a.MergePartialFromCodedStream(&input_stream));
+
+ std::string serialized = a.SerializeAsString();
+ EXPECT_EQ(serialized.substr(0, 2), data);
+ EXPECT_EQ(serialized.substr(2), data);
+}
+
+// The following two tests check for wire compatibility between packed and
+// unpacked repeated fields. There used to be a bug in the generated parsing
+// code that caused us to calculate the highest possible tag number without
+// taking into account that a repeated field might not be in the packed (or
+// unpacked) state we expect. These tests specifically check for that issue by
+// making sure we can parse repeated fields when the tag is higher than we would
+// expect.
+TEST(Lite, AllLite46) {
+ protobuf_unittest::PackedInt32 packed;
+ packed.add_repeated_int32(42);
+ std::string serialized;
+ ASSERT_TRUE(packed.SerializeToString(&serialized));
+
+ protobuf_unittest::NonPackedInt32 non_packed;
+ ASSERT_TRUE(non_packed.ParseFromString(serialized));
+ ASSERT_EQ(1, non_packed.repeated_int32_size());
+ EXPECT_EQ(42, non_packed.repeated_int32(0));
+}
+
+TEST(Lite, AllLite47) {
+ protobuf_unittest::NonPackedFixed32 non_packed;
+ non_packed.add_repeated_fixed32(42);
+ std::string serialized;
+ ASSERT_TRUE(non_packed.SerializeToString(&serialized));
+
+ protobuf_unittest::PackedFixed32 packed;
+ ASSERT_TRUE(packed.ParseFromString(serialized));
+ ASSERT_EQ(1, packed.repeated_fixed32_size());
+ EXPECT_EQ(42, packed.repeated_fixed32(0));
+}
+
+TEST(Lite, MapCrash) {
+ // See b/113635730
+ Arena arena;
+ auto msg = Arena::CreateMessage<protobuf_unittest::TestMapLite>(&arena);
+ // Payload for the map<string, Enum> with a enum varint that's longer >
+ // 10 bytes. This causes a parse fail and a subsequent delete. field 16
+ // (map<int32, MapEnumLite>) tag = 128+2 = \202 \1
+ // 13 long \15
+ // int32 key = 1 (\10 \1)
+ // MapEnumLite value = too long varint (parse error)
+ EXPECT_FALSE(msg->ParseFromString(
+ "\202\1\15\10\1\200\200\200\200\200\200\200\200\200\200\1"));
+}
+
+TEST(Lite, CorrectEnding) {
+ protobuf_unittest::TestAllTypesLite msg;
+ {
+ // All proto wireformat parsers should act the same on parsing data in as
+ // much as it concerns the parsing, ie. not the interpretation of the data.
+ // TestAllTypesLite is not a group inside another message. So in practice
+ // will not encounter an end-group tag. However the parser should behave
+ // like any wire format parser should.
+ static const char kWireFormat[] = "\204\1";
+ io::CodedInputStream cis(reinterpret_cast<const uint8*>(kWireFormat), 2);
+ // The old CodedInputStream parser got an optimization (ReadTagNoLastTag)
+ // for non-group messages (like TestAllTypesLite) which made it not accept
+ // end-group. This is not a real big deal, but I think going forward its
+ // good to have all parse loops behave 'exactly' the same.
+ EXPECT_TRUE(msg.MergePartialFromCodedStream(&cis));
+ EXPECT_FALSE(cis.ConsumedEntireMessage());
+ EXPECT_TRUE(cis.LastTagWas(132));
+ }
+ {
+ // This is an incomplete end-group tag. This should be a genuine parse
+ // failure.
+ static const char kWireFormat[] = "\214";
+ io::CodedInputStream cis(reinterpret_cast<const uint8*>(kWireFormat), 1);
+ // Unfortunately the old parser detects a parse error in ReadTag and returns
+ // 0 (as it states 0 is an invalid tag). However 0 is not an invalid tag
+ // as it can be used to terminate the stream, so this returns true.
+ EXPECT_FALSE(msg.MergePartialFromCodedStream(&cis));
+ }
+}
+
+TEST(Lite, DebugString) {
+ protobuf_unittest::TestAllTypesLite message1, message2;
+ EXPECT_TRUE(HasPrefixString(message1.DebugString(), "MessageLite at 0x"));
+ EXPECT_TRUE(HasPrefixString(message2.DebugString(), "MessageLite at 0x"));
+
+ // DebugString() and ShortDebugString() are the same for now.
+ EXPECT_EQ(message1.DebugString(), message1.ShortDebugString());
+
+ // Even identical lite protos should have different DebugString() output. Part
+ // of the reason for including the memory address is so that we get some
+ // non-determinism, which should make it easier for us to change the output
+ // later without breaking any code.
+ EXPECT_NE(message1.DebugString(), message2.DebugString());
+}
+
+TEST(Lite, EnumValueToName) {
+ EXPECT_EQ("FOREIGN_LITE_FOO", protobuf_unittest::ForeignEnumLite_Name(
+ protobuf_unittest::FOREIGN_LITE_FOO));
+ EXPECT_EQ("FOREIGN_LITE_BAR", protobuf_unittest::ForeignEnumLite_Name(
+ protobuf_unittest::FOREIGN_LITE_BAR));
+ EXPECT_EQ("FOREIGN_LITE_BAZ", protobuf_unittest::ForeignEnumLite_Name(
+ protobuf_unittest::FOREIGN_LITE_BAZ));
+ EXPECT_EQ("", protobuf_unittest::ForeignEnumLite_Name(0));
+ EXPECT_EQ("", protobuf_unittest::ForeignEnumLite_Name(999));
+}
+
+TEST(Lite, NestedEnumValueToName) {
+ EXPECT_EQ("FOO", protobuf_unittest::TestAllTypesLite::NestedEnum_Name(
+ protobuf_unittest::TestAllTypesLite::FOO));
+ EXPECT_EQ("BAR", protobuf_unittest::TestAllTypesLite::NestedEnum_Name(
+ protobuf_unittest::TestAllTypesLite::BAR));
+ EXPECT_EQ("BAZ", protobuf_unittest::TestAllTypesLite::NestedEnum_Name(
+ protobuf_unittest::TestAllTypesLite::BAZ));
+ EXPECT_EQ("", protobuf_unittest::TestAllTypesLite::NestedEnum_Name(0));
+ EXPECT_EQ("", protobuf_unittest::TestAllTypesLite::NestedEnum_Name(999));
+}
+
+TEST(Lite, EnumNameToValue) {
+ protobuf_unittest::ForeignEnumLite value;
+
+ ASSERT_TRUE(
+ protobuf_unittest::ForeignEnumLite_Parse("FOREIGN_LITE_FOO", &value));
+ EXPECT_EQ(protobuf_unittest::FOREIGN_LITE_FOO, value);
+
+ ASSERT_TRUE(
+ protobuf_unittest::ForeignEnumLite_Parse("FOREIGN_LITE_BAR", &value));
+ EXPECT_EQ(protobuf_unittest::FOREIGN_LITE_BAR, value);
+
+ ASSERT_TRUE(
+ protobuf_unittest::ForeignEnumLite_Parse("FOREIGN_LITE_BAZ", &value));
+ EXPECT_EQ(protobuf_unittest::FOREIGN_LITE_BAZ, value);
+
+ // Non-existent values
+ EXPECT_FALSE(protobuf_unittest::ForeignEnumLite_Parse("E", &value));
+ EXPECT_FALSE(
+ protobuf_unittest::ForeignEnumLite_Parse("FOREIGN_LITE_C", &value));
+ EXPECT_FALSE(protobuf_unittest::ForeignEnumLite_Parse("G", &value));
+}
+
+TEST(Lite, NestedEnumNameToValue) {
+ protobuf_unittest::TestAllTypesLite::NestedEnum value;
+
+ ASSERT_TRUE(
+ protobuf_unittest::TestAllTypesLite::NestedEnum_Parse("FOO", &value));
+ EXPECT_EQ(protobuf_unittest::TestAllTypesLite::FOO, value);
+
+ ASSERT_TRUE(
+ protobuf_unittest::TestAllTypesLite::NestedEnum_Parse("BAR", &value));
+ EXPECT_EQ(protobuf_unittest::TestAllTypesLite::BAR, value);
+
+ ASSERT_TRUE(
+ protobuf_unittest::TestAllTypesLite::NestedEnum_Parse("BAZ", &value));
+ EXPECT_EQ(protobuf_unittest::TestAllTypesLite::BAZ, value);
+
+ // Non-existent values
+ EXPECT_FALSE(
+ protobuf_unittest::TestAllTypesLite::NestedEnum_Parse("A", &value));
+ EXPECT_FALSE(
+ protobuf_unittest::TestAllTypesLite::NestedEnum_Parse("C", &value));
+ EXPECT_FALSE(
+ protobuf_unittest::TestAllTypesLite::NestedEnum_Parse("G", &value));
+}
+
+TEST(Lite, AliasedEnum) {
+ // Enums with allow_alias = true can have multiple entries with the same
+ // value.
+ EXPECT_EQ("FOO1", protobuf_unittest::DupEnum::TestEnumWithDupValueLite_Name(
+ protobuf_unittest::DupEnum::FOO1));
+ EXPECT_EQ("FOO1", protobuf_unittest::DupEnum::TestEnumWithDupValueLite_Name(
+ protobuf_unittest::DupEnum::FOO2));
+ EXPECT_EQ("BAR1", protobuf_unittest::DupEnum::TestEnumWithDupValueLite_Name(
+ protobuf_unittest::DupEnum::BAR1));
+ EXPECT_EQ("BAR1", protobuf_unittest::DupEnum::TestEnumWithDupValueLite_Name(
+ protobuf_unittest::DupEnum::BAR2));
+ EXPECT_EQ("BAZ", protobuf_unittest::DupEnum::TestEnumWithDupValueLite_Name(
+ protobuf_unittest::DupEnum::BAZ));
+ EXPECT_EQ("", protobuf_unittest::DupEnum::TestEnumWithDupValueLite_Name(999));
+
+ protobuf_unittest::DupEnum::TestEnumWithDupValueLite value;
+ ASSERT_TRUE(
+ protobuf_unittest::DupEnum::TestEnumWithDupValueLite_Parse("FOO1", &value));
+ EXPECT_EQ(protobuf_unittest::DupEnum::FOO1, value);
+
+ value = static_cast<protobuf_unittest::DupEnum::TestEnumWithDupValueLite>(0);
+ ASSERT_TRUE(
+ protobuf_unittest::DupEnum::TestEnumWithDupValueLite_Parse("FOO2", &value));
+ EXPECT_EQ(protobuf_unittest::DupEnum::FOO2, value);
+}
+
+
+TEST(Lite, CodedInputStreamRollback) {
+ {
+ protobuf_unittest::TestAllTypesLite m;
+ m.set_optional_bytes(std::string(30, 'a'));
+ std::string serialized = m.SerializeAsString();
+ serialized += '\014';
+ serialized += std::string(3, ' ');
+ io::ArrayInputStream is(serialized.data(), serialized.size(),
+ serialized.size() - 6);
+ {
+ io::CodedInputStream cis(&is);
+ m.Clear();
+ m.MergePartialFromCodedStream(&cis);
+ EXPECT_TRUE(cis.LastTagWas(12));
+ EXPECT_FALSE(cis.ConsumedEntireMessage());
+ // Should leave is with 3 spaces;
+ }
+ const void* data;
+ int size;
+ ASSERT_TRUE(is.Next(&data, &size));
+ ASSERT_EQ(size, 3);
+ EXPECT_EQ(memcmp(data, " ", 3), 0);
+ }
+ {
+ protobuf_unittest::TestPackedTypesLite m;
+ constexpr int kCount = 30;
+ for (int i = 0; i < kCount; i++) m.add_packed_fixed32(i);
+ std::string serialized = m.SerializeAsString();
+ serialized += '\014';
+ serialized += std::string(3, ' ');
+ // Buffer breaks in middle of a fixed32.
+ io::ArrayInputStream is(serialized.data(), serialized.size(),
+ serialized.size() - 7);
+ {
+ io::CodedInputStream cis(&is);
+ m.Clear();
+ m.MergePartialFromCodedStream(&cis);
+ EXPECT_TRUE(cis.LastTagWas(12));
+ EXPECT_FALSE(cis.ConsumedEntireMessage());
+ // Should leave is with 3 spaces;
+ }
+ ASSERT_EQ(m.packed_fixed32_size(), kCount);
+ for (int i = 0; i < kCount; i++) EXPECT_EQ(m.packed_fixed32(i), i);
+ const void* data;
+ int size;
+ ASSERT_TRUE(is.Next(&data, &size));
+ ASSERT_EQ(size, 3);
+ EXPECT_EQ(memcmp(data, " ", 3), 0);
+ }
+ {
+ protobuf_unittest::TestPackedTypesLite m;
+ constexpr int kCount = 30;
+ // Make sure we output 2 byte varints
+ for (int i = 0; i < kCount; i++) m.add_packed_fixed32(128 + i);
+ std::string serialized = m.SerializeAsString();
+ serialized += '\014';
+ serialized += std::string(3, ' ');
+ // Buffer breaks in middle of a 2 byte varint.
+ io::ArrayInputStream is(serialized.data(), serialized.size(),
+ serialized.size() - 5);
+ {
+ io::CodedInputStream cis(&is);
+ m.Clear();
+ m.MergePartialFromCodedStream(&cis);
+ EXPECT_TRUE(cis.LastTagWas(12));
+ EXPECT_FALSE(cis.ConsumedEntireMessage());
+ // Should leave is with 3 spaces;
+ }
+ ASSERT_EQ(m.packed_fixed32_size(), kCount);
+ for (int i = 0; i < kCount; i++) EXPECT_EQ(m.packed_fixed32(i), i + 128);
+ const void* data;
+ int size;
+ ASSERT_TRUE(is.Next(&data, &size));
+ ASSERT_EQ(size, 3);
+ EXPECT_EQ(memcmp(data, " ", 3), 0);
+ }
+}
+
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/map.cc b/NorthstarDedicatedTest/include/protobuf/map.cc
new file mode 100644
index 00000000..f1c9d962
--- /dev/null
+++ b/NorthstarDedicatedTest/include/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 <map.h>
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+void* const kGlobalEmptyTable[kGlobalEmptyTableSize] = {nullptr};
+
+} // namespace internal
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/map.h b/NorthstarDedicatedTest/include/protobuf/map.h
new file mode 100644
index 00000000..7f29d853
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/map.h
@@ -0,0 +1,1377 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 <stubs/common.h>
+#include <arena.h>
+#include <generated_enum_util.h>
+#include <map_type_handler.h>
+#include <stubs/hash.h>
+
+#ifdef SWIG
+#error "You cannot SWIG proto headers"
+#endif
+
+#include <port_def.inc>
+
+namespace google {
+namespace protobuf {
+
+template <typename Key, typename T>
+class Map;
+
+class MapIterator;
+
+template <typename Enum>
+struct is_proto_enum;
+
+namespace internal {
+template <typename Derived, typename Key, typename T,
+ WireFormatLite::FieldType key_wire_type,
+ WireFormatLite::FieldType value_wire_type>
+class MapFieldLite;
+
+template <typename Derived, typename Key, typename T,
+ WireFormatLite::FieldType key_wire_type,
+ WireFormatLite::FieldType value_wire_type>
+class MapField;
+
+template <typename Key, typename T>
+class TypeDefinedMapFieldBase;
+
+class DynamicMapField;
+
+class GeneratedMessageReflection;
+
+// re-implement std::allocator to use arena allocator for memory allocation.
+// Used for Map implementation. Users should not use this class
+// directly.
+template <typename U>
+class MapAllocator {
+ public:
+ using value_type = U;
+ using pointer = value_type*;
+ using const_pointer = const value_type*;
+ using reference = value_type&;
+ using const_reference = const value_type&;
+ using size_type = size_t;
+ using difference_type = ptrdiff_t;
+
+ constexpr MapAllocator() : arena_(nullptr) {}
+ explicit constexpr MapAllocator(Arena* arena) : arena_(arena) {}
+ template <typename X>
+ MapAllocator(const MapAllocator<X>& allocator) // NOLINT(runtime/explicit)
+ : arena_(allocator.arena()) {}
+
+ pointer allocate(size_type n, const void* /* hint */ = nullptr) {
+ // If arena is not given, malloc needs to be called which doesn't
+ // construct element object.
+ if (arena_ == nullptr) {
+ return static_cast<pointer>(::operator new(n * sizeof(value_type)));
+ } else {
+ return reinterpret_cast<pointer>(
+ Arena::CreateArray<uint8_t>(arena_, n * sizeof(value_type)));
+ }
+ }
+
+ void deallocate(pointer p, size_type n) {
+ if (arena_ == nullptr) {
+#if defined(__GXX_DELETE_WITH_SIZE__) || defined(__cpp_sized_deallocation)
+ ::operator delete(p, n * sizeof(value_type));
+#else
+ (void)n;
+ ::operator delete(p);
+#endif
+ }
+ }
+
+#if !defined(GOOGLE_PROTOBUF_OS_APPLE) && !defined(GOOGLE_PROTOBUF_OS_NACL) && \
+ !defined(GOOGLE_PROTOBUF_OS_EMSCRIPTEN)
+ template <class NodeType, class... Args>
+ void construct(NodeType* p, Args&&... args) {
+ // Clang 3.6 doesn't compile static casting to void* directly. (Issue
+ // #1266) According C++ standard 5.2.9/1: "The static_cast operator shall
+ // not cast away constness". So first the maybe const pointer is casted to
+ // const void* and after the const void* is const casted.
+ new (const_cast<void*>(static_cast<const void*>(p)))
+ NodeType(std::forward<Args>(args)...);
+ }
+
+ template <class NodeType>
+ void destroy(NodeType* p) {
+ p->~NodeType();
+ }
+#else
+ void construct(pointer p, const_reference t) { new (p) value_type(t); }
+
+ void destroy(pointer p) { p->~value_type(); }
+#endif
+
+ template <typename X>
+ struct rebind {
+ using other = MapAllocator<X>;
+ };
+
+ template <typename X>
+ bool operator==(const MapAllocator<X>& other) const {
+ return arena_ == other.arena_;
+ }
+
+ template <typename X>
+ bool operator!=(const MapAllocator<X>& other) const {
+ return arena_ != other.arena_;
+ }
+
+ // To support Visual Studio 2008
+ size_type max_size() const {
+ // parentheses around (std::...:max) prevents macro warning of max()
+ return (std::numeric_limits<size_type>::max)();
+ }
+
+ // To support gcc-4.4, which does not properly
+ // support templated friend classes
+ Arena* arena() const { return arena_; }
+
+ private:
+ using DestructorSkippable_ = void;
+ Arena* arena_;
+};
+
+template <typename T>
+using KeyForTree =
+ typename std::conditional<std::is_scalar<T>::value, T,
+ std::reference_wrapper<const T>>::type;
+
+// Default case: Not transparent.
+// We use std::hash<key_type>/std::less<key_type> and all the lookup functions
+// only accept `key_type`.
+template <typename key_type>
+struct TransparentSupport {
+ using hash = std::hash<key_type>;
+ using less = std::less<key_type>;
+
+ static bool Equals(const key_type& a, const key_type& b) { return a == b; }
+
+ template <typename K>
+ using key_arg = key_type;
+};
+
+#if defined(__cpp_lib_string_view)
+// If std::string_view is available, we add transparent support for 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 MapPair {
+ using first_type = const Key;
+ using second_type = T;
+
+ MapPair(const Key& other_first, const T& other_second)
+ : first(other_first), second(other_second) {}
+ explicit MapPair(const Key& other_first) : first(other_first), second() {}
+ explicit MapPair(Key&& other_first)
+ : first(std::move(other_first)), second() {}
+ MapPair(const MapPair& other) : first(other.first), second(other.second) {}
+
+ ~MapPair() {}
+
+ // Implicitly convertible to std::pair of compatible types.
+ template <typename T1, typename T2>
+ operator std::pair<T1, T2>() const { // NOLINT(runtime/explicit)
+ return std::pair<T1, T2>(first, second);
+ }
+
+ const Key first;
+ T second;
+
+ private:
+ friend class Arena;
+ friend class Map<Key, T>;
+};
+
+// Map is an associative container type used to store protobuf map
+// fields. Each Map instance may or may not use a different hash function, a
+// different iteration order, and so on. E.g., please don't examine
+// implementation details to decide if the following would work:
+// Map<int, int> m0, m1;
+// m0[0] = m1[0] = m0[1] = m1[1] = 0;
+// assert(m0.begin()->first == m1.begin()->first); // Bug!
+//
+// Map's interface is similar to std::unordered_map, except that Map is not
+// designed to play well with exceptions.
+template <typename Key, typename T>
+class Map {
+ public:
+ using key_type = Key;
+ using mapped_type = T;
+ using value_type = MapPair<Key, T>;
+
+ using pointer = value_type*;
+ using const_pointer = const value_type*;
+ using reference = value_type&;
+ using const_reference = const value_type&;
+
+ using size_type = size_t;
+ using hasher = typename internal::TransparentSupport<Key>::hash;
+
+ constexpr Map() : elements_(nullptr) {}
+ explicit Map(Arena* arena) : elements_(arena) {}
+
+ Map(const Map& other) : Map() { insert(other.begin(), other.end()); }
+
+ Map(Map&& other) noexcept : Map() {
+ if (other.arena() != nullptr) {
+ *this = other;
+ } else {
+ swap(other);
+ }
+ }
+
+ Map& operator=(Map&& other) noexcept {
+ if (this != &other) {
+ if (arena() != other.arena()) {
+ *this = other;
+ } else {
+ swap(other);
+ }
+ }
+ return *this;
+ }
+
+ template <class InputIt>
+ Map(const InputIt& first, const InputIt& last) : Map() {
+ insert(first, last);
+ }
+
+ ~Map() {}
+
+ private:
+ using Allocator = internal::MapAllocator<void*>;
+
+ // InnerMap is a generic hash-based map. It doesn't contain any
+ // protocol-buffer-specific logic. It is a chaining hash map with the
+ // additional feature that some buckets can be converted to use an ordered
+ // container. This ensures O(lg n) bounds on find, insert, and erase, while
+ // avoiding the overheads of ordered containers most of the time.
+ //
+ // The implementation doesn't need the full generality of unordered_map,
+ // and it doesn't have it. More bells and whistles can be added as needed.
+ // Some implementation details:
+ // 1. The hash function has type hasher and the equality function
+ // equal_to<Key>. We inherit from hasher to save space
+ // (empty-base-class optimization).
+ // 2. The number of buckets is a power of two.
+ // 3. Buckets are converted to trees in pairs: if we convert bucket b then
+ // buckets b and b^1 will share a tree. Invariant: buckets b and b^1 have
+ // the same non-null value iff they are sharing a tree. (An alternative
+ // implementation strategy would be to have a tag bit per bucket.)
+ // 4. As is typical for hash_map and such, the Keys and Values are always
+ // stored in linked list nodes. Pointers to elements are never invalidated
+ // until the element is deleted.
+ // 5. The trees' payload type is pointer to linked-list node. Tree-converting
+ // a bucket doesn't copy Key-Value pairs.
+ // 6. Once we've tree-converted a bucket, it is never converted back. However,
+ // the items a tree contains may wind up assigned to trees or lists upon a
+ // rehash.
+ // 7. The code requires no C++ features from C++14 or later.
+ // 8. Mutations to a map do not invalidate the map's iterators, pointers to
+ // elements, or references to elements.
+ // 9. Except for erase(iterator), any non-const method can reorder iterators.
+ // 10. InnerMap uses KeyForTree<Key> when using the Tree representation, which
+ // is either `Key`, if Key is a scalar, or `reference_wrapper<const Key>`
+ // otherwise. This avoids unnecessary copies of string keys, for example.
+ class InnerMap : private hasher {
+ public:
+ explicit constexpr InnerMap(Arena* arena)
+ : hasher(),
+ num_elements_(0),
+ num_buckets_(internal::kGlobalEmptyTableSize),
+ seed_(0),
+ index_of_first_non_null_(internal::kGlobalEmptyTableSize),
+ table_(const_cast<void**>(internal::kGlobalEmptyTable)),
+ alloc_(arena) {}
+
+ ~InnerMap() {
+ if (alloc_.arena() == nullptr &&
+ num_buckets_ != internal::kGlobalEmptyTableSize) {
+ clear();
+ Dealloc<void*>(table_, num_buckets_);
+ }
+ }
+
+ private:
+ enum { kMinTableSize = 8 };
+
+ // Linked-list nodes, as one would expect for a chaining hash table.
+ struct Node {
+ value_type kv;
+ Node* next;
+ };
+
+ // Trees. The payload type is a copy of Key, so that we can query the tree
+ // with Keys that are not in any particular data structure.
+ // The value is a void* pointing to Node. We use void* instead of Node* to
+ // avoid code bloat. That way there is only one instantiation of the tree
+ // class per key type.
+ using Tree = internal::TreeForMap<Key>;
+ using TreeIterator = typename Tree::iterator;
+
+ static Node* NodeFromTreeIterator(TreeIterator it) {
+ return static_cast<Node*>(it->second);
+ }
+
+ // iterator and const_iterator are instantiations of iterator_base.
+ template <typename KeyValueType>
+ class iterator_base {
+ public:
+ using reference = KeyValueType&;
+ using pointer = KeyValueType*;
+
+ // Invariants:
+ // node_ is always correct. This is handy because the most common
+ // operations are operator* and operator-> and they only use node_.
+ // When node_ is set to a non-null value, all the other non-const fields
+ // are updated to be correct also, but those fields can become stale
+ // if the underlying map is modified. When those fields are needed they
+ // are rechecked, and updated if necessary.
+ iterator_base() : node_(nullptr), m_(nullptr), bucket_index_(0) {}
+
+ explicit iterator_base(const InnerMap* m) : m_(m) {
+ SearchFrom(m->index_of_first_non_null_);
+ }
+
+ // Any iterator_base can convert to any other. This is overkill, and we
+ // rely on the enclosing class to use it wisely. The standard "iterator
+ // can convert to const_iterator" is OK but the reverse direction is not.
+ template <typename U>
+ explicit iterator_base(const iterator_base<U>& it)
+ : node_(it.node_), m_(it.m_), bucket_index_(it.bucket_index_) {}
+
+ iterator_base(Node* n, const InnerMap* m, size_type index)
+ : node_(n), m_(m), bucket_index_(index) {}
+
+ iterator_base(TreeIterator tree_it, const InnerMap* m, size_type index)
+ : node_(NodeFromTreeIterator(tree_it)), m_(m), bucket_index_(index) {
+ // Invariant: iterators that use buckets with trees have an even
+ // bucket_index_.
+ GOOGLE_DCHECK_EQ(bucket_index_ % 2, 0u);
+ }
+
+ // Advance through buckets, looking for the first that isn't empty.
+ // If nothing non-empty is found then leave node_ == nullptr.
+ void SearchFrom(size_type start_bucket) {
+ GOOGLE_DCHECK(m_->index_of_first_non_null_ == m_->num_buckets_ ||
+ m_->table_[m_->index_of_first_non_null_] != nullptr);
+ node_ = nullptr;
+ for (bucket_index_ = start_bucket; bucket_index_ < m_->num_buckets_;
+ bucket_index_++) {
+ if (m_->TableEntryIsNonEmptyList(bucket_index_)) {
+ node_ = static_cast<Node*>(m_->table_[bucket_index_]);
+ break;
+ } else if (m_->TableEntryIsTree(bucket_index_)) {
+ Tree* tree = static_cast<Tree*>(m_->table_[bucket_index_]);
+ GOOGLE_DCHECK(!tree->empty());
+ node_ = NodeFromTreeIterator(tree->begin());
+ break;
+ }
+ }
+ }
+
+ reference operator*() const { return node_->kv; }
+ pointer operator->() const { return &(operator*()); }
+
+ friend bool operator==(const iterator_base& a, const iterator_base& b) {
+ return a.node_ == b.node_;
+ }
+ friend bool operator!=(const iterator_base& a, const iterator_base& b) {
+ return a.node_ != b.node_;
+ }
+
+ iterator_base& operator++() {
+ if (node_->next == nullptr) {
+ TreeIterator tree_it;
+ const bool is_list = revalidate_if_necessary(&tree_it);
+ if (is_list) {
+ SearchFrom(bucket_index_ + 1);
+ } else {
+ GOOGLE_DCHECK_EQ(bucket_index_ & 1, 0u);
+ Tree* tree = static_cast<Tree*>(m_->table_[bucket_index_]);
+ if (++tree_it == tree->end()) {
+ SearchFrom(bucket_index_ + 2);
+ } else {
+ node_ = NodeFromTreeIterator(tree_it);
+ }
+ }
+ } else {
+ node_ = node_->next;
+ }
+ return *this;
+ }
+
+ iterator_base operator++(int /* unused */) {
+ iterator_base tmp = *this;
+ ++*this;
+ return tmp;
+ }
+
+ // Assumes node_ and m_ are correct and non-null, but other fields may be
+ // stale. Fix them as needed. Then return true iff node_ points to a
+ // Node in a list. If false is returned then *it is modified to be
+ // a valid iterator for node_.
+ bool revalidate_if_necessary(TreeIterator* it) {
+ GOOGLE_DCHECK(node_ != nullptr && m_ != nullptr);
+ // Force bucket_index_ to be in range.
+ bucket_index_ &= (m_->num_buckets_ - 1);
+ // Common case: the bucket we think is relevant points to node_.
+ if (m_->table_[bucket_index_] == static_cast<void*>(node_)) return true;
+ // Less common: the bucket is a linked list with node_ somewhere in it,
+ // but not at the head.
+ if (m_->TableEntryIsNonEmptyList(bucket_index_)) {
+ Node* l = static_cast<Node*>(m_->table_[bucket_index_]);
+ while ((l = l->next) != nullptr) {
+ if (l == node_) {
+ return true;
+ }
+ }
+ }
+ // Well, bucket_index_ still might be correct, but probably
+ // not. Revalidate just to be sure. This case is rare enough that we
+ // don't worry about potential optimizations, such as having a custom
+ // find-like method that compares Node* instead of the key.
+ iterator_base i(m_->find(node_->kv.first, it));
+ bucket_index_ = i.bucket_index_;
+ return m_->TableEntryIsList(bucket_index_);
+ }
+
+ Node* node_;
+ const InnerMap* m_;
+ size_type bucket_index_;
+ };
+
+ public:
+ using iterator = iterator_base<value_type>;
+ using const_iterator = iterator_base<const value_type>;
+
+ Arena* arena() const { return alloc_.arena(); }
+
+ void Swap(InnerMap* other) {
+ std::swap(num_elements_, other->num_elements_);
+ std::swap(num_buckets_, other->num_buckets_);
+ std::swap(seed_, other->seed_);
+ std::swap(index_of_first_non_null_, other->index_of_first_non_null_);
+ std::swap(table_, other->table_);
+ std::swap(alloc_, other->alloc_);
+ }
+
+ iterator begin() { return iterator(this); }
+ iterator end() { return iterator(); }
+ const_iterator begin() const { return const_iterator(this); }
+ const_iterator end() const { return const_iterator(); }
+
+ void clear() {
+ for (size_type b = 0; b < num_buckets_; b++) {
+ if (TableEntryIsNonEmptyList(b)) {
+ Node* node = static_cast<Node*>(table_[b]);
+ table_[b] = nullptr;
+ do {
+ Node* next = node->next;
+ DestroyNode(node);
+ node = next;
+ } while (node != nullptr);
+ } else if (TableEntryIsTree(b)) {
+ Tree* tree = static_cast<Tree*>(table_[b]);
+ GOOGLE_DCHECK(table_[b] == table_[b + 1] && (b & 1) == 0);
+ table_[b] = table_[b + 1] = nullptr;
+ typename Tree::iterator tree_it = tree->begin();
+ do {
+ Node* node = NodeFromTreeIterator(tree_it);
+ typename Tree::iterator next = tree_it;
+ ++next;
+ tree->erase(tree_it);
+ DestroyNode(node);
+ tree_it = next;
+ } while (tree_it != tree->end());
+ DestroyTree(tree);
+ b++;
+ }
+ }
+ num_elements_ = 0;
+ index_of_first_non_null_ = num_buckets_;
+ }
+
+ const hasher& hash_function() const { return *this; }
+
+ static size_type max_size() {
+ return static_cast<size_type>(1) << (sizeof(void**) >= 8 ? 60 : 28);
+ }
+ size_type size() const { return num_elements_; }
+ bool empty() const { return size() == 0; }
+
+ template <typename K>
+ iterator find(const K& k) {
+ return iterator(FindHelper(k).first);
+ }
+
+ template <typename K>
+ const_iterator find(const K& k) const {
+ return FindHelper(k).first;
+ }
+
+ // Insert the key into the map, if not present. In that case, the value will
+ // be value initialized.
+ template <typename K>
+ std::pair<iterator, bool> insert(K&& k) {
+ std::pair<const_iterator, size_type> p = FindHelper(k);
+ // Case 1: key was already present.
+ if (p.first.node_ != nullptr)
+ return std::make_pair(iterator(p.first), false);
+ // Case 2: insert.
+ if (ResizeIfLoadIsOutOfRange(num_elements_ + 1)) {
+ p = FindHelper(k);
+ }
+ const size_type b = p.second; // bucket number
+ // If K is not key_type, make the conversion to key_type explicit.
+ using TypeToInit = typename std::conditional<
+ std::is_same<typename std::decay<K>::type, key_type>::value, K&&,
+ key_type>::type;
+ Node* node = Alloc<Node>(1);
+ // Even when arena is nullptr, CreateInArenaStorage is still used to
+ // ensure the arena of submessage will be consistent. Otherwise,
+ // submessage may have its own arena when message-owned arena is enabled.
+ Arena::CreateInArenaStorage(const_cast<Key*>(&node->kv.first),
+ alloc_.arena(),
+ static_cast<TypeToInit>(std::forward<K>(k)));
+ Arena::CreateInArenaStorage(&node->kv.second, alloc_.arena());
+
+ iterator result = InsertUnique(b, node);
+ ++num_elements_;
+ return std::make_pair(result, true);
+ }
+
+ template <typename K>
+ value_type& operator[](K&& k) {
+ return *insert(std::forward<K>(k)).first;
+ }
+
+ void erase(iterator it) {
+ GOOGLE_DCHECK_EQ(it.m_, this);
+ typename Tree::iterator tree_it;
+ const bool is_list = it.revalidate_if_necessary(&tree_it);
+ size_type b = it.bucket_index_;
+ Node* const item = it.node_;
+ if (is_list) {
+ GOOGLE_DCHECK(TableEntryIsNonEmptyList(b));
+ Node* head = static_cast<Node*>(table_[b]);
+ head = EraseFromLinkedList(item, head);
+ table_[b] = static_cast<void*>(head);
+ } else {
+ GOOGLE_DCHECK(TableEntryIsTree(b));
+ Tree* tree = static_cast<Tree*>(table_[b]);
+ tree->erase(tree_it);
+ if (tree->empty()) {
+ // Force b to be the minimum of b and b ^ 1. This is important
+ // only because we want index_of_first_non_null_ to be correct.
+ b &= ~static_cast<size_type>(1);
+ DestroyTree(tree);
+ table_[b] = table_[b + 1] = nullptr;
+ }
+ }
+ DestroyNode(item);
+ --num_elements_;
+ if (PROTOBUF_PREDICT_FALSE(b == index_of_first_non_null_)) {
+ while (index_of_first_non_null_ < num_buckets_ &&
+ table_[index_of_first_non_null_] == nullptr) {
+ ++index_of_first_non_null_;
+ }
+ }
+ }
+
+ size_t SpaceUsedInternal() const {
+ return internal::SpaceUsedInTable<Key>(table_, num_buckets_,
+ num_elements_, sizeof(Node));
+ }
+
+ private:
+ const_iterator find(const Key& k, TreeIterator* it) const {
+ return FindHelper(k, it).first;
+ }
+ template <typename K>
+ std::pair<const_iterator, size_type> FindHelper(const K& k) const {
+ return FindHelper(k, nullptr);
+ }
+ template <typename K>
+ std::pair<const_iterator, size_type> FindHelper(const K& k,
+ TreeIterator* it) const {
+ size_type b = BucketNumber(k);
+ if (TableEntryIsNonEmptyList(b)) {
+ Node* node = static_cast<Node*>(table_[b]);
+ do {
+ if (internal::TransparentSupport<Key>::Equals(node->kv.first, k)) {
+ return std::make_pair(const_iterator(node, this, b), b);
+ } else {
+ node = node->next;
+ }
+ } while (node != nullptr);
+ } else if (TableEntryIsTree(b)) {
+ GOOGLE_DCHECK_EQ(table_[b], table_[b ^ 1]);
+ b &= ~static_cast<size_t>(1);
+ Tree* tree = static_cast<Tree*>(table_[b]);
+ auto tree_it = tree->find(k);
+ if (tree_it != tree->end()) {
+ if (it != nullptr) *it = tree_it;
+ return std::make_pair(const_iterator(tree_it, this, b), b);
+ }
+ }
+ return std::make_pair(end(), b);
+ }
+
+ // Insert the given Node in bucket b. If that would make bucket b too big,
+ // and bucket b is not a tree, create a tree for buckets b and b^1 to share.
+ // Requires count(*KeyPtrFromNodePtr(node)) == 0 and that b is the correct
+ // bucket. num_elements_ is not modified.
+ iterator InsertUnique(size_type b, Node* node) {
+ GOOGLE_DCHECK(index_of_first_non_null_ == num_buckets_ ||
+ table_[index_of_first_non_null_] != nullptr);
+ // In practice, the code that led to this point may have already
+ // determined whether we are inserting into an empty list, a short list,
+ // or whatever. But it's probably cheap enough to recompute that here;
+ // it's likely that we're inserting into an empty or short list.
+ iterator result;
+ GOOGLE_DCHECK(find(node->kv.first) == end());
+ if (TableEntryIsEmpty(b)) {
+ result = InsertUniqueInList(b, node);
+ } else if (TableEntryIsNonEmptyList(b)) {
+ if (PROTOBUF_PREDICT_FALSE(TableEntryIsTooLong(b))) {
+ TreeConvert(b);
+ result = InsertUniqueInTree(b, node);
+ GOOGLE_DCHECK_EQ(result.bucket_index_, b & ~static_cast<size_type>(1));
+ } else {
+ // Insert into a pre-existing list. This case cannot modify
+ // index_of_first_non_null_, so we skip the code to update it.
+ return InsertUniqueInList(b, node);
+ }
+ } else {
+ // Insert into a pre-existing tree. This case cannot modify
+ // index_of_first_non_null_, so we skip the code to update it.
+ return InsertUniqueInTree(b, node);
+ }
+ // parentheses around (std::min) prevents macro expansion of min(...)
+ index_of_first_non_null_ =
+ (std::min)(index_of_first_non_null_, result.bucket_index_);
+ return result;
+ }
+
+ // Returns whether we should insert after the head of the list. For
+ // non-optimized builds, we randomly decide whether to insert right at the
+ // head of the list or just after the head. This helps add a little bit of
+ // non-determinism to the map ordering.
+ bool ShouldInsertAfterHead(void* node) {
+#ifdef NDEBUG
+ (void)node;
+ return false;
+#else
+ // Doing modulo with a prime mixes the bits more.
+ return (reinterpret_cast<uintptr_t>(node) ^ seed_) % 13 > 6;
+#endif
+ }
+
+ // Helper for InsertUnique. Handles the case where bucket b is a
+ // not-too-long linked list.
+ iterator InsertUniqueInList(size_type b, Node* node) {
+ if (table_[b] != nullptr && ShouldInsertAfterHead(node)) {
+ Node* first = static_cast<Node*>(table_[b]);
+ node->next = first->next;
+ first->next = node;
+ return iterator(node, this, b);
+ }
+
+ node->next = static_cast<Node*>(table_[b]);
+ table_[b] = static_cast<void*>(node);
+ return iterator(node, this, b);
+ }
+
+ // Helper for InsertUnique. Handles the case where bucket b points to a
+ // Tree.
+ iterator InsertUniqueInTree(size_type b, Node* node) {
+ GOOGLE_DCHECK_EQ(table_[b], table_[b ^ 1]);
+ // Maintain the invariant that node->next is null for all Nodes in Trees.
+ node->next = nullptr;
+ return iterator(
+ static_cast<Tree*>(table_[b])->insert({node->kv.first, node}).first,
+ this, b & ~static_cast<size_t>(1));
+ }
+
+ // Returns whether it did resize. Currently this is only used when
+ // num_elements_ increases, though it could be used in other situations.
+ // It checks for load too low as well as load too high: because any number
+ // of erases can occur between inserts, the load could be as low as 0 here.
+ // Resizing to a lower size is not always helpful, but failing to do so can
+ // destroy the expected big-O bounds for some operations. By having the
+ // policy that sometimes we resize down as well as up, clients can easily
+ // keep O(size()) = O(number of buckets) if they want that.
+ bool ResizeIfLoadIsOutOfRange(size_type new_size) {
+ const size_type kMaxMapLoadTimes16 = 12; // controls RAM vs CPU tradeoff
+ const size_type hi_cutoff = num_buckets_ * kMaxMapLoadTimes16 / 16;
+ const size_type lo_cutoff = hi_cutoff / 4;
+ // We don't care how many elements are in trees. If a lot are,
+ // we may resize even though there are many empty buckets. In
+ // practice, this seems fine.
+ if (PROTOBUF_PREDICT_FALSE(new_size >= hi_cutoff)) {
+ if (num_buckets_ <= max_size() / 2) {
+ Resize(num_buckets_ * 2);
+ return true;
+ }
+ } else if (PROTOBUF_PREDICT_FALSE(new_size <= lo_cutoff &&
+ num_buckets_ > kMinTableSize)) {
+ size_type lg2_of_size_reduction_factor = 1;
+ // It's possible we want to shrink a lot here... size() could even be 0.
+ // So, estimate how much to shrink by making sure we don't shrink so
+ // much that we would need to grow the table after a few inserts.
+ const size_type hypothetical_size = new_size * 5 / 4 + 1;
+ while ((hypothetical_size << lg2_of_size_reduction_factor) <
+ hi_cutoff) {
+ ++lg2_of_size_reduction_factor;
+ }
+ size_type new_num_buckets = std::max<size_type>(
+ kMinTableSize, num_buckets_ >> lg2_of_size_reduction_factor);
+ if (new_num_buckets != num_buckets_) {
+ Resize(new_num_buckets);
+ return true;
+ }
+ }
+ return false;
+ }
+
+ // Resize to the given number of buckets.
+ void Resize(size_t new_num_buckets) {
+ if (num_buckets_ == internal::kGlobalEmptyTableSize) {
+ // This is the global empty array.
+ // Just overwrite with a new one. No need to transfer or free anything.
+ num_buckets_ = index_of_first_non_null_ = kMinTableSize;
+ table_ = CreateEmptyTable(num_buckets_);
+ seed_ = Seed();
+ return;
+ }
+
+ GOOGLE_DCHECK_GE(new_num_buckets, kMinTableSize);
+ void** const old_table = table_;
+ const size_type old_table_size = num_buckets_;
+ num_buckets_ = new_num_buckets;
+ table_ = CreateEmptyTable(num_buckets_);
+ const size_type start = index_of_first_non_null_;
+ index_of_first_non_null_ = num_buckets_;
+ for (size_type i = start; i < old_table_size; i++) {
+ if (internal::TableEntryIsNonEmptyList(old_table, i)) {
+ TransferList(old_table, i);
+ } else if (internal::TableEntryIsTree(old_table, i)) {
+ TransferTree(old_table, i++);
+ }
+ }
+ Dealloc<void*>(old_table, old_table_size);
+ }
+
+ void TransferList(void* const* table, size_type index) {
+ Node* node = static_cast<Node*>(table[index]);
+ do {
+ Node* next = node->next;
+ InsertUnique(BucketNumber(node->kv.first), node);
+ node = next;
+ } while (node != nullptr);
+ }
+
+ void TransferTree(void* const* table, size_type index) {
+ Tree* tree = static_cast<Tree*>(table[index]);
+ typename Tree::iterator tree_it = tree->begin();
+ do {
+ InsertUnique(BucketNumber(std::cref(tree_it->first).get()),
+ NodeFromTreeIterator(tree_it));
+ } while (++tree_it != tree->end());
+ DestroyTree(tree);
+ }
+
+ Node* EraseFromLinkedList(Node* item, Node* head) {
+ if (head == item) {
+ return head->next;
+ } else {
+ head->next = EraseFromLinkedList(item, head->next);
+ return head;
+ }
+ }
+
+ bool TableEntryIsEmpty(size_type b) const {
+ return internal::TableEntryIsEmpty(table_, b);
+ }
+ bool TableEntryIsNonEmptyList(size_type b) const {
+ return internal::TableEntryIsNonEmptyList(table_, b);
+ }
+ bool TableEntryIsTree(size_type b) const {
+ return internal::TableEntryIsTree(table_, b);
+ }
+ bool TableEntryIsList(size_type b) const {
+ return internal::TableEntryIsList(table_, b);
+ }
+
+ void TreeConvert(size_type b) {
+ GOOGLE_DCHECK(!TableEntryIsTree(b) && !TableEntryIsTree(b ^ 1));
+ Tree* tree =
+ Arena::Create<Tree>(alloc_.arena(), typename Tree::key_compare(),
+ typename Tree::allocator_type(alloc_));
+ size_type count = CopyListToTree(b, tree) + CopyListToTree(b ^ 1, tree);
+ GOOGLE_DCHECK_EQ(count, tree->size());
+ table_[b] = table_[b ^ 1] = static_cast<void*>(tree);
+ }
+
+ // Copy a linked list in the given bucket to a tree.
+ // Returns the number of things it copied.
+ size_type CopyListToTree(size_type b, Tree* tree) {
+ size_type count = 0;
+ Node* node = static_cast<Node*>(table_[b]);
+ while (node != nullptr) {
+ tree->insert({node->kv.first, node});
+ ++count;
+ Node* next = node->next;
+ node->next = nullptr;
+ node = next;
+ }
+ return count;
+ }
+
+ // Return whether table_[b] is a linked list that seems awfully long.
+ // Requires table_[b] to point to a non-empty linked list.
+ bool TableEntryIsTooLong(size_type b) {
+ const size_type kMaxLength = 8;
+ size_type count = 0;
+ Node* node = static_cast<Node*>(table_[b]);
+ do {
+ ++count;
+ node = node->next;
+ } while (node != nullptr);
+ // Invariant: no linked list ever is more than kMaxLength in length.
+ GOOGLE_DCHECK_LE(count, kMaxLength);
+ return count >= kMaxLength;
+ }
+
+ template <typename K>
+ size_type BucketNumber(const K& k) const {
+ // We xor the hash value against the random seed so that we effectively
+ // have a random hash function.
+ 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
+ std::pair<iterator, bool> insert(const value_type& value) {
+ std::pair<typename InnerMap::iterator, bool> p =
+ elements_.insert(value.first);
+ if (p.second) {
+ p.first->second = value.second;
+ }
+ return std::pair<iterator, bool>(iterator(p.first), p.second);
+ }
+ template <class InputIt>
+ void insert(InputIt first, InputIt last) {
+ for (InputIt it = first; it != last; ++it) {
+ iterator exist_it = find(it->first);
+ if (exist_it == end()) {
+ operator[](it->first) = it->second;
+ }
+ }
+ }
+ void insert(std::initializer_list<value_type> values) {
+ insert(values.begin(), values.end());
+ }
+
+ // Erase and clear
+ template <typename K = key_type>
+ size_type erase(const key_arg<K>& key) {
+ iterator it = find(key);
+ if (it == end()) {
+ return 0;
+ } else {
+ erase(it);
+ return 1;
+ }
+ }
+ iterator erase(iterator pos) {
+ iterator i = pos++;
+ elements_.erase(i.it_);
+ return pos;
+ }
+ void erase(iterator first, iterator last) {
+ while (first != last) {
+ first = erase(first);
+ }
+ }
+ void clear() { elements_.clear(); }
+
+ // Assign
+ Map& operator=(const Map& other) {
+ if (this != &other) {
+ clear();
+ insert(other.begin(), other.end());
+ }
+ return *this;
+ }
+
+ void swap(Map& other) {
+ if (arena() == other.arena()) {
+ InternalSwap(other);
+ } else {
+ // TODO(zuguang): optimize this. The temporary copy can be allocated
+ // in the same arena as the other message, and the "other = copy" can
+ // be replaced with the fast-path swap above.
+ Map copy = *this;
+ *this = other;
+ other = copy;
+ }
+ }
+
+ void InternalSwap(Map& other) { elements_.Swap(&other.elements_); }
+
+ // Access to hasher. Currently this returns a copy, but it may
+ // be modified to return a const reference in the future.
+ hasher hash_function() const { return elements_.hash_function(); }
+
+ size_t SpaceUsedExcludingSelfLong() const {
+ if (empty()) return 0;
+ return elements_.SpaceUsedInternal() + internal::SpaceUsedInValues(this);
+ }
+
+ private:
+ Arena* arena() const { return elements_.arena(); }
+ InnerMap elements_;
+
+ friend class Arena;
+ using InternalArenaConstructable_ = void;
+ using DestructorSkippable_ = void;
+ template <typename Derived, typename K, typename V,
+ internal::WireFormatLite::FieldType key_wire_type,
+ internal::WireFormatLite::FieldType value_wire_type>
+ friend class internal::MapFieldLite;
+};
+
+} // namespace protobuf
+} // namespace google
+
+#include <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_MAP_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/map_entry.h b/NorthstarDedicatedTest/include/protobuf/map_entry.h
new file mode 100644
index 00000000..dc44a64e
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/map_entry.h
@@ -0,0 +1,160 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef GOOGLE_PROTOBUF_MAP_ENTRY_H__
+#define GOOGLE_PROTOBUF_MAP_ENTRY_H__
+
+#include <generated_message_reflection.h>
+#include <map_entry_lite.h>
+#include <map_type_handler.h>
+#include <port.h>
+#include <reflection_ops.h>
+#include <unknown_field_set.h>
+#include <wire_format_lite.h>
+
+#include <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() : _internal_metadata_() {}
+ explicit MapEntry(Arena* arena)
+ : MapEntryImpl<Derived, Message, Key, Value, kKeyFieldType,
+ kValueFieldType>(arena),
+ _internal_metadata_(arena) {}
+ ~MapEntry() {
+ Message::_internal_metadata_.template Delete<UnknownFieldSet>();
+ _internal_metadata_.Delete<UnknownFieldSet>();
+ }
+ typedef void InternalArenaConstructable_;
+ typedef void DestructorSkippable_;
+
+ typedef typename MapEntryImpl<Derived, Message, Key, Value, kKeyFieldType,
+ kValueFieldType>::KeyTypeHandler KeyTypeHandler;
+ typedef
+ typename MapEntryImpl<Derived, Message, Key, Value, kKeyFieldType,
+ kValueFieldType>::ValueTypeHandler ValueTypeHandler;
+ size_t SpaceUsedLong() const override {
+ size_t size = sizeof(Derived);
+ size += KeyTypeHandler::SpaceUsedInMapEntryLong(this->key_);
+ size += ValueTypeHandler::SpaceUsedInMapEntryLong(this->value_);
+ return size;
+ }
+
+ InternalMetadata _internal_metadata_;
+
+ private:
+ friend class ::PROTOBUF_NAMESPACE_ID::Arena;
+ template <typename C, typename K, typename V,
+ WireFormatLite::FieldType k_wire_type, WireFormatLite::FieldType>
+ friend class internal::MapField;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MapEntry);
+};
+
+// Specialization for the full runtime
+template <typename Derived, typename Key, typename Value,
+ WireFormatLite::FieldType kKeyFieldType,
+ WireFormatLite::FieldType kValueFieldType>
+struct MapEntryHelper<
+ MapEntry<Derived, Key, Value, kKeyFieldType, kValueFieldType> >
+ : MapEntryHelper<
+ MapEntryLite<Derived, Key, Value, kKeyFieldType, kValueFieldType> > {
+ explicit MapEntryHelper(const MapPair<Key, Value>& map_pair)
+ : MapEntryHelper<
+ MapEntryLite<Derived, Key, Value, kKeyFieldType, kValueFieldType> >(
+ map_pair) {}
+};
+
+template <typename Derived, typename K, typename V,
+ WireFormatLite::FieldType key, WireFormatLite::FieldType value>
+struct DeconstructMapEntry<MapEntry<Derived, K, V, key, value> > {
+ typedef K Key;
+ typedef V Value;
+ static constexpr WireFormatLite::FieldType kKeyFieldType = key;
+ static constexpr WireFormatLite::FieldType kValueFieldType = value;
+};
+
+} // namespace internal
+} // namespace protobuf
+} // namespace google
+
+#include <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_MAP_ENTRY_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/map_entry_lite.h b/NorthstarDedicatedTest/include/protobuf/map_entry_lite.h
new file mode 100644
index 00000000..61b89d2c
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/map_entry_lite.h
@@ -0,0 +1,654 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef GOOGLE_PROTOBUF_MAP_ENTRY_LITE_H__
+#define GOOGLE_PROTOBUF_MAP_ENTRY_LITE_H__
+
+#include <assert.h>
+#include <string>
+
+#include <stubs/casts.h>
+#include <parse_context.h>
+#include <io/coded_stream.h>
+#include <arena.h>
+#include <arenastring.h>
+#include <generated_message_util.h>
+#include <map.h>
+#include <map_type_handler.h>
+#include <port.h>
+#include <wire_format_lite.h>
+
+#include <port_def.inc>
+#ifdef SWIG
+#error "You cannot SWIG proto headers"
+#endif
+
+namespace google {
+namespace protobuf {
+namespace internal {
+template <typename Derived, typename Key, typename Value,
+ WireFormatLite::FieldType kKeyFieldType,
+ WireFormatLite::FieldType kValueFieldType>
+class MapEntry;
+template <typename Derived, typename Key, typename Value,
+ WireFormatLite::FieldType kKeyFieldType,
+ WireFormatLite::FieldType kValueFieldType>
+class MapFieldLite;
+} // namespace internal
+} // namespace protobuf
+} // namespace google
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+// MoveHelper::Move is used to set *dest. It copies *src, or moves it (in
+// the C++11 sense), or swaps it. *src is left in a sane state for
+// subsequent destruction, but shouldn't be used for anything.
+template <bool is_enum, bool is_message, bool is_stringlike, typename T>
+struct MoveHelper { // primitives
+ static void Move(T* src, T* dest) { *dest = *src; }
+};
+
+template <bool is_message, bool is_stringlike, typename T>
+struct MoveHelper<true, is_message, is_stringlike, T> { // enums
+ static void Move(T* src, T* dest) { *dest = *src; }
+ // T is an enum here, so allow conversions to and from int.
+ static void Move(T* src, int* dest) { *dest = static_cast<int>(*src); }
+ static void Move(int* src, T* dest) { *dest = static_cast<T>(*src); }
+};
+
+template <bool is_stringlike, typename T>
+struct MoveHelper<false, true, is_stringlike, T> { // messages
+ static void Move(T* src, T* dest) { dest->Swap(src); }
+};
+
+template <typename T>
+struct MoveHelper<false, false, true, T> { // strings and similar
+ static void Move(T* src, T* dest) {
+ *dest = std::move(*src);
+ }
+};
+
+// Functions for operating on a map entry. Does not contain any representation
+// (this class is not intended to be instantiated).
+template <typename Key, typename Value, WireFormatLite::FieldType kKeyFieldType,
+ WireFormatLite::FieldType kValueFieldType>
+struct MapEntryFuncs {
+ typedef MapTypeHandler<kKeyFieldType, Key> KeyTypeHandler;
+ typedef MapTypeHandler<kValueFieldType, Value> ValueTypeHandler;
+ static const int kKeyFieldNumber = 1;
+ static const int kValueFieldNumber = 2;
+
+ static uint8_t* InternalSerialize(int field_number, const Key& key,
+ const Value& value, uint8_t* ptr,
+ io::EpsCopyOutputStream* stream) {
+ ptr = stream->EnsureSpace(ptr);
+ ptr = WireFormatLite::WriteTagToArray(
+ field_number, WireFormatLite::WIRETYPE_LENGTH_DELIMITED, ptr);
+ ptr = io::CodedOutputStream::WriteVarint32ToArray(GetCachedSize(key, value),
+ ptr);
+
+ ptr = KeyTypeHandler::Write(kKeyFieldNumber, key, ptr, stream);
+ return ValueTypeHandler::Write(kValueFieldNumber, value, ptr, stream);
+ }
+
+ static size_t ByteSizeLong(const Key& key, const Value& value) {
+ // Tags for key and value will both be one byte (field numbers 1 and 2).
+ size_t inner_length =
+ 2 + KeyTypeHandler::ByteSize(key) + ValueTypeHandler::ByteSize(value);
+ return inner_length + io::CodedOutputStream::VarintSize32(
+ static_cast<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);
+ }
+};
+
+// MapEntryImpl is used to implement parsing and serialization of map entries.
+// It uses Curious Recursive Template Pattern (CRTP) to provide the type of
+// the eventual code to the template code.
+template <typename Derived, typename Base, typename Key, typename Value,
+ WireFormatLite::FieldType kKeyFieldType,
+ WireFormatLite::FieldType kValueFieldType>
+class MapEntryImpl : public Base {
+ public:
+ typedef MapEntryFuncs<Key, Value, kKeyFieldType, kValueFieldType> Funcs;
+
+ protected:
+ // Provide utilities to parse/serialize key/value. Provide utilities to
+ // manipulate internal stored type.
+ typedef MapTypeHandler<kKeyFieldType, Key> KeyTypeHandler;
+ typedef MapTypeHandler<kValueFieldType, Value> ValueTypeHandler;
+
+ // Define internal memory layout. Strings and messages are stored as
+ // pointers, while other types are stored as values.
+ typedef typename KeyTypeHandler::TypeOnMemory KeyOnMemory;
+ typedef typename ValueTypeHandler::TypeOnMemory ValueOnMemory;
+
+ // Enum type cannot be used for MapTypeHandler::Read. Define a type
+ // which will replace Enum with int.
+ typedef typename KeyTypeHandler::MapEntryAccessorType KeyMapEntryAccessorType;
+ typedef
+ typename ValueTypeHandler::MapEntryAccessorType ValueMapEntryAccessorType;
+
+ // Constants for field number.
+ static const int kKeyFieldNumber = 1;
+ static const int kValueFieldNumber = 2;
+
+ // Constants for field tag.
+ static const uint8_t kKeyTag =
+ GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(kKeyFieldNumber, KeyTypeHandler::kWireType);
+ static const uint8_t kValueTag = GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(
+ kValueFieldNumber, ValueTypeHandler::kWireType);
+ static const size_t kTagSize = 1;
+
+ public:
+ // Work-around for a compiler bug (see repeated_field.h).
+ typedef void MapEntryHasMergeTypeTrait;
+ typedef Derived EntryType;
+ typedef Key EntryKeyType;
+ typedef Value EntryValueType;
+ static const WireFormatLite::FieldType kEntryKeyFieldType = kKeyFieldType;
+ static const WireFormatLite::FieldType kEntryValueFieldType = kValueFieldType;
+
+ constexpr MapEntryImpl()
+ : key_(KeyTypeHandler::Constinit()),
+ value_(ValueTypeHandler::Constinit()),
+ _has_bits_{} {}
+
+ explicit MapEntryImpl(Arena* arena)
+ : Base(arena),
+ key_(KeyTypeHandler::Constinit()),
+ value_(ValueTypeHandler::Constinit()),
+ _has_bits_{} {}
+
+ ~MapEntryImpl() {
+ if (Base::GetArenaForAllocation() != nullptr) return;
+ KeyTypeHandler::DeleteNoArena(key_);
+ ValueTypeHandler::DeleteNoArena(value_);
+ }
+
+ // accessors ======================================================
+
+ virtual inline const KeyMapEntryAccessorType& key() const {
+ return KeyTypeHandler::GetExternalReference(key_);
+ }
+ virtual inline const ValueMapEntryAccessorType& value() const {
+ return ValueTypeHandler::DefaultIfNotInitialized(value_);
+ }
+ inline KeyMapEntryAccessorType* mutable_key() {
+ set_has_key();
+ return KeyTypeHandler::EnsureMutable(&key_, Base::GetArenaForAllocation());
+ }
+ inline ValueMapEntryAccessorType* mutable_value() {
+ set_has_value();
+ return ValueTypeHandler::EnsureMutable(&value_,
+ Base::GetArenaForAllocation());
+ }
+
+ // implements MessageLite =========================================
+
+ // MapEntryImpl is for implementation only and this function isn't called
+ // anywhere. Just provide a fake implementation here for MessageLite.
+ 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_;
+ }
+
+ // This does what the typical MergePartialFromCodedStream() is expected to
+ // do, with the additional side-effect that if successful (i.e., if true is
+ // going to be its return value) it inserts the key-value pair into map_.
+ bool MergePartialFromCodedStream(io::CodedInputStream* input) {
+ // Look for the expected thing: a key and then a value. If it fails,
+ // invoke the enclosing class's MergePartialFromCodedStream, or return
+ // false if that would be pointless.
+ if (input->ExpectTag(kKeyTag)) {
+ if (!KeyTypeHandler::Read(input, &key_)) {
+ return false;
+ }
+ // Peek at the next byte to see if it is kValueTag. If not, bail out.
+ const void* data;
+ int size;
+ input->GetDirectBufferPointerInline(&data, &size);
+ // We could use memcmp here, but we don't bother. The tag is one byte.
+ static_assert(kTagSize == 1, "tag size must be 1");
+ if (size > 0 && *reinterpret_cast<const char*>(data) == kValueTag) {
+ typename Map::size_type map_size = map_->size();
+ value_ptr_ = &(*map_)[key_];
+ if (PROTOBUF_PREDICT_TRUE(map_size != map_->size())) {
+ // We created a new key-value pair. Fill in the value.
+ typedef
+ typename MapIf<ValueTypeHandler::kIsEnum, int*, Value*>::type T;
+ input->Skip(kTagSize); // Skip kValueTag.
+ if (!ValueTypeHandler::Read(input,
+ reinterpret_cast<T>(value_ptr_))) {
+ map_->erase(key_); // Failure! Undo insertion.
+ return false;
+ }
+ if (input->ExpectAtEnd()) return true;
+ return ReadBeyondKeyValuePair(input);
+ }
+ }
+ } else {
+ key_ = Key();
+ }
+
+ NewEntry();
+ *entry_->mutable_key() = key_;
+ const bool result = entry_->MergePartialFromCodedStream(input);
+ if (result) UseKeyAndValueFromEntry();
+ return result;
+ }
+
+ const char* _InternalParse(const char* ptr, ParseContext* ctx) {
+ if (PROTOBUF_PREDICT_TRUE(!ctx->Done(&ptr) && *ptr == kKeyTag)) {
+ ptr = KeyTypeHandler::Read(ptr + 1, ctx, &key_);
+ if (PROTOBUF_PREDICT_FALSE(!ptr || !Derived::ValidateKey(&key_))) {
+ return nullptr;
+ }
+ if (PROTOBUF_PREDICT_TRUE(!ctx->Done(&ptr) && *ptr == kValueTag)) {
+ typename Map::size_type map_size = map_->size();
+ value_ptr_ = &(*map_)[key_];
+ if (PROTOBUF_PREDICT_TRUE(map_size != map_->size())) {
+ using T =
+ typename MapIf<ValueTypeHandler::kIsEnum, int*, Value*>::type;
+ ptr = ValueTypeHandler::Read(ptr + 1, ctx,
+ reinterpret_cast<T>(value_ptr_));
+ if (PROTOBUF_PREDICT_FALSE(!ptr ||
+ !Derived::ValidateValue(value_ptr_))) {
+ map_->erase(key_); // Failure! Undo insertion.
+ return nullptr;
+ }
+ if (PROTOBUF_PREDICT_TRUE(ctx->Done(&ptr))) return ptr;
+ if (!ptr) return nullptr;
+ NewEntry();
+ ValueMover::Move(value_ptr_, entry_->mutable_value());
+ map_->erase(key_);
+ goto move_key;
+ }
+ } else {
+ if (!ptr) return nullptr;
+ }
+ NewEntry();
+ move_key:
+ KeyMover::Move(&key_, entry_->mutable_key());
+ } else {
+ if (!ptr) return nullptr;
+ NewEntry();
+ }
+ ptr = entry_->_InternalParse(ptr, ctx);
+ if (ptr) UseKeyAndValueFromEntry();
+ return ptr;
+ }
+
+ template <typename UnknownType>
+ const char* ParseWithEnumValidation(const char* ptr, ParseContext* ctx,
+ bool (*is_valid)(int),
+ 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(); }
+
+ public: // 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() {
+ MessageLite::_internal_metadata_.template Delete<std::string>();
+ }
+ void MergeFrom(const MapEntryLite& other) { MergeFromInternal(other); }
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MapEntryLite);
+};
+// The completely unprincipled and unwieldy use of template parameters in
+// the map code necessitates wrappers to make the code a little bit more
+// manageable.
+template <typename Derived>
+struct DeconstructMapEntry;
+
+template <typename T, typename K, typename V, WireFormatLite::FieldType key,
+ WireFormatLite::FieldType value>
+struct DeconstructMapEntry<MapEntryLite<T, K, V, key, value> > {
+ typedef K Key;
+ typedef V Value;
+ static const WireFormatLite::FieldType kKeyFieldType = key;
+ static const WireFormatLite::FieldType kValueFieldType = value;
+};
+
+// Helpers for deterministic serialization =============================
+
+// This struct can be used with any generic sorting algorithm. If the Key
+// type is relatively small and easy to copy then copying Keys into an
+// array of SortItems can be beneficial. Then all the data the sorting
+// algorithm needs to touch is in that one array.
+template <typename Key, typename PtrToKeyValuePair>
+struct SortItem {
+ SortItem() {}
+ explicit SortItem(PtrToKeyValuePair p) : first(p->first), second(p) {}
+
+ Key first;
+ PtrToKeyValuePair second;
+};
+
+template <typename T>
+struct CompareByFirstField {
+ bool operator()(const T& a, const T& b) const { return a.first < b.first; }
+};
+
+template <typename T>
+struct CompareByDerefFirst {
+ bool operator()(const T& a, const T& b) const { return a->first < b->first; }
+};
+
+// Helper for table driven serialization
+
+template <WireFormatLite::FieldType FieldType>
+struct FromHelper {
+ template <typename T>
+ static const T& From(const T& x) {
+ return x;
+ }
+};
+
+template <>
+struct FromHelper<WireFormatLite::TYPE_STRING> {
+ static ArenaStringPtr From(const std::string& x) {
+ ArenaStringPtr res;
+ TaggedPtr<std::string> ptr;
+ ptr.Set(const_cast<std::string*>(&x));
+ res.UnsafeSetTaggedPointer(ptr);
+ return res;
+ }
+};
+template <>
+struct FromHelper<WireFormatLite::TYPE_BYTES> {
+ static ArenaStringPtr From(const std::string& x) {
+ ArenaStringPtr res;
+ TaggedPtr<std::string> ptr;
+ ptr.Set(const_cast<std::string*>(&x));
+ res.UnsafeSetTaggedPointer(ptr);
+ return res;
+ }
+};
+template <>
+struct FromHelper<WireFormatLite::TYPE_MESSAGE> {
+ template <typename T>
+ static T* From(const T& x) {
+ return const_cast<T*>(&x);
+ }
+};
+
+template <typename MapEntryType>
+struct MapEntryHelper;
+
+template <typename T, typename Key, typename Value,
+ WireFormatLite::FieldType kKeyFieldType,
+ WireFormatLite::FieldType kValueFieldType>
+struct MapEntryHelper<
+ MapEntryLite<T, Key, Value, kKeyFieldType, kValueFieldType> > {
+ // Provide utilities to parse/serialize key/value. Provide utilities to
+ // manipulate internal stored type.
+ typedef MapTypeHandler<kKeyFieldType, Key> KeyTypeHandler;
+ typedef MapTypeHandler<kValueFieldType, Value> ValueTypeHandler;
+
+ // Define internal memory layout. Strings and messages are stored as
+ // pointers, while other types are stored as values.
+ typedef typename KeyTypeHandler::TypeOnMemory KeyOnMemory;
+ typedef typename ValueTypeHandler::TypeOnMemory ValueOnMemory;
+
+ explicit MapEntryHelper(const MapPair<Key, Value>& map_pair)
+ : _has_bits_(3),
+ _cached_size_(2 + KeyTypeHandler::GetCachedSize(map_pair.first) +
+ ValueTypeHandler::GetCachedSize(map_pair.second)),
+ key_(FromHelper<kKeyFieldType>::From(map_pair.first)),
+ value_(FromHelper<kValueFieldType>::From(map_pair.second)) {}
+
+ // Purposely not following the style guide naming. These are the names
+ // the proto compiler would generate given the map entry descriptor.
+ // The proto compiler generates the offsets in this struct as if this was
+ // a regular message. This way the table driven code barely notices it's
+ // dealing with a map field.
+ uint32_t _has_bits_; // NOLINT
+ uint32_t _cached_size_; // NOLINT
+ KeyOnMemory key_; // NOLINT
+ ValueOnMemory value_; // NOLINT
+};
+
+} // namespace internal
+} // namespace protobuf
+} // namespace google
+
+#include <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_MAP_ENTRY_LITE_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/map_field.cc b/NorthstarDedicatedTest/include/protobuf/map_field.cc
new file mode 100644
index 00000000..74a486e5
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/map_field.cc
@@ -0,0 +1,647 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <map_field.h>
+#include <map_field_inl.h>
+
+#include <vector>
+
+#include <port_def.inc>
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+MapFieldBase::~MapFieldBase() {
+ if (repeated_field_ != nullptr && arena_ == nullptr) delete repeated_field_;
+}
+
+const RepeatedPtrFieldBase& MapFieldBase::GetRepeatedField() const {
+ ConstAccess();
+ SyncRepeatedFieldWithMap();
+ return *reinterpret_cast<RepeatedPtrFieldBase*>(repeated_field_);
+}
+
+RepeatedPtrFieldBase* MapFieldBase::MutableRepeatedField() {
+ MutableAccess();
+ SyncRepeatedFieldWithMap();
+ SetRepeatedDirty();
+ return reinterpret_cast<RepeatedPtrFieldBase*>(repeated_field_);
+}
+
+void MapFieldBase::SwapState(MapFieldBase* other) {
+ // a relaxed swap of the atomic
+ auto other_state = other->state_.load(std::memory_order_relaxed);
+ auto this_state = state_.load(std::memory_order_relaxed);
+ other->state_.store(this_state, std::memory_order_relaxed);
+ state_.store(other_state, std::memory_order_relaxed);
+}
+
+void SwapRepeatedPtrToNull(RepeatedPtrField<Message>** from,
+ RepeatedPtrField<Message>** to, Arena* from_arena,
+ Arena* to_arena) {
+ GOOGLE_DCHECK(*from != nullptr);
+ GOOGLE_DCHECK(*to == nullptr);
+ *to = Arena::CreateMessage<RepeatedPtrField<Message> >(to_arena);
+ **to = std::move(**from);
+ if (from_arena == nullptr) {
+ delete *from;
+ }
+ *from = nullptr;
+}
+
+void MapFieldBase::Swap(MapFieldBase* other) {
+ if (arena_ == other->arena_) {
+ InternalSwap(other);
+ return;
+ }
+ if (repeated_field_ != nullptr || other->repeated_field_ != nullptr) {
+ if (repeated_field_ == nullptr) {
+ SwapRepeatedPtrToNull(&other->repeated_field_, &repeated_field_,
+ other->arena_, arena_);
+ } else if (other->repeated_field_ == nullptr) {
+ SwapRepeatedPtrToNull(&repeated_field_, &other->repeated_field_, arena_,
+ other->arena_);
+ } else {
+ repeated_field_->Swap(other->repeated_field_);
+ }
+ }
+ SwapState(other);
+}
+
+void MapFieldBase::UnsafeShallowSwap(MapFieldBase* other) {
+ GOOGLE_DCHECK_EQ(arena_, other->arena_);
+ InternalSwap(other);
+}
+
+void MapFieldBase::InternalSwap(MapFieldBase* other) {
+ std::swap(arena_, other->arena_);
+ std::swap(repeated_field_, other->repeated_field_);
+ SwapState(other);
+}
+
+size_t MapFieldBase::SpaceUsedExcludingSelfLong() const {
+ ConstAccess();
+ mutex_.Lock();
+ size_t size = SpaceUsedExcludingSelfNoLock();
+ mutex_.Unlock();
+ ConstAccess();
+ return size;
+}
+
+size_t MapFieldBase::SpaceUsedExcludingSelfNoLock() const {
+ if (repeated_field_ != nullptr) {
+ return repeated_field_->SpaceUsedExcludingSelfLong();
+ } else {
+ return 0;
+ }
+}
+
+bool MapFieldBase::IsMapValid() const {
+ ConstAccess();
+ // "Acquire" insures the operation after SyncRepeatedFieldWithMap won't get
+ // executed before state_ is checked.
+ int state = state_.load(std::memory_order_acquire);
+ return state != STATE_MODIFIED_REPEATED;
+}
+
+bool MapFieldBase::IsRepeatedFieldValid() const {
+ ConstAccess();
+ int state = state_.load(std::memory_order_acquire);
+ return state != STATE_MODIFIED_MAP;
+}
+
+void MapFieldBase::SetMapDirty() {
+ MutableAccess();
+ // These are called by (non-const) mutator functions. So by our API it's the
+ // callers responsibility to have these calls properly ordered.
+ state_.store(STATE_MODIFIED_MAP, std::memory_order_relaxed);
+}
+
+void MapFieldBase::SetRepeatedDirty() {
+ MutableAccess();
+ // These are called by (non-const) mutator functions. So by our API it's the
+ // callers responsibility to have these calls properly ordered.
+ state_.store(STATE_MODIFIED_REPEATED, std::memory_order_relaxed);
+}
+
+void MapFieldBase::SyncRepeatedFieldWithMap() const {
+ ConstAccess();
+ // acquire here matches with release below to ensure that we can only see a
+ // value of CLEAN after all previous changes have been synced.
+ switch (state_.load(std::memory_order_acquire)) {
+ case STATE_MODIFIED_MAP:
+ mutex_.Lock();
+ // Double check state, because another thread may have seen the same
+ // state and done the synchronization before the current thread.
+ if (state_.load(std::memory_order_relaxed) == STATE_MODIFIED_MAP) {
+ SyncRepeatedFieldWithMapNoLock();
+ state_.store(CLEAN, std::memory_order_release);
+ }
+ mutex_.Unlock();
+ ConstAccess();
+ break;
+ case CLEAN:
+ mutex_.Lock();
+ // Double check state
+ if (state_.load(std::memory_order_relaxed) == CLEAN) {
+ if (repeated_field_ == nullptr) {
+ repeated_field_ =
+ Arena::CreateMessage<RepeatedPtrField<Message> >(arena_);
+ }
+ state_.store(CLEAN, std::memory_order_release);
+ }
+ mutex_.Unlock();
+ ConstAccess();
+ break;
+ default:
+ break;
+ }
+}
+
+void MapFieldBase::SyncRepeatedFieldWithMapNoLock() const {
+ if (repeated_field_ == nullptr) {
+ repeated_field_ = Arena::CreateMessage<RepeatedPtrField<Message> >(arena_);
+ }
+}
+
+void MapFieldBase::SyncMapWithRepeatedField() const {
+ ConstAccess();
+ // acquire here matches with release below to ensure that we can only see a
+ // value of CLEAN after all previous changes have been synced.
+ if (state_.load(std::memory_order_acquire) == STATE_MODIFIED_REPEATED) {
+ mutex_.Lock();
+ // Double check state, because another thread may have seen the same state
+ // and done the synchronization before the current thread.
+ if (state_.load(std::memory_order_relaxed) == STATE_MODIFIED_REPEATED) {
+ SyncMapWithRepeatedFieldNoLock();
+ state_.store(CLEAN, std::memory_order_release);
+ }
+ mutex_.Unlock();
+ ConstAccess();
+ }
+}
+
+// ------------------DynamicMapField------------------
+DynamicMapField::DynamicMapField(const Message* default_entry)
+ : default_entry_(default_entry) {}
+
+DynamicMapField::DynamicMapField(const Message* default_entry, Arena* arena)
+ : TypeDefinedMapFieldBase<MapKey, MapValueRef>(arena),
+ map_(arena),
+ default_entry_(default_entry) {}
+
+DynamicMapField::~DynamicMapField() {
+ if (arena_ != nullptr) return;
+ // DynamicMapField owns map values. Need to delete them before clearing the
+ // map.
+ for (auto& kv : map_) {
+ kv.second.DeleteData();
+ }
+ map_.clear();
+}
+
+int DynamicMapField::size() const { return GetMap().size(); }
+
+void DynamicMapField::Clear() {
+ Map<MapKey, MapValueRef>* map = &const_cast<DynamicMapField*>(this)->map_;
+ if (MapFieldBase::arena_ == nullptr) {
+ for (Map<MapKey, MapValueRef>::iterator iter = map->begin();
+ iter != map->end(); ++iter) {
+ iter->second.DeleteData();
+ }
+ }
+
+ map->clear();
+
+ if (MapFieldBase::repeated_field_ != nullptr) {
+ MapFieldBase::repeated_field_->Clear();
+ }
+ // Data in map and repeated field are both empty, but we can't set status
+ // CLEAN which will invalidate previous reference to map.
+ MapFieldBase::SetMapDirty();
+}
+
+bool DynamicMapField::ContainsMapKey(const MapKey& map_key) const {
+ const Map<MapKey, MapValueRef>& map = GetMap();
+ Map<MapKey, MapValueRef>::const_iterator iter = map.find(map_key);
+ return iter != map.end();
+}
+
+void DynamicMapField::AllocateMapValue(MapValueRef* map_val) {
+ const FieldDescriptor* val_des = default_entry_->GetDescriptor()->map_value();
+ map_val->SetType(val_des->cpp_type());
+ // Allocate memory for the MapValueRef, and initialize to
+ // default value.
+ switch (val_des->cpp_type()) {
+#define HANDLE_TYPE(CPPTYPE, TYPE) \
+ case FieldDescriptor::CPPTYPE_##CPPTYPE: { \
+ TYPE* value = Arena::Create<TYPE>(MapFieldBase::arena_); \
+ map_val->SetValue(value); \
+ break; \
+ }
+ HANDLE_TYPE(INT32, 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 <port_undef.inc>
diff --git a/NorthstarDedicatedTest/include/protobuf/map_field.h b/NorthstarDedicatedTest/include/protobuf/map_field.h
new file mode 100644
index 00000000..17cc02f3
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/map_field.h
@@ -0,0 +1,923 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 <arena.h>
+#include <descriptor.h>
+#include <generated_message_reflection.h>
+#include <generated_message_util.h>
+#include <map_entry.h>
+#include <map_field_lite.h>
+#include <map_type_handler.h>
+#include <message.h>
+#include <stubs/mutex.h>
+#include <port.h>
+#include <repeated_field.h>
+#include <unknown_field_set.h>
+
+
+#include <port_def.inc>
+
+#ifdef SWIG
+#error "You cannot SWIG proto headers"
+#endif
+
+namespace google {
+namespace protobuf {
+class DynamicMessage;
+class MapIterator;
+
+#define TYPE_CHECK(EXPECTEDTYPE, METHOD) \
+ if (type() != EXPECTEDTYPE) { \
+ GOOGLE_LOG(FATAL) << "Protocol Buffer map usage error:\n" \
+ << METHOD << " type does not match\n" \
+ << " Expected : " \
+ << FieldDescriptor::CppTypeName(EXPECTEDTYPE) << "\n" \
+ << " Actual : " << FieldDescriptor::CppTypeName(type()); \
+ }
+
+// MapKey is an union type for representing any possible
+// map key.
+class PROTOBUF_EXPORT MapKey {
+ public:
+ MapKey() : type_() {}
+ MapKey(const MapKey& other) : type_() { CopyFrom(other); }
+
+ MapKey& operator=(const MapKey& other) {
+ CopyFrom(other);
+ return *this;
+ }
+
+ ~MapKey() {
+ if (type_ == FieldDescriptor::CPPTYPE_STRING) {
+ val_.string_value_.Destruct();
+ }
+ }
+
+ FieldDescriptor::CppType type() const {
+ if (type_ == FieldDescriptor::CppType()) {
+ GOOGLE_LOG(FATAL) << "Protocol Buffer map usage error:\n"
+ << "MapKey::type MapKey is not initialized. "
+ << "Call set methods to initialize MapKey.";
+ }
+ return type_;
+ }
+
+ void SetInt64Value(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.
+ explicit constexpr MapFieldBase(ConstantInitialized)
+ : arena_(nullptr),
+ repeated_field_(nullptr),
+ mutex_(GOOGLE_PROTOBUF_LINKER_INITIALIZED),
+ state_(STATE_MODIFIED_MAP) {}
+ explicit MapFieldBase(Arena* arena)
+ : arena_(arena), repeated_field_(nullptr), state_(STATE_MODIFIED_MAP) {}
+ virtual ~MapFieldBase();
+
+ // Returns reference to internal repeated field. Data written using
+ // Map's api prior to calling this function is guarantted to be
+ // included in repeated field.
+ const RepeatedPtrFieldBase& GetRepeatedField() const;
+
+ // Like above. Returns mutable pointer to the internal repeated field.
+ RepeatedPtrFieldBase* MutableRepeatedField();
+
+ // Pure virtual map APIs for Map Reflection.
+ virtual bool ContainsMapKey(const MapKey& map_key) const = 0;
+ virtual bool InsertOrLookupMapValue(const MapKey& map_key,
+ MapValueRef* val) = 0;
+ virtual bool LookupMapValue(const MapKey& map_key,
+ MapValueConstRef* val) const = 0;
+ bool LookupMapValue(const MapKey&, MapValueRef*) const = delete;
+
+ // Returns whether changes to the map are reflected in the repeated field.
+ bool IsRepeatedFieldValid() const;
+ // Insures operations after won't get executed before calling this.
+ bool IsMapValid() const;
+ virtual bool DeleteMapValue(const MapKey& map_key) = 0;
+ virtual bool EqualIterator(const MapIterator& a,
+ const MapIterator& b) const = 0;
+ virtual void MapBegin(MapIterator* map_iter) const = 0;
+ virtual void MapEnd(MapIterator* map_iter) const = 0;
+ virtual void MergeFrom(const MapFieldBase& other) = 0;
+ virtual void Swap(MapFieldBase* other);
+ virtual void UnsafeShallowSwap(MapFieldBase* other);
+ // Sync Map with repeated field and returns the size of map.
+ virtual int size() const = 0;
+ virtual void Clear() = 0;
+
+ // Returns the number of bytes used by the repeated field, excluding
+ // sizeof(*this)
+ size_t SpaceUsedExcludingSelfLong() const;
+
+ int SpaceUsedExcludingSelf() const {
+ return internal::ToIntSize(SpaceUsedExcludingSelfLong());
+ }
+
+ protected:
+ // Gets the size of space used by map field.
+ virtual size_t SpaceUsedExcludingSelfNoLock() const;
+
+ // Synchronizes the content in Map to RepeatedPtrField if there is any change
+ // to Map after last synchronization.
+ void SyncRepeatedFieldWithMap() const;
+ virtual void SyncRepeatedFieldWithMapNoLock() const;
+
+ // Synchronizes the content in RepeatedPtrField to Map if there is any change
+ // to RepeatedPtrField after last synchronization.
+ void SyncMapWithRepeatedField() const;
+ virtual void SyncMapWithRepeatedFieldNoLock() const {}
+
+ // Tells MapFieldBase that there is new change to Map.
+ void SetMapDirty();
+
+ // Tells MapFieldBase that there is new change to RepeatedPtrField.
+ void SetRepeatedDirty();
+
+ // Provides derived class the access to repeated field.
+ void* MutableRepeatedPtrField() const;
+
+ void InternalSwap(MapFieldBase* other);
+
+ // Support thread sanitizer (tsan) by making const / mutable races
+ // more apparent. If one thread calls MutableAccess() while another
+ // thread calls either ConstAccess() or MutableAccess(), on the same
+ // MapFieldBase-derived object, and there is no synchronization going
+ // on between them, tsan will alert.
+#if defined(__SANITIZE_THREAD__) || defined(THREAD_SANITIZER)
+ void ConstAccess() const { GOOGLE_CHECK_EQ(seq1_, seq2_); }
+ void MutableAccess() {
+ if (seq1_ & 1) {
+ seq2_ = ++seq1_;
+ } else {
+ seq1_ = ++seq2_;
+ }
+ }
+ unsigned int seq1_ = 0, seq2_ = 0;
+#else
+ void ConstAccess() const {}
+ void MutableAccess() {}
+#endif
+ enum State {
+ STATE_MODIFIED_MAP = 0, // map has newly added data that has not been
+ // synchronized to repeated field
+ STATE_MODIFIED_REPEATED = 1, // repeated field has newly added data that
+ // has not been synchronized to map
+ CLEAN = 2, // data in map and repeated field are same
+ };
+
+ Arena* arena_;
+ mutable RepeatedPtrField<Message>* repeated_field_;
+
+ mutable internal::WrappedMutex
+ mutex_; // The thread to synchronize map and repeated field
+ // needs to get lock first;
+ mutable std::atomic<State> state_;
+
+ private:
+ friend class ContendedMapCleanTest;
+ friend class GeneratedMessageReflection;
+ friend class MapFieldAccessor;
+ friend class ::PROTOBUF_NAMESPACE_ID::Reflection;
+ friend class ::PROTOBUF_NAMESPACE_ID::DynamicMessage;
+
+ // Virtual helper methods for MapIterator. MapIterator doesn't have the
+ // type helper for key and value. Call these help methods to deal with
+ // different types. Real helper methods are implemented in
+ // TypeDefinedMapFieldBase.
+ friend class ::PROTOBUF_NAMESPACE_ID::MapIterator;
+ // Allocate map<...>::iterator for MapIterator.
+ virtual void InitializeIterator(MapIterator* map_iter) const = 0;
+
+ // DeleteIterator() is called by the destructor of MapIterator only.
+ // It deletes map<...>::iterator for MapIterator.
+ virtual void DeleteIterator(MapIterator* map_iter) const = 0;
+
+ // Copy the map<...>::iterator from other_iterator to
+ // this_iterator.
+ virtual void CopyIterator(MapIterator* this_iterator,
+ const MapIterator& other_iterator) const = 0;
+
+ // IncreaseIterator() is called by operator++() of MapIterator only.
+ // It implements the ++ operator of MapIterator.
+ virtual void IncreaseIterator(MapIterator* map_iter) const = 0;
+
+ // Swaps state_ with another MapFieldBase
+ void SwapState(MapFieldBase* other);
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MapFieldBase);
+};
+
+// This class provides common Map Reflection implementations for generated
+// message and dynamic message.
+template <typename Key, typename T>
+class TypeDefinedMapFieldBase : public MapFieldBase {
+ public:
+ TypeDefinedMapFieldBase() {}
+
+ // This constructor is for constant initialized global instances.
+ // It uses a linker initialized mutex, so it is not compatible with regular
+ // runtime instances.
+ explicit constexpr TypeDefinedMapFieldBase(ConstantInitialized tag)
+ : MapFieldBase(tag) {}
+ explicit TypeDefinedMapFieldBase(Arena* arena) : MapFieldBase(arena) {}
+ ~TypeDefinedMapFieldBase() override {}
+ void MapBegin(MapIterator* map_iter) const override;
+ void MapEnd(MapIterator* map_iter) const override;
+ bool EqualIterator(const MapIterator& a, const MapIterator& b) const override;
+
+ virtual const Map<Key, T>& GetMap() const = 0;
+ virtual Map<Key, T>* MutableMap() = 0;
+
+ protected:
+ typename Map<Key, T>::const_iterator& InternalGetIterator(
+ const MapIterator* map_iter) const;
+
+ private:
+ void InitializeIterator(MapIterator* map_iter) const override;
+ void DeleteIterator(MapIterator* map_iter) const override;
+ void CopyIterator(MapIterator* this_iteratorm,
+ const MapIterator& that_iterator) const override;
+ void IncreaseIterator(MapIterator* map_iter) const override;
+
+ virtual void SetMapIteratorValue(MapIterator* map_iter) const = 0;
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(TypeDefinedMapFieldBase);
+};
+
+// This class provides access to map field using generated api. It is used for
+// internal generated message implementation only. Users should never use this
+// directly.
+template <typename Derived, typename Key, typename T,
+ WireFormatLite::FieldType kKeyFieldType,
+ WireFormatLite::FieldType kValueFieldType>
+class MapField : public TypeDefinedMapFieldBase<Key, T> {
+ // Provide utilities to parse/serialize key/value. Provide utilities to
+ // manipulate internal stored type.
+ typedef MapTypeHandler<kKeyFieldType, Key> KeyTypeHandler;
+ typedef MapTypeHandler<kValueFieldType, T> ValueTypeHandler;
+
+ // Define message type for internal repeated field.
+ typedef Derived EntryType;
+
+ // Define abbreviation for parent MapFieldLite
+ typedef MapFieldLite<Derived, Key, T, kKeyFieldType, kValueFieldType>
+ MapFieldLiteType;
+
+ // Enum needs to be handled differently from other types because it has
+ // different exposed type in Map's api and repeated field's api. For
+ // details see the comment in the implementation of
+ // SyncMapWithRepeatedFieldNoLock.
+ static constexpr bool kIsValueEnum = ValueTypeHandler::kIsEnum;
+ typedef typename MapIf<kIsValueEnum, T, const T&>::type CastValueType;
+
+ public:
+ typedef typename Derived::SuperType EntryTypeTrait;
+ typedef Map<Key, T> MapType;
+
+ MapField() {}
+
+ // This constructor is for constant initialized global instances.
+ // It uses a linker initialized mutex, so it is not compatible with regular
+ // runtime instances.
+ explicit constexpr MapField(ConstantInitialized tag)
+ : TypeDefinedMapFieldBase<Key, T>(tag), impl_() {}
+ explicit MapField(Arena* arena)
+ : TypeDefinedMapFieldBase<Key, T>(arena), impl_(arena) {}
+
+ // Implement MapFieldBase
+ bool ContainsMapKey(const MapKey& map_key) const override;
+ bool InsertOrLookupMapValue(const MapKey& map_key, MapValueRef* val) override;
+ bool LookupMapValue(const MapKey& map_key,
+ MapValueConstRef* val) const override;
+ bool LookupMapValue(const MapKey&, MapValueRef*) const = delete;
+ bool DeleteMapValue(const MapKey& map_key) override;
+
+ const Map<Key, T>& GetMap() const override {
+ MapFieldBase::SyncMapWithRepeatedField();
+ return impl_.GetMap();
+ }
+
+ Map<Key, T>* MutableMap() override {
+ MapFieldBase::SyncMapWithRepeatedField();
+ Map<Key, T>* result = impl_.MutableMap();
+ MapFieldBase::SetMapDirty();
+ return result;
+ }
+
+ int size() const override;
+ void Clear() override;
+ void MergeFrom(const MapFieldBase& other) override;
+ void Swap(MapFieldBase* other) override;
+ void UnsafeShallowSwap(MapFieldBase* other) override;
+ void InternalSwap(MapField* other);
+
+ // Used in the implementation of parsing. Caller should take the ownership iff
+ // arena_ is nullptr.
+ EntryType* NewEntry() const { return impl_.NewEntry(); }
+ // Used in the implementation of serializing enum value type. Caller should
+ // take the ownership iff arena_ is nullptr.
+ EntryType* NewEnumEntryWrapper(const Key& key, const T t) const {
+ return impl_.NewEnumEntryWrapper(key, t);
+ }
+ // Used in the implementation of serializing other value types. Caller should
+ // take the ownership iff arena_ is nullptr.
+ EntryType* NewEntryWrapper(const Key& key, const T& t) const {
+ return impl_.NewEntryWrapper(key, t);
+ }
+
+ const char* _InternalParse(const char* ptr, ParseContext* ctx) {
+ return impl_._InternalParse(ptr, ctx);
+ }
+ template <typename UnknownType>
+ const char* ParseWithEnumValidation(const char* ptr, ParseContext* ctx,
+ bool (*is_valid)(int), 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);
+ ~DynamicMapField() override;
+
+ // Implement MapFieldBase
+ bool ContainsMapKey(const MapKey& map_key) const override;
+ bool InsertOrLookupMapValue(const MapKey& map_key, MapValueRef* val) override;
+ bool LookupMapValue(const MapKey& map_key,
+ MapValueConstRef* val) const override;
+ bool LookupMapValue(const MapKey&, MapValueRef*) const = delete;
+ bool DeleteMapValue(const MapKey& map_key) override;
+ void MergeFrom(const MapFieldBase& other) override;
+ void Swap(MapFieldBase* other) override;
+ void UnsafeShallowSwap(MapFieldBase* other) override { Swap(other); }
+
+ const Map<MapKey, MapValueRef>& GetMap() const override;
+ Map<MapKey, MapValueRef>* MutableMap() override;
+
+ int size() const override;
+ void Clear() override;
+
+ private:
+ Map<MapKey, MapValueRef> map_;
+ const Message* default_entry_;
+
+ void AllocateMapValue(MapValueRef* map_val);
+
+ // Implements MapFieldBase
+ void SyncRepeatedFieldWithMapNoLock() const override;
+ void SyncMapWithRepeatedFieldNoLock() const override;
+ size_t SpaceUsedExcludingSelfNoLock() const override;
+ void SetMapIteratorValue(MapIterator* map_iter) const override;
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(DynamicMapField);
+};
+
+} // namespace internal
+
+// MapValueConstRef points to a map value. Users can NOT modify
+// the map value.
+class PROTOBUF_EXPORT MapValueConstRef {
+ public:
+ MapValueConstRef() : data_(nullptr), type_() {}
+
+ 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()->FindFieldByName("key")->cpp_type());
+ value_.SetType(field->message_type()->FindFieldByName("value")->cpp_type());
+ map_->InitializeIterator(this);
+ }
+ MapIterator(const MapIterator& other) {
+ map_ = other.map_;
+ map_->InitializeIterator(this);
+ map_->CopyIterator(this, other);
+ }
+ ~MapIterator() { map_->DeleteIterator(this); }
+ MapIterator& operator=(const MapIterator& other) {
+ map_ = other.map_;
+ map_->CopyIterator(this, other);
+ return *this;
+ }
+ friend bool operator==(const MapIterator& a, const MapIterator& b) {
+ return a.map_->EqualIterator(a, b);
+ }
+ friend bool operator!=(const MapIterator& a, const MapIterator& b) {
+ return !a.map_->EqualIterator(a, b);
+ }
+ MapIterator& operator++() {
+ map_->IncreaseIterator(this);
+ return *this;
+ }
+ MapIterator operator++(int) {
+ // iter_ is copied from Map<...>::iterator, no need to
+ // copy from its self again. Use the same implementation
+ // with operator++()
+ map_->IncreaseIterator(this);
+ return *this;
+ }
+ const MapKey& GetKey() { return key_; }
+ const MapValueRef& GetValueRef() { return value_; }
+ MapValueRef* MutableValueRef() {
+ map_->SetMapDirty();
+ return &value_;
+ }
+
+ private:
+ template <typename Key, typename T>
+ friend class internal::TypeDefinedMapFieldBase;
+ friend class internal::DynamicMapField;
+ template <typename Derived, typename Key, typename T,
+ internal::WireFormatLite::FieldType kKeyFieldType,
+ internal::WireFormatLite::FieldType kValueFieldType>
+ friend class internal::MapField;
+
+ // reinterpret_cast from heap-allocated Map<...>::iterator*. MapIterator owns
+ // the iterator. It is allocated by MapField<...>::InitializeIterator() called
+ // in constructor and deleted by MapField<...>::DeleteIterator() called in
+ // destructor.
+ void* iter_;
+ // Point to a MapField to call helper methods implemented in MapField.
+ // MapIterator does not own this object.
+ internal::MapFieldBase* map_;
+ MapKey key_;
+ MapValueRef value_;
+};
+
+} // namespace protobuf
+} // namespace google
+
+#include <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_MAP_FIELD_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/map_field_inl.h b/NorthstarDedicatedTest/include/protobuf/map_field_inl.h
new file mode 100644
index 00000000..a8f834f9
--- /dev/null
+++ b/NorthstarDedicatedTest/include/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 <stubs/casts.h>
+#include <map.h>
+#include <map_field.h>
+#include <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/NorthstarDedicatedTest/include/protobuf/map_field_lite.h b/NorthstarDedicatedTest/include/protobuf/map_field_lite.h
new file mode 100644
index 00000000..f283fe85
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/map_field_lite.h
@@ -0,0 +1,184 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef GOOGLE_PROTOBUF_MAP_FIELD_LITE_H__
+#define GOOGLE_PROTOBUF_MAP_FIELD_LITE_H__
+
+#include <type_traits>
+#include <parse_context.h>
+#include <io/coded_stream.h>
+#include <map.h>
+#include <map_entry_lite.h>
+#include <port.h>
+#include <wire_format_lite.h>
+
+#include <port_def.inc>
+
+#ifdef SWIG
+#error "You cannot SWIG proto headers"
+#endif
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+// This class provides access to map field using generated api. It is used for
+// internal generated message implementation only. Users should never use this
+// directly.
+template <typename Derived, typename Key, typename T,
+ WireFormatLite::FieldType key_wire_type,
+ WireFormatLite::FieldType value_wire_type>
+class MapFieldLite {
+ // Define message type for internal repeated field.
+ typedef Derived EntryType;
+
+ public:
+ typedef Map<Key, T> MapType;
+ typedef EntryType EntryTypeTrait;
+
+ constexpr MapFieldLite() {}
+
+ explicit MapFieldLite(Arena* arena) : map_(arena) {}
+
+ // Accessors
+ const Map<Key, T>& GetMap() const { return map_; }
+ Map<Key, T>* MutableMap() { return &map_; }
+
+ // Convenient methods for generated message implementation.
+ int size() const { return static_cast<int>(map_.size()); }
+ void Clear() { return map_.clear(); }
+ void MergeFrom(const MapFieldLite& other) {
+ for (typename Map<Key, T>::const_iterator it = other.map_.begin();
+ it != other.map_.end(); ++it) {
+ map_[it->first] = it->second;
+ }
+ }
+ void Swap(MapFieldLite* other) { map_.swap(other->map_); }
+ void InternalSwap(MapFieldLite* other) { map_.InternalSwap(other->map_); }
+
+ // Used in the implementation of parsing. Caller should take the ownership iff
+ // arena_ is nullptr.
+ EntryType* NewEntry() const {
+ return Arena::CreateMessage<EntryType>(map_.arena());
+ }
+ // Used in the implementation of serializing enum value type. Caller should
+ // take the ownership iff arena_ is nullptr.
+ EntryType* NewEnumEntryWrapper(const Key& key, const T t) const {
+ return EntryType::EnumWrap(key, t, map_.arena_);
+ }
+ // Used in the implementation of serializing other value types. Caller should
+ // take the ownership iff arena_ is nullptr.
+ EntryType* NewEntryWrapper(const Key& key, const T& t) const {
+ return EntryType::Wrap(key, t, map_.arena_);
+ }
+
+ const char* _InternalParse(const char* ptr, ParseContext* ctx) {
+ typename Derived::template Parser<MapFieldLite, Map<Key, T>> parser(this);
+ return parser._InternalParse(ptr, ctx);
+ }
+
+ template <typename UnknownType>
+ const char* ParseWithEnumValidation(const char* ptr, ParseContext* ctx,
+ bool (*is_valid)(int), 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<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;
+};
+
+} // namespace internal
+} // namespace protobuf
+} // namespace google
+
+#include <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_MAP_FIELD_LITE_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/map_field_test.cc b/NorthstarDedicatedTest/include/protobuf/map_field_test.cc
new file mode 100644
index 00000000..6db44a2b
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/map_field_test.cc
@@ -0,0 +1,527 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 <map>
+#include <memory>
+#include <unordered_map>
+
+#include <stubs/logging.h>
+#include <stubs/common.h>
+#include <arena_test_util.h>
+#include <map_test_util.h>
+#include <map_unittest.pb.h>
+#include <unittest.pb.h>
+#include <arena.h>
+#include <map.h>
+#include <map_field_inl.h>
+#include <message.h>
+#include <repeated_field.h>
+#include <gtest/gtest.h>
+
+// Must be included last.
+#include <port_def.inc>
+
+namespace google {
+namespace protobuf {
+
+namespace internal {
+
+using unittest::TestAllTypes;
+
+class MapFieldBaseStub : public MapFieldBase {
+ public:
+ typedef void InternalArenaConstructable_;
+ typedef void DestructorSkippable_;
+ MapFieldBaseStub() {}
+ explicit MapFieldBaseStub(Arena* arena) : MapFieldBase(arena) {}
+ // Get underlined repeated field without synchronizing map.
+ RepeatedPtrField<Message>* InternalRepeatedField() { return repeated_field_; }
+ bool IsMapClean() {
+ return state_.load(std::memory_order_relaxed) != STATE_MODIFIED_MAP;
+ }
+ bool IsRepeatedClean() {
+ return state_.load(std::memory_order_relaxed) != STATE_MODIFIED_REPEATED;
+ }
+ void SetMapDirty() {
+ state_.store(STATE_MODIFIED_MAP, std::memory_order_relaxed);
+ }
+ void SetRepeatedDirty() {
+ state_.store(STATE_MODIFIED_REPEATED, std::memory_order_relaxed);
+ }
+ bool ContainsMapKey(const MapKey& map_key) const override { return false; }
+ bool InsertOrLookupMapValue(const MapKey& map_key,
+ MapValueRef* val) override {
+ return false;
+ }
+ bool LookupMapValue(const MapKey& map_key,
+ MapValueConstRef* val) const override {
+ return false;
+ }
+ bool DeleteMapValue(const MapKey& map_key) override { return false; }
+ bool EqualIterator(const MapIterator& a,
+ const MapIterator& b) const override {
+ return false;
+ }
+ int size() const override { return 0; }
+ void Clear() override {}
+ void MapBegin(MapIterator* map_iter) const override {}
+ void MapEnd(MapIterator* map_iter) const override {}
+ void MergeFrom(const MapFieldBase& other) override {}
+ void Swap(MapFieldBase* other) override {}
+ void InitializeIterator(MapIterator* map_iter) const override {}
+ void DeleteIterator(MapIterator* map_iter) const override {}
+ void CopyIterator(MapIterator* this_iterator,
+ const MapIterator& other_iterator) const override {}
+ void IncreaseIterator(MapIterator* map_iter) const override {}
+
+ Arena* GetArenaForInternalRepeatedField() {
+ auto* repeated_field = MutableRepeatedField();
+ return repeated_field->GetArena();
+ }
+};
+
+class MapFieldBasePrimitiveTest : public testing::TestWithParam<bool> {
+ protected:
+ typedef unittest::TestMap_MapInt32Int32Entry_DoNotUse EntryType;
+ typedef MapField<EntryType, int32, int32, WireFormatLite::TYPE_INT32,
+ WireFormatLite::TYPE_INT32>
+ MapFieldType;
+
+ MapFieldBasePrimitiveTest()
+ : arena_(GetParam() ? new Arena() : nullptr),
+ map_field_(arena_.get()),
+ map_field_base_(map_field_.get()) {
+ // Get descriptors
+ map_descriptor_ = unittest::TestMap::descriptor()
+ ->FindFieldByName("map_int32_int32")
+ ->message_type();
+ key_descriptor_ = map_descriptor_->map_key();
+ value_descriptor_ = map_descriptor_->map_value();
+
+ // Build map field
+ map_field_base_ = map_field_.get();
+ map_ = map_field_->MutableMap();
+ initial_value_map_[0] = 100;
+ initial_value_map_[1] = 101;
+ map_->insert(initial_value_map_.begin(), initial_value_map_.end());
+ EXPECT_EQ(2, map_->size());
+ }
+
+ std::unique_ptr<Arena> arena_;
+ ArenaHolder<MapFieldType> map_field_;
+ MapFieldBase* map_field_base_;
+ Map<int32, int32>* map_;
+ const Descriptor* map_descriptor_;
+ const FieldDescriptor* key_descriptor_;
+ const FieldDescriptor* value_descriptor_;
+ std::map<int32, int32> initial_value_map_; // copy of initial values inserted
+};
+
+INSTANTIATE_TEST_SUITE_P(MapFieldBasePrimitiveTestInstance,
+ MapFieldBasePrimitiveTest,
+ testing::Values(true, false));
+
+TEST_P(MapFieldBasePrimitiveTest, SpaceUsedExcludingSelf) {
+ EXPECT_LT(0, map_field_base_->SpaceUsedExcludingSelf());
+}
+
+TEST_P(MapFieldBasePrimitiveTest, GetRepeatedField) {
+ const RepeatedPtrField<Message>& repeated =
+ reinterpret_cast<const RepeatedPtrField<Message>&>(
+ map_field_base_->GetRepeatedField());
+ EXPECT_EQ(2, repeated.size());
+ for (int i = 0; i < repeated.size(); i++) {
+ const Message& message = repeated.Get(i);
+ int key = message.GetReflection()->GetInt32(message, key_descriptor_);
+ int value = message.GetReflection()->GetInt32(message, value_descriptor_);
+ EXPECT_EQ(value, initial_value_map_[key]);
+ }
+}
+
+TEST_P(MapFieldBasePrimitiveTest, MutableRepeatedField) {
+ RepeatedPtrField<Message>* repeated =
+ reinterpret_cast<RepeatedPtrField<Message>*>(
+ map_field_base_->MutableRepeatedField());
+ EXPECT_EQ(2, repeated->size());
+ for (int i = 0; i < repeated->size(); i++) {
+ const Message& message = repeated->Get(i);
+ int key = message.GetReflection()->GetInt32(message, key_descriptor_);
+ int value = message.GetReflection()->GetInt32(message, value_descriptor_);
+ EXPECT_EQ(value, initial_value_map_[key]);
+ }
+}
+
+TEST_P(MapFieldBasePrimitiveTest, Arena) {
+ // Allocate a large initial block to avoid mallocs during hooked test.
+ std::vector<char> arena_block(128 * 1024);
+ ArenaOptions options;
+ options.initial_block = &arena_block[0];
+ options.initial_block_size = arena_block.size();
+ Arena arena(options);
+
+ {
+ // TODO(liujisi): Re-write the test to ensure the memory for the map and
+ // repeated fields are allocated from arenas.
+ // NoHeapChecker no_heap;
+
+ MapFieldType* map_field = Arena::CreateMessage<MapFieldType>(&arena);
+
+ // Set content in map
+ (*map_field->MutableMap())[100] = 101;
+
+ // Trigger conversion to repeated field.
+ map_field->GetRepeatedField();
+ }
+
+ {
+ // TODO(liujisi): Re-write the test to ensure the memory for the map and
+ // repeated fields are allocated from arenas.
+ // NoHeapChecker no_heap;
+
+ MapFieldBaseStub* map_field =
+ Arena::CreateMessage<MapFieldBaseStub>(&arena);
+
+ // Trigger conversion to repeated field.
+ EXPECT_TRUE(map_field->MutableRepeatedField() != nullptr);
+
+ EXPECT_EQ(map_field->GetArenaForInternalRepeatedField(), &arena);
+ }
+}
+
+TEST_P(MapFieldBasePrimitiveTest, EnforceNoArena) {
+ std::unique_ptr<MapFieldBaseStub> map_field(
+ Arena::CreateMessage<MapFieldBaseStub>(nullptr));
+ EXPECT_EQ(map_field->GetArenaForInternalRepeatedField(), nullptr);
+}
+
+namespace {
+enum State { CLEAN, MAP_DIRTY, REPEATED_DIRTY };
+} // anonymous namespace
+
+class MapFieldStateTest
+ : public testing::TestWithParam<std::tuple<State, bool>> {
+ protected:
+ typedef unittest::TestMap_MapInt32Int32Entry_DoNotUse EntryType;
+ typedef MapField<EntryType, int32, int32, WireFormatLite::TYPE_INT32,
+ WireFormatLite::TYPE_INT32>
+ MapFieldType;
+ MapFieldStateTest()
+ : arena_(std::get<1>(GetParam()) ? new Arena() : nullptr),
+ map_field_(arena_.get()),
+ map_field_base_(map_field_.get()),
+ state_(std::get<0>(GetParam())) {
+ // Build map field
+ Expect(map_field_.get(), MAP_DIRTY, 0, 0, true);
+ switch (state_) {
+ case CLEAN:
+ AddOneStillClean(map_field_.get());
+ break;
+ case MAP_DIRTY:
+ MakeMapDirty(map_field_.get());
+ break;
+ case REPEATED_DIRTY:
+ MakeRepeatedDirty(map_field_.get());
+ break;
+ default:
+ break;
+ }
+ }
+
+ void AddOneStillClean(MapFieldType* map_field) {
+ MapFieldBase* map_field_base = map_field;
+ Map<int32, int32>* map = map_field->MutableMap();
+ (*map)[0] = 0;
+ map_field_base->GetRepeatedField();
+ Expect(map_field, CLEAN, 1, 1, false);
+ }
+
+ void MakeMapDirty(MapFieldType* map_field) {
+ Map<int32, int32>* map = map_field->MutableMap();
+ (*map)[0] = 0;
+ Expect(map_field, MAP_DIRTY, 1, 0, true);
+ }
+
+ void MakeRepeatedDirty(MapFieldType* map_field) {
+ MakeMapDirty(map_field);
+ MapFieldBase* map_field_base = map_field;
+ map_field_base->MutableRepeatedField();
+ // We use MutableMap on impl_ because we don't want to disturb the syncing
+ Map<int32, int32>* map = map_field->impl_.MutableMap();
+ map->clear();
+
+ Expect(map_field, REPEATED_DIRTY, 0, 1, false);
+ }
+
+ void Expect(MapFieldType* map_field, State state, int map_size,
+ int repeated_size, bool is_repeated_null) {
+ MapFieldBase* map_field_base = map_field;
+ MapFieldBaseStub* stub =
+ reinterpret_cast<MapFieldBaseStub*>(map_field_base);
+
+ // We use MutableMap on impl_ because we don't want to disturb the syncing
+ Map<int32, int32>* map = map_field->impl_.MutableMap();
+ RepeatedPtrField<Message>* repeated_field = stub->InternalRepeatedField();
+
+ switch (state) {
+ case MAP_DIRTY:
+ EXPECT_FALSE(stub->IsMapClean());
+ EXPECT_TRUE(stub->IsRepeatedClean());
+ break;
+ case REPEATED_DIRTY:
+ EXPECT_TRUE(stub->IsMapClean());
+ EXPECT_FALSE(stub->IsRepeatedClean());
+ break;
+ case CLEAN:
+ EXPECT_TRUE(stub->IsMapClean());
+ EXPECT_TRUE(stub->IsRepeatedClean());
+ break;
+ default:
+ FAIL();
+ }
+
+ EXPECT_EQ(map_size, map->size());
+ if (is_repeated_null) {
+ EXPECT_TRUE(repeated_field == nullptr);
+ } else {
+ if (repeated_field == nullptr) {
+ EXPECT_EQ(repeated_size, 0);
+ } else {
+ EXPECT_EQ(repeated_size, repeated_field->size());
+ }
+ }
+ }
+
+ std::unique_ptr<Arena> arena_;
+ ArenaHolder<MapFieldType> map_field_;
+ MapFieldBase* map_field_base_;
+ State state_;
+};
+
+INSTANTIATE_TEST_SUITE_P(MapFieldStateTestInstance, MapFieldStateTest,
+ testing::Combine(testing::Values(CLEAN, MAP_DIRTY,
+ REPEATED_DIRTY),
+ testing::Values(true, false)));
+
+TEST_P(MapFieldStateTest, GetMap) {
+ map_field_->GetMap();
+ if (state_ != MAP_DIRTY) {
+ Expect(map_field_.get(), CLEAN, 1, 1, false);
+ } else {
+ Expect(map_field_.get(), MAP_DIRTY, 1, 0, true);
+ }
+}
+
+TEST_P(MapFieldStateTest, MutableMap) {
+ map_field_->MutableMap();
+ if (state_ != MAP_DIRTY) {
+ Expect(map_field_.get(), MAP_DIRTY, 1, 1, false);
+ } else {
+ Expect(map_field_.get(), MAP_DIRTY, 1, 0, true);
+ }
+}
+
+TEST_P(MapFieldStateTest, MergeFromClean) {
+ ArenaHolder<MapFieldType> other(arena_.get());
+ AddOneStillClean(other.get());
+
+ map_field_->MergeFrom(*other);
+
+ if (state_ != MAP_DIRTY) {
+ Expect(map_field_.get(), MAP_DIRTY, 1, 1, false);
+ } else {
+ Expect(map_field_.get(), MAP_DIRTY, 1, 0, true);
+ }
+
+ Expect(other.get(), CLEAN, 1, 1, false);
+}
+
+TEST_P(MapFieldStateTest, MergeFromMapDirty) {
+ ArenaHolder<MapFieldType> other(arena_.get());
+ MakeMapDirty(other.get());
+
+ map_field_->MergeFrom(*other);
+
+ if (state_ != MAP_DIRTY) {
+ Expect(map_field_.get(), MAP_DIRTY, 1, 1, false);
+ } else {
+ Expect(map_field_.get(), MAP_DIRTY, 1, 0, true);
+ }
+
+ Expect(other.get(), MAP_DIRTY, 1, 0, true);
+}
+
+TEST_P(MapFieldStateTest, MergeFromRepeatedDirty) {
+ ArenaHolder<MapFieldType> other(arena_.get());
+ MakeRepeatedDirty(other.get());
+
+ map_field_->MergeFrom(*other);
+
+ if (state_ != MAP_DIRTY) {
+ Expect(map_field_.get(), MAP_DIRTY, 1, 1, false);
+ } else {
+ Expect(map_field_.get(), MAP_DIRTY, 1, 0, true);
+ }
+
+ Expect(other.get(), CLEAN, 1, 1, false);
+}
+
+TEST_P(MapFieldStateTest, SwapClean) {
+ ArenaHolder<MapFieldType> other(arena_.get());
+ AddOneStillClean(other.get());
+
+ map_field_->Swap(other.get());
+
+ Expect(map_field_.get(), CLEAN, 1, 1, false);
+
+ switch (state_) {
+ case CLEAN:
+ Expect(other.get(), CLEAN, 1, 1, false);
+ break;
+ case MAP_DIRTY:
+ Expect(other.get(), MAP_DIRTY, 1, 0, true);
+ break;
+ case REPEATED_DIRTY:
+ Expect(other.get(), REPEATED_DIRTY, 0, 1, false);
+ break;
+ default:
+ break;
+ }
+}
+
+TEST_P(MapFieldStateTest, SwapMapDirty) {
+ ArenaHolder<MapFieldType> other(arena_.get());
+ MakeMapDirty(other.get());
+
+ map_field_->Swap(other.get());
+
+ Expect(map_field_.get(), MAP_DIRTY, 1, 0, true);
+
+ switch (state_) {
+ case CLEAN:
+ Expect(other.get(), CLEAN, 1, 1, false);
+ break;
+ case MAP_DIRTY:
+ Expect(other.get(), MAP_DIRTY, 1, 0, true);
+ break;
+ case REPEATED_DIRTY:
+ Expect(other.get(), REPEATED_DIRTY, 0, 1, false);
+ break;
+ default:
+ break;
+ }
+}
+
+TEST_P(MapFieldStateTest, SwapRepeatedDirty) {
+ ArenaHolder<MapFieldType> other(arena_.get());
+ MakeRepeatedDirty(other.get());
+
+ map_field_->Swap(other.get());
+
+ Expect(map_field_.get(), REPEATED_DIRTY, 0, 1, false);
+
+ switch (state_) {
+ case CLEAN:
+ Expect(other.get(), CLEAN, 1, 1, false);
+ break;
+ case MAP_DIRTY:
+ Expect(other.get(), MAP_DIRTY, 1, 0, true);
+ break;
+ case REPEATED_DIRTY:
+ Expect(other.get(), REPEATED_DIRTY, 0, 1, false);
+ break;
+ default:
+ break;
+ }
+}
+
+TEST_P(MapFieldStateTest, Clear) {
+ map_field_->Clear();
+
+ Expect(map_field_.get(), MAP_DIRTY, 0, 0, false);
+}
+
+TEST_P(MapFieldStateTest, SpaceUsedExcludingSelf) {
+ map_field_base_->SpaceUsedExcludingSelf();
+
+ switch (state_) {
+ case CLEAN:
+ Expect(map_field_.get(), CLEAN, 1, 1, false);
+ break;
+ case MAP_DIRTY:
+ Expect(map_field_.get(), MAP_DIRTY, 1, 0, true);
+ break;
+ case REPEATED_DIRTY:
+ Expect(map_field_.get(), REPEATED_DIRTY, 0, 1, false);
+ break;
+ default:
+ break;
+ }
+}
+
+TEST_P(MapFieldStateTest, GetMapField) {
+ map_field_base_->GetRepeatedField();
+
+ if (state_ != REPEATED_DIRTY) {
+ Expect(map_field_.get(), CLEAN, 1, 1, false);
+ } else {
+ Expect(map_field_.get(), REPEATED_DIRTY, 0, 1, false);
+ }
+}
+
+TEST_P(MapFieldStateTest, MutableMapField) {
+ map_field_base_->MutableRepeatedField();
+
+ if (state_ != REPEATED_DIRTY) {
+ Expect(map_field_.get(), REPEATED_DIRTY, 1, 1, false);
+ } else {
+ Expect(map_field_.get(), REPEATED_DIRTY, 0, 1, false);
+ }
+}
+
+class MyMapField
+ : public MapField<unittest::TestMap_MapInt32Int32Entry_DoNotUse, int32,
+ int32, internal::WireFormatLite::TYPE_INT32,
+ internal::WireFormatLite::TYPE_INT32> {
+ public:
+ constexpr MyMapField()
+ : MyMapField::MapField(internal::ConstantInitialized{}) {}
+};
+
+TEST(MapFieldTest, ConstInit) {
+ // This tests that `MapField` and all its base classes can be constant
+ // initialized.
+ PROTOBUF_CONSTINIT static MyMapField field; // NOLINT
+ EXPECT_EQ(field.size(), 0);
+}
+
+
+} // namespace internal
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/map_lite_test_util.cc b/NorthstarDedicatedTest/include/protobuf/map_lite_test_util.cc
new file mode 100644
index 00000000..c252091b
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/map_lite_test_util.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 <map_lite_test_util.h>
+#include <map_lite_unittest.pb.h>
+#include <map_test_util_impl.h>
+
+namespace google {
+namespace protobuf {
+
+void MapLiteTestUtil::SetMapFields(unittest::TestMapLite* message) {
+ MapTestUtilImpl::SetMapFields<unittest::MapEnumLite,
+ unittest::MAP_ENUM_BAR_LITE,
+ unittest::MAP_ENUM_BAZ_LITE>(message);
+}
+
+void MapLiteTestUtil::SetArenaMapFields(unittest::TestArenaMapLite* message) {
+ MapTestUtilImpl::SetArenaMapFields<unittest::MapEnumLite,
+ unittest::MAP_ENUM_BAR_LITE,
+ unittest::MAP_ENUM_BAZ_LITE>(message);
+}
+
+void MapLiteTestUtil::SetMapFieldsInitialized(unittest::TestMapLite* message) {
+ MapTestUtilImpl::SetMapFieldsInitialized(message);
+}
+
+void MapLiteTestUtil::ModifyMapFields(unittest::TestMapLite* message) {
+ MapTestUtilImpl::ModifyMapFields<unittest::MapEnumLite,
+ unittest::MAP_ENUM_FOO_LITE>(message);
+}
+
+void MapLiteTestUtil::ExpectClear(const unittest::TestMapLite& message) {
+ MapTestUtilImpl::ExpectClear(message);
+}
+
+void MapLiteTestUtil::ExpectMapFieldsSet(const unittest::TestMapLite& message) {
+ MapTestUtilImpl::ExpectMapFieldsSet<unittest::MapEnumLite,
+ unittest::MAP_ENUM_BAR_LITE,
+ unittest::MAP_ENUM_BAZ_LITE>(message);
+}
+
+void MapLiteTestUtil::ExpectArenaMapFieldsSet(
+ const unittest::TestArenaMapLite& message) {
+ MapTestUtilImpl::ExpectArenaMapFieldsSet<unittest::MapEnumLite,
+ unittest::MAP_ENUM_BAR_LITE,
+ unittest::MAP_ENUM_BAZ_LITE>(
+ message);
+}
+
+void MapLiteTestUtil::ExpectMapFieldsSetInitialized(
+ const unittest::TestMapLite& message) {
+ MapTestUtilImpl::ExpectMapFieldsSetInitialized<unittest::MapEnumLite,
+ unittest::MAP_ENUM_FOO_LITE>(
+ message);
+}
+
+void MapLiteTestUtil::ExpectMapFieldsModified(
+ const unittest::TestMapLite& message) {
+ MapTestUtilImpl::ExpectMapFieldsModified<unittest::MapEnumLite,
+ unittest::MAP_ENUM_BAR_LITE,
+ unittest::MAP_ENUM_FOO_LITE>(
+ message);
+}
+
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/map_lite_test_util.h b/NorthstarDedicatedTest/include/protobuf/map_lite_test_util.h
new file mode 100644
index 00000000..21e35200
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/map_lite_test_util.h
@@ -0,0 +1,80 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef GOOGLE_PROTOBUF_MAP_LITE_TEST_UTIL_H__
+#define GOOGLE_PROTOBUF_MAP_LITE_TEST_UTIL_H__
+
+#include <map_lite_unittest.pb.h>
+
+namespace google {
+namespace protobuf {
+
+class MapLiteTestUtil {
+ public:
+ // Set every field in the TestMapLite message to a unique value.
+ static void SetMapFields(protobuf_unittest::TestMapLite* message);
+
+ // Set every field in the TestArenaMapLite message to a unique value.
+ static void SetArenaMapFields(protobuf_unittest::TestArenaMapLite* message);
+
+ // Set every field in the message to a default value.
+ static void SetMapFieldsInitialized(protobuf_unittest::TestMapLite* message);
+
+ // Modify all the map fields of the message (which should already have been
+ // initialized with SetMapFields()).
+ static void ModifyMapFields(protobuf_unittest::TestMapLite* message);
+
+ // Check that all fields have the values that they should have after
+ // SetMapFields() is called.
+ static void ExpectMapFieldsSet(const protobuf_unittest::TestMapLite& message);
+
+ // Check that all fields have the values that they should have after
+ // SetMapFields() is called for TestArenaMapLite.
+ static void ExpectArenaMapFieldsSet(
+ const protobuf_unittest::TestArenaMapLite& message);
+
+ // Check that all fields have the values that they should have after
+ // SetMapFieldsInitialized() is called.
+ static void ExpectMapFieldsSetInitialized(
+ const protobuf_unittest::TestMapLite& message);
+
+ // Expect that the message is modified as would be expected from
+ // ModifyMapFields().
+ static void ExpectMapFieldsModified(
+ const protobuf_unittest::TestMapLite& message);
+
+ // Check that all fields are empty.
+ static void ExpectClear(const protobuf_unittest::TestMapLite& message);
+};
+
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_MAP_LITE_TEST_UTIL_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/map_lite_unittest.proto b/NorthstarDedicatedTest/include/protobuf/map_lite_unittest.proto
new file mode 100644
index 00000000..cc00deec
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/map_lite_unittest.proto
@@ -0,0 +1,127 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+syntax = "proto2";
+
+package protobuf_unittest;
+
+import "google/protobuf/unittest_lite.proto";
+
+option cc_enable_arenas = true;
+option optimize_for = LITE_RUNTIME;
+
+message TestMapLite {
+ map<int32, int32> map_int32_int32 = 1;
+ map<int64, int64> map_int64_int64 = 2;
+ map<uint32, uint32> map_uint32_uint32 = 3;
+ map<uint64, uint64> map_uint64_uint64 = 4;
+ map<sint32, sint32> map_sint32_sint32 = 5;
+ map<sint64, sint64> map_sint64_sint64 = 6;
+ map<fixed32, fixed32> map_fixed32_fixed32 = 7;
+ map<fixed64, fixed64> map_fixed64_fixed64 = 8;
+ map<sfixed32, sfixed32> map_sfixed32_sfixed32 = 9;
+ map<sfixed64, sfixed64> map_sfixed64_sfixed64 = 10;
+ map<int32, float> map_int32_float = 11;
+ map<int32, double> map_int32_double = 12;
+ map<bool, bool> map_bool_bool = 13;
+ map<string, string> map_string_string = 14;
+ map<int32, bytes> map_int32_bytes = 15;
+ map<int32, MapEnumLite> map_int32_enum = 16;
+ map<int32, ForeignMessageLite> map_int32_foreign_message = 17;
+ map<int32, int32> teboring = 18;
+}
+
+message TestArenaMapLite {
+ map<int32, int32> map_int32_int32 = 1;
+ map<int64, int64> map_int64_int64 = 2;
+ map<uint32, uint32> map_uint32_uint32 = 3;
+ map<uint64, uint64> map_uint64_uint64 = 4;
+ map<sint32, sint32> map_sint32_sint32 = 5;
+ map<sint64, sint64> map_sint64_sint64 = 6;
+ map<fixed32, fixed32> map_fixed32_fixed32 = 7;
+ map<fixed64, fixed64> map_fixed64_fixed64 = 8;
+ map<sfixed32, sfixed32> map_sfixed32_sfixed32 = 9;
+ map<sfixed64, sfixed64> map_sfixed64_sfixed64 = 10;
+ map<int32, float> map_int32_float = 11;
+ map<int32, double> map_int32_double = 12;
+ map<bool, bool> map_bool_bool = 13;
+ map<string, string> map_string_string = 14;
+ map<int32, bytes> map_int32_bytes = 15;
+ map<int32, MapEnumLite> map_int32_enum = 16;
+ map<int32, ForeignMessageArenaLite> map_int32_foreign_message = 17;
+}
+
+// Test embedded message with required fields
+message TestRequiredMessageMapLite {
+ map<int32, TestRequiredLite> map_field = 1;
+}
+
+message TestEnumMapLite {
+ map<int32, Proto2MapEnumLite> known_map_field = 101;
+ map<int32, Proto2MapEnumLite> unknown_map_field = 102;
+}
+
+message TestEnumMapPlusExtraLite {
+ map<int32, Proto2MapEnumPlusExtraLite> known_map_field = 101;
+ map<int32, Proto2MapEnumPlusExtraLite> unknown_map_field = 102;
+}
+
+message TestMessageMapLite {
+ map<int32, TestAllTypesLite> map_int32_message = 1;
+}
+
+enum Proto2MapEnumLite {
+ PROTO2_MAP_ENUM_FOO_LITE = 0;
+ PROTO2_MAP_ENUM_BAR_LITE = 1;
+ PROTO2_MAP_ENUM_BAZ_LITE = 2;
+}
+
+enum Proto2MapEnumPlusExtraLite {
+ E_PROTO2_MAP_ENUM_FOO_LITE = 0;
+ E_PROTO2_MAP_ENUM_BAR_LITE = 1;
+ E_PROTO2_MAP_ENUM_BAZ_LITE = 2;
+ E_PROTO2_MAP_ENUM_EXTRA_LITE = 3;
+}
+
+enum MapEnumLite {
+ MAP_ENUM_FOO_LITE = 0;
+ MAP_ENUM_BAR_LITE = 1;
+ MAP_ENUM_BAZ_LITE = 2;
+}
+
+message TestRequiredLite {
+ required int32 a = 1;
+ required int32 b = 2;
+ required int32 c = 3;
+}
+
+message ForeignMessageArenaLite {
+ optional int32 c = 1;
+}
diff --git a/NorthstarDedicatedTest/include/protobuf/map_proto2_unittest.proto b/NorthstarDedicatedTest/include/protobuf/map_proto2_unittest.proto
new file mode 100644
index 00000000..20d58f90
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/map_proto2_unittest.proto
@@ -0,0 +1,91 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+syntax = "proto2";
+option cc_enable_arenas = true;
+
+import "google/protobuf/unittest_import.proto";
+
+// We don't put this in a package within proto2 because we need to make sure
+// that the generated code doesn't depend on being in the proto2 namespace.
+// In map_test_util.h we do "using namespace unittest = protobuf_unittest".
+package protobuf_unittest;
+
+enum Proto2MapEnum {
+ PROTO2_MAP_ENUM_FOO = 0;
+ PROTO2_MAP_ENUM_BAR = 1;
+ PROTO2_MAP_ENUM_BAZ = 2;
+}
+
+enum Proto2MapEnumPlusExtra {
+ E_PROTO2_MAP_ENUM_FOO = 0;
+ E_PROTO2_MAP_ENUM_BAR = 1;
+ E_PROTO2_MAP_ENUM_BAZ = 2;
+ E_PROTO2_MAP_ENUM_EXTRA = 3;
+}
+
+message TestEnumMap {
+ map<int32, Proto2MapEnum> known_map_field = 101;
+ map<int32, Proto2MapEnum> unknown_map_field = 102;
+}
+
+message TestEnumMapPlusExtra {
+ map<int32, Proto2MapEnumPlusExtra> known_map_field = 101;
+ map<int32, Proto2MapEnumPlusExtra> unknown_map_field = 102;
+}
+
+message TestImportEnumMap {
+ map<int32, protobuf_unittest_import.ImportEnumForMap> import_enum_amp = 1;
+}
+
+message TestIntIntMap {
+ map<int32, int32> m = 1;
+}
+
+// Test all key types: string, plus the non-floating-point scalars.
+message TestMaps {
+ map<int32, TestIntIntMap> m_int32 = 1;
+ map<int64, TestIntIntMap> m_int64 = 2;
+ map<uint32, TestIntIntMap> m_uint32 = 3;
+ map<uint64, TestIntIntMap> m_uint64 = 4;
+ map<sint32, TestIntIntMap> m_sint32 = 5;
+ map<sint64, TestIntIntMap> m_sint64 = 6;
+ map<fixed32, TestIntIntMap> m_fixed32 = 7;
+ map<fixed64, TestIntIntMap> m_fixed64 = 8;
+ map<sfixed32, TestIntIntMap> m_sfixed32 = 9;
+ map<sfixed64, TestIntIntMap> m_sfixed64 = 10;
+ map<bool, TestIntIntMap> m_bool = 11;
+ map<string, TestIntIntMap> m_string = 12;
+}
+
+// Test maps in submessages.
+message TestSubmessageMaps {
+ optional TestMaps m = 1;
+}
diff --git a/NorthstarDedicatedTest/include/protobuf/map_test.cc b/NorthstarDedicatedTest/include/protobuf/map_test.cc
new file mode 100644
index 00000000..7925b67b
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/map_test.cc
@@ -0,0 +1,63 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 <map_proto2_unittest.pb.h>
+#include <map_unittest.pb.h>
+#include <reflection_tester.h>
+#include <test_util2.h>
+
+
+#define BRIDGE_UNITTEST ::google::protobuf::bridge_unittest
+#define UNITTEST ::protobuf_unittest
+#define UNITTEST_IMPORT ::protobuf_unittest_import
+#define UNITTEST_PACKAGE_NAME "protobuf_unittest"
+
+// Must include after defining UNITTEST, etc.
+// clang-format off
+#include <test_util.inc>
+#include <map_test_util.inc>
+#include <map_test.inc>
+// clang-format on
+
+// Must be included last.
+#include <port_def.inc>
+
+namespace google {
+namespace protobuf {
+namespace internal {
+namespace {
+
+
+
+
+} // namespace
+} // namespace internal
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/map_test.inc b/NorthstarDedicatedTest/include/protobuf/map_test.inc
new file mode 100644
index 00000000..c251e896
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/map_test.inc
@@ -0,0 +1,3874 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 hack to include windows.h first, which ensures the GetMessage macro can
+// be undefined when we include <stubs/common.h>
+#if defined(_MSC_VER)
+#define _WINSOCKAPI_ // to avoid re-definition in WinSock2.h
+#define NOMINMAX // to avoid defining min/max macros
+#include <windows.h>
+#endif // _WIN32
+
+#include <algorithm>
+#include <map>
+#include <memory>
+#include <random>
+#include <set>
+#include <sstream>
+#include <unordered_map>
+#include <unordered_set>
+#include <vector>
+
+#include <stubs/logging.h>
+#include <stubs/common.h>
+#include <stubs/stringprintf.h>
+#include <testing/file.h>
+#include <arena_test_util.h>
+#include <test_util2.h>
+#include <io/coded_stream.h>
+#include <io/tokenizer.h>
+#include <io/zero_copy_stream_impl.h>
+#include <descriptor.pb.h>
+#include <descriptor.h>
+#include <descriptor_database.h>
+#include <dynamic_message.h>
+#include <map.h>
+#include <map_field_inl.h>
+#include <message.h>
+#include <reflection.h>
+#include <reflection_ops.h>
+#include <text_format.h>
+#include <wire_format.h>
+#include <util/message_differencer.h>
+#include <util/time_util.h>
+#include <gmock/gmock.h>
+#include <testing/googletest.h>
+#include <gtest/gtest.h>
+#include <stubs/casts.h>
+#include <stubs/substitute.h>
+
+
+// Must be included last.
+#include <port_def.inc>
+
+namespace google {
+namespace protobuf {
+
+using UNITTEST::ForeignMessage;
+using UNITTEST::TestAllTypes;
+using UNITTEST::TestMap;
+using UNITTEST::TestRecursiveMapMessage;
+
+namespace internal {
+
+void MapTestForceDeterministic() {
+ io::CodedOutputStream::SetDefaultSerializationDeterministic();
+}
+
+namespace {
+
+// Map API Test =====================================================
+
+class MapImplTest : public ::testing::Test {
+ protected:
+ MapImplTest()
+ : map_ptr_(new Map<int32, int32>()),
+ map_(*map_ptr_),
+ const_map_(*map_ptr_) {
+ EXPECT_TRUE(map_.empty());
+ EXPECT_EQ(0, map_.size());
+ }
+
+ void ExpectSingleElement(int32 key, int32 value) {
+ EXPECT_FALSE(map_.empty());
+ EXPECT_EQ(1, map_.size());
+ ExpectElement(key, value);
+ }
+
+ void ExpectElements(const std::map<int32, int32>& map) {
+ EXPECT_FALSE(map_.empty());
+ EXPECT_EQ(map.size(), map_.size());
+ for (std::map<int32, int32>::const_iterator it = map.begin();
+ it != map.end(); ++it) {
+ ExpectElement(it->first, it->second);
+ }
+ }
+
+ void ExpectElement(int32 key, int32 value) {
+ // Test map size is correct.
+ EXPECT_EQ(value, map_[key]);
+ EXPECT_EQ(1, map_.count(key));
+ EXPECT_TRUE(map_.contains(key));
+
+ // Check mutable at and find work correctly.
+ EXPECT_EQ(value, map_.at(key));
+ Map<int32, int32>::iterator it = map_.find(key);
+
+ // iterator dereferenceable
+ EXPECT_EQ(key, (*it).first);
+ EXPECT_EQ(value, (*it).second);
+ EXPECT_EQ(key, it->first);
+ EXPECT_EQ(value, it->second);
+
+ // iterator mutable
+ ((*it).second) = value + 1;
+ EXPECT_EQ(value + 1, map_[key]);
+ ((*it).second) = value;
+ EXPECT_EQ(value, map_[key]);
+
+ it->second = value + 1;
+ EXPECT_EQ(value + 1, map_[key]);
+ it->second = value;
+ EXPECT_EQ(value, map_[key]);
+
+ // copy constructor
+ Map<int32, int32>::iterator it_copy = it;
+ EXPECT_EQ(key, it_copy->first);
+ EXPECT_EQ(value, it_copy->second);
+
+ // Immutable API ================================================
+
+ // Check immutable at and find work correctly.
+ EXPECT_EQ(value, const_map_.at(key));
+ Map<int32, int32>::const_iterator const_it = const_map_.find(key);
+
+ // iterator dereferenceable
+ EXPECT_EQ(key, (*const_it).first);
+ EXPECT_EQ(value, (*const_it).second);
+ EXPECT_EQ(key, const_it->first);
+ EXPECT_EQ(value, const_it->second);
+
+ // copy constructor
+ Map<int32, int32>::const_iterator const_it_copy = const_it;
+ EXPECT_EQ(key, const_it_copy->first);
+ EXPECT_EQ(value, const_it_copy->second);
+ }
+
+ std::unique_ptr<Map<int32, int32> > map_ptr_;
+ Map<int32, int32>& map_;
+ const Map<int32, int32>& const_map_;
+};
+
+TEST_F(MapImplTest, OperatorBracket) {
+ int32 key = 0;
+ int32 value1 = 100;
+ int32 value2 = 101;
+
+ EXPECT_EQ(0, map_[key]);
+
+ map_[key] = value1;
+ ExpectSingleElement(key, value1);
+
+ map_[key] = value2;
+ ExpectSingleElement(key, value2);
+}
+
+struct MoveTestKey {
+ MoveTestKey(int data, int* copies) : data(data), copies(copies) {}
+
+ MoveTestKey(const MoveTestKey& other)
+ : data(other.data), copies(other.copies) {
+ ++*copies;
+ }
+
+ MoveTestKey(MoveTestKey&& other) noexcept
+ : data(other.data), copies(other.copies) {}
+
+ friend bool operator==(const MoveTestKey& lhs, const MoveTestKey& rhs) {
+ return lhs.data == rhs.data;
+ }
+ friend bool operator<(const MoveTestKey& lhs, const MoveTestKey& rhs) {
+ return lhs.data < rhs.data;
+ }
+
+ int data;
+ int* copies;
+};
+
+} // namespace
+} // namespace internal
+} // namespace protobuf
+} // namespace google
+
+namespace std {
+
+template <> // NOLINT
+struct hash<google::protobuf::internal::MoveTestKey> {
+ size_t operator()(const google::protobuf::internal::MoveTestKey& key) const {
+ return hash<int>{}(key.data);
+ }
+};
+} // namespace std
+
+namespace google {
+namespace protobuf {
+namespace internal {
+namespace {
+
+TEST_F(MapImplTest, OperatorBracketRValue) {
+ Arena arena;
+ for (Arena* arena_to_use : {&arena, static_cast<Arena*>(nullptr)}) {
+ int copies = 0;
+ Map<MoveTestKey, int> map(arena_to_use);
+ MoveTestKey key1(1, &copies);
+ EXPECT_EQ(copies, 0);
+ map[key1] = 0;
+ EXPECT_EQ(copies, 1);
+ map[MoveTestKey(2, &copies)] = 2;
+ EXPECT_EQ(copies, 1);
+ }
+}
+
+TEST_F(MapImplTest, OperatorBracketNonExist) {
+ int32 key = 0;
+ int32 default_value = 0;
+
+ EXPECT_EQ(default_value, map_[key]);
+ ExpectSingleElement(key, default_value);
+}
+
+TEST_F(MapImplTest, MutableAt) {
+ int32 key = 0;
+ int32 value1 = 100;
+ int32 value2 = 101;
+
+ map_[key] = value1;
+ ExpectSingleElement(key, value1);
+
+ map_.at(key) = value2;
+ ExpectSingleElement(key, value2);
+}
+
+#ifdef PROTOBUF_HAS_DEATH_TEST
+
+TEST_F(MapImplTest, MutableAtNonExistDeathTest) {
+ EXPECT_DEATH(map_.at(0), "");
+}
+
+TEST_F(MapImplTest, ImmutableAtNonExistDeathTest) {
+ EXPECT_DEATH(const_map_.at(0), "");
+}
+
+TEST_F(MapImplTest, UsageErrors) {
+ MapKey key;
+ key.SetInt64Value(1);
+ EXPECT_DEATH(key.GetUInt64Value(),
+ "Protocol Buffer map usage error:\n"
+ "MapKey::GetUInt64Value type does not match\n"
+ " Expected : uint64\n"
+ " Actual : int64");
+
+ MapValueRef value;
+ EXPECT_DEATH(
+ value.SetFloatValue(0.1),
+ "Protocol Buffer map usage error:\n"
+ "MapValue[Const]*Ref::type MapValue[Const]*Ref is not initialized.");
+}
+
+#endif // PROTOBUF_HAS_DEATH_TEST
+
+TEST_F(MapImplTest, MapKeyAssignment) {
+ MapKey from, to;
+ from.SetStringValue("abc");
+ to = from;
+ EXPECT_EQ("abc", to.GetStringValue());
+}
+
+TEST_F(MapImplTest, CountNonExist) { EXPECT_EQ(0, map_.count(0)); }
+
+TEST_F(MapImplTest, ContainNotExist) { EXPECT_FALSE(map_.contains(0)); }
+
+TEST_F(MapImplTest, ImmutableContainNotExist) {
+ EXPECT_FALSE(const_map_.contains(0));
+}
+
+TEST_F(MapImplTest, MutableFindNonExist) {
+ EXPECT_TRUE(map_.end() == map_.find(0));
+}
+
+TEST_F(MapImplTest, ImmutableFindNonExist) {
+ EXPECT_TRUE(const_map_.end() == const_map_.find(0));
+}
+
+TEST_F(MapImplTest, ConstEnd) {
+ EXPECT_TRUE(const_map_.end() == const_map_.cend());
+}
+
+TEST_F(MapImplTest, GetReferenceFromIterator) {
+ for (int i = 0; i < 10; i++) {
+ map_[i] = i;
+ }
+
+ for (Map<int32, int32>::const_iterator it = map_.cbegin();
+ it != map_.cend();) {
+ Map<int32, int32>::const_reference entry = *it++;
+ EXPECT_EQ(entry.first, entry.second);
+ }
+
+ for (Map<int32, int32>::const_iterator it = const_map_.begin();
+ it != const_map_.end();) {
+ Map<int32, int32>::const_reference entry = *it++;
+ EXPECT_EQ(entry.first, entry.second);
+ }
+
+ for (Map<int32, int32>::iterator it = map_.begin(); it != map_.end();) {
+ Map<int32, int32>::reference entry = *it++;
+ EXPECT_EQ(entry.first + 1, ++entry.second);
+ }
+}
+
+TEST_F(MapImplTest, IteratorBasic) {
+ map_[0] = 0;
+
+ // Default constructible (per forward iterator requirements).
+ Map<int, int>::const_iterator cit;
+ Map<int, int>::iterator it;
+
+ it = map_.begin();
+ cit = it; // Converts to const_iterator
+
+ // Can compare between them.
+ EXPECT_TRUE(it == cit);
+ EXPECT_FALSE(cit != it);
+
+ // Pre increment.
+ EXPECT_FALSE(it == ++cit);
+
+ // Post increment.
+ EXPECT_FALSE(it++ == cit);
+ EXPECT_TRUE(it == cit);
+}
+
+template <typename Iterator>
+static int64 median(Iterator i0, Iterator i1) {
+ std::vector<int64> v(i0, i1);
+ std::nth_element(v.begin(), v.begin() + v.size() / 2, v.end());
+ return v[v.size() / 2];
+}
+
+static int64 Now() {
+ return util::TimeUtil::TimestampToNanoseconds(
+ util::TimeUtil::GetCurrentTime());
+}
+
+// Arbitrary odd integers for creating test data.
+static int k0 = 812398771;
+static int k1 = 1312938717;
+static int k2 = 1321555333;
+
+// A naive begin() implementation will cause begin() to get slower and slower
+// if one erases elements at the "front" of the hash map, and we'd like to
+// avoid that, as std::unordered_map does.
+TEST_F(MapImplTest, BeginIsFast) {
+ if (true) return; // TODO(gpike): make this less flaky and re-enable it.
+ Map<int32, int32> map;
+ const int kTestSize = 250000;
+ // Create a random-looking map of size n. Use non-negative integer keys.
+ uint32 frog = 123983;
+ int last_key = 0;
+ int counter = 0;
+ while (map.size() < kTestSize) {
+ frog *= static_cast<uint32>(k0);
+ frog ^= frog >> 17;
+ frog += counter++;
+ last_key =
+ static_cast<int>(frog) >= 0 ? static_cast<int>(frog) : last_key ^ 1;
+ GOOGLE_DCHECK_GE(last_key, 0);
+ map[last_key] = last_key ^ 1;
+ }
+ std::vector<int64> times;
+ // We're going to do map.erase(map.begin()) over and over again. But,
+ // just in case one iteration is fast compared to the granularity of
+ // our time keeping, we measure kChunkSize iterations per outer-loop iter.
+ const int kChunkSize = 1000;
+ GOOGLE_CHECK_EQ(kTestSize % kChunkSize, 0);
+ do {
+ const int64 start = Now();
+ for (int i = 0; i < kChunkSize; i++) {
+ map.erase(map.begin());
+ }
+ const int64 end = Now();
+ if (end > start) {
+ times.push_back(end - start);
+ }
+ } while (!map.empty());
+ if (times.size() < .99 * kTestSize / kChunkSize) {
+ GOOGLE_LOG(WARNING) << "Now() isn't helping us measure time";
+ return;
+ }
+ int64 x0 = median(times.begin(), times.begin() + 9);
+ int64 x1 = median(times.begin() + times.size() - 9, times.end());
+ GOOGLE_LOG(INFO) << "x0=" << x0 << ", x1=" << x1;
+ // x1 will greatly exceed x0 if the code we just executed took O(n^2) time.
+ // And we'll probably time out and never get here. So, this test is
+ // intentionally loose: we check that x0 and x1 are within a factor of 8.
+ EXPECT_GE(x1, x0 / 8);
+ EXPECT_GE(x0, x1 / 8);
+}
+
+// Try to create kTestSize keys that will land in just a few buckets, and
+// time the insertions, to get a rough estimate of whether an O(n^2) worst case
+// was triggered. This test is a hacky, but probably better than nothing.
+TEST_F(MapImplTest, HashFlood) {
+ const int kTestSize = 1024; // must be a power of 2
+ std::set<int> s;
+ for (int i = 0; s.size() < kTestSize; i++) {
+ if ((map_.hash_function()(i) & (kTestSize - 1)) < 3) {
+ s.insert(i);
+ }
+ }
+ // Create hash table with kTestSize entries that hash flood a table with
+ // 1024 (or 512 or 2048 or ...) entries. This assumes that map_ uses powers
+ // of 2 for table sizes, and that it's sufficient to "flood" with respect to
+ // the low bits of the output of map_.hash_function().
+ std::vector<int64> times;
+ std::set<int>::iterator it = s.begin();
+ int count = 0;
+ do {
+ const int64 start = Now();
+ map_[*it] = 0;
+ const int64 end = Now();
+ if (end > start) {
+ times.push_back(end - start);
+ }
+ ++count;
+ ++it;
+ } while (it != s.end());
+ if (times.size() < .99 * count) return;
+ int64 x0 = median(times.begin(), times.begin() + 9);
+ int64 x1 = median(times.begin() + times.size() - 9, times.end());
+ // x1 will greatly exceed x0 if the code we just executed took O(n^2) time.
+ // But we want to allow O(n log n). A factor of 20 should be generous enough.
+ EXPECT_LE(x1, x0 * 20);
+}
+
+TEST_F(MapImplTest, CopyIteratorStressTest) {
+ std::vector<Map<int32, int32>::iterator> v;
+ const int kIters = 1e5;
+ for (uint32 i = 0; i < kIters; i++) {
+ int32 key = (3 + i * (5 + i * (-8 + i * (62 + i)))) & 0x77777777;
+ map_[key] = i;
+ v.push_back(map_.find(key));
+ }
+ for (std::vector<Map<int32, int32>::iterator>::const_iterator it = v.begin();
+ it != v.end(); it++) {
+ Map<int32, int32>::iterator i = *it;
+ ASSERT_EQ(i->first, (*it)->first);
+ ASSERT_EQ(i->second, (*it)->second);
+ }
+}
+
+template <typename T, typename U>
+static void TestValidityForAllKeysExcept(int key_to_avoid, const T& check_map,
+ const U& map) {
+ typedef typename U::value_type value_type; // a key-value pair
+ for (typename U::const_iterator it = map.begin(); it != map.end(); ++it) {
+ const int key = it->first;
+ if (key == key_to_avoid) continue;
+ // All iterators relevant to this key, whether old (from check_map) or new,
+ // must point to the same memory. So, test pointer equality here.
+ const value_type* check_val = &*check_map.find(key)->second;
+ EXPECT_EQ(check_val, &*it);
+ EXPECT_EQ(check_val, &*map.find(key));
+ }
+}
+
+// EXPECT i0 and i1 to be the same. Advancing them should have the same effect,
+// too.
+template <typename Iter>
+static void TestEqualIterators(Iter i0, Iter i1, Iter end) {
+ const int kMaxAdvance = 10;
+ for (int i = 0; i < kMaxAdvance; i++) {
+ EXPECT_EQ(i0 == end, i1 == end);
+ if (i0 == end) return;
+ EXPECT_EQ(&*i0, &*i1) << "iter " << i;
+ ++i0;
+ ++i1;
+ }
+}
+
+template <typename IteratorType>
+static void TestOldVersusNewIterator(int skip, Map<int, int>* m) {
+ const int initial_size = m->size();
+ IteratorType it = m->begin();
+ for (int i = 0; i < skip && it != m->end(); it++, i++) {
+ }
+ if (it == m->end()) return;
+ const IteratorType old = it;
+ GOOGLE_LOG(INFO) << "skip=" << skip << ", old->first=" << old->first;
+ const int target_size =
+ initial_size < 100 ? initial_size * 5 : initial_size * 5 / 4;
+ for (int i = 0; m->size() <= target_size; i++) {
+ (*m)[i] = 0;
+ }
+ // Iterator 'old' should still work just fine despite the growth of *m.
+ const IteratorType after_growth = m->find(old->first);
+ TestEqualIterators<IteratorType>(old, after_growth, m->end());
+
+ // Now shrink the number of elements. Do this with a mix of erases and
+ // inserts to increase the chance that the hashtable will resize to a lower
+ // number of buckets. (But, in any case, the test is still useful.)
+ for (int i = 0; i < 2 * (target_size - initial_size); i++) {
+ if (i != old->first) {
+ m->erase(i);
+ }
+ if (((i ^ m->begin()->first) & 15) == 0) {
+ (*m)[i * 342] = i;
+ }
+ }
+ // Now, the table has grown and shrunk; test again.
+ TestEqualIterators<IteratorType>(old, m->find(old->first), m->end());
+ TestEqualIterators<IteratorType>(old, after_growth, m->end());
+}
+
+// Create and test an n-element Map, with emphasis on iterator correctness.
+static void StressTestIterators(int n) {
+ GOOGLE_LOG(INFO) << "StressTestIterators " << n;
+ GOOGLE_CHECK_GT(n, 0);
+ // Create a random-looking map of size n. Use non-negative integer keys.
+ Map<int, int> m;
+ uint32 frog = 123987 + n;
+ int last_key = 0;
+ int counter = 0;
+ while (m.size() < n) {
+ frog *= static_cast<uint32>(k0);
+ frog ^= frog >> 17;
+ frog += counter++;
+ last_key =
+ static_cast<int>(frog) >= 0 ? static_cast<int>(frog) : last_key ^ 1;
+ GOOGLE_DCHECK_GE(last_key, 0);
+ m[last_key] = last_key ^ 1;
+ }
+ // Test it.
+ ASSERT_EQ(n, m.size());
+ // Create maps of pointers and iterators.
+ // These should remain valid even if we modify m.
+ std::unordered_map<int, Map<int, int>::value_type*> mp(n);
+ std::unordered_map<int, Map<int, int>::iterator> mi(n);
+ for (Map<int, int>::iterator it = m.begin(); it != m.end(); ++it) {
+ mp[it->first] = &*it;
+ mi[it->first] = it;
+ }
+ ASSERT_EQ(m.size(), mi.size());
+ ASSERT_EQ(m.size(), mp.size());
+ m.erase(last_key);
+ ASSERT_EQ(n - 1, m.size());
+ TestValidityForAllKeysExcept(last_key, mp, m);
+ TestValidityForAllKeysExcept(last_key, mi, m);
+
+ m[last_key] = 0;
+ ASSERT_EQ(n, m.size());
+ // Test old iterator vs new iterator, with table modification in between.
+ TestOldVersusNewIterator<Map<int, int>::const_iterator>(n % 3, &m);
+ TestOldVersusNewIterator<Map<int, int>::iterator>(n % (1 + (n / 40)), &m);
+ // Finally, ensure erase(iterator) doesn't reorder anything, because that is
+ // what its documentation says.
+ m[last_key] = m[last_key ^ 999] = 0;
+ std::vector<Map<int, int>::iterator> v;
+ v.reserve(m.size());
+ int position_of_last_key = 0;
+ for (Map<int, int>::iterator it = m.begin(); it != m.end(); ++it) {
+ if (it->first == last_key) {
+ position_of_last_key = v.size();
+ }
+ v.push_back(it);
+ }
+ ASSERT_EQ(m.size(), v.size());
+ const Map<int, int>::iterator erase_result = m.erase(m.find(last_key));
+ int index = 0;
+ for (Map<int, int>::iterator it = m.begin(); it != m.end(); ++it, ++index) {
+ if (index == position_of_last_key) {
+ EXPECT_EQ(&*erase_result, &*v[++index]);
+ }
+ ASSERT_EQ(&*it, &*v[index]);
+ }
+}
+
+TEST_F(MapImplTest, IteratorInvalidation) {
+ // Create a set of pseudo-random sizes to test.
+#ifndef NDEBUG
+ const int kMaxSizeToTest = 100 * 1000;
+#else
+ const int kMaxSizeToTest = 1000 * 1000;
+#endif
+ std::set<int> s;
+ int n = kMaxSizeToTest;
+ unsigned int frog = k1 + n;
+ while (n > 1 && s.size() < 25) {
+ s.insert(n);
+ n = static_cast<int>(n * 100 / (101.0 + (frog & 63)));
+ frog *= k2;
+ frog ^= frog >> 17;
+ }
+ // Ensure we test a few small sizes.
+ s.insert(1);
+ s.insert(2);
+ s.insert(3);
+ // Now, the real work.
+ for (std::set<int>::iterator i = s.begin(); i != s.end(); ++i) {
+ StressTestIterators(*i);
+ }
+}
+
+// Test that erase() revalidates iterators.
+TEST_F(MapImplTest, EraseRevalidates) {
+ map_[3] = map_[13] = map_[20] = 0;
+ const int initial_size = map_.size();
+ EXPECT_EQ(3, initial_size);
+ std::vector<Map<int, int>::iterator> v;
+ for (Map<int, int>::iterator it = map_.begin(); it != map_.end(); ++it) {
+ v.push_back(it);
+ }
+ EXPECT_EQ(initial_size, v.size());
+ for (int i = 0; map_.size() <= initial_size * 20; i++) {
+ map_[i] = 0;
+ }
+ const int larger_size = map_.size();
+ // We've greatly increased the size of the map, so it is highly likely that
+ // the following will corrupt m if erase() doesn't properly revalidate
+ // iterators passed to it. Finishing this routine without crashing indicates
+ // success.
+ for (int i = 0; i < v.size(); i++) {
+ map_.erase(v[i]);
+ }
+ EXPECT_EQ(larger_size - v.size(), map_.size());
+}
+
+template <typename T>
+bool IsConstHelper(T& /*t*/) { // NOLINT. We want to catch non-const refs here.
+ return false;
+}
+template <typename T>
+bool IsConstHelper(const T& /*t*/) {
+ return true;
+}
+
+TEST_F(MapImplTest, IteratorConstness) {
+ map_[0] = 0;
+ EXPECT_TRUE(IsConstHelper(*map_.cbegin()));
+ EXPECT_TRUE(IsConstHelper(*const_map_.begin()));
+ EXPECT_FALSE(IsConstHelper(*map_.begin()));
+}
+
+bool IsForwardIteratorHelper(std::forward_iterator_tag /*tag*/) { return true; }
+
+TEST_F(MapImplTest, IteratorCategory) {
+ EXPECT_TRUE(IsForwardIteratorHelper(
+ std::iterator_traits<Map<int, int>::iterator>::iterator_category()));
+ EXPECT_TRUE(IsForwardIteratorHelper(
+ std::iterator_traits<
+ Map<int, int>::const_iterator>::iterator_category()));
+}
+
+TEST_F(MapImplTest, InsertSingle) {
+ int32 key = 0;
+ int32 value1 = 100;
+ int32 value2 = 101;
+
+ // Insert a non-existed key.
+ std::pair<Map<int32, int32>::iterator, bool> result1 =
+ map_.insert(Map<int32, int32>::value_type(key, value1));
+ ExpectSingleElement(key, value1);
+
+ Map<int32, int32>::iterator it1 = result1.first;
+ EXPECT_EQ(key, it1->first);
+ EXPECT_EQ(value1, it1->second);
+ EXPECT_TRUE(result1.second);
+
+ // Insert an existed key.
+ std::pair<Map<int32, int32>::iterator, bool> result2 =
+ map_.insert(Map<int32, int32>::value_type(key, value2));
+ ExpectSingleElement(key, value1);
+
+ Map<int32, int32>::iterator it2 = result2.first;
+ EXPECT_TRUE(it1 == it2);
+ EXPECT_FALSE(result2.second);
+}
+
+TEST_F(MapImplTest, InsertByIterator) {
+ int32 key1 = 0;
+ int32 key2 = 1;
+ int32 value1a = 100;
+ int32 value1b = 101;
+ int32 value2a = 200;
+ int32 value2b = 201;
+
+ std::map<int32, int32> map1;
+ map1[key1] = value1a;
+ map1[key2] = value2a;
+
+ map_.insert(map1.begin(), map1.end());
+ ExpectElements(map1);
+
+ std::map<int32, int32> map2;
+ map2[key1] = value1b;
+ map2[key2] = value2b;
+
+ map_.insert(map2.begin(), map2.end());
+ ExpectElements(map1);
+}
+
+TEST_F(MapImplTest, InsertByInitializerList) {
+ map_.insert({{1, 100}, {2, 200}});
+ ExpectElements({{1, 100}, {2, 200}});
+
+ map_.insert({{2, 201}, {3, 301}});
+ ExpectElements({{1, 100}, {2, 200}, {3, 301}});
+}
+
+TEST_F(MapImplTest, EraseSingleByKey) {
+ int32 key = 0;
+ int32 value = 100;
+
+ map_[key] = value;
+ ExpectSingleElement(key, value);
+
+ // Erase an existing key.
+ EXPECT_EQ(1, map_.erase(key));
+ EXPECT_TRUE(map_.empty());
+ EXPECT_EQ(0, map_.size());
+ EXPECT_TRUE(map_.end() == map_.find(key));
+ EXPECT_TRUE(map_.begin() == map_.end());
+
+ // Erase a non-existing key.
+ EXPECT_EQ(0, map_.erase(key));
+}
+
+TEST_F(MapImplTest, EraseMutipleByKey) {
+ // erase in one specific order to trigger corner cases
+ for (int i = 0; i < 5; i++) {
+ map_[i] = i;
+ }
+
+ map_.erase(0);
+ EXPECT_EQ(4, map_.size());
+ EXPECT_TRUE(map_.end() == map_.find(0));
+
+ map_.erase(1);
+ EXPECT_EQ(3, map_.size());
+ EXPECT_TRUE(map_.end() == map_.find(1));
+
+ map_.erase(3);
+ EXPECT_EQ(2, map_.size());
+ EXPECT_TRUE(map_.end() == map_.find(3));
+
+ map_.erase(4);
+ EXPECT_EQ(1, map_.size());
+ EXPECT_TRUE(map_.end() == map_.find(4));
+
+ map_.erase(2);
+ EXPECT_EQ(0, map_.size());
+ EXPECT_TRUE(map_.end() == map_.find(2));
+}
+
+TEST_F(MapImplTest, EraseSingleByIterator) {
+ int32 key = 0;
+ int32 value = 100;
+
+ map_[key] = value;
+ ExpectSingleElement(key, value);
+
+ Map<int32, int32>::iterator it = map_.find(key);
+ map_.erase(it);
+ EXPECT_TRUE(map_.empty());
+ EXPECT_EQ(0, map_.size());
+ EXPECT_TRUE(map_.end() == map_.find(key));
+ EXPECT_TRUE(map_.begin() == map_.end());
+}
+
+TEST_F(MapImplTest, ValidIteratorAfterErase) {
+ for (int i = 0; i < 10; i++) {
+ map_[i] = i;
+ }
+
+ int count = 0;
+
+ for (Map<int32, int32>::iterator it = map_.begin(); it != map_.end();) {
+ count++;
+ if (it->first % 2 == 1) {
+ map_.erase(it++);
+ } else {
+ ++it;
+ }
+ }
+
+ EXPECT_EQ(10, count);
+ EXPECT_EQ(5, map_.size());
+}
+
+TEST_F(MapImplTest, EraseByIterator) {
+ int32 key1 = 0;
+ int32 key2 = 1;
+ int32 value1 = 100;
+ int32 value2 = 101;
+
+ std::map<int32, int32> map;
+ map[key1] = value1;
+ map[key2] = value2;
+
+ map_.insert(map.begin(), map.end());
+ ExpectElements(map);
+
+ map_.erase(map_.begin(), map_.end());
+ EXPECT_TRUE(map_.empty());
+ EXPECT_EQ(0, map_.size());
+ EXPECT_TRUE(map_.end() == map_.find(key1));
+ EXPECT_TRUE(map_.end() == map_.find(key2));
+ EXPECT_TRUE(map_.begin() == map_.end());
+}
+
+TEST_F(MapImplTest, Clear) {
+ int32 key = 0;
+ int32 value = 100;
+
+ map_[key] = value;
+ ExpectSingleElement(key, value);
+
+ map_.clear();
+
+ EXPECT_TRUE(map_.empty());
+ EXPECT_EQ(0, map_.size());
+ EXPECT_TRUE(map_.end() == map_.find(key));
+ EXPECT_TRUE(map_.begin() == map_.end());
+}
+
+static void CopyConstructorHelper(Arena* arena, Map<int32, int32>* m) {
+ int32 key1 = 0;
+ int32 key2 = 1;
+ int32 value1 = 100;
+ int32 value2 = 101;
+
+ std::map<int32, int32> map;
+ map[key1] = value1;
+ map[key2] = value2;
+
+ m->insert(map.begin(), map.end());
+
+ Map<int32, int32> other(*m);
+
+ EXPECT_EQ(2, other.size());
+ EXPECT_EQ(value1, other.at(key1));
+ EXPECT_EQ(value2, other.at(key2));
+}
+
+TEST_F(MapImplTest, CopyConstructorWithArena) {
+ Arena a;
+ CopyConstructorHelper(&a, &map_);
+}
+
+TEST_F(MapImplTest, CopyConstructorWithoutArena) {
+ CopyConstructorHelper(nullptr, &map_);
+}
+
+TEST_F(MapImplTest, IterConstructor) {
+ int32 key1 = 0;
+ int32 key2 = 1;
+ int32 value1 = 100;
+ int32 value2 = 101;
+
+ std::map<int32, int32> map;
+ map[key1] = value1;
+ map[key2] = value2;
+
+ Map<int32, int32> new_map(map.begin(), map.end());
+
+ EXPECT_EQ(2, new_map.size());
+ EXPECT_EQ(value1, new_map.at(key1));
+ EXPECT_EQ(value2, new_map.at(key2));
+}
+
+TEST_F(MapImplTest, Assigner) {
+ int32 key1 = 0;
+ int32 key2 = 1;
+ int32 value1 = 100;
+ int32 value2 = 101;
+
+ std::map<int32, int32> map;
+ map[key1] = value1;
+ map[key2] = value2;
+
+ map_.insert(map.begin(), map.end());
+
+ Map<int32, int32> other;
+ int32 key_other = 123;
+ int32 value_other = 321;
+ other[key_other] = value_other;
+ EXPECT_EQ(1, other.size());
+
+ other = map_;
+
+ EXPECT_EQ(2, other.size());
+ EXPECT_EQ(value1, other.at(key1));
+ EXPECT_EQ(value2, other.at(key2));
+ EXPECT_TRUE(other.find(key_other) == other.end());
+
+ // Self assign
+ other = *&other; // Avoid -Wself-assign.
+ EXPECT_EQ(2, other.size());
+ EXPECT_EQ(value1, other.at(key1));
+ EXPECT_EQ(value2, other.at(key2));
+}
+
+TEST_F(MapImplTest, Rehash) {
+ const int test_size = 50;
+ std::map<int32, int32> reference_map;
+ for (int i = 0; i < test_size; i++) {
+ reference_map[i] = i;
+ }
+ for (int i = 0; i < test_size; i++) {
+ map_[i] = reference_map[i];
+ EXPECT_EQ(reference_map[i], map_[i]);
+ }
+ for (int i = 0; i < test_size; i++) {
+ map_.erase(i);
+ EXPECT_TRUE(map_.end() == map_.find(i));
+ }
+ EXPECT_TRUE(map_.empty());
+}
+
+TEST_F(MapImplTest, EqualRange) {
+ int key = 100, key_missing = 101;
+ map_[key] = 100;
+
+ std::pair<Map<int32, int32>::iterator, Map<int32, int32>::iterator> range =
+ map_.equal_range(key);
+ EXPECT_TRUE(map_.find(key) == range.first);
+ EXPECT_TRUE(++map_.find(key) == range.second);
+
+ range = map_.equal_range(key_missing);
+ EXPECT_TRUE(map_.end() == range.first);
+ EXPECT_TRUE(map_.end() == range.second);
+
+ std::pair<Map<int32, int32>::const_iterator,
+ Map<int32, int32>::const_iterator>
+ const_range = const_map_.equal_range(key);
+ EXPECT_TRUE(const_map_.find(key) == const_range.first);
+ EXPECT_TRUE(++const_map_.find(key) == const_range.second);
+
+ const_range = const_map_.equal_range(key_missing);
+ EXPECT_TRUE(const_map_.end() == const_range.first);
+ EXPECT_TRUE(const_map_.end() == const_range.second);
+}
+
+TEST_F(MapImplTest, ConvertToStdMap) {
+ map_[100] = 101;
+ std::map<int32, int32> std_map(map_.begin(), map_.end());
+ EXPECT_EQ(1, std_map.size());
+ EXPECT_EQ(101, std_map[100]);
+}
+
+TEST_F(MapImplTest, ConvertToStdVectorOfPairs) {
+ map_[100] = 101;
+ std::vector<std::pair<int32, int32> > std_vec(map_.begin(), map_.end());
+ EXPECT_EQ(1, std_vec.size());
+ EXPECT_EQ(100, std_vec[0].first);
+ EXPECT_EQ(101, std_vec[0].second);
+}
+
+TEST_F(MapImplTest, SwapBasic) {
+ Map<int32, int32> another;
+ map_[9398] = 41999;
+ another[9398] = 41999;
+ another[8070] = 42056;
+ another.swap(map_);
+ EXPECT_THAT(another,
+ testing::UnorderedElementsAre(testing::Pair(9398, 41999)));
+ EXPECT_THAT(map_, testing::UnorderedElementsAre(testing::Pair(8070, 42056),
+ testing::Pair(9398, 41999)));
+}
+
+TEST_F(MapImplTest, SwapArena) {
+ Arena arena1, arena2;
+ Map<int32, int32> m1(&arena1);
+ Map<int32, int32> m2(&arena2);
+ map_[9398] = 41999;
+ m1[9398] = 41999;
+ m1[8070] = 42056;
+ m2[10244] = 10247;
+ m2[8070] = 42056;
+ m1.swap(map_);
+ EXPECT_THAT(m1, testing::UnorderedElementsAre(testing::Pair(9398, 41999)));
+ EXPECT_THAT(map_, testing::UnorderedElementsAre(testing::Pair(8070, 42056),
+ testing::Pair(9398, 41999)));
+ m2.swap(m1);
+ EXPECT_THAT(m1, testing::UnorderedElementsAre(testing::Pair(8070, 42056),
+ testing::Pair(10244, 10247)));
+ EXPECT_THAT(m2, testing::UnorderedElementsAre(testing::Pair(9398, 41999)));
+}
+
+TEST_F(MapImplTest, SwapFieldArenaReflection) {
+ MapReflectionTester reflection_tester(UNITTEST::TestMap::descriptor());
+ Arena arena;
+
+ {
+ // Tests filled lfs and empty rhs.
+ TestMap rhs;
+
+ {
+ // Use local_arena to allocate lhs to trigger use-after-free error.
+ Arena local_arena;
+ auto* lhs = Arena::CreateMessage<TestMap>(&local_arena);
+ const auto* reflection = lhs->GetReflection();
+ std::vector<const FieldDescriptor*> fields;
+
+ reflection_tester.SetMapFieldsViaReflection(lhs);
+ reflection->ListFields(*lhs, &fields);
+
+ reflection->SwapFields(lhs, &rhs, fields);
+
+ reflection_tester.ExpectClearViaReflection(*lhs);
+ }
+
+ reflection_tester.ExpectMapFieldsSetViaReflection(rhs);
+ }
+}
+
+TEST_F(MapImplTest, CopyAssignMapIterator) {
+ TestMap message;
+ MapReflectionTester reflection_tester(UNITTEST::TestMap::descriptor());
+ reflection_tester.SetMapFieldsViaMapReflection(&message);
+ MapIterator it1 = reflection_tester.MapBegin(&message, "map_int32_int32");
+ MapIterator it2 = reflection_tester.MapEnd(&message, "map_int32_int32");
+ it2 = it1;
+ EXPECT_EQ(it1.GetKey().GetInt32Value(), it2.GetKey().GetInt32Value());
+}
+
+TEST_F(MapImplTest, SpaceUsed) {
+ constexpr size_t kMinCap = 8;
+
+ Map<int32, int32> m;
+ // An newly constructed map should have no space used.
+ EXPECT_EQ(m.SpaceUsedExcludingSelfLong(), 0);
+
+ size_t capacity = kMinCap;
+ for (int i = 0; i < 100; ++i) {
+ m[i];
+ static constexpr double kMaxLoadFactor = .75;
+ if (m.size() >= capacity * kMaxLoadFactor) {
+ capacity *= 2;
+ }
+ EXPECT_EQ(m.SpaceUsedExcludingSelfLong(),
+ sizeof(void*) * capacity +
+ m.size() * sizeof(std::pair<std::pair<int32, int32>, void*>));
+ }
+
+ // Test string, and non-scalar keys.
+ Map<std::string, int32> m2;
+ std::string str = "Some arbitrarily large string";
+ m2[str] = 1;
+ EXPECT_EQ(m2.SpaceUsedExcludingSelfLong(),
+ sizeof(void*) * kMinCap +
+ sizeof(std::pair<std::pair<std::string, int32>, void*>) +
+ internal::StringSpaceUsedExcludingSelfLong(str));
+
+ // Test messages, and non-scalar values.
+ Map<int32, TestAllTypes> m3;
+ m3[0].set_optional_string(str);
+ EXPECT_EQ(m3.SpaceUsedExcludingSelfLong(),
+ sizeof(void*) * kMinCap +
+ sizeof(std::pair<std::pair<int32, TestAllTypes>, void*>) +
+ m3[0].SpaceUsedLong() - sizeof(m3[0]));
+}
+
+// Attempts to verify that a map with keys a and b has a random ordering. This
+// function returns true if it succeeds in observing both possible orderings.
+bool MapOrderingIsRandom(int a, int b) {
+ bool saw_a_first = false;
+ bool saw_b_first = false;
+ std::vector<Map<int32, int32>> v(50);
+ for (int i = 0; i < 50; ++i) {
+ Map<int32, int32>& m = v[i];
+ m[a] = 0;
+ m[b] = 0;
+ int32 first_element = m.begin()->first;
+ if (first_element == a) saw_a_first = true;
+ if (first_element == b) saw_b_first = true;
+ if (saw_a_first && saw_b_first) {
+ return true;
+ }
+ }
+ return false;
+}
+
+// This test verifies that the iteration order is reasonably random even for
+// small maps.
+TEST_F(MapImplTest, RandomOrdering) {
+ for (int i = 0; i < 10; ++i) {
+ for (int j = i + 1; j < 10; ++j) {
+ EXPECT_TRUE(MapOrderingIsRandom(i, j))
+ << "Map with keys " << i << " and " << j
+ << " has deterministic ordering";
+ }
+ }
+}
+
+template <typename Key>
+void TestTransparent(const Key& key, const Key& miss_key) {
+ Map<std::string, int> m;
+ const auto& cm = m;
+
+ m.insert({"ABC", 1});
+
+ const auto abc_it = m.begin();
+
+ m.insert({"DEF", 2});
+
+ using testing::Pair;
+ using testing::UnorderedElementsAre;
+
+ EXPECT_EQ(m.at(key), 1);
+ EXPECT_EQ(cm.at(key), 1);
+
+#ifdef PROTOBUF_HAS_DEATH_TEST
+ EXPECT_DEATH(m.at(miss_key), "");
+ EXPECT_DEATH(cm.at(miss_key), "");
+#endif // PROTOBUF_HAS_DEATH_TEST
+
+ EXPECT_EQ(m.count(key), 1);
+ EXPECT_EQ(cm.count(key), 1);
+ EXPECT_EQ(m.count(miss_key), 0);
+ EXPECT_EQ(cm.count(miss_key), 0);
+
+ EXPECT_EQ(m.find(key), abc_it);
+ EXPECT_EQ(cm.find(key), abc_it);
+ EXPECT_EQ(m.find(miss_key), m.end());
+ EXPECT_EQ(cm.find(miss_key), cm.end());
+
+ EXPECT_TRUE(m.contains(key));
+ EXPECT_TRUE(cm.contains(key));
+ EXPECT_FALSE(m.contains(miss_key));
+ EXPECT_FALSE(cm.contains(miss_key));
+
+ EXPECT_THAT(m.equal_range(key), Pair(abc_it, std::next(abc_it)));
+ EXPECT_THAT(cm.equal_range(key), Pair(abc_it, std::next(abc_it)));
+ EXPECT_THAT(m.equal_range(miss_key), Pair(m.end(), m.end()));
+ EXPECT_THAT(cm.equal_range(miss_key), Pair(m.end(), m.end()));
+
+ EXPECT_THAT(m, UnorderedElementsAre(Pair("ABC", 1), Pair("DEF", 2)));
+ EXPECT_EQ(m.erase(key), 1);
+ EXPECT_THAT(m, UnorderedElementsAre(Pair("DEF", 2)));
+ EXPECT_EQ(m.erase(key), 0);
+ EXPECT_EQ(m.erase(miss_key), 0);
+ EXPECT_THAT(m, UnorderedElementsAre(Pair("DEF", 2)));
+
+ m[key];
+ EXPECT_THAT(m, UnorderedElementsAre(Pair("ABC", 0), Pair("DEF", 2)));
+ m[key] = 1;
+ EXPECT_THAT(m, UnorderedElementsAre(Pair("ABC", 1), Pair("DEF", 2)));
+}
+
+TEST_F(MapImplTest, TransparentLookupForString) {
+ TestTransparent("ABC", "LKJ");
+ TestTransparent(std::string("ABC"), std::string("LKJ"));
+#if defined(__cpp_lib_string_view)
+ TestTransparent(std::string_view("ABC"), std::string_view("LKJ"));
+#endif // defined(__cpp_lib_string_view)
+
+ // std::reference_wrapper
+ std::string abc = "ABC", lkj = "LKJ";
+ TestTransparent(std::ref(abc), std::ref(lkj));
+ TestTransparent(std::cref(abc), std::cref(lkj));
+}
+
+TEST_F(MapImplTest, ConstInit) {
+ PROTOBUF_CONSTINIT static Map<int, int> map; // NOLINT
+ EXPECT_TRUE(map.empty());
+}
+
+// Map Field Reflection Test ========================================
+
+static int Func(int i, int j) { return i * j; }
+
+static std::string StrFunc(int i, int j) { return StrCat(Func(i, j)); }
+
+static int Int(const std::string& value) {
+ int result = 0;
+ std::istringstream(value) >> result;
+ return result;
+}
+
+} // namespace
+
+// This class is a friend, so no anonymous namespace.
+class MapFieldReflectionTest : public testing::Test {
+ protected:
+ typedef FieldDescriptor FD;
+
+ int MapSize(const Reflection* reflection, const FieldDescriptor* field,
+ const Message& message) {
+ return reflection->MapSize(message, field);
+ }
+};
+
+namespace {
+
+TEST_F(MapFieldReflectionTest, RegularFields) {
+ TestMap message;
+ const Reflection* refl = message.GetReflection();
+ const Descriptor* desc = message.GetDescriptor();
+
+ Map<int32, int32>* map_int32_int32 = message.mutable_map_int32_int32();
+ Map<int32, double>* map_int32_double = message.mutable_map_int32_double();
+ Map<std::string, std::string>* map_string_string =
+ message.mutable_map_string_string();
+ Map<int32, ForeignMessage>* map_int32_foreign_message =
+ message.mutable_map_int32_foreign_message();
+
+ for (int i = 0; i < 10; ++i) {
+ (*map_int32_int32)[i] = Func(i, 1);
+ (*map_int32_double)[i] = Func(i, 2);
+ (*map_string_string)[StrFunc(i, 1)] = StrFunc(i, 5);
+ (*map_int32_foreign_message)[i].set_c(Func(i, 6));
+ }
+
+ // Get FieldDescriptors for all the fields of interest.
+ const FieldDescriptor* fd_map_int32_int32 =
+ desc->FindFieldByName("map_int32_int32");
+ const FieldDescriptor* fd_map_int32_double =
+ desc->FindFieldByName("map_int32_double");
+ const FieldDescriptor* fd_map_string_string =
+ desc->FindFieldByName("map_string_string");
+ const FieldDescriptor* fd_map_int32_foreign_message =
+ desc->FindFieldByName("map_int32_foreign_message");
+
+ const FieldDescriptor* fd_map_int32_in32_key =
+ fd_map_int32_int32->message_type()->FindFieldByName("key");
+ const FieldDescriptor* fd_map_int32_in32_value =
+ fd_map_int32_int32->message_type()->FindFieldByName("value");
+ const FieldDescriptor* fd_map_int32_double_key =
+ fd_map_int32_double->message_type()->FindFieldByName("key");
+ const FieldDescriptor* fd_map_int32_double_value =
+ fd_map_int32_double->message_type()->FindFieldByName("value");
+ const FieldDescriptor* fd_map_string_string_key =
+ fd_map_string_string->message_type()->FindFieldByName("key");
+ const FieldDescriptor* fd_map_string_string_value =
+ fd_map_string_string->message_type()->FindFieldByName("value");
+ const FieldDescriptor* fd_map_int32_foreign_message_key =
+ fd_map_int32_foreign_message->message_type()->FindFieldByName("key");
+ const FieldDescriptor* fd_map_int32_foreign_message_value =
+ fd_map_int32_foreign_message->message_type()->FindFieldByName("value");
+
+ // Get RepeatedPtrField objects for all fields of interest.
+ const RepeatedPtrField<Message>& mf_int32_int32 =
+ refl->GetRepeatedPtrField<Message>(message, fd_map_int32_int32);
+ const RepeatedPtrField<Message>& mf_int32_double =
+ refl->GetRepeatedPtrField<Message>(message, fd_map_int32_double);
+ const RepeatedPtrField<Message>& mf_string_string =
+ refl->GetRepeatedPtrField<Message>(message, fd_map_string_string);
+ const RepeatedPtrField<Message>& mf_int32_foreign_message =
+ refl->GetRepeatedPtrField<Message>(message, fd_map_int32_foreign_message);
+
+ // Get mutable RepeatedPtrField objects for all fields of interest.
+ RepeatedPtrField<Message>* mmf_int32_int32 =
+ refl->MutableRepeatedPtrField<Message>(&message, fd_map_int32_int32);
+ RepeatedPtrField<Message>* mmf_int32_double =
+ refl->MutableRepeatedPtrField<Message>(&message, fd_map_int32_double);
+ RepeatedPtrField<Message>* mmf_string_string =
+ refl->MutableRepeatedPtrField<Message>(&message, fd_map_string_string);
+ RepeatedPtrField<Message>* mmf_int32_foreign_message =
+ refl->MutableRepeatedPtrField<Message>(&message,
+ fd_map_int32_foreign_message);
+
+ // Make sure we can do gets through the RepeatedPtrField objects.
+ for (int i = 0; i < 10; ++i) {
+ {
+ // Check gets through const objects.
+ const Message& message_int32_int32 = mf_int32_int32.Get(i);
+ int32 key_int32_int32 = message_int32_int32.GetReflection()->GetInt32(
+ message_int32_int32, fd_map_int32_in32_key);
+ int32 value_int32_int32 = message_int32_int32.GetReflection()->GetInt32(
+ message_int32_int32, fd_map_int32_in32_value);
+ EXPECT_EQ(value_int32_int32, Func(key_int32_int32, 1));
+
+ const Message& message_int32_double = mf_int32_double.Get(i);
+ int32 key_int32_double = message_int32_double.GetReflection()->GetInt32(
+ message_int32_double, fd_map_int32_double_key);
+ double value_int32_double =
+ message_int32_double.GetReflection()->GetDouble(
+ message_int32_double, fd_map_int32_double_value);
+ EXPECT_EQ(value_int32_double, Func(key_int32_double, 2));
+
+ const Message& message_string_string = mf_string_string.Get(i);
+ std::string key_string_string =
+ message_string_string.GetReflection()->GetString(
+ message_string_string, fd_map_string_string_key);
+ std::string value_string_string =
+ message_string_string.GetReflection()->GetString(
+ message_string_string, fd_map_string_string_value);
+ EXPECT_EQ(value_string_string, StrFunc(Int(key_string_string), 5));
+
+ const Message& message_int32_message = mf_int32_foreign_message.Get(i);
+ int32 key_int32_message = message_int32_message.GetReflection()->GetInt32(
+ message_int32_message, fd_map_int32_foreign_message_key);
+ const ForeignMessage& value_int32_message =
+ down_cast<const ForeignMessage&>(
+ message_int32_message.GetReflection()->GetMessage(
+ message_int32_message, fd_map_int32_foreign_message_value));
+ EXPECT_EQ(value_int32_message.c(), Func(key_int32_message, 6));
+ }
+
+ {
+ // Check gets through mutable objects.
+ const Message& message_int32_int32 = mmf_int32_int32->Get(i);
+ int32 key_int32_int32 = message_int32_int32.GetReflection()->GetInt32(
+ message_int32_int32, fd_map_int32_in32_key);
+ int32 value_int32_int32 = message_int32_int32.GetReflection()->GetInt32(
+ message_int32_int32, fd_map_int32_in32_value);
+ EXPECT_EQ(value_int32_int32, Func(key_int32_int32, 1));
+
+ const Message& message_int32_double = mmf_int32_double->Get(i);
+ int32 key_int32_double = message_int32_double.GetReflection()->GetInt32(
+ message_int32_double, fd_map_int32_double_key);
+ double value_int32_double =
+ message_int32_double.GetReflection()->GetDouble(
+ message_int32_double, fd_map_int32_double_value);
+ EXPECT_EQ(value_int32_double, Func(key_int32_double, 2));
+
+ const Message& message_string_string = mmf_string_string->Get(i);
+ std::string key_string_string =
+ message_string_string.GetReflection()->GetString(
+ message_string_string, fd_map_string_string_key);
+ std::string value_string_string =
+ message_string_string.GetReflection()->GetString(
+ message_string_string, fd_map_string_string_value);
+ EXPECT_EQ(value_string_string, StrFunc(Int(key_string_string), 5));
+
+ const Message& message_int32_message = mmf_int32_foreign_message->Get(i);
+ int32 key_int32_message = message_int32_message.GetReflection()->GetInt32(
+ message_int32_message, fd_map_int32_foreign_message_key);
+ const ForeignMessage& value_int32_message =
+ down_cast<const ForeignMessage&>(
+ message_int32_message.GetReflection()->GetMessage(
+ message_int32_message, fd_map_int32_foreign_message_value));
+ EXPECT_EQ(value_int32_message.c(), Func(key_int32_message, 6));
+ }
+ }
+
+ // Do sets through the RepeatedPtrField objects.
+ for (int i = 0; i < 10; i++) {
+ {
+ Message* message_int32_int32 = mmf_int32_int32->Mutable(i);
+ int32 key_int32_int32 = message_int32_int32->GetReflection()->GetInt32(
+ *message_int32_int32, fd_map_int32_in32_key);
+ message_int32_int32->GetReflection()->SetInt32(message_int32_int32,
+ fd_map_int32_in32_value,
+ Func(key_int32_int32, -1));
+
+ Message* message_int32_double = mmf_int32_double->Mutable(i);
+ int32 key_int32_double = message_int32_double->GetReflection()->GetInt32(
+ *message_int32_double, fd_map_int32_double_key);
+ message_int32_double->GetReflection()->SetDouble(
+ message_int32_double, fd_map_int32_double_value,
+ Func(key_int32_double, -2));
+
+ Message* message_string_string = mmf_string_string->Mutable(i);
+ std::string key_string_string =
+ message_string_string->GetReflection()->GetString(
+ *message_string_string, fd_map_string_string_key);
+ message_string_string->GetReflection()->SetString(
+ message_string_string, fd_map_string_string_value,
+ StrFunc(Int(key_string_string), -5));
+
+ Message* message_int32_message = mmf_int32_foreign_message->Mutable(i);
+ int32 key_int32_message =
+ message_int32_message->GetReflection()->GetInt32(
+ *message_int32_message, fd_map_int32_foreign_message_key);
+ ForeignMessage* value_int32_message = down_cast<ForeignMessage*>(
+ message_int32_message->GetReflection()->MutableMessage(
+ message_int32_message, fd_map_int32_foreign_message_value));
+ value_int32_message->set_c(Func(key_int32_message, -6));
+ }
+ }
+
+ // Check gets through mutable objects.
+ for (int i = 0; i < 10; i++) {
+ EXPECT_EQ(Func(i, -1), message.map_int32_int32().at(i));
+ EXPECT_EQ(Func(i, -2), message.map_int32_double().at(i));
+ EXPECT_EQ(StrFunc(i, -5), message.map_string_string().at(StrFunc(i, 1)));
+ EXPECT_EQ(Func(i, -6), message.map_int32_foreign_message().at(i).c());
+ }
+}
+
+TEST_F(MapFieldReflectionTest, RepeatedFieldRefForRegularFields) {
+ TestMap message;
+ const Reflection* refl = message.GetReflection();
+ const Descriptor* desc = message.GetDescriptor();
+
+ Map<int32, int32>* map_int32_int32 = message.mutable_map_int32_int32();
+ Map<int32, double>* map_int32_double = message.mutable_map_int32_double();
+ Map<std::string, std::string>* map_string_string =
+ message.mutable_map_string_string();
+ Map<int32, ForeignMessage>* map_int32_foreign_message =
+ message.mutable_map_int32_foreign_message();
+
+ for (int i = 0; i < 10; ++i) {
+ (*map_int32_int32)[i] = Func(i, 1);
+ (*map_int32_double)[i] = Func(i, 2);
+ (*map_string_string)[StrFunc(i, 1)] = StrFunc(i, 5);
+ (*map_int32_foreign_message)[i].set_c(Func(i, 6));
+ }
+
+ // Get FieldDescriptors for all the fields of interest.
+ const FieldDescriptor* fd_map_int32_int32 =
+ desc->FindFieldByName("map_int32_int32");
+ const FieldDescriptor* fd_map_int32_double =
+ desc->FindFieldByName("map_int32_double");
+ const FieldDescriptor* fd_map_string_string =
+ desc->FindFieldByName("map_string_string");
+ const FieldDescriptor* fd_map_int32_foreign_message =
+ desc->FindFieldByName("map_int32_foreign_message");
+
+ const FieldDescriptor* fd_map_int32_in32_key =
+ fd_map_int32_int32->message_type()->FindFieldByName("key");
+ const FieldDescriptor* fd_map_int32_in32_value =
+ fd_map_int32_int32->message_type()->FindFieldByName("value");
+ const FieldDescriptor* fd_map_int32_double_key =
+ fd_map_int32_double->message_type()->FindFieldByName("key");
+ const FieldDescriptor* fd_map_int32_double_value =
+ fd_map_int32_double->message_type()->FindFieldByName("value");
+ const FieldDescriptor* fd_map_string_string_key =
+ fd_map_string_string->message_type()->FindFieldByName("key");
+ const FieldDescriptor* fd_map_string_string_value =
+ fd_map_string_string->message_type()->FindFieldByName("value");
+ const FieldDescriptor* fd_map_int32_foreign_message_key =
+ fd_map_int32_foreign_message->message_type()->FindFieldByName("key");
+ const FieldDescriptor* fd_map_int32_foreign_message_value =
+ fd_map_int32_foreign_message->message_type()->FindFieldByName("value");
+
+ // Get RepeatedFieldRef objects for all fields of interest.
+ const RepeatedFieldRef<Message> mf_int32_int32 =
+ refl->GetRepeatedFieldRef<Message>(message, fd_map_int32_int32);
+ const RepeatedFieldRef<Message> mf_int32_double =
+ refl->GetRepeatedFieldRef<Message>(message, fd_map_int32_double);
+ const RepeatedFieldRef<Message> mf_string_string =
+ refl->GetRepeatedFieldRef<Message>(message, fd_map_string_string);
+ const RepeatedFieldRef<Message> mf_int32_foreign_message =
+ refl->GetRepeatedFieldRef<Message>(message, fd_map_int32_foreign_message);
+
+ // Get mutable RepeatedFieldRef objects for all fields of interest.
+ const MutableRepeatedFieldRef<Message> mmf_int32_int32 =
+ refl->GetMutableRepeatedFieldRef<Message>(&message, fd_map_int32_int32);
+ const MutableRepeatedFieldRef<Message> mmf_int32_double =
+ refl->GetMutableRepeatedFieldRef<Message>(&message, fd_map_int32_double);
+ const MutableRepeatedFieldRef<Message> mmf_string_string =
+ refl->GetMutableRepeatedFieldRef<Message>(&message, fd_map_string_string);
+ const MutableRepeatedFieldRef<Message> mmf_int32_foreign_message =
+ refl->GetMutableRepeatedFieldRef<Message>(&message,
+ fd_map_int32_foreign_message);
+
+ // Get entry default instances
+ std::unique_ptr<Message> entry_int32_int32(
+ MessageFactory::generated_factory()
+ ->GetPrototype(fd_map_int32_int32->message_type())
+ ->New(message.GetArena()));
+ std::unique_ptr<Message> entry_int32_double(
+ MessageFactory::generated_factory()
+ ->GetPrototype(fd_map_int32_double->message_type())
+ ->New(message.GetArena()));
+ std::unique_ptr<Message> entry_string_string(
+ MessageFactory::generated_factory()
+ ->GetPrototype(fd_map_string_string->message_type())
+ ->New(message.GetArena()));
+ std::unique_ptr<Message> entry_int32_foreign_message(
+ MessageFactory::generated_factory()
+ ->GetPrototype(fd_map_int32_foreign_message->message_type())
+ ->New(message.GetArena()));
+
+ EXPECT_EQ(10, mf_int32_int32.size());
+ EXPECT_EQ(10, mmf_int32_int32.size());
+ EXPECT_EQ(10, mf_int32_double.size());
+ EXPECT_EQ(10, mmf_int32_double.size());
+ EXPECT_EQ(10, mf_string_string.size());
+ EXPECT_EQ(10, mmf_string_string.size());
+ EXPECT_EQ(10, mf_int32_foreign_message.size());
+ EXPECT_EQ(10, mmf_int32_foreign_message.size());
+
+ EXPECT_FALSE(mf_int32_int32.empty());
+ EXPECT_FALSE(mmf_int32_int32.empty());
+ EXPECT_FALSE(mf_int32_double.empty());
+ EXPECT_FALSE(mmf_int32_double.empty());
+ EXPECT_FALSE(mf_string_string.empty());
+ EXPECT_FALSE(mmf_string_string.empty());
+ EXPECT_FALSE(mf_int32_foreign_message.empty());
+ EXPECT_FALSE(mmf_int32_foreign_message.empty());
+
+ // Make sure we can do gets through the RepeatedFieldRef objects.
+ for (int i = 0; i < 10; ++i) {
+ {
+ // Check gets through const objects.
+ const Message& message_int32_int32 =
+ mf_int32_int32.Get(i, entry_int32_int32.get());
+ int32 key_int32_int32 = message_int32_int32.GetReflection()->GetInt32(
+ message_int32_int32, fd_map_int32_in32_key);
+ int32 value_int32_int32 = message_int32_int32.GetReflection()->GetInt32(
+ message_int32_int32, fd_map_int32_in32_value);
+ EXPECT_EQ(value_int32_int32, Func(key_int32_int32, 1));
+
+ const Message& message_int32_double =
+ mf_int32_double.Get(i, entry_int32_double.get());
+ int32 key_int32_double = message_int32_double.GetReflection()->GetInt32(
+ message_int32_double, fd_map_int32_double_key);
+ double value_int32_double =
+ message_int32_double.GetReflection()->GetDouble(
+ message_int32_double, fd_map_int32_double_value);
+ EXPECT_EQ(value_int32_double, Func(key_int32_double, 2));
+
+ const Message& message_string_string =
+ mf_string_string.Get(i, entry_string_string.get());
+ std::string key_string_string =
+ message_string_string.GetReflection()->GetString(
+ message_string_string, fd_map_string_string_key);
+ std::string value_string_string =
+ message_string_string.GetReflection()->GetString(
+ message_string_string, fd_map_string_string_value);
+ EXPECT_EQ(value_string_string, StrFunc(Int(key_string_string), 5));
+
+ const Message& message_int32_message =
+ mf_int32_foreign_message.Get(i, entry_int32_foreign_message.get());
+ int32 key_int32_message = message_int32_message.GetReflection()->GetInt32(
+ message_int32_message, fd_map_int32_foreign_message_key);
+ const ForeignMessage& value_int32_message =
+ down_cast<const ForeignMessage&>(
+ message_int32_message.GetReflection()->GetMessage(
+ message_int32_message, fd_map_int32_foreign_message_value));
+ EXPECT_EQ(value_int32_message.c(), Func(key_int32_message, 6));
+ }
+
+ {
+ // Check gets through mutable objects.
+ const Message& message_int32_int32 =
+ mmf_int32_int32.Get(i, entry_int32_int32.get());
+ int32 key_int32_int32 = message_int32_int32.GetReflection()->GetInt32(
+ message_int32_int32, fd_map_int32_in32_key);
+ int32 value_int32_int32 = message_int32_int32.GetReflection()->GetInt32(
+ message_int32_int32, fd_map_int32_in32_value);
+ EXPECT_EQ(value_int32_int32, Func(key_int32_int32, 1));
+
+ const Message& message_int32_double =
+ mmf_int32_double.Get(i, entry_int32_double.get());
+ int32 key_int32_double = message_int32_double.GetReflection()->GetInt32(
+ message_int32_double, fd_map_int32_double_key);
+ double value_int32_double =
+ message_int32_double.GetReflection()->GetDouble(
+ message_int32_double, fd_map_int32_double_value);
+ EXPECT_EQ(value_int32_double, Func(key_int32_double, 2));
+
+ const Message& message_string_string =
+ mmf_string_string.Get(i, entry_string_string.get());
+ std::string key_string_string =
+ message_string_string.GetReflection()->GetString(
+ message_string_string, fd_map_string_string_key);
+ std::string value_string_string =
+ message_string_string.GetReflection()->GetString(
+ message_string_string, fd_map_string_string_value);
+ EXPECT_EQ(value_string_string, StrFunc(Int(key_string_string), 5));
+
+ const Message& message_int32_message =
+ mmf_int32_foreign_message.Get(i, entry_int32_foreign_message.get());
+ int32 key_int32_message = message_int32_message.GetReflection()->GetInt32(
+ message_int32_message, fd_map_int32_foreign_message_key);
+ const ForeignMessage& value_int32_message =
+ down_cast<const ForeignMessage&>(
+ message_int32_message.GetReflection()->GetMessage(
+ message_int32_message, fd_map_int32_foreign_message_value));
+ EXPECT_EQ(value_int32_message.c(), Func(key_int32_message, 6));
+ }
+ }
+
+ // Make sure we can do sets through the RepeatedFieldRef objects.
+ for (int i = 0; i < 10; i++) {
+ const Message& message_int32_int32 =
+ mmf_int32_int32.Get(i, entry_int32_int32.get());
+ int key = message_int32_int32.GetReflection()->GetInt32(
+ message_int32_int32, fd_map_int32_in32_key);
+
+ entry_int32_int32->GetReflection()->SetInt32(
+ entry_int32_int32.get(), fd_map_int32_int32->message_type()->field(0),
+ key);
+ entry_int32_int32->GetReflection()->SetInt32(
+ entry_int32_int32.get(), fd_map_int32_int32->message_type()->field(1),
+ Func(key, -1));
+ entry_int32_double->GetReflection()->SetInt32(
+ entry_int32_double.get(), fd_map_int32_double->message_type()->field(0),
+ key);
+ entry_int32_double->GetReflection()->SetDouble(
+ entry_int32_double.get(), fd_map_int32_double->message_type()->field(1),
+ Func(key, -2));
+ entry_string_string->GetReflection()->SetString(
+ entry_string_string.get(),
+ fd_map_string_string->message_type()->field(0), StrFunc(key, 1));
+ entry_string_string->GetReflection()->SetString(
+ entry_string_string.get(),
+ fd_map_string_string->message_type()->field(1), StrFunc(key, -5));
+ entry_int32_foreign_message->GetReflection()->SetInt32(
+ entry_int32_foreign_message.get(),
+ fd_map_int32_foreign_message->message_type()->field(0), key);
+ Message* value_message =
+ entry_int32_foreign_message->GetReflection()->MutableMessage(
+ entry_int32_foreign_message.get(),
+ fd_map_int32_foreign_message->message_type()->field(1));
+ value_message->GetReflection()->SetInt32(
+ value_message, value_message->GetDescriptor()->FindFieldByName("c"),
+ Func(key, -6));
+
+ mmf_int32_int32.Set(i, *entry_int32_int32);
+ mmf_int32_double.Set(i, *entry_int32_double);
+ mmf_string_string.Set(i, *entry_string_string);
+ mmf_int32_foreign_message.Set(i, *entry_int32_foreign_message);
+ }
+
+ for (int i = 0; i < 10; i++) {
+ EXPECT_EQ(Func(i, -1), message.map_int32_int32().at(i));
+ EXPECT_EQ(Func(i, -2), message.map_int32_double().at(i));
+ EXPECT_EQ(StrFunc(i, -5), message.map_string_string().at(StrFunc(i, 1)));
+ EXPECT_EQ(Func(i, -6), message.map_int32_foreign_message().at(i).c());
+ }
+
+ // Test iterators.
+ {
+ int index = 0;
+ std::unordered_map<int32, int32> result;
+ for (RepeatedFieldRef<Message>::iterator it = mf_int32_int32.begin();
+ it != mf_int32_int32.end(); ++it) {
+ const Message& message = *it;
+ int32 key =
+ message.GetReflection()->GetInt32(message, fd_map_int32_in32_key);
+ int32 value =
+ message.GetReflection()->GetInt32(message, fd_map_int32_in32_value);
+ result[key] = value;
+ ++index;
+ }
+ EXPECT_EQ(10, index);
+ for (std::unordered_map<int32, int32>::const_iterator it = result.begin();
+ it != result.end(); ++it) {
+ EXPECT_EQ(message.map_int32_int32().at(it->first), it->second);
+ }
+ }
+
+ {
+ int index = 0;
+ std::unordered_map<int32, double> result;
+ for (RepeatedFieldRef<Message>::iterator it = mf_int32_double.begin();
+ it != mf_int32_double.end(); ++it) {
+ const Message& message = *it;
+ int32 key =
+ message.GetReflection()->GetInt32(message, fd_map_int32_double_key);
+ double value = message.GetReflection()->GetDouble(
+ message, fd_map_int32_double_value);
+ result[key] = value;
+ ++index;
+ }
+ EXPECT_EQ(10, index);
+ for (std::unordered_map<int32, double>::const_iterator it = result.begin();
+ it != result.end(); ++it) {
+ EXPECT_EQ(message.map_int32_double().at(it->first), it->second);
+ }
+ }
+
+ {
+ int index = 0;
+ std::unordered_map<std::string, std::string> result;
+ for (RepeatedFieldRef<Message>::iterator it = mf_string_string.begin();
+ it != mf_string_string.end(); ++it) {
+ const Message& message = *it;
+ std::string key =
+ message.GetReflection()->GetString(message, fd_map_string_string_key);
+ std::string value = message.GetReflection()->GetString(
+ message, fd_map_string_string_value);
+ result[key] = value;
+ ++index;
+ }
+ EXPECT_EQ(10, index);
+ for (std::unordered_map<std::string, std::string>::const_iterator it =
+ result.begin();
+ it != result.end(); ++it) {
+ EXPECT_EQ(message.map_string_string().at(it->first), it->second);
+ }
+ }
+
+ {
+ int index = 0;
+ std::map<int32, ForeignMessage> result;
+ for (RepeatedFieldRef<Message>::iterator it =
+ mf_int32_foreign_message.begin();
+ it != mf_int32_foreign_message.end(); ++it) {
+ const Message& message = *it;
+ int32 key = message.GetReflection()->GetInt32(
+ message, fd_map_int32_foreign_message_key);
+ const ForeignMessage& sub_message =
+ down_cast<const ForeignMessage&>(message.GetReflection()->GetMessage(
+ message, fd_map_int32_foreign_message_value));
+ result[key].MergeFrom(sub_message);
+ ++index;
+ }
+ EXPECT_EQ(10, index);
+ for (std::map<int32, ForeignMessage>::const_iterator it = result.begin();
+ it != result.end(); ++it) {
+ EXPECT_EQ(message.map_int32_foreign_message().at(it->first).c(),
+ it->second.c());
+ }
+ }
+
+ // Test MutableRepeatedFieldRef::Add()
+ entry_int32_int32->GetReflection()->SetInt32(
+ entry_int32_int32.get(), fd_map_int32_int32->message_type()->field(0),
+ 4321);
+ entry_int32_int32->GetReflection()->SetInt32(
+ entry_int32_int32.get(), fd_map_int32_int32->message_type()->field(1),
+ 1234);
+ mmf_int32_int32.Add(*entry_int32_int32);
+ EXPECT_EQ(1234, message.map_int32_int32().at(4321));
+
+ entry_int32_double->GetReflection()->SetInt32(
+ entry_int32_double.get(), fd_map_int32_double->message_type()->field(0),
+ 4321);
+ entry_int32_double->GetReflection()->SetDouble(
+ entry_int32_double.get(), fd_map_int32_double->message_type()->field(1),
+ 1234.0);
+ mmf_int32_double.Add(*entry_int32_double);
+ EXPECT_EQ(1234.0, message.map_int32_double().at(4321));
+
+ entry_string_string->GetReflection()->SetString(
+ entry_string_string.get(), fd_map_string_string->message_type()->field(0),
+ "4321");
+ entry_string_string->GetReflection()->SetString(
+ entry_string_string.get(), fd_map_string_string->message_type()->field(1),
+ "1234");
+ mmf_string_string.Add(*entry_string_string);
+ EXPECT_EQ("1234", message.map_string_string().at("4321"));
+
+ entry_int32_foreign_message->GetReflection()->SetInt32(
+ entry_int32_foreign_message.get(),
+ fd_map_int32_foreign_message->message_type()->field(0), 4321);
+ Message* value_message =
+ entry_int32_foreign_message->GetReflection()->MutableMessage(
+ entry_int32_foreign_message.get(),
+ fd_map_int32_foreign_message->message_type()->field(1));
+ ForeignMessage foreign_message;
+ foreign_message.set_c(1234);
+ value_message->CopyFrom(foreign_message);
+
+ mmf_int32_foreign_message.Add(*entry_int32_foreign_message);
+ EXPECT_EQ(1234, message.map_int32_foreign_message().at(4321).c());
+
+ // Test Reflection::AddAllocatedMessage
+ Message* free_entry_string_string =
+ MessageFactory::generated_factory()
+ ->GetPrototype(fd_map_string_string->message_type())
+ ->New();
+ entry_string_string->GetReflection()->SetString(
+ free_entry_string_string, fd_map_string_string->message_type()->field(0),
+ "4321");
+ entry_string_string->GetReflection()->SetString(
+ free_entry_string_string, fd_map_string_string->message_type()->field(1),
+ "1234");
+ refl->AddAllocatedMessage(&message, fd_map_string_string,
+ free_entry_string_string);
+
+ // Test MutableRepeatedFieldRef::RemoveLast()
+ mmf_int32_int32.RemoveLast();
+ mmf_int32_double.RemoveLast();
+ mmf_string_string.RemoveLast();
+ mmf_int32_foreign_message.RemoveLast();
+ EXPECT_EQ(10, message.map_int32_int32().size());
+ EXPECT_EQ(10, message.map_int32_double().size());
+ EXPECT_EQ(11, message.map_string_string().size());
+ EXPECT_EQ(10, message.map_int32_foreign_message().size());
+
+ // Test MutableRepeatedFieldRef::SwapElements()
+ {
+ const Message& message0a = mmf_int32_int32.Get(0, entry_int32_int32.get());
+ int32 int32_value0a =
+ message0a.GetReflection()->GetInt32(message0a, fd_map_int32_in32_value);
+ const Message& message9a = mmf_int32_int32.Get(9, entry_int32_int32.get());
+ int32 int32_value9a =
+ message9a.GetReflection()->GetInt32(message9a, fd_map_int32_in32_value);
+
+ mmf_int32_int32.SwapElements(0, 9);
+
+ const Message& message0b = mmf_int32_int32.Get(0, entry_int32_int32.get());
+ int32 int32_value0b =
+ message0b.GetReflection()->GetInt32(message0b, fd_map_int32_in32_value);
+ const Message& message9b = mmf_int32_int32.Get(9, entry_int32_int32.get());
+ int32 int32_value9b =
+ message9b.GetReflection()->GetInt32(message9b, fd_map_int32_in32_value);
+
+ EXPECT_EQ(int32_value9a, int32_value0b);
+ EXPECT_EQ(int32_value0a, int32_value9b);
+ }
+
+ {
+ const Message& message0a =
+ mmf_int32_double.Get(0, entry_int32_double.get());
+ double double_value0a = message0a.GetReflection()->GetDouble(
+ message0a, fd_map_int32_double_value);
+ const Message& message9a =
+ mmf_int32_double.Get(9, entry_int32_double.get());
+ double double_value9a = message9a.GetReflection()->GetDouble(
+ message9a, fd_map_int32_double_value);
+
+ mmf_int32_double.SwapElements(0, 9);
+
+ const Message& message0b =
+ mmf_int32_double.Get(0, entry_int32_double.get());
+ double double_value0b = message0b.GetReflection()->GetDouble(
+ message0b, fd_map_int32_double_value);
+ const Message& message9b =
+ mmf_int32_double.Get(9, entry_int32_double.get());
+ double double_value9b = message9b.GetReflection()->GetDouble(
+ message9b, fd_map_int32_double_value);
+
+ EXPECT_EQ(double_value9a, double_value0b);
+ EXPECT_EQ(double_value0a, double_value9b);
+ }
+
+ {
+ const Message& message0a =
+ mmf_string_string.Get(0, entry_string_string.get());
+ std::string string_value0a = message0a.GetReflection()->GetString(
+ message0a, fd_map_string_string_value);
+ const Message& message9a =
+ mmf_string_string.Get(9, entry_string_string.get());
+ std::string string_value9a = message9a.GetReflection()->GetString(
+ message9a, fd_map_string_string_value);
+
+ mmf_string_string.SwapElements(0, 9);
+
+ const Message& message0b =
+ mmf_string_string.Get(0, entry_string_string.get());
+ std::string string_value0b = message0b.GetReflection()->GetString(
+ message0b, fd_map_string_string_value);
+ const Message& message9b =
+ mmf_string_string.Get(9, entry_string_string.get());
+ std::string string_value9b = message9b.GetReflection()->GetString(
+ message9b, fd_map_string_string_value);
+
+ EXPECT_EQ(string_value9a, string_value0b);
+ EXPECT_EQ(string_value0a, string_value9b);
+ }
+
+ {
+ const Message& message0a =
+ mmf_int32_foreign_message.Get(0, entry_int32_foreign_message.get());
+ const ForeignMessage& sub_message0a =
+ down_cast<const ForeignMessage&>(message0a.GetReflection()->GetMessage(
+ message0a, fd_map_int32_foreign_message_value));
+ int32 int32_value0a = sub_message0a.c();
+ const Message& message9a =
+ mmf_int32_foreign_message.Get(9, entry_int32_foreign_message.get());
+ const ForeignMessage& sub_message9a =
+ down_cast<const ForeignMessage&>(message9a.GetReflection()->GetMessage(
+ message9a, fd_map_int32_foreign_message_value));
+ int32 int32_value9a = sub_message9a.c();
+
+ mmf_int32_foreign_message.SwapElements(0, 9);
+
+ const Message& message0b =
+ mmf_int32_foreign_message.Get(0, entry_int32_foreign_message.get());
+ const ForeignMessage& sub_message0b =
+ down_cast<const ForeignMessage&>(message0b.GetReflection()->GetMessage(
+ message0b, fd_map_int32_foreign_message_value));
+ int32 int32_value0b = sub_message0b.c();
+ const Message& message9b =
+ mmf_int32_foreign_message.Get(9, entry_int32_foreign_message.get());
+ const ForeignMessage& sub_message9b =
+ down_cast<const ForeignMessage&>(message9b.GetReflection()->GetMessage(
+ message9b, fd_map_int32_foreign_message_value));
+ int32 int32_value9b = sub_message9b.c();
+
+ EXPECT_EQ(int32_value9a, int32_value0b);
+ EXPECT_EQ(int32_value0a, int32_value9b);
+ }
+
+ // TODO(b/181148674): After supporting arena agnostic delete or let map entry
+ // handle heap allocation, this could be removed.
+ if (message.GetArena() != nullptr) {
+ entry_int32_int32.release();
+ entry_int32_double.release();
+ entry_string_string.release();
+ entry_int32_foreign_message.release();
+ }
+}
+
+TEST_F(MapFieldReflectionTest, RepeatedFieldRefMergeFromAndSwap) {
+ // Set-up message content.
+ TestMap m0, m1, m2;
+ for (int i = 0; i < 10; ++i) {
+ (*m0.mutable_map_int32_int32())[i] = Func(i, 1);
+ (*m0.mutable_map_int32_double())[i] = Func(i, 2);
+ (*m0.mutable_map_string_string())[StrFunc(i, 1)] = StrFunc(i, 5);
+ (*m0.mutable_map_int32_foreign_message())[i].set_c(Func(i, 6));
+ (*m1.mutable_map_int32_int32())[i + 10] = Func(i, 11);
+ (*m1.mutable_map_int32_double())[i + 10] = Func(i, 12);
+ (*m1.mutable_map_string_string())[StrFunc(i + 10, 1)] = StrFunc(i, 15);
+ (*m1.mutable_map_int32_foreign_message())[i + 10].set_c(Func(i, 16));
+ (*m2.mutable_map_int32_int32())[i + 20] = Func(i, 21);
+ (*m2.mutable_map_int32_double())[i + 20] = Func(i, 22);
+ (*m2.mutable_map_string_string())[StrFunc(i + 20, 1)] = StrFunc(i, 25);
+ (*m2.mutable_map_int32_foreign_message())[i + 20].set_c(Func(i, 26));
+ }
+
+ const Reflection* refl = m0.GetReflection();
+ const Descriptor* desc = m0.GetDescriptor();
+
+ // Get FieldDescriptors for all the fields of interest.
+ const FieldDescriptor* fd_map_int32_int32 =
+ desc->FindFieldByName("map_int32_int32");
+ const FieldDescriptor* fd_map_int32_double =
+ desc->FindFieldByName("map_int32_double");
+ const FieldDescriptor* fd_map_string_string =
+ desc->FindFieldByName("map_string_string");
+ const FieldDescriptor* fd_map_int32_foreign_message =
+ desc->FindFieldByName("map_int32_foreign_message");
+
+ // Get MutableRepeatedFieldRef objects for all fields of interest.
+ const MutableRepeatedFieldRef<Message> mmf_int32_int32 =
+ refl->GetMutableRepeatedFieldRef<Message>(&m0, fd_map_int32_int32);
+ const MutableRepeatedFieldRef<Message> mmf_int32_double =
+ refl->GetMutableRepeatedFieldRef<Message>(&m0, fd_map_int32_double);
+ const MutableRepeatedFieldRef<Message> mmf_string_string =
+ refl->GetMutableRepeatedFieldRef<Message>(&m0, fd_map_string_string);
+ const MutableRepeatedFieldRef<Message> mmf_int32_foreign_message =
+ refl->GetMutableRepeatedFieldRef<Message>(&m0,
+ fd_map_int32_foreign_message);
+
+ // Test MutableRepeatedRef::CopyFrom
+ mmf_int32_int32.CopyFrom(
+ refl->GetRepeatedFieldRef<Message>(m1, fd_map_int32_int32));
+ mmf_int32_double.CopyFrom(
+ refl->GetRepeatedFieldRef<Message>(m1, fd_map_int32_double));
+ mmf_string_string.CopyFrom(
+ refl->GetRepeatedFieldRef<Message>(m1, fd_map_string_string));
+ mmf_int32_foreign_message.CopyFrom(
+ refl->GetRepeatedFieldRef<Message>(m1, fd_map_int32_foreign_message));
+
+ for (int i = 0; i < 10; ++i) {
+ EXPECT_EQ(Func(i, 11), m0.map_int32_int32().at(i + 10));
+ EXPECT_EQ(Func(i, 12), m0.map_int32_double().at(i + 10));
+ EXPECT_EQ(StrFunc(i, 15), m0.map_string_string().at(StrFunc(i + 10, 1)));
+ EXPECT_EQ(Func(i, 16), m0.map_int32_foreign_message().at(i + 10).c());
+ }
+
+ // Test MutableRepeatedRef::MergeFrom
+ mmf_int32_int32.MergeFrom(
+ refl->GetRepeatedFieldRef<Message>(m2, fd_map_int32_int32));
+ mmf_int32_double.MergeFrom(
+ refl->GetRepeatedFieldRef<Message>(m2, fd_map_int32_double));
+ mmf_string_string.MergeFrom(
+ refl->GetRepeatedFieldRef<Message>(m2, fd_map_string_string));
+ mmf_int32_foreign_message.MergeFrom(
+ refl->GetRepeatedFieldRef<Message>(m2, fd_map_int32_foreign_message));
+ for (int i = 0; i < 10; ++i) {
+ EXPECT_EQ(Func(i, 21), m0.map_int32_int32().at(i + 20));
+ EXPECT_EQ(Func(i, 22), m0.map_int32_double().at(i + 20));
+ EXPECT_EQ(StrFunc(i, 25), m0.map_string_string().at(StrFunc(i + 20, 1)));
+ EXPECT_EQ(Func(i, 26), m0.map_int32_foreign_message().at(i + 20).c());
+ }
+
+ // Test MutableRepeatedRef::Swap
+ // Swap between m0 and m2.
+ mmf_int32_int32.Swap(
+ refl->GetMutableRepeatedFieldRef<Message>(&m2, fd_map_int32_int32));
+ mmf_int32_double.Swap(
+ refl->GetMutableRepeatedFieldRef<Message>(&m2, fd_map_int32_double));
+ mmf_string_string.Swap(
+ refl->GetMutableRepeatedFieldRef<Message>(&m2, fd_map_string_string));
+ mmf_int32_foreign_message.Swap(refl->GetMutableRepeatedFieldRef<Message>(
+ &m2, fd_map_int32_foreign_message));
+ for (int i = 0; i < 10; ++i) {
+ // Check the content of m0.
+ EXPECT_EQ(Func(i, 21), m0.map_int32_int32().at(i + 20));
+ EXPECT_EQ(Func(i, 22), m0.map_int32_double().at(i + 20));
+ EXPECT_EQ(StrFunc(i, 25), m0.map_string_string().at(StrFunc(i + 20, 1)));
+ EXPECT_EQ(Func(i, 26), m0.map_int32_foreign_message().at(i + 20).c());
+
+ // Check the content of m2.
+ EXPECT_EQ(Func(i, 11), m2.map_int32_int32().at(i + 10));
+ EXPECT_EQ(Func(i, 12), m2.map_int32_double().at(i + 10));
+ EXPECT_EQ(StrFunc(i, 15), m2.map_string_string().at(StrFunc(i + 10, 1)));
+ EXPECT_EQ(Func(i, 16), m2.map_int32_foreign_message().at(i + 10).c());
+ EXPECT_EQ(Func(i, 21), m2.map_int32_int32().at(i + 20));
+ EXPECT_EQ(Func(i, 22), m2.map_int32_double().at(i + 20));
+ EXPECT_EQ(StrFunc(i, 25), m2.map_string_string().at(StrFunc(i + 20, 1)));
+ EXPECT_EQ(Func(i, 26), m2.map_int32_foreign_message().at(i + 20).c());
+ }
+
+ // TODO(teboring): add test for duplicated key
+}
+
+TEST_F(MapFieldReflectionTest, MapSizeWithDuplicatedKey) {
+ // Dynamic Message
+ {
+ DynamicMessageFactory factory;
+ std::unique_ptr<Message> message(
+ factory.GetPrototype(UNITTEST::TestMap::descriptor())->New());
+ const Reflection* reflection = message->GetReflection();
+ const FieldDescriptor* field =
+ UNITTEST::TestMap::descriptor()->FindFieldByName("map_int32_int32");
+
+ Message* entry1 = reflection->AddMessage(message.get(), field);
+ Message* entry2 = reflection->AddMessage(message.get(), field);
+
+ const Reflection* entry_reflection = entry1->GetReflection();
+ const FieldDescriptor* key_field =
+ entry1->GetDescriptor()->FindFieldByName("key");
+ entry_reflection->SetInt32(entry1, key_field, 1);
+ entry_reflection->SetInt32(entry2, key_field, 1);
+
+ EXPECT_EQ(2, reflection->FieldSize(*message, field));
+ EXPECT_EQ(1, MapSize(reflection, field, *message));
+ EXPECT_EQ(2, reflection->FieldSize(*message, field));
+ }
+
+ // Generated Message
+ {
+ UNITTEST::TestMap message;
+ const Reflection* reflection = message.GetReflection();
+ const FieldDescriptor* field =
+ message.GetDescriptor()->FindFieldByName("map_int32_int32");
+
+ Message* entry1 = reflection->AddMessage(&message, field);
+ Message* entry2 = reflection->AddMessage(&message, field);
+
+ const Reflection* entry_reflection = entry1->GetReflection();
+ const FieldDescriptor* key_field =
+ entry1->GetDescriptor()->FindFieldByName("key");
+ entry_reflection->SetInt32(entry1, key_field, 1);
+ entry_reflection->SetInt32(entry2, key_field, 1);
+
+ EXPECT_EQ(2, reflection->FieldSize(message, field));
+ EXPECT_EQ(1, MapSize(reflection, field, message));
+ }
+}
+
+TEST_F(MapFieldReflectionTest, UninitializedEntry) {
+ UNITTEST::TestRequiredMessageMap message;
+ const Reflection* reflection = message.GetReflection();
+ const FieldDescriptor* field =
+ message.GetDescriptor()->FindFieldByName("map_field");
+ auto entry = reflection->AddMessage(&message, field);
+ EXPECT_FALSE(entry->IsInitialized());
+ EXPECT_FALSE(message.IsInitialized());
+}
+
+class MyMapEntry
+ : public internal::MapEntry<MyMapEntry, ::google::protobuf::int32, ::google::protobuf::int32,
+ internal::WireFormatLite::TYPE_INT32,
+ internal::WireFormatLite::TYPE_INT32> {
+ public:
+ constexpr MyMapEntry() {}
+ MyMapEntry(Arena*) { std::abort(); }
+ Metadata GetMetadata() const override { std::abort(); }
+ static bool ValidateKey(void*) { return true; }
+ static bool ValidateValue(void*) { return true; }
+};
+
+class MyMapEntryLite
+ : public internal::MapEntryLite<MyMapEntryLite, ::google::protobuf::int32, ::google::protobuf::int32,
+ internal::WireFormatLite::TYPE_INT32,
+ internal::WireFormatLite::TYPE_INT32> {
+ public:
+ constexpr MyMapEntryLite() {}
+ explicit MyMapEntryLite(Arena*) { std::abort(); }
+ static bool ValidateKey(void*) { return true; }
+ static bool ValidateValue(void*) { return true; }
+};
+
+TEST(MapEntryTest, ConstInit) {
+ // This verifies that `MapEntry`, `MapEntryLite` and `MapEntryImpl` can be
+ // constant initialized.
+ PROTOBUF_CONSTINIT static MyMapEntry entry{};
+ EXPECT_NE(entry.SpaceUsed(), 0);
+
+ PROTOBUF_CONSTINIT static MyMapEntryLite entry_lite{}; // NOLINT
+ EXPECT_TRUE(entry_lite.IsInitialized());
+}
+
+// Generated Message Test ===========================================
+
+TEST(GeneratedMapFieldTest, Accessors) {
+ UNITTEST::TestMap message;
+
+ MapTestUtil::SetMapFields(&message);
+ MapTestUtil::ExpectMapFieldsSet(message);
+
+ MapTestUtil::ModifyMapFields(&message);
+ MapTestUtil::ExpectMapFieldsModified(message);
+}
+
+TEST(GeneratedMapFieldTest, SetMapFieldsInitialized) {
+ UNITTEST::TestMap message;
+
+ MapTestUtil::SetMapFieldsInitialized(&message);
+ MapTestUtil::ExpectMapFieldsSetInitialized(message);
+}
+
+TEST(GeneratedMapFieldTest, Proto2SetMapFieldsInitialized) {
+ UNITTEST::TestEnumMap message;
+ EXPECT_EQ(UNITTEST::PROTO2_MAP_ENUM_FOO,
+ (*message.mutable_known_map_field())[0]);
+}
+
+TEST(GeneratedMapFieldTest, Clear) {
+ UNITTEST::TestMap message;
+
+ MapTestUtil::SetMapFields(&message);
+ message.Clear();
+ MapTestUtil::ExpectClear(message);
+}
+
+TEST(GeneratedMapFieldTest, ClearMessageMap) {
+ UNITTEST::TestMessageMap message;
+
+ // Creates a TestAllTypes with default value
+ TestUtil::ExpectClear((*message.mutable_map_int32_message())[0]);
+}
+
+TEST(GeneratedMapFieldTest, CopyFrom) {
+ UNITTEST::TestMap message1, message2;
+
+ MapTestUtil::SetMapFields(&message1);
+ message2.CopyFrom(message1);
+ MapTestUtil::ExpectMapFieldsSet(message2);
+
+ // Copying from self should be a no-op.
+ message2.CopyFrom(message2);
+ MapTestUtil::ExpectMapFieldsSet(message2);
+}
+
+TEST(GeneratedMapFieldTest, CopyFromMessageMap) {
+ UNITTEST::TestMessageMap message1, message2;
+
+ (*message1.mutable_map_int32_message())[0].add_repeated_int32(100);
+ (*message2.mutable_map_int32_message())[0].add_repeated_int32(101);
+
+ message1.CopyFrom(message2);
+
+ // Checks repeated field is overwritten.
+ EXPECT_EQ(1, message1.map_int32_message().at(0).repeated_int32_size());
+ EXPECT_EQ(101, message1.map_int32_message().at(0).repeated_int32(0));
+}
+
+TEST(GeneratedMapFieldTest, SwapWithEmpty) {
+ UNITTEST::TestMap message1, message2;
+
+ MapTestUtil::SetMapFields(&message1);
+ MapTestUtil::ExpectMapFieldsSet(message1);
+ MapTestUtil::ExpectClear(message2);
+
+ message1.Swap(&message2);
+ MapTestUtil::ExpectMapFieldsSet(message2);
+ MapTestUtil::ExpectClear(message1);
+}
+
+TEST(GeneratedMapFieldTest, SwapWithSelf) {
+ UNITTEST::TestMap message;
+
+ MapTestUtil::SetMapFields(&message);
+ MapTestUtil::ExpectMapFieldsSet(message);
+
+ message.Swap(&message);
+ MapTestUtil::ExpectMapFieldsSet(message);
+}
+
+TEST(GeneratedMapFieldTest, SwapWithOther) {
+ UNITTEST::TestMap message1, message2;
+
+ MapTestUtil::SetMapFields(&message1);
+ MapTestUtil::SetMapFields(&message2);
+ MapTestUtil::ModifyMapFields(&message2);
+
+ message1.Swap(&message2);
+ MapTestUtil::ExpectMapFieldsModified(message1);
+ MapTestUtil::ExpectMapFieldsSet(message2);
+}
+
+TEST(GeneratedMapFieldTest, CopyConstructor) {
+ UNITTEST::TestMap message1;
+ MapTestUtil::SetMapFields(&message1);
+
+ UNITTEST::TestMap message2(message1);
+ MapTestUtil::ExpectMapFieldsSet(message2);
+}
+
+TEST(GeneratedMapFieldTest, CopyAssignmentOperator) {
+ UNITTEST::TestMap message1;
+ MapTestUtil::SetMapFields(&message1);
+
+ UNITTEST::TestMap message2;
+ message2 = message1;
+ MapTestUtil::ExpectMapFieldsSet(message2);
+
+ // Make sure that self-assignment does something sane.
+ message2.operator=(message2);
+ MapTestUtil::ExpectMapFieldsSet(message2);
+}
+
+#if !defined(PROTOBUF_TEST_NO_DESCRIPTORS) || PROTOBUF_RTTI
+TEST(GeneratedMapFieldTest, UpcastCopyFrom) {
+ // Test the CopyFrom method that takes in the generic const Message&
+ // parameter.
+ UNITTEST::TestMap message1, message2;
+
+ MapTestUtil::SetMapFields(&message1);
+
+ const Message* source = implicit_cast<const Message*>(&message1);
+ message2.CopyFrom(*source);
+
+ MapTestUtil::ExpectMapFieldsSet(message2);
+}
+#endif
+
+#ifndef PROTOBUF_TEST_NO_DESCRIPTORS
+
+TEST(GeneratedMapFieldTest, CopyFromDynamicMessage) {
+ // Test copying from a DynamicMessage, which must fall back to using
+ // reflection.
+ UNITTEST::TestMap message2;
+
+ // Construct a new version of the dynamic message via the factory.
+ DynamicMessageFactory factory;
+ std::unique_ptr<Message> message1;
+ message1.reset(factory.GetPrototype(UNITTEST::TestMap::descriptor())->New());
+ MapReflectionTester reflection_tester(UNITTEST::TestMap::descriptor());
+ reflection_tester.SetMapFieldsViaReflection(message1.get());
+ reflection_tester.ExpectMapFieldsSetViaReflection(*message1);
+ reflection_tester.ExpectMapFieldsSetViaReflectionIterator(message1.get());
+ message2.CopyFrom(*message1);
+ MapTestUtil::ExpectMapFieldsSet(message2);
+}
+
+TEST(GeneratedMapFieldTest, CopyFromDynamicMessageMapReflection) {
+ UNITTEST::TestMap message2;
+
+ // Construct a new version of the dynamic message via the factory.
+ DynamicMessageFactory factory;
+ std::unique_ptr<Message> message1;
+ message1.reset(factory.GetPrototype(UNITTEST::TestMap::descriptor())->New());
+ MapReflectionTester reflection_tester(UNITTEST::TestMap::descriptor());
+ reflection_tester.SetMapFieldsViaMapReflection(message1.get());
+ reflection_tester.ExpectMapFieldsSetViaReflection(*message1);
+ reflection_tester.ExpectMapFieldsSetViaReflectionIterator(message1.get());
+ message2.CopyFrom(*message1);
+ MapTestUtil::ExpectMapFieldsSet(message2);
+}
+
+TEST(GeneratedMapFieldTest, DynamicMessageMergeFromDynamicMessage) {
+ // Construct two dynamic message and sets via map reflection.
+ DynamicMessageFactory factory;
+ std::unique_ptr<Message> message1;
+ message1.reset(factory.GetPrototype(UNITTEST::TestMap::descriptor())->New());
+ MapReflectionTester reflection_tester(UNITTEST::TestMap::descriptor());
+ reflection_tester.SetMapFieldsViaMapReflection(message1.get());
+
+ // message2 is created by same factory.
+ std::unique_ptr<Message> message2;
+ message2.reset(factory.GetPrototype(UNITTEST::TestMap::descriptor())->New());
+ reflection_tester.SetMapFieldsViaMapReflection(message2.get());
+
+ // message3 is created by different factory.
+ DynamicMessageFactory factory3;
+ std::unique_ptr<Message> message3;
+ message3.reset(factory3.GetPrototype(UNITTEST::TestMap::descriptor())->New());
+ reflection_tester.SetMapFieldsViaMapReflection(message3.get());
+
+ message2->MergeFrom(*message1);
+ message3->MergeFrom(*message1);
+
+ // Test MergeFrom does not sync to repeated fields and
+ // there is no duplicate keys in text format.
+ std::string output1, output2, output3;
+ TextFormat::PrintToString(*message1, &output1);
+ TextFormat::PrintToString(*message2, &output2);
+ TextFormat::PrintToString(*message3, &output3);
+ EXPECT_EQ(output1, output2);
+ EXPECT_EQ(output1, output3);
+}
+
+TEST(GeneratedMapFieldTest, DynamicMessageCopyFrom) {
+ // Test copying to a DynamicMessage, which must fall back to using reflection.
+ UNITTEST::TestMap message2;
+ MapTestUtil::SetMapFields(&message2);
+
+ // Construct a new version of the dynamic message via the factory.
+ DynamicMessageFactory factory;
+ std::unique_ptr<Message> message1;
+ message1.reset(factory.GetPrototype(UNITTEST::TestMap::descriptor())->New());
+
+ MapReflectionTester reflection_tester(UNITTEST::TestMap::descriptor());
+ message1->MergeFrom(message2);
+ reflection_tester.ExpectMapFieldsSetViaReflection(*message1);
+ reflection_tester.ExpectMapFieldsSetViaReflectionIterator(message1.get());
+}
+
+TEST(GeneratedMapFieldTest, DynamicMessageCopyFromMapReflection) {
+ MapReflectionTester reflection_tester(UNITTEST::TestMap::descriptor());
+ UNITTEST::TestMap message2;
+ reflection_tester.SetMapFieldsViaMapReflection(&message2);
+
+ // Construct a dynamic message via the factory.
+ DynamicMessageFactory factory;
+ std::unique_ptr<Message> message1;
+ message1.reset(factory.GetPrototype(UNITTEST::TestMap::descriptor())->New());
+
+ message1->MergeFrom(message2);
+ reflection_tester.ExpectMapFieldsSetViaReflectionIterator(message1.get());
+ reflection_tester.ExpectMapFieldsSetViaReflection(*message1);
+}
+
+TEST(GeneratedMapFieldTest, SyncDynamicMapWithRepeatedField) {
+ // Construct a dynamic message via the factory.
+ MapReflectionTester reflection_tester(UNITTEST::TestMap::descriptor());
+ DynamicMessageFactory factory;
+ std::unique_ptr<Message> message;
+ message.reset(factory.GetPrototype(UNITTEST::TestMap::descriptor())->New());
+ reflection_tester.SetMapFieldsViaReflection(message.get());
+ reflection_tester.ExpectMapFieldsSetViaReflectionIterator(message.get());
+ reflection_tester.ExpectMapFieldsSetViaReflection(*message);
+}
+
+#endif // !PROTOBUF_TEST_NO_DESCRIPTORS
+
+TEST(GeneratedMapFieldTest, NonEmptyMergeFrom) {
+ UNITTEST::TestMap message1, message2;
+
+ MapTestUtil::SetMapFields(&message1);
+
+ // This field will test merging into an empty spot.
+ (*message2.mutable_map_int32_int32())[1] = 1;
+ message1.mutable_map_int32_int32()->erase(1);
+
+ // This tests overwriting.
+ (*message2.mutable_map_int32_double())[1] = 1;
+ (*message1.mutable_map_int32_double())[1] = 2;
+
+ message1.MergeFrom(message2);
+ MapTestUtil::ExpectMapFieldsSet(message1);
+
+ // Test reflection MergeFrom does not sync to repeated field
+ // and there is no duplicated keys.
+ MapTestUtil::SetMapFields(&message1);
+ MapTestUtil::SetMapFields(&message2);
+
+ message2.MergeFrom(message1);
+
+ std::string output1, output2;
+ TextFormat::PrintToString(message1, &output1);
+ TextFormat::PrintToString(message2, &output2);
+ EXPECT_EQ(output1, output2);
+}
+
+TEST(GeneratedMapFieldTest, MergeFromMessageMap) {
+ UNITTEST::TestMessageMap message1, message2;
+
+ (*message1.mutable_map_int32_message())[0].add_repeated_int32(100);
+ (*message2.mutable_map_int32_message())[0].add_repeated_int32(101);
+
+ message1.MergeFrom(message2);
+
+ // Checks repeated field is overwritten.
+ EXPECT_EQ(1, message1.map_int32_message().at(0).repeated_int32_size());
+ EXPECT_EQ(101, message1.map_int32_message().at(0).repeated_int32(0));
+}
+
+// Test the generated SerializeWithCachedSizesToArray()
+TEST(GeneratedMapFieldTest, SerializationToArray) {
+ UNITTEST::TestMap message1, message2;
+ std::string data;
+ MapTestUtil::SetMapFields(&message1);
+ size_t size = message1.ByteSizeLong();
+ data.resize(size);
+ uint8* start = reinterpret_cast<uint8*>(::google::protobuf::string_as_array(&data));
+ uint8* end = message1.SerializeWithCachedSizesToArray(start);
+ EXPECT_EQ(size, end - start);
+ EXPECT_TRUE(message2.ParseFromString(data));
+ MapTestUtil::ExpectMapFieldsSet(message2);
+}
+
+// Test the generated SerializeWithCachedSizes()
+TEST(GeneratedMapFieldTest, SerializationToStream) {
+ UNITTEST::TestMap message1, message2;
+ MapTestUtil::SetMapFields(&message1);
+ size_t size = message1.ByteSizeLong();
+ std::string data;
+ data.resize(size);
+ {
+ // Allow the output stream to buffer only one byte at a time.
+ io::ArrayOutputStream array_stream(::google::protobuf::string_as_array(&data), size, 1);
+ io::CodedOutputStream output_stream(&array_stream);
+ message1.SerializeWithCachedSizes(&output_stream);
+ EXPECT_FALSE(output_stream.HadError());
+ EXPECT_EQ(size, output_stream.ByteCount());
+ }
+ EXPECT_TRUE(message2.ParseFromString(data));
+ MapTestUtil::ExpectMapFieldsSet(message2);
+}
+
+TEST(GeneratedMapFieldTest, ParseFailsIfMalformed) {
+ UNITTEST::TestMapSubmessage o, p;
+ auto m = o.mutable_test_map()->mutable_map_int32_foreign_message();
+ (*m)[0].set_c(-1);
+ std::string serialized;
+ EXPECT_TRUE(o.SerializeToString(&serialized));
+
+ // Should parse correctly.
+ EXPECT_TRUE(p.ParseFromString(serialized));
+
+ // Overwriting the last byte to 0xFF results in malformed wire.
+ serialized[serialized.size() - 1] = 0xFF;
+ EXPECT_FALSE(p.ParseFromString(serialized));
+}
+
+
+TEST(GeneratedMapFieldTest, SameTypeMaps) {
+ const Descriptor* map1 = UNITTEST::TestSameTypeMap::descriptor()
+ ->FindFieldByName("map1")
+ ->message_type();
+ const Descriptor* map2 = UNITTEST::TestSameTypeMap::descriptor()
+ ->FindFieldByName("map2")
+ ->message_type();
+
+ const Message* map1_entry =
+ MessageFactory::generated_factory()->GetPrototype(map1);
+ const Message* map2_entry =
+ MessageFactory::generated_factory()->GetPrototype(map2);
+
+ EXPECT_EQ(map1, map1_entry->GetDescriptor());
+ EXPECT_EQ(map2, map2_entry->GetDescriptor());
+}
+
+TEST(GeneratedMapFieldTest, Proto2UnknownEnum) {
+ UNITTEST::TestEnumMapPlusExtra from;
+ (*from.mutable_known_map_field())[0] = UNITTEST::E_PROTO2_MAP_ENUM_FOO;
+ (*from.mutable_unknown_map_field())[0] = UNITTEST::E_PROTO2_MAP_ENUM_EXTRA;
+ std::string data;
+ from.SerializeToString(&data);
+
+ UNITTEST::TestEnumMap to;
+ EXPECT_TRUE(to.ParseFromString(data));
+ EXPECT_EQ(0, to.unknown_map_field().size());
+ const UnknownFieldSet& unknown_field_set =
+ to.GetReflection()->GetUnknownFields(to);
+ EXPECT_EQ(1, unknown_field_set.field_count());
+ EXPECT_EQ(1, to.known_map_field().size());
+ EXPECT_EQ(UNITTEST::PROTO2_MAP_ENUM_FOO, to.known_map_field().at(0));
+
+ data.clear();
+ from.Clear();
+ to.SerializeToString(&data);
+ EXPECT_TRUE(from.ParseFromString(data));
+ EXPECT_EQ(0, from.GetReflection()->GetUnknownFields(from).field_count());
+ EXPECT_EQ(1, from.known_map_field().size());
+ EXPECT_EQ(UNITTEST::E_PROTO2_MAP_ENUM_FOO, from.known_map_field().at(0));
+ EXPECT_EQ(1, from.unknown_map_field().size());
+ EXPECT_EQ(UNITTEST::E_PROTO2_MAP_ENUM_EXTRA, from.unknown_map_field().at(0));
+}
+
+TEST(GeneratedMapFieldTest, StandardWireFormat) {
+ UNITTEST::TestMap message;
+ std::string data = "\x0A\x04\x08\x01\x10\x01";
+
+ EXPECT_TRUE(message.ParseFromString(data));
+ EXPECT_EQ(1, message.map_int32_int32().size());
+ EXPECT_EQ(1, message.map_int32_int32().at(1));
+}
+
+TEST(GeneratedMapFieldTest, UnorderedWireFormat) {
+ UNITTEST::TestMap message;
+
+ // put value before key in wire format
+ std::string data = "\x0A\x04\x10\x01\x08\x02";
+
+ EXPECT_TRUE(message.ParseFromString(data));
+ EXPECT_EQ(1, message.map_int32_int32().size());
+ ASSERT_NE(message.map_int32_int32().find(2), message.map_int32_int32().end());
+ EXPECT_EQ(1, message.map_int32_int32().at(2));
+}
+
+TEST(GeneratedMapFieldTest, DuplicatedKeyWireFormat) {
+ UNITTEST::TestMap message;
+
+ // Two key fields in wire format
+ std::string data = "\x0A\x06\x08\x01\x08\x02\x10\x01";
+
+ EXPECT_TRUE(message.ParseFromString(data));
+ EXPECT_EQ(1, message.map_int32_int32().size());
+ EXPECT_EQ(1, message.map_int32_int32().at(2));
+
+ // A similar test, but with a map from int to a message type.
+ // Again, we want to be sure that the "second one wins" when
+ // there are two separate entries with the same key.
+ const int key = 99;
+ UNITTEST::TestRequiredMessageMap map_message;
+ UNITTEST::TestRequired with_dummy4;
+ with_dummy4.set_a(0);
+ with_dummy4.set_b(0);
+ with_dummy4.set_c(0);
+ with_dummy4.set_dummy4(11);
+ (*map_message.mutable_map_field())[key] = with_dummy4;
+ std::string s = map_message.SerializeAsString();
+ UNITTEST::TestRequired with_dummy5;
+ with_dummy5.set_a(0);
+ with_dummy5.set_b(0);
+ with_dummy5.set_c(0);
+ with_dummy5.set_dummy5(12);
+ (*map_message.mutable_map_field())[key] = with_dummy5;
+ std::string both = s + map_message.SerializeAsString();
+ // We don't expect a merge now. The "second one wins."
+ ASSERT_TRUE(map_message.ParseFromString(both));
+ ASSERT_EQ(1, map_message.map_field().size());
+ ASSERT_EQ(1, map_message.map_field().count(key));
+ EXPECT_EQ(0, map_message.map_field().find(key)->second.a());
+ EXPECT_EQ(0, map_message.map_field().find(key)->second.b());
+ EXPECT_EQ(0, map_message.map_field().find(key)->second.c());
+ EXPECT_FALSE(map_message.map_field().find(key)->second.has_dummy4());
+ ASSERT_TRUE(map_message.map_field().find(key)->second.has_dummy5());
+ EXPECT_EQ(12, map_message.map_field().find(key)->second.dummy5());
+}
+
+// Exhaustive combinations of keys, values, and junk in any order.
+// This re-tests some of the things tested above, but if it fails
+// it's more work to determine what went wrong, so it isn't necessarily
+// bad that we have the simpler tests too.
+TEST(GeneratedMapFieldTest, KeysValuesUnknownsWireFormat) {
+ UNITTEST::TestMap message;
+ const int kMaxNumKeysAndValuesAndJunk = 4;
+ const char kKeyTag = 0x08;
+ const char kValueTag = 0x10;
+ const char kJunkTag = 0x20;
+ for (int items = 0; items <= kMaxNumKeysAndValuesAndJunk; items++) {
+ std::string data = "\x0A";
+ // Encode length of what will follow.
+ data.push_back(items * 2);
+ static const int kBitsOfIPerItem = 4;
+ static const int mask = (1 << kBitsOfIPerItem) - 1;
+ // Each iteration of the following is a test. It uses i as bit vector
+ // encoding the keys and values to put in the wire format.
+ for (int i = 0; i < (1 << (items * kBitsOfIPerItem)); i++) {
+ std::string wire_format = data;
+ int expected_key = 0;
+ int expected_value = 0;
+ for (int k = i, j = 0; j < items; j++, k >>= kBitsOfIPerItem) {
+ bool is_key = k & 0x1;
+ bool is_value = !is_key && (k & 0x2);
+ wire_format.push_back(is_key ? kKeyTag
+ : is_value ? kValueTag : kJunkTag);
+ char c = static_cast<char>(k & mask) >> 2; // One char after the tag.
+ wire_format.push_back(c);
+ if (is_key) expected_key = static_cast<int>(c);
+ if (is_value) expected_value = static_cast<int>(c);
+ bool res = message.ParseFromString(wire_format);
+ bool expect_success = true;
+ // Unfortunately the old map parser accepts malformed input, the new
+ // parser accepts only correct input.
+ if (j != items - 1) expect_success = false;
+ if (expect_success) {
+ ASSERT_TRUE(res);
+ ASSERT_EQ(1, message.map_int32_int32().size());
+ ASSERT_EQ(expected_key, message.map_int32_int32().begin()->first);
+ ASSERT_EQ(expected_value, message.map_int32_int32().begin()->second);
+ } else {
+ ASSERT_FALSE(res);
+ }
+ }
+ }
+ }
+}
+
+TEST(GeneratedMapFieldTest, DuplicatedValueWireFormat) {
+ UNITTEST::TestMap message;
+
+ // Two value fields in wire format
+ std::string data = "\x0A\x06\x08\x01\x10\x01\x10\x02";
+
+ EXPECT_TRUE(message.ParseFromString(data));
+ EXPECT_EQ(1, message.map_int32_int32().size());
+ EXPECT_EQ(2, message.map_int32_int32().at(1));
+}
+
+TEST(GeneratedMapFieldTest, MissedKeyWireFormat) {
+ UNITTEST::TestMap message;
+
+ // No key field in wire format
+ std::string data = "\x0A\x02\x10\x01";
+
+ EXPECT_TRUE(message.ParseFromString(data));
+ EXPECT_EQ(1, message.map_int32_int32().size());
+ ASSERT_NE(message.map_int32_int32().find(0), message.map_int32_int32().end());
+ EXPECT_EQ(1, message.map_int32_int32().at(0));
+}
+
+TEST(GeneratedMapFieldTest, MissedValueWireFormat) {
+ UNITTEST::TestMap message;
+
+ // No value field in wire format
+ std::string data = "\x0A\x02\x08\x01";
+
+ EXPECT_TRUE(message.ParseFromString(data));
+ EXPECT_EQ(1, message.map_int32_int32().size());
+ ASSERT_NE(message.map_int32_int32().find(1), message.map_int32_int32().end());
+ EXPECT_EQ(0, message.map_int32_int32().at(1));
+}
+
+TEST(GeneratedMapFieldTest, MissedValueTextFormat) {
+ UNITTEST::TestMap message;
+
+ // No value field in text format
+ std::string text =
+ "map_int32_foreign_message {\n"
+ " key: 1234567890\n"
+ "}";
+
+ EXPECT_TRUE(TextFormat::ParseFromString(text, &message));
+ EXPECT_EQ(1, message.map_int32_foreign_message().size());
+ EXPECT_EQ(11, message.ByteSizeLong());
+}
+
+TEST(GeneratedMapFieldTest, UnknownFieldWireFormat) {
+ UNITTEST::TestMap message;
+
+ // Unknown field in wire format
+ std::string data = "\x0A\x06\x08\x02\x10\x03\x18\x01";
+
+ EXPECT_TRUE(message.ParseFromString(data));
+ EXPECT_EQ(1, message.map_int32_int32().size());
+ EXPECT_EQ(3, message.map_int32_int32().at(2));
+}
+
+TEST(GeneratedMapFieldTest, CorruptedWireFormat) {
+ UNITTEST::TestMap message;
+
+ // corrupted data in wire format
+ std::string data = "\x0A\x06\x08\x02\x11\x03";
+
+ EXPECT_FALSE(message.ParseFromString(data));
+}
+
+TEST(GeneratedMapFieldTest, IsInitialized) {
+ UNITTEST::TestRequiredMessageMap map_message;
+
+ // Add an uninitialized message.
+ (*map_message.mutable_map_field())[0];
+ EXPECT_FALSE(map_message.IsInitialized());
+
+ // Initialize uninitialized message
+ (*map_message.mutable_map_field())[0].set_a(0);
+ (*map_message.mutable_map_field())[0].set_b(0);
+ (*map_message.mutable_map_field())[0].set_c(0);
+ EXPECT_TRUE(map_message.IsInitialized());
+}
+
+TEST(GeneratedMapFieldTest, SpaceUsed) {
+ UNITTEST::TestRequiredMessageMap map_message;
+ const size_t initial = map_message.SpaceUsed();
+ const size_t space_used_message = UNITTEST::TestRequired().SpaceUsed();
+
+ auto& m = *map_message.mutable_map_field();
+ constexpr int kNumValues = 100;
+ for (int i = 0; i < kNumValues; ++i) {
+ m[i];
+ }
+
+ // The exact value will depend on internal state, like collisions,
+ // so we can't predict it. But we can predict a lower bound.
+ size_t lower_bound =
+ initial + kNumValues * (space_used_message + sizeof(int32) +
+ /* Node::next */ sizeof(void*) +
+ /* table entry */ sizeof(void*));
+
+ EXPECT_LE(lower_bound, map_message.SpaceUsed());
+}
+
+TEST(GeneratedMapFieldTest, MessagesMustMerge) {
+ UNITTEST::TestRequiredMessageMap map_message;
+
+ UNITTEST::TestRequired with_dummy4;
+ with_dummy4.set_a(97);
+ with_dummy4.set_b(91);
+ with_dummy4.set_dummy4(98);
+ EXPECT_FALSE(with_dummy4.IsInitialized());
+ (*map_message.mutable_map_field())[0] = with_dummy4;
+ EXPECT_FALSE(map_message.IsInitialized());
+
+ UNITTEST::TestRequired with_dummy5;
+ with_dummy5.set_b(0);
+ with_dummy5.set_c(33);
+ with_dummy5.set_dummy5(99);
+ EXPECT_FALSE(with_dummy5.IsInitialized());
+ (*map_message.mutable_map_field())[0] = with_dummy5;
+ EXPECT_FALSE(map_message.IsInitialized());
+
+ // The wire format of MapEntry is straightforward (*) and can be manually
+ // constructed to force merging of two uninitialized messages that would
+ // result in an initialized message.
+ //
+ // (*) http://google3/net/proto2/internal/map_test.cc?l=2433&rcl=310012028
+ std::string dummy4_s = with_dummy4.SerializePartialAsString();
+ std::string dummy5_s = with_dummy5.SerializePartialAsString();
+ int payload_size = dummy4_s.size() + dummy5_s.size();
+ // Makes sure the payload size fits into one byte.
+ ASSERT_LT(payload_size, 128);
+
+ std::string s(6, 0);
+ char* p = &s[0];
+ *p++ = WireFormatLite::MakeTag(1, WireFormatLite::WIRETYPE_LENGTH_DELIMITED);
+ // Length: 2B for key tag & val and 2B for val tag and length of the following
+ // payload.
+ *p++ = 4 + payload_size;
+ *p++ = WireFormatLite::MakeTag(1, WireFormatLite::WIRETYPE_VARINT);
+ *p++ = 0;
+ *p++ = WireFormatLite::MakeTag(2, WireFormatLite::WIRETYPE_LENGTH_DELIMITED);
+ *p++ = payload_size;
+ StrAppend(&s, dummy4_s, dummy5_s);
+
+ // Test key then value then value.
+ int key = 0;
+ ASSERT_TRUE(map_message.ParseFromString(s));
+ ASSERT_EQ(1, map_message.map_field().size());
+ ASSERT_EQ(1, map_message.map_field().count(key));
+ EXPECT_EQ(97, map_message.map_field().find(key)->second.a());
+ EXPECT_EQ(0, map_message.map_field().find(key)->second.b());
+ EXPECT_EQ(33, map_message.map_field().find(key)->second.c());
+ EXPECT_EQ(98, map_message.map_field().find(key)->second.dummy4());
+ EXPECT_EQ(99, map_message.map_field().find(key)->second.dummy5());
+
+ // Test key then value then value then key.
+ s.push_back(s[2]); // Copy the key's tag.
+ key = 19;
+ s.push_back(key); // Second key is 19 instead of 0.
+ s[1] += 2; // Adjust encoded size.
+ ASSERT_TRUE(map_message.ParseFromString(s));
+ ASSERT_EQ(1, map_message.map_field().size());
+ ASSERT_EQ(1, map_message.map_field().count(key));
+ EXPECT_EQ(97, map_message.map_field().find(key)->second.a());
+ EXPECT_EQ(0, map_message.map_field().find(key)->second.b());
+ EXPECT_EQ(33, map_message.map_field().find(key)->second.c());
+ EXPECT_EQ(98, map_message.map_field().find(key)->second.dummy4());
+ EXPECT_EQ(99, map_message.map_field().find(key)->second.dummy5());
+}
+
+// Generated Message Reflection Test ================================
+
+TEST(GeneratedMapFieldReflectionTest, SpaceUsed) {
+ UNITTEST::TestMap message;
+ MapReflectionTester reflection_tester(UNITTEST::TestMap::descriptor());
+ reflection_tester.SetMapFieldsViaReflection(&message);
+
+ EXPECT_LT(0, message.GetReflection()->SpaceUsedLong(message));
+}
+
+TEST(GeneratedMapFieldReflectionTest, Accessors) {
+ // Set every field to a unique value then go back and check all those
+ // values.
+ UNITTEST::TestMap message;
+ MapReflectionTester reflection_tester(UNITTEST::TestMap::descriptor());
+ reflection_tester.SetMapFieldsViaReflection(&message);
+ MapTestUtil::ExpectMapFieldsSet(message);
+ reflection_tester.ExpectMapFieldsSetViaReflection(message);
+ reflection_tester.ExpectMapFieldsSetViaReflectionIterator(&message);
+
+ reflection_tester.ModifyMapFieldsViaReflection(&message);
+ MapTestUtil::ExpectMapFieldsModified(message);
+}
+
+TEST(GeneratedMapFieldReflectionTest, Swap) {
+ UNITTEST::TestMap message1;
+ UNITTEST::TestMap message2;
+
+ MapTestUtil::SetMapFields(&message1);
+
+ const Reflection* reflection = message1.GetReflection();
+ reflection->Swap(&message1, &message2);
+
+ MapTestUtil::ExpectClear(message1);
+ MapTestUtil::ExpectMapFieldsSet(message2);
+}
+
+TEST(GeneratedMapFieldReflectionTest, SwapWithBothSet) {
+ UNITTEST::TestMap message1;
+ UNITTEST::TestMap message2;
+
+ MapTestUtil::SetMapFields(&message1);
+ MapTestUtil::SetMapFields(&message2);
+ MapTestUtil::ModifyMapFields(&message2);
+
+ const Reflection* reflection = message1.GetReflection();
+ reflection->Swap(&message1, &message2);
+
+ MapTestUtil::ExpectMapFieldsModified(message1);
+ MapTestUtil::ExpectMapFieldsSet(message2);
+}
+
+TEST(GeneratedMapFieldReflectionTest, SwapFields) {
+ UNITTEST::TestMap message1;
+ UNITTEST::TestMap message2;
+
+ MapTestUtil::SetMapFields(&message2);
+
+ std::vector<const FieldDescriptor*> fields;
+ const Reflection* reflection = message1.GetReflection();
+ reflection->ListFields(message2, &fields);
+ reflection->SwapFields(&message1, &message2, fields);
+
+ MapTestUtil::ExpectMapFieldsSet(message1);
+ MapTestUtil::ExpectClear(message2);
+}
+
+TEST(GeneratedMapFieldReflectionTest, ClearField) {
+ UNITTEST::TestMap message;
+ MapTestUtil::SetMapFields(&message);
+ MapTestUtil::ExpectMapFieldsSet(message);
+
+ MapReflectionTester reflection_tester(UNITTEST::TestMap::descriptor());
+ reflection_tester.ClearMapFieldsViaReflection(&message);
+ reflection_tester.ExpectClearViaReflection(message);
+ reflection_tester.ExpectClearViaReflectionIterator(&message);
+}
+
+TEST(GeneratedMapFieldReflectionTest, RemoveLast) {
+ UNITTEST::TestMap message;
+ MapReflectionTester reflection_tester(UNITTEST::TestMap::descriptor());
+
+ MapTestUtil::SetMapFields(&message);
+ MapTestUtil::ExpectMapsSize(message, 2);
+ std::vector<const Message*> expected_entries =
+ MapTestUtil::GetMapEntries(message, 0);
+
+ reflection_tester.RemoveLastMapsViaReflection(&message);
+
+ MapTestUtil::ExpectMapsSize(message, 1);
+ std::vector<const Message*> remained_entries =
+ MapTestUtil::GetMapEntries(message, 0);
+ EXPECT_TRUE(expected_entries == remained_entries);
+}
+
+TEST(GeneratedMapFieldReflectionTest, ReleaseLast) {
+ UNITTEST::TestMap message;
+ const Descriptor* descriptor = message.GetDescriptor();
+ MapReflectionTester reflection_tester(descriptor);
+
+ MapTestUtil::SetMapFields(&message);
+
+ MapTestUtil::ExpectMapsSize(message, 2);
+
+ reflection_tester.ReleaseLastMapsViaReflection(&message);
+
+ MapTestUtil::ExpectMapsSize(message, 1);
+
+ // Now test that we actually release the right message.
+ message.Clear();
+ MapTestUtil::SetMapFields(&message);
+
+ MapTestUtil::ExpectMapsSize(message, 2);
+ std::vector<const Message*> expect_last =
+ MapTestUtil::GetMapEntries(message, 1);
+ std::vector<const Message*> release_last =
+ MapTestUtil::GetMapEntriesFromRelease(&message);
+ MapTestUtil::ExpectMapsSize(message, 1);
+ EXPECT_TRUE(expect_last == release_last);
+ for (std::vector<const Message*>::iterator it = release_last.begin();
+ it != release_last.end(); ++it) {
+ delete *it;
+ }
+}
+
+TEST(GeneratedMapFieldReflectionTest, SwapElements) {
+ UNITTEST::TestMap message;
+ MapReflectionTester reflection_tester(UNITTEST::TestMap::descriptor());
+
+ MapTestUtil::SetMapFields(&message);
+
+ // Get pointers of map entries at their original position
+ std::vector<const Message*> entries0 = MapTestUtil::GetMapEntries(message, 0);
+ std::vector<const Message*> entries1 = MapTestUtil::GetMapEntries(message, 1);
+
+ // Swap the first time.
+ reflection_tester.SwapMapsViaReflection(&message);
+
+ // Get pointer of map entry after swap once.
+ std::vector<const Message*> entries0_once =
+ MapTestUtil::GetMapEntries(message, 0);
+ std::vector<const Message*> entries1_once =
+ MapTestUtil::GetMapEntries(message, 1);
+
+ // Test map entries are swapped.
+ MapTestUtil::ExpectMapsSize(message, 2);
+ EXPECT_TRUE(entries0 == entries1_once);
+ EXPECT_TRUE(entries1 == entries0_once);
+
+ // Swap the second time.
+ reflection_tester.SwapMapsViaReflection(&message);
+
+ // Get pointer of map entry after swap once.
+ std::vector<const Message*> entries0_twice =
+ MapTestUtil::GetMapEntries(message, 0);
+ std::vector<const Message*> entries1_twice =
+ MapTestUtil::GetMapEntries(message, 1);
+
+ // Test map entries are swapped back.
+ MapTestUtil::ExpectMapsSize(message, 2);
+ EXPECT_TRUE(entries0 == entries0_twice);
+ EXPECT_TRUE(entries1 == entries1_twice);
+}
+
+TEST(GeneratedMapFieldReflectionTest, MutableUnknownFields) {
+ UNITTEST::TestMap message;
+ MapReflectionTester reflection_tester(UNITTEST::TestMap::descriptor());
+ reflection_tester.MutableUnknownFieldsOfMapFieldsViaReflection(&message);
+}
+
+TEST(GeneratedMapFieldReflectionTest, EmbedProto2Message) {
+ UNITTEST::TestMessageMap message;
+
+ const FieldDescriptor* map_field =
+ UNITTEST::TestMessageMap::descriptor()->FindFieldByName(
+ "map_int32_message");
+ const FieldDescriptor* value =
+ map_field->message_type()->FindFieldByName("value");
+
+ Message* entry_message =
+ message.GetReflection()->AddMessage(&message, map_field);
+ EXPECT_EQ(
+ &entry_message->GetReflection()->GetMessage(*entry_message, value),
+ reinterpret_cast<const Message*>(&TestAllTypes::default_instance()));
+
+ Message* proto2_message =
+ entry_message->GetReflection()->MutableMessage(entry_message, value);
+ EXPECT_EQ(UNITTEST::TestAllTypes::descriptor(),
+ proto2_message->GetDescriptor());
+ ASSERT_EQ(1, message.map_int32_message().size());
+}
+
+TEST(GeneratedMapFieldReflectionTest, MergeFromClearMapEntry) {
+ UNITTEST::TestMap message;
+ const FieldDescriptor* map_field =
+ UNITTEST::TestMap::descriptor()->FindFieldByName("map_int32_int32");
+ const FieldDescriptor* key =
+ map_field->message_type()->FindFieldByName("key");
+ const FieldDescriptor* value =
+ map_field->message_type()->FindFieldByName("value");
+
+ Message* entry_message1 =
+ message.GetReflection()->AddMessage(&message, map_field);
+ EXPECT_FALSE(entry_message1->GetReflection()->HasField(*entry_message1, key));
+ EXPECT_FALSE(
+ entry_message1->GetReflection()->HasField(*entry_message1, value));
+
+ Message* entry_message2 =
+ message.GetReflection()->AddMessage(&message, map_field);
+ EXPECT_FALSE(entry_message2->GetReflection()->HasField(*entry_message2, key));
+ EXPECT_FALSE(
+ entry_message2->GetReflection()->HasField(*entry_message2, value));
+
+ entry_message1->MergeFrom(*entry_message2);
+ EXPECT_FALSE(entry_message1->GetReflection()->HasField(*entry_message1, key));
+ EXPECT_FALSE(
+ entry_message1->GetReflection()->HasField(*entry_message1, value));
+}
+
+TEST(GeneratedMapFieldReflectionTest, MapEntryClear) {
+ UNITTEST::TestMap message;
+ MapReflectionTester reflection_tester(UNITTEST::TestMap::descriptor());
+ reflection_tester.MutableUnknownFieldsOfMapFieldsViaReflection(&message);
+}
+
+TEST(GeneratedMapFieldReflectionTest, Proto2MapEntryClear) {
+ UNITTEST::TestEnumMap message;
+ const Descriptor* descriptor = message.GetDescriptor();
+ const FieldDescriptor* field_descriptor =
+ descriptor->FindFieldByName("known_map_field");
+ const FieldDescriptor* value_descriptor =
+ field_descriptor->message_type()->FindFieldByName("value");
+ Message* sub_message =
+ message.GetReflection()->AddMessage(&message, field_descriptor);
+ EXPECT_EQ(0, sub_message->GetReflection()->GetEnumValue(*sub_message,
+ value_descriptor));
+}
+
+// Map Reflection API Test =========================================
+
+TEST(GeneratedMapFieldReflectionTest, SetViaMapReflection) {
+ UNITTEST::TestMap message;
+ MapReflectionTester reflection_tester(UNITTEST::TestMap::descriptor());
+ reflection_tester.SetMapFieldsViaMapReflection(&message);
+ reflection_tester.ExpectMapFieldsSetViaReflection(message);
+ reflection_tester.ExpectMapFieldsSetViaReflectionIterator(&message);
+}
+
+// Dynamic Message Test =============================================
+
+class MapFieldInDynamicMessageTest : public testing::Test {
+ protected:
+ const DescriptorPool* pool_;
+ DynamicMessageFactory factory_;
+ const Descriptor* map_descriptor_;
+ const Descriptor* recursive_map_descriptor_;
+ const Message* map_prototype_;
+
+ MapFieldInDynamicMessageTest()
+ : pool_(DescriptorPool::generated_pool()), factory_(pool_) {}
+
+ virtual void SetUp() {
+ map_descriptor_ = pool_->FindMessageTypeByName(
+ std::string(UNITTEST_PACKAGE_NAME) + ".TestMap");
+ recursive_map_descriptor_ = pool_->FindMessageTypeByName(
+ std::string(UNITTEST_PACKAGE_NAME) + ".TestRecursiveMapMessage");
+ ASSERT_TRUE(map_descriptor_ != nullptr);
+ ASSERT_TRUE(recursive_map_descriptor_ != nullptr);
+ map_prototype_ = factory_.GetPrototype(map_descriptor_);
+ }
+};
+
+TEST_F(MapFieldInDynamicMessageTest, MapIndependentOffsets) {
+ // Check that all fields have independent offsets by setting each
+ // one to a unique value then checking that they all still have those
+ // unique values (i.e. they don't stomp each other).
+ std::unique_ptr<Message> message(map_prototype_->New());
+ MapReflectionTester reflection_tester(map_descriptor_);
+
+ reflection_tester.SetMapFieldsViaReflection(message.get());
+ reflection_tester.ExpectMapFieldsSetViaReflection(*message);
+}
+
+TEST_F(MapFieldInDynamicMessageTest, DynamicMapReflection) {
+ // Check that map fields work properly.
+ std::unique_ptr<Message> message(map_prototype_->New());
+
+ // Check set functions.
+ MapReflectionTester reflection_tester(map_descriptor_);
+ reflection_tester.SetMapFieldsViaMapReflection(message.get());
+ reflection_tester.ExpectMapFieldsSetViaReflection(*message);
+}
+
+TEST_F(MapFieldInDynamicMessageTest, MapSpaceUsed) {
+ // Test that SpaceUsedLong() works properly
+
+ // Since we share the implementation with generated messages, we don't need
+ // to test very much here. Just make sure it appears to be working.
+
+ std::unique_ptr<Message> message(map_prototype_->New());
+ MapReflectionTester reflection_tester(map_descriptor_);
+
+ int initial_space_used = message->SpaceUsedLong();
+
+ reflection_tester.SetMapFieldsViaReflection(message.get());
+ EXPECT_LT(initial_space_used, message->SpaceUsedLong());
+}
+
+TEST_F(MapFieldInDynamicMessageTest, RecursiveMap) {
+ TestRecursiveMapMessage from;
+ (*from.mutable_a())[""];
+ std::string data = from.SerializeAsString();
+ std::unique_ptr<Message> to(
+ factory_.GetPrototype(recursive_map_descriptor_)->New());
+ ASSERT_TRUE(to->ParseFromString(data));
+}
+
+TEST_F(MapFieldInDynamicMessageTest, MapValueReferernceValidAfterSerialize) {
+ std::unique_ptr<Message> message(map_prototype_->New());
+ MapReflectionTester reflection_tester(map_descriptor_);
+ reflection_tester.SetMapFieldsViaMapReflection(message.get());
+
+ // Get value reference before serialization, so that we know the value is from
+ // map.
+ MapKey map_key;
+ MapValueRef map_val;
+ map_key.SetInt32Value(0);
+ reflection_tester.GetMapValueViaMapReflection(
+ message.get(), "map_int32_foreign_message", map_key, &map_val);
+ Message* submsg = map_val.MutableMessageValue();
+
+ // In previous implementation, calling SerializeToString will cause syncing
+ // from map to repeated field, which will invalidate the submsg we previously
+ // got.
+ std::string data;
+ message->SerializeToString(&data);
+
+ const Reflection* submsg_reflection = submsg->GetReflection();
+ const Descriptor* submsg_desc = submsg->GetDescriptor();
+ const FieldDescriptor* submsg_field = submsg_desc->FindFieldByName("c");
+ submsg_reflection->SetInt32(submsg, submsg_field, 128);
+
+ message->SerializeToString(&data);
+ TestMap to;
+ to.ParseFromString(data);
+ EXPECT_EQ(128, to.map_int32_foreign_message().at(0).c());
+}
+
+TEST_F(MapFieldInDynamicMessageTest, MapEntryReferernceValidAfterSerialize) {
+ std::unique_ptr<Message> message(map_prototype_->New());
+ MapReflectionTester reflection_tester(map_descriptor_);
+ reflection_tester.SetMapFieldsViaReflection(message.get());
+
+ // Get map entry before serialization, so that we know the it is from
+ // repeated field.
+ Message* map_entry = reflection_tester.GetMapEntryViaReflection(
+ message.get(), "map_int32_foreign_message", 0);
+ const Reflection* map_entry_reflection = map_entry->GetReflection();
+ const Descriptor* map_entry_desc = map_entry->GetDescriptor();
+ const FieldDescriptor* value_field = map_entry_desc->FindFieldByName("value");
+ Message* submsg =
+ map_entry_reflection->MutableMessage(map_entry, value_field);
+
+ // In previous implementation, calling SerializeToString will cause syncing
+ // from repeated field to map, which will invalidate the map_entry we
+ // previously got.
+ std::string data;
+ message->SerializeToString(&data);
+
+ const Reflection* submsg_reflection = submsg->GetReflection();
+ const Descriptor* submsg_desc = submsg->GetDescriptor();
+ const FieldDescriptor* submsg_field = submsg_desc->FindFieldByName("c");
+ submsg_reflection->SetInt32(submsg, submsg_field, 128);
+
+ message->SerializeToString(&data);
+ TestMap to;
+ to.ParseFromString(data);
+ EXPECT_EQ(128, to.map_int32_foreign_message().at(0).c());
+}
+
+// ReflectionOps Test ===============================================
+
+TEST(ReflectionOpsForMapFieldTest, MapSanityCheck) {
+ UNITTEST::TestMap message;
+
+ MapTestUtil::SetMapFields(&message);
+ MapTestUtil::ExpectMapFieldsSet(message);
+}
+
+TEST(ReflectionOpsForMapFieldTest, MapCopy) {
+ UNITTEST::TestMap message, message2;
+
+ MapTestUtil::SetMapFields(&message);
+
+ ReflectionOps::Copy(message, &message2);
+
+ MapTestUtil::ExpectMapFieldsSet(message2);
+
+ // Copying from self should be a no-op.
+ ReflectionOps::Copy(message2, &message2);
+ MapTestUtil::ExpectMapFieldsSet(message2);
+}
+
+TEST(ReflectionOpsForMapFieldTest, MergeMap) {
+ // Note: Copy is implemented in terms of Merge() so technically the Copy
+ // test already tested most of this.
+
+ UNITTEST::TestMap message, message2;
+
+ MapTestUtil::SetMapFields(&message);
+
+ ReflectionOps::Merge(message2, &message);
+
+ MapTestUtil::ExpectMapFieldsSet(message);
+}
+
+TEST(ReflectionOpsForMapFieldTest, ClearMap) {
+ UNITTEST::TestMap message;
+
+ MapTestUtil::SetMapFields(&message);
+
+ ReflectionOps::Clear(&message);
+
+ MapTestUtil::ExpectClear(message);
+}
+
+TEST(ReflectionOpsForMapFieldTest, MapDiscardUnknownFields) {
+ UNITTEST::TestMap message;
+ MapTestUtil::SetMapFields(&message);
+
+ // Set some unknown fields in message.
+ message.GetReflection()->MutableUnknownFields(&message)->AddVarint(123456,
+ 654321);
+
+ // Discard them.
+ ReflectionOps::DiscardUnknownFields(&message);
+ MapTestUtil::ExpectMapFieldsSet(message);
+
+ EXPECT_EQ(0,
+ message.GetReflection()->GetUnknownFields(message).field_count());
+}
+
+TEST(ReflectionOpsForMapFieldTest, IsInitialized) {
+ UNITTEST::TestRequiredMessageMap map_message;
+
+ // Add an uninitialized message.
+ (*map_message.mutable_map_field())[0];
+ EXPECT_FALSE(ReflectionOps::IsInitialized(map_message));
+
+ // Initialize uninitialized message
+ (*map_message.mutable_map_field())[0].set_a(0);
+ (*map_message.mutable_map_field())[0].set_b(0);
+ (*map_message.mutable_map_field())[0].set_c(0);
+ EXPECT_TRUE(ReflectionOps::IsInitialized(map_message));
+}
+
+// Wire Format Test =================================================
+
+TEST(WireFormatForMapFieldTest, ParseMap) {
+ UNITTEST::TestMap source, dest;
+ std::string data;
+
+ // Serialize using the generated code.
+ MapTestUtil::SetMapFields(&source);
+ source.SerializeToString(&data);
+
+ // Parse using WireFormat.
+ io::ArrayInputStream raw_input(data.data(), data.size());
+ io::CodedInputStream input(&raw_input);
+ WireFormat::ParseAndMergePartial(&input, &dest);
+
+ // Check.
+ MapTestUtil::ExpectMapFieldsSet(dest);
+}
+
+TEST(WireFormatForMapFieldTest, MapByteSize) {
+ UNITTEST::TestMap message;
+ MapTestUtil::SetMapFields(&message);
+
+ EXPECT_EQ(message.ByteSizeLong(), WireFormat::ByteSize(message));
+ message.Clear();
+ EXPECT_EQ(0, message.ByteSizeLong());
+ EXPECT_EQ(0, WireFormat::ByteSize(message));
+}
+
+TEST(WireFormatForMapFieldTest, SerializeMap) {
+ UNITTEST::TestMap message;
+ std::string generated_data;
+ std::string dynamic_data;
+
+ MapTestUtil::SetMapFields(&message);
+
+ // Serialize using the generated code.
+ {
+ message.ByteSizeLong();
+ io::StringOutputStream raw_output(&generated_data);
+ io::CodedOutputStream output(&raw_output);
+ message.SerializeWithCachedSizes(&output);
+ ASSERT_FALSE(output.HadError());
+ }
+
+ // Serialize using WireFormat.
+ {
+ io::StringOutputStream raw_output(&dynamic_data);
+ io::CodedOutputStream output(&raw_output);
+ size_t size = WireFormat::ByteSize(message);
+ WireFormat::SerializeWithCachedSizes(message, size, &output);
+ ASSERT_FALSE(output.HadError());
+ }
+
+ // Should parse to the same message.
+ EXPECT_TRUE(TestUtil::EqualsToSerialized(message, generated_data));
+ EXPECT_TRUE(TestUtil::EqualsToSerialized(message, dynamic_data));
+}
+
+TEST(WireFormatForMapFieldTest, SerializeMapDynamicMessage) {
+ DynamicMessageFactory factory;
+ std::unique_ptr<Message> dynamic_message;
+ dynamic_message.reset(
+ factory.GetPrototype(UNITTEST::TestMap::descriptor())->New());
+ MapReflectionTester reflection_tester(UNITTEST::TestMap::descriptor());
+ reflection_tester.SetMapFieldsViaReflection(dynamic_message.get());
+ reflection_tester.ExpectMapFieldsSetViaReflection(*dynamic_message);
+
+ UNITTEST::TestMap generated_message;
+ MapTestUtil::SetMapFields(&generated_message);
+ MapTestUtil::ExpectMapFieldsSet(generated_message);
+
+ std::string generated_data;
+ std::string dynamic_data;
+
+ // Serialize.
+ generated_message.SerializeToString(&generated_data);
+ dynamic_message->SerializeToString(&dynamic_data);
+
+ // Because map serialization doesn't guarantee order, we just compare
+ // serialized size here. This is enough to tell dynamic message doesn't miss
+ // anything in serialization.
+ EXPECT_TRUE(dynamic_data.size() == generated_data.size());
+}
+
+TEST(WireFormatForMapFieldTest, MapByteSizeDynamicMessage) {
+ DynamicMessageFactory factory;
+ std::unique_ptr<Message> dynamic_message;
+ dynamic_message.reset(
+ factory.GetPrototype(UNITTEST::TestMap::descriptor())->New());
+ MapReflectionTester reflection_tester(UNITTEST::TestMap::descriptor());
+ reflection_tester.SetMapFieldsViaReflection(dynamic_message.get());
+ reflection_tester.ExpectMapFieldsSetViaReflection(*dynamic_message);
+ std::string expected_serialized_data;
+ dynamic_message->SerializeToString(&expected_serialized_data);
+ int expected_size = expected_serialized_data.size();
+ EXPECT_EQ(dynamic_message->ByteSizeLong(), expected_size);
+ TestMap expected_message;
+ expected_message.ParseFromString(expected_serialized_data);
+
+ std::unique_ptr<Message> message2;
+ message2.reset(factory.GetPrototype(UNITTEST::TestMap::descriptor())->New());
+ reflection_tester.SetMapFieldsViaMapReflection(message2.get());
+
+ const FieldDescriptor* field =
+ UNITTEST::TestMap::descriptor()->FindFieldByName("map_int32_int32");
+ const Reflection* reflection = dynamic_message->GetReflection();
+
+ // Force the map field to mark with STATE_MODIFIED_REPEATED
+ reflection->RemoveLast(dynamic_message.get(), field);
+ dynamic_message->MergeFrom(*message2);
+ dynamic_message->MergeFrom(*message2);
+ // The map field is marked as STATE_MODIFIED_REPEATED, ByteSizeLong() will use
+ // repeated field which have duplicate keys to calculate.
+ size_t duplicate_size = dynamic_message->ByteSizeLong();
+ EXPECT_TRUE(duplicate_size > expected_size);
+ std::string duplicate_serialized_data;
+ dynamic_message->SerializeToString(&duplicate_serialized_data);
+ EXPECT_EQ(dynamic_message->ByteSizeLong(), duplicate_serialized_data.size());
+
+ // Force the map field to mark with map CLEAN
+ EXPECT_EQ(reflection_tester.MapSize(
+ *dynamic_message, "map_int32_int32"), 2);
+ EXPECT_EQ(reflection_tester.MapSize(
+ *dynamic_message, "map_int32_int32"), 2);
+ EXPECT_EQ(reflection_tester.MapSize(
+ *dynamic_message, "map_int64_int64"), 2);
+ EXPECT_EQ(reflection_tester.MapSize(
+ *dynamic_message, "map_uint32_uint32"), 2);
+ EXPECT_EQ(reflection_tester.MapSize(
+ *dynamic_message, "map_uint64_uint64"), 2);
+ EXPECT_EQ(reflection_tester.MapSize(
+ *dynamic_message, "map_sint32_sint32"), 2);
+ EXPECT_EQ(reflection_tester.MapSize(
+ *dynamic_message, "map_sint64_sint64"), 2);
+ EXPECT_EQ(reflection_tester.MapSize(
+ *dynamic_message, "map_fixed32_fixed32"), 2);
+ EXPECT_EQ(reflection_tester.MapSize(
+ *dynamic_message, "map_fixed64_fixed64"), 2);
+ EXPECT_EQ(reflection_tester.MapSize(
+ *dynamic_message, "map_sfixed32_sfixed32"), 2);
+ EXPECT_EQ(reflection_tester.MapSize(
+ *dynamic_message, "map_sfixed64_sfixed64"), 2);
+ EXPECT_EQ(reflection_tester.MapSize(
+ *dynamic_message, "map_int32_float"), 2);
+ EXPECT_EQ(reflection_tester.MapSize(
+ *dynamic_message, "map_int32_double"), 2);
+ EXPECT_EQ(reflection_tester.MapSize(
+ *dynamic_message, "map_bool_bool"), 2);
+ EXPECT_EQ(reflection_tester.MapSize(
+ *dynamic_message, "map_string_string"), 2);
+ EXPECT_EQ(reflection_tester.MapSize(
+ *dynamic_message, "map_int32_bytes"), 2);
+ EXPECT_EQ(reflection_tester.MapSize(
+ *dynamic_message, "map_int32_enum"), 2);
+ EXPECT_EQ(reflection_tester.MapSize(*dynamic_message, "map_int32_foreign_message"), 2);
+ // The map field is marked as CLEAN, ByteSizeLong() will use map which do not
+ // have duplicate keys to calculate.
+ int size = dynamic_message->ByteSizeLong();
+ EXPECT_EQ(expected_size, size);
+
+ // Protobuf used to have a bug for serialize when map it marked CLEAN. It used
+ // repeated field to calculate ByteSizeLong but use map to serialize the real
+ // data, thus the ByteSizeLong may bigger than real serialized size. A crash
+ // might be happen at SerializeToString(). Or an "unexpected end group"
+ // warning was raised at parse back if user use SerializeWithCachedSizes()
+ // which avoids size check at serialize.
+ std::string serialized_data;
+ dynamic_message->SerializeToString(&serialized_data);
+ EXPECT_TRUE(dynamic_message->ParseFromString(serialized_data));
+}
+
+TEST(WireFormatForMapFieldTest, MapParseHelpers) {
+ std::string data;
+
+ {
+ // Set up.
+ UNITTEST::TestMap message;
+ MapTestUtil::SetMapFields(&message);
+ message.SerializeToString(&data);
+ }
+
+ {
+ // Test ParseFromString.
+ UNITTEST::TestMap message;
+ EXPECT_TRUE(message.ParseFromString(data));
+ MapTestUtil::ExpectMapFieldsSet(message);
+ }
+
+ {
+ // Test ParseFromIstream.
+ UNITTEST::TestMap message;
+ std::stringstream stream(data);
+ EXPECT_TRUE(message.ParseFromIstream(&stream));
+ EXPECT_TRUE(stream.eof());
+ MapTestUtil::ExpectMapFieldsSet(message);
+ }
+
+ {
+ // Test ParseFromBoundedZeroCopyStream.
+ std::string data_with_junk(data);
+ data_with_junk.append("some junk on the end");
+ io::ArrayInputStream stream(data_with_junk.data(), data_with_junk.size());
+ UNITTEST::TestMap message;
+ EXPECT_TRUE(message.ParseFromBoundedZeroCopyStream(&stream, data.size()));
+ MapTestUtil::ExpectMapFieldsSet(message);
+ }
+
+ {
+ // Test that ParseFromBoundedZeroCopyStream fails (but doesn't crash) if
+ // EOF is reached before the expected number of bytes.
+ io::ArrayInputStream stream(data.data(), data.size());
+ UNITTEST::TestAllTypes message;
+ EXPECT_FALSE(
+ message.ParseFromBoundedZeroCopyStream(&stream, data.size() + 1));
+ }
+}
+
+// Deterministic Serialization Test ==========================================
+
+template <typename T>
+static std::string DeterministicSerializationWithSerializePartialToCodedStream(
+ const T& t) {
+ const size_t size = t.ByteSizeLong();
+ std::string result(size, '\0');
+ io::ArrayOutputStream array_stream(::google::protobuf::string_as_array(&result), size);
+ io::CodedOutputStream output_stream(&array_stream);
+ output_stream.SetSerializationDeterministic(true);
+ t.SerializePartialToCodedStream(&output_stream);
+ EXPECT_FALSE(output_stream.HadError());
+ EXPECT_EQ(size, output_stream.ByteCount());
+ return result;
+}
+
+template <typename T>
+static std::string DeterministicSerializationWithSerializeToCodedStream(
+ const T& t) {
+ const size_t size = t.ByteSizeLong();
+ std::string result(size, '\0');
+ io::ArrayOutputStream array_stream(::google::protobuf::string_as_array(&result), size);
+ io::CodedOutputStream output_stream(&array_stream);
+ output_stream.SetSerializationDeterministic(true);
+ t.SerializeToCodedStream(&output_stream);
+ EXPECT_FALSE(output_stream.HadError());
+ EXPECT_EQ(size, output_stream.ByteCount());
+ return result;
+}
+
+template <typename T>
+static std::string DeterministicSerialization(const T& t) {
+ const size_t size = t.ByteSizeLong();
+ std::string result(size, '\0');
+ io::ArrayOutputStream array_stream(::google::protobuf::string_as_array(&result), size);
+ {
+ io::CodedOutputStream output_stream(&array_stream);
+ output_stream.SetSerializationDeterministic(true);
+ t.SerializeWithCachedSizes(&output_stream);
+ EXPECT_FALSE(output_stream.HadError());
+ EXPECT_EQ(size, output_stream.ByteCount());
+ }
+ EXPECT_EQ(result, DeterministicSerializationWithSerializeToCodedStream(t));
+ EXPECT_EQ(result,
+ DeterministicSerializationWithSerializePartialToCodedStream(t));
+ return result;
+}
+
+// Helper for MapSerializationTest. Return a 7-bit ASCII string.
+static std::string ConstructKey(uint64 n) {
+ std::string s(n % static_cast<uint64>(9), '\0');
+ if (s.empty()) {
+ return StrCat(n);
+ } else {
+ while (n != 0) {
+ s[n % s.size()] = (n >> 10) & 0x7f;
+ n /= 888;
+ }
+ return s;
+ }
+}
+
+TEST(MapSerializationTest, Deterministic) {
+ const int kIters = 25;
+ UNITTEST::TestMaps t;
+ UNITTEST::TestIntIntMap inner;
+ (*inner.mutable_m())[0] = (*inner.mutable_m())[10] =
+ (*inner.mutable_m())[-200] = 0;
+ uint64 frog = 9;
+ const uint64 multiplier = 0xa29cd16f;
+ for (int i = 0; i < kIters; i++) {
+ const int32 i32 = static_cast<int32>(frog & 0xffffffff);
+ const uint32 u32 = static_cast<uint32>(i32) * 91919;
+ const int64 i64 = static_cast<int64>(frog);
+ const uint64 u64 = frog * static_cast<uint64>(187321);
+ const bool b = i32 > 0;
+ const std::string s = ConstructKey(frog);
+ (*inner.mutable_m())[i] = i32;
+ (*t.mutable_m_int32())[i32] = (*t.mutable_m_sint32())[i32] =
+ (*t.mutable_m_sfixed32())[i32] = inner;
+ (*t.mutable_m_uint32())[u32] = (*t.mutable_m_fixed32())[u32] = inner;
+ (*t.mutable_m_int64())[i64] = (*t.mutable_m_sint64())[i64] =
+ (*t.mutable_m_sfixed64())[i64] = inner;
+ (*t.mutable_m_uint64())[u64] = (*t.mutable_m_fixed64())[u64] = inner;
+ (*t.mutable_m_bool())[b] = inner;
+ (*t.mutable_m_string())[s] = inner;
+ (*t.mutable_m_string())[s + std::string(1 << (u32 % static_cast<uint32>(9)),
+ b)] = inner;
+ inner.mutable_m()->erase(i);
+ frog = frog * multiplier + i;
+ frog ^= (frog >> 41);
+ }
+
+ // Verifies if two consecutive calls to deterministic serialization produce
+ // the same bytes. Deterministic serialization means the same serialization
+ // bytes in the same binary.
+ const std::string s1 = DeterministicSerialization(t);
+ const std::string s2 = DeterministicSerialization(t);
+ EXPECT_EQ(s1, s2);
+
+ UNITTEST::TestMaps u;
+ EXPECT_TRUE(u.ParseFromString(s1));
+ EXPECT_TRUE(util::MessageDifferencer::Equals(u, t));
+}
+
+TEST(MapSerializationTest, DeterministicSubmessage) {
+ UNITTEST::TestSubmessageMaps p;
+ UNITTEST::TestMaps t;
+ const std::string filename = "golden_message_maps";
+ std::string golden;
+ GOOGLE_CHECK_OK(File::GetContents(
+ TestUtil::GetTestDataPath("net/proto2/internal/testdata/" + filename),
+ &golden, true));
+ t.ParseFromString(golden);
+ *(p.mutable_m()) = t;
+ std::vector<std::string> v;
+ // Use multiple attempts to increase the chance of a failure if something is
+ // buggy. For example, each separate copy of a map might use a different
+ // randomly-chosen hash function.
+ const int kAttempts = 10;
+ for (int i = 0; i < kAttempts; i++) {
+ UNITTEST::TestSubmessageMaps q(p);
+ ASSERT_EQ(DeterministicSerialization(q), DeterministicSerialization(p));
+ }
+}
+
+// Text Format Test =================================================
+
+TEST(TextFormatMapTest, SerializeAndParse) {
+ UNITTEST::TestMap source;
+ UNITTEST::TestMap dest;
+ MapTestUtil::SetMapFields(&source);
+ std::string output;
+
+ // Test compact ASCII
+ TextFormat::Printer printer;
+ printer.PrintToString(source, &output);
+ TextFormat::Parser parser;
+ EXPECT_TRUE(parser.ParseFromString(output, &dest));
+ MapTestUtil::ExpectMapFieldsSet(dest);
+}
+
+TEST(TextFormatMapTest, DynamicMessage) {
+ TestMap prototype;
+ DynamicMessageFactory factory;
+ std::unique_ptr<Message> message(
+ factory.GetPrototype(prototype.GetDescriptor())->New());
+ MapReflectionTester tester(message->GetDescriptor());
+ tester.SetMapFieldsViaReflection(message.get());
+
+ std::string expected_text;
+ GOOGLE_CHECK_OK(
+ File::GetContents(TestUtil::GetTestDataPath("net/proto2/internal/"
+ "testdata/map_test_data.txt"),
+ &expected_text, true));
+
+ CleanStringLineEndings(&expected_text, false);
+ EXPECT_EQ(message->DebugString(), expected_text);
+}
+
+TEST(TextFormatMapTest, Sorted) {
+ UNITTEST::TestMap message;
+ MapReflectionTester tester(message.GetDescriptor());
+ tester.SetMapFieldsViaReflection(&message);
+
+ std::string expected_text;
+ GOOGLE_CHECK_OK(
+ File::GetContents(TestUtil::GetTestDataPath("net/proto2/internal/"
+ "testdata/map_test_data.txt"),
+ &expected_text, true));
+
+ CleanStringLineEndings(&expected_text, false);
+ EXPECT_EQ(message.DebugString(), expected_text);
+
+ // Test again on the reverse order.
+ UNITTEST::TestMap message2;
+ tester.SetMapFieldsViaReflection(&message2);
+ tester.SwapMapsViaReflection(&message2);
+ EXPECT_EQ(message2.DebugString(), expected_text);
+}
+
+TEST(TextFormatMapTest, ParseCorruptedString) {
+ std::string serialized_message;
+ GOOGLE_CHECK_OK(
+ File::GetContents(TestUtil::GetTestDataPath(
+ "net/proto2/internal/testdata/golden_message_maps"),
+ &serialized_message, true));
+ UNITTEST::TestMaps message;
+ GOOGLE_CHECK(message.ParseFromString(serialized_message));
+ TestParseCorruptedString<UNITTEST::TestMaps, true>(message);
+ TestParseCorruptedString<UNITTEST::TestMaps, false>(message);
+}
+
+// Previously, serializing to text format will disable iterator from generated
+// API. Now, the iterator can be still used even after serializing to text
+// format.
+TEST(TextFormatMapTest, NoDisableIterator) {
+ UNITTEST::TestMap source;
+ (*source.mutable_map_int32_int32())[1] = 1;
+
+ // Get iterator.
+ Map<int32, int32>::iterator iter = source.mutable_map_int32_int32()->find(1);
+
+ // Serialize message to text format, which will invalidate the previous
+ // iterator previously.
+ std::string output;
+ TextFormat::Printer printer;
+ printer.PrintToString(source, &output);
+
+ // Modify map via the iterator (invalidated in previous implementation.).
+ iter->second = 2;
+
+ // In previous implementation, the new change won't be reflected in text
+ // format, because the previous iterator has been invalidated.
+ output.clear();
+ printer.PrintToString(source, &output);
+ std::string expected =
+ "map_int32_int32 {\n"
+ " key: 1\n"
+ " value: 2\n"
+ "}\n";
+ EXPECT_EQ(output, expected);
+}
+
+// Previously, serializing to text format will disable iterator from reflection
+// API.
+TEST(TextFormatMapTest, NoDisableReflectionIterator) {
+ UNITTEST::TestMap source;
+ (*source.mutable_map_int32_int32())[1] = 1;
+
+ // Get iterator. This will also sync internal repeated field with map inside
+ // of MapField.
+ const Reflection* reflection = source.GetReflection();
+ const FieldDescriptor* field_desc =
+ source.GetDescriptor()->FindFieldByName("map_int32_int32");
+ RepeatedPtrField<Message>* map_field =
+ reflection->MutableRepeatedPtrField<Message>(&source, field_desc);
+ RepeatedPtrField<Message>::iterator iter = map_field->begin();
+
+ // Serialize message to text format, which will invalidate the previous
+ // iterator previously.
+ std::string output;
+ TextFormat::Printer printer;
+ printer.PrintToString(source, &output);
+
+ // Modify map via the iterator (invalidated in previous implementation.).
+ const Reflection* map_entry_reflection = iter->GetReflection();
+ const FieldDescriptor* value_field_desc =
+ iter->GetDescriptor()->FindFieldByName("value");
+ map_entry_reflection->SetInt32(&(*iter), value_field_desc, 2);
+ GOOGLE_LOG(INFO) << iter->DebugString();
+
+ // In previous implementation, the new change won't be reflected in text
+ // format, because the previous iterator has been invalidated.
+ output.clear();
+ printer.PrintToString(source, &output);
+ std::string expected =
+ "map_int32_int32 {\n"
+ " key: 1\n"
+ " value: 2\n"
+ "}\n";
+ EXPECT_EQ(output, expected);
+}
+
+// arena support =================================================
+TEST(ArenaTest, ParsingAndSerializingNoHeapAllocation) {
+ // Allocate a large initial block to avoid mallocs during hooked test.
+ std::vector<char> arena_block(128 * 1024);
+ ArenaOptions options;
+ options.initial_block = &arena_block[0];
+ options.initial_block_size = arena_block.size();
+ Arena arena(options);
+ std::string data;
+ data.reserve(128 * 1024);
+
+ {
+ // TODO(teboring): Enable no heap check when ArenaStringPtr is used in map.
+ // NoHeapChecker no_heap;
+
+ UNITTEST::TestArenaMap* from =
+ Arena::CreateMessage<UNITTEST::TestArenaMap>(&arena);
+ MapTestUtil::SetArenaMapFields(from);
+ from->SerializeToString(&data);
+
+ UNITTEST::TestArenaMap* to =
+ Arena::CreateMessage<UNITTEST::TestArenaMap>(&arena);
+ to->ParseFromString(data);
+ MapTestUtil::ExpectArenaMapFieldsSet(*to);
+ }
+}
+
+TEST(ArenaTest, SubmessageOnSameArena) {
+ Arena arena;
+ for (Arena* arena_to_use : {&arena, static_cast<Arena*>(nullptr)}) {
+ ArenaHolder<UNITTEST::TestArenaMap> m(arena_to_use);
+ auto* subm = &(*m->mutable_map_int32_foreign_message())[0];
+ EXPECT_EQ(subm->GetArena(), arena_to_use);
+ }
+}
+
+// Use text format parsing and serializing to test reflection api.
+TEST(ArenaTest, ReflectionInTextFormat) {
+ Arena arena;
+ std::string data;
+
+ TextFormat::Printer printer;
+ TextFormat::Parser parser;
+
+ UNITTEST::TestArenaMap* from =
+ Arena::CreateMessage<UNITTEST::TestArenaMap>(&arena);
+ UNITTEST::TestArenaMap* to =
+ Arena::CreateMessage<UNITTEST::TestArenaMap>(&arena);
+
+ MapTestUtil::SetArenaMapFields(from);
+ printer.PrintToString(*from, &data);
+
+ EXPECT_TRUE(parser.ParseFromString(data, to));
+ MapTestUtil::ExpectArenaMapFieldsSet(*to);
+}
+
+// Make sure the memory allocated for string in map is deallocated.
+TEST(ArenaTest, StringMapNoLeak) {
+ Arena arena;
+ UNITTEST::TestArenaMap* message =
+ Arena::CreateMessage<UNITTEST::TestArenaMap>(&arena);
+ std::string data;
+ // String with length less than 16 will not be allocated from heap.
+ int original_capacity = data.capacity();
+ while (data.capacity() <= original_capacity) {
+ data.append("a");
+ }
+ (*message->mutable_map_string_string())[data] = data;
+ // We rely on heap checkers to detect memory leak for us.
+ ASSERT_FALSE(message == nullptr);
+}
+
+TEST(ArenaTest, IsInitialized) {
+ // Allocate a large initial polluted block.
+ std::vector<char> arena_block(128 * 1024);
+ std::fill(arena_block.begin(), arena_block.end(), '\xff');
+
+ ArenaOptions options;
+ options.initial_block = &arena_block[0];
+ options.initial_block_size = arena_block.size();
+ Arena arena(options);
+
+ UNITTEST::TestArenaMap* message =
+ Arena::CreateMessage<UNITTEST::TestArenaMap>(&arena);
+ EXPECT_EQ(0, (*message->mutable_map_int32_int32())[0]);
+}
+
+TEST(ArenaTest, DynamicMapFieldOnArena) {
+ Arena arena;
+ UNITTEST::TestMap message2;
+
+ DynamicMessageFactory factory;
+ Message* message1 =
+ factory.GetPrototype(UNITTEST::TestMap::descriptor())->New(&arena);
+ MapReflectionTester reflection_tester(UNITTEST::TestMap::descriptor());
+ reflection_tester.SetMapFieldsViaReflection(message1);
+ reflection_tester.ExpectMapFieldsSetViaReflection(*message1);
+ reflection_tester.ExpectMapFieldsSetViaReflectionIterator(message1);
+ message2.CopyFrom(*message1);
+ MapTestUtil::ExpectMapFieldsSet(message2);
+}
+
+TEST(ArenaTest, DynamicMapFieldOnArenaMemoryLeak) {
+ auto* desc = UNITTEST::TestMap::descriptor();
+ auto* field = desc->FindFieldByName("map_int32_int32");
+
+ Arena arena;
+ DynamicMessageFactory factory;
+ auto* message = factory.GetPrototype(desc)->New(&arena);
+ auto* reflection = message->GetReflection();
+ reflection->AddMessage(message, field);
+
+ // Force internal syncing, which initializes the mutex.
+ MapReflectionTester reflection_tester(UNITTEST::TestMap::descriptor());
+ int size = reflection_tester.MapSize(*message, "map_int32_int32");
+ EXPECT_EQ(size, 1);
+}
+
+TEST(MoveTest, MoveConstructorWorks) {
+ Map<int32, TestAllTypes> original_map;
+ original_map[42].mutable_optional_nested_message()->set_bb(42);
+ original_map[43].mutable_optional_nested_message()->set_bb(43);
+ const auto* nested_msg42_ptr = &original_map[42].optional_nested_message();
+ const auto* nested_msg43_ptr = &original_map[43].optional_nested_message();
+
+ Map<int32, TestAllTypes> moved_to_map(std::move(original_map));
+ EXPECT_TRUE(original_map.empty());
+ EXPECT_EQ(2, moved_to_map.size());
+ EXPECT_EQ(42, moved_to_map[42].optional_nested_message().bb());
+ EXPECT_EQ(43, moved_to_map[43].optional_nested_message().bb());
+ // This test takes advantage of the fact that pointers are swapped, so there
+ // should be pointer stability.
+ EXPECT_EQ(nested_msg42_ptr, &moved_to_map[42].optional_nested_message());
+ EXPECT_EQ(nested_msg43_ptr, &moved_to_map[43].optional_nested_message());
+}
+
+TEST(MoveTest, MoveAssignmentWorks) {
+ Map<int32, TestAllTypes> original_map;
+ original_map[42].mutable_optional_nested_message()->set_bb(42);
+ original_map[43].mutable_optional_nested_message()->set_bb(43);
+ const auto* nested_msg42_ptr = &original_map[42].optional_nested_message();
+ const auto* nested_msg43_ptr = &original_map[43].optional_nested_message();
+
+ Map<int32, TestAllTypes> moved_to_map = std::move(original_map);
+ EXPECT_TRUE(original_map.empty());
+ EXPECT_EQ(2, moved_to_map.size());
+ EXPECT_EQ(42, moved_to_map[42].optional_nested_message().bb());
+ EXPECT_EQ(43, moved_to_map[43].optional_nested_message().bb());
+ // This test takes advantage of the fact that pointers are swapped, so there
+ // should be pointer stability.
+ EXPECT_EQ(nested_msg42_ptr, &moved_to_map[42].optional_nested_message());
+ EXPECT_EQ(nested_msg43_ptr, &moved_to_map[43].optional_nested_message());
+}
+
+} // namespace
+} // namespace internal
+} // namespace protobuf
+} // namespace google
+
+#include <port_undef.inc>
diff --git a/NorthstarDedicatedTest/include/protobuf/map_test_util.h b/NorthstarDedicatedTest/include/protobuf/map_test_util.h
new file mode 100644
index 00000000..2428e63c
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/map_test_util.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.
+
+#ifndef GOOGLE_PROTOBUF_MAP_TEST_UTIL_H__
+#define GOOGLE_PROTOBUF_MAP_TEST_UTIL_H__
+
+#include <map_unittest.pb.h>
+#include <reflection_tester.h>
+
+#define UNITTEST ::protobuf_unittest
+#define BRIDGE_UNITTEST ::google::protobuf::bridge_unittest
+
+// Must be included after defining UNITTEST, etc.
+#include <map_test_util.inc>
+
+#undef UNITTEST
+#undef BRIDGE_UNITTEST
+
+#endif // GOOGLE_PROTOBUF_MAP_TEST_UTIL_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/map_test_util.inc b/NorthstarDedicatedTest/include/protobuf/map_test_util.inc
new file mode 100644
index 00000000..2d206676
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/map_test_util.inc
@@ -0,0 +1,271 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 <map_test_util_impl.h>
+#include <descriptor.h>
+#include <message.h>
+
+namespace google {
+namespace protobuf {
+
+class MapTestUtil {
+ public:
+ // Set every field in the TestMap message to a unique value.
+ static void SetMapFields(UNITTEST::TestMap* message);
+
+ // Set every field in the TestArenaMap message to a unique value.
+ static void SetArenaMapFields(UNITTEST::TestArenaMap* message);
+
+ // Set every field in the message to a default value.
+ static void SetMapFieldsInitialized(UNITTEST::TestMap* message);
+
+ // Modify all the map fields of the message (which should already have been
+ // initialized with SetMapFields()).
+ static void ModifyMapFields(UNITTEST::TestMap* message);
+
+ // Check that all fields have the values that they should have after
+ // SetMapFields() is called.
+ static void ExpectMapFieldsSet(const UNITTEST::TestMap& message);
+
+ // Check that all fields have the values that they should have after
+ // SetMapFields() is called for TestArenaMap.
+ static void ExpectArenaMapFieldsSet(const UNITTEST::TestArenaMap& message);
+
+ // Check that all fields have the values that they should have after
+ // SetMapFieldsInitialized() is called.
+ static void ExpectMapFieldsSetInitialized(const UNITTEST::TestMap& message);
+
+ // Expect that the message is modified as would be expected from
+ // ModifyMapFields().
+ static void ExpectMapFieldsModified(const UNITTEST::TestMap& message);
+
+ // Check that all fields are empty.
+ static void ExpectClear(const UNITTEST::TestMap& message);
+
+ // Check that all map fields have the given size.
+ static void ExpectMapsSize(const UNITTEST::TestMap& message, int size);
+
+ // Get pointers of map entries at given index.
+ static std::vector<const Message*> GetMapEntries(
+ const UNITTEST::TestMap& message, int index);
+
+ // Get pointers of map entries from release.
+ static std::vector<const Message*> GetMapEntriesFromRelease(
+ UNITTEST::TestMap* message);
+};
+
+inline void MapTestUtil::SetMapFields(UNITTEST::TestMap* message) {
+ MapTestUtilImpl::SetMapFields<UNITTEST::MapEnum, UNITTEST::MAP_ENUM_BAR,
+ UNITTEST::MAP_ENUM_BAZ>(message);
+}
+
+inline void MapTestUtil::SetArenaMapFields(UNITTEST::TestArenaMap* message) {
+ MapTestUtilImpl::SetArenaMapFields<UNITTEST::MapEnum, UNITTEST::MAP_ENUM_BAR,
+ UNITTEST::MAP_ENUM_BAZ>(message);
+}
+
+inline void MapTestUtil::SetMapFieldsInitialized(UNITTEST::TestMap* message) {
+ MapTestUtilImpl::SetMapFieldsInitialized(message);
+}
+
+inline void MapTestUtil::ModifyMapFields(UNITTEST::TestMap* message) {
+ MapTestUtilImpl::ModifyMapFields<UNITTEST::MapEnum, UNITTEST::MAP_ENUM_FOO>(
+ message);
+}
+
+inline void MapTestUtil::ExpectClear(const UNITTEST::TestMap& message) {
+ MapTestUtilImpl::ExpectClear(message);
+}
+
+inline void MapTestUtil::ExpectMapFieldsSet(const UNITTEST::TestMap& message) {
+ MapTestUtilImpl::ExpectMapFieldsSet<UNITTEST::MapEnum, UNITTEST::MAP_ENUM_BAR,
+ UNITTEST::MAP_ENUM_BAZ>(message);
+}
+
+inline void MapTestUtil::ExpectArenaMapFieldsSet(
+ const UNITTEST::TestArenaMap& message) {
+ MapTestUtilImpl::ExpectArenaMapFieldsSet<
+ UNITTEST::MapEnum, UNITTEST::MAP_ENUM_BAR, UNITTEST::MAP_ENUM_BAZ>(
+ message);
+}
+
+inline void MapTestUtil::ExpectMapFieldsSetInitialized(
+ const UNITTEST::TestMap& message) {
+ MapTestUtilImpl::ExpectMapFieldsSetInitialized<UNITTEST::MapEnum,
+ UNITTEST::MAP_ENUM_FOO>(
+ message);
+}
+
+inline void MapTestUtil::ExpectMapFieldsModified(
+ const UNITTEST::TestMap& message) {
+ MapTestUtilImpl::ExpectMapFieldsModified<
+ UNITTEST::MapEnum, UNITTEST::MAP_ENUM_BAR, UNITTEST::MAP_ENUM_FOO>(
+ message);
+}
+
+inline void MapTestUtil::ExpectMapsSize(const UNITTEST::TestMap& message,
+ int size) {
+ const Descriptor* descriptor = message.GetDescriptor();
+
+ EXPECT_EQ(size, message.GetReflection()->FieldSize(
+ message, descriptor->FindFieldByName("map_int32_int32")));
+ EXPECT_EQ(size, message.GetReflection()->FieldSize(
+ message, descriptor->FindFieldByName("map_int64_int64")));
+ EXPECT_EQ(size,
+ message.GetReflection()->FieldSize(
+ message, descriptor->FindFieldByName("map_uint32_uint32")));
+ EXPECT_EQ(size,
+ message.GetReflection()->FieldSize(
+ message, descriptor->FindFieldByName("map_uint64_uint64")));
+ EXPECT_EQ(size,
+ message.GetReflection()->FieldSize(
+ message, descriptor->FindFieldByName("map_sint32_sint32")));
+ EXPECT_EQ(size,
+ message.GetReflection()->FieldSize(
+ message, descriptor->FindFieldByName("map_sint64_sint64")));
+ EXPECT_EQ(size,
+ message.GetReflection()->FieldSize(
+ message, descriptor->FindFieldByName("map_fixed32_fixed32")));
+ EXPECT_EQ(size,
+ message.GetReflection()->FieldSize(
+ message, descriptor->FindFieldByName("map_fixed64_fixed64")));
+ EXPECT_EQ(size,
+ message.GetReflection()->FieldSize(
+ message, descriptor->FindFieldByName("map_sfixed32_sfixed32")));
+ EXPECT_EQ(size,
+ message.GetReflection()->FieldSize(
+ message, descriptor->FindFieldByName("map_sfixed64_sfixed64")));
+ EXPECT_EQ(size, message.GetReflection()->FieldSize(
+ message, descriptor->FindFieldByName("map_int32_float")));
+ EXPECT_EQ(size,
+ message.GetReflection()->FieldSize(
+ message, descriptor->FindFieldByName("map_int32_double")));
+ EXPECT_EQ(size, message.GetReflection()->FieldSize(
+ message, descriptor->FindFieldByName("map_bool_bool")));
+ EXPECT_EQ(size,
+ message.GetReflection()->FieldSize(
+ message, descriptor->FindFieldByName("map_string_string")));
+ EXPECT_EQ(size, message.GetReflection()->FieldSize(
+ message, descriptor->FindFieldByName("map_int32_bytes")));
+ EXPECT_EQ(
+ size,
+ message.GetReflection()->FieldSize(
+ message, descriptor->FindFieldByName("map_int32_foreign_message")));
+}
+
+inline std::vector<const Message*> MapTestUtil::GetMapEntries(
+ const UNITTEST::TestMap& message, int index) {
+ const Descriptor* descriptor = message.GetDescriptor();
+ std::vector<const Message*> result;
+
+ result.push_back(&message.GetReflection()->GetRepeatedMessage(
+ message, descriptor->FindFieldByName("map_int32_int32"), index));
+ result.push_back(&message.GetReflection()->GetRepeatedMessage(
+ message, descriptor->FindFieldByName("map_int64_int64"), index));
+ result.push_back(&message.GetReflection()->GetRepeatedMessage(
+ message, descriptor->FindFieldByName("map_uint32_uint32"), index));
+ result.push_back(&message.GetReflection()->GetRepeatedMessage(
+ message, descriptor->FindFieldByName("map_uint64_uint64"), index));
+ result.push_back(&message.GetReflection()->GetRepeatedMessage(
+ message, descriptor->FindFieldByName("map_sint32_sint32"), index));
+ result.push_back(&message.GetReflection()->GetRepeatedMessage(
+ message, descriptor->FindFieldByName("map_sint64_sint64"), index));
+ result.push_back(&message.GetReflection()->GetRepeatedMessage(
+ message, descriptor->FindFieldByName("map_fixed32_fixed32"), index));
+ result.push_back(&message.GetReflection()->GetRepeatedMessage(
+ message, descriptor->FindFieldByName("map_fixed64_fixed64"), index));
+ result.push_back(&message.GetReflection()->GetRepeatedMessage(
+ message, descriptor->FindFieldByName("map_sfixed32_sfixed32"), index));
+ result.push_back(&message.GetReflection()->GetRepeatedMessage(
+ message, descriptor->FindFieldByName("map_sfixed64_sfixed64"), index));
+ result.push_back(&message.GetReflection()->GetRepeatedMessage(
+ message, descriptor->FindFieldByName("map_int32_float"), index));
+ result.push_back(&message.GetReflection()->GetRepeatedMessage(
+ message, descriptor->FindFieldByName("map_int32_double"), index));
+ result.push_back(&message.GetReflection()->GetRepeatedMessage(
+ message, descriptor->FindFieldByName("map_bool_bool"), index));
+ result.push_back(&message.GetReflection()->GetRepeatedMessage(
+ message, descriptor->FindFieldByName("map_string_string"), index));
+ result.push_back(&message.GetReflection()->GetRepeatedMessage(
+ message, descriptor->FindFieldByName("map_int32_bytes"), index));
+ result.push_back(&message.GetReflection()->GetRepeatedMessage(
+ message, descriptor->FindFieldByName("map_int32_enum"), index));
+ result.push_back(&message.GetReflection()->GetRepeatedMessage(
+ message, descriptor->FindFieldByName("map_int32_foreign_message"),
+ index));
+
+ return result;
+}
+
+inline std::vector<const Message*> MapTestUtil::GetMapEntriesFromRelease(
+ UNITTEST::TestMap* message) {
+ const Descriptor* descriptor = message->GetDescriptor();
+ std::vector<const Message*> result;
+
+ result.push_back(message->GetReflection()->ReleaseLast(
+ message, descriptor->FindFieldByName("map_int32_int32")));
+ result.push_back(message->GetReflection()->ReleaseLast(
+ message, descriptor->FindFieldByName("map_int64_int64")));
+ result.push_back(message->GetReflection()->ReleaseLast(
+ message, descriptor->FindFieldByName("map_uint32_uint32")));
+ result.push_back(message->GetReflection()->ReleaseLast(
+ message, descriptor->FindFieldByName("map_uint64_uint64")));
+ result.push_back(message->GetReflection()->ReleaseLast(
+ message, descriptor->FindFieldByName("map_sint32_sint32")));
+ result.push_back(message->GetReflection()->ReleaseLast(
+ message, descriptor->FindFieldByName("map_sint64_sint64")));
+ result.push_back(message->GetReflection()->ReleaseLast(
+ message, descriptor->FindFieldByName("map_fixed32_fixed32")));
+ result.push_back(message->GetReflection()->ReleaseLast(
+ message, descriptor->FindFieldByName("map_fixed64_fixed64")));
+ result.push_back(message->GetReflection()->ReleaseLast(
+ message, descriptor->FindFieldByName("map_sfixed32_sfixed32")));
+ result.push_back(message->GetReflection()->ReleaseLast(
+ message, descriptor->FindFieldByName("map_sfixed64_sfixed64")));
+ result.push_back(message->GetReflection()->ReleaseLast(
+ message, descriptor->FindFieldByName("map_int32_float")));
+ result.push_back(message->GetReflection()->ReleaseLast(
+ message, descriptor->FindFieldByName("map_int32_double")));
+ result.push_back(message->GetReflection()->ReleaseLast(
+ message, descriptor->FindFieldByName("map_bool_bool")));
+ result.push_back(message->GetReflection()->ReleaseLast(
+ message, descriptor->FindFieldByName("map_string_string")));
+ result.push_back(message->GetReflection()->ReleaseLast(
+ message, descriptor->FindFieldByName("map_int32_bytes")));
+ result.push_back(message->GetReflection()->ReleaseLast(
+ message, descriptor->FindFieldByName("map_int32_enum")));
+ result.push_back(message->GetReflection()->ReleaseLast(
+ message, descriptor->FindFieldByName("map_int32_foreign_message")));
+
+ return result;
+}
+
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/map_test_util_impl.h b/NorthstarDedicatedTest/include/protobuf/map_test_util_impl.h
new file mode 100644
index 00000000..512a1baf
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/map_test_util_impl.h
@@ -0,0 +1,476 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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_TEST_UTIL_IMPL_H__
+#define GOOGLE_PROTOBUF_MAP_TEST_UTIL_IMPL_H__
+
+#include <stubs/logging.h>
+#include <stubs/common.h>
+#include <gtest/gtest.h>
+
+
+namespace protobuf_unittest {} // namespace protobuf_unittest
+
+namespace google {
+namespace protobuf {
+
+namespace unittest = ::protobuf_unittest;
+
+class MapTestUtilImpl {
+ public:
+ // Set every field in the TestMap message to a unique value.
+ template <typename EnumType, EnumType enum_value0, EnumType enum_value1,
+ typename MapMessage>
+ static void SetMapFields(MapMessage* message);
+
+ // Set every field in the TestArenaMap message to a unique value.
+ template <typename EnumType, EnumType enum_value0, EnumType enum_value1,
+ typename MapMessage>
+ static void SetArenaMapFields(MapMessage* message);
+
+ // Set every field in the message to a default value.
+ template <typename MapMessage>
+ static void SetMapFieldsInitialized(MapMessage* message);
+
+ // Modify all the map fields of the message (which should already have been
+ // initialized with SetMapFields()).
+ template <typename EnumType, EnumType enum_value, typename MapMessage>
+ static void ModifyMapFields(MapMessage* message);
+
+ // Check that all fields have the values that they should have after
+ // SetMapFields() is called.
+ template <typename EnumType, EnumType enum_value0, EnumType enum_value1,
+ typename MapMessage>
+ static void ExpectMapFieldsSet(const MapMessage& message);
+
+ // Check that all fields have the values that they should have after
+ // SetMapFields() is called for TestArenaMap.
+ template <typename EnumType, EnumType enum_value0, EnumType enum_value1,
+ typename MapMessage>
+ static void ExpectArenaMapFieldsSet(const MapMessage& message);
+
+ // Check that all fields have the values that they should have after
+ // SetMapFieldsInitialized() is called.
+ template <typename EnumType, EnumType enum_value, typename MapMessage>
+ static void ExpectMapFieldsSetInitialized(const MapMessage& message);
+
+ // Expect that the message is modified as would be expected from
+ // ModifyMapFields().
+ template <typename EnumType, EnumType enum_value0, EnumType enum_value1,
+ typename MapMessage>
+ static void ExpectMapFieldsModified(const MapMessage& message);
+
+ // Check that all fields are empty.
+ template <typename MapMessage>
+ static void ExpectClear(const MapMessage& message);
+
+ // // Check that all map fields have the given size.
+ // template <typename MapMessage>
+ // static void ExpectMapsSize(const MapMessage& message, int size);
+
+ // // Get pointers of map entries at given index.
+ // static std::vector<const Message*> GetMapEntries(
+ // const MapMessage& message, int index);
+
+ // // Get pointers of map entries from release.
+ // static std::vector<const Message*> GetMapEntriesFromRelease(
+ // MapMessage* message);
+};
+
+template <typename EnumType, EnumType enum_value0, EnumType enum_value1,
+ typename MapMessage>
+void MapTestUtilImpl::SetMapFields(MapMessage* message) {
+ // Add first element.
+ (*message->mutable_map_int32_int32())[0] = 0;
+ (*message->mutable_map_int64_int64())[0] = 0;
+ (*message->mutable_map_uint32_uint32())[0] = 0;
+ (*message->mutable_map_uint64_uint64())[0] = 0;
+ (*message->mutable_map_sint32_sint32())[0] = 0;
+ (*message->mutable_map_sint64_sint64())[0] = 0;
+ (*message->mutable_map_fixed32_fixed32())[0] = 0;
+ (*message->mutable_map_fixed64_fixed64())[0] = 0;
+ (*message->mutable_map_sfixed32_sfixed32())[0] = 0;
+ (*message->mutable_map_sfixed64_sfixed64())[0] = 0;
+ (*message->mutable_map_int32_float())[0] = 0.0;
+ (*message->mutable_map_int32_double())[0] = 0.0;
+ (*message->mutable_map_bool_bool())[0] = false;
+ (*message->mutable_map_string_string())["0"] = "0";
+ (*message->mutable_map_int32_bytes())[0] = "0";
+ (*message->mutable_map_int32_enum())[0] = enum_value0;
+ (*message->mutable_map_int32_foreign_message())[0].set_c(0);
+
+ // Add second element
+ (*message->mutable_map_int32_int32())[1] = 1;
+ (*message->mutable_map_int64_int64())[1] = 1;
+ (*message->mutable_map_uint32_uint32())[1] = 1;
+ (*message->mutable_map_uint64_uint64())[1] = 1;
+ (*message->mutable_map_sint32_sint32())[1] = 1;
+ (*message->mutable_map_sint64_sint64())[1] = 1;
+ (*message->mutable_map_fixed32_fixed32())[1] = 1;
+ (*message->mutable_map_fixed64_fixed64())[1] = 1;
+ (*message->mutable_map_sfixed32_sfixed32())[1] = 1;
+ (*message->mutable_map_sfixed64_sfixed64())[1] = 1;
+ (*message->mutable_map_int32_float())[1] = 1.0;
+ (*message->mutable_map_int32_double())[1] = 1.0;
+ (*message->mutable_map_bool_bool())[1] = true;
+ (*message->mutable_map_string_string())["1"] = "1";
+ (*message->mutable_map_int32_bytes())[1] = "1";
+ (*message->mutable_map_int32_enum())[1] = enum_value1;
+ (*message->mutable_map_int32_foreign_message())[1].set_c(1);
+}
+
+template <typename EnumType, EnumType enum_value0, EnumType enum_value1,
+ typename MapMessage>
+void MapTestUtilImpl::SetArenaMapFields(MapMessage* message) {
+ // Add first element.
+ (*message->mutable_map_int32_int32())[0] = 0;
+ (*message->mutable_map_int64_int64())[0] = 0;
+ (*message->mutable_map_uint32_uint32())[0] = 0;
+ (*message->mutable_map_uint64_uint64())[0] = 0;
+ (*message->mutable_map_sint32_sint32())[0] = 0;
+ (*message->mutable_map_sint64_sint64())[0] = 0;
+ (*message->mutable_map_fixed32_fixed32())[0] = 0;
+ (*message->mutable_map_fixed64_fixed64())[0] = 0;
+ (*message->mutable_map_sfixed32_sfixed32())[0] = 0;
+ (*message->mutable_map_sfixed64_sfixed64())[0] = 0;
+ (*message->mutable_map_int32_float())[0] = 0.0;
+ (*message->mutable_map_int32_double())[0] = 0.0;
+ (*message->mutable_map_bool_bool())[0] = false;
+ (*message->mutable_map_string_string())["0"] = "0";
+ (*message->mutable_map_int32_bytes())[0] = "0";
+ (*message->mutable_map_int32_enum())[0] = enum_value0;
+ (*message->mutable_map_int32_foreign_message())[0].set_c(0);
+
+ // Add second element
+ (*message->mutable_map_int32_int32())[1] = 1;
+ (*message->mutable_map_int64_int64())[1] = 1;
+ (*message->mutable_map_uint32_uint32())[1] = 1;
+ (*message->mutable_map_uint64_uint64())[1] = 1;
+ (*message->mutable_map_sint32_sint32())[1] = 1;
+ (*message->mutable_map_sint64_sint64())[1] = 1;
+ (*message->mutable_map_fixed32_fixed32())[1] = 1;
+ (*message->mutable_map_fixed64_fixed64())[1] = 1;
+ (*message->mutable_map_sfixed32_sfixed32())[1] = 1;
+ (*message->mutable_map_sfixed64_sfixed64())[1] = 1;
+ (*message->mutable_map_int32_float())[1] = 1.0;
+ (*message->mutable_map_int32_double())[1] = 1.0;
+ (*message->mutable_map_bool_bool())[1] = true;
+ (*message->mutable_map_string_string())["1"] = "1";
+ (*message->mutable_map_int32_bytes())[1] = "1";
+ (*message->mutable_map_int32_enum())[1] = enum_value1;
+ (*message->mutable_map_int32_foreign_message())[1].set_c(1);
+}
+
+template <typename MapMessage>
+void MapTestUtilImpl::SetMapFieldsInitialized(MapMessage* message) {
+ // Add first element using bracket operator, which should assign default
+ // value automatically.
+ (*message->mutable_map_int32_int32())[0];
+ (*message->mutable_map_int64_int64())[0];
+ (*message->mutable_map_uint32_uint32())[0];
+ (*message->mutable_map_uint64_uint64())[0];
+ (*message->mutable_map_sint32_sint32())[0];
+ (*message->mutable_map_sint64_sint64())[0];
+ (*message->mutable_map_fixed32_fixed32())[0];
+ (*message->mutable_map_fixed64_fixed64())[0];
+ (*message->mutable_map_sfixed32_sfixed32())[0];
+ (*message->mutable_map_sfixed64_sfixed64())[0];
+ (*message->mutable_map_int32_float())[0];
+ (*message->mutable_map_int32_double())[0];
+ (*message->mutable_map_bool_bool())[0];
+ (*message->mutable_map_string_string())["0"];
+ (*message->mutable_map_int32_bytes())[0];
+ (*message->mutable_map_int32_enum())[0];
+ (*message->mutable_map_int32_foreign_message())[0];
+}
+
+template <typename EnumType, EnumType enum_value, typename MapMessage>
+void MapTestUtilImpl::ModifyMapFields(MapMessage* message) {
+ (*message->mutable_map_int32_int32())[1] = 2;
+ (*message->mutable_map_int64_int64())[1] = 2;
+ (*message->mutable_map_uint32_uint32())[1] = 2;
+ (*message->mutable_map_uint64_uint64())[1] = 2;
+ (*message->mutable_map_sint32_sint32())[1] = 2;
+ (*message->mutable_map_sint64_sint64())[1] = 2;
+ (*message->mutable_map_fixed32_fixed32())[1] = 2;
+ (*message->mutable_map_fixed64_fixed64())[1] = 2;
+ (*message->mutable_map_sfixed32_sfixed32())[1] = 2;
+ (*message->mutable_map_sfixed64_sfixed64())[1] = 2;
+ (*message->mutable_map_int32_float())[1] = 2.0;
+ (*message->mutable_map_int32_double())[1] = 2.0;
+ (*message->mutable_map_bool_bool())[1] = false;
+ (*message->mutable_map_string_string())["1"] = "2";
+ (*message->mutable_map_int32_bytes())[1] = "2";
+ (*message->mutable_map_int32_enum())[1] = enum_value;
+ (*message->mutable_map_int32_foreign_message())[1].set_c(2);
+}
+
+template <typename MapMessage>
+void MapTestUtilImpl::ExpectClear(const MapMessage& message) {
+ EXPECT_EQ(0, message.map_int32_int32().size());
+ EXPECT_EQ(0, message.map_int64_int64().size());
+ EXPECT_EQ(0, message.map_uint32_uint32().size());
+ EXPECT_EQ(0, message.map_uint64_uint64().size());
+ EXPECT_EQ(0, message.map_sint32_sint32().size());
+ EXPECT_EQ(0, message.map_sint64_sint64().size());
+ EXPECT_EQ(0, message.map_fixed32_fixed32().size());
+ EXPECT_EQ(0, message.map_fixed64_fixed64().size());
+ EXPECT_EQ(0, message.map_sfixed32_sfixed32().size());
+ EXPECT_EQ(0, message.map_sfixed64_sfixed64().size());
+ EXPECT_EQ(0, message.map_int32_float().size());
+ EXPECT_EQ(0, message.map_int32_double().size());
+ EXPECT_EQ(0, message.map_bool_bool().size());
+ EXPECT_EQ(0, message.map_string_string().size());
+ EXPECT_EQ(0, message.map_int32_bytes().size());
+ EXPECT_EQ(0, message.map_int32_enum().size());
+ EXPECT_EQ(0, message.map_int32_foreign_message().size());
+}
+
+template <typename EnumType, EnumType enum_value0, EnumType enum_value1,
+ typename MapMessage>
+void MapTestUtilImpl::ExpectMapFieldsSet(const MapMessage& message) {
+ ASSERT_EQ(2, message.map_int32_int32().size());
+ ASSERT_EQ(2, message.map_int64_int64().size());
+ ASSERT_EQ(2, message.map_uint32_uint32().size());
+ ASSERT_EQ(2, message.map_uint64_uint64().size());
+ ASSERT_EQ(2, message.map_sint32_sint32().size());
+ ASSERT_EQ(2, message.map_sint64_sint64().size());
+ ASSERT_EQ(2, message.map_fixed32_fixed32().size());
+ ASSERT_EQ(2, message.map_fixed64_fixed64().size());
+ ASSERT_EQ(2, message.map_sfixed32_sfixed32().size());
+ ASSERT_EQ(2, message.map_sfixed64_sfixed64().size());
+ ASSERT_EQ(2, message.map_int32_float().size());
+ ASSERT_EQ(2, message.map_int32_double().size());
+ ASSERT_EQ(2, message.map_bool_bool().size());
+ ASSERT_EQ(2, message.map_string_string().size());
+ ASSERT_EQ(2, message.map_int32_bytes().size());
+ ASSERT_EQ(2, message.map_int32_enum().size());
+ ASSERT_EQ(2, message.map_int32_foreign_message().size());
+
+ EXPECT_EQ(0, message.map_int32_int32().at(0));
+ EXPECT_EQ(0, message.map_int64_int64().at(0));
+ EXPECT_EQ(0, message.map_uint32_uint32().at(0));
+ EXPECT_EQ(0, message.map_uint64_uint64().at(0));
+ EXPECT_EQ(0, message.map_sint32_sint32().at(0));
+ EXPECT_EQ(0, message.map_sint64_sint64().at(0));
+ EXPECT_EQ(0, message.map_fixed32_fixed32().at(0));
+ EXPECT_EQ(0, message.map_fixed64_fixed64().at(0));
+ EXPECT_EQ(0, message.map_sfixed32_sfixed32().at(0));
+ EXPECT_EQ(0, message.map_sfixed64_sfixed64().at(0));
+ EXPECT_EQ(0, message.map_int32_float().at(0));
+ EXPECT_EQ(0, message.map_int32_double().at(0));
+ EXPECT_EQ(false, message.map_bool_bool().at(0));
+ EXPECT_EQ("0", message.map_string_string().at("0"));
+ EXPECT_EQ("0", message.map_int32_bytes().at(0));
+ EXPECT_EQ(enum_value0, message.map_int32_enum().at(0));
+ EXPECT_EQ(0, message.map_int32_foreign_message().at(0).c());
+
+ EXPECT_EQ(1, message.map_int32_int32().at(1));
+ EXPECT_EQ(1, message.map_int64_int64().at(1));
+ EXPECT_EQ(1, message.map_uint32_uint32().at(1));
+ EXPECT_EQ(1, message.map_uint64_uint64().at(1));
+ EXPECT_EQ(1, message.map_sint32_sint32().at(1));
+ EXPECT_EQ(1, message.map_sint64_sint64().at(1));
+ EXPECT_EQ(1, message.map_fixed32_fixed32().at(1));
+ EXPECT_EQ(1, message.map_fixed64_fixed64().at(1));
+ EXPECT_EQ(1, message.map_sfixed32_sfixed32().at(1));
+ EXPECT_EQ(1, message.map_sfixed64_sfixed64().at(1));
+ EXPECT_EQ(1, message.map_int32_float().at(1));
+ EXPECT_EQ(1, message.map_int32_double().at(1));
+ EXPECT_EQ(true, message.map_bool_bool().at(1));
+ EXPECT_EQ("1", message.map_string_string().at("1"));
+ EXPECT_EQ("1", message.map_int32_bytes().at(1));
+ EXPECT_EQ(enum_value1, message.map_int32_enum().at(1));
+ EXPECT_EQ(1, message.map_int32_foreign_message().at(1).c());
+}
+
+template <typename EnumType, EnumType enum_value0, EnumType enum_value1,
+ typename MapMessage>
+void MapTestUtilImpl::ExpectArenaMapFieldsSet(const MapMessage& message) {
+ EXPECT_EQ(2, message.map_int32_int32().size());
+ EXPECT_EQ(2, message.map_int64_int64().size());
+ EXPECT_EQ(2, message.map_uint32_uint32().size());
+ EXPECT_EQ(2, message.map_uint64_uint64().size());
+ EXPECT_EQ(2, message.map_sint32_sint32().size());
+ EXPECT_EQ(2, message.map_sint64_sint64().size());
+ EXPECT_EQ(2, message.map_fixed32_fixed32().size());
+ EXPECT_EQ(2, message.map_fixed64_fixed64().size());
+ EXPECT_EQ(2, message.map_sfixed32_sfixed32().size());
+ EXPECT_EQ(2, message.map_sfixed64_sfixed64().size());
+ EXPECT_EQ(2, message.map_int32_float().size());
+ EXPECT_EQ(2, message.map_int32_double().size());
+ EXPECT_EQ(2, message.map_bool_bool().size());
+ EXPECT_EQ(2, message.map_string_string().size());
+ EXPECT_EQ(2, message.map_int32_bytes().size());
+ EXPECT_EQ(2, message.map_int32_enum().size());
+ EXPECT_EQ(2, message.map_int32_foreign_message().size());
+
+ EXPECT_EQ(0, message.map_int32_int32().at(0));
+ EXPECT_EQ(0, message.map_int64_int64().at(0));
+ EXPECT_EQ(0, message.map_uint32_uint32().at(0));
+ EXPECT_EQ(0, message.map_uint64_uint64().at(0));
+ EXPECT_EQ(0, message.map_sint32_sint32().at(0));
+ EXPECT_EQ(0, message.map_sint64_sint64().at(0));
+ EXPECT_EQ(0, message.map_fixed32_fixed32().at(0));
+ EXPECT_EQ(0, message.map_fixed64_fixed64().at(0));
+ EXPECT_EQ(0, message.map_sfixed32_sfixed32().at(0));
+ EXPECT_EQ(0, message.map_sfixed64_sfixed64().at(0));
+ EXPECT_EQ(0, message.map_int32_float().at(0));
+ EXPECT_EQ(0, message.map_int32_double().at(0));
+ EXPECT_EQ(false, message.map_bool_bool().at(0));
+ EXPECT_EQ("0", message.map_string_string().at("0"));
+ EXPECT_EQ("0", message.map_int32_bytes().at(0));
+ EXPECT_EQ(enum_value0, message.map_int32_enum().at(0));
+ EXPECT_EQ(0, message.map_int32_foreign_message().at(0).c());
+
+ EXPECT_EQ(1, message.map_int32_int32().at(1));
+ EXPECT_EQ(1, message.map_int64_int64().at(1));
+ EXPECT_EQ(1, message.map_uint32_uint32().at(1));
+ EXPECT_EQ(1, message.map_uint64_uint64().at(1));
+ EXPECT_EQ(1, message.map_sint32_sint32().at(1));
+ EXPECT_EQ(1, message.map_sint64_sint64().at(1));
+ EXPECT_EQ(1, message.map_fixed32_fixed32().at(1));
+ EXPECT_EQ(1, message.map_fixed64_fixed64().at(1));
+ EXPECT_EQ(1, message.map_sfixed32_sfixed32().at(1));
+ EXPECT_EQ(1, message.map_sfixed64_sfixed64().at(1));
+ EXPECT_EQ(1, message.map_int32_float().at(1));
+ EXPECT_EQ(1, message.map_int32_double().at(1));
+ EXPECT_EQ(true, message.map_bool_bool().at(1));
+ EXPECT_EQ("1", message.map_string_string().at("1"));
+ EXPECT_EQ("1", message.map_int32_bytes().at(1));
+ EXPECT_EQ(enum_value1, message.map_int32_enum().at(1));
+ EXPECT_EQ(1, message.map_int32_foreign_message().at(1).c());
+}
+
+template <typename EnumType, EnumType enum_value, typename MapMessage>
+void MapTestUtilImpl::ExpectMapFieldsSetInitialized(const MapMessage& message) {
+ EXPECT_EQ(1, message.map_int32_int32().size());
+ EXPECT_EQ(1, message.map_int64_int64().size());
+ EXPECT_EQ(1, message.map_uint32_uint32().size());
+ EXPECT_EQ(1, message.map_uint64_uint64().size());
+ EXPECT_EQ(1, message.map_sint32_sint32().size());
+ EXPECT_EQ(1, message.map_sint64_sint64().size());
+ EXPECT_EQ(1, message.map_fixed32_fixed32().size());
+ EXPECT_EQ(1, message.map_fixed64_fixed64().size());
+ EXPECT_EQ(1, message.map_sfixed32_sfixed32().size());
+ EXPECT_EQ(1, message.map_sfixed64_sfixed64().size());
+ EXPECT_EQ(1, message.map_int32_float().size());
+ EXPECT_EQ(1, message.map_int32_double().size());
+ EXPECT_EQ(1, message.map_bool_bool().size());
+ EXPECT_EQ(1, message.map_string_string().size());
+ EXPECT_EQ(1, message.map_int32_bytes().size());
+ EXPECT_EQ(1, message.map_int32_enum().size());
+ EXPECT_EQ(1, message.map_int32_foreign_message().size());
+
+ EXPECT_EQ(0, message.map_int32_int32().at(0));
+ EXPECT_EQ(0, message.map_int64_int64().at(0));
+ EXPECT_EQ(0, message.map_uint32_uint32().at(0));
+ EXPECT_EQ(0, message.map_uint64_uint64().at(0));
+ EXPECT_EQ(0, message.map_sint32_sint32().at(0));
+ EXPECT_EQ(0, message.map_sint64_sint64().at(0));
+ EXPECT_EQ(0, message.map_fixed32_fixed32().at(0));
+ EXPECT_EQ(0, message.map_fixed64_fixed64().at(0));
+ EXPECT_EQ(0, message.map_sfixed32_sfixed32().at(0));
+ EXPECT_EQ(0, message.map_sfixed64_sfixed64().at(0));
+ EXPECT_EQ(0, message.map_int32_float().at(0));
+ EXPECT_EQ(0, message.map_int32_double().at(0));
+ EXPECT_EQ(false, message.map_bool_bool().at(0));
+ EXPECT_EQ("", message.map_string_string().at("0"));
+ EXPECT_EQ("", message.map_int32_bytes().at(0));
+ EXPECT_EQ(enum_value, message.map_int32_enum().at(0));
+ EXPECT_EQ(0, message.map_int32_foreign_message().at(0).ByteSizeLong());
+}
+
+template <typename EnumType, EnumType enum_value0, EnumType enum_value1,
+ typename MapMessage>
+void MapTestUtilImpl::ExpectMapFieldsModified(const MapMessage& message) {
+ // ModifyMapFields only sets the second element of each field. In addition to
+ // verifying this, we also verify that the first element and size were *not*
+ // modified.
+ EXPECT_EQ(2, message.map_int32_int32().size());
+ EXPECT_EQ(2, message.map_int64_int64().size());
+ EXPECT_EQ(2, message.map_uint32_uint32().size());
+ EXPECT_EQ(2, message.map_uint64_uint64().size());
+ EXPECT_EQ(2, message.map_sint32_sint32().size());
+ EXPECT_EQ(2, message.map_sint64_sint64().size());
+ EXPECT_EQ(2, message.map_fixed32_fixed32().size());
+ EXPECT_EQ(2, message.map_fixed64_fixed64().size());
+ EXPECT_EQ(2, message.map_sfixed32_sfixed32().size());
+ EXPECT_EQ(2, message.map_sfixed64_sfixed64().size());
+ EXPECT_EQ(2, message.map_int32_float().size());
+ EXPECT_EQ(2, message.map_int32_double().size());
+ EXPECT_EQ(2, message.map_bool_bool().size());
+ EXPECT_EQ(2, message.map_string_string().size());
+ EXPECT_EQ(2, message.map_int32_bytes().size());
+ EXPECT_EQ(2, message.map_int32_enum().size());
+ EXPECT_EQ(2, message.map_int32_foreign_message().size());
+
+ EXPECT_EQ(0, message.map_int32_int32().at(0));
+ EXPECT_EQ(0, message.map_int64_int64().at(0));
+ EXPECT_EQ(0, message.map_uint32_uint32().at(0));
+ EXPECT_EQ(0, message.map_uint64_uint64().at(0));
+ EXPECT_EQ(0, message.map_sint32_sint32().at(0));
+ EXPECT_EQ(0, message.map_sint64_sint64().at(0));
+ EXPECT_EQ(0, message.map_fixed32_fixed32().at(0));
+ EXPECT_EQ(0, message.map_fixed64_fixed64().at(0));
+ EXPECT_EQ(0, message.map_sfixed32_sfixed32().at(0));
+ EXPECT_EQ(0, message.map_sfixed64_sfixed64().at(0));
+ EXPECT_EQ(0, message.map_int32_float().at(0));
+ EXPECT_EQ(0, message.map_int32_double().at(0));
+ EXPECT_EQ(false, message.map_bool_bool().at(0));
+ EXPECT_EQ("0", message.map_string_string().at("0"));
+ EXPECT_EQ("0", message.map_int32_bytes().at(0));
+ EXPECT_EQ(enum_value0, message.map_int32_enum().at(0));
+ EXPECT_EQ(0, message.map_int32_foreign_message().at(0).c());
+
+ // Actually verify the second (modified) elements now.
+ EXPECT_EQ(2, message.map_int32_int32().at(1));
+ EXPECT_EQ(2, message.map_int64_int64().at(1));
+ EXPECT_EQ(2, message.map_uint32_uint32().at(1));
+ EXPECT_EQ(2, message.map_uint64_uint64().at(1));
+ EXPECT_EQ(2, message.map_sint32_sint32().at(1));
+ EXPECT_EQ(2, message.map_sint64_sint64().at(1));
+ EXPECT_EQ(2, message.map_fixed32_fixed32().at(1));
+ EXPECT_EQ(2, message.map_fixed64_fixed64().at(1));
+ EXPECT_EQ(2, message.map_sfixed32_sfixed32().at(1));
+ EXPECT_EQ(2, message.map_sfixed64_sfixed64().at(1));
+ EXPECT_EQ(2, message.map_int32_float().at(1));
+ EXPECT_EQ(2, message.map_int32_double().at(1));
+ EXPECT_EQ(false, message.map_bool_bool().at(1));
+ EXPECT_EQ("2", message.map_string_string().at("1"));
+ EXPECT_EQ("2", message.map_int32_bytes().at(1));
+ EXPECT_EQ(enum_value1, message.map_int32_enum().at(1));
+ EXPECT_EQ(2, message.map_int32_foreign_message().at(1).c());
+}
+
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_MAP_TEST_UTIL_IMPL_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/map_type_handler.h b/NorthstarDedicatedTest/include/protobuf/map_type_handler.h
new file mode 100644
index 00000000..d8570c03
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/map_type_handler.h
@@ -0,0 +1,691 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef GOOGLE_PROTOBUF_MAP_TYPE_HANDLER_H__
+#define GOOGLE_PROTOBUF_MAP_TYPE_HANDLER_H__
+
+#include <parse_context.h>
+#include <io/coded_stream.h>
+#include <arena.h>
+#include <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, 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(&internal::GetEmptyStringAlreadyInited(), from, arena); \
+ } \
+ template <typename Type> \
+ void MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::DeleteNoArena( \
+ TypeOnMemory& value) { \
+ value.DestroyNoArena(&internal::GetEmptyStringAlreadyInited()); \
+ } \
+ template <typename Type> \
+ constexpr auto \
+ MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::Constinit() \
+ ->TypeOnMemory { \
+ return TypeOnMemory(&internal::fixed_address_empty_string); \
+ } \
+ template <typename Type> \
+ inline typename MapTypeHandler<WireFormatLite::TYPE_##FieldType, \
+ Type>::MapEntryAccessorType* \
+ MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::EnsureMutable( \
+ TypeOnMemory* value, Arena* arena) { \
+ return value->Mutable(ArenaStringPtr::EmptyDefault{}, arena); \
+ } \
+ template <typename Type> \
+ inline const typename MapTypeHandler<WireFormatLite::TYPE_##FieldType, \
+ Type>::MapEntryAccessorType& \
+ MapTypeHandler<WireFormatLite::TYPE_##FieldType, \
+ Type>::DefaultIfNotInitialized(const TypeOnMemory& value) { \
+ return value.Get(); \
+ } \
+ template <typename Type> \
+ inline bool \
+ MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::IsInitialized( \
+ const TypeOnMemory& /* value */) { \
+ return true; \
+ }
+STRING_OR_BYTES_HANDLER_FUNCTIONS(STRING)
+STRING_OR_BYTES_HANDLER_FUNCTIONS(BYTES)
+#undef STRING_OR_BYTES_HANDLER_FUNCTIONS
+
+#define PRIMITIVE_HANDLER_FUNCTIONS(FieldType) \
+ template <typename Type> \
+ inline const typename MapTypeHandler<WireFormatLite::TYPE_##FieldType, \
+ Type>::MapEntryAccessorType& \
+ MapTypeHandler<WireFormatLite::TYPE_##FieldType, \
+ Type>::GetExternalReference(const TypeOnMemory& value) { \
+ return value; \
+ } \
+ template <typename Type> \
+ inline size_t MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>:: \
+ SpaceUsedInMapEntryLong(const TypeOnMemory& /* value */) { \
+ return 0; \
+ } \
+ template <typename Type> \
+ inline void MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::Clear( \
+ TypeOnMemory* value, Arena* /* arena */) { \
+ *value = 0; \
+ } \
+ template <typename Type> \
+ inline void MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::Merge( \
+ const MapEntryAccessorType& from, TypeOnMemory* to, \
+ Arena* /* arena */) { \
+ *to = from; \
+ } \
+ template <typename Type> \
+ inline void MapTypeHandler<WireFormatLite::TYPE_##FieldType, \
+ Type>::DeleteNoArena(TypeOnMemory& /* x */) {} \
+ template <typename Type> \
+ constexpr auto \
+ MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::Constinit() \
+ ->TypeOnMemory { \
+ return 0; \
+ } \
+ template <typename Type> \
+ inline typename MapTypeHandler<WireFormatLite::TYPE_##FieldType, \
+ Type>::MapEntryAccessorType* \
+ MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::EnsureMutable( \
+ TypeOnMemory* value, Arena* /* arena */) { \
+ return value; \
+ } \
+ template <typename Type> \
+ inline const typename MapTypeHandler<WireFormatLite::TYPE_##FieldType, \
+ Type>::MapEntryAccessorType& \
+ MapTypeHandler<WireFormatLite::TYPE_##FieldType, \
+ Type>::DefaultIfNotInitialized(const TypeOnMemory& value) { \
+ return value; \
+ } \
+ template <typename Type> \
+ inline bool \
+ MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::IsInitialized( \
+ const TypeOnMemory& /* value */) { \
+ return true; \
+ }
+PRIMITIVE_HANDLER_FUNCTIONS(INT64)
+PRIMITIVE_HANDLER_FUNCTIONS(UINT64)
+PRIMITIVE_HANDLER_FUNCTIONS(INT32)
+PRIMITIVE_HANDLER_FUNCTIONS(UINT32)
+PRIMITIVE_HANDLER_FUNCTIONS(SINT64)
+PRIMITIVE_HANDLER_FUNCTIONS(SINT32)
+PRIMITIVE_HANDLER_FUNCTIONS(ENUM)
+PRIMITIVE_HANDLER_FUNCTIONS(DOUBLE)
+PRIMITIVE_HANDLER_FUNCTIONS(FLOAT)
+PRIMITIVE_HANDLER_FUNCTIONS(FIXED64)
+PRIMITIVE_HANDLER_FUNCTIONS(FIXED32)
+PRIMITIVE_HANDLER_FUNCTIONS(SFIXED64)
+PRIMITIVE_HANDLER_FUNCTIONS(SFIXED32)
+PRIMITIVE_HANDLER_FUNCTIONS(BOOL)
+#undef PRIMITIVE_HANDLER_FUNCTIONS
+
+} // namespace internal
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_MAP_TYPE_HANDLER_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/map_unittest.proto b/NorthstarDedicatedTest/include/protobuf/map_unittest.proto
new file mode 100644
index 00000000..263ef61f
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/map_unittest.proto
@@ -0,0 +1,125 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+syntax = "proto3";
+
+option cc_enable_arenas = true;
+
+import "google/protobuf/unittest.proto";
+
+// We don't put this in a package within proto2 because we need to make sure
+// that the generated code doesn't depend on being in the proto2 namespace.
+// In map_test_util.h we do "using namespace unittest = protobuf_unittest".
+package protobuf_unittest;
+
+// Tests maps.
+message TestMap {
+ map<int32, int32> map_int32_int32 = 1;
+ map<int64, int64> map_int64_int64 = 2;
+ map<uint32, uint32> map_uint32_uint32 = 3;
+ map<uint64, uint64> map_uint64_uint64 = 4;
+ map<sint32, sint32> map_sint32_sint32 = 5;
+ map<sint64, sint64> map_sint64_sint64 = 6;
+ map<fixed32, fixed32> map_fixed32_fixed32 = 7;
+ map<fixed64, fixed64> map_fixed64_fixed64 = 8;
+ map<sfixed32, sfixed32> map_sfixed32_sfixed32 = 9;
+ map<sfixed64, sfixed64> map_sfixed64_sfixed64 = 10;
+ map<int32, float> map_int32_float = 11;
+ map<int32, double> map_int32_double = 12;
+ map<bool, bool> map_bool_bool = 13;
+ map<string, string> map_string_string = 14;
+ map<int32, bytes> map_int32_bytes = 15;
+ map<int32, MapEnum> map_int32_enum = 16;
+ map<int32, ForeignMessage> map_int32_foreign_message = 17;
+ map<string, ForeignMessage> map_string_foreign_message = 18;
+ map<int32, TestAllTypes> map_int32_all_types = 19;
+}
+
+message TestMapSubmessage {
+ TestMap test_map = 1;
+}
+
+message TestMessageMap {
+ map<int32, TestAllTypes> map_int32_message = 1;
+}
+
+// Two map fields share the same entry default instance.
+message TestSameTypeMap {
+ map<int32, int32> map1 = 1;
+ map<int32, int32> map2 = 2;
+}
+
+
+enum MapEnum {
+ MAP_ENUM_FOO = 0;
+ MAP_ENUM_BAR = 1;
+ MAP_ENUM_BAZ = 2;
+}
+
+// Test embedded message with required fields
+message TestRequiredMessageMap {
+ map<int32, TestRequired> map_field = 1;
+}
+
+message TestArenaMap {
+ map<int32, int32> map_int32_int32 = 1;
+ map<int64, int64> map_int64_int64 = 2;
+ map<uint32, uint32> map_uint32_uint32 = 3;
+ map<uint64, uint64> map_uint64_uint64 = 4;
+ map<sint32, sint32> map_sint32_sint32 = 5;
+ map<sint64, sint64> map_sint64_sint64 = 6;
+ map<fixed32, fixed32> map_fixed32_fixed32 = 7;
+ map<fixed64, fixed64> map_fixed64_fixed64 = 8;
+ map<sfixed32, sfixed32> map_sfixed32_sfixed32 = 9;
+ map<sfixed64, sfixed64> map_sfixed64_sfixed64 = 10;
+ map<int32, float> map_int32_float = 11;
+ map<int32, double> map_int32_double = 12;
+ map<bool, bool> map_bool_bool = 13;
+ map<string, string> map_string_string = 14;
+ map<int32, bytes> map_int32_bytes = 15;
+ map<int32, MapEnum> map_int32_enum = 16;
+ map<int32, ForeignMessage> map_int32_foreign_message = 17;
+}
+
+// Previously, message containing enum called Type cannot be used as value of
+// map field.
+message MessageContainingEnumCalledType {
+ enum Type { TYPE_FOO = 0; }
+ map<string, MessageContainingEnumCalledType> type = 1;
+}
+
+// Previously, message cannot contain map field called "entry".
+message MessageContainingMapCalledEntry {
+ map<int32, int32> entry = 1;
+}
+
+message TestRecursiveMapMessage {
+ map<string, TestRecursiveMapMessage> a = 1;
+}
diff --git a/NorthstarDedicatedTest/include/protobuf/message.cc b/NorthstarDedicatedTest/include/protobuf/message.cc
new file mode 100644
index 00000000..f808ff22
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/message.cc
@@ -0,0 +1,400 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <message.h>
+
+#include <iostream>
+#include <stack>
+#include <unordered_map>
+
+#include <stubs/casts.h>
+#include <stubs/logging.h>
+#include <stubs/common.h>
+#include <descriptor.pb.h>
+#include <parse_context.h>
+#include <reflection_internal.h>
+#include <io/coded_stream.h>
+#include <io/zero_copy_stream_impl.h>
+#include <descriptor.h>
+#include <generated_message_reflection.h>
+#include <generated_message_util.h>
+#include <map_field.h>
+#include <map_field_inl.h>
+#include <reflection_ops.h>
+#include <unknown_field_set.h>
+#include <wire_format.h>
+#include <wire_format_lite.h>
+#include <stubs/strutil.h>
+#include <stubs/map_util.h>
+#include <stubs/stl_util.h>
+#include <stubs/hash.h>
+
+#include <port_def.inc>
+
+namespace google {
+namespace protobuf {
+
+namespace internal {
+
+// TODO(gerbens) make this factorized better. This should not have to hop
+// to reflection. Currently uses GeneratedMessageReflection and thus is
+// defined in generated_message_reflection.cc
+void RegisterFileLevelMetadata(const DescriptorTable* descriptor_table);
+
+} // namespace internal
+
+using internal::ReflectionOps;
+using internal::WireFormat;
+using internal::WireFormatLite;
+
+void Message::MergeFrom(const Message& from) {
+ auto* class_to = GetClassData();
+ auto* class_from = from.GetClassData();
+ auto* merge_to_from = class_to ? class_to->merge_to_from : nullptr;
+ if (class_to == nullptr || class_to != class_from) {
+ merge_to_from = [](Message* to, const Message& from) {
+ ReflectionOps::Merge(from, to);
+ };
+ }
+ merge_to_from(this, from);
+}
+
+void Message::CheckTypeAndMergeFrom(const MessageLite& other) {
+ MergeFrom(*down_cast<const Message*>(&other));
+}
+
+void Message::CopyFrom(const Message& from) {
+ if (&from == this) return;
+
+ auto* class_to = GetClassData();
+ auto* class_from = from.GetClassData();
+ auto* copy_to_from = class_to ? class_to->copy_to_from : nullptr;
+
+ if (class_to == nullptr || class_to != class_from) {
+ const Descriptor* descriptor = GetDescriptor();
+ GOOGLE_CHECK_EQ(from.GetDescriptor(), descriptor)
+ << ": Tried to copy from a message with a different type. "
+ "to: "
+ << descriptor->full_name()
+ << ", "
+ "from: "
+ << from.GetDescriptor()->full_name();
+ copy_to_from = [](Message* to, const Message& from) {
+ ReflectionOps::Copy(from, to);
+ };
+ }
+ copy_to_from(this, from);
+}
+
+void Message::CopyWithSizeCheck(Message* to, const Message& from) {
+#ifndef NDEBUG
+ size_t from_size = from.ByteSizeLong();
+#endif
+ to->Clear();
+#ifndef NDEBUG
+ GOOGLE_CHECK_EQ(from_size, from.ByteSizeLong())
+ << "Source of CopyFrom changed when clearing target. Either "
+ "source is a nested message in target (not allowed), or "
+ "another thread is modifying the source.";
+#endif
+ to->GetClassData()->merge_to_from(to, from);
+}
+
+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 <port_undef.inc>
diff --git a/NorthstarDedicatedTest/include/protobuf/message.h b/NorthstarDedicatedTest/include/protobuf/message.h
new file mode 100644
index 00000000..0ab3fe77
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/message.h
@@ -0,0 +1,1487 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 <stubs/casts.h>
+#include <stubs/common.h>
+#include <arena.h>
+#include <descriptor.h>
+#include <generated_message_reflection.h>
+#include <generated_message_util.h>
+#include <message_lite.h>
+#include <port.h>
+
+
+#define GOOGLE_PROTOBUF_HAS_ONEOF
+#define GOOGLE_PROTOBUF_HAS_ARENAS
+
+#include <port_def.inc>
+
+#ifdef SWIG
+#error "You cannot SWIG proto headers"
+#endif
+
+namespace google {
+namespace protobuf {
+
+// Defined in this file.
+class Message;
+class Reflection;
+class MessageFactory;
+
+// Defined in other files.
+class AssignDescriptorsHelper;
+class DynamicMessageFactory;
+class DynamicMessageReflectionHelper;
+class GeneratedMessageReflectionTestHelper;
+class MapKey;
+class MapValueConstRef;
+class MapValueRef;
+class MapIterator;
+class MapReflectionTester;
+
+namespace internal {
+struct DescriptorTable;
+class MapFieldBase;
+class SwapFieldHelper;
+class CachedSize;
+} // namespace internal
+class UnknownFieldSet; // unknown_field_set.h
+namespace io {
+class ZeroCopyInputStream; // zero_copy_stream.h
+class ZeroCopyOutputStream; // zero_copy_stream.h
+class CodedInputStream; // coded_stream.h
+class CodedOutputStream; // coded_stream.h
+} // namespace io
+namespace python {
+class MapReflectionFriend; // scalar_map_container.h
+class MessageReflectionFriend;
+} // namespace python
+namespace expr {
+class CelMapReflectionFriend; // field_backed_map_impl.cc
+}
+
+namespace internal {
+class MapFieldPrinterHelper; // text_format.cc
+}
+namespace util {
+class MessageDifferencer;
+}
+
+
+namespace internal {
+class ReflectionAccessor; // message.cc
+class ReflectionOps; // reflection_ops.h
+class MapKeySorter; // wire_format.cc
+class WireFormat; // wire_format.h
+class MapFieldReflectionTest; // map_test.cc
+} // namespace internal
+
+template <typename T>
+class RepeatedField; // repeated_field.h
+
+template <typename T>
+class RepeatedPtrField; // repeated_field.h
+
+// A container to hold message metadata.
+struct Metadata {
+ const Descriptor* descriptor;
+ const Reflection* reflection;
+};
+
+namespace internal {
+template <class To>
+inline To* GetPointerAtOffset(Message* message, 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);
+} // namespace internal
+
+// Abstract interface for protocol messages.
+//
+// See also MessageLite, which contains most every-day operations. Message
+// adds descriptors and reflection on top of that.
+//
+// The methods of this class that are virtual but not pure-virtual have
+// default implementations based on reflection. Message classes which are
+// optimized for speed will want to override these with faster implementations,
+// but classes optimized for code size may be happy with keeping them. See
+// the optimize_for option in descriptor.proto.
+//
+// Users must not derive from this class. Only the protocol compiler and
+// the internal library are allowed to create subclasses.
+class PROTOBUF_EXPORT Message : public MessageLite {
+ public:
+ constexpr Message() {}
+
+ // Basic Operations ------------------------------------------------
+
+ // Construct a new instance of the same type. Ownership is passed to the
+ // caller. (This is also defined in MessageLite, but is defined again here
+ // for return-type covariance.)
+ Message* New() const { return New(nullptr); }
+
+ // Construct a new instance on the arena. Ownership is passed to the caller
+ // if arena is a nullptr.
+ Message* New(Arena* arena) const override = 0;
+
+ // Make this message into a copy of the given message. The given message
+ // must have the same descriptor, but need not necessarily be the same class.
+ // By default this is just implemented as "Clear(); MergeFrom(from);".
+ virtual void CopyFrom(const Message& from);
+
+ // Merge the fields from the given message into this message. Singular
+ // fields will be overwritten, if specified in from, except for embedded
+ // messages which will be merged. Repeated fields will be concatenated.
+ // The given message must be of the same type as this message (i.e. the
+ // exact same class).
+ virtual void MergeFrom(const Message& from);
+
+ // Verifies that IsInitialized() returns true. GOOGLE_CHECK-fails otherwise, with
+ // a nice error message.
+ void CheckInitialized() const;
+
+ // Slowly build a list of all required fields that are not set.
+ // This is much, much slower than IsInitialized() as it is implemented
+ // purely via reflection. Generally, you should not call this unless you
+ // have already determined that an error exists by calling IsInitialized().
+ void FindInitializationErrors(std::vector<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, useful for debugging
+ // and other purposes.
+ 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; }
+
+ // CopyWithSizeCheck calls Clear() and then MergeFrom(), and in debug
+ // builds, checks that calling Clear() on the destination message doesn't
+ // alter the size of the source. It assumes the messages are known to be
+ // of the same type, and thus uses GetClassData().
+ static void CopyWithSizeCheck(Message* to, const Message& from);
+
+ inline explicit Message(Arena* arena, bool is_message_owned = false)
+ : MessageLite(arena, is_message_owned) {}
+ size_t ComputeUnknownFieldsSize(size_t total_size,
+ internal::CachedSize* cached_size) const;
+ size_t MaybeComputeUnknownFieldsSize(size_t total_size,
+ internal::CachedSize* cached_size) const;
+
+
+ protected:
+ static 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;
+
+ const Descriptor* const descriptor_;
+ const internal::ReflectionSchema schema_;
+ const DescriptorPool* const descriptor_pool_;
+ MessageFactory* const message_factory_;
+
+ // Last non weak field index. This is an optimization when most weak fields
+ // are at the end of the containing message. If a message proto doesn't
+ // contain weak fields, then this field equals descriptor_->field_count().
+ int last_non_weak_field_index_;
+
+ template <typename T, typename Enable>
+ friend class RepeatedFieldRef;
+ template <typename T, typename Enable>
+ friend class MutableRepeatedFieldRef;
+ friend class ::PROTOBUF_NAMESPACE_ID::MessageLayoutInspector;
+ friend class ::PROTOBUF_NAMESPACE_ID::AssignDescriptorsHelper;
+ friend class DynamicMessageFactory;
+ friend class DynamicMessageReflectionHelper;
+ friend class GeneratedMessageReflectionTestHelper;
+ friend class python::MapReflectionFriend;
+ friend class python::MessageReflectionFriend;
+ friend class util::MessageDifferencer;
+#define GOOGLE_PROTOBUF_HAS_CEL_MAP_REFLECTION_FRIEND
+ friend class expr::CelMapReflectionFriend;
+ friend class internal::MapFieldReflectionTest;
+ friend class internal::MapKeySorter;
+ friend class internal::WireFormat;
+ friend class internal::ReflectionOps;
+ friend class internal::SwapFieldHelper;
+ // Needed for implementing text format for map.
+ friend class internal::MapFieldPrinterHelper;
+
+ Reflection(const Descriptor* descriptor,
+ const internal::ReflectionSchema& schema,
+ const DescriptorPool* pool, MessageFactory* factory);
+
+ // Special version for specialized implementations of string. We can't
+ // call MutableRawRepeatedField directly here because we don't have access to
+ // FieldOptions::* which are defined in descriptor.pb.h. Including that
+ // file here is not possible because it would cause a circular include cycle.
+ // We use 1 routine rather than 2 (const vs mutable) because it is private
+ // and mutable a repeated string field doesn't change the message.
+ void* MutableRawRepeatedString(Message* message, const FieldDescriptor* field,
+ bool is_string) const;
+
+ friend class MapReflectionTester;
+ // Returns true if key is in map. Returns false if key is not in map field.
+ bool ContainsMapKey(const Message& message, const FieldDescriptor* field,
+ const MapKey& key) const;
+
+ // If key is in map field: Saves the value pointer to val and returns
+ // false. If key in not in map field: Insert the key into map, saves
+ // value pointer to val and returns true. Users are able to modify the
+ // map value by MapValueRef.
+ bool InsertOrLookupMapValue(Message* message, const FieldDescriptor* field,
+ const MapKey& key, MapValueRef* val) const;
+
+ // If key is in map field: Saves the value pointer to val and returns true.
+ // Returns false if key is not in map field. Users are NOT able to modify
+ // the value by MapValueConstRef.
+ bool LookupMapValue(const Message& message, const FieldDescriptor* field,
+ const MapKey& key, MapValueConstRef* val) const;
+ bool LookupMapValue(const Message&, const FieldDescriptor*, const MapKey&,
+ MapValueRef*) const = delete;
+
+ // Delete and returns true if key is in the map field. Returns false
+ // otherwise.
+ bool DeleteMapValue(Message* message, const FieldDescriptor* field,
+ const MapKey& key) const;
+
+ // Returns a MapIterator referring to the first element in the map field.
+ // If the map field is empty, this function returns the same as
+ // reflection::MapEnd. Mutation to the field may invalidate the iterator.
+ MapIterator MapBegin(Message* message, const FieldDescriptor* field) const;
+
+ // Returns a MapIterator referring to the theoretical element that would
+ // follow the last element in the map field. It does not point to any
+ // real element. Mutation to the field may invalidate the iterator.
+ MapIterator MapEnd(Message* message, const FieldDescriptor* field) const;
+
+ // Get the number of <key, value> pair of a map field. The result may be
+ // different from FieldSize which can have duplicate keys.
+ int MapSize(const Message& message, const FieldDescriptor* field) const;
+
+ // Help method for MapIterator.
+ friend class MapIterator;
+ friend class WireFormatForMapFieldTest;
+ internal::MapFieldBase* MutableMapData(Message* message,
+ const FieldDescriptor* field) const;
+
+ const internal::MapFieldBase* GetMapData(const Message& message,
+ const FieldDescriptor* field) const;
+
+ template <class T>
+ const T& GetRawNonOneof(const Message& message,
+ const FieldDescriptor* field) const;
+ template <class T>
+ T* MutableRawNonOneof(Message* message, const FieldDescriptor* field) const;
+
+ template <typename Type>
+ const Type& GetRaw(const Message& message,
+ const FieldDescriptor* field) const;
+ template <typename Type>
+ inline Type* MutableRaw(Message* message, const FieldDescriptor* field) const;
+ template <typename Type>
+ const Type& DefaultRaw(const FieldDescriptor* field) const;
+
+ const Message* GetDefaultMessageInstance(const FieldDescriptor* field) const;
+
+ inline const 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;
+
+ inline const internal::InternalMetadata& GetInternalMetadata(
+ const Message& message) const;
+
+ internal::InternalMetadata* MutableInternalMetadata(Message* message) const;
+
+ inline bool IsInlined(const FieldDescriptor* field) const;
+
+ inline bool HasBit(const Message& message,
+ const FieldDescriptor* field) const;
+ inline void SetBit(Message* message, const FieldDescriptor* field) const;
+ inline void ClearBit(Message* message, const FieldDescriptor* field) const;
+ inline void SwapBit(Message* message1, Message* message2,
+ const FieldDescriptor* field) const;
+
+ inline const uint32_t* GetInlinedStringDonatedArray(
+ const Message& message) const;
+ inline uint32_t* MutableInlinedStringDonatedArray(Message* message) const;
+ inline bool IsInlinedStringDonated(const Message& message,
+ const FieldDescriptor* field) const;
+
+ // Shallow-swap fields listed in fields vector of two messages. It is the
+ // caller's responsibility to make sure shallow swap is safe.
+ void UnsafeShallowSwapFields(
+ Message* message1, Message* message2,
+ const std::vector<const FieldDescriptor*>& fields) const;
+
+ // This function only swaps the field. Should swap corresponding has_bit
+ // before or after using this function.
+ void SwapField(Message* message1, Message* message2,
+ const FieldDescriptor* field) const;
+
+ // Unsafe but shallow version of SwapField.
+ void UnsafeShallowSwapField(Message* message1, Message* message2,
+ const FieldDescriptor* field) const;
+
+ template <bool unsafe_shallow_swap>
+ void SwapFieldsImpl(Message* message1, Message* message2,
+ const std::vector<const FieldDescriptor*>& fields) const;
+
+ template <bool unsafe_shallow_swap>
+ void SwapOneofField(Message* lhs, Message* rhs,
+ const OneofDescriptor* oneof_descriptor) const;
+
+ inline bool HasOneofField(const Message& message,
+ const FieldDescriptor* field) const;
+ inline void SetOneofCase(Message* message,
+ const FieldDescriptor* field) const;
+ inline void ClearOneofField(Message* message,
+ const FieldDescriptor* field) const;
+
+ template <typename Type>
+ inline const Type& GetField(const Message& message,
+ const FieldDescriptor* field) const;
+ template <typename Type>
+ inline void SetField(Message* message, const FieldDescriptor* field,
+ const Type& value) const;
+ template <typename Type>
+ inline Type* MutableField(Message* message,
+ const FieldDescriptor* field) const;
+ template <typename Type>
+ inline const Type& GetRepeatedField(const Message& message,
+ const FieldDescriptor* field,
+ int index) const;
+ template <typename Type>
+ inline const Type& GetRepeatedPtrField(const Message& message,
+ const FieldDescriptor* field,
+ int index) const;
+ template <typename Type>
+ inline void SetRepeatedField(Message* message, const FieldDescriptor* field,
+ int index, Type value) const;
+ template <typename Type>
+ inline Type* MutableRepeatedField(Message* message,
+ const FieldDescriptor* field,
+ int index) const;
+ template <typename Type>
+ inline void AddField(Message* message, const FieldDescriptor* field,
+ const Type& value) const;
+ template <typename Type>
+ inline Type* AddField(Message* message, const FieldDescriptor* field) const;
+
+ int GetExtensionNumberOrDie(const Descriptor* type) const;
+
+ // Internal versions of EnumValue API perform no checking. Called after checks
+ // by public methods.
+ void SetEnumValueInternal(Message* message, const FieldDescriptor* field,
+ int value) const;
+ void SetRepeatedEnumValueInternal(Message* message,
+ const FieldDescriptor* field, int index,
+ int value) const;
+ void AddEnumValueInternal(Message* message, const FieldDescriptor* field,
+ int value) const;
+
+ friend inline // inline so nobody can call this function.
+ void
+ RegisterAllTypesInternal(const Metadata* file_level_metadata, int size);
+ friend inline const char* ParseLenDelim(int field_number,
+ const FieldDescriptor* field,
+ Message* msg,
+ const Reflection* reflection,
+ const char* ptr,
+ internal::ParseContext* ctx);
+ friend inline const char* ParsePackedField(const FieldDescriptor* field,
+ Message* msg,
+ const Reflection* reflection,
+ const char* ptr,
+ internal::ParseContext* ctx);
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Reflection);
+};
+
+// Abstract interface for a factory for message objects.
+class PROTOBUF_EXPORT MessageFactory {
+ public:
+ inline MessageFactory() {}
+ virtual ~MessageFactory();
+
+ // Given a Descriptor, gets or constructs the default (prototype) Message
+ // of that type. You can then call that message's New() method to construct
+ // a mutable message of that type.
+ //
+ // Calling this method twice with the same Descriptor returns the same
+ // object. The returned object remains property of the factory. Also, any
+ // objects created by calling the prototype's New() method share some data
+ // with the prototype, so these must be destroyed before the MessageFactory
+ // is destroyed.
+ //
+ // The given descriptor must outlive the returned message, and hence must
+ // outlive the MessageFactory.
+ //
+ // Some implementations do not support all types. GetPrototype() will
+ // return nullptr if the descriptor passed in is not supported.
+ //
+ // This method may or may not be thread-safe depending on the implementation.
+ // Each implementation should document its own degree thread-safety.
+ virtual const Message* GetPrototype(const Descriptor* type) = 0;
+
+ // Gets a MessageFactory which supports all generated, compiled-in messages.
+ // In other words, for any compiled-in type FooMessage, the following is true:
+ // MessageFactory::generated_factory()->GetPrototype(
+ // FooMessage::descriptor()) == FooMessage::default_instance()
+ // This factory supports all types which are found in
+ // DescriptorPool::generated_pool(). If given a descriptor from any other
+ // pool, GetPrototype() will return nullptr. (You can also check if a
+ // descriptor is for a generated message by checking if
+ // descriptor->file()->pool() == DescriptorPool::generated_pool().)
+ //
+ // This factory is 100% thread-safe; calling GetPrototype() does not modify
+ // any shared data.
+ //
+ // This factory is a singleton. The caller must not delete the object.
+ static MessageFactory* generated_factory();
+
+ // For internal use only: Registers a .proto file at static initialization
+ // time, to be placed in generated_factory. The first time GetPrototype()
+ // is called with a descriptor from this file, |register_messages| will be
+ // called, with the file name as the parameter. It must call
+ // InternalRegisterGeneratedMessage() (below) to register each message type
+ // in the file. This strange mechanism is necessary because descriptors are
+ // built lazily, so we can't register types by their descriptor until we
+ // know that the descriptor exists. |filename| must be a permanent string.
+ static void InternalRegisterGeneratedFile(
+ const google::protobuf::internal::DescriptorTable* table);
+
+ // For internal use only: Registers a message type. Called only by the
+ // functions which are registered with InternalRegisterGeneratedFile(),
+ // above.
+ static void InternalRegisterGeneratedMessage(const Descriptor* descriptor,
+ const Message* prototype);
+
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageFactory);
+};
+
+#define DECLARE_GET_REPEATED_FIELD(TYPE) \
+ template <> \
+ PROTOBUF_EXPORT const RepeatedField<TYPE>& \
+ Reflection::GetRepeatedFieldInternal<TYPE>( \
+ const Message& message, const FieldDescriptor* field) const; \
+ \
+ template <> \
+ PROTOBUF_EXPORT RepeatedField<TYPE>* \
+ Reflection::MutableRepeatedFieldInternal<TYPE>( \
+ Message * message, const FieldDescriptor* field) const;
+
+DECLARE_GET_REPEATED_FIELD(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<FooMessage>();
+//
+// This will ensure that the following lookup will succeed:
+//
+// DescriptorPool::generated_pool()->FindMessageTypeByName("FooMessage");
+//
+// As a side-effect, it will also guarantee that anything else from the same
+// .proto file will also be available for lookup in the generated pool.
+//
+// This function does not actually register the message, so it does not need
+// to be called before the lookup. However it does need to occur in a function
+// that cannot be stripped from the binary (ie. it must be reachable from main).
+//
+// Best practice is to call this function as close as possible to where the
+// reflection is actually needed. This function is very cheap to call, so you
+// should not need to worry about its runtime overhead except in the tightest
+// of loops (on x86-64 it compiles into two "mov" instructions).
+template <typename T>
+void LinkMessageReflection() {
+ internal::StrongReference(T::default_instance);
+}
+
+// =============================================================================
+// Implementation details for {Get,Mutable}RawRepeatedPtrField. We provide
+// specializations for <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 <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_MESSAGE_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/message_lite.cc b/NorthstarDedicatedTest/include/protobuf/message_lite.cc
new file mode 100644
index 00000000..2bbacebb
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/message_lite.cc
@@ -0,0 +1,595 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 <message_lite.h>
+
+#include <climits>
+#include <cstdint>
+#include <string>
+
+#include <stubs/logging.h>
+#include <stubs/common.h>
+#include <stubs/stringprintf.h>
+#include <parse_context.h>
+#include <io/coded_stream.h>
+#include <io/zero_copy_stream.h>
+#include <io/zero_copy_stream_impl.h>
+#include <io/zero_copy_stream_impl_lite.h>
+#include <arena.h>
+#include <generated_message_table_driven.h>
+#include <generated_message_util.h>
+#include <repeated_field.h>
+#include <stubs/strutil.h>
+#include <stubs/stl_util.h>
+#include <stubs/mutex.h>
+
+#include <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(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 {
+
+template <>
+MessageLite* GenericTypeHandler<MessageLite>::NewFromPrototype(
+ const MessageLite* prototype, Arena* arena) {
+ return prototype->New(arena);
+}
+template <>
+void GenericTypeHandler<MessageLite>::Merge(const MessageLite& from,
+ MessageLite* to) {
+ to->CheckTypeAndMergeFrom(from);
+}
+template <>
+void GenericTypeHandler<std::string>::Merge(const std::string& from,
+ std::string* to) {
+ *to = from;
+}
+
+// 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 <port_undef.inc>
diff --git a/NorthstarDedicatedTest/include/protobuf/message_lite.h b/NorthstarDedicatedTest/include/protobuf/message_lite.h
new file mode 100644
index 00000000..4a735b26
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/message_lite.h
@@ -0,0 +1,593 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 <stubs/common.h>
+#include <stubs/logging.h>
+#include <io/coded_stream.h>
+#include <arena.h>
+#include <explicitly_constructed.h>
+#include <metadata_lite.h>
+#include <stubs/once.h>
+#include <port.h>
+#include <stubs/strutil.h>
+
+
+// clang-format off
+#include <port_def.inc>
+// clang-format on
+
+#ifdef SWIG
+#error "You cannot SWIG proto headers"
+#endif
+
+namespace google {
+namespace protobuf {
+
+template <typename T>
+class RepeatedPtrField;
+
+class FastReflectionMessageMutator;
+class FastReflectionStringSetter;
+class Reflection;
+
+namespace io {
+
+class CodedInputStream;
+class CodedOutputStream;
+class ZeroCopyInputStream;
+class ZeroCopyOutputStream;
+
+} // namespace io
+namespace internal {
+
+class SwapFieldHelper;
+
+// Tag type used to invoke the constinit constructor overload of some classes.
+// Such constructors are internal implementation details of the library.
+struct ConstantInitialized {
+ explicit ConstantInitialized() = default;
+};
+
+// See parse_context.h for explanation
+class ParseContext;
+
+class ExtensionSet;
+class LazyField;
+class RepeatedPtrFieldBase;
+class TcParser;
+class WireFormatLite;
+class WeakFieldMap;
+
+template <typename Type>
+class GenericTypeHandler; // defined in repeated_field.h
+
+// We compute sizes as size_t but cache them as int. This function converts a
+// computed size to a cached size. Since we don't proceed with serialization
+// if the total size was > INT_MAX, it is not important what this function
+// returns for inputs > INT_MAX. However this case should not error or
+// GOOGLE_CHECK-fail, because the full size_t resolution is still returned from
+// ByteSizeLong() and checked against INT_MAX; we can catch the overflow
+// there.
+inline int ToCachedSize(size_t size) { return static_cast<int>(size); }
+
+// We mainly calculate sizes in terms of size_t, but some functions that
+// compute sizes return "int". These int sizes are expected to always be
+// positive. This function is more efficient than casting an int to size_t
+// directly on 64-bit platforms because it avoids making the compiler emit a
+// sign extending instruction, which we don't want and don't want to pay for.
+inline size_t FromIntSize(int size) {
+ // Convert to unsigned before widening so sign extension is not necessary.
+ return static_cast<unsigned int>(size);
+}
+
+// For cases where a legacy function returns an integer size. We GOOGLE_DCHECK()
+// that the conversion will fit within an integer; if this is false then we
+// are losing information.
+inline int ToIntSize(size_t size) {
+ GOOGLE_DCHECK_LE(size, static_cast<size_t>(INT_MAX));
+ return static_cast<int>(size);
+}
+
+// Default empty string object. Don't use this directly. Instead, call
+// GetEmptyString() to get the reference.
+PROTOBUF_EXPORT extern ExplicitlyConstructed<std::string>
+ 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;
+
+ // Same as GetOwningArena.
+ Arena* GetArena() const { return GetOwningArena(); }
+
+ // Clear all fields of the message and set them to their default values.
+ // Clear() avoids freeing memory, assuming that any memory allocated
+ // to hold parts of the message will be needed again to hold the next
+ // message. If you actually want to free the memory used by a Message,
+ // you must delete it.
+ virtual void Clear() = 0;
+
+ // Quickly check if all required fields have values set.
+ virtual bool IsInitialized() const = 0;
+
+ // This is not implemented for Lite messages -- it just returns "(cannot
+ // determine missing fields for lite message)". However, it is implemented
+ // for full messages. See message.h.
+ virtual 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;
+ }
+
+ protected:
+ template <typename T>
+ static T* CreateMaybeMessage(Arena* arena) {
+ return Arena::CreateMaybeMessage<T>(arena);
+ }
+
+ inline explicit MessageLite(Arena* arena, bool is_message_owned = false)
+ : _internal_metadata_(arena, is_message_owned) {}
+
+ // Returns the arena, if any, that directly owns this message and its internal
+ // memory (Arena::Own is different in that the arena doesn't directly own the
+ // internal memory). This method is used in proto's implementation for
+ // swapping, moving and setting allocated, for deciding whether the ownership
+ // of this message or its internal memory could be changed.
+ Arena* GetOwningArena() const { return _internal_metadata_.owning_arena(); }
+
+ // Returns the arena, used for allocating internal objects(e.g., child
+ // messages, etc), or owning incoming objects (e.g., set allocated).
+ Arena* GetArenaForAllocation() const { return _internal_metadata_.arena(); }
+
+ internal::InternalMetadata _internal_metadata_;
+
+ public:
+ enum ParseFlags {
+ kMerge = 0,
+ kParse = 1,
+ kMergePartial = 2,
+ kParsePartial = 3,
+ kMergeWithAliasing = 4,
+ kParseWithAliasing = 5,
+ kMergePartialWithAliasing = 6,
+ kParsePartialWithAliasing = 7
+ };
+
+ template <ParseFlags flags, typename T>
+ 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:
+ // TODO(gerbens) make this a pure abstract function
+ virtual const void* InternalGetTable() const { return nullptr; }
+
+ friend class FastReflectionMessageMutator;
+ friend class FastReflectionStringSetter;
+ friend class Message;
+ friend class Reflection;
+ friend class internal::ExtensionSet;
+ friend class internal::LazyField;
+ friend class internal::SwapFieldHelper;
+ friend class internal::TcParser;
+ friend class internal::WeakFieldMap;
+ friend class internal::WireFormatLite;
+
+ template <typename Type>
+ friend class Arena::InternalHelper;
+ template <typename Type>
+ friend class internal::GenericTypeHandler;
+
+ void LogInitializationErrorMessage() const;
+
+ 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 <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_MESSAGE_LITE_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/message_unittest.cc b/NorthstarDedicatedTest/include/protobuf/message_unittest.cc
new file mode 100644
index 00000000..96202fbe
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/message_unittest.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.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <unittest.pb.h>
+
+#define MESSAGE_TEST_NAME MessageTest
+#define MESSAGE_FACTORY_TEST_NAME MessageFactoryTest
+#define UNITTEST_PACKAGE_NAME "protobuf_unittest"
+#define UNITTEST ::protobuf_unittest
+#define UNITTEST_IMPORT ::protobuf_unittest_import
+
+// Must include after the above macros.
+// clang-format off
+#include <test_util.inc>
+#include <message_unittest.inc>
+#include <arena.h>
+// clang-format on
diff --git a/NorthstarDedicatedTest/include/protobuf/message_unittest.inc b/NorthstarDedicatedTest/include/protobuf/message_unittest.inc
new file mode 100644
index 00000000..6037eb94
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/message_unittest.inc
@@ -0,0 +1,897 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 needs to be included as .inc as it depends on certain macros being
+// defined prior to its inclusion.
+
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include <cmath>
+#include <limits>
+
+#include <message.h>
+#ifndef _MSC_VER
+#include <unistd.h>
+#endif
+#include <fstream>
+#include <sstream>
+
+#include <stubs/logging.h>
+#include <stubs/common.h>
+#include <test_util2.h>
+#include <io/coded_stream.h>
+#include <io/zero_copy_stream.h>
+#include <io/zero_copy_stream_impl.h>
+#include <descriptor.pb.h>
+#include <arena.h>
+#include <descriptor.h>
+#include <generated_message_reflection.h>
+#include <gmock/gmock.h>
+#include <testing/googletest.h>
+#include <gtest/gtest.h>
+#include <stubs/logging.h>
+#include <stubs/substitute.h>
+#include <io/io_win32.h>
+
+
+namespace google {
+namespace protobuf {
+
+#if defined(_WIN32)
+// 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::close;
+using google::protobuf::io::win32::open;
+#endif
+
+#ifndef O_BINARY
+#ifdef _O_BINARY
+#define O_BINARY _O_BINARY
+#else
+#define O_BINARY 0 // If this isn't defined, the platform doesn't need it.
+#endif
+#endif
+
+TEST(MESSAGE_TEST_NAME, SerializeHelpers) {
+ // TODO(kenton): Test more helpers? They're all two-liners so it seems
+ // like a waste of time.
+
+ UNITTEST::TestAllTypes message;
+ TestUtil::SetAllFields(&message);
+ std::stringstream stream;
+
+ std::string str1("foo");
+ std::string str2("bar");
+
+ EXPECT_TRUE(message.SerializeToString(&str1));
+ EXPECT_TRUE(message.AppendToString(&str2));
+ EXPECT_TRUE(message.SerializeToOstream(&stream));
+
+ EXPECT_EQ(str1.size() + 3, str2.size());
+ EXPECT_EQ("bar", str2.substr(0, 3));
+ // Don't use EXPECT_EQ because we don't want to dump raw binary data to
+ // stdout.
+ EXPECT_TRUE(str2.substr(3) == str1);
+
+ // GCC gives some sort of error if we try to just do stream.str() == str1.
+ std::string temp = stream.str();
+ EXPECT_TRUE(temp == str1);
+
+ EXPECT_TRUE(message.SerializeAsString() == str1);
+
+}
+
+TEST(MESSAGE_TEST_NAME, SerializeToBrokenOstream) {
+ std::ofstream out;
+ UNITTEST::TestAllTypes message;
+ message.set_optional_int32(123);
+
+ EXPECT_FALSE(message.SerializeToOstream(&out));
+}
+
+TEST(MESSAGE_TEST_NAME, ParseFromFileDescriptor) {
+ std::string filename =
+ TestUtil::GetTestDataPath("net/proto2/internal/testdata/golden_message");
+ int file = open(filename.c_str(), O_RDONLY | O_BINARY);
+ ASSERT_GE(file, 0);
+
+ UNITTEST::TestAllTypes message;
+ EXPECT_TRUE(message.ParseFromFileDescriptor(file));
+ TestUtil::ExpectAllFieldsSet(message);
+
+ EXPECT_GE(close(file), 0);
+}
+
+TEST(MESSAGE_TEST_NAME, ParsePackedFromFileDescriptor) {
+ std::string filename = TestUtil::GetTestDataPath(
+ "net/proto2/internal/testdata/golden_packed_fields_message");
+ int file = open(filename.c_str(), O_RDONLY | O_BINARY);
+ ASSERT_GE(file, 0);
+
+ UNITTEST::TestPackedTypes message;
+ EXPECT_TRUE(message.ParseFromFileDescriptor(file));
+ TestUtil::ExpectPackedFieldsSet(message);
+
+ EXPECT_GE(close(file), 0);
+}
+
+TEST(MESSAGE_TEST_NAME, ParseHelpers) {
+ // TODO(kenton): Test more helpers? They're all two-liners so it seems
+ // like a waste of time.
+ std::string data;
+
+ {
+ // Set up.
+ UNITTEST::TestAllTypes message;
+ TestUtil::SetAllFields(&message);
+ message.SerializeToString(&data);
+ }
+
+ {
+ // Test ParseFromString.
+ UNITTEST::TestAllTypes message;
+ EXPECT_TRUE(message.ParseFromString(data));
+ TestUtil::ExpectAllFieldsSet(message);
+ }
+
+ {
+ // Test ParseFromIstream.
+ UNITTEST::TestAllTypes message;
+ std::stringstream stream(data);
+ EXPECT_TRUE(message.ParseFromIstream(&stream));
+ EXPECT_TRUE(stream.eof());
+ TestUtil::ExpectAllFieldsSet(message);
+ }
+
+ {
+ // Test ParseFromBoundedZeroCopyStream.
+ std::string data_with_junk(data);
+ data_with_junk.append("some junk on the end");
+ io::ArrayInputStream stream(data_with_junk.data(), data_with_junk.size());
+ UNITTEST::TestAllTypes message;
+ EXPECT_TRUE(message.ParseFromBoundedZeroCopyStream(&stream, data.size()));
+ TestUtil::ExpectAllFieldsSet(message);
+ }
+
+ {
+ // Test that ParseFromBoundedZeroCopyStream fails (but doesn't crash) if
+ // EOF is reached before the expected number of bytes.
+ io::ArrayInputStream stream(data.data(), data.size());
+ UNITTEST::TestAllTypes message;
+ EXPECT_FALSE(
+ message.ParseFromBoundedZeroCopyStream(&stream, data.size() + 1));
+ }
+}
+
+TEST(MESSAGE_TEST_NAME, ParseFailsIfNotInitialized) {
+ UNITTEST::TestRequired message;
+ std::vector<std::string> errors;
+
+ {
+ ScopedMemoryLog log;
+ EXPECT_FALSE(message.ParseFromString(""));
+ errors = log.GetMessages(ERROR);
+ }
+
+ ASSERT_EQ(1, errors.size());
+ EXPECT_EQ(
+ "Can't parse message of type \"" + std::string(UNITTEST_PACKAGE_NAME) +
+ ".TestRequired\" because it is missing required fields: a, b, c",
+ errors[0]);
+}
+
+TEST(MESSAGE_TEST_NAME, ParseFailsIfSubmessageNotInitialized) {
+ UNITTEST::TestRequiredForeign source, message;
+ source.mutable_optional_message()->set_dummy2(100);
+ std::string serialized = source.SerializePartialAsString();
+
+ EXPECT_TRUE(message.ParsePartialFromString(serialized));
+ EXPECT_FALSE(message.IsInitialized());
+
+ std::vector<std::string> errors;
+ {
+ ScopedMemoryLog log;
+ EXPECT_FALSE(message.ParseFromString(source.SerializePartialAsString()));
+ errors = log.GetMessages(ERROR);
+ }
+
+ EXPECT_THAT(
+ errors,
+ testing::ElementsAre(
+ "Can't parse message of type \"" +
+ std::string(UNITTEST_PACKAGE_NAME) +
+ ".TestRequiredForeign\" because it is missing required fields: "
+ "optional_message.a, optional_message.b, optional_message.c"));
+}
+
+TEST(MESSAGE_TEST_NAME, ParseFailsIfExtensionNotInitialized) {
+ UNITTEST::TestChildExtension source, message;
+ auto* r = source.mutable_optional_extension()->MutableExtension(
+ UNITTEST::TestRequired::single);
+ r->set_dummy2(100);
+ std::string serialized = source.SerializePartialAsString();
+
+ EXPECT_TRUE(message.ParsePartialFromString(serialized));
+ EXPECT_FALSE(message.IsInitialized());
+
+ std::vector<std::string> errors;
+ {
+ ScopedMemoryLog log;
+ EXPECT_FALSE(message.ParseFromString(source.SerializePartialAsString()));
+ errors = log.GetMessages(ERROR);
+ }
+
+ EXPECT_THAT(errors,
+ testing::ElementsAre(strings::Substitute(
+ "Can't parse message of type \"$0.TestChildExtension\" "
+ "because it is missing required fields: "
+ "optional_extension.($0.TestRequired.single).a, "
+ "optional_extension.($0.TestRequired.single).b, "
+ "optional_extension.($0.TestRequired.single).c",
+ UNITTEST_PACKAGE_NAME)));
+}
+
+TEST(MESSAGE_TEST_NAME, ParseFailsIfSubmessageTruncated) {
+ UNITTEST::NestedTestAllTypes o, p;
+ constexpr int kDepth = 5;
+ auto* child = o.mutable_child();
+ for (int i = 0; i < kDepth; i++) {
+ child = child->mutable_child();
+ }
+ TestUtil::SetAllFields(child->mutable_payload());
+
+ std::string serialized;
+ EXPECT_TRUE(o.SerializeToString(&serialized));
+
+ // Should parse correctly.
+ EXPECT_TRUE(p.ParseFromString(serialized));
+
+ constexpr int kMaxTruncate = 50;
+ ASSERT_GT(serialized.size(), kMaxTruncate);
+
+ for (int i = 1; i < kMaxTruncate; i += 3) {
+ EXPECT_FALSE(
+ p.ParseFromString(serialized.substr(0, serialized.size() - i)));
+ }
+}
+
+TEST(MESSAGE_TEST_NAME, ParseFailsIfWireMalformed) {
+ UNITTEST::NestedTestAllTypes o, p;
+ constexpr int kDepth = 5;
+ auto* child = o.mutable_child();
+ for (int i = 0; i < kDepth; i++) {
+ child = child->mutable_child();
+ }
+ // -1 becomes \xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x1
+ child->mutable_payload()->set_optional_int32(-1);
+
+ std::string serialized;
+ EXPECT_TRUE(o.SerializeToString(&serialized));
+
+ // Should parse correctly.
+ EXPECT_TRUE(p.ParseFromString(serialized));
+
+ // Overwriting the last byte to 0xFF results in malformed wire.
+ serialized[serialized.size() - 1] = 0xFF;
+ EXPECT_FALSE(p.ParseFromString(serialized));
+}
+
+TEST(MESSAGE_TEST_NAME, ParseFailsIfOneofWireMalformed) {
+ UNITTEST::NestedTestAllTypes o, p;
+ constexpr int kDepth = 5;
+ auto* child = o.mutable_child();
+ for (int i = 0; i < kDepth; i++) {
+ child = child->mutable_child();
+ }
+ // -1 becomes \xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x1
+ child->mutable_payload()->mutable_oneof_nested_message()->set_bb(-1);
+
+ std::string serialized;
+ EXPECT_TRUE(o.SerializeToString(&serialized));
+
+ // Should parse correctly.
+ EXPECT_TRUE(p.ParseFromString(serialized));
+
+ // Overwriting the last byte to 0xFF results in malformed wire.
+ serialized[serialized.size() - 1] = 0xFF;
+ EXPECT_FALSE(p.ParseFromString(serialized));
+}
+
+TEST(MESSAGE_TEST_NAME, ParseFailsIfExtensionWireMalformed) {
+ UNITTEST::TestChildExtension o, p;
+ auto* m = o.mutable_optional_extension()->MutableExtension(
+ UNITTEST::optional_nested_message_extension);
+
+ // -1 becomes \xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x1
+ m->set_bb(-1);
+
+ std::string serialized;
+ EXPECT_TRUE(o.SerializeToString(&serialized));
+
+ // Should parse correctly.
+ EXPECT_TRUE(p.ParseFromString(serialized));
+
+ // Overwriting the last byte to 0xFF results in malformed wire.
+ serialized[serialized.size() - 1] = 0xFF;
+ EXPECT_FALSE(p.ParseFromString(serialized));
+}
+
+TEST(MESSAGE_TEST_NAME, Swap) {
+ UNITTEST::NestedTestAllTypes o;
+ constexpr int kDepth = 5;
+ auto* child = o.mutable_child();
+ for (int i = 0; i < kDepth; i++) {
+ child = child->mutable_child();
+ }
+ TestUtil::SetAllFields(child->mutable_payload());
+
+ std::string serialized;
+ EXPECT_TRUE(o.SerializeToString(&serialized));
+
+ {
+ Arena arena;
+ UNITTEST::NestedTestAllTypes* p1 =
+ Arena::CreateMessage<UNITTEST::NestedTestAllTypes>(&arena);
+
+ // Should parse correctly.
+ EXPECT_TRUE(p1->ParseFromString(serialized));
+
+ UNITTEST::NestedTestAllTypes* p2 =
+ Arena::CreateMessage<UNITTEST::NestedTestAllTypes>(&arena);
+
+ p1->Swap(p2);
+
+ EXPECT_EQ(o.SerializeAsString(), p2->SerializeAsString());
+ }
+}
+
+TEST(MESSAGE_TEST_NAME, BypassInitializationCheckOnParse) {
+ UNITTEST::TestRequired message;
+ io::ArrayInputStream raw_input(nullptr, 0);
+ io::CodedInputStream input(&raw_input);
+ EXPECT_TRUE(message.MergePartialFromCodedStream(&input));
+}
+
+TEST(MESSAGE_TEST_NAME, InitializationErrorString) {
+ UNITTEST::TestRequired message;
+ EXPECT_EQ("a, b, c", message.InitializationErrorString());
+}
+
+TEST(MESSAGE_TEST_NAME, DynamicCastToGenerated) {
+ UNITTEST::TestAllTypes test_all_types;
+
+ Message* test_all_types_pointer = &test_all_types;
+ EXPECT_EQ(&test_all_types, DynamicCastToGenerated<UNITTEST::TestAllTypes>(
+ test_all_types_pointer));
+ EXPECT_EQ(nullptr, DynamicCastToGenerated<UNITTEST::TestRequired>(
+ test_all_types_pointer));
+
+ const Message* test_all_types_pointer_const = &test_all_types;
+ EXPECT_EQ(&test_all_types,
+ DynamicCastToGenerated<const UNITTEST::TestAllTypes>(
+ test_all_types_pointer_const));
+ EXPECT_EQ(nullptr, DynamicCastToGenerated<const UNITTEST::TestRequired>(
+ test_all_types_pointer_const));
+
+ Message* test_all_types_pointer_nullptr = nullptr;
+ EXPECT_EQ(nullptr, DynamicCastToGenerated<UNITTEST::TestAllTypes>(
+ test_all_types_pointer_nullptr));
+}
+
+#ifdef PROTOBUF_HAS_DEATH_TEST // death tests do not work on Windows yet.
+
+TEST(MESSAGE_TEST_NAME, SerializeFailsIfNotInitialized) {
+ UNITTEST::TestRequired message;
+ std::string data;
+ EXPECT_DEBUG_DEATH(EXPECT_TRUE(message.SerializeToString(&data)),
+ "Can't serialize message of type \"" +
+ std::string(UNITTEST_PACKAGE_NAME) +
+ ".TestRequired\" because "
+ "it is missing required fields: a, b, c");
+}
+
+TEST(MESSAGE_TEST_NAME, CheckInitialized) {
+ UNITTEST::TestRequired message;
+ EXPECT_DEATH(message.CheckInitialized(),
+ "Message of type \"" + std::string(UNITTEST_PACKAGE_NAME) +
+ ".TestRequired\" is missing required "
+ "fields: a, b, c");
+}
+
+#endif // PROTOBUF_HAS_DEATH_TEST
+
+namespace {
+// An input stream that repeats a std::string's content for a number of times.
+// It helps us create a really large input without consuming too much memory.
+// Used to test the parsing behavior when the input size exceeds 2G or close to
+// it.
+class RepeatedInputStream : public io::ZeroCopyInputStream {
+ public:
+ RepeatedInputStream(const std::string& data, size_t count)
+ : data_(data), count_(count), position_(0), total_byte_count_(0) {}
+
+ bool Next(const void** data, int* size) override {
+ if (position_ == data_.size()) {
+ if (--count_ == 0) {
+ return false;
+ }
+ position_ = 0;
+ }
+ *data = &data_[position_];
+ *size = static_cast<int>(data_.size() - position_);
+ position_ = data_.size();
+ total_byte_count_ += *size;
+ return true;
+ }
+
+ void BackUp(int count) override {
+ position_ -= static_cast<size_t>(count);
+ total_byte_count_ -= count;
+ }
+
+ bool Skip(int count) override {
+ while (count > 0) {
+ const void* data;
+ int size;
+ if (!Next(&data, &size)) {
+ break;
+ }
+ if (size >= count) {
+ BackUp(size - count);
+ return true;
+ } else {
+ count -= size;
+ }
+ }
+ return false;
+ }
+
+ int64_t ByteCount() const override { return total_byte_count_; }
+
+ private:
+ std::string data_;
+ size_t count_; // The number of strings that haven't been consumed.
+ size_t position_; // Position in the std::string for the next read.
+ int64 total_byte_count_;
+};
+} // namespace
+
+TEST(MESSAGE_TEST_NAME, TestParseMessagesCloseTo2G) {
+ constexpr int32_t kint32max = std::numeric_limits<int32_t>::max();
+
+ // Create a message with a large std::string field.
+ std::string value = std::string(64 * 1024 * 1024, 'x');
+ UNITTEST::TestAllTypes message;
+ message.set_optional_string(value);
+
+ // Repeat this message in the input stream to make the total input size
+ // close to 2G.
+ std::string data = message.SerializeAsString();
+ size_t count = static_cast<size_t>(kint32max) / data.size();
+ RepeatedInputStream input(data, count);
+
+ // The parsing should succeed.
+ UNITTEST::TestAllTypes result;
+ EXPECT_TRUE(result.ParseFromZeroCopyStream(&input));
+
+ // When there are multiple occurrences of a singular field, the last one
+ // should win.
+ EXPECT_EQ(value, result.optional_string());
+}
+
+TEST(MESSAGE_TEST_NAME, TestParseMessagesOver2G) {
+ // Create a message with a large std::string field.
+ std::string value = std::string(64 * 1024 * 1024, 'x');
+ UNITTEST::TestAllTypes message;
+ message.set_optional_string(value);
+
+ // Repeat this message in the input stream to make the total input size
+ // larger than 2G.
+ std::string data = message.SerializeAsString();
+ size_t count = static_cast<size_t>(kint32max) / data.size() + 1;
+ RepeatedInputStream input(data, count);
+
+ // The parsing should fail.
+ UNITTEST::TestAllTypes result;
+ EXPECT_FALSE(result.ParseFromZeroCopyStream(&input));
+}
+
+TEST(MESSAGE_TEST_NAME, BypassInitializationCheckOnSerialize) {
+ UNITTEST::TestRequired message;
+ io::ArrayOutputStream raw_output(nullptr, 0);
+ io::CodedOutputStream output(&raw_output);
+ EXPECT_TRUE(message.SerializePartialToCodedStream(&output));
+}
+
+TEST(MESSAGE_TEST_NAME, FindInitializationErrors) {
+ UNITTEST::TestRequired message;
+ std::vector<std::string> errors;
+ message.FindInitializationErrors(&errors);
+ ASSERT_EQ(3, errors.size());
+ EXPECT_EQ("a", errors[0]);
+ EXPECT_EQ("b", errors[1]);
+ EXPECT_EQ("c", errors[2]);
+}
+
+TEST(MESSAGE_TEST_NAME, ReleaseMustUseResult) {
+ UNITTEST::TestAllTypes message;
+ auto* f = new UNITTEST::ForeignMessage();
+ f->set_c(1000);
+ message.set_allocated_optional_foreign_message(f);
+ auto* mf = message.mutable_optional_foreign_message();
+ EXPECT_EQ(mf, f);
+ std::unique_ptr<UNITTEST::ForeignMessage> rf(
+ message.release_optional_foreign_message());
+ EXPECT_NE(rf.get(), nullptr);
+}
+
+TEST(MESSAGE_TEST_NAME, ParseFailsOnInvalidMessageEnd) {
+ UNITTEST::TestAllTypes message;
+
+ // Control case.
+ EXPECT_TRUE(message.ParseFromArray("", 0));
+
+ // The byte is a valid varint, but not a valid tag (zero).
+ EXPECT_FALSE(message.ParseFromArray("\0", 1));
+
+ // The byte is a malformed varint.
+ EXPECT_FALSE(message.ParseFromArray("\200", 1));
+
+ // The byte is an endgroup tag, but we aren't parsing a group.
+ EXPECT_FALSE(message.ParseFromArray("\014", 1));
+}
+
+// Regression test for b/23630858
+TEST(MESSAGE_TEST_NAME, MessageIsStillValidAfterParseFails) {
+ UNITTEST::TestAllTypes message;
+
+ // 9 0xFFs for the "optional_uint64" field.
+ std::string invalid_data = "\x20\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF";
+
+ EXPECT_FALSE(message.ParseFromString(invalid_data));
+ message.Clear();
+ EXPECT_EQ(0, message.optional_uint64());
+
+ // invalid data for field "optional_string". Length prefix is 1 but no
+ // payload.
+ std::string invalid_string_data = "\x72\x01";
+ {
+ Arena arena;
+ UNITTEST::TestAllTypes* arena_message =
+ Arena::CreateMessage<UNITTEST::TestAllTypes>(&arena);
+ EXPECT_FALSE(arena_message->ParseFromString(invalid_string_data));
+ arena_message->Clear();
+ EXPECT_EQ("", arena_message->optional_string());
+ }
+}
+
+
+namespace {
+
+void ExpectMessageMerged(const UNITTEST::TestAllTypes& message) {
+ EXPECT_EQ(3, message.optional_int32());
+ EXPECT_EQ(2, message.optional_int64());
+ EXPECT_EQ("hello", message.optional_string());
+}
+
+void AssignParsingMergeMessages(UNITTEST::TestAllTypes* msg1,
+ UNITTEST::TestAllTypes* msg2,
+ UNITTEST::TestAllTypes* msg3) {
+ msg1->set_optional_int32(1);
+ msg2->set_optional_int64(2);
+ msg3->set_optional_int32(3);
+ msg3->set_optional_string("hello");
+}
+
+} // namespace
+
+// Test that if an optional or required message/group field appears multiple
+// times in the input, they need to be merged.
+TEST(MESSAGE_TEST_NAME, ParsingMerge) {
+ UNITTEST::TestParsingMerge::RepeatedFieldsGenerator generator;
+ UNITTEST::TestAllTypes* msg1;
+ UNITTEST::TestAllTypes* msg2;
+ UNITTEST::TestAllTypes* msg3;
+
+#define ASSIGN_REPEATED_FIELD(FIELD) \
+ msg1 = generator.add_##FIELD(); \
+ msg2 = generator.add_##FIELD(); \
+ msg3 = generator.add_##FIELD(); \
+ AssignParsingMergeMessages(msg1, msg2, msg3)
+
+ ASSIGN_REPEATED_FIELD(field1);
+ ASSIGN_REPEATED_FIELD(field2);
+ ASSIGN_REPEATED_FIELD(field3);
+ ASSIGN_REPEATED_FIELD(ext1);
+ ASSIGN_REPEATED_FIELD(ext2);
+
+#undef ASSIGN_REPEATED_FIELD
+#define ASSIGN_REPEATED_GROUP(FIELD) \
+ msg1 = generator.add_##FIELD()->mutable_field1(); \
+ msg2 = generator.add_##FIELD()->mutable_field1(); \
+ msg3 = generator.add_##FIELD()->mutable_field1(); \
+ AssignParsingMergeMessages(msg1, msg2, msg3)
+
+ ASSIGN_REPEATED_GROUP(group1);
+ ASSIGN_REPEATED_GROUP(group2);
+
+#undef ASSIGN_REPEATED_GROUP
+
+ std::string buffer;
+ generator.SerializeToString(&buffer);
+ UNITTEST::TestParsingMerge parsing_merge;
+ parsing_merge.ParseFromString(buffer);
+
+ // Required and optional fields should be merged.
+ ExpectMessageMerged(parsing_merge.required_all_types());
+ ExpectMessageMerged(parsing_merge.optional_all_types());
+ ExpectMessageMerged(parsing_merge.optionalgroup().optional_group_all_types());
+ ExpectMessageMerged(
+ parsing_merge.GetExtension(UNITTEST::TestParsingMerge::optional_ext));
+
+ // Repeated fields should not be merged.
+ EXPECT_EQ(3, parsing_merge.repeated_all_types_size());
+ EXPECT_EQ(3, parsing_merge.repeatedgroup_size());
+ EXPECT_EQ(
+ 3, parsing_merge.ExtensionSize(UNITTEST::TestParsingMerge::repeated_ext));
+}
+
+TEST(MESSAGE_TEST_NAME, MergeFrom) {
+ UNITTEST::TestAllTypes source, dest;
+
+ // Optional fields
+ source.set_optional_int32(1); // only source
+ source.set_optional_int64(2); // both source and dest
+ dest.set_optional_int64(3);
+ dest.set_optional_uint32(4); // only dest
+
+ // Optional fields with defaults
+ source.set_default_int32(13); // only source
+ source.set_default_int64(14); // both source and dest
+ dest.set_default_int64(15);
+ dest.set_default_uint32(16); // only dest
+
+ // Repeated fields
+ source.add_repeated_int32(5); // only source
+ source.add_repeated_int32(6);
+ source.add_repeated_int64(7); // both source and dest
+ source.add_repeated_int64(8);
+ dest.add_repeated_int64(9);
+ dest.add_repeated_int64(10);
+ dest.add_repeated_uint32(11); // only dest
+ dest.add_repeated_uint32(12);
+
+ dest.MergeFrom(source);
+
+ // Optional fields: source overwrites dest if source is specified
+ EXPECT_EQ(1, dest.optional_int32()); // only source: use source
+ EXPECT_EQ(2, dest.optional_int64()); // source and dest: use source
+ EXPECT_EQ(4, dest.optional_uint32()); // only dest: use dest
+ EXPECT_EQ(0, dest.optional_uint64()); // neither: use default
+
+ // Optional fields with defaults
+ EXPECT_EQ(13, dest.default_int32()); // only source: use source
+ EXPECT_EQ(14, dest.default_int64()); // source and dest: use source
+ EXPECT_EQ(16, dest.default_uint32()); // only dest: use dest
+ EXPECT_EQ(44, dest.default_uint64()); // neither: use default
+
+ // Repeated fields: concatenate source onto the end of dest
+ ASSERT_EQ(2, dest.repeated_int32_size());
+ EXPECT_EQ(5, dest.repeated_int32(0));
+ EXPECT_EQ(6, dest.repeated_int32(1));
+ ASSERT_EQ(4, dest.repeated_int64_size());
+ EXPECT_EQ(9, dest.repeated_int64(0));
+ EXPECT_EQ(10, dest.repeated_int64(1));
+ EXPECT_EQ(7, dest.repeated_int64(2));
+ EXPECT_EQ(8, dest.repeated_int64(3));
+ ASSERT_EQ(2, dest.repeated_uint32_size());
+ EXPECT_EQ(11, dest.repeated_uint32(0));
+ EXPECT_EQ(12, dest.repeated_uint32(1));
+ ASSERT_EQ(0, dest.repeated_uint64_size());
+}
+
+TEST(MESSAGE_TEST_NAME, IsInitialized) {
+ UNITTEST::TestIsInitialized msg;
+ EXPECT_TRUE(msg.IsInitialized());
+ UNITTEST::TestIsInitialized::SubMessage* sub_message =
+ msg.mutable_sub_message();
+ EXPECT_TRUE(msg.IsInitialized());
+ UNITTEST::TestIsInitialized::SubMessage::SubGroup* sub_group =
+ sub_message->mutable_subgroup();
+ EXPECT_FALSE(msg.IsInitialized());
+ sub_group->set_i(1);
+ EXPECT_TRUE(msg.IsInitialized());
+}
+
+TEST(MESSAGE_TEST_NAME, IsInitializedSplitBytestream) {
+ UNITTEST::TestRequired ab, c;
+ ab.set_a(1);
+ ab.set_b(2);
+ c.set_c(3);
+
+ // The protobuf represented by the concatenated string has all required
+ // fields (a,b,c) set.
+ std::string bytes =
+ ab.SerializePartialAsString() + c.SerializePartialAsString();
+
+ UNITTEST::TestRequired concatenated;
+ EXPECT_TRUE(concatenated.ParsePartialFromString(bytes));
+ EXPECT_TRUE(concatenated.IsInitialized());
+
+ UNITTEST::TestRequiredForeign fab, fc;
+ fab.mutable_optional_message()->set_a(1);
+ fab.mutable_optional_message()->set_b(2);
+ fc.mutable_optional_message()->set_c(3);
+
+ bytes =
+ fab.SerializePartialAsString() + fc.SerializePartialAsString();
+
+ UNITTEST::TestRequiredForeign fconcatenated;
+ EXPECT_TRUE(fconcatenated.ParsePartialFromString(bytes));
+ EXPECT_TRUE(fconcatenated.IsInitialized());
+}
+
+TEST(MESSAGE_FACTORY_TEST_NAME, GeneratedFactoryLookup) {
+ EXPECT_EQ(MessageFactory::generated_factory()->GetPrototype(
+ UNITTEST::TestAllTypes::descriptor()),
+ &UNITTEST::TestAllTypes::default_instance());
+}
+
+TEST(MESSAGE_FACTORY_TEST_NAME, GeneratedFactoryUnknownType) {
+ // Construct a new descriptor.
+ DescriptorPool pool;
+ FileDescriptorProto file;
+ file.set_name("foo.proto");
+ file.add_message_type()->set_name("Foo");
+ const Descriptor* descriptor = pool.BuildFile(file)->message_type(0);
+
+ // Trying to construct it should return nullptr.
+ EXPECT_TRUE(MessageFactory::generated_factory()->GetPrototype(descriptor) ==
+ nullptr);
+}
+
+TEST(MESSAGE_TEST_NAME, MOMIParserEdgeCases) {
+ {
+ UNITTEST::TestAllTypes msg;
+ // Parser ends in last 16 bytes of buffer due to a 0.
+ std::string data;
+ // 12 bytes of data
+ for (int i = 0; i < 4; i++) data += "\370\1\1";
+ // 13 byte is terminator
+ data += '\0'; // Terminator
+ // followed by the rest of the stream
+ // space is ascii 32 so no end group
+ data += std::string(30, ' ');
+ io::ArrayInputStream zcis(data.data(), data.size(), 17);
+ io::CodedInputStream cis(&zcis);
+ EXPECT_TRUE(msg.MergePartialFromCodedStream(&cis));
+ EXPECT_EQ(cis.CurrentPosition(), 3 * 4 + 1);
+ }
+ {
+ // Parser ends in last 16 bytes of buffer due to a end-group.
+ // Must use a message that is a group. Otherwise ending on a group end is
+ // a failure.
+ UNITTEST::TestAllTypes::OptionalGroup msg;
+ std::string data;
+ for (int i = 0; i < 3; i++) data += "\370\1\1";
+ data += '\14'; // Octal end-group tag 12 (1 * 8 + 4(
+ data += std::string(30, ' ');
+ io::ArrayInputStream zcis(data.data(), data.size(), 17);
+ io::CodedInputStream cis(&zcis);
+ EXPECT_TRUE(msg.MergePartialFromCodedStream(&cis));
+ EXPECT_EQ(cis.CurrentPosition(), 3 * 3 + 1);
+ EXPECT_TRUE(cis.LastTagWas(12));
+ }
+ {
+ // Parser ends in last 16 bytes of buffer due to a end-group. But is inside
+ // a length delimited field.
+ // a failure.
+ UNITTEST::TestAllTypes::OptionalGroup msg;
+ std::string data;
+ data += "\22\3foo";
+ data += '\14'; // Octal end-group tag 12 (1 * 8 + 4(
+ data += std::string(30, ' ');
+ io::ArrayInputStream zcis(data.data(), data.size(), 17);
+ io::CodedInputStream cis(&zcis);
+ EXPECT_TRUE(msg.MergePartialFromCodedStream(&cis));
+ EXPECT_EQ(cis.CurrentPosition(), 6);
+ EXPECT_TRUE(cis.LastTagWas(12));
+ }
+ {
+ // Parser fails when ending on 0 if from ZeroCopyInputStream
+ UNITTEST::TestAllTypes msg;
+ std::string data;
+ // 12 bytes of data
+ for (int i = 0; i < 4; i++) data += "\370\1\1";
+ // 13 byte is terminator
+ data += '\0'; // Terminator
+ data += std::string(30, ' ');
+ io::ArrayInputStream zcis(data.data(), data.size(), 17);
+ EXPECT_FALSE(msg.ParsePartialFromZeroCopyStream(&zcis));
+ }
+}
+
+
+TEST(MESSAGE_TEST_NAME, CheckSerializationWhenInterleavedExtensions) {
+ UNITTEST::TestExtensionRangeSerialize in_message;
+
+ in_message.set_foo_one(1);
+ in_message.set_foo_two(2);
+ in_message.set_foo_three(3);
+ in_message.set_foo_four(4);
+
+ in_message.SetExtension(UNITTEST::TestExtensionRangeSerialize::bar_one, 1);
+ in_message.SetExtension(UNITTEST::TestExtensionRangeSerialize::bar_two, 2);
+ in_message.SetExtension(UNITTEST::TestExtensionRangeSerialize::bar_three, 3);
+ in_message.SetExtension(UNITTEST::TestExtensionRangeSerialize::bar_four, 4);
+ in_message.SetExtension(UNITTEST::TestExtensionRangeSerialize::bar_five, 5);
+
+ std::string buffer;
+ in_message.SerializeToString(&buffer);
+
+ UNITTEST::TestExtensionRangeSerialize out_message;
+ out_message.ParseFromString(buffer);
+
+ EXPECT_EQ(1, out_message.foo_one());
+ EXPECT_EQ(2, out_message.foo_two());
+ EXPECT_EQ(3, out_message.foo_three());
+ EXPECT_EQ(4, out_message.foo_four());
+
+ EXPECT_EQ(1, out_message.GetExtension(UNITTEST::TestExtensionRangeSerialize::bar_one));
+ EXPECT_EQ(2, out_message.GetExtension(UNITTEST::TestExtensionRangeSerialize::bar_two));
+ EXPECT_EQ(3, out_message.GetExtension(UNITTEST::TestExtensionRangeSerialize::bar_three));
+ EXPECT_EQ(4, out_message.GetExtension(UNITTEST::TestExtensionRangeSerialize::bar_four));
+ EXPECT_EQ(5, out_message.GetExtension(UNITTEST::TestExtensionRangeSerialize::bar_five));
+}
+
+TEST(MESSAGE_TEST_NAME, PreservesFloatingPointNegative0) {
+ UNITTEST::TestAllTypes in_message;
+ in_message.set_optional_float(-0.0f);
+ in_message.set_optional_double(-0.0);
+ std::string serialized;
+ EXPECT_TRUE(in_message.SerializeToString(&serialized));
+ UNITTEST::TestAllTypes out_message;
+ EXPECT_TRUE(out_message.ParseFromString(serialized));
+ EXPECT_EQ(in_message.optional_float(), out_message.optional_float());
+ EXPECT_EQ(std::signbit(in_message.optional_float()),
+ std::signbit(out_message.optional_float()));
+ EXPECT_EQ(in_message.optional_double(), out_message.optional_double());
+ EXPECT_EQ(std::signbit(in_message.optional_double()),
+ std::signbit(out_message.optional_double()));
+}
+
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/metadata.h b/NorthstarDedicatedTest/include/protobuf/metadata.h
new file mode 100644
index 00000000..4e89648e
--- /dev/null
+++ b/NorthstarDedicatedTest/include/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/NorthstarDedicatedTest/include/protobuf/metadata_lite.h b/NorthstarDedicatedTest/include/protobuf/metadata_lite.h
new file mode 100644
index 00000000..4c8ed843
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/metadata_lite.h
@@ -0,0 +1,270 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef GOOGLE_PROTOBUF_METADATA_LITE_H__
+#define GOOGLE_PROTOBUF_METADATA_LITE_H__
+
+#include <string>
+#include <stubs/common.h>
+#include <arena.h>
+#include <port.h>
+
+#include <port_def.inc>
+
+#ifdef SWIG
+#error "You cannot SWIG proto headers"
+#endif
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+// This is the representation for messages that support arena allocation. It
+// uses a tagged pointer to either store the owning Arena pointer, if there are
+// no unknown fields, or a pointer to a block of memory with both the owning
+// Arena pointer and the UnknownFieldSet, if there are unknown fields. Besides,
+// it also uses the tag to distinguish whether the owning Arena pointer is also
+// used by sub-structure allocation. This optimization allows for
+// "zero-overhead" storage of the Arena pointer, relative to the above baseline
+// implementation.
+//
+// The tagged pointer uses the least two significant bits to disambiguate cases.
+// It uses bit 0 == 0 to indicate an arena pointer and bit 0 == 1 to indicate a
+// UFS+Arena-container pointer. Besides it uses bit 1 == 0 to indicate arena
+// allocation and bit 1 == 1 to indicate heap allocation.
+class InternalMetadata {
+ public:
+ constexpr InternalMetadata() : ptr_(0) {}
+ explicit InternalMetadata(Arena* arena, bool is_message_owned = false)
+ : ptr_(is_message_owned
+ ? reinterpret_cast<intptr_t>(arena) | kMessageOwnedArenaTagMask
+ : reinterpret_cast<intptr_t>(arena)) {
+ GOOGLE_DCHECK(!is_message_owned || arena != nullptr);
+ }
+
+ ~InternalMetadata() {
+ if (HasMessageOwnedArenaTag()) {
+ delete arena();
+ }
+ }
+
+ template <typename T>
+ void Delete() {
+ // Note that Delete<> should be called not more than once.
+ if (have_unknown_fields()) {
+ DeleteOutOfLineHelper<T>();
+ }
+ }
+
+ PROTOBUF_NDEBUG_INLINE Arena* owning_arena() const {
+ return HasMessageOwnedArenaTag() ? nullptr : arena();
+ }
+
+ PROTOBUF_NDEBUG_INLINE Arena* arena() const {
+ if (PROTOBUF_PREDICT_FALSE(have_unknown_fields())) {
+ return PtrValue<ContainerBase>()->arena;
+ } else {
+ return PtrValue<Arena>();
+ }
+ }
+
+ PROTOBUF_NDEBUG_INLINE bool have_unknown_fields() const {
+ return HasUnknownFieldsTag();
+ }
+
+ PROTOBUF_NDEBUG_INLINE void* raw_arena_ptr() const {
+ return reinterpret_cast<void*>(ptr_);
+ }
+
+ template <typename T>
+ PROTOBUF_NDEBUG_INLINE const T& unknown_fields(
+ const T& (*default_instance)()) const {
+ if (PROTOBUF_PREDICT_FALSE(have_unknown_fields())) {
+ return PtrValue<Container<T>>()->unknown_fields;
+ } else {
+ return default_instance();
+ }
+ }
+
+ template <typename T>
+ PROTOBUF_NDEBUG_INLINE T* mutable_unknown_fields() {
+ if (PROTOBUF_PREDICT_TRUE(have_unknown_fields())) {
+ return &PtrValue<Container<T>>()->unknown_fields;
+ } else {
+ return mutable_unknown_fields_slow<T>();
+ }
+ }
+
+ template <typename T>
+ PROTOBUF_NDEBUG_INLINE void Swap(InternalMetadata* other) {
+ // Semantics here are that we swap only the unknown fields, not the arena
+ // pointer. We cannot simply swap ptr_ with other->ptr_ because we need to
+ // maintain our own arena ptr. Also, our ptr_ and other's ptr_ may be in
+ // different states (direct arena pointer vs. container with UFS) so we
+ // cannot simply swap ptr_ and then restore the arena pointers. We reuse
+ // UFS's swap implementation instead.
+ if (have_unknown_fields() || other->have_unknown_fields()) {
+ DoSwap<T>(other->mutable_unknown_fields<T>());
+ }
+ }
+
+ PROTOBUF_NDEBUG_INLINE void InternalSwap(InternalMetadata* other) {
+ std::swap(ptr_, other->ptr_);
+ }
+
+ template <typename T>
+ PROTOBUF_NDEBUG_INLINE void MergeFrom(const InternalMetadata& other) {
+ if (other.have_unknown_fields()) {
+ DoMergeFrom<T>(other.unknown_fields<T>(nullptr));
+ }
+ }
+
+ template <typename T>
+ PROTOBUF_NDEBUG_INLINE void Clear() {
+ if (have_unknown_fields()) {
+ DoClear<T>();
+ }
+ }
+
+ private:
+ intptr_t ptr_;
+
+ // Tagged pointer implementation.
+ static constexpr intptr_t kUnknownFieldsTagMask = 1;
+ static constexpr intptr_t kMessageOwnedArenaTagMask = 2;
+ static constexpr intptr_t kPtrTagMask =
+ kUnknownFieldsTagMask | kMessageOwnedArenaTagMask;
+ static constexpr intptr_t kPtrValueMask = ~kPtrTagMask;
+
+ // Accessors for pointer tag and pointer value.
+ PROTOBUF_ALWAYS_INLINE bool HasUnknownFieldsTag() const {
+ return ptr_ & kUnknownFieldsTagMask;
+ }
+ PROTOBUF_ALWAYS_INLINE bool HasMessageOwnedArenaTag() const {
+ return ptr_ & kMessageOwnedArenaTagMask;
+ }
+
+ template <typename U>
+ U* PtrValue() const {
+ return reinterpret_cast<U*>(ptr_ & kPtrValueMask);
+ }
+
+ // If ptr_'s tag is kTagContainer, it points to an instance of this struct.
+ struct ContainerBase {
+ Arena* arena;
+ };
+
+ template <typename T>
+ struct Container : public ContainerBase {
+ T unknown_fields;
+ };
+
+ template <typename T>
+ PROTOBUF_NOINLINE void DeleteOutOfLineHelper() {
+ if (arena() == nullptr) {
+ delete PtrValue<Container<T>>();
+ }
+ }
+
+ template <typename T>
+ PROTOBUF_NOINLINE T* mutable_unknown_fields_slow() {
+ Arena* my_arena = arena();
+ Container<T>* container = Arena::Create<Container<T>>(my_arena);
+ intptr_t message_owned_arena_tag = ptr_ & kMessageOwnedArenaTagMask;
+ // Two-step assignment works around a bug in clang's static analyzer:
+ // https://bugs.llvm.org/show_bug.cgi?id=34198.
+ ptr_ = reinterpret_cast<intptr_t>(container);
+ ptr_ |= kUnknownFieldsTagMask | message_owned_arena_tag;
+ container->arena = my_arena;
+ return &(container->unknown_fields);
+ }
+
+ // Templated functions.
+
+ template <typename T>
+ PROTOBUF_NOINLINE void DoClear() {
+ mutable_unknown_fields<T>()->Clear();
+ }
+
+ template <typename T>
+ PROTOBUF_NOINLINE void DoMergeFrom(const T& other) {
+ mutable_unknown_fields<T>()->MergeFrom(other);
+ }
+
+ template <typename T>
+ PROTOBUF_NOINLINE void DoSwap(T* other) {
+ mutable_unknown_fields<T>()->Swap(other);
+ }
+};
+
+// String Template specializations.
+
+template <>
+PROTOBUF_EXPORT void InternalMetadata::DoClear<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 <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_METADATA_LITE_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/no_field_presence_test.cc b/NorthstarDedicatedTest/include/protobuf/no_field_presence_test.cc
new file mode 100644
index 00000000..4644312d
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/no_field_presence_test.cc
@@ -0,0 +1,575 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 <string>
+
+#include <unittest.pb.h>
+#include <unittest_no_field_presence.pb.h>
+#include <descriptor.pb.h>
+#include <descriptor.h>
+#include <gtest/gtest.h>
+
+namespace google {
+namespace protobuf {
+namespace {
+
+// Helper: checks that all fields have default (zero/empty) values.
+void CheckDefaultValues(
+ const proto2_nofieldpresence_unittest::TestAllTypes& m) {
+ EXPECT_EQ(0, m.optional_int32());
+ EXPECT_EQ(0, m.optional_int64());
+ EXPECT_EQ(0, m.optional_uint32());
+ EXPECT_EQ(0, m.optional_uint64());
+ EXPECT_EQ(0, m.optional_sint32());
+ EXPECT_EQ(0, m.optional_sint64());
+ EXPECT_EQ(0, m.optional_fixed32());
+ EXPECT_EQ(0, m.optional_fixed64());
+ EXPECT_EQ(0, m.optional_sfixed32());
+ EXPECT_EQ(0, m.optional_sfixed64());
+ EXPECT_EQ(0, m.optional_float());
+ EXPECT_EQ(0, m.optional_double());
+ EXPECT_EQ(false, m.optional_bool());
+ EXPECT_EQ(0, m.optional_string().size());
+ EXPECT_EQ(0, m.optional_bytes().size());
+
+ EXPECT_EQ(false, m.has_optional_nested_message());
+ // accessor for message fields returns default instance when not present
+ EXPECT_EQ(0, m.optional_nested_message().bb());
+ EXPECT_EQ(false, m.has_optional_proto2_message());
+ // Embedded proto2 messages still have proto2 semantics, e.g. non-zero default
+ // values. Here the submessage is not present but its accessor returns the
+ // default instance.
+ EXPECT_EQ(41, m.optional_proto2_message().default_int32());
+ EXPECT_EQ(false, m.has_optional_foreign_message());
+ EXPECT_EQ(proto2_nofieldpresence_unittest::TestAllTypes::FOO,
+ m.optional_nested_enum());
+ EXPECT_EQ(proto2_nofieldpresence_unittest::FOREIGN_FOO,
+ m.optional_foreign_enum());
+
+
+ EXPECT_EQ(0, m.repeated_int32_size());
+ EXPECT_EQ(0, m.repeated_int64_size());
+ EXPECT_EQ(0, m.repeated_uint32_size());
+ EXPECT_EQ(0, m.repeated_uint64_size());
+ EXPECT_EQ(0, m.repeated_sint32_size());
+ EXPECT_EQ(0, m.repeated_sint64_size());
+ EXPECT_EQ(0, m.repeated_fixed32_size());
+ EXPECT_EQ(0, m.repeated_fixed64_size());
+ EXPECT_EQ(0, m.repeated_sfixed32_size());
+ EXPECT_EQ(0, m.repeated_sfixed64_size());
+ EXPECT_EQ(0, m.repeated_float_size());
+ EXPECT_EQ(0, m.repeated_double_size());
+ EXPECT_EQ(0, m.repeated_bool_size());
+ EXPECT_EQ(0, m.repeated_string_size());
+ EXPECT_EQ(0, m.repeated_bytes_size());
+ EXPECT_EQ(0, m.repeated_nested_message_size());
+ EXPECT_EQ(0, m.repeated_foreign_message_size());
+ EXPECT_EQ(0, m.repeated_proto2_message_size());
+ EXPECT_EQ(0, m.repeated_nested_enum_size());
+ EXPECT_EQ(0, m.repeated_foreign_enum_size());
+ EXPECT_EQ(0, m.repeated_lazy_message_size());
+ EXPECT_EQ(proto2_nofieldpresence_unittest::TestAllTypes::ONEOF_FIELD_NOT_SET,
+ m.oneof_field_case());
+}
+
+void FillValues(proto2_nofieldpresence_unittest::TestAllTypes* m) {
+ m->set_optional_int32(100);
+ m->set_optional_int64(101);
+ m->set_optional_uint32(102);
+ m->set_optional_uint64(103);
+ m->set_optional_sint32(104);
+ m->set_optional_sint64(105);
+ m->set_optional_fixed32(106);
+ m->set_optional_fixed64(107);
+ m->set_optional_sfixed32(108);
+ m->set_optional_sfixed64(109);
+ m->set_optional_float(110.0);
+ m->set_optional_double(111.0);
+ m->set_optional_bool(true);
+ m->set_optional_string("asdf");
+ m->set_optional_bytes("jkl;");
+ m->mutable_optional_nested_message()->set_bb(42);
+ m->mutable_optional_foreign_message()->set_c(43);
+ m->mutable_optional_proto2_message()->set_optional_int32(44);
+ m->set_optional_nested_enum(
+ proto2_nofieldpresence_unittest::TestAllTypes::BAZ);
+ m->set_optional_foreign_enum(proto2_nofieldpresence_unittest::FOREIGN_BAZ);
+ m->mutable_optional_lazy_message()->set_bb(45);
+ m->add_repeated_int32(100);
+ m->add_repeated_int64(101);
+ m->add_repeated_uint32(102);
+ m->add_repeated_uint64(103);
+ m->add_repeated_sint32(104);
+ m->add_repeated_sint64(105);
+ m->add_repeated_fixed32(106);
+ m->add_repeated_fixed64(107);
+ m->add_repeated_sfixed32(108);
+ m->add_repeated_sfixed64(109);
+ m->add_repeated_float(110.0);
+ m->add_repeated_double(111.0);
+ m->add_repeated_bool(true);
+ m->add_repeated_string("asdf");
+ m->add_repeated_bytes("jkl;");
+ m->add_repeated_nested_message()->set_bb(46);
+ m->add_repeated_foreign_message()->set_c(47);
+ m->add_repeated_proto2_message()->set_optional_int32(48);
+ m->add_repeated_nested_enum(
+ proto2_nofieldpresence_unittest::TestAllTypes::BAZ);
+ m->add_repeated_foreign_enum(proto2_nofieldpresence_unittest::FOREIGN_BAZ);
+ m->add_repeated_lazy_message()->set_bb(49);
+
+ m->set_oneof_uint32(1);
+ m->mutable_oneof_nested_message()->set_bb(50);
+ m->set_oneof_string("test"); // only this one remains set
+}
+
+void CheckNonDefaultValues(
+ const proto2_nofieldpresence_unittest::TestAllTypes& m) {
+ EXPECT_EQ(100, m.optional_int32());
+ EXPECT_EQ(101, m.optional_int64());
+ EXPECT_EQ(102, m.optional_uint32());
+ EXPECT_EQ(103, m.optional_uint64());
+ EXPECT_EQ(104, m.optional_sint32());
+ EXPECT_EQ(105, m.optional_sint64());
+ EXPECT_EQ(106, m.optional_fixed32());
+ EXPECT_EQ(107, m.optional_fixed64());
+ EXPECT_EQ(108, m.optional_sfixed32());
+ EXPECT_EQ(109, m.optional_sfixed64());
+ EXPECT_EQ(110.0, m.optional_float());
+ EXPECT_EQ(111.0, m.optional_double());
+ EXPECT_EQ(true, m.optional_bool());
+ EXPECT_EQ("asdf", m.optional_string());
+ EXPECT_EQ("jkl;", m.optional_bytes());
+ EXPECT_EQ(true, m.has_optional_nested_message());
+ EXPECT_EQ(42, m.optional_nested_message().bb());
+ EXPECT_EQ(true, m.has_optional_foreign_message());
+ EXPECT_EQ(43, m.optional_foreign_message().c());
+ EXPECT_EQ(true, m.has_optional_proto2_message());
+ EXPECT_EQ(44, m.optional_proto2_message().optional_int32());
+ EXPECT_EQ(proto2_nofieldpresence_unittest::TestAllTypes::BAZ,
+ m.optional_nested_enum());
+ EXPECT_EQ(proto2_nofieldpresence_unittest::FOREIGN_BAZ,
+ m.optional_foreign_enum());
+ EXPECT_EQ(true, m.has_optional_lazy_message());
+ EXPECT_EQ(45, m.optional_lazy_message().bb());
+
+ EXPECT_EQ(1, m.repeated_int32_size());
+ EXPECT_EQ(100, m.repeated_int32(0));
+ EXPECT_EQ(1, m.repeated_int64_size());
+ EXPECT_EQ(101, m.repeated_int64(0));
+ EXPECT_EQ(1, m.repeated_uint32_size());
+ EXPECT_EQ(102, m.repeated_uint32(0));
+ EXPECT_EQ(1, m.repeated_uint64_size());
+ EXPECT_EQ(103, m.repeated_uint64(0));
+ EXPECT_EQ(1, m.repeated_sint32_size());
+ EXPECT_EQ(104, m.repeated_sint32(0));
+ EXPECT_EQ(1, m.repeated_sint64_size());
+ EXPECT_EQ(105, m.repeated_sint64(0));
+ EXPECT_EQ(1, m.repeated_fixed32_size());
+ EXPECT_EQ(106, m.repeated_fixed32(0));
+ EXPECT_EQ(1, m.repeated_fixed64_size());
+ EXPECT_EQ(107, m.repeated_fixed64(0));
+ EXPECT_EQ(1, m.repeated_sfixed32_size());
+ EXPECT_EQ(108, m.repeated_sfixed32(0));
+ EXPECT_EQ(1, m.repeated_sfixed64_size());
+ EXPECT_EQ(109, m.repeated_sfixed64(0));
+ EXPECT_EQ(1, m.repeated_float_size());
+ EXPECT_EQ(110.0, m.repeated_float(0));
+ EXPECT_EQ(1, m.repeated_double_size());
+ EXPECT_EQ(111.0, m.repeated_double(0));
+ EXPECT_EQ(1, m.repeated_bool_size());
+ EXPECT_EQ(true, m.repeated_bool(0));
+ EXPECT_EQ(1, m.repeated_string_size());
+ EXPECT_EQ("asdf", m.repeated_string(0));
+ EXPECT_EQ(1, m.repeated_bytes_size());
+ EXPECT_EQ("jkl;", m.repeated_bytes(0));
+ EXPECT_EQ(1, m.repeated_nested_message_size());
+ EXPECT_EQ(46, m.repeated_nested_message(0).bb());
+ EXPECT_EQ(1, m.repeated_foreign_message_size());
+ EXPECT_EQ(47, m.repeated_foreign_message(0).c());
+ EXPECT_EQ(1, m.repeated_proto2_message_size());
+ EXPECT_EQ(48, m.repeated_proto2_message(0).optional_int32());
+ EXPECT_EQ(1, m.repeated_nested_enum_size());
+ EXPECT_EQ(proto2_nofieldpresence_unittest::TestAllTypes::BAZ,
+ m.repeated_nested_enum(0));
+ EXPECT_EQ(1, m.repeated_foreign_enum_size());
+ EXPECT_EQ(proto2_nofieldpresence_unittest::FOREIGN_BAZ,
+ m.repeated_foreign_enum(0));
+ EXPECT_EQ(1, m.repeated_lazy_message_size());
+ EXPECT_EQ(49, m.repeated_lazy_message(0).bb());
+
+ EXPECT_EQ(proto2_nofieldpresence_unittest::TestAllTypes::kOneofString,
+ m.oneof_field_case());
+ EXPECT_EQ("test", m.oneof_string());
+}
+
+TEST(NoFieldPresenceTest, BasicMessageTest) {
+ proto2_nofieldpresence_unittest::TestAllTypes message;
+ // Check default values, fill all fields, check values. We just want to
+ // exercise the basic getters/setter paths here to make sure no
+ // field-presence-related changes broke these.
+ CheckDefaultValues(message);
+ FillValues(&message);
+ CheckNonDefaultValues(message);
+
+ // Clear() should be equivalent to getting a freshly-constructed message.
+ message.Clear();
+ CheckDefaultValues(message);
+}
+
+TEST(NoFieldPresenceTest, MessageFieldPresenceTest) {
+ // check that presence still works properly for message fields.
+ proto2_nofieldpresence_unittest::TestAllTypes message;
+ EXPECT_EQ(false, message.has_optional_nested_message());
+ // Getter should fetch default instance, and not cause the field to become
+ // present.
+ EXPECT_EQ(0, message.optional_nested_message().bb());
+ EXPECT_EQ(false, message.has_optional_nested_message());
+ message.mutable_optional_nested_message()->set_bb(42);
+ EXPECT_EQ(true, message.has_optional_nested_message());
+ message.clear_optional_nested_message();
+ EXPECT_EQ(false, message.has_optional_nested_message());
+
+ // Likewise for a lazy message field.
+ EXPECT_EQ(false, message.has_optional_lazy_message());
+ // Getter should fetch default instance, and not cause the field to become
+ // present.
+ EXPECT_EQ(0, message.optional_lazy_message().bb());
+ EXPECT_EQ(false, message.has_optional_lazy_message());
+ message.mutable_optional_lazy_message()->set_bb(42);
+ EXPECT_EQ(true, message.has_optional_lazy_message());
+ message.clear_optional_lazy_message();
+ EXPECT_EQ(false, message.has_optional_lazy_message());
+
+ // Test field presence of a message field on the default instance.
+ EXPECT_EQ(false,
+ proto2_nofieldpresence_unittest::TestAllTypes::default_instance()
+ .has_optional_nested_message());
+}
+
+TEST(NoFieldPresenceTest, ReflectionHasFieldTest) {
+ // check that HasField reports true on all scalar fields. Check that it
+ // behaves properly for message fields.
+
+ proto2_nofieldpresence_unittest::TestAllTypes message;
+ const Reflection* r = message.GetReflection();
+ const Descriptor* desc = message.GetDescriptor();
+
+ // Check initial state: scalars not present (due to need to be consistent with
+ // MergeFrom()), message fields not present, oneofs not present.
+ for (int i = 0; i < desc->field_count(); i++) {
+ const FieldDescriptor* field = desc->field(i);
+ if (field->is_repeated()) continue;
+ EXPECT_EQ(false, r->HasField(message, field));
+ }
+
+ // Test field presence of a message field on the default instance.
+ const FieldDescriptor* msg_field =
+ desc->FindFieldByName("optional_nested_message");
+ EXPECT_EQ(
+ false,
+ r->HasField(
+ proto2_nofieldpresence_unittest::TestAllTypes::default_instance(),
+ msg_field));
+
+ // Fill all fields, expect everything to report true (check oneofs below).
+ FillValues(&message);
+ for (int i = 0; i < desc->field_count(); i++) {
+ const FieldDescriptor* field = desc->field(i);
+ if (field->is_repeated() || field->containing_oneof()) {
+ continue;
+ }
+ if (field->options().ctype() != FieldOptions::STRING) {
+ continue;
+ }
+ EXPECT_EQ(true, r->HasField(message, field));
+ }
+
+ message.Clear();
+
+ // Check zero/empty-means-not-present semantics.
+ const FieldDescriptor* field_int32 = desc->FindFieldByName("optional_int32");
+ const FieldDescriptor* field_double =
+ desc->FindFieldByName("optional_double");
+ const FieldDescriptor* field_string =
+ desc->FindFieldByName("optional_string");
+
+ EXPECT_EQ(false, r->HasField(message, field_int32));
+ EXPECT_EQ(false, r->HasField(message, field_double));
+ EXPECT_EQ(false, r->HasField(message, field_string));
+
+ message.set_optional_int32(42);
+ EXPECT_EQ(true, r->HasField(message, field_int32));
+ message.set_optional_int32(0);
+ EXPECT_EQ(false, r->HasField(message, field_int32));
+
+ message.set_optional_double(42.0);
+ EXPECT_EQ(true, r->HasField(message, field_double));
+ message.set_optional_double(0.0);
+ EXPECT_EQ(false, r->HasField(message, field_double));
+
+ message.set_optional_string("test");
+ EXPECT_EQ(true, r->HasField(message, field_string));
+ message.set_optional_string("");
+ EXPECT_EQ(false, r->HasField(message, field_string));
+}
+
+TEST(NoFieldPresenceTest, ReflectionClearFieldTest) {
+ proto2_nofieldpresence_unittest::TestAllTypes message;
+
+ const Reflection* r = message.GetReflection();
+ const Descriptor* desc = message.GetDescriptor();
+
+ const FieldDescriptor* field_int32 = desc->FindFieldByName("optional_int32");
+ const FieldDescriptor* field_double =
+ desc->FindFieldByName("optional_double");
+ const FieldDescriptor* field_string =
+ desc->FindFieldByName("optional_string");
+ const FieldDescriptor* field_message =
+ desc->FindFieldByName("optional_nested_message");
+ const FieldDescriptor* field_lazy =
+ desc->FindFieldByName("optional_lazy_message");
+
+ message.set_optional_int32(42);
+ r->ClearField(&message, field_int32);
+ EXPECT_EQ(0, message.optional_int32());
+
+ message.set_optional_double(42.0);
+ r->ClearField(&message, field_double);
+ EXPECT_EQ(0.0, message.optional_double());
+
+ message.set_optional_string("test");
+ r->ClearField(&message, field_string);
+ EXPECT_EQ("", message.optional_string());
+
+ message.mutable_optional_nested_message()->set_bb(1234);
+ r->ClearField(&message, field_message);
+ EXPECT_FALSE(message.has_optional_nested_message());
+ EXPECT_EQ(0, message.optional_nested_message().bb());
+
+ message.mutable_optional_lazy_message()->set_bb(42);
+ r->ClearField(&message, field_lazy);
+ EXPECT_FALSE(message.has_optional_lazy_message());
+ EXPECT_EQ(0, message.optional_lazy_message().bb());
+}
+
+TEST(NoFieldPresenceTest, HasFieldOneofsTest) {
+ // check that HasField behaves properly for oneofs.
+ proto2_nofieldpresence_unittest::TestAllTypes message;
+
+ const Reflection* r = message.GetReflection();
+ const Descriptor* desc = message.GetDescriptor();
+ const FieldDescriptor* desc_oneof_uint32 =
+ desc->FindFieldByName("oneof_uint32");
+ const FieldDescriptor* desc_oneof_nested_message =
+ desc->FindFieldByName("oneof_nested_message");
+ const FieldDescriptor* desc_oneof_string =
+ desc->FindFieldByName("oneof_string");
+ GOOGLE_CHECK(desc_oneof_uint32 != nullptr);
+ GOOGLE_CHECK(desc_oneof_nested_message != nullptr);
+ GOOGLE_CHECK(desc_oneof_string != nullptr);
+
+ EXPECT_EQ(false, r->HasField(message, desc_oneof_uint32));
+ EXPECT_EQ(false, r->HasField(message, desc_oneof_nested_message));
+ EXPECT_EQ(false, r->HasField(message, desc_oneof_string));
+
+ message.set_oneof_string("test");
+ EXPECT_EQ(false, r->HasField(message, desc_oneof_uint32));
+ EXPECT_EQ(false, r->HasField(message, desc_oneof_nested_message));
+ EXPECT_EQ(true, r->HasField(message, desc_oneof_string));
+ message.mutable_oneof_nested_message()->set_bb(42);
+ EXPECT_EQ(false, r->HasField(message, desc_oneof_uint32));
+ EXPECT_EQ(true, r->HasField(message, desc_oneof_nested_message));
+ EXPECT_EQ(false, r->HasField(message, desc_oneof_string));
+
+ message.Clear();
+ EXPECT_EQ(false, r->HasField(message, desc_oneof_uint32));
+ EXPECT_EQ(false, r->HasField(message, desc_oneof_nested_message));
+ EXPECT_EQ(false, r->HasField(message, desc_oneof_string));
+}
+
+TEST(NoFieldPresenceTest, DontSerializeDefaultValuesTest) {
+ // check that serialized data contains only non-zero numeric fields/non-empty
+ // string/byte fields.
+ proto2_nofieldpresence_unittest::TestAllTypes message;
+ std::string output;
+
+ // All default values -> no output.
+ message.SerializeToString(&output);
+ EXPECT_EQ(0, output.size());
+
+ // Zero values -> still no output.
+ message.set_optional_int32(0);
+ message.set_optional_int64(0);
+ message.set_optional_uint32(0);
+ message.set_optional_uint64(0);
+ message.set_optional_sint32(0);
+ message.set_optional_sint64(0);
+ message.set_optional_fixed32(0);
+ message.set_optional_fixed64(0);
+ message.set_optional_sfixed32(0);
+ message.set_optional_sfixed64(0);
+ message.set_optional_float(0);
+ message.set_optional_double(0);
+ message.set_optional_bool(0);
+ message.set_optional_string("");
+ message.set_optional_bytes("");
+ message.set_optional_nested_enum(
+ proto2_nofieldpresence_unittest::TestAllTypes::FOO); // first enum entry
+ message.set_optional_foreign_enum(
+ proto2_nofieldpresence_unittest::FOREIGN_FOO); // first enum entry
+
+ message.SerializeToString(&output);
+ EXPECT_EQ(0, output.size());
+
+ message.set_optional_int32(1);
+ message.SerializeToString(&output);
+ EXPECT_EQ(2, output.size());
+ EXPECT_EQ("\x08\x01", output);
+
+ message.set_optional_int32(0);
+ message.SerializeToString(&output);
+ EXPECT_EQ(0, output.size());
+}
+
+TEST(NoFieldPresenceTest, MergeFromIfNonzeroTest) {
+ // check that MergeFrom copies if nonzero/nondefault only.
+ proto2_nofieldpresence_unittest::TestAllTypes source;
+ proto2_nofieldpresence_unittest::TestAllTypes dest;
+
+ dest.set_optional_int32(42);
+ dest.set_optional_string("test");
+ source.set_optional_int32(0);
+ source.set_optional_string("");
+ // MergeFrom() copies only if present in serialization, i.e., non-zero.
+ dest.MergeFrom(source);
+ EXPECT_EQ(42, dest.optional_int32());
+ EXPECT_EQ("test", dest.optional_string());
+
+ source.set_optional_int32(84);
+ source.set_optional_string("test2");
+ dest.MergeFrom(source);
+ EXPECT_EQ(84, dest.optional_int32());
+ EXPECT_EQ("test2", dest.optional_string());
+}
+
+TEST(NoFieldPresenceTest, IsInitializedTest) {
+ // Check that IsInitialized works properly.
+ proto2_nofieldpresence_unittest::TestProto2Required message;
+
+ EXPECT_EQ(true, message.IsInitialized());
+ message.mutable_proto2()->set_a(1);
+ EXPECT_EQ(false, message.IsInitialized());
+ message.mutable_proto2()->set_b(1);
+ EXPECT_EQ(false, message.IsInitialized());
+ message.mutable_proto2()->set_c(1);
+ EXPECT_EQ(true, message.IsInitialized());
+}
+
+TEST(NoFieldPresenceTest, LazyMessageFieldHasBit) {
+ // Check that has-bit interaction with lazy message works (has-bit before and
+ // after lazy decode).
+ proto2_nofieldpresence_unittest::TestAllTypes message;
+ const Reflection* r = message.GetReflection();
+ const Descriptor* desc = message.GetDescriptor();
+ const FieldDescriptor* field = desc->FindFieldByName("optional_lazy_message");
+ GOOGLE_CHECK(field != nullptr);
+
+ EXPECT_EQ(false, message.has_optional_lazy_message());
+ EXPECT_EQ(false, r->HasField(message, field));
+
+ message.mutable_optional_lazy_message()->set_bb(42);
+ EXPECT_EQ(true, message.has_optional_lazy_message());
+ EXPECT_EQ(true, r->HasField(message, field));
+
+ // Serialize and parse with a new message object so that lazy field on new
+ // object is in unparsed state.
+ std::string output;
+ message.SerializeToString(&output);
+ proto2_nofieldpresence_unittest::TestAllTypes message2;
+ message2.ParseFromString(output);
+
+ EXPECT_EQ(true, message2.has_optional_lazy_message());
+ EXPECT_EQ(true, r->HasField(message2, field));
+
+ // Access field to force lazy parse.
+ EXPECT_EQ(42, message.optional_lazy_message().bb());
+ EXPECT_EQ(true, message2.has_optional_lazy_message());
+ EXPECT_EQ(true, r->HasField(message2, field));
+}
+
+TEST(NoFieldPresenceTest, OneofPresence) {
+ proto2_nofieldpresence_unittest::TestAllTypes message;
+ // oneof fields still have field presence -- ensure that this goes on the wire
+ // even though its value is the empty string.
+ message.set_oneof_string("");
+ std::string serialized;
+ message.SerializeToString(&serialized);
+ // Tag: 113 --> tag is (113 << 3) | 2 (length delimited) = 906
+ // varint: 0x8a 0x07
+ // Length: 0x00
+ EXPECT_EQ(3, serialized.size());
+ EXPECT_EQ(static_cast<char>(0x8a), serialized.at(0));
+ EXPECT_EQ(static_cast<char>(0x07), serialized.at(1));
+ EXPECT_EQ(static_cast<char>(0x00), serialized.at(2));
+
+ message.Clear();
+ EXPECT_TRUE(message.ParseFromString(serialized));
+ EXPECT_EQ(proto2_nofieldpresence_unittest::TestAllTypes::kOneofString,
+ message.oneof_field_case());
+
+ // Also test int32 and enum fields.
+ message.Clear();
+ message.set_oneof_uint32(0); // would not go on wire if ordinary field.
+ message.SerializeToString(&serialized);
+ EXPECT_EQ(3, serialized.size());
+ EXPECT_TRUE(message.ParseFromString(serialized));
+ EXPECT_EQ(proto2_nofieldpresence_unittest::TestAllTypes::kOneofUint32,
+ message.oneof_field_case());
+
+ message.Clear();
+ message.set_oneof_enum(
+ proto2_nofieldpresence_unittest::TestAllTypes::FOO); // default
+ // value.
+ message.SerializeToString(&serialized);
+ EXPECT_EQ(3, serialized.size());
+ EXPECT_TRUE(message.ParseFromString(serialized));
+ EXPECT_EQ(proto2_nofieldpresence_unittest::TestAllTypes::kOneofEnum,
+ message.oneof_field_case());
+
+ message.Clear();
+ message.set_oneof_string("test");
+ message.clear_oneof_string();
+ EXPECT_EQ(0, message.ByteSizeLong());
+}
+
+} // namespace
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/package_info.h b/NorthstarDedicatedTest/include/protobuf/package_info.h
new file mode 100644
index 00000000..2b61679a
--- /dev/null
+++ b/NorthstarDedicatedTest/include/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/NorthstarDedicatedTest/include/protobuf/parse_context.cc b/NorthstarDedicatedTest/include/protobuf/parse_context.cc
new file mode 100644
index 00000000..944474cd
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/parse_context.cc
@@ -0,0 +1,559 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <parse_context.h>
+
+#include <stubs/stringprintf.h>
+#include <io/coded_stream.h>
+#include <io/zero_copy_stream.h>
+#include <arenastring.h>
+#include <message_lite.h>
+#include <repeated_field.h>
+#include <wire_format_lite.h>
+#include <stubs/strutil.h>
+
+#include <port_def.inc>
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+namespace {
+
+// Only call if at start of tag.
+bool ParseEndsInSlopRegion(const char* begin, int overrun, int depth) {
+ constexpr int kSlopBytes = EpsCopyInputStream::kSlopBytes;
+ GOOGLE_DCHECK(overrun >= 0);
+ GOOGLE_DCHECK(overrun <= kSlopBytes);
+ auto ptr = begin + overrun;
+ auto end = begin + kSlopBytes;
+ while (ptr < end) {
+ 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(limit_ > 0);
+ GOOGLE_DCHECK(limit_end_ == buffer_end_); // because limit_ > 0
+ const char* p;
+ do {
+ // We are past the end of buffer_end_, in the slop region.
+ GOOGLE_DCHECK(overrun >= 0);
+ p = NextBuffer(overrun, depth);
+ if (p == nullptr) {
+ // We are at the end of the stream
+ if (PROTOBUF_PREDICT_FALSE(overrun != 0)) return {nullptr, true};
+ GOOGLE_DCHECK(limit_ > 0);
+ limit_end_ = buffer_end_;
+ // Distinguish ending on a pushed limit or ending on end-of-stream.
+ SetEndOfStream();
+ return {buffer_end_, true};
+ }
+ limit_ -= buffer_end_ - p; // Adjust limit_ relative to new anchor
+ p += overrun;
+ overrun = p - buffer_end_;
+ } while (overrun >= 0);
+ limit_end_ = buffer_end_ + std::min(0, limit_);
+ return {p, false};
+}
+
+const char* EpsCopyInputStream::SkipFallback(const char* ptr, int size) {
+ return AppendSize(ptr, size, [](const char* /*p*/, int /*s*/) {});
+}
+
+const char* EpsCopyInputStream::ReadStringFallback(const char* ptr, int size,
+ 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); });
+}
+
+
+template <int>
+void byteswap(void* p);
+template <>
+void byteswap<1>(void* /*p*/) {}
+template <>
+void byteswap<4>(void* p) {
+ *static_cast<uint32_t*>(p) = bswap_32(*static_cast<uint32_t*>(p));
+}
+template <>
+void byteswap<8>(void* p) {
+ *static_cast<uint64_t*>(p) = bswap_64(*static_cast<uint64_t*>(p));
+}
+
+const char* EpsCopyInputStream::InitFrom(io::ZeroCopyInputStream* zcis) {
+ zcis_ = zcis;
+ const void* data;
+ int size;
+ limit_ = INT_MAX;
+ if (zcis->Next(&data, &size)) {
+ overall_limit_ -= size;
+ if (size > kSlopBytes) {
+ auto ptr = static_cast<const char*>(data);
+ limit_ -= size - kSlopBytes;
+ limit_end_ = buffer_end_ = ptr + size - kSlopBytes;
+ next_chunk_ = buffer_;
+ if (aliasing_ == kOnPatch) aliasing_ = kNoDelta;
+ return ptr;
+ } else {
+ limit_end_ = buffer_end_ = buffer_ + kSlopBytes;
+ next_chunk_ = buffer_;
+ auto ptr = buffer_ + 2 * kSlopBytes - size;
+ std::memcpy(ptr, data, size);
+ return ptr;
+ }
+ }
+ overall_limit_ = 0;
+ next_chunk_ = nullptr;
+ size_ = 0;
+ limit_end_ = buffer_end_ = buffer_;
+ return buffer_;
+}
+
+const char* ParseContext::ReadSizeAndPushLimitAndDepth(const char* ptr,
+ int* old_limit) {
+ int size = ReadSize(&ptr);
+ if (PROTOBUF_PREDICT_FALSE(!ptr)) {
+ *old_limit = 0; // Make sure this isn't uninitialized even on error return
+ return nullptr;
+ }
+ *old_limit = PushLimit(ptr, size);
+ if (--depth_ < 0) return nullptr;
+ return ptr;
+}
+
+const char* ParseContext::ParseMessage(MessageLite* msg, const char* ptr) {
+ int old;
+ ptr = ReadSizeAndPushLimitAndDepth(ptr, &old);
+ ptr = ptr ? msg->_InternalParse(ptr, this) : nullptr;
+ depth_++;
+ if (!PopLimit(old)) return nullptr;
+ return ptr;
+}
+
+inline void WriteVarint(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(const char* field_name, const char* operation_str,
+ bool emit_stacktrace);
+
+bool VerifyUTF8(StringPiece str, const char* field_name) {
+ if (!IsStructurallyValidUTF8(str)) {
+ PrintUTF8ErrorLog(field_name, "parsing", false);
+ return false;
+ }
+ return true;
+}
+
+const char* InlineGreedyStringParser(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 <port_undef.inc>
diff --git a/NorthstarDedicatedTest/include/protobuf/parse_context.h b/NorthstarDedicatedTest/include/protobuf/parse_context.h
new file mode 100644
index 00000000..7bc9b8af
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/parse_context.h
@@ -0,0 +1,938 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 <io/coded_stream.h>
+#include <io/zero_copy_stream.h>
+#include <arena.h>
+#include <arenastring.h>
+#include <implicit_weak_message.h>
+#include <inlined_string_field.h>
+#include <metadata_lite.h>
+#include <port.h>
+#include <repeated_field.h>
+#include <wire_format_lite.h>
+#include <stubs/strutil.h>
+
+#include <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_);
+ }
+ 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;
+};
+
+// ParseContext holds all data that is global to the entire parse. Most
+// importantly it contains the input stream, but also recursion depth and also
+// stores the end group tag, in case a parser ended on a endgroup, to verify
+// matching start/end group tags.
+class PROTOBUF_EXPORT ParseContext : public EpsCopyInputStream {
+ public:
+ struct Data {
+ const DescriptorPool* pool = nullptr;
+ MessageFactory* factory = nullptr;
+ Arena* arena = nullptr;
+ };
+
+ template <typename... T>
+ ParseContext(int depth, bool aliasing, const char** start, T&&... args)
+ : EpsCopyInputStream(aliasing), depth_(depth) {
+ *start = InitFrom(std::forward<T>(args)...);
+ }
+
+ void TrackCorrectEnding() { group_depth_ = 0; }
+
+ bool Done(const char** ptr) { return DoneWithCheck(ptr, group_depth_); }
+
+ int depth() const { return depth_; }
+
+ Data& data() { return data_; }
+ const Data& data() const { return data_; }
+
+ const char* ParseMessage(MessageLite* msg, const char* ptr);
+
+ // This overload supports those few cases where ParseMessage is called
+ // on a class that is not actually a proto message.
+ // TODO(jorg): Eliminate this use case.
+ template <typename T,
+ typename std::enable_if<!std::is_base_of<MessageLite, T>::value,
+ bool>::type = true>
+ PROTOBUF_NODISCARD const char* ParseMessage(T* msg, const char* ptr);
+
+ template <typename T>
+ PROTOBUF_NODISCARD PROTOBUF_NDEBUG_INLINE const char* ParseGroup(
+ T* msg, const char* ptr, 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);
+#ifndef PROTOBUF_LITTLE_ENDIAN
+ tmp = bswap_16(tmp);
+#endif
+ return tmp;
+ }
+};
+
+template <>
+struct EndianHelper<4> {
+ static uint32_t Load(const void* p) {
+ uint32_t tmp;
+ std::memcpy(&tmp, p, 4);
+#ifndef PROTOBUF_LITTLE_ENDIAN
+ tmp = bswap_32(tmp);
+#endif
+ return tmp;
+ }
+};
+
+template <>
+struct EndianHelper<8> {
+ static uint64_t Load(const void* p) {
+ uint64_t tmp;
+ std::memcpy(&tmp, p, 8);
+#ifndef PROTOBUF_LITTLE_ENDIAN
+ tmp = bswap_64(tmp);
+#endif
+ return tmp;
+ }
+};
+
+template <typename T>
+T UnalignedLoad(const char* p) {
+ auto tmp = EndianHelper<sizeof(T)>::Load(p);
+ T res;
+ memcpy(&res, &tmp, sizeof(T));
+ return res;
+}
+
+PROTOBUF_EXPORT
+std::pair<const char*, 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;
+}
+
+// Decode 2 consecutive bytes of a varint and returns the value, shifted left
+// by 1. It simultaneous updates *ptr to *ptr + 1 or *ptr + 2 depending if the
+// first byte's continuation bit is set.
+// If bit 15 of return value is set (equivalent to the continuation bits of both
+// bytes being set) the varint continues, otherwise the parse is done. On x86
+// movsx eax, dil
+// add edi, eax
+// adc [rsi], 1
+// add eax, eax
+// and eax, edi
+inline 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);
+ // This add is an amazing operation, it cancels the low byte continuation bit
+ // from y transferring it to the carry. Simultaneously it also shifts the 7
+ // LSB left by one tightly against high byte varint bits. Hence value now
+ // contains the unpacked value shifted left by 1.
+ value += x;
+ // Use the carry to update the ptr appropriately.
+ *ptr += value < x ? 2 : 1;
+ return value & (x + x); // Mask out the high byte iff no continuation
+}
+
+// More efficient varint parsing for big varints
+inline const char* ParseBigVarint(const char* p, 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_EXPORT PROTOBUF_NODISCARD 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_EXPORT PROTOBUF_NODISCARD const char* PackedInt32Parser(
+ void* object, const char* ptr, ParseContext* ctx);
+PROTOBUF_EXPORT PROTOBUF_NODISCARD const char* PackedUInt32Parser(
+ void* object, const char* ptr, ParseContext* ctx);
+PROTOBUF_EXPORT PROTOBUF_NODISCARD const char* PackedInt64Parser(
+ void* object, const char* ptr, ParseContext* ctx);
+PROTOBUF_EXPORT PROTOBUF_NODISCARD const char* PackedUInt64Parser(
+ void* object, const char* ptr, ParseContext* ctx);
+PROTOBUF_EXPORT PROTOBUF_NODISCARD const char* PackedSInt32Parser(
+ void* object, const char* ptr, ParseContext* ctx);
+PROTOBUF_EXPORT PROTOBUF_NODISCARD const char* PackedSInt64Parser(
+ void* object, const char* ptr, ParseContext* ctx);
+PROTOBUF_EXPORT PROTOBUF_NODISCARD const char* PackedEnumParser(
+ void* object, const char* ptr, ParseContext* ctx);
+
+template <typename T>
+PROTOBUF_NODISCARD const char* PackedEnumParser(void* object, const char* ptr,
+ ParseContext* ctx,
+ bool (*is_valid)(int),
+ InternalMetadata* metadata,
+ int field_num) {
+ return ctx->ReadPackedVarint(
+ ptr, [object, is_valid, metadata, field_num](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_EXPORT PROTOBUF_NODISCARD const char* PackedBoolParser(
+ void* object, const char* ptr, ParseContext* ctx);
+PROTOBUF_EXPORT PROTOBUF_NODISCARD const char* PackedFixed32Parser(
+ void* object, const char* ptr, ParseContext* ctx);
+PROTOBUF_EXPORT PROTOBUF_NODISCARD const char* PackedSFixed32Parser(
+ void* object, const char* ptr, ParseContext* ctx);
+PROTOBUF_EXPORT PROTOBUF_NODISCARD const char* PackedFixed64Parser(
+ void* object, const char* ptr, ParseContext* ctx);
+PROTOBUF_EXPORT PROTOBUF_NODISCARD const char* PackedSFixed64Parser(
+ void* object, const char* ptr, ParseContext* ctx);
+PROTOBUF_EXPORT PROTOBUF_NODISCARD const char* PackedFloatParser(
+ void* object, const char* ptr, ParseContext* ctx);
+PROTOBUF_EXPORT PROTOBUF_NODISCARD const char* PackedDoubleParser(
+ void* object, const char* ptr, ParseContext* ctx);
+
+// This is the only recursive parser.
+PROTOBUF_EXPORT PROTOBUF_NODISCARD const char* UnknownGroupLiteParse(
+ 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_EXPORT PROTOBUF_NODISCARD const char* UnknownFieldParse(
+ uint32_t tag, std::string* unknown, const char* ptr, ParseContext* ctx);
+
+} // namespace internal
+} // namespace protobuf
+} // namespace google
+
+#include <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_PARSE_CONTEXT_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/port.h b/NorthstarDedicatedTest/include/protobuf/port.h
new file mode 100644
index 00000000..4c09eb1d
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/port.h
@@ -0,0 +1,40 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// A common header that is included across all protobuf headers. We do our best
+// to avoid #defining any macros here; instead we generally put macros in
+// port_def.inc and port_undef.inc so they are not visible from outside of
+// protobuf.
+
+#ifndef GOOGLE_PROTOBUF_PORT_H__
+#define GOOGLE_PROTOBUF_PORT_H__
+
+
+#endif // GOOGLE_PROTOBUF_PORT_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/port_def.inc b/NorthstarDedicatedTest/include/protobuf/port_def.inc
new file mode 100644
index 00000000..37632cf5
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/port_def.inc
@@ -0,0 +1,824 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// This file defines common macros that are used in protobuf.
+//
+// To hide these definitions from the outside world (and to prevent collisions
+// if more than one version of protobuf is #included in the same project) you
+// must follow this pattern when #including port_def.inc in a header file:
+//
+// #include "other_header.h"
+// #include "message.h"
+// // etc.
+//
+// #include "port_def.inc" // MUST be last header included
+//
+// // Definitions for this header.
+//
+// #include "port_undef.inc"
+//
+// This is a textual header with no include guard, because we want to
+// detect/prohibit anytime it is #included twice without a corresponding
+// #undef.
+
+// The definitions in this file are intended to be portable across Clang,
+// GCC, and MSVC. Function-like macros are usable without an #ifdef guard.
+// Syntax macros (for example, attributes) are always defined, although
+// they may be empty.
+//
+// Some definitions rely on the NDEBUG macro and/or (in MSVC) _DEBUG:
+// - https://en.cppreference.com/w/c/error/assert
+// - https://docs.microsoft.com/en-us/cpp/preprocessor/predefined-macros#microsoft-specific-predefined-macros
+//
+// References for predefined macros:
+// - Standard: https://en.cppreference.com/w/cpp/preprocessor/replace
+// - Clang: https://clang.llvm.org/docs/LanguageExtensions.html
+// (see also GCC predefined macros)
+// - GCC: https://gcc.gnu.org/onlinedocs/cpp/Predefined-Macros.html
+// - MSVC: https://docs.microsoft.com/en-us/cpp/preprocessor/predefined-macros
+// - Interactive (Clang/GCC only): https://www.compiler-explorer.com/z/hc6jKd3sj
+//
+// References for attributes (and extension attributes):
+// - Standard: https://en.cppreference.com/w/cpp/language/attributes
+// - Clang: https://clang.llvm.org/docs/AttributeReference.html
+// - GCC: https://gcc.gnu.org/onlinedocs/gcc/Attribute-Syntax.html
+// (see Clang attribute docs as well)
+//
+// References for standard C++ language conformance (and minimum versions):
+// - Clang: https://clang.llvm.org/cxx_status.html
+// - GCC: https://gcc.gnu.org/projects/cxx-status.html
+// - MSVC: https://docs.microsoft.com/en-us/cpp/overview/visual-cpp-language-conformance
+//
+// Historical release notes (which can help to determine minimum versions):
+// - Clang: https://releases.llvm.org/
+// - GCC: https://gcc.gnu.org/releases.html
+// - MSVC: https://docs.microsoft.com/en-us/visualstudio/releases/2019/release-notes-history
+// https://docs.microsoft.com/en-us/visualstudio/releasenotes/vs2017-relnotes-history
+
+// Portable fallbacks for C++20 feature test macros:
+// https://en.cppreference.com/w/cpp/feature_test
+#ifndef __has_cpp_attribute
+#define __has_cpp_attribute(x) 0
+#define PROTOBUF_has_cpp_attribute_DEFINED_
+#endif
+
+// Portable fallback for Clang's __has_feature macro:
+// https://clang.llvm.org/docs/LanguageExtensions.html#has-feature-and-has-extension
+#ifndef __has_feature
+#define __has_feature(x) 0
+#define PROTOBUF_has_feature_DEFINED_
+#endif
+
+// Portable fallback for Clang's __has_warning macro:
+#ifndef __has_warning
+#define __has_warning(x) 0
+#define PROTOBUF_has_warning_DEFINED_
+#endif
+
+// Portable fallbacks for the __has_attribute macro (GCC and Clang):
+// https://clang.llvm.org/docs/LanguageExtensions.html#has-attribute
+// https://gcc.gnu.org/onlinedocs/cpp/_005f_005fhas_005fattribute.html
+#ifndef __has_attribute
+#define __has_attribute(x) 0
+#define PROTOBUF_has_attribute_DEFINED_
+#endif
+
+// Portable fallback for __has_builtin (GCC and Clang):
+// https://clang.llvm.org/docs/LanguageExtensions.html#has-builtin
+// https://gcc.gnu.org/onlinedocs/cpp/_005f_005fhas_005fbuiltin.html
+#ifndef __has_builtin
+#define __has_builtin(x) 0
+#define PROTOBUF_has_builtin_DEFINED_
+#endif
+
+// Portable check for GCC minimum version:
+// https://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html
+#if defined(__GNUC__) && defined(__GNUC_MINOR__) \
+ && defined(__GNUC_PATCHLEVEL__)
+# define PROTOBUF_GNUC_MIN(x, y) \
+ (__GNUC__ > (x) || __GNUC__ == (x) && __GNUC_MINOR__ >= (y))
+#else
+# define PROTOBUF_GNUC_MIN(x, y) 0
+#endif
+
+// Portable check for MSVC minimum version:
+// https://docs.microsoft.com/en-us/cpp/preprocessor/predefined-macros
+#if defined(_MSC_VER)
+#define PROTOBUF_MSC_VER_MIN(x) (_MSC_VER >= x)
+#else
+#define PROTOBUF_MSC_VER_MIN(x) 0
+#endif
+
+// Portable check for minimum C++ language version:
+// https://en.cppreference.com/w/cpp/preprocessor/replace
+// https://docs.microsoft.com/en-us/cpp/preprocessor/predefined-macros
+#if !defined(_MSVC_LANG)
+#define PROTOBUF_CPLUSPLUS_MIN(x) (__cplusplus >= x)
+#else
+#define PROTOBUF_CPLUSPLUS_MIN(x) (_MSVC_LANG >= x)
+#endif
+
+// Future versions of protobuf will include breaking changes to some APIs.
+// This macro can be set to enable these API changes ahead of time, so that
+// user code can be updated before upgrading versions of protobuf.
+// #define PROTOBUF_FUTURE_BREAKING_CHANGES 1
+
+#ifdef PROTOBUF_VERSION
+#error PROTOBUF_VERSION was previously defined
+#endif
+#define PROTOBUF_VERSION 3019004
+
+#ifdef PROTOBUF_MIN_HEADER_VERSION_FOR_PROTOC
+#error PROTOBUF_MIN_HEADER_VERSION_FOR_PROTOC was previously defined
+#endif
+#define PROTOBUF_MIN_HEADER_VERSION_FOR_PROTOC 3019000
+
+#ifdef PROTOBUF_MIN_PROTOC_VERSION
+#error PROTOBUF_MIN_PROTOC_VERSION was previously defined
+#endif
+#define PROTOBUF_MIN_PROTOC_VERSION 3019000
+
+#ifdef PROTOBUF_VERSION_SUFFIX
+#error PROTOBUF_VERSION_SUFFIX was previously defined
+#endif
+#define PROTOBUF_VERSION_SUFFIX ""
+
+#if defined(PROTOBUF_NAMESPACE) || defined(PROTOBUF_NAMESPACE_ID)
+#error PROTOBUF_NAMESPACE or PROTOBUF_NAMESPACE_ID was previously defined
+#endif
+#define PROTOBUF_NAMESPACE "google::protobuf"
+#define PROTOBUF_NAMESPACE_ID google::protobuf
+#define PROTOBUF_NAMESPACE_OPEN \
+ namespace google { \
+ namespace protobuf {
+#define PROTOBUF_NAMESPACE_CLOSE \
+ } /* namespace protobuf */ \
+ } /* namespace google */
+
+#ifdef PROTOBUF_ALWAYS_INLINE
+#error PROTOBUF_ALWAYS_INLINE was previously defined
+#endif
+// For functions we want to force inline.
+#if defined(PROTOBUF_NO_INLINE)
+# define PROTOBUF_ALWAYS_INLINE
+#elif PROTOBUF_GNUC_MIN(3, 1)
+# define PROTOBUF_ALWAYS_INLINE __attribute__((always_inline))
+#elif defined(_MSC_VER)
+# define PROTOBUF_ALWAYS_INLINE __forceinline
+#else
+# define PROTOBUF_ALWAYS_INLINE
+#endif
+
+#ifdef PROTOBUF_NDEBUG_INLINE
+#error PROTOBUF_NDEBUG_INLINE was previously defined
+#endif
+// Avoid excessive inlining in non-optimized builds. Without other optimizations
+// the inlining is not going to provide benefits anyway and the huge resulting
+// functions, especially in the proto-generated serialization functions, produce
+// stack frames so large that many tests run into stack overflows (b/32192897).
+#if defined(NDEBUG) || (defined(_MSC_VER) && !defined(_DEBUG))
+# define PROTOBUF_NDEBUG_INLINE PROTOBUF_ALWAYS_INLINE
+#else
+# define PROTOBUF_NDEBUG_INLINE
+#endif
+
+// Note that PROTOBUF_NOINLINE is an attribute applied to functions, to prevent
+// them from being inlined by the compiler. This is different from
+// PROTOBUF_NO_INLINE, which is a user-supplied macro that disables forced
+// inlining by PROTOBUF_(ALWAYS|NDEBUG)_INLINE.
+#ifdef PROTOBUF_NOINLINE
+#error PROTOBUF_NOINLINE was previously defined
+#endif
+#if PROTOBUF_GNUC_MIN(3, 1)
+# define PROTOBUF_NOINLINE __attribute__((noinline))
+#elif defined(_MSC_VER)
+// Seems to have been around since at least Visual Studio 2005
+# define PROTOBUF_NOINLINE __declspec(noinline)
+#endif
+
+#ifdef PROTOBUF_MUSTTAIL
+#error PROTOBUF_MUSTTAIL was previously defined
+#endif
+#ifdef PROTOBUF_TAILCALL
+#error PROTOBUF_TAILCALL was previously defined
+#endif
+#if __has_cpp_attribute(clang::musttail) && \
+ !defined(__arm__) && !defined(_ARCH_PPC) && !defined(__wasm__)
+# ifndef PROTO2_OPENSOURCE
+// Compilation fails on ARM32: b/195943306
+// Compilation fails on powerpc64le: b/187985113
+# endif
+#define PROTOBUF_MUSTTAIL [[clang::musttail]]
+#define PROTOBUF_TAILCALL true
+#else
+#define PROTOBUF_MUSTTAIL
+#define PROTOBUF_TAILCALL false
+#endif
+
+#ifdef PROTOBUF_EXCLUSIVE_LOCKS_REQUIRED
+#error PROTOBUF_EXCLUSIVE_LOCKS_REQUIRED was previously defined
+#endif
+#if __has_attribute(exclusive_locks_required)
+#define PROTOBUF_EXCLUSIVE_LOCKS_REQUIRED(...) \
+ __attribute__((exclusive_locks_required(__VA_ARGS__)))
+#else
+#define PROTOBUF_EXCLUSIVE_LOCKS_REQUIRED(...)
+#endif
+
+#ifdef PROTOBUF_NO_THREAD_SAFETY_ANALYSIS
+#error PROTOBUF_NO_THREAD_SAFETY_ANALYSIS was previously defined
+#endif
+#if __has_attribute(no_thread_safety_analysis)
+#define PROTOBUF_NO_THREAD_SAFETY_ANALYSIS \
+ __attribute__((no_thread_safety_analysis))
+#else
+#define PROTOBUF_NO_THREAD_SAFETY_ANALYSIS
+#endif
+
+#ifdef PROTOBUF_GUARDED_BY
+#error PROTOBUF_GUARDED_BY was previously defined
+#endif
+#if __has_attribute(guarded_by)
+#define PROTOBUF_GUARDED_BY(x) __attribute__((guarded_by(x)))
+#else
+#define PROTOBUF_GUARDED_BY(x)
+#endif
+
+#ifdef PROTOBUF_LOCKS_EXCLUDED
+#error PROTOBUF_LOCKS_EXCLUDED was previously defined
+#endif
+#if __has_attribute(locks_excluded)
+#define PROTOBUF_LOCKS_EXCLUDED(...) \
+ __attribute__((locks_excluded(__VA_ARGS__)))
+#else
+#define PROTOBUF_LOCKS_EXCLUDED(...)
+#endif
+
+#ifdef PROTOBUF_COLD
+#error PROTOBUF_COLD was previously defined
+#endif
+#if __has_attribute(cold) || PROTOBUF_GNUC_MIN(4, 3)
+# define PROTOBUF_COLD __attribute__((cold))
+#else
+# define PROTOBUF_COLD
+#endif
+
+#ifdef PROTOBUF_SECTION_VARIABLE
+#error PROTOBUF_SECTION_VARIABLE was previously defined
+#endif
+#if (__has_attribute(section) || defined(__GNUC__)) && defined(__ELF__)
+// Place a variable in the given ELF section.
+# define PROTOBUF_SECTION_VARIABLE(x) __attribute__((section(#x)))
+#else
+# define PROTOBUF_SECTION_VARIABLE(x)
+#endif
+
+#if defined(PROTOBUF_DEPRECATED)
+#error PROTOBUF_DEPRECATED was previously defined
+#endif
+#if defined(PROTOBUF_DEPRECATED_MSG)
+#error PROTOBUF_DEPRECATED_MSG was previously defined
+#endif
+#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 3019000
+
+#ifdef PROTOBUF_RTTI
+#error PROTOBUF_RTTI was previously defined
+#endif
+#if defined(GOOGLE_PROTOBUF_NO_RTTI) && GOOGLE_PROTOBUF_NO_RTTI
+#define PROTOBUF_RTTI 0
+#elif __has_feature(cxx_rtti)
+#define PROTOBUF_RTTI 1
+#elif defined(__cxx_rtti)
+// https://en.cppreference.com/w/User:D41D8CD98F/feature_testing_macros#C.2B.2B98
+#define PROTOBUF_RTTI 1
+#else
+#define PROTOBUF_RTTI 0
+#endif
+
+// Returns the offset of the given field within the given aggregate type.
+// This is equivalent to the ANSI C offsetof() macro. However, according
+// to the C++ standard, offsetof() only works on POD types, and GCC
+// enforces this requirement with a warning. In practice, this rule is
+// unnecessarily strict; there is probably no compiler or platform on
+// which the offsets of the direct fields of a class are non-constant.
+// Fields inherited from superclasses *can* have non-constant offsets,
+// but that's not what this macro will be used for.
+#ifdef PROTOBUF_FIELD_OFFSET
+#error PROTOBUF_FIELD_OFFSET was previously defined
+#endif
+#if defined(__clang__)
+// For Clang we use __builtin_offsetof() and suppress the warning,
+// to avoid Control Flow Integrity and UBSan vptr sanitizers from
+// crashing while trying to validate the invalid reinterpret_casts.
+#define PROTOBUF_FIELD_OFFSET(TYPE, FIELD) \
+ _Pragma("clang diagnostic push") \
+ _Pragma("clang diagnostic ignored \"-Winvalid-offsetof\"") \
+ __builtin_offsetof(TYPE, FIELD) \
+ _Pragma("clang diagnostic pop")
+#elif PROTOBUF_GNUC_MIN(4, 8)
+#define PROTOBUF_FIELD_OFFSET(TYPE, FIELD) __builtin_offsetof(TYPE, FIELD)
+#else // defined(__clang__)
+// Note that we calculate relative to the pointer value 16 here since if we
+// just use zero, GCC complains about dereferencing a NULL pointer. We
+// choose 16 rather than some other number just in case the compiler would
+// be confused by an unaligned pointer.
+#define PROTOBUF_FIELD_OFFSET(TYPE, FIELD) \
+ static_cast< ::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(LIBPROTOBUF_EXPORTS)
+# define PROTOC_EXPORT __attribute__((visibility("default")))
+#else
+# define PROTOC_EXPORT
+#endif
+
+#if defined(PROTOBUF_PREDICT_TRUE) || defined(PROTOBUF_PREDICT_FALSE)
+#error PROTOBUF_PREDICT_(TRUE|FALSE) was previously defined
+#endif
+#if PROTOBUF_GNUC_MIN(3, 0)
+# define PROTOBUF_PREDICT_TRUE(x) (__builtin_expect(false || (x), true))
+# define PROTOBUF_PREDICT_FALSE(x) (__builtin_expect(false || (x), false))
+#else
+# define PROTOBUF_PREDICT_TRUE(x) (x)
+# define PROTOBUF_PREDICT_FALSE(x) (x)
+#endif
+
+#ifdef PROTOBUF_NODISCARD
+#error PROTOBUF_NODISCARD was previously defined
+#endif
+#if __has_cpp_attribute(nodiscard)
+#define PROTOBUF_NODISCARD [[nodiscard]]
+#elif __has_attribute(warn_unused_result) || PROTOBUF_GNUC_MIN(4, 8)
+#define PROTOBUF_NODISCARD __attribute__((warn_unused_result))
+#else
+#define PROTOBUF_NODISCARD
+#endif
+
+#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE
+#error PROTOBUF_FORCE_COPY_IN_RELEASE was previously defined
+#endif
+
+#ifdef PROTOBUF_FORCE_COPY_IN_SWAP
+#error PROTOBUF_FORCE_COPY_IN_SWAP was previously defined
+#endif
+
+#ifdef PROTOBUF_FORCE_COPY_IN_MOVE
+#error PROTOBUF_FORCE_COPY_IN_MOVE was previously defined
+#endif
+
+// Force copy the default string to a string field so that non-optimized builds
+// have harder-to-rely-on address stability.
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+#error PROTOBUF_FORCE_COPY_DEFAULT_STRING was previously defined
+#endif
+
+#ifdef PROTOBUF_FALLTHROUGH_INTENDED
+#error PROTOBUF_FALLTHROUGH_INTENDED was previously defined
+#endif
+#if __has_cpp_attribute(fallthrough)
+#define PROTOBUF_FALLTHROUGH_INTENDED [[fallthrough]]
+#elif __has_feature(cxx_attributes) && __has_warning("-Wimplicit-fallthrough")
+#define PROTOBUF_FALLTHROUGH_INTENDED [[clang::fallthrough]]
+#elif PROTOBUF_GNUC_MIN(7, 0)
+#define PROTOBUF_FALLTHROUGH_INTENDED [[gnu::fallthrough]]
+#else
+#define PROTOBUF_FALLTHROUGH_INTENDED
+#endif
+
+// PROTOBUF_ASSUME(pred) tells the compiler that it can assume pred is true. To
+// be safe, we also validate the assumption with a GOOGLE_DCHECK in unoptimized
+// builds. The macro does not do anything useful if the compiler does not
+// support __builtin_assume.
+#ifdef PROTOBUF_ASSUME
+#error PROTOBUF_ASSUME was previously defined
+#endif
+#if __has_builtin(__builtin_assume)
+#define PROTOBUF_ASSUME(pred) \
+ GOOGLE_DCHECK(pred); \
+ __builtin_assume(pred)
+#else
+#define PROTOBUF_ASSUME(pred) GOOGLE_DCHECK(pred)
+#endif
+
+// Specify memory alignment for structs, classes, etc.
+// Use like:
+// class PROTOBUF_ALIGNAS(16) MyClass { ... }
+// PROTOBUF_ALIGNAS(16) int array[4];
+//
+// In most places you can use the C++11 keyword "alignas", which is preferred.
+//
+// But compilers have trouble mixing __attribute__((...)) syntax with
+// alignas(...) syntax.
+//
+// Doesn't work in clang or gcc:
+// struct alignas(16) __attribute__((packed)) S { char c; };
+// Works in clang but not gcc:
+// struct __attribute__((packed)) alignas(16) S2 { char c; };
+// Works in clang and gcc:
+// struct alignas(16) S3 { char c; } __attribute__((packed));
+//
+// There are also some attributes that must be specified *before* a class
+// definition: visibility (used for exporting functions/classes) is one of
+// these attributes. This means that it is not possible to use alignas() with a
+// class that is marked as exported.
+#ifdef PROTOBUF_ALIGNAS
+#error PROTOBUF_ALIGNAS was previously defined
+#endif
+#if defined(_MSC_VER)
+#define PROTOBUF_ALIGNAS(byte_alignment) __declspec(align(byte_alignment))
+#elif PROTOBUF_GNUC_MIN(3, 0)
+#define PROTOBUF_ALIGNAS(byte_alignment) \
+ __attribute__((aligned(byte_alignment)))
+#else
+#define PROTOBUF_ALIGNAS(byte_alignment) alignas(byte_alignment)
+#endif
+
+#ifdef PROTOBUF_FINAL
+#error PROTOBUF_FINAL was previously defined
+#endif
+#define PROTOBUF_FINAL final
+
+#ifdef PROTOBUF_THREAD_LOCAL
+#error PROTOBUF_THREAD_LOCAL was previously defined
+#endif
+#if defined(_MSC_VER)
+#define PROTOBUF_THREAD_LOCAL __declspec(thread)
+#else
+#define PROTOBUF_THREAD_LOCAL __thread
+#endif
+
+// For enabling message owned arena, one major blocker is semantic change from
+// moving to copying when there is ownership transfer (e.g., move ctor, swap,
+// set allocated, release). This change not only causes performance regression
+// but also breaks users code (e.g., dangling reference). For top-level
+// messages, since it owns the arena, we can mitigate the issue by transferring
+// ownership of arena. However, we cannot do that for nested messages. In order
+// to tell how many usages of nested messages affected by message owned arena,
+// we need to simulate the arena ownership.
+// This experiment is purely for the purpose of gathering data. All code guarded
+// by this flag is supposed to be removed after this experiment.
+#define PROTOBUF_MESSAGE_OWNED_ARENA_EXPERIMENT
+#ifdef PROTOBUF_CONSTINIT
+#error PROTOBUF_CONSTINIT was previously defined
+#endif
+#if defined(__cpp_constinit) && !PROTOBUF_GNUC_MIN(3, 0) && !defined(_MSC_VER)
+// Our use of constinit does not yet work with GCC:
+// https://github.com/protocolbuffers/protobuf/issues/8310
+// Does not work yet with Visual Studio 2019 Update 16.10
+#define PROTOBUF_CONSTINIT constinit
+#elif !defined(_MSC_VER) && \
+ __has_cpp_attribute(clang::require_constant_initialization)
+#define PROTOBUF_CONSTINIT [[clang::require_constant_initialization]]
+#else
+#define PROTOBUF_CONSTINIT
+#endif
+
+// Some globals with an empty non-trivial destructor are annotated with
+// no_destroy for performance reasons. It reduces the cost of these globals in
+// non-opt mode and under sanitizers.
+#ifdef PROTOBUF_ATTRIBUTE_NO_DESTROY
+#error PROTOBUF_ATTRIBUTE_NO_DESTROY was previously defined
+#endif
+#if __has_cpp_attribute(clang::no_destroy)
+#define PROTOBUF_ATTRIBUTE_NO_DESTROY [[clang::no_destroy]]
+#else
+#define PROTOBUF_ATTRIBUTE_NO_DESTROY
+#endif
+
+// Protobuf extensions and reflection require registration of the protos linked
+// in the binary. Not until everything is registered does the runtime have a
+// complete view on all protos. When code is using reflection or extensions
+// in between registration calls this can lead to surprising behavior. By
+// having the registration run first we mitigate this scenario.
+// Highest priority is 101. We use 102 to allow code that really wants to
+// higher priority to still beat us.
+#ifdef PROTOBUF_ATTRIBUTE_INIT_PRIORITY
+#error PROTOBUF_ATTRIBUTE_INIT_PRIORITY was previously defined
+#endif
+#if PROTOBUF_GNUC_MIN(3, 0) && (!defined(__APPLE__) || defined(__clang__)) && !((defined(sun) || defined(__sun)) && (defined(__SVR4) || defined(__svr4__)))
+#define PROTOBUF_ATTRIBUTE_INIT_PRIORITY __attribute__((init_priority((102))))
+#else
+#define PROTOBUF_ATTRIBUTE_INIT_PRIORITY
+#endif
+
+#ifdef PROTOBUF_PRAGMA_INIT_SEG
+#error PROTOBUF_PRAGMA_INIT_SEG was previously defined
+#endif
+#if _MSC_VER
+#define PROTOBUF_PRAGMA_INIT_SEG __pragma(init_seg(lib))
+#else
+#define PROTOBUF_PRAGMA_INIT_SEG
+#endif
+
+#ifdef PROTOBUF_ATTRIBUTE_WEAK
+#error PROTOBUF_ATTRIBUTE_WEAK was previously defined
+#endif
+#if __has_attribute(weak) && \
+ !defined(__APPLE__) && \
+ (!defined(_WIN32) || __clang_major__ < 9) && \
+ !defined(__MINGW32__)
+#define PROTOBUF_ATTRIBUTE_WEAK __attribute__((weak))
+#define PROTOBUF_HAVE_ATTRIBUTE_WEAK 1
+#else
+#define PROTOBUF_ATTRIBUTE_WEAK
+#define PROTOBUF_HAVE_ATTRIBUTE_WEAK 0
+#endif
+
+// Macros to detect sanitizers.
+#ifdef PROTOBUF_ASAN
+#error PROTOBUF_ASAN was previously defined
+#endif
+#ifdef PROTOBUF_MSAN
+#error PROTOBUF_MSAN was previously defined
+#endif
+#ifdef PROTOBUF_TSAN
+#error PROTOBUF_TSAN was previously defined
+#endif
+#if defined(__clang__)
+# if __has_feature(address_sanitizer)
+# define PROTOBUF_ASAN 1
+# endif
+# if __has_feature(thread_sanitizer)
+# define PROTOBUF_TSAN 1
+# endif
+# if __has_feature(memory_sanitizer)
+# define PROTOBUF_MSAN 1
+# endif
+#elif PROTOBUF_GNUC_MIN(3, 0)
+// Double-guard is needed for -Wundef:
+# ifdef __SANITIZE_ADDRESS__
+# if __SANITIZE_ADDRESS__
+# define PROTOBUF_ASAN 1
+# endif
+# endif
+# ifdef __SANITIZE_THREAD__
+# if __SANITIZE_THREAD__
+# define PROTOBUF_TSAN 1
+# endif
+# endif
+#endif
+
+// Tail call table-driven parsing can be enabled by defining
+// PROTOBUF_EXPERIMENTAL_USE_TAIL_CALL_TABLE_PARSER at compilation time. Note
+// that this macro is for small-scale testing only, and is not supported.
+#ifdef PROTOBUF_TAIL_CALL_TABLE_PARSER_ENABLED
+#error PROTOBUF_TAIL_CALL_TABLE_PARSER_ENABLED was previously declared
+#endif
+#if defined(PROTOBUF_EXPERIMENTAL_USE_TAIL_CALL_TABLE_PARSER)
+#define PROTOBUF_TAIL_CALL_TABLE_PARSER_ENABLED 1
+// Selectively use static member functions instead of templates:
+#ifndef PROTOBUF_TC_STATIC_PARSE_SINGULAR1
+# define PROTOBUF_TC_STATIC_PARSE_SINGULAR1 1
+#endif
+#ifndef PROTOBUF_TC_STATIC_PARSE_SINGULAR2
+# define PROTOBUF_TC_STATIC_PARSE_SINGULAR2 0
+#endif
+#ifndef PROTOBUF_TC_STATIC_PARSE_REPEATED1
+# define PROTOBUF_TC_STATIC_PARSE_REPEATED1 0
+#endif
+#ifndef PROTOBUF_TC_STATIC_PARSE_REPEATED2
+# define PROTOBUF_TC_STATIC_PARSE_REPEATED2 0
+#endif
+#endif
+
+#define PROTOBUF_TC_PARAM_DECL \
+ ::google::protobuf::MessageLite *msg, const char *ptr, \
+ ::google::protobuf::internal::ParseContext *ctx, \
+ const ::google::protobuf::internal::TcParseTableBase *table, \
+ 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
+
+// Windows declares several inconvenient macro names. We #undef them and then
+// restore them in port_undef.inc.
+#ifdef _MSC_VER
+#pragma push_macro("CREATE_NEW")
+#undef CREATE_NEW
+#pragma push_macro("DELETE")
+#undef DELETE
+#pragma push_macro("DOUBLE_CLICK")
+#undef DOUBLE_CLICK
+#pragma push_macro("ERROR")
+#undef ERROR
+#pragma push_macro("ERROR_BUSY")
+#undef ERROR_BUSY
+#pragma push_macro("ERROR_INSTALL_FAILED")
+#undef ERROR_INSTALL_FAILED
+#pragma push_macro("ERROR_NOT_FOUND")
+#undef ERROR_NOT_FOUND
+#pragma push_macro("GetMessage")
+#undef GetMessage
+#pragma push_macro("IGNORE")
+#undef IGNORE
+#pragma push_macro("IN")
+#undef IN
+#pragma push_macro("INPUT_KEYBOARD")
+#undef INPUT_KEYBOARD
+#pragma push_macro("NO_ERROR")
+#undef NO_ERROR
+#pragma push_macro("OUT")
+#undef OUT
+#pragma push_macro("OPTIONAL")
+#undef OPTIONAL
+#pragma push_macro("min")
+#undef min
+#pragma push_macro("max")
+#undef max
+#pragma push_macro("NEAR")
+#undef NEAR
+#pragma push_macro("NO_DATA")
+#undef NO_DATA
+#pragma push_macro("REASON_UNKNOWN")
+#undef REASON_UNKNOWN
+#pragma push_macro("SERVICE_DISABLED")
+#undef SERVICE_DISABLED
+#pragma push_macro("SEVERITY_ERROR")
+#undef SEVERITY_ERROR
+#pragma push_macro("STRICT")
+#undef STRICT
+#pragma push_macro("timezone")
+#undef timezone
+#endif // _MSC_VER
+
+#if defined(__clang__) || PROTOBUF_GNUC_MIN(3, 0) || defined(_MSC_VER)
+// Don't let Objective-C Macros interfere with proto identifiers with the same
+// name.
+#pragma push_macro("DEBUG")
+#undef DEBUG
+#endif // defined(__clang__) || PROTOBUF_GNUC_MIN(3, 0) || defined(_MSC_VER)
+
+#if defined(__clang__)
+#pragma clang diagnostic push
+// TODO(gerbens) ideally we cleanup the code. But a cursory try shows many
+// violations. So let's ignore for now.
+#pragma clang diagnostic ignored "-Wshorten-64-to-32"
+#elif PROTOBUF_GNUC_MIN(3, 0)
+// GCC does not allow disabling diagnostics within an expression:
+// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60875, so we disable this one
+// globally even though it's only used for PROTOBUF_FIELD_OFFSET.
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Winvalid-offsetof"
+#endif
+
+// Silence some MSVC warnings in all our code.
+#if _MSC_VER
+#pragma warning(push)
+// For non-trivial unions
+#pragma warning(disable : 4582)
+#pragma warning(disable : 4583)
+// For init_seg(lib)
+#pragma warning(disable : 4073)
+// To silence the fact that we will pop this push from another file
+#pragma warning(disable : 5031)
+// Conditional expression is constant
+#pragma warning(disable: 4127)
+// decimal digit terminates octal escape sequence
+#pragma warning(disable: 4125)
+#endif
+
+// We don't want code outside port_def doing complex testing, so
+// remove our portable condition test macros to nudge folks away from
+// using it themselves.
+#ifdef PROTOBUF_has_cpp_attribute_DEFINED_
+# undef __has_cpp_attribute
+# undef PROTOBUF_has_cpp_attribute_DEFINED_
+#endif
+#ifdef PROTOBUF_has_feature_DEFINED_
+# undef __has_feature
+# undef PROTOBUF_has_feature_DEFINED_
+#endif
+#ifdef PROTOBUF_has_warning_DEFINED_
+# undef __has_warning
+# undef PROTOBUF_has_warning_DEFINED_
+#endif
+#ifdef PROTOBUF_has_attribute_DEFINED_
+# undef __has_attribute
+# undef PROTOBUF_has_attribute_DEFINED_
+#endif
+#ifdef PROTOBUF_has_builtin_DEFINED_
+# undef __has_builtin
+# undef PROTOBUF_has_builtin_DEFINED_
+#endif
diff --git a/NorthstarDedicatedTest/include/protobuf/port_undef.inc b/NorthstarDedicatedTest/include/protobuf/port_undef.inc
new file mode 100644
index 00000000..579eb419
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/port_undef.inc
@@ -0,0 +1,145 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// #undefs all macros defined in port_def.inc. See comments in port_def.inc
+// for more info.
+
+#ifndef PROTOBUF_NAMESPACE
+#error "port_undef.inc must be included after port_def.inc"
+#endif
+#undef PROTOBUF_GNUC_MIN
+#undef PROTOBUF_MSC_VER_MIN
+#undef PROTOBUF_CPLUSPLUS_MIN
+#undef PROTOBUF_NAMESPACE
+#undef PROTOBUF_NAMESPACE_ID
+#undef PROTOBUF_ALWAYS_INLINE
+#undef PROTOBUF_NDEBUG_INLINE
+#undef PROTOBUF_MUSTTAIL
+#undef PROTOBUF_TAILCALL
+#undef PROTOBUF_COLD
+#undef PROTOBUF_NOINLINE
+#undef PROTOBUF_SECTION_VARIABLE
+#undef PROTOBUF_DEPRECATED
+#undef PROTOBUF_DEPRECATED_ENUM
+#undef PROTOBUF_DEPRECATED_MSG
+#undef PROTOBUF_FUNC_ALIGN
+#undef PROTOBUF_RETURNS_NONNULL
+#undef PROTOBUF_ATTRIBUTE_REINITIALIZES
+#undef PROTOBUF_RTTI
+#undef PROTOBUF_VERSION
+#undef PROTOBUF_VERSION_SUFFIX
+#undef PROTOBUF_FIELD_OFFSET
+#undef PROTOBUF_MIN_HEADER_VERSION_FOR_PROTOC
+#undef PROTOBUF_MIN_PROTOC_VERSION
+#undef PROTOBUF_PREDICT_TRUE
+#undef PROTOBUF_PREDICT_FALSE
+#undef PROTOBUF_FALLTHROUGH_INTENDED
+#undef PROTOBUF_EXPORT
+#undef PROTOC_EXPORT
+#undef PROTOBUF_NODISCARD
+#undef PROTOBUF_FORCE_COPY_IN_RELEASE
+#undef PROTOBUF_FORCE_COPY_IN_SWAP
+#undef PROTOBUF_FORCE_COPY_IN_MOVE
+#undef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+#undef PROTOBUF_NAMESPACE_OPEN
+#undef PROTOBUF_NAMESPACE_CLOSE
+#undef PROTOBUF_UNUSED
+#undef PROTOBUF_ASSUME
+#undef PROTOBUF_EXPORT_TEMPLATE_DECLARE
+#undef PROTOBUF_EXPORT_TEMPLATE_DEFINE
+#undef PROTOBUF_ALIGNAS
+#undef PROTOBUF_FINAL
+#undef PROTOBUF_THREAD_LOCAL
+#undef PROTOBUF_MESSAGE_OWNED_ARENA_EXPERIMENT
+#undef PROTOBUF_CONSTINIT
+#undef PROTOBUF_ATTRIBUTE_WEAK
+#undef PROTOBUF_HAVE_ATTRIBUTE_WEAK
+#undef PROTOBUF_ATTRIBUTE_NO_DESTROY
+#undef PROTOBUF_ATTRIBUTE_INIT_PRIORITY
+#undef PROTOBUF_PRAGMA_INIT_SEG
+#undef PROTOBUF_ASAN
+#undef PROTOBUF_MSAN
+#undef PROTOBUF_TSAN
+#undef PROTOBUF_TAIL_CALL_TABLE_PARSER_ENABLED
+#undef PROTOBUF_TC_STATIC_PARSE_SINGULAR1
+#undef PROTOBUF_TC_STATIC_PARSE_SINGULAR2
+#undef PROTOBUF_TC_STATIC_PARSE_REPEATED1
+#undef PROTOBUF_TC_STATIC_PARSE_REPEATED2
+#undef PROTOBUF_TC_PARAM_DECL
+#undef PROTOBUF_EXCLUSIVE_LOCKS_REQUIRED
+#undef PROTOBUF_LOCKS_EXCLUDED
+#undef PROTOBUF_NO_THREAD_SAFETY_ANALYSIS
+#undef PROTOBUF_GUARDED_BY
+
+#ifdef PROTOBUF_FUTURE_BREAKING_CHANGES
+#undef PROTOBUF_FUTURE_BREAKING_CHANGES
+#endif
+
+// Restore macro that may have been #undef'd in port_def.inc.
+#ifdef _MSC_VER
+#pragma pop_macro("CREATE_NEW")
+#pragma pop_macro("DELETE")
+#pragma pop_macro("DOUBLE_CLICK")
+#pragma pop_macro("ERROR")
+#pragma pop_macro("ERROR_BUSY")
+#pragma pop_macro("ERROR_INSTALL_FAILED")
+#pragma pop_macro("ERROR_NOT_FOUND")
+#pragma pop_macro("GetMessage")
+#pragma pop_macro("IGNORE")
+#pragma pop_macro("IN")
+#pragma pop_macro("INPUT_KEYBOARD")
+#pragma pop_macro("OUT")
+#pragma pop_macro("OPTIONAL")
+#pragma pop_macro("min")
+#pragma pop_macro("max")
+#pragma pop_macro("NEAR")
+#pragma pop_macro("NO_DATA")
+#pragma pop_macro("NO_ERROR")
+#pragma pop_macro("REASON_UNKNOWN")
+#pragma pop_macro("SERVICE_DISABLED")
+#pragma pop_macro("SEVERITY_ERROR")
+#pragma pop_macro("STRICT")
+#pragma pop_macro("timezone")
+#endif
+
+#if defined(__clang__) || defined(__GNUC__) || defined(_MSC_VER)
+#pragma pop_macro("DEBUG")
+#endif // defined(__clang__) || defined(__GNUC__) || defined(_MSC_VER)
+
+#if defined(__clang__)
+#pragma clang diagnostic pop
+#elif defined(__GNUC__)
+#pragma GCC diagnostic pop
+#endif
+
+// Pop the warning(push) from port_def.inc
+#if _MSC_VER
+#pragma warning(pop)
+#endif
diff --git a/NorthstarDedicatedTest/include/protobuf/preserve_unknown_enum_test.cc b/NorthstarDedicatedTest/include/protobuf/preserve_unknown_enum_test.cc
new file mode 100644
index 00000000..de26344d
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/preserve_unknown_enum_test.cc
@@ -0,0 +1,290 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 <unittest.pb.h>
+#include <unittest_preserve_unknown_enum.pb.h>
+#include <unittest_preserve_unknown_enum2.pb.h>
+#include <descriptor.h>
+#include <dynamic_message.h>
+#include <gtest/gtest.h>
+
+namespace google {
+namespace protobuf {
+namespace {
+
+void FillMessage(
+ proto3_preserve_unknown_enum_unittest::MyMessagePlusExtra* message) {
+ message->set_e(proto3_preserve_unknown_enum_unittest::E_EXTRA);
+ message->add_repeated_e(proto3_preserve_unknown_enum_unittest::E_EXTRA);
+ message->add_repeated_packed_e(
+ proto3_preserve_unknown_enum_unittest::E_EXTRA);
+ message->add_repeated_packed_unexpected_e(
+ proto3_preserve_unknown_enum_unittest::E_EXTRA);
+ message->set_oneof_e_1(proto3_preserve_unknown_enum_unittest::E_EXTRA);
+}
+
+void CheckMessage(
+ const proto3_preserve_unknown_enum_unittest::MyMessagePlusExtra& message) {
+ EXPECT_EQ(proto3_preserve_unknown_enum_unittest::E_EXTRA, message.e());
+ EXPECT_EQ(1, message.repeated_e_size());
+ EXPECT_EQ(proto3_preserve_unknown_enum_unittest::E_EXTRA,
+ message.repeated_e(0));
+ EXPECT_EQ(1, message.repeated_packed_e_size());
+ EXPECT_EQ(proto3_preserve_unknown_enum_unittest::E_EXTRA,
+ message.repeated_packed_e(0));
+ EXPECT_EQ(1, message.repeated_packed_unexpected_e_size());
+ EXPECT_EQ(proto3_preserve_unknown_enum_unittest::E_EXTRA,
+ message.repeated_packed_unexpected_e(0));
+ EXPECT_EQ(proto3_preserve_unknown_enum_unittest::E_EXTRA,
+ message.oneof_e_1());
+}
+
+void CheckMessage(
+ const proto3_preserve_unknown_enum_unittest::MyMessage& message) {
+ EXPECT_EQ(static_cast<int>(proto3_preserve_unknown_enum_unittest::E_EXTRA),
+ static_cast<int>(message.e()));
+ EXPECT_EQ(1, message.repeated_e_size());
+ EXPECT_EQ(static_cast<int>(proto3_preserve_unknown_enum_unittest::E_EXTRA),
+ static_cast<int>(message.repeated_e(0)));
+ EXPECT_EQ(1, message.repeated_packed_e_size());
+ EXPECT_EQ(static_cast<int>(proto3_preserve_unknown_enum_unittest::E_EXTRA),
+ static_cast<int>(message.repeated_packed_e(0)));
+ EXPECT_EQ(1, message.repeated_packed_unexpected_e_size());
+ EXPECT_EQ(static_cast<int>(proto3_preserve_unknown_enum_unittest::E_EXTRA),
+ static_cast<int>(message.repeated_packed_unexpected_e(0)));
+ EXPECT_EQ(static_cast<int>(proto3_preserve_unknown_enum_unittest::E_EXTRA),
+ static_cast<int>(message.oneof_e_1()));
+}
+
+} // anonymous namespace
+
+// Test that parsing preserves an unknown value in the enum field and does not
+// punt it to the UnknownFieldSet.
+TEST(PreserveUnknownEnumTest, PreserveParseAndSerialize) {
+ proto3_preserve_unknown_enum_unittest::MyMessagePlusExtra orig_message;
+ FillMessage(&orig_message);
+ std::string serialized;
+ orig_message.SerializeToString(&serialized);
+
+ proto3_preserve_unknown_enum_unittest::MyMessage message;
+ EXPECT_EQ(true, message.ParseFromString(serialized));
+ CheckMessage(message);
+
+ serialized.clear();
+ message.SerializeToString(&serialized);
+ EXPECT_EQ(true, orig_message.ParseFromString(serialized));
+ CheckMessage(orig_message);
+}
+
+// Test that reflection based implementation also keeps unknown enum values and
+// doesn't put them into UnknownFieldSet.
+TEST(PreserveUnknownEnumTest, PreserveParseAndSerializeDynamicMessage) {
+ proto3_preserve_unknown_enum_unittest::MyMessagePlusExtra orig_message;
+ FillMessage(&orig_message);
+ std::string serialized = orig_message.SerializeAsString();
+
+ DynamicMessageFactory factory;
+ std::unique_ptr<Message> message(
+ factory
+ .GetPrototype(
+ proto3_preserve_unknown_enum_unittest::MyMessage::descriptor())
+ ->New());
+ EXPECT_EQ(true, message->ParseFromString(serialized));
+ message->DiscardUnknownFields();
+
+ serialized = message->SerializeAsString();
+ EXPECT_EQ(true, orig_message.ParseFromString(serialized));
+ CheckMessage(orig_message);
+}
+
+// Test that for proto2 messages, unknown values are in unknown fields.
+TEST(PreserveUnknownEnumTest, Proto2HidesUnknownValues) {
+ proto3_preserve_unknown_enum_unittest::MyMessagePlusExtra orig_message;
+ FillMessage(&orig_message);
+
+ std::string serialized;
+ orig_message.SerializeToString(&serialized);
+
+ proto2_preserve_unknown_enum_unittest::MyMessage message;
+ EXPECT_EQ(true, message.ParseFromString(serialized));
+ // The intermediate message has everything in its "unknown fields".
+ proto2_preserve_unknown_enum_unittest::MyMessage message2 = message;
+ message2.DiscardUnknownFields();
+ EXPECT_EQ(0, message2.ByteSizeLong());
+
+ // But when we pass it to the correct structure, all values are there.
+ serialized.clear();
+ message.SerializeToString(&serialized);
+ EXPECT_EQ(true, orig_message.ParseFromString(serialized));
+ CheckMessage(orig_message);
+}
+
+// Same as before, for a dynamic message.
+TEST(PreserveUnknownEnumTest, DynamicProto2HidesUnknownValues) {
+ proto3_preserve_unknown_enum_unittest::MyMessagePlusExtra orig_message;
+ FillMessage(&orig_message);
+
+ std::string serialized;
+ orig_message.SerializeToString(&serialized);
+
+ DynamicMessageFactory factory;
+ std::unique_ptr<Message> message(
+ factory
+ .GetPrototype(
+ proto2_preserve_unknown_enum_unittest::MyMessage::descriptor())
+ ->New());
+ EXPECT_EQ(true, message->ParseFromString(serialized));
+ // The intermediate message has everything in its "unknown fields".
+ proto2_preserve_unknown_enum_unittest::MyMessage message2;
+ message2.CopyFrom(*message);
+ message2.DiscardUnknownFields();
+ EXPECT_EQ(0, message2.ByteSizeLong());
+
+ // But when we pass it to the correct structure, all values are there.
+ serialized.clear();
+ message->SerializeToString(&serialized);
+ EXPECT_EQ(true, orig_message.ParseFromString(serialized));
+ CheckMessage(orig_message);
+}
+
+// Test that reflection provides EnumValueDescriptors for unknown values.
+TEST(PreserveUnknownEnumTest, DynamicEnumValueDescriptors) {
+ proto3_preserve_unknown_enum_unittest::MyMessagePlusExtra orig_message;
+ FillMessage(&orig_message);
+ std::string serialized;
+ orig_message.SerializeToString(&serialized);
+
+ proto3_preserve_unknown_enum_unittest::MyMessage message;
+ EXPECT_EQ(true, message.ParseFromString(serialized));
+ CheckMessage(message);
+
+ const Reflection* r = message.GetReflection();
+ const Descriptor* d = message.GetDescriptor();
+ const FieldDescriptor* field = d->FindFieldByName("e");
+
+ // This should dynamically create an EnumValueDescriptor.
+ const EnumValueDescriptor* enum_value = r->GetEnum(message, field);
+ EXPECT_EQ(enum_value->number(),
+ static_cast<int>(proto3_preserve_unknown_enum_unittest::E_EXTRA));
+
+ // Fetching value for a second time should return the same pointer.
+ const EnumValueDescriptor* enum_value_second = r->GetEnum(message, field);
+ EXPECT_EQ(enum_value, enum_value_second);
+
+ // Check the repeated case too.
+ const FieldDescriptor* repeated_field = d->FindFieldByName("repeated_e");
+ enum_value = r->GetRepeatedEnum(message, repeated_field, 0);
+ EXPECT_EQ(enum_value->number(),
+ static_cast<int>(proto3_preserve_unknown_enum_unittest::E_EXTRA));
+ // Should reuse the same EnumValueDescriptor, even for a different field.
+ EXPECT_EQ(enum_value, enum_value_second);
+
+ // We should be able to use the returned value descriptor to set a value on
+ // another message.
+ Message* m = message.New();
+ r->SetEnum(m, field, enum_value);
+ EXPECT_EQ(enum_value, r->GetEnum(*m, field));
+ delete m;
+}
+
+// Test that the new integer-based enum reflection API works.
+TEST(PreserveUnknownEnumTest, IntegerEnumReflectionAPI) {
+ proto3_preserve_unknown_enum_unittest::MyMessage message;
+ const Reflection* r = message.GetReflection();
+ const Descriptor* d = message.GetDescriptor();
+
+ const FieldDescriptor* singular_field = d->FindFieldByName("e");
+ const FieldDescriptor* repeated_field = d->FindFieldByName("repeated_e");
+
+ r->SetEnumValue(&message, singular_field, 42);
+ EXPECT_EQ(42, r->GetEnumValue(message, singular_field));
+ r->AddEnumValue(&message, repeated_field, 42);
+ r->AddEnumValue(&message, repeated_field, 42);
+ EXPECT_EQ(42, r->GetRepeatedEnumValue(message, repeated_field, 0));
+ r->SetRepeatedEnumValue(&message, repeated_field, 1, 84);
+ EXPECT_EQ(84, r->GetRepeatedEnumValue(message, repeated_field, 1));
+ const EnumValueDescriptor* enum_value = r->GetEnum(message, singular_field);
+ EXPECT_EQ(42, enum_value->number());
+}
+
+// Test that the EnumValue API works properly for proto2 messages as well.
+TEST(PreserveUnknownEnumTest, Proto2CatchesUnknownValues) {
+ protobuf_unittest::TestAllTypes message; // proto2 message
+ const Reflection* r = message.GetReflection();
+ const Descriptor* d = message.GetDescriptor();
+ const FieldDescriptor* repeated_field =
+ d->FindFieldByName("repeated_nested_enum");
+ // Add one element to the repeated field so that we can test
+ // SetRepeatedEnumValue.
+ const EnumValueDescriptor* enum_value =
+ repeated_field->enum_type()->FindValueByName("BAR");
+ EXPECT_TRUE(enum_value != nullptr);
+ r->AddEnum(&message, repeated_field, enum_value);
+
+ const FieldDescriptor* singular_field =
+ d->FindFieldByName("optional_nested_enum");
+ // Enum-field integer-based setters treat as unknown integer values as
+ // unknown fields.
+ r->SetEnumValue(&message, singular_field, 4242);
+ EXPECT_EQ(r->GetEnum(message, singular_field)->number(),
+ protobuf_unittest::TestAllTypes::FOO);
+ r->SetRepeatedEnumValue(&message, repeated_field, 0, 4242);
+ // repeated_nested_enum was set to bar above, this should not have changed.
+ EXPECT_EQ(r->GetRepeatedEnum(message, repeated_field, 0)->number(),
+ protobuf_unittest::TestAllTypes::BAR);
+ r->AddEnumValue(&message, repeated_field, 4242);
+ // No element should be added
+ EXPECT_EQ(message.repeated_nested_enum_size(), 1);
+
+ // We require the enums to end up in unknown field set
+ ASSERT_EQ(message.unknown_fields().field_count(), 3);
+ EXPECT_EQ(message.unknown_fields().field(0).number(),
+ singular_field->number());
+ EXPECT_EQ(message.unknown_fields().field(0).varint(), 4242);
+ EXPECT_EQ(message.unknown_fields().field(1).number(),
+ repeated_field->number());
+ EXPECT_EQ(message.unknown_fields().field(1).varint(), 4242);
+ EXPECT_EQ(message.unknown_fields().field(2).number(),
+ repeated_field->number());
+ EXPECT_EQ(message.unknown_fields().field(2).varint(), 4242);
+}
+
+TEST(PreserveUnknownEnumTest, SupportsUnknownEnumValuesAPI) {
+ protobuf_unittest::TestAllTypes proto2_message;
+ proto3_preserve_unknown_enum_unittest::MyMessage new_message;
+
+ const Reflection* proto2_reflection = proto2_message.GetReflection();
+ const Reflection* new_reflection = new_message.GetReflection();
+
+ EXPECT_FALSE(proto2_reflection->SupportsUnknownEnumValues());
+ EXPECT_TRUE(new_reflection->SupportsUnknownEnumValues());
+}
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/proto3_arena_lite_unittest.cc b/NorthstarDedicatedTest/include/protobuf/proto3_arena_lite_unittest.cc
new file mode 100644
index 00000000..1d8f0c52
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/proto3_arena_lite_unittest.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.
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include <unittest_proto3_arena.pb.h>
+#include <arena.h>
+#include <testing/googletest.h>
+#include <gtest/gtest.h>
+
+using proto3_arena_unittest::TestAllTypes;
+
+namespace google {
+namespace protobuf {
+namespace {
+// We selectively set/check a few representative fields rather than all fields
+// as this test is only expected to cover the basics of arena support.
+void SetAllFields(TestAllTypes* m) {
+ m->set_optional_int32(100);
+ m->set_optional_string("asdf");
+ m->set_optional_bytes("jkl;");
+ m->mutable_optional_nested_message()->set_bb(42);
+ m->mutable_optional_foreign_message()->set_c(43);
+ m->set_optional_nested_enum(proto3_arena_unittest::TestAllTypes::BAZ);
+ m->set_optional_foreign_enum(proto3_arena_unittest::FOREIGN_BAZ);
+ m->mutable_optional_lazy_message()->set_bb(45);
+ m->add_repeated_int32(100);
+ m->add_repeated_string("asdf");
+ m->add_repeated_bytes("jkl;");
+ m->add_repeated_nested_message()->set_bb(46);
+ m->add_repeated_foreign_message()->set_c(47);
+ m->add_repeated_nested_enum(proto3_arena_unittest::TestAllTypes::BAZ);
+ m->add_repeated_foreign_enum(proto3_arena_unittest::FOREIGN_BAZ);
+ m->add_repeated_lazy_message()->set_bb(49);
+
+ m->set_oneof_uint32(1);
+ m->mutable_oneof_nested_message()->set_bb(50);
+ m->set_oneof_string("test"); // only this one remains set
+}
+
+void ExpectAllFieldsSet(const TestAllTypes& m) {
+ EXPECT_EQ(100, m.optional_int32());
+ EXPECT_EQ("asdf", m.optional_string());
+ EXPECT_EQ("jkl;", m.optional_bytes());
+ EXPECT_EQ(true, m.has_optional_nested_message());
+ EXPECT_EQ(42, m.optional_nested_message().bb());
+ EXPECT_EQ(true, m.has_optional_foreign_message());
+ EXPECT_EQ(43, m.optional_foreign_message().c());
+ EXPECT_EQ(proto3_arena_unittest::TestAllTypes::BAZ, m.optional_nested_enum());
+ EXPECT_EQ(proto3_arena_unittest::FOREIGN_BAZ, m.optional_foreign_enum());
+ EXPECT_EQ(true, m.has_optional_lazy_message());
+ EXPECT_EQ(45, m.optional_lazy_message().bb());
+
+ EXPECT_EQ(1, m.repeated_int32_size());
+ EXPECT_EQ(100, m.repeated_int32(0));
+ EXPECT_EQ(1, m.repeated_string_size());
+ EXPECT_EQ("asdf", m.repeated_string(0));
+ EXPECT_EQ(1, m.repeated_bytes_size());
+ EXPECT_EQ("jkl;", m.repeated_bytes(0));
+ EXPECT_EQ(1, m.repeated_nested_message_size());
+ EXPECT_EQ(46, m.repeated_nested_message(0).bb());
+ EXPECT_EQ(1, m.repeated_foreign_message_size());
+ EXPECT_EQ(47, m.repeated_foreign_message(0).c());
+ EXPECT_EQ(1, m.repeated_nested_enum_size());
+ EXPECT_EQ(proto3_arena_unittest::TestAllTypes::BAZ,
+ m.repeated_nested_enum(0));
+ EXPECT_EQ(1, m.repeated_foreign_enum_size());
+ EXPECT_EQ(proto3_arena_unittest::FOREIGN_BAZ, m.repeated_foreign_enum(0));
+ EXPECT_EQ(1, m.repeated_lazy_message_size());
+ EXPECT_EQ(49, m.repeated_lazy_message(0).bb());
+
+ EXPECT_EQ(proto3_arena_unittest::TestAllTypes::kOneofString,
+ m.oneof_field_case());
+ EXPECT_EQ("test", m.oneof_string());
+}
+
+// In this file we only test some basic functionalities of arena support in
+// proto3 and expect the arena support to be fully tested in proto2 unittests
+// because proto3 shares most code with proto2.
+
+TEST(Proto3ArenaLiteTest, Parsing) {
+ TestAllTypes original;
+ SetAllFields(&original);
+
+ Arena arena;
+ TestAllTypes* arena_message = Arena::CreateMessage<TestAllTypes>(&arena);
+ arena_message->ParseFromString(original.SerializeAsString());
+ ExpectAllFieldsSet(*arena_message);
+}
+
+TEST(Proto3ArenaLiteTest, Swap) {
+ Arena arena1;
+ Arena arena2;
+
+ // Test Swap().
+ TestAllTypes* arena1_message = Arena::CreateMessage<TestAllTypes>(&arena1);
+ TestAllTypes* arena2_message = Arena::CreateMessage<TestAllTypes>(&arena2);
+ arena1_message->Swap(arena2_message);
+ EXPECT_EQ(&arena1, arena1_message->GetArena());
+ EXPECT_EQ(&arena2, arena2_message->GetArena());
+}
+
+TEST(Proto3ArenaLiteTest, SetAllocatedMessage) {
+ Arena arena;
+ TestAllTypes* arena_message = Arena::CreateMessage<TestAllTypes>(&arena);
+ TestAllTypes::NestedMessage* nested = new TestAllTypes::NestedMessage;
+ nested->set_bb(118);
+ arena_message->set_allocated_optional_nested_message(nested);
+ EXPECT_EQ(118, arena_message->optional_nested_message().bb());
+}
+
+TEST(Proto3ArenaLiteTest, ReleaseMessage) {
+ Arena arena;
+ TestAllTypes* arena_message = Arena::CreateMessage<TestAllTypes>(&arena);
+ arena_message->mutable_optional_nested_message()->set_bb(118);
+ std::unique_ptr<TestAllTypes::NestedMessage> nested(
+ arena_message->release_optional_nested_message());
+ EXPECT_EQ(118, nested->bb());
+}
+
+} // namespace
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/proto3_arena_unittest.cc b/NorthstarDedicatedTest/include/protobuf/proto3_arena_unittest.cc
new file mode 100644
index 00000000..5331a33b
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/proto3_arena_unittest.cc
@@ -0,0 +1,632 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include <test_util.h>
+#include <unittest.pb.h>
+#include <unittest_proto3_arena.pb.h>
+#include <unittest_proto3_optional.pb.h>
+#include <arena.h>
+#include <text_format.h>
+#include <testing/googletest.h>
+#include <gtest/gtest.h>
+#include <stubs/strutil.h>
+
+// Must be included last.
+#include <port_def.inc>
+
+using proto3_arena_unittest::ForeignMessage;
+using proto3_arena_unittest::TestAllTypes;
+
+namespace google {
+namespace protobuf {
+
+namespace internal {
+
+class Proto3ArenaTestHelper {
+ public:
+ template <typename T>
+ static Arena* GetOwningArena(const T& msg) {
+ return msg.GetOwningArena();
+ }
+};
+
+} // namespace internal
+
+namespace {
+// We selectively set/check a few representative fields rather than all fields
+// as this test is only expected to cover the basics of arena support.
+void SetAllFields(TestAllTypes* m) {
+ m->set_optional_int32(100);
+ m->set_optional_string("asdf");
+ m->set_optional_bytes("jkl;");
+ m->mutable_optional_nested_message()->set_bb(42);
+ m->mutable_optional_foreign_message()->set_c(43);
+ m->set_optional_nested_enum(proto3_arena_unittest::TestAllTypes::BAZ);
+ m->set_optional_foreign_enum(proto3_arena_unittest::FOREIGN_BAZ);
+ m->mutable_optional_lazy_message()->set_bb(45);
+ m->add_repeated_int32(100);
+ m->add_repeated_string("asdf");
+ m->add_repeated_bytes("jkl;");
+ m->add_repeated_nested_message()->set_bb(46);
+ m->add_repeated_foreign_message()->set_c(47);
+ m->add_repeated_nested_enum(proto3_arena_unittest::TestAllTypes::BAZ);
+ m->add_repeated_foreign_enum(proto3_arena_unittest::FOREIGN_BAZ);
+ m->add_repeated_lazy_message()->set_bb(49);
+
+ m->set_oneof_uint32(1);
+ m->mutable_oneof_nested_message()->set_bb(50);
+ m->set_oneof_string("test"); // only this one remains set
+}
+
+void ExpectAllFieldsSet(const TestAllTypes& m) {
+ EXPECT_EQ(100, m.optional_int32());
+ EXPECT_EQ("asdf", m.optional_string());
+ EXPECT_EQ("jkl;", m.optional_bytes());
+ EXPECT_EQ(true, m.has_optional_nested_message());
+ EXPECT_EQ(42, m.optional_nested_message().bb());
+ EXPECT_EQ(true, m.has_optional_foreign_message());
+ EXPECT_EQ(43, m.optional_foreign_message().c());
+ EXPECT_EQ(proto3_arena_unittest::TestAllTypes::BAZ, m.optional_nested_enum());
+ EXPECT_EQ(proto3_arena_unittest::FOREIGN_BAZ, m.optional_foreign_enum());
+ EXPECT_EQ(true, m.has_optional_lazy_message());
+ EXPECT_EQ(45, m.optional_lazy_message().bb());
+
+ EXPECT_EQ(1, m.repeated_int32_size());
+ EXPECT_EQ(100, m.repeated_int32(0));
+ EXPECT_EQ(1, m.repeated_string_size());
+ EXPECT_EQ("asdf", m.repeated_string(0));
+ EXPECT_EQ(1, m.repeated_bytes_size());
+ EXPECT_EQ("jkl;", m.repeated_bytes(0));
+ EXPECT_EQ(1, m.repeated_nested_message_size());
+ EXPECT_EQ(46, m.repeated_nested_message(0).bb());
+ EXPECT_EQ(1, m.repeated_foreign_message_size());
+ EXPECT_EQ(47, m.repeated_foreign_message(0).c());
+ EXPECT_EQ(1, m.repeated_nested_enum_size());
+ EXPECT_EQ(proto3_arena_unittest::TestAllTypes::BAZ,
+ m.repeated_nested_enum(0));
+ EXPECT_EQ(1, m.repeated_foreign_enum_size());
+ EXPECT_EQ(proto3_arena_unittest::FOREIGN_BAZ, m.repeated_foreign_enum(0));
+ EXPECT_EQ(1, m.repeated_lazy_message_size());
+ EXPECT_EQ(49, m.repeated_lazy_message(0).bb());
+
+ EXPECT_EQ(proto3_arena_unittest::TestAllTypes::kOneofString,
+ m.oneof_field_case());
+ EXPECT_EQ("test", m.oneof_string());
+}
+
+// In this file we only test some basic functionalities of arena support in
+// proto3 and expect the arena support to be fully tested in proto2 unittests
+// because proto3 shares most code with proto2.
+
+TEST(Proto3ArenaTest, Parsing) {
+ TestAllTypes original;
+ SetAllFields(&original);
+
+ Arena arena;
+ TestAllTypes* arena_message = Arena::CreateMessage<TestAllTypes>(&arena);
+ arena_message->ParseFromString(original.SerializeAsString());
+ ExpectAllFieldsSet(*arena_message);
+}
+
+TEST(Proto3ArenaTest, UnknownFields) {
+ TestAllTypes original;
+ SetAllFields(&original);
+
+ Arena arena;
+ TestAllTypes* arena_message = Arena::CreateMessage<TestAllTypes>(&arena);
+ arena_message->ParseFromString(original.SerializeAsString());
+ ExpectAllFieldsSet(*arena_message);
+
+ // In proto3 we can still get a pointer to the UnknownFieldSet through
+ // reflection API.
+ UnknownFieldSet* unknown_fields =
+ arena_message->GetReflection()->MutableUnknownFields(arena_message);
+ // We can modify this UnknownFieldSet.
+ unknown_fields->AddVarint(1, 2);
+ // And the unknown fields should be changed.
+ ASSERT_NE(original.ByteSizeLong(), arena_message->ByteSizeLong());
+ ASSERT_FALSE(
+ arena_message->GetReflection()->GetUnknownFields(*arena_message).empty());
+}
+
+TEST(Proto3ArenaTest, GetArena) {
+ Arena arena;
+
+ // Tests arena-allocated message and submessages.
+ auto* arena_message1 = Arena::CreateMessage<TestAllTypes>(&arena);
+ auto* arena_submessage1 = arena_message1->mutable_optional_foreign_message();
+ auto* arena_repeated_submessage1 =
+ arena_message1->add_repeated_foreign_message();
+ EXPECT_EQ(&arena, arena_message1->GetArena());
+ EXPECT_EQ(&arena, arena_submessage1->GetArena());
+ EXPECT_EQ(&arena, arena_repeated_submessage1->GetArena());
+
+ // Tests attached heap-allocated messages.
+ auto* arena_message2 = Arena::CreateMessage<TestAllTypes>(&arena);
+ arena_message2->set_allocated_optional_foreign_message(new ForeignMessage());
+ arena_message2->mutable_repeated_foreign_message()->AddAllocated(
+ new ForeignMessage());
+ const auto& submessage2 = arena_message2->optional_foreign_message();
+ const auto& repeated_submessage2 =
+ arena_message2->repeated_foreign_message(0);
+ EXPECT_EQ(nullptr, submessage2.GetArena());
+ EXPECT_EQ(nullptr, repeated_submessage2.GetArena());
+
+ // Tests message created by Arena::Create.
+ auto* arena_message3 = Arena::Create<TestAllTypes>(&arena);
+ EXPECT_EQ(nullptr, arena_message3->GetArena());
+}
+
+TEST(Proto3ArenaTest, GetArenaWithUnknown) {
+ Arena arena;
+
+ // Tests arena-allocated message and submessages.
+ auto* arena_message1 = Arena::CreateMessage<TestAllTypes>(&arena);
+ arena_message1->GetReflection()->MutableUnknownFields(arena_message1);
+ auto* arena_submessage1 = arena_message1->mutable_optional_foreign_message();
+ arena_submessage1->GetReflection()->MutableUnknownFields(arena_submessage1);
+ auto* arena_repeated_submessage1 =
+ arena_message1->add_repeated_foreign_message();
+ arena_repeated_submessage1->GetReflection()->MutableUnknownFields(
+ arena_repeated_submessage1);
+ EXPECT_EQ(&arena, arena_message1->GetArena());
+ EXPECT_EQ(&arena, arena_submessage1->GetArena());
+ EXPECT_EQ(&arena, arena_repeated_submessage1->GetArena());
+
+ // Tests attached heap-allocated messages.
+ auto* arena_message2 = Arena::CreateMessage<TestAllTypes>(&arena);
+ arena_message2->set_allocated_optional_foreign_message(new ForeignMessage());
+ arena_message2->mutable_repeated_foreign_message()->AddAllocated(
+ new ForeignMessage());
+ auto* submessage2 = arena_message2->mutable_optional_foreign_message();
+ submessage2->GetReflection()->MutableUnknownFields(submessage2);
+ auto* repeated_submessage2 =
+ arena_message2->mutable_repeated_foreign_message(0);
+ repeated_submessage2->GetReflection()->MutableUnknownFields(
+ repeated_submessage2);
+ EXPECT_EQ(nullptr, submessage2->GetArena());
+ EXPECT_EQ(nullptr, repeated_submessage2->GetArena());
+}
+
+TEST(Proto3ArenaTest, Swap) {
+ Arena arena1;
+ Arena arena2;
+
+ // Test Swap().
+ TestAllTypes* arena1_message = Arena::CreateMessage<TestAllTypes>(&arena1);
+ TestAllTypes* arena2_message = Arena::CreateMessage<TestAllTypes>(&arena2);
+ arena1_message->Swap(arena2_message);
+ EXPECT_EQ(&arena1, arena1_message->GetArena());
+ EXPECT_EQ(&arena2, arena2_message->GetArena());
+}
+
+TEST(Proto3ArenaTest, SetAllocatedMessage) {
+ Arena arena;
+ TestAllTypes* arena_message = Arena::CreateMessage<TestAllTypes>(&arena);
+ TestAllTypes::NestedMessage* nested = new TestAllTypes::NestedMessage;
+ nested->set_bb(118);
+ arena_message->set_allocated_optional_nested_message(nested);
+ EXPECT_EQ(118, arena_message->optional_nested_message().bb());
+}
+
+TEST(Proto3ArenaTest, ReleaseMessage) {
+ Arena arena;
+ TestAllTypes* arena_message = Arena::CreateMessage<TestAllTypes>(&arena);
+ arena_message->mutable_optional_nested_message()->set_bb(118);
+ std::unique_ptr<TestAllTypes::NestedMessage> nested(
+ arena_message->release_optional_nested_message());
+ EXPECT_EQ(118, nested->bb());
+}
+
+TEST(Proto3ArenaTest, MessageFieldClear) {
+ // GitHub issue #310: https://github.com/protocolbuffers/protobuf/issues/310
+ Arena arena;
+ TestAllTypes* arena_message = Arena::CreateMessage<TestAllTypes>(&arena);
+ arena_message->mutable_optional_nested_message()->set_bb(118);
+ // This should not crash, but prior to the bugfix, it tried to use `operator
+ // delete` the nested message (which is on the arena):
+ arena_message->Clear();
+}
+
+TEST(Proto3ArenaTest, MessageFieldClearViaReflection) {
+ Arena arena;
+ TestAllTypes* message = Arena::CreateMessage<TestAllTypes>(&arena);
+ const Reflection* r = message->GetReflection();
+ const Descriptor* d = message->GetDescriptor();
+ const FieldDescriptor* msg_field =
+ d->FindFieldByName("optional_nested_message");
+
+ message->mutable_optional_nested_message()->set_bb(1);
+ r->ClearField(message, msg_field);
+ EXPECT_FALSE(message->has_optional_nested_message());
+ EXPECT_EQ(0, message->optional_nested_message().bb());
+}
+
+TEST(Proto3OptionalTest, OptionalFields) {
+ protobuf_unittest::TestProto3Optional msg;
+ EXPECT_FALSE(msg.has_optional_int32());
+ msg.set_optional_int32(0);
+ EXPECT_TRUE(msg.has_optional_int32());
+
+ std::string serialized;
+ msg.SerializeToString(&serialized);
+ EXPECT_GT(serialized.size(), 0);
+
+ msg.clear_optional_int32();
+ EXPECT_FALSE(msg.has_optional_int32());
+ msg.SerializeToString(&serialized);
+ EXPECT_EQ(serialized.size(), 0);
+}
+
+TEST(Proto3OptionalTest, OptionalFieldDescriptor) {
+ const Descriptor* d = protobuf_unittest::TestProto3Optional::descriptor();
+
+ for (int i = 0; i < d->field_count(); i++) {
+ const FieldDescriptor* f = d->field(i);
+ if (HasPrefixString(f->name(), "singular")) {
+ EXPECT_FALSE(f->has_optional_keyword()) << f->full_name();
+ EXPECT_FALSE(f->has_presence()) << f->full_name();
+ EXPECT_FALSE(f->containing_oneof()) << f->full_name();
+ } else {
+ EXPECT_TRUE(f->has_optional_keyword()) << f->full_name();
+ EXPECT_TRUE(f->has_presence()) << f->full_name();
+ EXPECT_TRUE(f->containing_oneof()) << f->full_name();
+ }
+ }
+}
+
+TEST(Proto3OptionalTest, Extensions) {
+ const DescriptorPool* p = DescriptorPool::generated_pool();
+ const FieldDescriptor* no_optional = p->FindExtensionByName(
+ "protobuf_unittest.Proto3OptionalExtensions.ext_no_optional");
+ const FieldDescriptor* with_optional = p->FindExtensionByName(
+ "protobuf_unittest.Proto3OptionalExtensions.ext_with_optional");
+ GOOGLE_CHECK(no_optional);
+ GOOGLE_CHECK(with_optional);
+ EXPECT_FALSE(no_optional->has_optional_keyword());
+ EXPECT_TRUE(with_optional->has_optional_keyword());
+
+ const Descriptor* d = protobuf_unittest::Proto3OptionalExtensions::descriptor();
+ EXPECT_TRUE(d->options().HasExtension(
+ protobuf_unittest::Proto3OptionalExtensions::ext_no_optional));
+ EXPECT_TRUE(d->options().HasExtension(
+ protobuf_unittest::Proto3OptionalExtensions::ext_with_optional));
+ EXPECT_EQ(8, d->options().GetExtension(
+ protobuf_unittest::Proto3OptionalExtensions::ext_no_optional));
+ EXPECT_EQ(16,
+ d->options().GetExtension(
+ protobuf_unittest::Proto3OptionalExtensions::ext_with_optional));
+
+ const Descriptor* d2 = protobuf_unittest::TestProto3Optional::descriptor();
+ EXPECT_FALSE(d2->options().HasExtension(
+ protobuf_unittest::Proto3OptionalExtensions::ext_no_optional));
+ EXPECT_FALSE(d2->options().HasExtension(
+ protobuf_unittest::Proto3OptionalExtensions::ext_with_optional));
+}
+
+TEST(Proto3OptionalTest, OptionalField) {
+ protobuf_unittest::TestProto3Optional msg;
+ EXPECT_FALSE(msg.has_optional_int32());
+ msg.set_optional_int32(0);
+ EXPECT_TRUE(msg.has_optional_int32());
+
+ std::string serialized;
+ msg.SerializeToString(&serialized);
+ EXPECT_GT(serialized.size(), 0);
+
+ msg.clear_optional_int32();
+ EXPECT_FALSE(msg.has_optional_int32());
+ msg.SerializeToString(&serialized);
+ EXPECT_EQ(serialized.size(), 0);
+}
+
+TEST(Proto3OptionalTest, OptionalFieldReflection) {
+ // Tests that oneof reflection works on synthetic oneofs.
+ //
+ // We test this more deeply elsewhere by parsing/serializing TextFormat (which
+ // doesn't treat synthetic oneofs specially, so reflects over them normally).
+ protobuf_unittest::TestProto3Optional msg;
+ const google::protobuf::Descriptor* d = msg.GetDescriptor();
+ const google::protobuf::Reflection* r = msg.GetReflection();
+ const google::protobuf::FieldDescriptor* f = d->FindFieldByName("optional_int32");
+ const google::protobuf::OneofDescriptor* o = d->FindOneofByName("_optional_int32");
+ GOOGLE_CHECK(f);
+ GOOGLE_CHECK(o);
+ EXPECT_TRUE(o->is_synthetic());
+
+ EXPECT_FALSE(r->HasField(msg, f));
+ EXPECT_FALSE(r->HasOneof(msg, o));
+ EXPECT_TRUE(r->GetOneofFieldDescriptor(msg, o) == nullptr);
+
+ r->SetInt32(&msg, f, 123);
+ EXPECT_EQ(123, msg.optional_int32());
+ EXPECT_EQ(123, r->GetInt32(msg, f));
+ EXPECT_TRUE(r->HasField(msg, f));
+ EXPECT_TRUE(r->HasOneof(msg, o));
+ EXPECT_EQ(f, r->GetOneofFieldDescriptor(msg, o));
+
+ std::vector<const FieldDescriptor*> fields;
+ r->ListFields(msg, &fields);
+ EXPECT_EQ(1, fields.size());
+ EXPECT_EQ(f, fields[0]);
+
+ r->ClearOneof(&msg, o);
+ EXPECT_FALSE(r->HasField(msg, f));
+ EXPECT_FALSE(r->HasOneof(msg, o));
+ EXPECT_TRUE(r->GetOneofFieldDescriptor(msg, o) == nullptr);
+
+ msg.set_optional_int32(123);
+ EXPECT_EQ(123, r->GetInt32(msg, f));
+ EXPECT_TRUE(r->HasField(msg, f));
+ EXPECT_TRUE(r->HasOneof(msg, o));
+ EXPECT_EQ(f, r->GetOneofFieldDescriptor(msg, o));
+
+ r->ClearOneof(&msg, o);
+ EXPECT_FALSE(r->HasField(msg, f));
+ EXPECT_FALSE(r->HasOneof(msg, o));
+ EXPECT_TRUE(r->GetOneofFieldDescriptor(msg, o) == nullptr);
+}
+
+// It's a regression test for b/160665543.
+TEST(Proto3OptionalTest, ClearNonOptionalMessageField) {
+ protobuf_unittest::TestProto3OptionalMessage msg;
+ msg.mutable_nested_message();
+ const google::protobuf::Descriptor* d = msg.GetDescriptor();
+ const google::protobuf::Reflection* r = msg.GetReflection();
+ const google::protobuf::FieldDescriptor* f = d->FindFieldByName("nested_message");
+ r->ClearField(&msg, f);
+}
+
+TEST(Proto3OptionalTest, ClearOptionalMessageField) {
+ protobuf_unittest::TestProto3OptionalMessage msg;
+ msg.mutable_optional_nested_message();
+ const google::protobuf::Descriptor* d = msg.GetDescriptor();
+ const google::protobuf::Reflection* r = msg.GetReflection();
+ const google::protobuf::FieldDescriptor* f =
+ d->FindFieldByName("optional_nested_message");
+ r->ClearField(&msg, f);
+}
+
+TEST(Proto3OptionalTest, SwapNonOptionalMessageField) {
+ protobuf_unittest::TestProto3OptionalMessage msg1;
+ protobuf_unittest::TestProto3OptionalMessage msg2;
+ msg1.mutable_nested_message();
+ const google::protobuf::Descriptor* d = msg1.GetDescriptor();
+ const google::protobuf::Reflection* r = msg1.GetReflection();
+ const google::protobuf::FieldDescriptor* f = d->FindFieldByName("nested_message");
+ r->SwapFields(&msg1, &msg2, {f});
+}
+
+TEST(Proto3OptionalTest, SwapOptionalMessageField) {
+ protobuf_unittest::TestProto3OptionalMessage msg1;
+ protobuf_unittest::TestProto3OptionalMessage msg2;
+ msg1.mutable_optional_nested_message();
+ const google::protobuf::Descriptor* d = msg1.GetDescriptor();
+ const google::protobuf::Reflection* r = msg1.GetReflection();
+ const google::protobuf::FieldDescriptor* f =
+ d->FindFieldByName("optional_nested_message");
+ r->SwapFields(&msg1, &msg2, {f});
+}
+
+void SetAllFieldsZero(protobuf_unittest::TestProto3Optional* msg) {
+ msg->set_optional_int32(0);
+ msg->set_optional_int64(0);
+ msg->set_optional_uint32(0);
+ msg->set_optional_uint64(0);
+ msg->set_optional_sint32(0);
+ msg->set_optional_sint64(0);
+ msg->set_optional_fixed32(0);
+ msg->set_optional_fixed64(0);
+ msg->set_optional_sfixed32(0);
+ msg->set_optional_sfixed64(0);
+ msg->set_optional_float(0);
+ msg->set_optional_double(0);
+ msg->set_optional_bool(false);
+ msg->set_optional_string("");
+ msg->set_optional_bytes("");
+ msg->mutable_optional_nested_message();
+ msg->mutable_lazy_nested_message();
+ msg->set_optional_nested_enum(
+ protobuf_unittest::TestProto3Optional::UNSPECIFIED);
+}
+
+void SetAllFieldsNonZero(protobuf_unittest::TestProto3Optional* msg) {
+ msg->set_optional_int32(101);
+ msg->set_optional_int64(102);
+ msg->set_optional_uint32(103);
+ msg->set_optional_uint64(104);
+ msg->set_optional_sint32(105);
+ msg->set_optional_sint64(106);
+ msg->set_optional_fixed32(107);
+ msg->set_optional_fixed64(108);
+ msg->set_optional_sfixed32(109);
+ msg->set_optional_sfixed64(110);
+ msg->set_optional_float(111);
+ msg->set_optional_double(112);
+ msg->set_optional_bool(true);
+ msg->set_optional_string("abc");
+ msg->set_optional_bytes("def");
+ msg->mutable_optional_nested_message();
+ msg->mutable_lazy_nested_message();
+ msg->set_optional_nested_enum(protobuf_unittest::TestProto3Optional::BAZ);
+}
+
+void TestAllFieldsZero(const protobuf_unittest::TestProto3Optional& msg) {
+ EXPECT_EQ(0, msg.optional_int32());
+ EXPECT_EQ(0, msg.optional_int64());
+ EXPECT_EQ(0, msg.optional_uint32());
+ EXPECT_EQ(0, msg.optional_uint64());
+ EXPECT_EQ(0, msg.optional_sint32());
+ EXPECT_EQ(0, msg.optional_sint64());
+ EXPECT_EQ(0, msg.optional_fixed32());
+ EXPECT_EQ(0, msg.optional_fixed64());
+ EXPECT_EQ(0, msg.optional_sfixed32());
+ EXPECT_EQ(0, msg.optional_sfixed64());
+ EXPECT_EQ(0, msg.optional_float());
+ EXPECT_EQ(0, msg.optional_double());
+ EXPECT_EQ(0, msg.optional_bool());
+ EXPECT_EQ("", msg.optional_string());
+ EXPECT_EQ("", msg.optional_bytes());
+ EXPECT_EQ(protobuf_unittest::TestProto3Optional::UNSPECIFIED,
+ msg.optional_nested_enum());
+
+ const Reflection* r = msg.GetReflection();
+ const Descriptor* d = msg.GetDescriptor();
+ EXPECT_EQ("", r->GetString(msg, d->FindFieldByName("optional_string")));
+}
+
+void TestAllFieldsNonZero(const protobuf_unittest::TestProto3Optional& msg) {
+ EXPECT_EQ(101, msg.optional_int32());
+ EXPECT_EQ(102, msg.optional_int64());
+ EXPECT_EQ(103, msg.optional_uint32());
+ EXPECT_EQ(104, msg.optional_uint64());
+ EXPECT_EQ(105, msg.optional_sint32());
+ EXPECT_EQ(106, msg.optional_sint64());
+ EXPECT_EQ(107, msg.optional_fixed32());
+ EXPECT_EQ(108, msg.optional_fixed64());
+ EXPECT_EQ(109, msg.optional_sfixed32());
+ EXPECT_EQ(110, msg.optional_sfixed64());
+ EXPECT_EQ(111, msg.optional_float());
+ EXPECT_EQ(112, msg.optional_double());
+ EXPECT_EQ(true, msg.optional_bool());
+ EXPECT_EQ("abc", msg.optional_string());
+ EXPECT_EQ("def", msg.optional_bytes());
+ EXPECT_EQ(protobuf_unittest::TestProto3Optional::BAZ,
+ msg.optional_nested_enum());
+}
+
+void TestAllFieldsSet(const protobuf_unittest::TestProto3Optional& msg,
+ bool set) {
+ EXPECT_EQ(set, msg.has_optional_int32());
+ EXPECT_EQ(set, msg.has_optional_int64());
+ EXPECT_EQ(set, msg.has_optional_uint32());
+ EXPECT_EQ(set, msg.has_optional_uint64());
+ EXPECT_EQ(set, msg.has_optional_sint32());
+ EXPECT_EQ(set, msg.has_optional_sint64());
+ EXPECT_EQ(set, msg.has_optional_fixed32());
+ EXPECT_EQ(set, msg.has_optional_fixed64());
+ EXPECT_EQ(set, msg.has_optional_sfixed32());
+ EXPECT_EQ(set, msg.has_optional_sfixed64());
+ EXPECT_EQ(set, msg.has_optional_float());
+ EXPECT_EQ(set, msg.has_optional_double());
+ EXPECT_EQ(set, msg.has_optional_bool());
+ EXPECT_EQ(set, msg.has_optional_string());
+ EXPECT_EQ(set, msg.has_optional_bytes());
+ EXPECT_EQ(set, msg.has_optional_nested_message());
+ EXPECT_EQ(set, msg.has_lazy_nested_message());
+ EXPECT_EQ(set, msg.has_optional_nested_enum());
+}
+
+TEST(Proto3OptionalTest, BinaryRoundTrip) {
+ protobuf_unittest::TestProto3Optional msg;
+ TestAllFieldsSet(msg, false);
+ SetAllFieldsZero(&msg);
+ TestAllFieldsZero(msg);
+ TestAllFieldsSet(msg, true);
+
+ protobuf_unittest::TestProto3Optional msg2;
+ std::string serialized;
+ msg.SerializeToString(&serialized);
+ EXPECT_TRUE(msg2.ParseFromString(serialized));
+ TestAllFieldsZero(msg2);
+ TestAllFieldsSet(msg2, true);
+}
+
+TEST(Proto3OptionalTest, TextFormatRoundTripZeros) {
+ protobuf_unittest::TestProto3Optional msg;
+ SetAllFieldsZero(&msg);
+
+ protobuf_unittest::TestProto3Optional msg2;
+ std::string text;
+ EXPECT_TRUE(TextFormat::PrintToString(msg, &text));
+ EXPECT_TRUE(TextFormat::ParseFromString(text, &msg2));
+ TestAllFieldsSet(msg2, true);
+ TestAllFieldsZero(msg2);
+}
+
+TEST(Proto3OptionalTest, TextFormatRoundTripNonZeros) {
+ protobuf_unittest::TestProto3Optional msg;
+ SetAllFieldsNonZero(&msg);
+
+ protobuf_unittest::TestProto3Optional msg2;
+ std::string text;
+ EXPECT_TRUE(TextFormat::PrintToString(msg, &text));
+ EXPECT_TRUE(TextFormat::ParseFromString(text, &msg2));
+ TestAllFieldsSet(msg2, true);
+ TestAllFieldsNonZero(msg2);
+}
+
+TEST(Proto3OptionalTest, SwapRoundTripZero) {
+ protobuf_unittest::TestProto3Optional msg;
+ SetAllFieldsZero(&msg);
+ TestAllFieldsSet(msg, true);
+
+ protobuf_unittest::TestProto3Optional msg2;
+ msg.Swap(&msg2);
+ TestAllFieldsSet(msg2, true);
+ TestAllFieldsZero(msg2);
+}
+
+TEST(Proto3OptionalTest, SwapRoundTripNonZero) {
+ protobuf_unittest::TestProto3Optional msg;
+ SetAllFieldsNonZero(&msg);
+ TestAllFieldsSet(msg, true);
+
+ protobuf_unittest::TestProto3Optional msg2;
+ msg.Swap(&msg2);
+ TestAllFieldsSet(msg2, true);
+ TestAllFieldsNonZero(msg2);
+}
+
+TEST(Proto3OptionalTest, ReflectiveSwapRoundTrip) {
+ protobuf_unittest::TestProto3Optional msg;
+ SetAllFieldsZero(&msg);
+ TestAllFieldsSet(msg, true);
+
+ protobuf_unittest::TestProto3Optional msg2;
+ msg2.GetReflection()->Swap(&msg, &msg2);
+ TestAllFieldsSet(msg2, true);
+ TestAllFieldsZero(msg2);
+}
+
+TEST(Proto3OptionalTest, PlainFields) {
+ const Descriptor* d = TestAllTypes::descriptor();
+
+ EXPECT_FALSE(d->FindFieldByName("optional_int32")->has_presence());
+ EXPECT_TRUE(d->FindFieldByName("oneof_nested_message")->has_presence());
+}
+
+} // namespace
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/proto3_lite_unittest.cc b/NorthstarDedicatedTest/include/protobuf/proto3_lite_unittest.cc
new file mode 100644
index 00000000..a25968b5
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/proto3_lite_unittest.cc
@@ -0,0 +1,43 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <unittest_proto3.pb.h>
+
+#define LITE_TEST_NAME Proto3LiteTest
+#define UNITTEST ::proto3_unittest
+
+// Must include after the above macros.
+#include <proto3_lite_unittest.inc>
+
+// Make extract script happy.
+namespace google {
+namespace protobuf {
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/proto3_lite_unittest.inc b/NorthstarDedicatedTest/include/protobuf/proto3_lite_unittest.inc
new file mode 100644
index 00000000..c00fa9c4
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/proto3_lite_unittest.inc
@@ -0,0 +1,146 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include <arena.h>
+#include <testing/googletest.h>
+#include <gtest/gtest.h>
+
+using UNITTEST::TestAllTypes;
+
+namespace google {
+namespace protobuf {
+namespace {
+// We selectively set/check a few representative fields rather than all fields
+// as this test is only expected to cover the basics of lite support.
+void SetAllFields(TestAllTypes* m) {
+ m->set_optional_int32(100);
+ m->set_optional_string("asdf");
+ m->set_optional_bytes("jkl;");
+ m->mutable_optional_nested_message()->set_bb(42);
+ m->mutable_optional_foreign_message()->set_c(43);
+ m->set_optional_nested_enum(UNITTEST::TestAllTypes::BAZ);
+ m->set_optional_foreign_enum(
+ UNITTEST::FOREIGN_BAZ);
+ m->mutable_optional_lazy_message()->set_bb(45);
+ m->add_repeated_int32(100);
+ m->add_repeated_string("asdf");
+ m->add_repeated_bytes("jkl;");
+ m->add_repeated_nested_message()->set_bb(46);
+ m->add_repeated_foreign_message()->set_c(47);
+ m->add_repeated_nested_enum(UNITTEST::TestAllTypes::BAZ);
+ m->add_repeated_foreign_enum(
+ UNITTEST::FOREIGN_BAZ);
+ m->add_repeated_lazy_message()->set_bb(49);
+
+ m->set_oneof_uint32(1);
+ m->mutable_oneof_nested_message()->set_bb(50);
+ m->set_oneof_string("test"); // only this one remains set
+}
+
+void ExpectAllFieldsSet(const TestAllTypes& m) {
+ EXPECT_EQ(100, m.optional_int32());
+ EXPECT_EQ("asdf", m.optional_string());
+ EXPECT_EQ("jkl;", m.optional_bytes());
+ EXPECT_EQ(true, m.has_optional_nested_message());
+ EXPECT_EQ(42, m.optional_nested_message().bb());
+ EXPECT_EQ(true, m.has_optional_foreign_message());
+ EXPECT_EQ(43, m.optional_foreign_message().c());
+ EXPECT_EQ(UNITTEST::TestAllTypes::BAZ, m.optional_nested_enum());
+ EXPECT_EQ(UNITTEST::FOREIGN_BAZ,
+ m.optional_foreign_enum());
+ EXPECT_EQ(true, m.has_optional_lazy_message());
+ EXPECT_EQ(45, m.optional_lazy_message().bb());
+
+ EXPECT_EQ(1, m.repeated_int32_size());
+ EXPECT_EQ(100, m.repeated_int32(0));
+ EXPECT_EQ(1, m.repeated_string_size());
+ EXPECT_EQ("asdf", m.repeated_string(0));
+ EXPECT_EQ(1, m.repeated_bytes_size());
+ EXPECT_EQ("jkl;", m.repeated_bytes(0));
+ EXPECT_EQ(1, m.repeated_nested_message_size());
+ EXPECT_EQ(46, m.repeated_nested_message(0).bb());
+ EXPECT_EQ(1, m.repeated_foreign_message_size());
+ EXPECT_EQ(47, m.repeated_foreign_message(0).c());
+ EXPECT_EQ(1, m.repeated_nested_enum_size());
+ EXPECT_EQ(UNITTEST::TestAllTypes::BAZ, m.repeated_nested_enum(0));
+ EXPECT_EQ(1, m.repeated_foreign_enum_size());
+ EXPECT_EQ(UNITTEST::FOREIGN_BAZ,
+ m.repeated_foreign_enum(0));
+ EXPECT_EQ(1, m.repeated_lazy_message_size());
+ EXPECT_EQ(49, m.repeated_lazy_message(0).bb());
+
+ EXPECT_EQ(UNITTEST::TestAllTypes::kOneofString,
+ m.oneof_field_case());
+ EXPECT_EQ("test", m.oneof_string());
+}
+
+// In this file we only test some basic functionalities of in proto3 and expect
+// the rest is fully tested in proto2 unittests because proto3 shares most code
+// with proto2.
+
+TEST(LITE_TEST_NAME, Parsing) {
+ TestAllTypes original;
+ SetAllFields(&original);
+
+ TestAllTypes msg;
+ msg.ParseFromString(original.SerializeAsString());
+ ExpectAllFieldsSet(msg);
+}
+
+TEST(LITE_TEST_NAME, Swap) {
+ // Test Swap().
+ TestAllTypes msg1;
+ TestAllTypes msg2;
+ msg1.set_optional_string("123");
+ msg2.set_optional_string("3456");
+ msg1.Swap(&msg2);
+ EXPECT_EQ("3456", msg1.optional_string());
+ EXPECT_EQ("123", msg2.optional_string());
+ EXPECT_EQ(msg1.ByteSize(), msg2.ByteSize() + 1);
+}
+
+TEST(LITE_TEST_NAME, OneofHazzers) {
+ TestAllTypes msg;
+ msg.set_oneof_uint32(1);
+ msg.set_oneof_string("test");
+
+ EXPECT_EQ(true, msg.has_oneof_string());
+ EXPECT_EQ(false, msg.has_oneof_uint32());
+ EXPECT_EQ(false, msg.has_oneof_bytes());
+ EXPECT_EQ(false, msg.has_oneof_nested_message());
+}
+
+} // namespace
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/reflection.h b/NorthstarDedicatedTest/include/protobuf/reflection.h
new file mode 100644
index 00000000..dab721c8
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/reflection.h
@@ -0,0 +1,568 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// This header defines the RepeatedFieldRef class template used to access
+// repeated fields with protobuf reflection API.
+#ifndef GOOGLE_PROTOBUF_REFLECTION_H__
+#define GOOGLE_PROTOBUF_REFLECTION_H__
+
+#include <memory>
+
+#include <message.h>
+#include <generated_enum_util.h>
+
+#ifdef SWIG
+#error "You cannot SWIG proto headers"
+#endif
+
+#include <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 <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_REFLECTION_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/reflection_internal.h b/NorthstarDedicatedTest/include/protobuf/reflection_internal.h
new file mode 100644
index 00000000..b163dfed
--- /dev/null
+++ b/NorthstarDedicatedTest/include/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 <map_field.h>
+#include <reflection.h>
+#include <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/NorthstarDedicatedTest/include/protobuf/reflection_ops.cc b/NorthstarDedicatedTest/include/protobuf/reflection_ops.cc
new file mode 100644
index 00000000..cb6d8f59
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/reflection_ops.cc
@@ -0,0 +1,454 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+#include <reflection_ops.h>
+
+#include <string>
+#include <vector>
+
+#include <stubs/logging.h>
+#include <stubs/common.h>
+#include <descriptor.pb.h>
+#include <descriptor.h>
+#include <map_field.h>
+#include <map_field_inl.h>
+#include <unknown_field_set.h>
+
+#include <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;
+ }
+ }
+ }
+
+ to_reflection->MutableUnknownFields(to)->MergeFrom(
+ from_reflection->GetUnknownFields(from));
+}
+
+void ReflectionOps::Clear(Message* message) {
+ const Reflection* reflection = GetReflectionOrDie(*message);
+
+ std::vector<const FieldDescriptor*> fields;
+ reflection->ListFieldsOmitStripped(*message, &fields);
+ for (const FieldDescriptor* field : fields) {
+ reflection->ClearField(message, field);
+ }
+
+ reflection->MutableUnknownFields(message)->Clear();
+}
+
+bool ReflectionOps::IsInitialized(const Message& message, bool check_fields,
+ bool check_descendants) {
+ const Descriptor* descriptor = message.GetDescriptor();
+ const Reflection* reflection = GetReflectionOrDie(message);
+ if (const int field_count = descriptor->field_count()) {
+ const FieldDescriptor* begin = descriptor->field(0);
+ const FieldDescriptor* end = begin + field_count;
+ GOOGLE_DCHECK_EQ(descriptor->field(field_count - 1), end - 1);
+
+ if (check_fields) {
+ // Check required fields of this message.
+ for (const FieldDescriptor* field = begin; field != end; ++field) {
+ if (field->is_required() && !reflection->HasField(message, field)) {
+ return false;
+ }
+ }
+ }
+
+ if (check_descendants) {
+ for (const FieldDescriptor* field = begin; field != end; ++field) {
+ if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+ const Descriptor* message_type = field->message_type();
+ if (PROTOBUF_PREDICT_FALSE(message_type->options().map_entry())) {
+ if (message_type->field(1)->cpp_type() ==
+ FieldDescriptor::CPPTYPE_MESSAGE) {
+ const MapFieldBase* map_field =
+ reflection->GetMapData(message, field);
+ if (map_field->IsMapValid()) {
+ MapIterator it(const_cast<Message*>(&message), field);
+ MapIterator end_map(const_cast<Message*>(&message), field);
+ for (map_field->MapBegin(&it), map_field->MapEnd(&end_map);
+ it != end_map; ++it) {
+ if (!it.GetValueRef().GetMessageValue().IsInitialized()) {
+ return false;
+ }
+ }
+ }
+ }
+ } else if (field->is_repeated()) {
+ const int size = reflection->FieldSize(message, field);
+ for (int j = 0; j < size; j++) {
+ if (!reflection->GetRepeatedMessage(message, field, j)
+ .IsInitialized()) {
+ return false;
+ }
+ }
+ } else if (reflection->HasField(message, field)) {
+ if (!reflection->GetMessage(message, field).IsInitialized()) {
+ return false;
+ }
+ }
+ }
+ }
+ }
+ }
+ if (check_descendants && reflection->HasExtensionSet(message) &&
+ !reflection->GetExtensionSet(message).IsInitialized()) {
+ return false;
+ }
+ return true;
+}
+
+bool ReflectionOps::IsInitialized(const Message& message) {
+ const Descriptor* descriptor = message.GetDescriptor();
+ const Reflection* reflection = GetReflectionOrDie(message);
+
+ // Check required fields of this message.
+ {
+ const int field_count = descriptor->field_count();
+ for (int i = 0; i < field_count; i++) {
+ if (descriptor->field(i)->is_required()) {
+ if (!reflection->HasField(message, descriptor->field(i))) {
+ return false;
+ }
+ }
+ }
+ }
+
+ // Check that sub-messages are initialized.
+ std::vector<const FieldDescriptor*> fields;
+ // Should be safe to skip stripped fields because required fields are not
+ // stripped.
+ reflection->ListFieldsOmitStripped(message, &fields);
+ for (const FieldDescriptor* field : fields) {
+ if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+
+ if (field->is_map()) {
+ const FieldDescriptor* value_field = field->message_type()->field(1);
+ if (value_field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+ const MapFieldBase* map_field =
+ reflection->GetMapData(message, field);
+ if (map_field->IsMapValid()) {
+ MapIterator iter(const_cast<Message*>(&message), field);
+ MapIterator end(const_cast<Message*>(&message), field);
+ for (map_field->MapBegin(&iter), map_field->MapEnd(&end);
+ iter != end; ++iter) {
+ if (!iter.GetValueRef().GetMessageValue().IsInitialized()) {
+ return false;
+ }
+ }
+ continue;
+ }
+ } else {
+ continue;
+ }
+ }
+
+ if (field->is_repeated()) {
+ int size = reflection->FieldSize(message, field);
+
+ for (int j = 0; j < size; j++) {
+ if (!reflection->GetRepeatedMessage(message, field, j)
+ .IsInitialized()) {
+ return false;
+ }
+ }
+ } else {
+ if (!reflection->GetMessage(message, field).IsInitialized()) {
+ return false;
+ }
+ }
+ }
+ }
+
+ return true;
+}
+
+static bool IsMapValueMessageTyped(const FieldDescriptor* map_field) {
+ return map_field->message_type()->field(1)->cpp_type() ==
+ FieldDescriptor::CPPTYPE_MESSAGE;
+}
+
+void ReflectionOps::DiscardUnknownFields(Message* message) {
+ const Reflection* reflection = GetReflectionOrDie(*message);
+
+ reflection->MutableUnknownFields(message)->Clear();
+
+ // Walk through the fields of this message and DiscardUnknownFields on any
+ // messages present.
+ std::vector<const FieldDescriptor*> fields;
+ reflection->ListFields(*message, &fields);
+ for (const FieldDescriptor* field : fields) {
+ // Skip over non-message fields.
+ if (field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) {
+ continue;
+ }
+ // Discard the unknown fields in maps that contain message values.
+ if (field->is_map() && IsMapValueMessageTyped(field)) {
+ const MapFieldBase* map_field =
+ reflection->MutableMapData(message, field);
+ if (map_field->IsMapValid()) {
+ MapIterator iter(message, field);
+ MapIterator end(message, field);
+ for (map_field->MapBegin(&iter), map_field->MapEnd(&end); iter != end;
+ ++iter) {
+ iter.MutableValueRef()->MutableMessageValue()->DiscardUnknownFields();
+ }
+ }
+ // Discard every unknown field inside messages in a repeated field.
+ } else if (field->is_repeated()) {
+ int size = reflection->FieldSize(*message, field);
+ for (int j = 0; j < size; j++) {
+ reflection->MutableRepeatedMessage(message, field, j)
+ ->DiscardUnknownFields();
+ }
+ // Discard the unknown fields inside an optional message.
+ } else {
+ reflection->MutableMessage(message, field)->DiscardUnknownFields();
+ }
+ }
+}
+
+static 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::InternalHelper<Message>::GetOwningArena(lhs) !=
+ Arena::InternalHelper<Message>::GetOwningArena(rhs));
+ GOOGLE_DCHECK(Arena::InternalHelper<Message>::GetOwningArena(lhs) != nullptr ||
+ Arena::InternalHelper<Message>::GetOwningArena(rhs) != nullptr);
+#endif // !PROTOBUF_FORCE_COPY_IN_SWAP
+ // At least one of these must have an arena, so make `rhs` point to it.
+ Arena* arena = Arena::InternalHelper<Message>::GetOwningArena(rhs);
+ if (arena == nullptr) {
+ std::swap(lhs, rhs);
+ arena = Arena::InternalHelper<Message>::GetOwningArena(rhs);
+ }
+
+ // Improve efficiency by placing the temporary on an arena so that messages
+ // are copied twice rather than three times.
+ Message* tmp = rhs->New(arena);
+ tmp->CheckTypeAndMergeFrom(*lhs);
+ lhs->Clear();
+ lhs->CheckTypeAndMergeFrom(*rhs);
+#ifdef PROTOBUF_FORCE_COPY_IN_SWAP
+ rhs->Clear();
+ rhs->CheckTypeAndMergeFrom(*tmp);
+ if (arena == nullptr) delete tmp;
+#else // PROTOBUF_FORCE_COPY_IN_SWAP
+ rhs->GetReflection()->Swap(tmp, rhs);
+#endif // !PROTOBUF_FORCE_COPY_IN_SWAP
+}
+
+} // namespace internal
+} // namespace protobuf
+} // namespace google
+
+#include <port_undef.inc>
diff --git a/NorthstarDedicatedTest/include/protobuf/reflection_ops.h b/NorthstarDedicatedTest/include/protobuf/reflection_ops.h
new file mode 100644
index 00000000..9ce4e8bc
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/reflection_ops.h
@@ -0,0 +1,91 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// This header is logically internal, but is made public because it is used
+// from protocol-compiler-generated code, which may reside in other components.
+
+#ifndef GOOGLE_PROTOBUF_REFLECTION_OPS_H__
+#define GOOGLE_PROTOBUF_REFLECTION_OPS_H__
+
+#include <stubs/common.h>
+#include <message.h>
+
+#ifdef SWIG
+#error "You cannot SWIG proto headers"
+#endif
+
+#include <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 <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_REFLECTION_OPS_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/reflection_ops_unittest.cc b/NorthstarDedicatedTest/include/protobuf/reflection_ops_unittest.cc
new file mode 100644
index 00000000..7f918937
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/reflection_ops_unittest.cc
@@ -0,0 +1,546 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <reflection_ops.h>
+#include <test_util.h>
+#include <unittest.pb.h>
+#include <descriptor.h>
+
+#include <stubs/logging.h>
+#include <stubs/common.h>
+#include <testing/googletest.h>
+#include <gtest/gtest.h>
+
+#include <stubs/strutil.h>
+
+namespace google {
+namespace protobuf {
+namespace internal {
+namespace {
+
+TEST(ReflectionOpsTest, SanityCheck) {
+ unittest::TestAllTypes message;
+
+ TestUtil::SetAllFields(&message);
+ TestUtil::ExpectAllFieldsSet(message);
+}
+
+TEST(ReflectionOpsTest, Copy) {
+ unittest::TestAllTypes message, message2;
+
+ TestUtil::SetAllFields(&message);
+
+ ReflectionOps::Copy(message, &message2);
+
+ TestUtil::ExpectAllFieldsSet(message2);
+
+ // Copying from self should be a no-op.
+ ReflectionOps::Copy(message2, &message2);
+ TestUtil::ExpectAllFieldsSet(message2);
+}
+
+TEST(ReflectionOpsTest, CopyExtensions) {
+ unittest::TestAllExtensions message, message2;
+
+ TestUtil::SetAllExtensions(&message);
+
+ ReflectionOps::Copy(message, &message2);
+
+ TestUtil::ExpectAllExtensionsSet(message2);
+}
+
+TEST(ReflectionOpsTest, CopyOneof) {
+ unittest::TestOneof2 message, message2;
+ TestUtil::SetOneof1(&message);
+ ReflectionOps::Copy(message, &message2);
+ TestUtil::ExpectOneofSet1(message2);
+
+ TestUtil::SetOneof2(&message);
+ TestUtil::ExpectOneofSet2(message);
+ ReflectionOps::Copy(message, &message2);
+ TestUtil::ExpectOneofSet2(message2);
+}
+
+TEST(ReflectionOpsTest, Merge) {
+ // Note: Copy is implemented in terms of Merge() so technically the Copy
+ // test already tested most of this.
+
+ unittest::TestAllTypes message, message2;
+
+ TestUtil::SetAllFields(&message);
+
+ // This field will test merging into an empty spot.
+ message2.set_optional_int32(message.optional_int32());
+ message.clear_optional_int32();
+
+ // This tests overwriting.
+ message2.set_optional_string(message.optional_string());
+ message.set_optional_string("something else");
+
+ // This tests concatenating.
+ message2.add_repeated_int32(message.repeated_int32(1));
+ int32 i = message.repeated_int32(0);
+ message.clear_repeated_int32();
+ message.add_repeated_int32(i);
+
+ ReflectionOps::Merge(message2, &message);
+
+ TestUtil::ExpectAllFieldsSet(message);
+}
+
+TEST(ReflectionOpsTest, MergeExtensions) {
+ // Note: Copy is implemented in terms of Merge() so technically the Copy
+ // test already tested most of this.
+
+ unittest::TestAllExtensions message, message2;
+
+ TestUtil::SetAllExtensions(&message);
+
+ // This field will test merging into an empty spot.
+ message2.SetExtension(
+ unittest::optional_int32_extension,
+ message.GetExtension(unittest::optional_int32_extension));
+ message.ClearExtension(unittest::optional_int32_extension);
+
+ // This tests overwriting.
+ message2.SetExtension(
+ unittest::optional_string_extension,
+ message.GetExtension(unittest::optional_string_extension));
+ message.SetExtension(unittest::optional_string_extension, "something else");
+
+ // This tests concatenating.
+ message2.AddExtension(
+ unittest::repeated_int32_extension,
+ message.GetExtension(unittest::repeated_int32_extension, 1));
+ int32 i = message.GetExtension(unittest::repeated_int32_extension, 0);
+ message.ClearExtension(unittest::repeated_int32_extension);
+ message.AddExtension(unittest::repeated_int32_extension, i);
+
+ ReflectionOps::Merge(message2, &message);
+
+ TestUtil::ExpectAllExtensionsSet(message);
+}
+
+TEST(ReflectionOpsTest, MergeUnknown) {
+ // Test that the messages' UnknownFieldSets are correctly merged.
+ unittest::TestEmptyMessage message1, message2;
+ message1.mutable_unknown_fields()->AddVarint(1234, 1);
+ message2.mutable_unknown_fields()->AddVarint(1234, 2);
+
+ ReflectionOps::Merge(message2, &message1);
+
+ ASSERT_EQ(2, message1.unknown_fields().field_count());
+ ASSERT_EQ(UnknownField::TYPE_VARINT,
+ message1.unknown_fields().field(0).type());
+ EXPECT_EQ(1, message1.unknown_fields().field(0).varint());
+ ASSERT_EQ(UnknownField::TYPE_VARINT,
+ message1.unknown_fields().field(1).type());
+ EXPECT_EQ(2, message1.unknown_fields().field(1).varint());
+}
+
+TEST(ReflectionOpsTest, MergeOneof) {
+ unittest::TestOneof2 message1, message2;
+ TestUtil::SetOneof1(&message1);
+
+ // Merge to empty message
+ ReflectionOps::Merge(message1, &message2);
+ TestUtil::ExpectOneofSet1(message2);
+
+ // Merge with the same oneof fields
+ ReflectionOps::Merge(message1, &message2);
+ TestUtil::ExpectOneofSet1(message2);
+
+ // Merge with different oneof fields
+ TestUtil::SetOneof2(&message1);
+ ReflectionOps::Merge(message1, &message2);
+ TestUtil::ExpectOneofSet2(message2);
+}
+
+#ifdef PROTOBUF_HAS_DEATH_TEST
+
+TEST(ReflectionOpsTest, MergeFromSelf) {
+ // Note: Copy is implemented in terms of Merge() so technically the Copy
+ // test already tested most of this.
+
+ unittest::TestAllTypes message;
+
+ EXPECT_DEATH(ReflectionOps::Merge(message, &message), "&from");
+}
+
+#endif // PROTOBUF_HAS_DEATH_TEST
+
+TEST(ReflectionOpsTest, Clear) {
+ unittest::TestAllTypes message;
+
+ TestUtil::SetAllFields(&message);
+
+ ReflectionOps::Clear(&message);
+
+ TestUtil::ExpectClear(message);
+
+ // Check that getting embedded messages returns the objects created during
+ // SetAllFields() rather than default instances.
+ EXPECT_NE(&unittest::TestAllTypes::OptionalGroup::default_instance(),
+ &message.optionalgroup());
+ EXPECT_NE(&unittest::TestAllTypes::NestedMessage::default_instance(),
+ &message.optional_nested_message());
+ EXPECT_NE(&unittest::ForeignMessage::default_instance(),
+ &message.optional_foreign_message());
+ EXPECT_NE(&unittest_import::ImportMessage::default_instance(),
+ &message.optional_import_message());
+}
+
+TEST(ReflectionOpsTest, ClearExtensions) {
+ unittest::TestAllExtensions message;
+
+ TestUtil::SetAllExtensions(&message);
+
+ ReflectionOps::Clear(&message);
+
+ TestUtil::ExpectExtensionsClear(message);
+
+ // Check that getting embedded messages returns the objects created during
+ // SetAllExtensions() rather than default instances.
+ EXPECT_NE(&unittest::OptionalGroup_extension::default_instance(),
+ &message.GetExtension(unittest::optionalgroup_extension));
+ EXPECT_NE(&unittest::TestAllTypes::NestedMessage::default_instance(),
+ &message.GetExtension(unittest::optional_nested_message_extension));
+ EXPECT_NE(
+ &unittest::ForeignMessage::default_instance(),
+ &message.GetExtension(unittest::optional_foreign_message_extension));
+ EXPECT_NE(&unittest_import::ImportMessage::default_instance(),
+ &message.GetExtension(unittest::optional_import_message_extension));
+}
+
+TEST(ReflectionOpsTest, ClearUnknown) {
+ // Test that the message's UnknownFieldSet is correctly cleared.
+ unittest::TestEmptyMessage message;
+ message.mutable_unknown_fields()->AddVarint(1234, 1);
+
+ ReflectionOps::Clear(&message);
+
+ EXPECT_EQ(0, message.unknown_fields().field_count());
+}
+
+TEST(ReflectionOpsTest, ClearOneof) {
+ unittest::TestOneof2 message;
+
+ TestUtil::ExpectOneofClear(message);
+ TestUtil::SetOneof1(&message);
+ TestUtil::ExpectOneofSet1(message);
+ ReflectionOps::Clear(&message);
+ TestUtil::ExpectOneofClear(message);
+
+ TestUtil::SetOneof1(&message);
+ TestUtil::ExpectOneofSet1(message);
+ TestUtil::SetOneof2(&message);
+ TestUtil::ExpectOneofSet2(message);
+ ReflectionOps::Clear(&message);
+ TestUtil::ExpectOneofClear(message);
+}
+
+TEST(ReflectionOpsTest, DiscardUnknownFields) {
+ unittest::TestAllTypes message;
+ TestUtil::SetAllFields(&message);
+
+ // Set some unknown fields in message.
+ message.mutable_unknown_fields()->AddVarint(123456, 654321);
+ message.mutable_optional_nested_message()
+ ->mutable_unknown_fields()
+ ->AddVarint(123456, 654321);
+ message.mutable_repeated_nested_message(0)
+ ->mutable_unknown_fields()
+ ->AddVarint(123456, 654321);
+
+ EXPECT_EQ(1, message.unknown_fields().field_count());
+ EXPECT_EQ(1,
+ message.optional_nested_message().unknown_fields().field_count());
+ EXPECT_EQ(1,
+ message.repeated_nested_message(0).unknown_fields().field_count());
+
+ // Discard them.
+ ReflectionOps::DiscardUnknownFields(&message);
+ TestUtil::ExpectAllFieldsSet(message);
+
+ EXPECT_EQ(0, message.unknown_fields().field_count());
+ EXPECT_EQ(0,
+ message.optional_nested_message().unknown_fields().field_count());
+ EXPECT_EQ(0,
+ message.repeated_nested_message(0).unknown_fields().field_count());
+}
+
+TEST(ReflectionOpsTest, DiscardUnknownExtensions) {
+ unittest::TestAllExtensions message;
+ TestUtil::SetAllExtensions(&message);
+
+ // Set some unknown fields.
+ message.mutable_unknown_fields()->AddVarint(123456, 654321);
+ message.MutableExtension(unittest::optional_nested_message_extension)
+ ->mutable_unknown_fields()
+ ->AddVarint(123456, 654321);
+ message.MutableExtension(unittest::repeated_nested_message_extension, 0)
+ ->mutable_unknown_fields()
+ ->AddVarint(123456, 654321);
+
+ EXPECT_EQ(1, message.unknown_fields().field_count());
+ EXPECT_EQ(1, message.GetExtension(unittest::optional_nested_message_extension)
+ .unknown_fields()
+ .field_count());
+ EXPECT_EQ(1,
+ message.GetExtension(unittest::repeated_nested_message_extension, 0)
+ .unknown_fields()
+ .field_count());
+
+ // Discard them.
+ ReflectionOps::DiscardUnknownFields(&message);
+ TestUtil::ExpectAllExtensionsSet(message);
+
+ EXPECT_EQ(0, message.unknown_fields().field_count());
+ EXPECT_EQ(0, message.GetExtension(unittest::optional_nested_message_extension)
+ .unknown_fields()
+ .field_count());
+ EXPECT_EQ(0,
+ message.GetExtension(unittest::repeated_nested_message_extension, 0)
+ .unknown_fields()
+ .field_count());
+}
+
+TEST(ReflectionOpsTest, IsInitialized) {
+ unittest::TestRequired message;
+
+ EXPECT_FALSE(ReflectionOps::IsInitialized(message));
+ EXPECT_FALSE(ReflectionOps::IsInitialized(message, true, false));
+ EXPECT_TRUE(ReflectionOps::IsInitialized(message, false, true));
+ message.set_a(1);
+ EXPECT_FALSE(ReflectionOps::IsInitialized(message));
+ EXPECT_FALSE(ReflectionOps::IsInitialized(message, true, true));
+ EXPECT_TRUE(ReflectionOps::IsInitialized(message, false, true));
+ message.set_b(2);
+ EXPECT_FALSE(ReflectionOps::IsInitialized(message));
+ EXPECT_FALSE(ReflectionOps::IsInitialized(message, true, true));
+ EXPECT_TRUE(ReflectionOps::IsInitialized(message, false, true));
+ message.set_c(3);
+ EXPECT_TRUE(ReflectionOps::IsInitialized(message));
+ EXPECT_TRUE(ReflectionOps::IsInitialized(message, true, false));
+ EXPECT_TRUE(ReflectionOps::IsInitialized(message, false, true));
+}
+
+TEST(ReflectionOpsTest, ForeignIsInitialized) {
+ unittest::TestRequiredForeign message;
+
+ // Starts out initialized because the foreign message is itself an optional
+ // field.
+ EXPECT_TRUE(ReflectionOps::IsInitialized(message));
+ EXPECT_TRUE(ReflectionOps::IsInitialized(message, false, true));
+
+ // Once we create that field, the message is no longer initialized.
+ message.mutable_optional_message();
+ EXPECT_FALSE(ReflectionOps::IsInitialized(message));
+ EXPECT_TRUE(ReflectionOps::IsInitialized(message, true, false));
+ EXPECT_FALSE(ReflectionOps::IsInitialized(message, false, true));
+
+ // Initialize it. Now we're initialized.
+ message.mutable_optional_message()->set_a(1);
+ message.mutable_optional_message()->set_b(2);
+ message.mutable_optional_message()->set_c(3);
+ EXPECT_TRUE(ReflectionOps::IsInitialized(message));
+ EXPECT_TRUE(ReflectionOps::IsInitialized(message, true, false));
+ EXPECT_TRUE(ReflectionOps::IsInitialized(message, false, true));
+
+ // Add a repeated version of the message. No longer initialized.
+ unittest::TestRequired* sub_message = message.add_repeated_message();
+ EXPECT_FALSE(ReflectionOps::IsInitialized(message));
+ EXPECT_TRUE(ReflectionOps::IsInitialized(message, true, false));
+ EXPECT_FALSE(ReflectionOps::IsInitialized(message, false, true));
+
+ // Initialize that repeated version.
+ sub_message->set_a(1);
+ sub_message->set_b(2);
+ sub_message->set_c(3);
+ EXPECT_TRUE(ReflectionOps::IsInitialized(message));
+ EXPECT_TRUE(ReflectionOps::IsInitialized(message, true, false));
+ EXPECT_TRUE(ReflectionOps::IsInitialized(message, false, true));
+}
+
+TEST(ReflectionOpsTest, ExtensionIsInitialized) {
+ unittest::TestAllExtensions message;
+
+ // Starts out initialized because the foreign message is itself an optional
+ // field.
+ EXPECT_TRUE(ReflectionOps::IsInitialized(message));
+ EXPECT_TRUE(ReflectionOps::IsInitialized(message, true, false));
+ EXPECT_TRUE(ReflectionOps::IsInitialized(message, false, true));
+
+ // Once we create that field, the message is no longer initialized.
+ message.MutableExtension(unittest::TestRequired::single);
+ EXPECT_FALSE(ReflectionOps::IsInitialized(message));
+ EXPECT_TRUE(ReflectionOps::IsInitialized(message, true, false));
+ EXPECT_FALSE(ReflectionOps::IsInitialized(message, false, true));
+
+ // Initialize it. Now we're initialized.
+ message.MutableExtension(unittest::TestRequired::single)->set_a(1);
+ message.MutableExtension(unittest::TestRequired::single)->set_b(2);
+ message.MutableExtension(unittest::TestRequired::single)->set_c(3);
+ EXPECT_TRUE(ReflectionOps::IsInitialized(message));
+ EXPECT_TRUE(ReflectionOps::IsInitialized(message, true, false));
+ EXPECT_TRUE(ReflectionOps::IsInitialized(message, false, true));
+
+ // Add a repeated version of the message. No longer initialized.
+ message.AddExtension(unittest::TestRequired::multi);
+ EXPECT_FALSE(ReflectionOps::IsInitialized(message));
+ EXPECT_TRUE(ReflectionOps::IsInitialized(message, true, false));
+ EXPECT_FALSE(ReflectionOps::IsInitialized(message, false, true));
+
+ // Initialize that repeated version.
+ message.MutableExtension(unittest::TestRequired::multi, 0)->set_a(1);
+ message.MutableExtension(unittest::TestRequired::multi, 0)->set_b(2);
+ message.MutableExtension(unittest::TestRequired::multi, 0)->set_c(3);
+ EXPECT_TRUE(ReflectionOps::IsInitialized(message));
+ EXPECT_TRUE(ReflectionOps::IsInitialized(message, true, false));
+ EXPECT_TRUE(ReflectionOps::IsInitialized(message, false, true));
+}
+
+TEST(ReflectionOpsTest, OneofIsInitialized) {
+ unittest::TestRequiredOneof message;
+ EXPECT_TRUE(ReflectionOps::IsInitialized(message));
+ EXPECT_TRUE(ReflectionOps::IsInitialized(message, true, false));
+ EXPECT_TRUE(ReflectionOps::IsInitialized(message, false, true));
+
+ message.mutable_foo_message();
+ EXPECT_FALSE(ReflectionOps::IsInitialized(message));
+ EXPECT_TRUE(ReflectionOps::IsInitialized(message, true, false));
+ EXPECT_FALSE(ReflectionOps::IsInitialized(message, false, true));
+
+ message.set_foo_int(1);
+ EXPECT_TRUE(ReflectionOps::IsInitialized(message));
+ EXPECT_TRUE(ReflectionOps::IsInitialized(message, true, false));
+ EXPECT_TRUE(ReflectionOps::IsInitialized(message, false, true));
+
+ message.mutable_foo_message();
+ EXPECT_FALSE(ReflectionOps::IsInitialized(message));
+ EXPECT_TRUE(ReflectionOps::IsInitialized(message, true, false));
+ EXPECT_FALSE(ReflectionOps::IsInitialized(message, false, true));
+ message.mutable_foo_message()->set_required_double(0.1);
+ EXPECT_TRUE(ReflectionOps::IsInitialized(message));
+ EXPECT_TRUE(ReflectionOps::IsInitialized(message, true, false));
+ EXPECT_TRUE(ReflectionOps::IsInitialized(message, false, true));
+}
+
+static std::string FindInitializationErrors(const Message& message) {
+ std::vector<std::string> errors;
+ ReflectionOps::FindInitializationErrors(message, "", &errors);
+ return Join(errors, ",");
+}
+
+TEST(ReflectionOpsTest, FindInitializationErrors) {
+ unittest::TestRequired message;
+ EXPECT_EQ("a,b,c", FindInitializationErrors(message));
+}
+
+TEST(ReflectionOpsTest, FindForeignInitializationErrors) {
+ unittest::TestRequiredForeign message;
+ message.mutable_optional_message();
+ message.add_repeated_message();
+ message.add_repeated_message();
+ EXPECT_EQ(
+ "optional_message.a,"
+ "optional_message.b,"
+ "optional_message.c,"
+ "repeated_message[0].a,"
+ "repeated_message[0].b,"
+ "repeated_message[0].c,"
+ "repeated_message[1].a,"
+ "repeated_message[1].b,"
+ "repeated_message[1].c",
+ FindInitializationErrors(message));
+}
+
+TEST(ReflectionOpsTest, FindExtensionInitializationErrors) {
+ unittest::TestAllExtensions message;
+ message.MutableExtension(unittest::TestRequired::single);
+ message.AddExtension(unittest::TestRequired::multi);
+ message.AddExtension(unittest::TestRequired::multi);
+ EXPECT_EQ(
+ "(protobuf_unittest.TestRequired.single).a,"
+ "(protobuf_unittest.TestRequired.single).b,"
+ "(protobuf_unittest.TestRequired.single).c,"
+ "(protobuf_unittest.TestRequired.multi)[0].a,"
+ "(protobuf_unittest.TestRequired.multi)[0].b,"
+ "(protobuf_unittest.TestRequired.multi)[0].c,"
+ "(protobuf_unittest.TestRequired.multi)[1].a,"
+ "(protobuf_unittest.TestRequired.multi)[1].b,"
+ "(protobuf_unittest.TestRequired.multi)[1].c",
+ FindInitializationErrors(message));
+}
+
+TEST(ReflectionOpsTest, FindOneofInitializationErrors) {
+ unittest::TestRequiredOneof message;
+ message.mutable_foo_message();
+ EXPECT_EQ("foo_message.required_double", FindInitializationErrors(message));
+}
+
+TEST(ReflectionOpsTest, GenericSwap) {
+ Arena arena;
+ {
+ unittest::TestAllTypes message;
+ auto* arena_message = Arena::CreateMessage<unittest::TestAllTypes>(&arena);
+ TestUtil::SetAllFields(arena_message);
+ const uint64 initial_arena_size = arena.SpaceUsed();
+
+ GenericSwap(&message, arena_message);
+
+ TestUtil::ExpectAllFieldsSet(message);
+ TestUtil::ExpectClear(*arena_message);
+ // The temp should be allocated on the arena in this case.
+ EXPECT_GT(arena.SpaceUsed(), initial_arena_size);
+ }
+ {
+ unittest::TestAllTypes message;
+ auto* arena_message = Arena::CreateMessage<unittest::TestAllTypes>(&arena);
+ TestUtil::SetAllFields(arena_message);
+ const uint64 initial_arena_size = arena.SpaceUsed();
+
+ GenericSwap(arena_message, &message);
+
+ TestUtil::ExpectAllFieldsSet(message);
+ TestUtil::ExpectClear(*arena_message);
+ // The temp should be allocated on the arena in this case.
+ EXPECT_GT(arena.SpaceUsed(), initial_arena_size);
+ }
+}
+
+} // namespace
+} // namespace internal
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/reflection_tester.cc b/NorthstarDedicatedTest/include/protobuf/reflection_tester.cc
new file mode 100644
index 00000000..015be7c0
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/reflection_tester.cc
@@ -0,0 +1,1673 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 <reflection_tester.h>
+
+#include <map_field.h>
+#include <message.h>
+#include <gtest/gtest.h>
+
+// Must include last.
+#include <port_def.inc>
+
+namespace google {
+namespace protobuf {
+
+MapReflectionTester::MapReflectionTester(const Descriptor* base_descriptor)
+ : base_descriptor_(base_descriptor) {
+ const DescriptorPool* pool = base_descriptor->file()->pool();
+ std::string package = base_descriptor->file()->package();
+
+ map_enum_foo_ = pool->FindEnumValueByName(package + ".MAP_ENUM_FOO");
+ map_enum_bar_ = pool->FindEnumValueByName(package + ".MAP_ENUM_BAR");
+ map_enum_baz_ = pool->FindEnumValueByName(package + ".MAP_ENUM_BAZ");
+
+ foreign_c_ = pool->FindFieldByName(package + ".ForeignMessage.c");
+ map_int32_int32_key_ =
+ pool->FindFieldByName(package + ".TestMap.MapInt32Int32Entry.key");
+ map_int32_int32_val_ =
+ pool->FindFieldByName(package + ".TestMap.MapInt32Int32Entry.value");
+ map_int64_int64_key_ =
+ pool->FindFieldByName(package + ".TestMap.MapInt64Int64Entry.key");
+ map_int64_int64_val_ =
+ pool->FindFieldByName(package + ".TestMap.MapInt64Int64Entry.value");
+ map_uint32_uint32_key_ =
+ pool->FindFieldByName(package + ".TestMap.MapUint32Uint32Entry.key");
+ map_uint32_uint32_val_ =
+ pool->FindFieldByName(package + ".TestMap.MapUint32Uint32Entry.value");
+ map_uint64_uint64_key_ =
+ pool->FindFieldByName(package + ".TestMap.MapUint64Uint64Entry.key");
+ map_uint64_uint64_val_ =
+ pool->FindFieldByName(package + ".TestMap.MapUint64Uint64Entry.value");
+ map_sint32_sint32_key_ =
+ pool->FindFieldByName(package + ".TestMap.MapSint32Sint32Entry.key");
+ map_sint32_sint32_val_ =
+ pool->FindFieldByName(package + ".TestMap.MapSint32Sint32Entry.value");
+ map_sint64_sint64_key_ =
+ pool->FindFieldByName(package + ".TestMap.MapSint64Sint64Entry.key");
+ map_sint64_sint64_val_ =
+ pool->FindFieldByName(package + ".TestMap.MapSint64Sint64Entry.value");
+ map_fixed32_fixed32_key_ =
+ pool->FindFieldByName(package + ".TestMap.MapFixed32Fixed32Entry.key");
+ map_fixed32_fixed32_val_ =
+ pool->FindFieldByName(package + ".TestMap.MapFixed32Fixed32Entry.value");
+ map_fixed64_fixed64_key_ =
+ pool->FindFieldByName(package + ".TestMap.MapFixed64Fixed64Entry.key");
+ map_fixed64_fixed64_val_ =
+ pool->FindFieldByName(package + ".TestMap.MapFixed64Fixed64Entry.value");
+ map_sfixed32_sfixed32_key_ =
+ pool->FindFieldByName(package + ".TestMap.MapSfixed32Sfixed32Entry.key");
+ map_sfixed32_sfixed32_val_ = pool->FindFieldByName(
+ package + ".TestMap.MapSfixed32Sfixed32Entry.value");
+ map_sfixed64_sfixed64_key_ =
+ pool->FindFieldByName(package + ".TestMap.MapSfixed64Sfixed64Entry.key");
+ map_sfixed64_sfixed64_val_ = pool->FindFieldByName(
+ package + ".TestMap.MapSfixed64Sfixed64Entry.value");
+ map_int32_float_key_ =
+ pool->FindFieldByName(package + ".TestMap.MapInt32FloatEntry.key");
+ map_int32_float_val_ =
+ pool->FindFieldByName(package + ".TestMap.MapInt32FloatEntry.value");
+ map_int32_double_key_ =
+ pool->FindFieldByName(package + ".TestMap.MapInt32DoubleEntry.key");
+ map_int32_double_val_ =
+ pool->FindFieldByName(package + ".TestMap.MapInt32DoubleEntry.value");
+ map_bool_bool_key_ =
+ pool->FindFieldByName(package + ".TestMap.MapBoolBoolEntry.key");
+ map_bool_bool_val_ =
+ pool->FindFieldByName(package + ".TestMap.MapBoolBoolEntry.value");
+ map_string_string_key_ =
+ pool->FindFieldByName(package + ".TestMap.MapStringStringEntry.key");
+ map_string_string_val_ =
+ pool->FindFieldByName(package + ".TestMap.MapStringStringEntry.value");
+ map_int32_bytes_key_ =
+ pool->FindFieldByName(package + ".TestMap.MapInt32BytesEntry.key");
+ map_int32_bytes_val_ =
+ pool->FindFieldByName(package + ".TestMap.MapInt32BytesEntry.value");
+ map_int32_enum_key_ =
+ pool->FindFieldByName(package + ".TestMap.MapInt32EnumEntry.key");
+ map_int32_enum_val_ =
+ pool->FindFieldByName(package + ".TestMap.MapInt32EnumEntry.value");
+ map_int32_foreign_message_key_ = pool->FindFieldByName(
+ package + ".TestMap.MapInt32ForeignMessageEntry.key");
+ map_int32_foreign_message_val_ = pool->FindFieldByName(
+ package + ".TestMap.MapInt32ForeignMessageEntry.value");
+
+ EXPECT_FALSE(map_enum_foo_ == nullptr);
+ EXPECT_FALSE(map_enum_bar_ == nullptr);
+ EXPECT_FALSE(map_enum_baz_ == nullptr);
+ EXPECT_FALSE(map_int32_int32_key_ == nullptr);
+ EXPECT_FALSE(map_int32_int32_val_ == nullptr);
+ EXPECT_FALSE(map_int64_int64_key_ == nullptr);
+ EXPECT_FALSE(map_int64_int64_val_ == nullptr);
+ EXPECT_FALSE(map_uint32_uint32_key_ == nullptr);
+ EXPECT_FALSE(map_uint32_uint32_val_ == nullptr);
+ EXPECT_FALSE(map_uint64_uint64_key_ == nullptr);
+ EXPECT_FALSE(map_uint64_uint64_val_ == nullptr);
+ EXPECT_FALSE(map_sint32_sint32_key_ == nullptr);
+ EXPECT_FALSE(map_sint32_sint32_val_ == nullptr);
+ EXPECT_FALSE(map_sint64_sint64_key_ == nullptr);
+ EXPECT_FALSE(map_sint64_sint64_val_ == nullptr);
+ EXPECT_FALSE(map_fixed32_fixed32_key_ == nullptr);
+ EXPECT_FALSE(map_fixed32_fixed32_val_ == nullptr);
+ EXPECT_FALSE(map_fixed64_fixed64_key_ == nullptr);
+ EXPECT_FALSE(map_fixed64_fixed64_val_ == nullptr);
+ EXPECT_FALSE(map_sfixed32_sfixed32_key_ == nullptr);
+ EXPECT_FALSE(map_sfixed32_sfixed32_val_ == nullptr);
+ EXPECT_FALSE(map_sfixed64_sfixed64_key_ == nullptr);
+ EXPECT_FALSE(map_sfixed64_sfixed64_val_ == nullptr);
+ EXPECT_FALSE(map_int32_float_key_ == nullptr);
+ EXPECT_FALSE(map_int32_float_val_ == nullptr);
+ EXPECT_FALSE(map_int32_double_key_ == nullptr);
+ EXPECT_FALSE(map_int32_double_val_ == nullptr);
+ EXPECT_FALSE(map_bool_bool_key_ == nullptr);
+ EXPECT_FALSE(map_bool_bool_val_ == nullptr);
+ EXPECT_FALSE(map_string_string_key_ == nullptr);
+ EXPECT_FALSE(map_string_string_val_ == nullptr);
+ EXPECT_FALSE(map_int32_bytes_key_ == nullptr);
+ EXPECT_FALSE(map_int32_bytes_val_ == nullptr);
+ EXPECT_FALSE(map_int32_enum_key_ == nullptr);
+ EXPECT_FALSE(map_int32_enum_val_ == nullptr);
+ EXPECT_FALSE(map_int32_foreign_message_key_ == nullptr);
+ EXPECT_FALSE(map_int32_foreign_message_val_ == nullptr);
+
+ std::vector<const FieldDescriptor*> all_map_descriptors = {
+ map_int32_int32_key_,
+ map_int32_int32_val_,
+ map_int64_int64_key_,
+ map_int64_int64_val_,
+ map_uint32_uint32_key_,
+ map_uint32_uint32_val_,
+ map_uint64_uint64_key_,
+ map_uint64_uint64_val_,
+ map_sint32_sint32_key_,
+ map_sint32_sint32_val_,
+ map_sint64_sint64_key_,
+ map_sint64_sint64_val_,
+ map_fixed32_fixed32_key_,
+ map_fixed32_fixed32_val_,
+ map_fixed64_fixed64_key_,
+ map_fixed64_fixed64_val_,
+ map_sfixed32_sfixed32_key_,
+ map_sfixed32_sfixed32_val_,
+ map_sfixed64_sfixed64_key_,
+ map_sfixed64_sfixed64_val_,
+ map_int32_float_key_,
+ map_int32_float_val_,
+ map_int32_double_key_,
+ map_int32_double_val_,
+ map_bool_bool_key_,
+ map_bool_bool_val_,
+ map_string_string_key_,
+ map_string_string_val_,
+ map_int32_bytes_key_,
+ map_int32_bytes_val_,
+ map_int32_enum_key_,
+ map_int32_enum_val_,
+ map_int32_foreign_message_key_,
+ map_int32_foreign_message_val_};
+ for (const FieldDescriptor* fdesc : all_map_descriptors) {
+ GOOGLE_CHECK(fdesc->containing_type() != nullptr) << fdesc->name();
+ if (fdesc->name() == "key") {
+ EXPECT_EQ(fdesc->containing_type()->map_key(), fdesc);
+ } else {
+ EXPECT_EQ(fdesc->name(), "value");
+ EXPECT_EQ(fdesc->containing_type()->map_value(), fdesc);
+ }
+ }
+}
+
+// Shorthand to get a FieldDescriptor for a field of unittest::TestMap.
+const FieldDescriptor* MapReflectionTester::F(const std::string& name) {
+ const FieldDescriptor* result = nullptr;
+ result = base_descriptor_->FindFieldByName(name);
+ GOOGLE_CHECK(result != nullptr);
+ return result;
+}
+
+void MapReflectionTester::SetMapFieldsViaReflection(Message* message) {
+ const Reflection* reflection = message->GetReflection();
+ Message* sub_message = nullptr;
+ Message* sub_foreign_message = nullptr;
+
+ // Add first element.
+ sub_message = reflection->AddMessage(message, F("map_int32_int32"));
+ sub_message->GetReflection()->SetInt32(sub_message, map_int32_int32_key_, 0);
+ sub_message->GetReflection()->SetInt32(sub_message, map_int32_int32_val_, 0);
+
+ sub_message = reflection->AddMessage(message, F("map_int64_int64"));
+ sub_message->GetReflection()->SetInt64(sub_message, map_int64_int64_key_, 0);
+ sub_message->GetReflection()->SetInt64(sub_message, map_int64_int64_val_, 0);
+
+ sub_message = reflection->AddMessage(message, F("map_uint32_uint32"));
+ sub_message->GetReflection()->SetUInt32(sub_message, map_uint32_uint32_key_,
+ 0);
+ sub_message->GetReflection()->SetUInt32(sub_message, map_uint32_uint32_val_,
+ 0);
+
+ sub_message = reflection->AddMessage(message, F("map_uint64_uint64"));
+ sub_message->GetReflection()->SetUInt64(sub_message, map_uint64_uint64_key_,
+ 0);
+ sub_message->GetReflection()->SetUInt64(sub_message, map_uint64_uint64_val_,
+ 0);
+
+ sub_message = reflection->AddMessage(message, F("map_sint32_sint32"));
+ sub_message->GetReflection()->SetInt32(sub_message, map_sint32_sint32_key_,
+ 0);
+ sub_message->GetReflection()->SetInt32(sub_message, map_sint32_sint32_val_,
+ 0);
+
+ sub_message = reflection->AddMessage(message, F("map_sint64_sint64"));
+ sub_message->GetReflection()->SetInt64(sub_message, map_sint64_sint64_key_,
+ 0);
+ sub_message->GetReflection()->SetInt64(sub_message, map_sint64_sint64_val_,
+ 0);
+
+ sub_message = reflection->AddMessage(message, F("map_fixed32_fixed32"));
+ sub_message->GetReflection()->SetUInt32(sub_message, map_fixed32_fixed32_key_,
+ 0);
+ sub_message->GetReflection()->SetUInt32(sub_message, map_fixed32_fixed32_val_,
+ 0);
+
+ sub_message = reflection->AddMessage(message, F("map_fixed64_fixed64"));
+ sub_message->GetReflection()->SetUInt64(sub_message, map_fixed64_fixed64_key_,
+ 0);
+ sub_message->GetReflection()->SetUInt64(sub_message, map_fixed64_fixed64_val_,
+ 0);
+
+ sub_message = reflection->AddMessage(message, F("map_sfixed32_sfixed32"));
+ sub_message->GetReflection()->SetInt32(sub_message,
+ map_sfixed32_sfixed32_key_, 0);
+ sub_message->GetReflection()->SetInt32(sub_message,
+ map_sfixed32_sfixed32_val_, 0);
+
+ sub_message = reflection->AddMessage(message, F("map_sfixed64_sfixed64"));
+ sub_message->GetReflection()->SetInt64(sub_message,
+ map_sfixed64_sfixed64_key_, 0);
+ sub_message->GetReflection()->SetInt64(sub_message,
+ map_sfixed64_sfixed64_val_, 0);
+
+ sub_message = reflection->AddMessage(message, F("map_int32_float"));
+ sub_message->GetReflection()->SetInt32(sub_message, map_int32_float_key_, 0);
+ sub_message->GetReflection()->SetFloat(sub_message, map_int32_float_val_,
+ 0.0);
+
+ sub_message = reflection->AddMessage(message, F("map_int32_double"));
+ sub_message->GetReflection()->SetInt32(sub_message, map_int32_double_key_, 0);
+ sub_message->GetReflection()->SetDouble(sub_message, map_int32_double_val_,
+ 0.0);
+
+ sub_message = reflection->AddMessage(message, F("map_bool_bool"));
+ sub_message->GetReflection()->SetBool(sub_message, map_bool_bool_key_, false);
+ sub_message->GetReflection()->SetBool(sub_message, map_bool_bool_val_, false);
+
+ sub_message = reflection->AddMessage(message, F("map_string_string"));
+ sub_message->GetReflection()->SetString(sub_message, map_string_string_key_,
+ "0");
+ sub_message->GetReflection()->SetString(sub_message, map_string_string_val_,
+ "0");
+
+ sub_message = reflection->AddMessage(message, F("map_int32_bytes"));
+ sub_message->GetReflection()->SetInt32(sub_message, map_int32_bytes_key_, 0);
+ sub_message->GetReflection()->SetString(sub_message, map_int32_bytes_val_,
+ "0");
+
+ sub_message = reflection->AddMessage(message, F("map_int32_enum"));
+ sub_message->GetReflection()->SetInt32(sub_message, map_int32_enum_key_, 0);
+ sub_message->GetReflection()->SetEnum(sub_message, map_int32_enum_val_,
+ map_enum_bar_);
+
+ sub_message = reflection->AddMessage(message, F("map_int32_foreign_message"));
+ sub_message->GetReflection()->SetInt32(sub_message,
+ map_int32_foreign_message_key_, 0);
+ sub_foreign_message = sub_message->GetReflection()->MutableMessage(
+ sub_message, map_int32_foreign_message_val_, nullptr);
+ sub_foreign_message->GetReflection()->SetInt32(sub_foreign_message,
+ foreign_c_, 0);
+
+ // Add second element
+ sub_message = reflection->AddMessage(message, F("map_int32_int32"));
+ sub_message->GetReflection()->SetInt32(sub_message, map_int32_int32_key_, 1);
+ sub_message->GetReflection()->SetInt32(sub_message, map_int32_int32_val_, 1);
+
+ sub_message = reflection->AddMessage(message, F("map_int64_int64"));
+ sub_message->GetReflection()->SetInt64(sub_message, map_int64_int64_key_, 1);
+ sub_message->GetReflection()->SetInt64(sub_message, map_int64_int64_val_, 1);
+
+ sub_message = reflection->AddMessage(message, F("map_uint32_uint32"));
+ sub_message->GetReflection()->SetUInt32(sub_message, map_uint32_uint32_key_,
+ 1);
+ sub_message->GetReflection()->SetUInt32(sub_message, map_uint32_uint32_val_,
+ 1);
+
+ sub_message = reflection->AddMessage(message, F("map_uint64_uint64"));
+ sub_message->GetReflection()->SetUInt64(sub_message, map_uint64_uint64_key_,
+ 1);
+ sub_message->GetReflection()->SetUInt64(sub_message, map_uint64_uint64_val_,
+ 1);
+
+ sub_message = reflection->AddMessage(message, F("map_sint32_sint32"));
+ sub_message->GetReflection()->SetInt32(sub_message, map_sint32_sint32_key_,
+ 1);
+ sub_message->GetReflection()->SetInt32(sub_message, map_sint32_sint32_val_,
+ 1);
+
+ sub_message = reflection->AddMessage(message, F("map_sint64_sint64"));
+ sub_message->GetReflection()->SetInt64(sub_message, map_sint64_sint64_key_,
+ 1);
+ sub_message->GetReflection()->SetInt64(sub_message, map_sint64_sint64_val_,
+ 1);
+
+ sub_message = reflection->AddMessage(message, F("map_fixed32_fixed32"));
+ sub_message->GetReflection()->SetUInt32(sub_message, map_fixed32_fixed32_key_,
+ 1);
+ sub_message->GetReflection()->SetUInt32(sub_message, map_fixed32_fixed32_val_,
+ 1);
+
+ sub_message = reflection->AddMessage(message, F("map_fixed64_fixed64"));
+ sub_message->GetReflection()->SetUInt64(sub_message, map_fixed64_fixed64_key_,
+ 1);
+ sub_message->GetReflection()->SetUInt64(sub_message, map_fixed64_fixed64_val_,
+ 1);
+
+ sub_message = reflection->AddMessage(message, F("map_sfixed32_sfixed32"));
+ sub_message->GetReflection()->SetInt32(sub_message,
+ map_sfixed32_sfixed32_key_, 1);
+ sub_message->GetReflection()->SetInt32(sub_message,
+ map_sfixed32_sfixed32_val_, 1);
+
+ sub_message = reflection->AddMessage(message, F("map_sfixed64_sfixed64"));
+ sub_message->GetReflection()->SetInt64(sub_message,
+ map_sfixed64_sfixed64_key_, 1);
+ sub_message->GetReflection()->SetInt64(sub_message,
+ map_sfixed64_sfixed64_val_, 1);
+
+ sub_message = reflection->AddMessage(message, F("map_int32_float"));
+ sub_message->GetReflection()->SetInt32(sub_message, map_int32_float_key_, 1);
+ sub_message->GetReflection()->SetFloat(sub_message, map_int32_float_val_,
+ 1.0);
+
+ sub_message = reflection->AddMessage(message, F("map_int32_double"));
+ sub_message->GetReflection()->SetInt32(sub_message, map_int32_double_key_, 1);
+ sub_message->GetReflection()->SetDouble(sub_message, map_int32_double_val_,
+ 1.0);
+
+ sub_message = reflection->AddMessage(message, F("map_bool_bool"));
+ sub_message->GetReflection()->SetBool(sub_message, map_bool_bool_key_, true);
+ sub_message->GetReflection()->SetBool(sub_message, map_bool_bool_val_, true);
+
+ sub_message = reflection->AddMessage(message, F("map_string_string"));
+ sub_message->GetReflection()->SetString(sub_message, map_string_string_key_,
+ "1");
+ sub_message->GetReflection()->SetString(sub_message, map_string_string_val_,
+ "1");
+
+ sub_message = reflection->AddMessage(message, F("map_int32_bytes"));
+ sub_message->GetReflection()->SetInt32(sub_message, map_int32_bytes_key_, 1);
+ sub_message->GetReflection()->SetString(sub_message, map_int32_bytes_val_,
+ "1");
+
+ sub_message = reflection->AddMessage(message, F("map_int32_enum"));
+ sub_message->GetReflection()->SetInt32(sub_message, map_int32_enum_key_, 1);
+ sub_message->GetReflection()->SetEnum(sub_message, map_int32_enum_val_,
+ map_enum_baz_);
+
+ sub_message = reflection->AddMessage(message, F("map_int32_foreign_message"));
+ sub_message->GetReflection()->SetInt32(sub_message,
+ map_int32_foreign_message_key_, 1);
+ sub_foreign_message = sub_message->GetReflection()->MutableMessage(
+ sub_message, map_int32_foreign_message_val_, nullptr);
+ sub_foreign_message->GetReflection()->SetInt32(sub_foreign_message,
+ foreign_c_, 1);
+}
+
+void MapReflectionTester::SetMapFieldsViaMapReflection(Message* message) {
+ const Reflection* reflection = message->GetReflection();
+
+ Message* sub_foreign_message = nullptr;
+ MapValueRef map_val;
+ MapValueConstRef map_val_const;
+
+ // Add first element.
+ MapKey map_key;
+ map_key.SetInt32Value(0);
+ EXPECT_FALSE(reflection->LookupMapValue(*message, F("map_int32_int32"),
+ map_key, &map_val_const));
+ EXPECT_TRUE(reflection->InsertOrLookupMapValue(message, F("map_int32_int32"),
+ map_key, &map_val));
+ map_val.SetInt32Value(0);
+
+ map_key.SetInt64Value(0);
+ EXPECT_FALSE(reflection->LookupMapValue(*message, F("map_int64_int64"),
+ map_key, &map_val_const));
+ EXPECT_TRUE(reflection->InsertOrLookupMapValue(message, F("map_int64_int64"),
+ map_key, &map_val));
+ map_val.SetInt64Value(0);
+
+ map_key.SetUInt32Value(0);
+ EXPECT_FALSE(reflection->LookupMapValue(*message, F("map_uint32_uint32"),
+ map_key, &map_val_const));
+ EXPECT_TRUE(reflection->InsertOrLookupMapValue(
+ message, F("map_uint32_uint32"), map_key, &map_val));
+ map_val.SetUInt32Value(0);
+
+ map_key.SetUInt64Value(0);
+ EXPECT_TRUE(reflection->InsertOrLookupMapValue(
+ message, F("map_uint64_uint64"), map_key, &map_val));
+ map_val.SetUInt64Value(0);
+
+ map_key.SetInt32Value(0);
+ EXPECT_TRUE(reflection->InsertOrLookupMapValue(
+ message, F("map_sint32_sint32"), map_key, &map_val));
+ map_val.SetInt32Value(0);
+
+ map_key.SetInt64Value(0);
+ EXPECT_TRUE(reflection->InsertOrLookupMapValue(
+ message, F("map_sint64_sint64"), map_key, &map_val));
+ map_val.SetInt64Value(0);
+
+ map_key.SetUInt32Value(0);
+ EXPECT_TRUE(reflection->InsertOrLookupMapValue(
+ message, F("map_fixed32_fixed32"), map_key, &map_val));
+ map_val.SetUInt32Value(0);
+
+ map_key.SetUInt64Value(0);
+ EXPECT_TRUE(reflection->InsertOrLookupMapValue(
+ message, F("map_fixed64_fixed64"), map_key, &map_val));
+ map_val.SetUInt64Value(0);
+
+ map_key.SetInt32Value(0);
+ EXPECT_TRUE(reflection->InsertOrLookupMapValue(
+ message, F("map_sfixed32_sfixed32"), map_key, &map_val));
+ map_val.SetInt32Value(0);
+
+ map_key.SetInt64Value(0);
+ EXPECT_TRUE(reflection->InsertOrLookupMapValue(
+ message, F("map_sfixed64_sfixed64"), map_key, &map_val));
+ map_val.SetInt64Value(0);
+
+ map_key.SetInt32Value(0);
+ EXPECT_TRUE(reflection->InsertOrLookupMapValue(message, F("map_int32_float"),
+ map_key, &map_val));
+ map_val.SetFloatValue(0.0);
+
+ map_key.SetInt32Value(0);
+ EXPECT_TRUE(reflection->InsertOrLookupMapValue(message, F("map_int32_double"),
+ map_key, &map_val));
+ map_val.SetDoubleValue(0.0);
+
+ map_key.SetBoolValue(false);
+ EXPECT_FALSE(reflection->LookupMapValue(*message, F("map_bool_bool"), map_key,
+ &map_val_const));
+ EXPECT_TRUE(reflection->InsertOrLookupMapValue(message, F("map_bool_bool"),
+ map_key, &map_val));
+ map_val.SetBoolValue(false);
+
+ map_key.SetStringValue("0");
+ EXPECT_FALSE(reflection->LookupMapValue(*message, F("map_string_string"),
+ map_key, &map_val_const));
+ EXPECT_TRUE(reflection->InsertOrLookupMapValue(
+ message, F("map_string_string"), map_key, &map_val));
+ map_val.SetStringValue("0");
+
+ map_key.SetInt32Value(0);
+ EXPECT_FALSE(reflection->LookupMapValue(*message, F("map_int32_bytes"),
+ map_key, &map_val_const));
+ EXPECT_TRUE(reflection->InsertOrLookupMapValue(message, F("map_int32_bytes"),
+ map_key, &map_val));
+ map_val.SetStringValue("0");
+
+ map_key.SetInt32Value(0);
+ EXPECT_FALSE(reflection->LookupMapValue(*message, F("map_int32_enum"),
+ map_key, &map_val_const));
+ EXPECT_TRUE(reflection->InsertOrLookupMapValue(message, F("map_int32_enum"),
+ map_key, &map_val));
+ map_val.SetEnumValue(map_enum_bar_->number());
+
+ map_key.SetInt32Value(0);
+ EXPECT_FALSE(reflection->LookupMapValue(
+ *message, F("map_int32_foreign_message"), map_key, &map_val_const));
+ EXPECT_TRUE(reflection->InsertOrLookupMapValue(
+ message, F("map_int32_foreign_message"), map_key, &map_val));
+ sub_foreign_message = map_val.MutableMessageValue();
+ sub_foreign_message->GetReflection()->SetInt32(sub_foreign_message,
+ foreign_c_, 0);
+
+ // Add second element
+ map_key.SetInt32Value(1);
+ EXPECT_TRUE(reflection->InsertOrLookupMapValue(message, F("map_int32_int32"),
+ map_key, &map_val));
+ map_val.SetInt32Value(1);
+ EXPECT_FALSE(reflection->InsertOrLookupMapValue(message, F("map_int32_int32"),
+ map_key, &map_val));
+
+ map_key.SetInt64Value(1);
+ EXPECT_TRUE(reflection->InsertOrLookupMapValue(message, F("map_int64_int64"),
+ map_key, &map_val));
+ map_val.SetInt64Value(1);
+ EXPECT_FALSE(reflection->InsertOrLookupMapValue(message, F("map_int64_int64"),
+ map_key, &map_val));
+
+ map_key.SetUInt32Value(1);
+ reflection->InsertOrLookupMapValue(message, F("map_uint32_uint32"), map_key,
+ &map_val);
+ map_val.SetUInt32Value(1);
+
+ map_key.SetUInt64Value(1);
+ reflection->InsertOrLookupMapValue(message, F("map_uint64_uint64"), map_key,
+ &map_val);
+ map_val.SetUInt64Value(1);
+
+ map_key.SetInt32Value(1);
+ reflection->InsertOrLookupMapValue(message, F("map_sint32_sint32"), map_key,
+ &map_val);
+ map_val.SetInt32Value(1);
+
+ map_key.SetInt64Value(1);
+ reflection->InsertOrLookupMapValue(message, F("map_sint64_sint64"), map_key,
+ &map_val);
+ map_val.SetInt64Value(1);
+
+ map_key.SetUInt32Value(1);
+ reflection->InsertOrLookupMapValue(message, F("map_fixed32_fixed32"), map_key,
+ &map_val);
+ map_val.SetUInt32Value(1);
+
+ map_key.SetUInt64Value(1);
+ reflection->InsertOrLookupMapValue(message, F("map_fixed64_fixed64"), map_key,
+ &map_val);
+ map_val.SetUInt64Value(1);
+
+ map_key.SetInt32Value(1);
+ reflection->InsertOrLookupMapValue(message, F("map_sfixed32_sfixed32"),
+ map_key, &map_val);
+ map_val.SetInt32Value(1);
+
+ map_key.SetInt64Value(1);
+ reflection->InsertOrLookupMapValue(message, F("map_sfixed64_sfixed64"),
+ map_key, &map_val);
+ map_val.SetInt64Value(1);
+
+ map_key.SetInt32Value(1);
+ reflection->InsertOrLookupMapValue(message, F("map_int32_float"), map_key,
+ &map_val);
+ map_val.SetFloatValue(1.0);
+
+ map_key.SetInt32Value(1);
+ reflection->InsertOrLookupMapValue(message, F("map_int32_double"), map_key,
+ &map_val);
+ map_val.SetDoubleValue(1.0);
+
+ map_key.SetBoolValue(true);
+ reflection->InsertOrLookupMapValue(message, F("map_bool_bool"), map_key,
+ &map_val);
+ map_val.SetBoolValue(true);
+
+ map_key.SetStringValue("1");
+ reflection->InsertOrLookupMapValue(message, F("map_string_string"), map_key,
+ &map_val);
+ map_val.SetStringValue("1");
+
+ map_key.SetInt32Value(1);
+ reflection->InsertOrLookupMapValue(message, F("map_int32_bytes"), map_key,
+ &map_val);
+ map_val.SetStringValue("1");
+
+ map_key.SetInt32Value(1);
+ reflection->InsertOrLookupMapValue(message, F("map_int32_enum"), map_key,
+ &map_val);
+ map_val.SetEnumValue(map_enum_baz_->number());
+
+ map_key.SetInt32Value(1);
+ EXPECT_TRUE(reflection->InsertOrLookupMapValue(
+ message, F("map_int32_foreign_message"), map_key, &map_val));
+ sub_foreign_message = map_val.MutableMessageValue();
+ sub_foreign_message->GetReflection()->SetInt32(sub_foreign_message,
+ foreign_c_, 1);
+}
+
+void MapReflectionTester::GetMapValueViaMapReflection(
+ Message* message, const std::string& field_name, const MapKey& map_key,
+ MapValueRef* map_val) {
+ const Reflection* reflection = message->GetReflection();
+ EXPECT_FALSE(reflection->InsertOrLookupMapValue(message, F(field_name),
+ map_key, map_val));
+}
+
+Message* MapReflectionTester::GetMapEntryViaReflection(
+ Message* message, const std::string& field_name, int index) {
+ const Reflection* reflection = message->GetReflection();
+ return reflection->MutableRepeatedMessage(message, F(field_name), index);
+}
+
+MapIterator MapReflectionTester::MapBegin(Message* message,
+ const std::string& field_name) {
+ const Reflection* reflection = message->GetReflection();
+ return reflection->MapBegin(message, F(field_name));
+}
+
+MapIterator MapReflectionTester::MapEnd(Message* message,
+ const std::string& field_name) {
+ const Reflection* reflection = message->GetReflection();
+ return reflection->MapEnd(message, F(field_name));
+}
+
+int MapReflectionTester::MapSize(const Message& message,
+ const std::string& field_name) {
+ const Reflection* reflection = message.GetReflection();
+ return reflection->MapSize(message, F(field_name));
+}
+
+void MapReflectionTester::ClearMapFieldsViaReflection(Message* message) {
+ const Reflection* reflection = message->GetReflection();
+
+ reflection->ClearField(message, F("map_int32_int32"));
+ reflection->ClearField(message, F("map_int64_int64"));
+ reflection->ClearField(message, F("map_uint32_uint32"));
+ reflection->ClearField(message, F("map_uint64_uint64"));
+ reflection->ClearField(message, F("map_sint32_sint32"));
+ reflection->ClearField(message, F("map_sint64_sint64"));
+ reflection->ClearField(message, F("map_fixed32_fixed32"));
+ reflection->ClearField(message, F("map_fixed64_fixed64"));
+ reflection->ClearField(message, F("map_sfixed32_sfixed32"));
+ reflection->ClearField(message, F("map_sfixed64_sfixed64"));
+ reflection->ClearField(message, F("map_int32_float"));
+ reflection->ClearField(message, F("map_int32_double"));
+ reflection->ClearField(message, F("map_bool_bool"));
+ reflection->ClearField(message, F("map_string_string"));
+ reflection->ClearField(message, F("map_int32_bytes"));
+ reflection->ClearField(message, F("map_int32_enum"));
+ reflection->ClearField(message, F("map_int32_foreign_message"));
+}
+
+void MapReflectionTester::ModifyMapFieldsViaReflection(Message* message) {
+ const Reflection* reflection = message->GetReflection();
+ MapValueRef map_val;
+ Message* sub_foreign_message;
+
+ // Modify the second element
+ MapKey map_key;
+ map_key.SetInt32Value(1);
+ EXPECT_FALSE(reflection->InsertOrLookupMapValue(message, F("map_int32_int32"),
+ map_key, &map_val));
+ map_val.SetInt32Value(2);
+
+ map_key.SetInt64Value(1);
+ EXPECT_FALSE(reflection->InsertOrLookupMapValue(message, F("map_int64_int64"),
+ map_key, &map_val));
+ map_val.SetInt64Value(2);
+
+ map_key.SetUInt32Value(1);
+ EXPECT_FALSE(reflection->InsertOrLookupMapValue(
+ message, F("map_uint32_uint32"), map_key, &map_val));
+ map_val.SetUInt32Value(2);
+
+ map_key.SetUInt64Value(1);
+ reflection->InsertOrLookupMapValue(message, F("map_uint64_uint64"), map_key,
+ &map_val);
+ map_val.SetUInt64Value(2);
+
+ map_key.SetInt32Value(1);
+ reflection->InsertOrLookupMapValue(message, F("map_sint32_sint32"), map_key,
+ &map_val);
+ map_val.SetInt32Value(2);
+
+ map_key.SetInt64Value(1);
+ reflection->InsertOrLookupMapValue(message, F("map_sint64_sint64"), map_key,
+ &map_val);
+ map_val.SetInt64Value(2);
+
+ map_key.SetUInt32Value(1);
+ reflection->InsertOrLookupMapValue(message, F("map_fixed32_fixed32"), map_key,
+ &map_val);
+ map_val.SetUInt32Value(2);
+
+ map_key.SetUInt64Value(1);
+ reflection->InsertOrLookupMapValue(message, F("map_fixed64_fixed64"), map_key,
+ &map_val);
+ map_val.SetUInt64Value(2);
+
+ map_key.SetInt32Value(1);
+ reflection->InsertOrLookupMapValue(message, F("map_sfixed32_sfixed32"),
+ map_key, &map_val);
+ map_val.SetInt32Value(2);
+
+ map_key.SetInt64Value(1);
+ reflection->InsertOrLookupMapValue(message, F("map_sfixed64_sfixed64"),
+ map_key, &map_val);
+ map_val.SetInt64Value(2);
+
+ map_key.SetInt32Value(1);
+ reflection->InsertOrLookupMapValue(message, F("map_int32_float"), map_key,
+ &map_val);
+ map_val.SetFloatValue(2.0);
+
+ map_key.SetInt32Value(1);
+ reflection->InsertOrLookupMapValue(message, F("map_int32_double"), map_key,
+ &map_val);
+ map_val.SetDoubleValue(2.0);
+
+ map_key.SetBoolValue(true);
+ reflection->InsertOrLookupMapValue(message, F("map_bool_bool"), map_key,
+ &map_val);
+ map_val.SetBoolValue(false);
+
+ map_key.SetStringValue("1");
+ reflection->InsertOrLookupMapValue(message, F("map_string_string"), map_key,
+ &map_val);
+ map_val.SetStringValue("2");
+
+ map_key.SetInt32Value(1);
+ reflection->InsertOrLookupMapValue(message, F("map_int32_bytes"), map_key,
+ &map_val);
+ map_val.SetStringValue("2");
+
+ map_key.SetInt32Value(1);
+ reflection->InsertOrLookupMapValue(message, F("map_int32_enum"), map_key,
+ &map_val);
+ map_val.SetEnumValue(map_enum_foo_->number());
+
+ map_key.SetInt32Value(1);
+ EXPECT_FALSE(reflection->InsertOrLookupMapValue(
+ message, F("map_int32_foreign_message"), map_key, &map_val));
+ sub_foreign_message = map_val.MutableMessageValue();
+ sub_foreign_message->GetReflection()->SetInt32(sub_foreign_message,
+ foreign_c_, 2);
+}
+
+void MapReflectionTester::RemoveLastMapsViaReflection(Message* message) {
+ const Reflection* reflection = message->GetReflection();
+
+ std::vector<const FieldDescriptor*> output;
+ reflection->ListFields(*message, &output);
+ for (int i = 0; i < output.size(); ++i) {
+ const FieldDescriptor* field = output[i];
+ if (!field->is_repeated()) continue;
+ reflection->RemoveLast(message, field);
+ }
+}
+
+void MapReflectionTester::ReleaseLastMapsViaReflection(Message* message) {
+ const Reflection* reflection = message->GetReflection();
+
+ std::vector<const FieldDescriptor*> output;
+ reflection->ListFields(*message, &output);
+ for (int i = 0; i < output.size(); ++i) {
+ const FieldDescriptor* field = output[i];
+ if (!field->is_repeated()) continue;
+ if (field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) continue;
+
+ Message* released = reflection->ReleaseLast(message, field);
+ ASSERT_TRUE(released != nullptr)
+ << "ReleaseLast returned nullptr for: " << field->name();
+ delete released;
+ }
+}
+
+void MapReflectionTester::SwapMapsViaReflection(Message* message) {
+ const Reflection* reflection = message->GetReflection();
+ std::vector<const FieldDescriptor*> output;
+ reflection->ListFields(*message, &output);
+ for (int i = 0; i < output.size(); ++i) {
+ const FieldDescriptor* field = output[i];
+ if (!field->is_repeated()) continue;
+ reflection->SwapElements(message, field, 0, 1);
+ }
+}
+
+void MapReflectionTester::MutableUnknownFieldsOfMapFieldsViaReflection(
+ Message* message) {
+ const Reflection* reflection = message->GetReflection();
+ Message* sub_message = nullptr;
+
+ sub_message = reflection->AddMessage(message, F("map_int32_int32"));
+ EXPECT_TRUE(sub_message->GetReflection()->MutableUnknownFields(sub_message) !=
+ nullptr);
+ sub_message = reflection->AddMessage(message, F("map_int64_int64"));
+ EXPECT_TRUE(sub_message->GetReflection()->MutableUnknownFields(sub_message) !=
+ nullptr);
+ sub_message = reflection->AddMessage(message, F("map_uint32_uint32"));
+ EXPECT_TRUE(sub_message->GetReflection()->MutableUnknownFields(sub_message) !=
+ nullptr);
+ sub_message = reflection->AddMessage(message, F("map_uint64_uint64"));
+ EXPECT_TRUE(sub_message->GetReflection()->MutableUnknownFields(sub_message) !=
+ nullptr);
+ sub_message = reflection->AddMessage(message, F("map_sint32_sint32"));
+ EXPECT_TRUE(sub_message->GetReflection()->MutableUnknownFields(sub_message) !=
+ nullptr);
+ sub_message = reflection->AddMessage(message, F("map_sint64_sint64"));
+ EXPECT_TRUE(sub_message->GetReflection()->MutableUnknownFields(sub_message) !=
+ nullptr);
+ sub_message = reflection->AddMessage(message, F("map_fixed32_fixed32"));
+ EXPECT_TRUE(sub_message->GetReflection()->MutableUnknownFields(sub_message) !=
+ nullptr);
+ sub_message = reflection->AddMessage(message, F("map_fixed64_fixed64"));
+ EXPECT_TRUE(sub_message->GetReflection()->MutableUnknownFields(sub_message) !=
+ nullptr);
+ sub_message = reflection->AddMessage(message, F("map_sfixed32_sfixed32"));
+ EXPECT_TRUE(sub_message->GetReflection()->MutableUnknownFields(sub_message) !=
+ nullptr);
+ sub_message = reflection->AddMessage(message, F("map_sfixed64_sfixed64"));
+ EXPECT_TRUE(sub_message->GetReflection()->MutableUnknownFields(sub_message) !=
+ nullptr);
+ sub_message = reflection->AddMessage(message, F("map_int32_float"));
+ EXPECT_TRUE(sub_message->GetReflection()->MutableUnknownFields(sub_message) !=
+ nullptr);
+ sub_message = reflection->AddMessage(message, F("map_int32_double"));
+ EXPECT_TRUE(sub_message->GetReflection()->MutableUnknownFields(sub_message) !=
+ nullptr);
+ sub_message = reflection->AddMessage(message, F("map_bool_bool"));
+ EXPECT_TRUE(sub_message->GetReflection()->MutableUnknownFields(sub_message) !=
+ nullptr);
+ sub_message = reflection->AddMessage(message, F("map_string_string"));
+ EXPECT_TRUE(sub_message->GetReflection()->MutableUnknownFields(sub_message) !=
+ nullptr);
+ sub_message = reflection->AddMessage(message, F("map_int32_bytes"));
+ EXPECT_TRUE(sub_message->GetReflection()->MutableUnknownFields(sub_message) !=
+ nullptr);
+ sub_message = reflection->AddMessage(message, F("map_int32_enum"));
+ EXPECT_TRUE(sub_message->GetReflection()->MutableUnknownFields(sub_message) !=
+ nullptr);
+ sub_message = reflection->AddMessage(message, F("map_int32_foreign_message"));
+ EXPECT_TRUE(sub_message->GetReflection()->MutableUnknownFields(sub_message) !=
+ nullptr);
+}
+
+void MapReflectionTester::ExpectMapFieldsSetViaReflection(
+ const Message& message) {
+ std::string scratch;
+ const Reflection* reflection = message.GetReflection();
+ const Message* sub_message;
+ MapKey map_key;
+ MapValueConstRef map_value_const_ref;
+
+ // -----------------------------------------------------------------
+
+ ASSERT_EQ(2, reflection->FieldSize(message, F("map_int32_int32")));
+ ASSERT_EQ(2, reflection->FieldSize(message, F("map_int64_int64")));
+ ASSERT_EQ(2, reflection->FieldSize(message, F("map_uint32_uint32")));
+ ASSERT_EQ(2, reflection->FieldSize(message, F("map_uint64_uint64")));
+ ASSERT_EQ(2, reflection->FieldSize(message, F("map_sint32_sint32")));
+ ASSERT_EQ(2, reflection->FieldSize(message, F("map_sint64_sint64")));
+ ASSERT_EQ(2, reflection->FieldSize(message, F("map_fixed32_fixed32")));
+ ASSERT_EQ(2, reflection->FieldSize(message, F("map_fixed64_fixed64")));
+ ASSERT_EQ(2, reflection->FieldSize(message, F("map_sfixed32_sfixed32")));
+ ASSERT_EQ(2, reflection->FieldSize(message, F("map_sfixed64_sfixed64")));
+ ASSERT_EQ(2, reflection->FieldSize(message, F("map_int32_float")));
+ ASSERT_EQ(2, reflection->FieldSize(message, F("map_int32_double")));
+ ASSERT_EQ(2, reflection->FieldSize(message, F("map_bool_bool")));
+ ASSERT_EQ(2, reflection->FieldSize(message, F("map_string_string")));
+ ASSERT_EQ(2, reflection->FieldSize(message, F("map_int32_bytes")));
+ ASSERT_EQ(2, reflection->FieldSize(message, F("map_int32_enum")));
+ ASSERT_EQ(2, reflection->FieldSize(message, F("map_int32_foreign_message")));
+
+ {
+ std::map<int32_t, int32_t> map;
+ map[0] = 0;
+ map[1] = 1;
+ for (int i = 0; i < 2; i++) {
+ const internal::MapFieldBase& map_field =
+ reflection->GetRaw<internal::MapFieldBase>(message,
+ F("map_int32_int32"));
+ if (map_field.IsRepeatedFieldValid()) {
+ // Check with RepeatedField Reflection
+ sub_message =
+ &reflection->GetRepeatedMessage(message, F("map_int32_int32"), i);
+ int32_t key = sub_message->GetReflection()->GetInt32(
+ *sub_message, map_int32_int32_key_);
+ int32_t val = sub_message->GetReflection()->GetInt32(
+ *sub_message, map_int32_int32_val_);
+ EXPECT_EQ(map[key], val);
+ } else {
+ // Check with Map Reflection
+ map_key.SetInt32Value(i);
+ EXPECT_TRUE(
+ reflection->ContainsMapKey(message, F("map_int32_int32"), map_key));
+ EXPECT_TRUE(reflection->LookupMapValue(message, F("map_int32_int32"),
+ map_key, &map_value_const_ref));
+ EXPECT_EQ(map_value_const_ref.GetInt32Value(), map[i]);
+ }
+ }
+ }
+ {
+ std::map<int64_t, int64_t> map;
+ map[0] = 0;
+ map[1] = 1;
+ for (int i = 0; i < 2; i++) {
+ const internal::MapFieldBase& map_field =
+ reflection->GetRaw<internal::MapFieldBase>(message,
+ F("map_int64_int64"));
+ if (map_field.IsRepeatedFieldValid()) {
+ // Check with RepeatedField Reflection
+ sub_message =
+ &reflection->GetRepeatedMessage(message, F("map_int64_int64"), i);
+ int64_t key = sub_message->GetReflection()->GetInt64(
+ *sub_message, map_int64_int64_key_);
+ int64_t val = sub_message->GetReflection()->GetInt64(
+ *sub_message, map_int64_int64_val_);
+ EXPECT_EQ(map[key], val);
+ } else {
+ // Check with Map Reflection
+ map_key.SetInt64Value(i);
+ EXPECT_TRUE(
+ reflection->ContainsMapKey(message, F("map_int64_int64"), map_key));
+ EXPECT_TRUE(reflection->LookupMapValue(message, F("map_int64_int64"),
+ map_key, &map_value_const_ref));
+ EXPECT_EQ(map_value_const_ref.GetInt64Value(), map[i]);
+ }
+ }
+ }
+ {
+ std::map<uint32_t, uint32_t> map;
+ map[0] = 0;
+ map[1] = 1;
+ for (int i = 0; i < 2; i++) {
+ const internal::MapFieldBase& map_field =
+ reflection->GetRaw<internal::MapFieldBase>(message,
+ F("map_uint32_uint32"));
+ if (map_field.IsRepeatedFieldValid()) {
+ // Check with RepeatedField Reflection
+ sub_message =
+ &reflection->GetRepeatedMessage(message, F("map_uint32_uint32"), i);
+ uint32_t key = sub_message->GetReflection()->GetUInt32(
+ *sub_message, map_uint32_uint32_key_);
+ uint32_t val = sub_message->GetReflection()->GetUInt32(
+ *sub_message, map_uint32_uint32_val_);
+ EXPECT_EQ(map[key], val);
+ } else {
+ // Check with Map Reflection
+ map_key.SetUInt32Value(i);
+ EXPECT_TRUE(reflection->ContainsMapKey(message, F("map_uint32_uint32"),
+ map_key));
+ EXPECT_TRUE(reflection->LookupMapValue(message, F("map_uint32_uint32"),
+ map_key, &map_value_const_ref));
+ EXPECT_EQ(map_value_const_ref.GetUInt32Value(), map[i]);
+ }
+ }
+ }
+ {
+ std::map<uint64_t, uint64_t> map;
+ map[0] = 0;
+ map[1] = 1;
+ for (int i = 0; i < 2; i++) {
+ const internal::MapFieldBase& map_field =
+ reflection->GetRaw<internal::MapFieldBase>(message,
+ F("map_uint64_uint64"));
+ if (map_field.IsRepeatedFieldValid()) {
+ // Check with RepeatedField Reflection
+ sub_message =
+ &reflection->GetRepeatedMessage(message, F("map_uint64_uint64"), i);
+ uint64_t key = sub_message->GetReflection()->GetUInt64(
+ *sub_message, map_uint64_uint64_key_);
+ uint64_t val = sub_message->GetReflection()->GetUInt64(
+ *sub_message, map_uint64_uint64_val_);
+ EXPECT_EQ(map[key], val);
+ } else {
+ // Check with Map Reflection
+ map_key.SetUInt64Value(i);
+ EXPECT_TRUE(reflection->ContainsMapKey(message, F("map_uint64_uint64"),
+ map_key));
+ EXPECT_TRUE(reflection->LookupMapValue(message, F("map_uint64_uint64"),
+ map_key, &map_value_const_ref));
+ EXPECT_EQ(map_value_const_ref.GetUInt64Value(), map[i]);
+ }
+ }
+ }
+ {
+ std::map<int32_t, int32_t> map;
+ map[0] = 0;
+ map[1] = 1;
+ for (int i = 0; i < 2; i++) {
+ const internal::MapFieldBase& map_field =
+ reflection->GetRaw<internal::MapFieldBase>(message,
+ F("map_sint32_sint32"));
+ if (map_field.IsRepeatedFieldValid()) {
+ // Check with RepeatedField Reflection
+ sub_message =
+ &reflection->GetRepeatedMessage(message, F("map_sint32_sint32"), i);
+ int32_t key = sub_message->GetReflection()->GetInt32(
+ *sub_message, map_sint32_sint32_key_);
+ int32_t val = sub_message->GetReflection()->GetInt32(
+ *sub_message, map_sint32_sint32_val_);
+ EXPECT_EQ(map[key], val);
+ } else {
+ // Check with Map Reflection
+ map_key.SetInt32Value(i);
+ EXPECT_EQ(true, reflection->ContainsMapKey(
+ message, F("map_sint32_sint32"), map_key));
+ EXPECT_TRUE(reflection->LookupMapValue(message, F("map_sint32_sint32"),
+ map_key, &map_value_const_ref));
+ EXPECT_EQ(map_value_const_ref.GetInt32Value(), map[i]);
+ }
+ }
+ }
+ {
+ std::map<int64_t, int64_t> map;
+ map[0] = 0;
+ map[1] = 1;
+ for (int i = 0; i < 2; i++) {
+ const internal::MapFieldBase& map_field =
+ reflection->GetRaw<internal::MapFieldBase>(message,
+ F("map_sint64_sint64"));
+ if (map_field.IsRepeatedFieldValid()) {
+ // Check with RepeatedField Reflection
+ sub_message =
+ &reflection->GetRepeatedMessage(message, F("map_sint64_sint64"), i);
+ int64_t key = sub_message->GetReflection()->GetInt64(
+ *sub_message, map_sint64_sint64_key_);
+ int64_t val = sub_message->GetReflection()->GetInt64(
+ *sub_message, map_sint64_sint64_val_);
+ EXPECT_EQ(map[key], val);
+ } else {
+ // Check with Map Reflection
+ map_key.SetInt64Value(i);
+ EXPECT_EQ(true, reflection->ContainsMapKey(
+ message, F("map_sint64_sint64"), map_key));
+ EXPECT_TRUE(reflection->LookupMapValue(message, F("map_sint64_sint64"),
+ map_key, &map_value_const_ref));
+ EXPECT_EQ(map_value_const_ref.GetInt64Value(), map[i]);
+ }
+ }
+ }
+ {
+ std::map<uint32_t, uint32_t> map;
+ map[0] = 0;
+ map[1] = 1;
+ for (int i = 0; i < 2; i++) {
+ const internal::MapFieldBase& map_field =
+ reflection->GetRaw<internal::MapFieldBase>(message,
+ F("map_fixed32_fixed32"));
+ if (map_field.IsRepeatedFieldValid()) {
+ // Check with RepeatedField Reflection
+ sub_message = &reflection->GetRepeatedMessage(
+ message, F("map_fixed32_fixed32"), i);
+ uint32_t key = sub_message->GetReflection()->GetUInt32(
+ *sub_message, map_fixed32_fixed32_key_);
+ uint32_t val = sub_message->GetReflection()->GetUInt32(
+ *sub_message, map_fixed32_fixed32_val_);
+ EXPECT_EQ(map[key], val);
+ } else {
+ // Check with Map Reflection
+ map_key.SetUInt32Value(i);
+ EXPECT_EQ(true, reflection->ContainsMapKey(
+ message, F("map_fixed32_fixed32"), map_key));
+ EXPECT_TRUE(reflection->LookupMapValue(
+ message, F("map_fixed32_fixed32"), map_key, &map_value_const_ref));
+ EXPECT_EQ(map_value_const_ref.GetUInt32Value(), map[i]);
+ }
+ }
+ }
+ {
+ std::map<uint64_t, uint64_t> map;
+ map[0] = 0;
+ map[1] = 1;
+ for (int i = 0; i < 2; i++) {
+ const internal::MapFieldBase& map_field =
+ reflection->GetRaw<internal::MapFieldBase>(message,
+ F("map_fixed64_fixed64"));
+ if (map_field.IsRepeatedFieldValid()) {
+ // Check with RepeatedField Reflection
+ sub_message = &reflection->GetRepeatedMessage(
+ message, F("map_fixed64_fixed64"), i);
+ uint64_t key = sub_message->GetReflection()->GetUInt64(
+ *sub_message, map_fixed64_fixed64_key_);
+ uint64_t val = sub_message->GetReflection()->GetUInt64(
+ *sub_message, map_fixed64_fixed64_val_);
+ EXPECT_EQ(map[key], val);
+ } else {
+ // Check with Map Reflection
+ map_key.SetUInt64Value(i);
+ EXPECT_EQ(true, reflection->ContainsMapKey(
+ message, F("map_fixed64_fixed64"), map_key));
+ EXPECT_TRUE(reflection->LookupMapValue(
+ message, F("map_fixed64_fixed64"), map_key, &map_value_const_ref));
+ EXPECT_EQ(map_value_const_ref.GetUInt64Value(), map[i]);
+ }
+ }
+ }
+ {
+ std::map<int32_t, int32_t> map;
+ map[0] = 0;
+ map[1] = 1;
+ for (int i = 0; i < 2; i++) {
+ const internal::MapFieldBase& map_field =
+ reflection->GetRaw<internal::MapFieldBase>(
+ message, F("map_sfixed32_sfixed32"));
+ if (map_field.IsRepeatedFieldValid()) {
+ // Check with RepeatedField Reflection
+ sub_message = &reflection->GetRepeatedMessage(
+ message, F("map_sfixed32_sfixed32"), i);
+ int32_t key = sub_message->GetReflection()->GetInt32(
+ *sub_message, map_sfixed32_sfixed32_key_);
+ int32_t val = sub_message->GetReflection()->GetInt32(
+ *sub_message, map_sfixed32_sfixed32_val_);
+ EXPECT_EQ(map[key], val);
+ } else {
+ // Check with Map Reflection
+ map_key.SetInt32Value(i);
+ EXPECT_EQ(true, reflection->ContainsMapKey(
+ message, F("map_sfixed32_sfixed32"), map_key));
+ EXPECT_TRUE(reflection->LookupMapValue(message,
+ F("map_sfixed32_sfixed32"),
+ map_key, &map_value_const_ref));
+ EXPECT_EQ(map_value_const_ref.GetInt32Value(), map[i]);
+ }
+ }
+ }
+ {
+ std::map<int64_t, int64_t> map;
+ map[0] = 0;
+ map[1] = 1;
+ for (int i = 0; i < 2; i++) {
+ const internal::MapFieldBase& map_field =
+ reflection->GetRaw<internal::MapFieldBase>(
+ message, F("map_sfixed64_sfixed64"));
+ if (map_field.IsRepeatedFieldValid()) {
+ // Check with RepeatedField Reflection
+ sub_message = &reflection->GetRepeatedMessage(
+ message, F("map_sfixed64_sfixed64"), i);
+ int64_t key = sub_message->GetReflection()->GetInt64(
+ *sub_message, map_sfixed64_sfixed64_key_);
+ int64_t val = sub_message->GetReflection()->GetInt64(
+ *sub_message, map_sfixed64_sfixed64_val_);
+ EXPECT_EQ(map[key], val);
+ } else {
+ // Check with Map Reflection
+ map_key.SetInt64Value(i);
+ EXPECT_EQ(true, reflection->ContainsMapKey(
+ message, F("map_sfixed64_sfixed64"), map_key));
+ EXPECT_TRUE(reflection->LookupMapValue(message,
+ F("map_sfixed64_sfixed64"),
+ map_key, &map_value_const_ref));
+ EXPECT_EQ(map_value_const_ref.GetInt64Value(), map[i]);
+ }
+ }
+ }
+ {
+ std::map<int32_t, float> map;
+ map[0] = 0.0;
+ map[1] = 1.0;
+ for (int i = 0; i < 2; i++) {
+ const internal::MapFieldBase& map_field =
+ reflection->GetRaw<internal::MapFieldBase>(message,
+ F("map_int32_float"));
+ if (map_field.IsRepeatedFieldValid()) {
+ // Check with RepeatedField Reflection
+ sub_message =
+ &reflection->GetRepeatedMessage(message, F("map_int32_float"), i);
+ int32_t key = sub_message->GetReflection()->GetInt32(
+ *sub_message, map_int32_float_key_);
+ float val = sub_message->GetReflection()->GetFloat(
+ *sub_message, map_int32_float_val_);
+ EXPECT_EQ(map[key], val);
+ } else {
+ // Check with Map Reflection
+ map_key.SetInt32Value(i);
+ EXPECT_EQ(true, reflection->ContainsMapKey(
+ message, F("map_int32_float"), map_key));
+ EXPECT_TRUE(reflection->LookupMapValue(message, F("map_int32_float"),
+ map_key, &map_value_const_ref));
+ EXPECT_EQ(map_value_const_ref.GetFloatValue(), map[i]);
+ }
+ }
+ }
+ {
+ std::map<int32_t, double> map;
+ map[0] = 0.0;
+ map[1] = 1.0;
+ for (int i = 0; i < 2; i++) {
+ const internal::MapFieldBase& map_field =
+ reflection->GetRaw<internal::MapFieldBase>(message,
+ F("map_int32_double"));
+ if (map_field.IsRepeatedFieldValid()) {
+ // Check with RepeatedField Reflection
+ sub_message =
+ &reflection->GetRepeatedMessage(message, F("map_int32_double"), i);
+ int32_t key = sub_message->GetReflection()->GetInt32(
+ *sub_message, map_int32_double_key_);
+ double val = sub_message->GetReflection()->GetDouble(
+ *sub_message, map_int32_double_val_);
+ EXPECT_EQ(map[key], val);
+ } else {
+ // Check with Map Reflection
+ map_key.SetInt32Value(i);
+ EXPECT_EQ(true, reflection->ContainsMapKey(
+ message, F("map_int32_double"), map_key));
+ EXPECT_TRUE(reflection->LookupMapValue(message, F("map_int32_double"),
+ map_key, &map_value_const_ref));
+ EXPECT_EQ(map_value_const_ref.GetDoubleValue(), map[i]);
+ }
+ }
+ }
+ {
+ std::map<bool, bool> map;
+ map[false] = false;
+ map[true] = true;
+ std::vector<bool> keys = {false, true};
+ std::vector<bool> vals = {false, true};
+ for (int i = 0; i < 2; i++) {
+ const internal::MapFieldBase& map_field =
+ reflection->GetRaw<internal::MapFieldBase>(message,
+ F("map_bool_bool"));
+ if (map_field.IsRepeatedFieldValid()) {
+ // Check with RepeatedField Reflection
+ sub_message =
+ &reflection->GetRepeatedMessage(message, F("map_bool_bool"), i);
+ bool key = sub_message->GetReflection()->GetBool(*sub_message,
+ map_bool_bool_key_);
+ bool val = sub_message->GetReflection()->GetBool(*sub_message,
+ map_bool_bool_val_);
+ EXPECT_EQ(map[key], val);
+ } else {
+ // Check with Map Reflection
+ map_key.SetBoolValue(keys[i]);
+ EXPECT_EQ(true, reflection->ContainsMapKey(message, F("map_bool_bool"),
+ map_key));
+ EXPECT_TRUE(reflection->LookupMapValue(message, F("map_bool_bool"),
+ map_key, &map_value_const_ref));
+ EXPECT_EQ(map_value_const_ref.GetBoolValue(), vals[i]);
+ }
+ }
+ }
+ {
+ std::map<std::string, std::string> map;
+ map["0"] = "0";
+ map["1"] = "1";
+ std::vector<std::string> keys = {"0", "1"};
+ std::vector<std::string> vals = {"0", "1"};
+ for (int i = 0; i < 2; i++) {
+ const internal::MapFieldBase& map_field =
+ reflection->GetRaw<internal::MapFieldBase>(message,
+ F("map_string_string"));
+ if (map_field.IsRepeatedFieldValid()) {
+ // Check with RepeatedField Reflection
+ sub_message =
+ &reflection->GetRepeatedMessage(message, F("map_string_string"), i);
+ std::string key = sub_message->GetReflection()->GetString(
+ *sub_message, map_string_string_key_);
+ std::string val = sub_message->GetReflection()->GetString(
+ *sub_message, map_string_string_val_);
+ EXPECT_EQ(map[key], val);
+ } else {
+ // Check with Map Reflection
+ map_key.SetStringValue(keys[i]);
+ EXPECT_EQ(true, reflection->ContainsMapKey(
+ message, F("map_string_string"), map_key));
+ EXPECT_TRUE(reflection->LookupMapValue(message, F("map_string_string"),
+ map_key, &map_value_const_ref));
+ EXPECT_EQ(map_value_const_ref.GetStringValue(), vals[i]);
+ }
+ }
+ }
+ {
+ std::map<int32_t, std::string> map;
+ map[0] = "0";
+ map[1] = "1";
+ for (int i = 0; i < 2; i++) {
+ const internal::MapFieldBase& map_field =
+ reflection->GetRaw<internal::MapFieldBase>(message,
+ F("map_int32_bytes"));
+ if (map_field.IsRepeatedFieldValid()) {
+ // Check with RepeatedField Reflection
+ sub_message =
+ &reflection->GetRepeatedMessage(message, F("map_int32_bytes"), i);
+ int32_t key = sub_message->GetReflection()->GetInt32(
+ *sub_message, map_int32_bytes_key_);
+ std::string val = sub_message->GetReflection()->GetString(
+ *sub_message, map_int32_bytes_val_);
+ EXPECT_EQ(map[key], val);
+ } else {
+ // Check with Map Reflection
+ map_key.SetInt32Value(i);
+ EXPECT_EQ(true, reflection->ContainsMapKey(
+ message, F("map_int32_bytes"), map_key));
+ EXPECT_TRUE(reflection->LookupMapValue(message, F("map_int32_bytes"),
+ map_key, &map_value_const_ref));
+ EXPECT_EQ(map_value_const_ref.GetStringValue(), map[i]);
+ }
+ }
+ }
+ {
+ std::map<int32_t, const EnumValueDescriptor*> map;
+ map[0] = map_enum_bar_;
+ map[1] = map_enum_baz_;
+ for (int i = 0; i < 2; i++) {
+ const internal::MapFieldBase& map_field =
+ reflection->GetRaw<internal::MapFieldBase>(message,
+ F("map_int32_enum"));
+ if (map_field.IsRepeatedFieldValid()) {
+ // Check with RepeatedField Reflection
+ sub_message =
+ &reflection->GetRepeatedMessage(message, F("map_int32_enum"), i);
+ int32_t key = sub_message->GetReflection()->GetInt32(
+ *sub_message, map_int32_enum_key_);
+ const EnumValueDescriptor* val = sub_message->GetReflection()->GetEnum(
+ *sub_message, map_int32_enum_val_);
+ EXPECT_EQ(map[key], val);
+ } else {
+ // Check with Map Reflection
+ map_key.SetInt32Value(i);
+ EXPECT_EQ(true, reflection->ContainsMapKey(message, F("map_int32_enum"),
+ map_key));
+ EXPECT_TRUE(reflection->LookupMapValue(message, F("map_int32_enum"),
+ map_key, &map_value_const_ref));
+ EXPECT_EQ(map_value_const_ref.GetEnumValue(), map[i]->number());
+ }
+ }
+ }
+ {
+ std::map<int32_t, int32_t> map;
+ map[0] = 0;
+ map[1] = 1;
+ for (int i = 0; i < 2; i++) {
+ const internal::MapFieldBase& map_field =
+ reflection->GetRaw<internal::MapFieldBase>(
+ message, F("map_int32_foreign_message"));
+ if (map_field.IsRepeatedFieldValid()) {
+ // Check with RepeatedField Reflection
+ sub_message = &reflection->GetRepeatedMessage(
+ message, F("map_int32_foreign_message"), i);
+ int32_t key = sub_message->GetReflection()->GetInt32(
+ *sub_message, map_int32_foreign_message_key_);
+ const Message& foreign_message =
+ sub_message->GetReflection()->GetMessage(
+ *sub_message, map_int32_foreign_message_val_);
+ int32_t val = foreign_message.GetReflection()->GetInt32(foreign_message,
+ foreign_c_);
+ EXPECT_EQ(map[key], val);
+ } else {
+ // Check with Map Reflection
+ map_key.SetInt32Value(i);
+ EXPECT_EQ(true, reflection->ContainsMapKey(
+ message, F("map_int32_foreign_message"), map_key));
+ EXPECT_TRUE(reflection->LookupMapValue(message,
+ F("map_int32_foreign_message"),
+ map_key, &map_value_const_ref));
+ const Message& foreign_message = map_value_const_ref.GetMessageValue();
+ EXPECT_EQ(foreign_message.GetReflection()->GetInt32(foreign_message,
+ foreign_c_),
+ map[i]);
+ }
+ }
+ }
+}
+
+void MapReflectionTester::ExpectMapFieldsSetViaReflectionIterator(
+ Message* message) {
+ std::string scratch;
+ std::string serialized;
+ const Reflection* reflection = message->GetReflection();
+
+ ASSERT_EQ(2, reflection->FieldSize(*message, F("map_int32_int32")));
+ ASSERT_EQ(2, reflection->FieldSize(*message, F("map_int64_int64")));
+ ASSERT_EQ(2, reflection->FieldSize(*message, F("map_uint32_uint32")));
+ ASSERT_EQ(2, reflection->FieldSize(*message, F("map_uint64_uint64")));
+ ASSERT_EQ(2, reflection->FieldSize(*message, F("map_sint32_sint32")));
+ ASSERT_EQ(2, reflection->FieldSize(*message, F("map_sint64_sint64")));
+ ASSERT_EQ(2, reflection->FieldSize(*message, F("map_fixed32_fixed32")));
+ ASSERT_EQ(2, reflection->FieldSize(*message, F("map_fixed64_fixed64")));
+ ASSERT_EQ(2, reflection->FieldSize(*message, F("map_sfixed32_sfixed32")));
+ ASSERT_EQ(2, reflection->FieldSize(*message, F("map_sfixed64_sfixed64")));
+ ASSERT_EQ(2, reflection->FieldSize(*message, F("map_int32_float")));
+ ASSERT_EQ(2, reflection->FieldSize(*message, F("map_int32_double")));
+ ASSERT_EQ(2, reflection->FieldSize(*message, F("map_bool_bool")));
+ ASSERT_EQ(2, reflection->FieldSize(*message, F("map_string_string")));
+ ASSERT_EQ(2, reflection->FieldSize(*message, F("map_int32_bytes")));
+ ASSERT_EQ(2, reflection->FieldSize(*message, F("map_int32_enum")));
+ ASSERT_EQ(2, reflection->FieldSize(*message, F("map_int32_foreign_message")));
+
+ {
+ std::map<int32_t, int32_t> map;
+ map[0] = 0;
+ map[1] = 1;
+ int size = 0;
+ for (MapIterator iter = reflection->MapBegin(message, F("map_int32_int32"));
+ iter != reflection->MapEnd(message, F("map_int32_int32"));
+ ++iter, ++size) {
+ // Check const methods do not invalidate map.
+ message->DebugString();
+ message->ShortDebugString();
+ message->SerializeToString(&serialized);
+ message->SpaceUsedLong();
+ message->ByteSizeLong();
+ EXPECT_EQ(map[iter.GetKey().GetInt32Value()],
+ iter.GetValueRef().GetInt32Value());
+ }
+ EXPECT_EQ(size, 2);
+ }
+ {
+ std::map<int64_t, int64_t> map;
+ map[0] = 0;
+ map[1] = 1;
+ for (MapIterator iter = reflection->MapBegin(message, F("map_int64_int64"));
+ iter != reflection->MapEnd(message, F("map_int64_int64")); ++iter) {
+ EXPECT_EQ(map[iter.GetKey().GetInt64Value()],
+ iter.GetValueRef().GetInt64Value());
+ }
+ }
+ {
+ std::map<uint32_t, uint32_t> map;
+ map[0] = 0;
+ map[1] = 1;
+ for (MapIterator iter =
+ reflection->MapBegin(message, F("map_uint32_uint32"));
+ iter != reflection->MapEnd(message, F("map_uint32_uint32")); ++iter) {
+ EXPECT_EQ(map[iter.GetKey().GetUInt32Value()],
+ iter.GetValueRef().GetUInt32Value());
+ }
+ }
+ {
+ std::map<uint64_t, uint64_t> map;
+ map[0] = 0;
+ map[1] = 1;
+ for (MapIterator iter =
+ reflection->MapBegin(message, F("map_uint64_uint64"));
+ iter != reflection->MapEnd(message, F("map_uint64_uint64")); ++iter) {
+ EXPECT_EQ(map[iter.GetKey().GetUInt64Value()],
+ iter.GetValueRef().GetUInt64Value());
+ }
+ }
+ {
+ std::map<int32_t, int32_t> map;
+ map[0] = 0;
+ map[1] = 1;
+ for (MapIterator iter =
+ reflection->MapBegin(message, F("map_sint32_sint32"));
+ iter != reflection->MapEnd(message, F("map_sint32_sint32")); ++iter) {
+ EXPECT_EQ(map[iter.GetKey().GetInt32Value()],
+ iter.GetValueRef().GetInt32Value());
+ }
+ }
+ {
+ std::map<int64_t, int64_t> map;
+ map[0] = 0;
+ map[1] = 1;
+ for (MapIterator iter =
+ reflection->MapBegin(message, F("map_sint64_sint64"));
+ iter != reflection->MapEnd(message, F("map_sint64_sint64")); ++iter) {
+ EXPECT_EQ(map[iter.GetKey().GetInt64Value()],
+ iter.GetValueRef().GetInt64Value());
+ }
+ }
+ {
+ std::map<uint32_t, uint32_t> map;
+ map[0] = 0;
+ map[1] = 1;
+ for (MapIterator iter =
+ reflection->MapBegin(message, F("map_fixed32_fixed32"));
+ iter != reflection->MapEnd(message, F("map_fixed32_fixed32"));
+ ++iter) {
+ EXPECT_EQ(map[iter.GetKey().GetUInt32Value()],
+ iter.GetValueRef().GetUInt32Value());
+ }
+ }
+ {
+ std::map<uint64_t, uint64_t> map;
+ map[0] = 0;
+ map[1] = 1;
+ for (MapIterator iter =
+ reflection->MapBegin(message, F("map_fixed64_fixed64"));
+ iter != reflection->MapEnd(message, F("map_fixed64_fixed64"));
+ ++iter) {
+ EXPECT_EQ(map[iter.GetKey().GetUInt64Value()],
+ iter.GetValueRef().GetUInt64Value());
+ }
+ }
+ {
+ std::map<int32_t, int32_t> map;
+ map[0] = 0;
+ map[1] = 1;
+ for (MapIterator iter =
+ reflection->MapBegin(message, F("map_sfixed32_sfixed32"));
+ iter != reflection->MapEnd(message, F("map_sfixed32_sfixed32"));
+ ++iter) {
+ EXPECT_EQ(map[iter.GetKey().GetInt32Value()],
+ iter.GetValueRef().GetInt32Value());
+ }
+ }
+ {
+ std::map<int32_t, float> map;
+ map[0] = 0.0;
+ map[1] = 1.0;
+ for (MapIterator iter = reflection->MapBegin(message, F("map_int32_float"));
+ iter != reflection->MapEnd(message, F("map_int32_float")); ++iter) {
+ EXPECT_EQ(map[iter.GetKey().GetInt32Value()],
+ iter.GetValueRef().GetFloatValue());
+ }
+ }
+ {
+ std::map<int32_t, double> map;
+ map[0] = 0.0;
+ map[1] = 1.0;
+ for (MapIterator iter =
+ reflection->MapBegin(message, F("map_int32_double"));
+ iter != reflection->MapEnd(message, F("map_int32_double")); ++iter) {
+ EXPECT_EQ(map[iter.GetKey().GetInt32Value()],
+ iter.GetValueRef().GetDoubleValue());
+ }
+ }
+ {
+ std::map<bool, bool> map;
+ map[false] = false;
+ map[true] = true;
+ for (MapIterator iter = reflection->MapBegin(message, F("map_bool_bool"));
+ iter != reflection->MapEnd(message, F("map_bool_bool")); ++iter) {
+ EXPECT_EQ(map[iter.GetKey().GetBoolValue()],
+ iter.GetValueRef().GetBoolValue());
+ }
+ }
+ {
+ std::map<std::string, std::string> map;
+ map["0"] = "0";
+ map["1"] = "1";
+ int size = 0;
+ for (MapIterator iter =
+ reflection->MapBegin(message, F("map_string_string"));
+ iter != reflection->MapEnd(message, F("map_string_string"));
+ ++iter, ++size) {
+ // Check const methods do not invalidate map.
+ message->DebugString();
+ message->ShortDebugString();
+ message->SerializeToString(&serialized);
+ message->SpaceUsedLong();
+ message->ByteSizeLong();
+ EXPECT_EQ(map[iter.GetKey().GetStringValue()],
+ iter.GetValueRef().GetStringValue());
+ }
+ EXPECT_EQ(size, 2);
+ }
+ {
+ std::map<int32_t, std::string> map;
+ map[0] = "0";
+ map[1] = "1";
+ for (MapIterator iter = reflection->MapBegin(message, F("map_int32_bytes"));
+ iter != reflection->MapEnd(message, F("map_int32_bytes")); ++iter) {
+ EXPECT_EQ(map[iter.GetKey().GetInt32Value()],
+ iter.GetValueRef().GetStringValue());
+ }
+ }
+ {
+ std::map<int32_t, const EnumValueDescriptor*> map;
+ map[0] = map_enum_bar_;
+ map[1] = map_enum_baz_;
+ for (MapIterator iter = reflection->MapBegin(message, F("map_int32_enum"));
+ iter != reflection->MapEnd(message, F("map_int32_enum")); ++iter) {
+ EXPECT_EQ(map[iter.GetKey().GetInt32Value()]->number(),
+ iter.GetValueRef().GetEnumValue());
+ }
+ }
+ {
+ std::map<int32_t, int32_t> map;
+ map[0] = 0;
+ map[1] = 1;
+ int size = 0;
+ for (MapIterator iter =
+ reflection->MapBegin(message, F("map_int32_foreign_message"));
+ iter != reflection->MapEnd(message, F("map_int32_foreign_message"));
+ ++iter, ++size) {
+ // Check const methods do not invalidate map.
+ message->DebugString();
+ message->ShortDebugString();
+ message->SerializeToString(&serialized);
+ message->SpaceUsedLong();
+ message->ByteSizeLong();
+ const Message& sub_message = iter.GetValueRef().GetMessageValue();
+ EXPECT_EQ(map[iter.GetKey().GetInt32Value()],
+ sub_message.GetReflection()->GetInt32(sub_message, foreign_c_));
+ }
+ EXPECT_EQ(size, 2);
+ }
+}
+
+void MapReflectionTester::ExpectClearViaReflection(const Message& message) {
+ const Reflection* reflection = message.GetReflection();
+ // Map fields are empty.
+ EXPECT_EQ(0, reflection->FieldSize(message, F("map_int32_int32")));
+ EXPECT_EQ(0, reflection->FieldSize(message, F("map_int64_int64")));
+ EXPECT_EQ(0, reflection->FieldSize(message, F("map_uint32_uint32")));
+ EXPECT_EQ(0, reflection->FieldSize(message, F("map_uint64_uint64")));
+ EXPECT_EQ(0, reflection->FieldSize(message, F("map_sint32_sint32")));
+ EXPECT_EQ(0, reflection->FieldSize(message, F("map_sint64_sint64")));
+ EXPECT_EQ(0, reflection->FieldSize(message, F("map_fixed32_fixed32")));
+ EXPECT_EQ(0, reflection->FieldSize(message, F("map_fixed64_fixed64")));
+ EXPECT_EQ(0, reflection->FieldSize(message, F("map_sfixed32_sfixed32")));
+ EXPECT_EQ(0, reflection->FieldSize(message, F("map_sfixed64_sfixed64")));
+ EXPECT_EQ(0, reflection->FieldSize(message, F("map_int32_float")));
+ EXPECT_EQ(0, reflection->FieldSize(message, F("map_int32_double")));
+ EXPECT_EQ(0, reflection->FieldSize(message, F("map_bool_bool")));
+ EXPECT_EQ(0, reflection->FieldSize(message, F("map_string_string")));
+ EXPECT_EQ(0, reflection->FieldSize(message, F("map_int32_bytes")));
+ EXPECT_EQ(0, reflection->FieldSize(message, F("map_int32_enum")));
+ EXPECT_EQ(0, reflection->FieldSize(message, F("map_int32_foreign_message")));
+ EXPECT_TRUE(reflection->GetMapData(message, F("map_int32_foreign_message"))
+ ->IsMapValid());
+}
+
+void MapReflectionTester::ExpectClearViaReflectionIterator(Message* message) {
+ const Reflection* reflection = message->GetReflection();
+ EXPECT_TRUE(reflection->MapBegin(message, F("map_int32_int32")) ==
+ reflection->MapEnd(message, F("map_int32_int32")));
+ EXPECT_TRUE(reflection->MapBegin(message, F("map_int64_int64")) ==
+ reflection->MapEnd(message, F("map_int64_int64")));
+ EXPECT_TRUE(reflection->MapBegin(message, F("map_uint32_uint32")) ==
+ reflection->MapEnd(message, F("map_uint32_uint32")));
+ EXPECT_TRUE(reflection->MapBegin(message, F("map_uint64_uint64")) ==
+ reflection->MapEnd(message, F("map_uint64_uint64")));
+ EXPECT_TRUE(reflection->MapBegin(message, F("map_sint32_sint32")) ==
+ reflection->MapEnd(message, F("map_sint32_sint32")));
+ EXPECT_TRUE(reflection->MapBegin(message, F("map_sint64_sint64")) ==
+ reflection->MapEnd(message, F("map_sint64_sint64")));
+ EXPECT_TRUE(reflection->MapBegin(message, F("map_fixed32_fixed32")) ==
+ reflection->MapEnd(message, F("map_fixed32_fixed32")));
+ EXPECT_TRUE(reflection->MapBegin(message, F("map_fixed64_fixed64")) ==
+ reflection->MapEnd(message, F("map_fixed64_fixed64")));
+ EXPECT_TRUE(reflection->MapBegin(message, F("map_sfixed32_sfixed32")) ==
+ reflection->MapEnd(message, F("map_sfixed32_sfixed32")));
+ EXPECT_TRUE(reflection->MapBegin(message, F("map_sfixed64_sfixed64")) ==
+ reflection->MapEnd(message, F("map_sfixed64_sfixed64")));
+ EXPECT_TRUE(reflection->MapBegin(message, F("map_int32_float")) ==
+ reflection->MapEnd(message, F("map_int32_float")));
+ EXPECT_TRUE(reflection->MapBegin(message, F("map_int32_double")) ==
+ reflection->MapEnd(message, F("map_int32_double")));
+ EXPECT_TRUE(reflection->MapBegin(message, F("map_bool_bool")) ==
+ reflection->MapEnd(message, F("map_bool_bool")));
+ EXPECT_TRUE(reflection->MapBegin(message, F("map_string_string")) ==
+ reflection->MapEnd(message, F("map_string_string")));
+ EXPECT_TRUE(reflection->MapBegin(message, F("map_int32_bytes")) ==
+ reflection->MapEnd(message, F("map_int32_bytes")));
+ EXPECT_TRUE(reflection->MapBegin(message, F("map_int32_enum")) ==
+ reflection->MapEnd(message, F("map_int32_enum")));
+ EXPECT_TRUE(reflection->MapBegin(message, F("map_int32_foreign_message")) ==
+ reflection->MapEnd(message, F("map_int32_foreign_message")));
+}
+
+} // namespace protobuf
+} // namespace google
+
+#include <port_undef.inc>
diff --git a/NorthstarDedicatedTest/include/protobuf/reflection_tester.h b/NorthstarDedicatedTest/include/protobuf/reflection_tester.h
new file mode 100644
index 00000000..6f30fdd3
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/reflection_tester.h
@@ -0,0 +1,122 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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_TESTER_H__
+#define GOOGLE_PROTOBUF_REFLECTION_TESTER_H__
+
+#include <message.h>
+
+// Must be included last.
+#include <port_def.inc>
+
+namespace google {
+namespace protobuf {
+
+// Provides APIs to test protocol buffers reflectively.
+class MapReflectionTester {
+ public:
+ // base_descriptor must be a descriptor for TestMap, which is used for
+ // MapReflectionTester to fetch the FieldDescriptors needed to use the
+ // reflection interface.
+ explicit MapReflectionTester(const Descriptor* base_descriptor);
+
+ void SetMapFieldsViaReflection(Message* message);
+ void SetMapFieldsViaMapReflection(Message* message);
+ void ClearMapFieldsViaReflection(Message* message);
+ void ModifyMapFieldsViaReflection(Message* message);
+ void RemoveLastMapsViaReflection(Message* message);
+ void ReleaseLastMapsViaReflection(Message* message);
+ void SwapMapsViaReflection(Message* message);
+ void MutableUnknownFieldsOfMapFieldsViaReflection(Message* message);
+ void ExpectMapFieldsSetViaReflection(const Message& message);
+ void ExpectMapFieldsSetViaReflectionIterator(Message* message);
+ void ExpectClearViaReflection(const Message& message);
+ void ExpectClearViaReflectionIterator(Message* message);
+ void GetMapValueViaMapReflection(Message* message,
+ const std::string& field_name,
+ const MapKey& map_key, MapValueRef* map_val);
+ Message* GetMapEntryViaReflection(Message* message,
+ const std::string& field_name, int index);
+ MapIterator MapBegin(Message* message, const std::string& field_name);
+ MapIterator MapEnd(Message* message, const std::string& field_name);
+ int MapSize(const Message& message, const std::string& field_name);
+
+ private:
+ const FieldDescriptor* F(const std::string& name);
+
+ const Descriptor* base_descriptor_;
+
+ const EnumValueDescriptor* map_enum_bar_;
+ const EnumValueDescriptor* map_enum_baz_;
+ const EnumValueDescriptor* map_enum_foo_;
+
+ const FieldDescriptor* foreign_c_;
+ const FieldDescriptor* map_int32_int32_key_;
+ const FieldDescriptor* map_int32_int32_val_;
+ const FieldDescriptor* map_int64_int64_key_;
+ const FieldDescriptor* map_int64_int64_val_;
+ const FieldDescriptor* map_uint32_uint32_key_;
+ const FieldDescriptor* map_uint32_uint32_val_;
+ const FieldDescriptor* map_uint64_uint64_key_;
+ const FieldDescriptor* map_uint64_uint64_val_;
+ const FieldDescriptor* map_sint32_sint32_key_;
+ const FieldDescriptor* map_sint32_sint32_val_;
+ const FieldDescriptor* map_sint64_sint64_key_;
+ const FieldDescriptor* map_sint64_sint64_val_;
+ const FieldDescriptor* map_fixed32_fixed32_key_;
+ const FieldDescriptor* map_fixed32_fixed32_val_;
+ const FieldDescriptor* map_fixed64_fixed64_key_;
+ const FieldDescriptor* map_fixed64_fixed64_val_;
+ const FieldDescriptor* map_sfixed32_sfixed32_key_;
+ const FieldDescriptor* map_sfixed32_sfixed32_val_;
+ const FieldDescriptor* map_sfixed64_sfixed64_key_;
+ const FieldDescriptor* map_sfixed64_sfixed64_val_;
+ const FieldDescriptor* map_int32_float_key_;
+ const FieldDescriptor* map_int32_float_val_;
+ const FieldDescriptor* map_int32_double_key_;
+ const FieldDescriptor* map_int32_double_val_;
+ const FieldDescriptor* map_bool_bool_key_;
+ const FieldDescriptor* map_bool_bool_val_;
+ const FieldDescriptor* map_string_string_key_;
+ const FieldDescriptor* map_string_string_val_;
+ const FieldDescriptor* map_int32_bytes_key_;
+ const FieldDescriptor* map_int32_bytes_val_;
+ const FieldDescriptor* map_int32_enum_key_;
+ const FieldDescriptor* map_int32_enum_val_;
+ const FieldDescriptor* map_int32_foreign_message_key_;
+ const FieldDescriptor* map_int32_foreign_message_val_;
+};
+
+} // namespace protobuf
+} // namespace google
+
+#include <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_REFLECTION_TESTER_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/repeated_field.cc b/NorthstarDedicatedTest/include/protobuf/repeated_field.cc
new file mode 100644
index 00000000..a44d8304
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/repeated_field.cc
@@ -0,0 +1,60 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <repeated_field.h>
+
+#include <algorithm>
+
+#include <stubs/logging.h>
+#include <stubs/common.h>
+
+#include <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 protobuf
+} // namespace google
+
+#include <port_undef.inc>
diff --git a/NorthstarDedicatedTest/include/protobuf/repeated_field.h b/NorthstarDedicatedTest/include/protobuf/repeated_field.h
new file mode 100644
index 00000000..3ada547f
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/repeated_field.h
@@ -0,0 +1,1057 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// RepeatedField and RepeatedPtrField are used by generated protocol message
+// classes to manipulate repeated fields. These classes are very similar to
+// STL's vector, but include a number of optimizations found to be useful
+// specifically in the case of Protocol Buffers. RepeatedPtrField is
+// particularly different from STL vector as it manages ownership of the
+// pointers that it contains.
+//
+// Typically, clients should not need to access RepeatedField objects directly,
+// but should instead use the accessor functions generated automatically by the
+// protocol compiler.
+//
+// This header covers RepeatedField.
+
+#ifndef GOOGLE_PROTOBUF_REPEATED_FIELD_H__
+#define GOOGLE_PROTOBUF_REPEATED_FIELD_H__
+
+#include <utility>
+#ifdef _MSC_VER
+// This is required for min/max on VS2013 only.
+#include <algorithm>
+#endif
+
+#include <iterator>
+#include <limits>
+#include <string>
+#include <type_traits>
+
+#include <stubs/logging.h>
+#include <stubs/common.h>
+#include <repeated_ptr_field.h>
+#include <arena.h>
+#include <message_lite.h>
+#include <port.h>
+
+
+// Must be included last.
+#include <port_def.inc>
+
+#ifdef SWIG
+#error "You cannot SWIG proto headers"
+#endif
+
+namespace google {
+namespace protobuf {
+
+class Message;
+
+namespace internal {
+
+// kRepeatedFieldLowerClampLimit is the smallest size that will be allocated
+// when growing a repeated field.
+constexpr int kRepeatedFieldLowerClampLimit = 4;
+
+// kRepeatedFieldUpperClampLimit is the lowest signed integer value that
+// overflows when multiplied by 2 (which is undefined behavior). Sizes above
+// this will clamp to the maximum int value instead of following exponential
+// growth when growing a repeated field.
+constexpr int kRepeatedFieldUpperClampLimit =
+ (std::numeric_limits<int>::max() / 2) + 1;
+
+template <typename Iter>
+inline int CalculateReserve(Iter begin, Iter end, std::forward_iterator_tag) {
+ return static_cast<int>(std::distance(begin, end));
+}
+
+template <typename Iter>
+inline int CalculateReserve(Iter /*begin*/, Iter /*end*/,
+ std::input_iterator_tag /*unused*/) {
+ return -1;
+}
+
+template <typename Iter>
+inline int CalculateReserve(Iter begin, Iter end) {
+ typedef typename std::iterator_traits<Iter>::iterator_category Category;
+ return CalculateReserve(begin, end, Category());
+}
+
+// Swaps two blocks of memory of size sizeof(T).
+template <typename T>
+inline void SwapBlock(char* p, char* q) {
+ T tmp;
+ memcpy(&tmp, p, sizeof(T));
+ memcpy(p, q, sizeof(T));
+ memcpy(q, &tmp, sizeof(T));
+}
+
+// Swaps two blocks of memory of size kSize:
+// template <int kSize> void memswap(char* p, char* q);
+
+template <int kSize>
+inline typename std::enable_if<(kSize == 0), void>::type memswap(char*, char*) {
+}
+
+#define PROTO_MEMSWAP_DEF_SIZE(reg_type, max_size) \
+ template <int kSize> \
+ typename std::enable_if<(kSize >= sizeof(reg_type) && kSize < (max_size)), \
+ void>::type \
+ memswap(char* p, char* q) { \
+ SwapBlock<reg_type>(p, q); \
+ memswap<kSize - sizeof(reg_type)>(p + sizeof(reg_type), \
+ q + sizeof(reg_type)); \
+ }
+
+PROTO_MEMSWAP_DEF_SIZE(uint8_t, 2)
+PROTO_MEMSWAP_DEF_SIZE(uint16_t, 4)
+PROTO_MEMSWAP_DEF_SIZE(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
+
+} // 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 return a pointer to it.
+ // The new element is uninitialized if |Element| is a POD type.
+ Element* Add();
+ // Append elements in the range [begin, end) after reserving
+ // the appropriate number of elements.
+ template <typename Iter>
+ void Add(Iter begin, Iter end);
+
+ // Remove the last element in the array.
+ void RemoveLast();
+
+ // Extract elements with indices in "[start .. start+num-1]".
+ // Copy them into "elements[0 .. num-1]" if "elements" is not nullptr.
+ // Caution: implementation also moves elements with indices [start+num ..].
+ // Calling this routine inside a loop can cause quadratic behavior.
+ void ExtractSubrange(int start, int num, Element* elements);
+
+ PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear();
+ void MergeFrom(const RepeatedField& other);
+ PROTOBUF_ATTRIBUTE_REINITIALIZES void CopyFrom(const RepeatedField& other);
+
+ // Replaces the contents with RepeatedField(begin, end).
+ template <typename Iter>
+ PROTOBUF_ATTRIBUTE_REINITIALIZES void Assign(Iter begin, Iter end);
+
+ // Reserve space to expand the field to at least the given size. If the
+ // array is grown, it will always be at least doubled in size.
+ void Reserve(int new_size);
+
+ // Resize the RepeatedField to a new, smaller size. This is O(1).
+ void Truncate(int new_size);
+
+ void AddAlreadyReserved(const Element& value);
+ // Appends a new element and return a pointer to it.
+ // The new element is uninitialized if |Element| is a POD type.
+ // Should be called only if Capacity() > Size().
+ Element* AddAlreadyReserved();
+ Element* AddNAlreadyReserved(int elements);
+ int Capacity() const;
+
+ // Like STL resize. Uses value to fill appended elements.
+ // Like Truncate() if new_size <= size(), otherwise this is
+ // O(new_size - size()).
+ void Resize(int new_size, const Element& value);
+
+ // Gets the underlying array. This pointer is possibly invalidated by
+ // any add or remove operation.
+ Element* mutable_data();
+ const Element* data() const;
+
+ // Swap entire contents with "other". If they are separate arenas then, copies
+ // data between each other.
+ void Swap(RepeatedField* other);
+
+ // Swap entire contents with "other". Should be called only if the caller can
+ // guarantee that both repeated fields are on the same arena or are on the
+ // heap. Swapping between different arenas is disallowed and caught by a
+ // GOOGLE_DCHECK (see API docs for details).
+ void UnsafeArenaSwap(RepeatedField* other);
+
+ // Swap two elements.
+ void SwapElements(int index1, int index2);
+
+ // STL-like iterator support
+ typedef Element* iterator;
+ typedef const Element* const_iterator;
+ typedef Element value_type;
+ typedef value_type& reference;
+ typedef const value_type& const_reference;
+ typedef value_type* pointer;
+ typedef const value_type* const_pointer;
+ typedef int size_type;
+ typedef ptrdiff_t difference_type;
+
+ iterator begin();
+ const_iterator begin() const;
+ const_iterator cbegin() const;
+ iterator end();
+ const_iterator end() const;
+ const_iterator cend() const;
+
+ // Reverse iterator support
+ typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+ typedef std::reverse_iterator<iterator> reverse_iterator;
+ reverse_iterator rbegin() { return reverse_iterator(end()); }
+ const_reverse_iterator rbegin() const {
+ return const_reverse_iterator(end());
+ }
+ reverse_iterator rend() { return reverse_iterator(begin()); }
+ const_reverse_iterator rend() const {
+ return const_reverse_iterator(begin());
+ }
+
+ // Returns the number of bytes used by the repeated field, excluding
+ // sizeof(*this)
+ size_t SpaceUsedExcludingSelfLong() const;
+
+ int SpaceUsedExcludingSelf() const {
+ return internal::ToIntSize(SpaceUsedExcludingSelfLong());
+ }
+
+ // Removes the element referenced by position.
+ //
+ // Returns an iterator to the element immediately following the removed
+ // element.
+ //
+ // Invalidates all iterators at or after the removed element, including end().
+ iterator erase(const_iterator position);
+
+ // Removes the elements in the range [first, last).
+ //
+ // Returns an iterator to the element immediately following the removed range.
+ //
+ // Invalidates all iterators at or after the removed range, including end().
+ iterator erase(const_iterator first, const_iterator last);
+
+ // Get the Arena on which this RepeatedField stores its elements.
+ inline Arena* GetArena() const {
+ return (total_size_ == 0) ? static_cast<Arena*>(arena_or_elements_)
+ : rep()->arena;
+ }
+
+ // For internal use only.
+ //
+ // This is public due to it being called by generated code.
+ inline void InternalSwap(RepeatedField* other);
+
+ private:
+ static constexpr int kInitialSize = 0;
+ // A note on the representation here (see also comment below for
+ // RepeatedPtrFieldBase's struct Rep):
+ //
+ // We maintain the same sizeof(RepeatedField) as before we added arena support
+ // so that we do not degrade performance by bloating memory usage. Directly
+ // adding an arena_ element to RepeatedField is quite costly. By using
+ // indirection in this way, we keep the same size when the RepeatedField is
+ // empty (common case), and add only an 8-byte header to the elements array
+ // when non-empty. We make sure to place the size fields directly in the
+ // RepeatedField class to avoid costly cache misses due to the indirection.
+ int current_size_;
+ int total_size_;
+ struct Rep {
+ Arena* arena;
+ // Here we declare a huge array as a way of approximating C's "flexible
+ // array member" feature without relying on undefined behavior.
+ Element elements[(std::numeric_limits<int>::max() - 2 * sizeof(Arena*)) /
+ sizeof(Element)];
+ };
+ static constexpr size_t kRepHeaderSize = offsetof(Rep, elements);
+
+ // If total_size_ == 0 this points to an Arena otherwise it points to the
+ // elements member of a Rep struct. Using this invariant allows the storage of
+ // the arena pointer without an extra allocation in the constructor.
+ void* arena_or_elements_;
+
+ // Return pointer to elements array.
+ // pre-condition: the array must have been allocated.
+ Element* elements() const {
+ GOOGLE_DCHECK_GT(total_size_, 0);
+ // Because of above pre-condition this cast is safe.
+ return unsafe_elements();
+ }
+
+ // Return pointer to elements array if it exists otherwise either null or
+ // a invalid pointer is returned. This only happens for empty repeated fields,
+ // where you can't dereference this pointer anyway (it's empty).
+ Element* unsafe_elements() const {
+ return static_cast<Element*>(arena_or_elements_);
+ }
+
+ // Return pointer to the Rep struct.
+ // pre-condition: the Rep must have been allocated, ie elements() is safe.
+ Rep* rep() const {
+ char* addr = reinterpret_cast<char*>(elements()) - offsetof(Rep, elements);
+ return reinterpret_cast<Rep*>(addr);
+ }
+
+ friend class Arena;
+ typedef void InternalArenaConstructable_;
+
+ // Move the contents of |from| into |to|, possibly clobbering |from| in the
+ // process. For primitive types this is just a memcpy(), but it could be
+ // specialized for non-primitive types to, say, swap each element instead.
+ void MoveArray(Element* to, Element* from, int size);
+
+ // Copy the elements of |from| into |to|.
+ void CopyArray(Element* to, const Element* from, int size);
+
+ // Internal helper to delete all elements and deallocate the storage.
+ void InternalDeallocate(Rep* rep, int size) {
+ if (rep != nullptr) {
+ Element* e = &rep->elements[0];
+ if (!std::is_trivial<Element>::value) {
+ Element* limit = &rep->elements[size];
+ for (; e < limit; e++) {
+ e->~Element();
+ }
+ }
+ if (rep->arena == nullptr) {
+#if defined(__GXX_DELETE_WITH_SIZE__) || defined(__cpp_sized_deallocation)
+ const size_t bytes = size * sizeof(*e) + kRepHeaderSize;
+ ::operator delete(static_cast<void*>(rep), bytes);
+#else
+ ::operator delete(static_cast<void*>(rep));
+#endif
+ }
+ }
+ }
+
+ // This class is a performance wrapper around RepeatedField::Add(const T&)
+ // function. In general unless a RepeatedField is a local stack variable LLVM
+ // has a hard time optimizing Add. The machine code tends to be
+ // loop:
+ // mov %size, dword ptr [%repeated_field] // load
+ // cmp %size, dword ptr [%repeated_field + 4]
+ // jae fallback
+ // mov %buffer, qword ptr [%repeated_field + 8]
+ // mov dword [%buffer + %size * 4], %value
+ // inc %size // increment
+ // mov dword ptr [%repeated_field], %size // store
+ // jmp loop
+ //
+ // This puts a load/store in each iteration of the important loop variable
+ // size. It's a pretty bad compile that happens even in simple cases, but
+ // largely the presence of the fallback path disturbs the compilers mem-to-reg
+ // analysis.
+ //
+ // This class takes ownership of a repeated field for the duration of it's
+ // lifetime. The repeated field should not be accessed during this time, ie.
+ // only access through this class is allowed. This class should always be a
+ // function local stack variable. Intended use
+ //
+ // void AddSequence(const int* begin, const int* end, RepeatedField<int>* out)
+ // {
+ // RepeatedFieldAdder<int> adder(out); // Take ownership of out
+ // for (auto it = begin; it != end; ++it) {
+ // adder.Add(*it);
+ // }
+ // }
+ //
+ // Typically due to the fact adder is a local stack variable. The compiler
+ // will be successful in mem-to-reg transformation and the machine code will
+ // be loop: cmp %size, %capacity jae fallback mov dword ptr [%buffer + %size *
+ // 4], %val inc %size jmp loop
+ //
+ // The first version executes at 7 cycles per iteration while the second
+ // version near 1 or 2 cycles.
+ template <int = 0, bool = std::is_trivial<Element>::value>
+ class FastAdderImpl {
+ public:
+ explicit FastAdderImpl(RepeatedField* rf) : repeated_field_(rf) {
+ index_ = repeated_field_->current_size_;
+ capacity_ = repeated_field_->total_size_;
+ buffer_ = repeated_field_->unsafe_elements();
+ }
+ ~FastAdderImpl() { repeated_field_->current_size_ = index_; }
+
+ void Add(Element val) {
+ if (index_ == capacity_) {
+ repeated_field_->current_size_ = index_;
+ repeated_field_->Reserve(index_ + 1);
+ capacity_ = repeated_field_->total_size_;
+ buffer_ = repeated_field_->unsafe_elements();
+ }
+ buffer_[index_++] = val;
+ }
+
+ private:
+ RepeatedField* repeated_field_;
+ int index_;
+ int capacity_;
+ Element* buffer_;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FastAdderImpl);
+ };
+
+ // FastAdder is a wrapper for adding fields. The specialization above handles
+ // POD types more efficiently than RepeatedField.
+ template <int I>
+ class FastAdderImpl<I, false> {
+ public:
+ explicit FastAdderImpl(RepeatedField* rf) : repeated_field_(rf) {}
+ void Add(const Element& val) { repeated_field_->Add(val); }
+
+ private:
+ RepeatedField* repeated_field_;
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FastAdderImpl);
+ };
+
+ using FastAdder = FastAdderImpl<>;
+
+ friend class TestRepeatedFieldHelper;
+ friend class ::google::protobuf::internal::ParseContext;
+};
+
+namespace internal {
+
+// This is a helper template to copy an array of elements efficiently when they
+// have a trivial copy constructor, and correctly otherwise. This really
+// shouldn't be necessary, but our compiler doesn't optimize std::copy very
+// effectively.
+template <typename Element,
+ bool HasTrivialCopy = std::is_trivial<Element>::value>
+struct ElementCopier {
+ void operator()(Element* to, const Element* from, int array_size);
+};
+
+} // namespace internal
+
+// implementation ====================================================
+
+template <typename Element>
+constexpr RepeatedField<Element>::RepeatedField()
+ : current_size_(0), total_size_(0), arena_or_elements_(nullptr) {}
+
+template <typename Element>
+inline RepeatedField<Element>::RepeatedField(Arena* arena)
+ : current_size_(0), total_size_(0), arena_or_elements_(arena) {}
+
+template <typename Element>
+inline RepeatedField<Element>::RepeatedField(const RepeatedField& other)
+ : current_size_(0), total_size_(0), arena_or_elements_(nullptr) {
+ if (other.current_size_ != 0) {
+ Reserve(other.size());
+ AddNAlreadyReserved(other.size());
+ CopyArray(Mutable(0), &other.Get(0), other.size());
+ }
+}
+
+template <typename Element>
+template <typename Iter, typename>
+RepeatedField<Element>::RepeatedField(Iter begin, Iter end)
+ : current_size_(0), total_size_(0), arena_or_elements_(nullptr) {
+ Add(begin, end);
+}
+
+template <typename Element>
+RepeatedField<Element>::~RepeatedField() {
+#ifndef NDEBUG
+ // Try to trigger segfault / asan failure in non-opt builds. If arena_
+ // lifetime has ended before the destructor.
+ auto arena = GetArena();
+ if (arena) (void)arena->SpaceAllocated();
+#endif
+ if (total_size_ > 0) {
+ InternalDeallocate(rep(), total_size_);
+ }
+}
+
+template <typename Element>
+inline RepeatedField<Element>& RepeatedField<Element>::operator=(
+ const RepeatedField& other) {
+ if (this != &other) CopyFrom(other);
+ return *this;
+}
+
+template <typename Element>
+inline RepeatedField<Element>::RepeatedField(RepeatedField&& other) noexcept
+ : RepeatedField() {
+#ifdef PROTOBUF_FORCE_COPY_IN_MOVE
+ CopyFrom(other);
+#else // PROTOBUF_FORCE_COPY_IN_MOVE
+ // We don't just call Swap(&other) here because it would perform 3 copies if
+ // other is on an arena. This field can't be on an arena because arena
+ // construction always uses the Arena* accepting constructor.
+ if (other.GetArena()) {
+ CopyFrom(other);
+ } else {
+ InternalSwap(&other);
+ }
+#endif // !PROTOBUF_FORCE_COPY_IN_MOVE
+}
+
+template <typename Element>
+inline RepeatedField<Element>& RepeatedField<Element>::operator=(
+ RepeatedField&& other) noexcept {
+ // We don't just call Swap(&other) here because it would perform 3 copies if
+ // the two fields are on different arenas.
+ if (this != &other) {
+ if (GetArena() != other.GetArena()
+#ifdef PROTOBUF_FORCE_COPY_IN_MOVE
+ || GetArena() == nullptr
+#endif // !PROTOBUF_FORCE_COPY_IN_MOVE
+ ) {
+ CopyFrom(other);
+ } else {
+ InternalSwap(&other);
+ }
+ }
+ return *this;
+}
+
+template <typename Element>
+inline bool RepeatedField<Element>::empty() const {
+ return current_size_ == 0;
+}
+
+template <typename Element>
+inline int RepeatedField<Element>::size() const {
+ return current_size_;
+}
+
+template <typename Element>
+inline int RepeatedField<Element>::Capacity() const {
+ return total_size_;
+}
+
+template <typename Element>
+inline void RepeatedField<Element>::AddAlreadyReserved(const Element& value) {
+ GOOGLE_DCHECK_LT(current_size_, total_size_);
+ elements()[current_size_++] = value;
+}
+
+template <typename Element>
+inline Element* RepeatedField<Element>::AddAlreadyReserved() {
+ GOOGLE_DCHECK_LT(current_size_, total_size_);
+ return &elements()[current_size_++];
+}
+
+template <typename Element>
+inline Element* RepeatedField<Element>::AddNAlreadyReserved(int n) {
+ GOOGLE_DCHECK_GE(total_size_ - current_size_, n)
+ << total_size_ << ", " << current_size_;
+ // Warning: sometimes people call this when n == 0 and total_size_ == 0. In
+ // this case the return pointer points to a zero size array (n == 0). Hence
+ // we can just use unsafe_elements(), because the user cannot dereference the
+ // pointer anyway.
+ Element* ret = unsafe_elements() + current_size_;
+ current_size_ += n;
+ return ret;
+}
+
+template <typename Element>
+inline void RepeatedField<Element>::Resize(int new_size, const Element& value) {
+ GOOGLE_DCHECK_GE(new_size, 0);
+ if (new_size > current_size_) {
+ Reserve(new_size);
+ std::fill(&elements()[current_size_], &elements()[new_size], value);
+ }
+ current_size_ = new_size;
+}
+
+template <typename Element>
+inline const Element& RepeatedField<Element>::Get(int index) const {
+ GOOGLE_DCHECK_GE(index, 0);
+ GOOGLE_DCHECK_LT(index, current_size_);
+ return elements()[index];
+}
+
+template <typename Element>
+inline const Element& RepeatedField<Element>::at(int index) const {
+ GOOGLE_CHECK_GE(index, 0);
+ GOOGLE_CHECK_LT(index, current_size_);
+ return elements()[index];
+}
+
+template <typename Element>
+inline Element& RepeatedField<Element>::at(int index) {
+ GOOGLE_CHECK_GE(index, 0);
+ GOOGLE_CHECK_LT(index, current_size_);
+ return elements()[index];
+}
+
+template <typename Element>
+inline Element* RepeatedField<Element>::Mutable(int index) {
+ GOOGLE_DCHECK_GE(index, 0);
+ GOOGLE_DCHECK_LT(index, current_size_);
+ return &elements()[index];
+}
+
+template <typename Element>
+inline void RepeatedField<Element>::Set(int index, const Element& value) {
+ GOOGLE_DCHECK_GE(index, 0);
+ GOOGLE_DCHECK_LT(index, current_size_);
+ elements()[index] = value;
+}
+
+template <typename Element>
+inline void RepeatedField<Element>::Add(const Element& value) {
+ 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 (GetArena() != nullptr && GetArena() == other->GetArena()) {
+#else // PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetArena() == other->GetArena()) {
+#endif // !PROTOBUF_FORCE_COPY_IN_SWAP
+ InternalSwap(other);
+ } else {
+ RepeatedField<Element> temp(other->GetArena());
+ temp.MergeFrom(*this);
+ CopyFrom(*other);
+ other->UnsafeArenaSwap(&temp);
+ }
+}
+
+template <typename Element>
+void RepeatedField<Element>::UnsafeArenaSwap(RepeatedField* other) {
+ if (this == other) return;
+ InternalSwap(other);
+}
+
+template <typename Element>
+void RepeatedField<Element>::SwapElements(int index1, int index2) {
+ using std::swap; // enable ADL with fallback
+ swap(elements()[index1], elements()[index2]);
+}
+
+template <typename Element>
+inline typename RepeatedField<Element>::iterator
+RepeatedField<Element>::begin() {
+ return unsafe_elements();
+}
+template <typename Element>
+inline typename RepeatedField<Element>::const_iterator
+RepeatedField<Element>::begin() const {
+ return unsafe_elements();
+}
+template <typename Element>
+inline typename RepeatedField<Element>::const_iterator
+RepeatedField<Element>::cbegin() const {
+ return unsafe_elements();
+}
+template <typename Element>
+inline typename RepeatedField<Element>::iterator RepeatedField<Element>::end() {
+ return unsafe_elements() + current_size_;
+}
+template <typename Element>
+inline typename RepeatedField<Element>::const_iterator
+RepeatedField<Element>::end() const {
+ return unsafe_elements() + current_size_;
+}
+template <typename Element>
+inline typename RepeatedField<Element>::const_iterator
+RepeatedField<Element>::cend() const {
+ return unsafe_elements() + current_size_;
+}
+
+template <typename Element>
+inline size_t RepeatedField<Element>::SpaceUsedExcludingSelfLong() const {
+ return total_size_ > 0 ? (total_size_ * sizeof(Element) + kRepHeaderSize) : 0;
+}
+
+namespace internal {
+// Returns the new size for a reserved field based on its 'total_size' and the
+// requested 'new_size'. The result is clamped to the closed interval:
+// [internal::kMinRepeatedFieldAllocationSize,
+// std::numeric_limits<int>::max()]
+// Requires:
+// new_size > total_size &&
+// (total_size == 0 ||
+// total_size >= kRepeatedFieldLowerClampLimit)
+inline int CalculateReserveSize(int total_size, int new_size) {
+ if (new_size < kRepeatedFieldLowerClampLimit) {
+ // Clamp to smallest allowed size.
+ return kRepeatedFieldLowerClampLimit;
+ }
+ if (total_size < kRepeatedFieldUpperClampLimit) {
+ return std::max(total_size * 2, new_size);
+ } else {
+ // Clamp to largest allowed size.
+ GOOGLE_DCHECK_GT(new_size, kRepeatedFieldUpperClampLimit);
+ return std::numeric_limits<int>::max();
+ }
+}
+} // namespace internal
+
+// Avoid inlining of Reserve(): new, copy, and delete[] lead to a significant
+// amount of code bloat.
+template <typename Element>
+void RepeatedField<Element>::Reserve(int new_size) {
+ if (total_size_ >= new_size) return;
+ Rep* old_rep = total_size_ > 0 ? rep() : nullptr;
+ Rep* new_rep;
+ Arena* arena = GetArena();
+ new_size = internal::CalculateReserveSize(total_size_, new_size);
+ GOOGLE_DCHECK_LE(
+ static_cast<size_t>(new_size),
+ (std::numeric_limits<size_t>::max() - kRepHeaderSize) / sizeof(Element))
+ << "Requested size is too large to fit into size_t.";
+ size_t bytes =
+ kRepHeaderSize + sizeof(Element) * static_cast<size_t>(new_size);
+ if (arena == nullptr) {
+ new_rep = static_cast<Rep*>(::operator new(bytes));
+ } else {
+ new_rep = reinterpret_cast<Rep*>(Arena::CreateArray<char>(arena, bytes));
+ }
+ new_rep->arena = arena;
+ int old_total_size = total_size_;
+ // Already known: new_size >= internal::kMinRepeatedFieldAllocationSize
+ // Maintain invariant:
+ // total_size_ == 0 ||
+ // total_size_ >= internal::kMinRepeatedFieldAllocationSize
+ total_size_ = new_size;
+ arena_or_elements_ = new_rep->elements;
+ // Invoke placement-new on newly allocated elements. We shouldn't have to do
+ // this, since Element is supposed to be POD, but a previous version of this
+ // code allocated storage with "new Element[size]" and some code uses
+ // RepeatedField with non-POD types, relying on constructor invocation. If
+ // Element has a trivial constructor (e.g., 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);
+
+}
+
+template <typename Element>
+inline void RepeatedField<Element>::Truncate(int new_size) {
+ GOOGLE_DCHECK_LE(new_size, current_size_);
+ if (current_size_ > 0) {
+ current_size_ = new_size;
+ }
+}
+
+template <typename Element>
+inline void RepeatedField<Element>::MoveArray(Element* to, Element* from,
+ int array_size) {
+ CopyArray(to, from, array_size);
+}
+
+template <typename Element>
+inline void RepeatedField<Element>::CopyArray(Element* to, const Element* from,
+ int array_size) {
+ internal::ElementCopier<Element>()(to, from, array_size);
+}
+
+namespace internal {
+
+template <typename Element, bool HasTrivialCopy>
+void ElementCopier<Element, HasTrivialCopy>::operator()(Element* to,
+ const Element* from,
+ int array_size) {
+ std::copy(from, from + array_size, to);
+}
+
+template <typename Element>
+struct ElementCopier<Element, true> {
+ void operator()(Element* to, const Element* from, int array_size) {
+ memcpy(to, from, static_cast<size_t>(array_size) * sizeof(Element));
+ }
+};
+
+} // namespace internal
+
+
+// -------------------------------------------------------------------
+
+// Iterators and helper functions that follow the spirit of the STL
+// std::back_insert_iterator and std::back_inserter but are tailor-made
+// for RepeatedField and RepeatedPtrField. Typical usage would be:
+//
+// std::copy(some_sequence.begin(), some_sequence.end(),
+// RepeatedFieldBackInserter(proto.mutable_sequence()));
+//
+// Ported by johannes from util/gtl/proto-array-iterators.h
+
+namespace internal {
+// A back inserter for RepeatedField objects.
+template <typename T>
+class RepeatedFieldBackInsertIterator {
+ public:
+ using iterator_category = std::output_iterator_tag;
+ using value_type = T;
+ using pointer = void;
+ using reference = void;
+ using difference_type = std::ptrdiff_t;
+
+ explicit RepeatedFieldBackInsertIterator(
+ RepeatedField<T>* const mutable_field)
+ : field_(mutable_field) {}
+ RepeatedFieldBackInsertIterator<T>& operator=(const T& value) {
+ field_->Add(value);
+ return *this;
+ }
+ RepeatedFieldBackInsertIterator<T>& operator*() { return *this; }
+ RepeatedFieldBackInsertIterator<T>& operator++() { return *this; }
+ RepeatedFieldBackInsertIterator<T>& operator++(int /* unused */) {
+ return *this;
+ }
+
+ private:
+ RepeatedField<T>* field_;
+};
+
+} // namespace internal
+
+// Provides a back insert iterator for RepeatedField instances,
+// similar to std::back_inserter().
+template <typename T>
+internal::RepeatedFieldBackInsertIterator<T> RepeatedFieldBackInserter(
+ RepeatedField<T>* const mutable_field) {
+ return internal::RepeatedFieldBackInsertIterator<T>(mutable_field);
+}
+
+// Extern declarations of common instantiations to reduce library bloat.
+extern template class PROTOBUF_EXPORT_TEMPLATE_DECLARE RepeatedField<bool>;
+extern template class PROTOBUF_EXPORT_TEMPLATE_DECLARE RepeatedField<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 protobuf
+} // namespace google
+
+#include <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_REPEATED_FIELD_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/repeated_field_reflection_unittest.cc b/NorthstarDedicatedTest/include/protobuf/repeated_field_reflection_unittest.cc
new file mode 100644
index 00000000..c00070f3
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/repeated_field_reflection_unittest.cc
@@ -0,0 +1,708 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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: tgs@google.com (Tom Szymanski)
+//
+// Test reflection methods for aggregate access to Repeated[Ptr]Fields.
+// This test proto2 methods on a proto2 layout.
+
+#include <stubs/casts.h>
+#include <stubs/stringprintf.h>
+#include <test_util.h>
+#include <unittest.pb.h>
+#include <dynamic_message.h>
+#include <reflection.h>
+#include <gtest/gtest.h>
+
+namespace google {
+namespace protobuf {
+
+using unittest::ForeignMessage;
+using unittest::TestAllExtensions;
+using unittest::TestAllTypes;
+
+namespace {
+
+static int Func(int i, int j) { return i * j; }
+
+static std::string StrFunc(int i, int j) { return StrCat(Func(i, 4)); }
+
+TEST(RepeatedFieldReflectionTest, RegularFields) {
+ TestAllTypes message;
+ const Reflection* refl = message.GetReflection();
+ const Descriptor* desc = message.GetDescriptor();
+
+ for (int i = 0; i < 10; ++i) {
+ message.add_repeated_int32(Func(i, 1));
+ message.add_repeated_double(Func(i, 2));
+ message.add_repeated_string(StrFunc(i, 5));
+ message.add_repeated_foreign_message()->set_c(Func(i, 6));
+ }
+
+ // Get FieldDescriptors for all the fields of interest.
+ const FieldDescriptor* fd_repeated_int32 =
+ desc->FindFieldByName("repeated_int32");
+ const FieldDescriptor* fd_repeated_double =
+ desc->FindFieldByName("repeated_double");
+ const FieldDescriptor* fd_repeated_string =
+ desc->FindFieldByName("repeated_string");
+ const FieldDescriptor* fd_repeated_foreign_message =
+ desc->FindFieldByName("repeated_foreign_message");
+
+ // Get RepeatedField objects for all fields of interest.
+ const RepeatedField<int32>& rf_int32 =
+ refl->GetRepeatedField<int32>(message, fd_repeated_int32);
+ const RepeatedField<double>& rf_double =
+ refl->GetRepeatedField<double>(message, fd_repeated_double);
+
+ // Get mutable RepeatedField objects for all fields of interest.
+ RepeatedField<int32>* mrf_int32 =
+ refl->MutableRepeatedField<int32>(&message, fd_repeated_int32);
+ RepeatedField<double>* mrf_double =
+ refl->MutableRepeatedField<double>(&message, fd_repeated_double);
+
+ // Get RepeatedPtrField objects for all fields of interest.
+ const RepeatedPtrField<std::string>& rpf_string =
+ refl->GetRepeatedPtrField<std::string>(message, fd_repeated_string);
+ const RepeatedPtrField<ForeignMessage>& rpf_foreign_message =
+ refl->GetRepeatedPtrField<ForeignMessage>(message,
+ fd_repeated_foreign_message);
+ const RepeatedPtrField<Message>& rpf_message =
+ refl->GetRepeatedPtrField<Message>(message, fd_repeated_foreign_message);
+
+ // Get mutable RepeatedPtrField objects for all fields of interest.
+ RepeatedPtrField<std::string>* mrpf_string =
+ refl->MutableRepeatedPtrField<std::string>(&message, fd_repeated_string);
+ RepeatedPtrField<ForeignMessage>* mrpf_foreign_message =
+ refl->MutableRepeatedPtrField<ForeignMessage>(
+ &message, fd_repeated_foreign_message);
+ RepeatedPtrField<Message>* mrpf_message =
+ refl->MutableRepeatedPtrField<Message>(&message,
+ fd_repeated_foreign_message);
+
+ // Make sure we can do gets and sets through the Repeated[Ptr]Field objects.
+ for (int i = 0; i < 10; ++i) {
+ // Check gets through const objects.
+ EXPECT_EQ(rf_int32.Get(i), Func(i, 1));
+ EXPECT_EQ(rf_double.Get(i), Func(i, 2));
+ EXPECT_EQ(rpf_string.Get(i), StrFunc(i, 5));
+ EXPECT_EQ(rpf_foreign_message.Get(i).c(), Func(i, 6));
+ EXPECT_EQ(down_cast<const ForeignMessage*>(&rpf_message.Get(i))->c(),
+ Func(i, 6));
+
+ // Check gets through mutable objects.
+ EXPECT_EQ(mrf_int32->Get(i), Func(i, 1));
+ EXPECT_EQ(mrf_double->Get(i), Func(i, 2));
+ EXPECT_EQ(mrpf_string->Get(i), StrFunc(i, 5));
+ EXPECT_EQ(mrpf_foreign_message->Get(i).c(), Func(i, 6));
+ EXPECT_EQ(down_cast<const ForeignMessage*>(&mrpf_message->Get(i))->c(),
+ Func(i, 6));
+
+ // Check sets through mutable objects.
+ mrf_int32->Set(i, Func(i, -1));
+ mrf_double->Set(i, Func(i, -2));
+ mrpf_string->Mutable(i)->assign(StrFunc(i, -5));
+ mrpf_foreign_message->Mutable(i)->set_c(Func(i, -6));
+ EXPECT_EQ(message.repeated_int32(i), Func(i, -1));
+ EXPECT_EQ(message.repeated_double(i), Func(i, -2));
+ EXPECT_EQ(message.repeated_string(i), StrFunc(i, -5));
+ EXPECT_EQ(message.repeated_foreign_message(i).c(), Func(i, -6));
+ down_cast<ForeignMessage*>(mrpf_message->Mutable(i))->set_c(Func(i, 7));
+ EXPECT_EQ(message.repeated_foreign_message(i).c(), Func(i, 7));
+ }
+
+#ifdef PROTOBUF_HAS_DEATH_TEST
+ // Make sure types are checked correctly at runtime.
+ const FieldDescriptor* fd_optional_int32 =
+ desc->FindFieldByName("optional_int32");
+ EXPECT_DEATH(refl->GetRepeatedField<int32>(message, fd_optional_int32),
+ "requires a repeated field");
+ EXPECT_DEATH(refl->GetRepeatedField<double>(message, fd_repeated_int32),
+ "not the right type");
+ EXPECT_DEATH(refl->GetRepeatedPtrField<TestAllTypes>(
+ message, fd_repeated_foreign_message),
+ "wrong submessage type");
+#endif // PROTOBUF_HAS_DEATH_TEST
+}
+
+
+TEST(RepeatedFieldReflectionTest, ExtensionFields) {
+ TestAllExtensions extended_message;
+ const Reflection* refl = extended_message.GetReflection();
+ const Descriptor* desc = extended_message.GetDescriptor();
+
+ for (int i = 0; i < 10; ++i) {
+ extended_message.AddExtension(unittest::repeated_int64_extension,
+ Func(i, 1));
+ }
+
+ const FieldDescriptor* fd_repeated_int64_extension =
+ desc->file()->FindExtensionByName("repeated_int64_extension");
+ GOOGLE_CHECK(fd_repeated_int64_extension != nullptr);
+
+ const RepeatedField<int64>& rf_int64_extension =
+ refl->GetRepeatedField<int64>(extended_message,
+ fd_repeated_int64_extension);
+
+ RepeatedField<int64>* mrf_int64_extension = refl->MutableRepeatedField<int64>(
+ &extended_message, fd_repeated_int64_extension);
+
+ for (int i = 0; i < 10; ++i) {
+ EXPECT_EQ(Func(i, 1), rf_int64_extension.Get(i));
+ mrf_int64_extension->Set(i, Func(i, -1));
+ EXPECT_EQ(Func(i, -1), extended_message.GetExtension(
+ unittest::repeated_int64_extension, i));
+ }
+}
+
+template <typename Ref, typename MessageType, typename ValueType>
+void TestRepeatedFieldRefIteratorForPrimitive(
+ const Ref& handle, const MessageType& message,
+ ValueType (MessageType::*GetFunc)(int) const) {
+ int index = 0;
+ for (typename Ref::const_iterator it = handle.begin(); it != handle.end();
+ ++it) {
+ EXPECT_EQ((message.*GetFunc)(index), *it);
+ ++index;
+ }
+ EXPECT_EQ(handle.size(), index);
+}
+
+template <typename MessageType, typename ValueType>
+void TestRepeatedFieldRefIteratorForString(
+ const RepeatedFieldRef<std::string>& handle, const MessageType& message,
+ ValueType (MessageType::*GetFunc)(int) const) {
+ int index = 0;
+ for (typename RepeatedFieldRef<std::string>::const_iterator it =
+ handle.begin();
+ it != handle.end(); ++it) {
+ // Test both operator* and operator->
+ EXPECT_EQ((message.*GetFunc)(index), *it);
+ EXPECT_EQ((message.*GetFunc)(index).size(), it->size());
+ ++index;
+ }
+ EXPECT_EQ(handle.size(), index);
+}
+
+TEST(RepeatedFieldReflectionTest, RepeatedFieldRefForRegularFields) {
+ TestAllTypes message;
+ const Reflection* refl = message.GetReflection();
+ const Descriptor* desc = message.GetDescriptor();
+
+ for (int i = 0; i < 10; ++i) {
+ message.add_repeated_int32(Func(i, 1));
+ message.add_repeated_double(Func(i, 2));
+ message.add_repeated_string(StrFunc(i, 5));
+ message.add_repeated_foreign_message()->set_c(Func(i, 6));
+ }
+
+ // Get FieldDescriptors for all the fields of interest.
+ const FieldDescriptor* fd_repeated_int32 =
+ desc->FindFieldByName("repeated_int32");
+ const FieldDescriptor* fd_repeated_double =
+ desc->FindFieldByName("repeated_double");
+ const FieldDescriptor* fd_repeated_string =
+ desc->FindFieldByName("repeated_string");
+ const FieldDescriptor* fd_repeated_foreign_message =
+ desc->FindFieldByName("repeated_foreign_message");
+
+ // Get RepeatedFieldRef objects for all fields of interest.
+ const RepeatedFieldRef<int32> rf_int32 =
+ refl->GetRepeatedFieldRef<int32>(message, fd_repeated_int32);
+ const RepeatedFieldRef<double> rf_double =
+ refl->GetRepeatedFieldRef<double>(message, fd_repeated_double);
+ const RepeatedFieldRef<std::string> rf_string =
+ refl->GetRepeatedFieldRef<std::string>(message, fd_repeated_string);
+ const RepeatedFieldRef<ForeignMessage> rf_foreign_message =
+ refl->GetRepeatedFieldRef<ForeignMessage>(message,
+ fd_repeated_foreign_message);
+ const RepeatedFieldRef<Message> rf_message =
+ refl->GetRepeatedFieldRef<Message>(message, fd_repeated_foreign_message);
+
+ // Get MutableRepeatedFieldRef objects for all fields of interest.
+ const MutableRepeatedFieldRef<int32> mrf_int32 =
+ refl->GetMutableRepeatedFieldRef<int32>(&message, fd_repeated_int32);
+ const MutableRepeatedFieldRef<double> mrf_double =
+ refl->GetMutableRepeatedFieldRef<double>(&message, fd_repeated_double);
+ const MutableRepeatedFieldRef<std::string> mrf_string =
+ refl->GetMutableRepeatedFieldRef<std::string>(&message,
+ fd_repeated_string);
+ const MutableRepeatedFieldRef<ForeignMessage> mrf_foreign_message =
+ refl->GetMutableRepeatedFieldRef<ForeignMessage>(
+ &message, fd_repeated_foreign_message);
+ const MutableRepeatedFieldRef<Message> mrf_message =
+ refl->GetMutableRepeatedFieldRef<Message>(&message,
+ fd_repeated_foreign_message);
+
+ EXPECT_EQ(message.repeated_int32_size(), rf_int32.size());
+ EXPECT_EQ(message.repeated_int32_size(), mrf_int32.size());
+ EXPECT_EQ(message.repeated_double_size(), rf_double.size());
+ EXPECT_EQ(message.repeated_double_size(), mrf_double.size());
+ EXPECT_EQ(message.repeated_string_size(), rf_string.size());
+ EXPECT_EQ(message.repeated_string_size(), mrf_string.size());
+ EXPECT_EQ(message.repeated_foreign_message_size(), rf_foreign_message.size());
+ EXPECT_EQ(message.repeated_foreign_message_size(),
+ mrf_foreign_message.size());
+ EXPECT_EQ(message.repeated_foreign_message_size(), rf_message.size());
+ EXPECT_EQ(message.repeated_foreign_message_size(), mrf_message.size());
+
+ EXPECT_FALSE(rf_int32.empty());
+ EXPECT_FALSE(mrf_int32.empty());
+ EXPECT_FALSE(rf_double.empty());
+ EXPECT_FALSE(mrf_double.empty());
+ EXPECT_FALSE(rf_string.empty());
+ EXPECT_FALSE(mrf_string.empty());
+ EXPECT_FALSE(rf_foreign_message.empty());
+ EXPECT_FALSE(mrf_foreign_message.empty());
+ EXPECT_FALSE(rf_message.empty());
+ EXPECT_FALSE(mrf_message.empty());
+
+ // Make sure we can do gets and sets through the RepeatedFieldRef objects.
+ for (int i = 0; i < 10; ++i) {
+ // Check gets through const objects.
+ EXPECT_EQ(rf_int32.Get(i), Func(i, 1));
+ EXPECT_EQ(rf_double.Get(i), Func(i, 2));
+ EXPECT_EQ(rf_string.Get(i), StrFunc(i, 5));
+ ForeignMessage scratch_space;
+ EXPECT_EQ(rf_foreign_message.Get(i, &scratch_space).c(), Func(i, 6));
+ EXPECT_EQ(
+ down_cast<const ForeignMessage&>(rf_message.Get(i, &scratch_space)).c(),
+ Func(i, 6));
+
+ // Check gets through mutable objects.
+ EXPECT_EQ(mrf_int32.Get(i), Func(i, 1));
+ EXPECT_EQ(mrf_double.Get(i), Func(i, 2));
+ EXPECT_EQ(mrf_string.Get(i), StrFunc(i, 5));
+ EXPECT_EQ(mrf_foreign_message.Get(i, &scratch_space).c(), Func(i, 6));
+ EXPECT_EQ(
+ down_cast<const ForeignMessage&>(mrf_message.Get(i, &scratch_space))
+ .c(),
+ Func(i, 6));
+
+ // Check sets through mutable objects.
+ mrf_int32.Set(i, Func(i, -1));
+ mrf_double.Set(i, Func(i, -2));
+ mrf_string.Set(i, StrFunc(i, -5));
+ ForeignMessage foreign_message;
+ foreign_message.set_c(Func(i, -6));
+ mrf_foreign_message.Set(i, foreign_message);
+ EXPECT_EQ(message.repeated_int32(i), Func(i, -1));
+ EXPECT_EQ(message.repeated_double(i), Func(i, -2));
+ EXPECT_EQ(message.repeated_string(i), StrFunc(i, -5));
+ EXPECT_EQ(message.repeated_foreign_message(i).c(), Func(i, -6));
+ foreign_message.set_c(Func(i, 7));
+ mrf_message.Set(i, foreign_message);
+ EXPECT_EQ(message.repeated_foreign_message(i).c(), Func(i, 7));
+ }
+
+ // Test iterators.
+ TestRepeatedFieldRefIteratorForPrimitive(rf_int32, message,
+ &TestAllTypes::repeated_int32);
+ TestRepeatedFieldRefIteratorForPrimitive(rf_double, message,
+ &TestAllTypes::repeated_double);
+ TestRepeatedFieldRefIteratorForString(rf_string, message,
+ &TestAllTypes::repeated_string);
+
+ // Test iterators for message fields.
+ typedef RepeatedFieldRef<ForeignMessage>::iterator MessageIterator;
+ int index = 0;
+ for (MessageIterator it = rf_foreign_message.begin();
+ it != rf_foreign_message.end(); ++it) {
+ EXPECT_EQ(message.repeated_foreign_message(index).c(), it->c());
+ ++index;
+ }
+ EXPECT_EQ(10, index);
+
+ // Test iterator operators that are not usually used in regular for-loops.
+ // Including: post increment, assign, ==.
+ MessageIterator old_it = rf_foreign_message.begin();
+ MessageIterator new_it = old_it++;
+ EXPECT_FALSE(old_it == new_it);
+ // Check that old_it++ increments old_it once.
+ for (index = 1; old_it != rf_foreign_message.end(); ++old_it, ++index) {
+ EXPECT_EQ(message.repeated_foreign_message(index).c(), old_it->c());
+ }
+ EXPECT_EQ(10, index);
+ // Test assign operator.
+ old_it = new_it;
+ for (index = 0; old_it != rf_foreign_message.end(); ++old_it, ++index) {
+ EXPECT_EQ(message.repeated_foreign_message(index).c(), old_it->c());
+ }
+ EXPECT_EQ(10, index);
+ // Check that the returned value of old_it++ is the one before increment.
+ for (index = 0; new_it != rf_foreign_message.end(); ++new_it, ++index) {
+ EXPECT_EQ(message.repeated_foreign_message(index).c(), new_it->c());
+ }
+ EXPECT_EQ(10, index);
+
+ // Test MutableRepeatedFieldRef::Add()
+ mrf_int32.Add(1234);
+ mrf_double.Add(1234.0);
+ mrf_string.Add("1234");
+ ForeignMessage foreign_message;
+ foreign_message.set_c(1234);
+ mrf_foreign_message.Add(foreign_message);
+ EXPECT_EQ(1234, message.repeated_int32(10));
+ EXPECT_EQ(1234.0, message.repeated_double(10));
+ EXPECT_EQ("1234", message.repeated_string(10));
+ EXPECT_EQ(1234, message.repeated_foreign_message(10).c());
+
+ // Test MutableRepeatedFieldRef::RemoveLast()
+ mrf_int32.RemoveLast();
+ mrf_double.RemoveLast();
+ mrf_string.RemoveLast();
+ mrf_foreign_message.RemoveLast();
+ EXPECT_EQ(10, message.repeated_int32_size());
+ EXPECT_EQ(10, message.repeated_double_size());
+ EXPECT_EQ(10, message.repeated_string_size());
+ EXPECT_EQ(10, message.repeated_foreign_message_size());
+
+ // Test MutableRepeatedFieldRef::SwapElements()
+ mrf_int32.SwapElements(0, 9);
+ mrf_double.SwapElements(0, 9);
+ mrf_string.SwapElements(0, 9);
+ mrf_foreign_message.SwapElements(0, 9);
+ EXPECT_EQ(Func(9, -1), message.repeated_int32(0));
+ EXPECT_EQ(Func(0, -1), message.repeated_int32(9));
+ EXPECT_EQ(Func(9, -2), message.repeated_double(0));
+ EXPECT_EQ(Func(0, -2), message.repeated_double(9));
+ EXPECT_EQ(StrFunc(9, -5), message.repeated_string(0));
+ EXPECT_EQ(StrFunc(0, -5), message.repeated_string(9));
+ EXPECT_EQ(Func(9, 7), message.repeated_foreign_message(0).c());
+ EXPECT_EQ(Func(0, 7), message.repeated_foreign_message(9).c());
+
+ // Test MutableRepeatedFieldRef::Clear()
+ mrf_int32.Clear();
+ mrf_double.Clear();
+ mrf_string.Clear();
+ mrf_foreign_message.Clear();
+ EXPECT_EQ(0, message.repeated_int32_size());
+ EXPECT_EQ(0, message.repeated_double_size());
+ EXPECT_EQ(0, message.repeated_string_size());
+ EXPECT_EQ(0, message.repeated_foreign_message_size());
+
+ // Test (Mutable)RepeatedFieldRef::empty()
+ EXPECT_TRUE(rf_int32.empty());
+ EXPECT_TRUE(mrf_int32.empty());
+ EXPECT_TRUE(rf_double.empty());
+ EXPECT_TRUE(mrf_double.empty());
+ EXPECT_TRUE(rf_string.empty());
+ EXPECT_TRUE(mrf_string.empty());
+ EXPECT_TRUE(rf_foreign_message.empty());
+ EXPECT_TRUE(mrf_foreign_message.empty());
+ EXPECT_TRUE(rf_message.empty());
+ EXPECT_TRUE(mrf_message.empty());
+
+#ifdef PROTOBUF_HAS_DEATH_TEST
+
+ // Make sure types are checked correctly at runtime.
+ const FieldDescriptor* fd_optional_int32 =
+ desc->FindFieldByName("optional_int32");
+ EXPECT_DEATH(refl->GetRepeatedFieldRef<int32>(message, fd_optional_int32),
+ "");
+ EXPECT_DEATH(refl->GetRepeatedFieldRef<double>(message, fd_repeated_int32),
+ "");
+ EXPECT_DEATH(refl->GetRepeatedFieldRef<TestAllTypes>(
+ message, fd_repeated_foreign_message),
+ "");
+
+#endif // PROTOBUF_HAS_DEATH_TEST
+}
+
+TEST(RepeatedFieldReflectionTest, RepeatedFieldRefForEnums) {
+ TestAllTypes message;
+ const Reflection* refl = message.GetReflection();
+ const Descriptor* desc = message.GetDescriptor();
+
+ for (int i = 0; i < 10; ++i) {
+ message.add_repeated_nested_enum(TestAllTypes::BAR);
+ }
+
+ const FieldDescriptor* fd_repeated_nested_enum =
+ desc->FindFieldByName("repeated_nested_enum");
+ const RepeatedFieldRef<TestAllTypes::NestedEnum> enum_ref =
+ refl->GetRepeatedFieldRef<TestAllTypes::NestedEnum>(
+ message, fd_repeated_nested_enum);
+ const MutableRepeatedFieldRef<TestAllTypes::NestedEnum> mutable_enum_ref =
+ refl->GetMutableRepeatedFieldRef<TestAllTypes::NestedEnum>(
+ &message, fd_repeated_nested_enum);
+ const RepeatedFieldRef<int32> int32_ref =
+ refl->GetRepeatedFieldRef<int32>(message, fd_repeated_nested_enum);
+ const MutableRepeatedFieldRef<int32> mutable_int32_ref =
+ refl->GetMutableRepeatedFieldRef<int32>(&message,
+ fd_repeated_nested_enum);
+
+ EXPECT_EQ(message.repeated_nested_enum_size(), enum_ref.size());
+ EXPECT_EQ(message.repeated_nested_enum_size(), mutable_enum_ref.size());
+ EXPECT_EQ(message.repeated_nested_enum_size(), int32_ref.size());
+ EXPECT_EQ(message.repeated_nested_enum_size(), mutable_int32_ref.size());
+
+ EXPECT_FALSE(enum_ref.empty());
+ EXPECT_FALSE(mutable_enum_ref.empty());
+ EXPECT_FALSE(int32_ref.empty());
+ EXPECT_FALSE(mutable_int32_ref.empty());
+
+ for (int i = 0; i < 10; ++i) {
+ EXPECT_EQ(TestAllTypes::BAR, enum_ref.Get(i));
+ EXPECT_EQ(TestAllTypes::BAR, mutable_enum_ref.Get(i));
+ mutable_enum_ref.Set(i, TestAllTypes::BAZ);
+ EXPECT_EQ(TestAllTypes::BAZ, enum_ref.Get(i));
+ EXPECT_EQ(TestAllTypes::BAZ, message.repeated_nested_enum(i));
+
+ message.set_repeated_nested_enum(i, TestAllTypes::BAR);
+ EXPECT_EQ(TestAllTypes::BAR, int32_ref.Get(i));
+ EXPECT_EQ(TestAllTypes::BAR, mutable_int32_ref.Get(i));
+ mutable_int32_ref.Set(i, TestAllTypes::BAZ);
+ EXPECT_EQ(TestAllTypes::BAZ, int32_ref.Get(i));
+ EXPECT_EQ(TestAllTypes::BAZ, message.repeated_nested_enum(i));
+ }
+
+ TestRepeatedFieldRefIteratorForPrimitive(enum_ref, message,
+ &TestAllTypes::repeated_nested_enum);
+ TestRepeatedFieldRefIteratorForPrimitive(int32_ref, message,
+ &TestAllTypes::repeated_nested_enum);
+
+ // Test Add()
+ mutable_enum_ref.Add(TestAllTypes::FOO);
+ EXPECT_EQ(TestAllTypes::FOO, message.repeated_nested_enum(10));
+ mutable_int32_ref.Add(TestAllTypes::BAR);
+ EXPECT_EQ(TestAllTypes::BAR, message.repeated_nested_enum(11));
+
+ // Test RemoveLast()
+ mutable_enum_ref.RemoveLast();
+ EXPECT_EQ(11, message.repeated_nested_enum_size());
+ mutable_int32_ref.RemoveLast();
+ EXPECT_EQ(10, message.repeated_nested_enum_size());
+
+ // Test SwapElements()
+ mutable_enum_ref.Set(0, TestAllTypes::BAR);
+ mutable_enum_ref.Set(9, TestAllTypes::BAZ);
+ mutable_enum_ref.SwapElements(0, 9);
+ EXPECT_EQ(TestAllTypes::BAZ, enum_ref.Get(0));
+ EXPECT_EQ(TestAllTypes::BAR, enum_ref.Get(9));
+ mutable_int32_ref.SwapElements(0, 9);
+ EXPECT_EQ(TestAllTypes::BAR, enum_ref.Get(0));
+ EXPECT_EQ(TestAllTypes::BAZ, enum_ref.Get(9));
+
+ // Test Clear()
+ mutable_enum_ref.Clear();
+ EXPECT_EQ(0, message.repeated_nested_enum_size());
+ mutable_enum_ref.Add(TestAllTypes::FOO);
+ EXPECT_EQ(1, message.repeated_nested_enum_size());
+ mutable_int32_ref.Clear();
+ EXPECT_EQ(0, message.repeated_nested_enum_size());
+
+ // Test empty()
+ EXPECT_TRUE(enum_ref.empty());
+ EXPECT_TRUE(mutable_enum_ref.empty());
+ EXPECT_TRUE(int32_ref.empty());
+ EXPECT_TRUE(mutable_int32_ref.empty());
+}
+
+TEST(RepeatedFieldReflectionTest, RepeatedFieldRefForExtensionFields) {
+ TestAllExtensions extended_message;
+ const Reflection* refl = extended_message.GetReflection();
+ const Descriptor* desc = extended_message.GetDescriptor();
+
+ for (int i = 0; i < 10; ++i) {
+ extended_message.AddExtension(unittest::repeated_int64_extension,
+ Func(i, 1));
+ }
+
+ const FieldDescriptor* fd_repeated_int64_extension =
+ desc->file()->FindExtensionByName("repeated_int64_extension");
+ GOOGLE_CHECK(fd_repeated_int64_extension != nullptr);
+
+ const RepeatedFieldRef<int64> rf_int64_extension =
+ refl->GetRepeatedFieldRef<int64>(extended_message,
+ fd_repeated_int64_extension);
+
+ const MutableRepeatedFieldRef<int64> mrf_int64_extension =
+ refl->GetMutableRepeatedFieldRef<int64>(&extended_message,
+ fd_repeated_int64_extension);
+
+ for (int i = 0; i < 10; ++i) {
+ EXPECT_EQ(Func(i, 1), rf_int64_extension.Get(i));
+ mrf_int64_extension.Set(i, Func(i, -1));
+ EXPECT_EQ(Func(i, -1), extended_message.GetExtension(
+ unittest::repeated_int64_extension, i));
+ }
+}
+
+
+TEST(RepeatedFieldReflectionTest, RepeatedFieldRefMergeFromAndSwap) {
+ // Set-up message content.
+ TestAllTypes m0, m1, m2;
+ for (int i = 0; i < 10; ++i) {
+ m0.add_repeated_int32(Func(i, 1));
+ m0.add_repeated_double(Func(i, 2));
+ m0.add_repeated_string(StrFunc(i, 5));
+ m0.add_repeated_foreign_message()->set_c(Func(i, 6));
+ m0.add_repeated_nested_enum(TestAllTypes::FOO);
+ m1.add_repeated_int32(Func(i, 11));
+ m1.add_repeated_double(Func(i, 12));
+ m1.add_repeated_string(StrFunc(i, 15));
+ m1.add_repeated_foreign_message()->set_c(Func(i, 16));
+ m1.add_repeated_nested_enum(TestAllTypes::BAR);
+ m2.add_repeated_int32(Func(i, 21));
+ m2.add_repeated_double(Func(i, 22));
+ m2.add_repeated_string(StrFunc(i, 25));
+ m2.add_repeated_foreign_message()->set_c(Func(i, 26));
+ m2.add_repeated_nested_enum(TestAllTypes::BAZ);
+ }
+
+ const Reflection* refl = m0.GetReflection();
+ const Descriptor* desc = m0.GetDescriptor();
+
+ // Get FieldDescriptors for all the fields of interest.
+ const FieldDescriptor* fd_repeated_int32 =
+ desc->FindFieldByName("repeated_int32");
+ const FieldDescriptor* fd_repeated_double =
+ desc->FindFieldByName("repeated_double");
+ const FieldDescriptor* fd_repeated_string =
+ desc->FindFieldByName("repeated_string");
+ const FieldDescriptor* fd_repeated_foreign_message =
+ desc->FindFieldByName("repeated_foreign_message");
+ const FieldDescriptor* fd_repeated_nested_enum =
+ desc->FindFieldByName("repeated_nested_enum");
+
+ // Get MutableRepeatedFieldRef objects for all fields of interest.
+ const MutableRepeatedFieldRef<int32> mrf_int32 =
+ refl->GetMutableRepeatedFieldRef<int32>(&m0, fd_repeated_int32);
+ const MutableRepeatedFieldRef<double> mrf_double =
+ refl->GetMutableRepeatedFieldRef<double>(&m0, fd_repeated_double);
+ const MutableRepeatedFieldRef<std::string> mrf_string =
+ refl->GetMutableRepeatedFieldRef<std::string>(&m0, fd_repeated_string);
+ const MutableRepeatedFieldRef<ForeignMessage> mrf_foreign_message =
+ refl->GetMutableRepeatedFieldRef<ForeignMessage>(
+ &m0, fd_repeated_foreign_message);
+ const MutableRepeatedFieldRef<TestAllTypes::NestedEnum> mrf_nested_enum =
+ refl->GetMutableRepeatedFieldRef<TestAllTypes::NestedEnum>(
+ &m0, fd_repeated_nested_enum);
+
+ // Test MutableRepeatedRef::CopyFrom
+ mrf_int32.CopyFrom(refl->GetRepeatedFieldRef<int32>(m1, fd_repeated_int32));
+ mrf_double.CopyFrom(
+ refl->GetRepeatedFieldRef<double>(m1, fd_repeated_double));
+ mrf_string.CopyFrom(
+ refl->GetRepeatedFieldRef<std::string>(m1, fd_repeated_string));
+ mrf_foreign_message.CopyFrom(refl->GetRepeatedFieldRef<ForeignMessage>(
+ m1, fd_repeated_foreign_message));
+ mrf_nested_enum.CopyFrom(refl->GetRepeatedFieldRef<TestAllTypes::NestedEnum>(
+ m1, fd_repeated_nested_enum));
+ for (int i = 0; i < 10; ++i) {
+ EXPECT_EQ(Func(i, 11), m0.repeated_int32(i));
+ EXPECT_EQ(Func(i, 12), m0.repeated_double(i));
+ EXPECT_EQ(StrFunc(i, 15), m0.repeated_string(i));
+ EXPECT_EQ(Func(i, 16), m0.repeated_foreign_message(i).c());
+ EXPECT_EQ(TestAllTypes::BAR, m0.repeated_nested_enum(i));
+ }
+
+ // Test MutableRepeatedRef::MergeFrom
+ mrf_int32.MergeFrom(refl->GetRepeatedFieldRef<int32>(m2, fd_repeated_int32));
+ mrf_double.MergeFrom(
+ refl->GetRepeatedFieldRef<double>(m2, fd_repeated_double));
+ mrf_string.MergeFrom(
+ refl->GetRepeatedFieldRef<std::string>(m2, fd_repeated_string));
+ mrf_foreign_message.MergeFrom(refl->GetRepeatedFieldRef<ForeignMessage>(
+ m2, fd_repeated_foreign_message));
+ mrf_nested_enum.MergeFrom(refl->GetRepeatedFieldRef<TestAllTypes::NestedEnum>(
+ m2, fd_repeated_nested_enum));
+ for (int i = 0; i < 10; ++i) {
+ EXPECT_EQ(Func(i, 21), m0.repeated_int32(i + 10));
+ EXPECT_EQ(Func(i, 22), m0.repeated_double(i + 10));
+ EXPECT_EQ(StrFunc(i, 25), m0.repeated_string(i + 10));
+ EXPECT_EQ(Func(i, 26), m0.repeated_foreign_message(i + 10).c());
+ EXPECT_EQ(TestAllTypes::BAZ, m0.repeated_nested_enum(i + 10));
+ }
+
+ // Test MutableRepeatedRef::Swap
+ // Swap between m0 and m2.
+ mrf_int32.Swap(
+ refl->GetMutableRepeatedFieldRef<int32>(&m2, fd_repeated_int32));
+ mrf_double.Swap(
+ refl->GetMutableRepeatedFieldRef<double>(&m2, fd_repeated_double));
+ mrf_string.Swap(
+ refl->GetMutableRepeatedFieldRef<std::string>(&m2, fd_repeated_string));
+ mrf_foreign_message.Swap(refl->GetMutableRepeatedFieldRef<ForeignMessage>(
+ &m2, fd_repeated_foreign_message));
+ mrf_nested_enum.Swap(
+ refl->GetMutableRepeatedFieldRef<TestAllTypes::NestedEnum>(
+ &m2, fd_repeated_nested_enum));
+ for (int i = 0; i < 10; ++i) {
+ // Check the content of m0.
+ EXPECT_EQ(Func(i, 21), m0.repeated_int32(i));
+ EXPECT_EQ(Func(i, 22), m0.repeated_double(i));
+ EXPECT_EQ(StrFunc(i, 25), m0.repeated_string(i));
+ EXPECT_EQ(Func(i, 26), m0.repeated_foreign_message(i).c());
+ EXPECT_EQ(TestAllTypes::BAZ, m0.repeated_nested_enum(i));
+
+ // Check the content of m2.
+ EXPECT_EQ(Func(i, 11), m2.repeated_int32(i));
+ EXPECT_EQ(Func(i, 12), m2.repeated_double(i));
+ EXPECT_EQ(StrFunc(i, 15), m2.repeated_string(i));
+ EXPECT_EQ(Func(i, 16), m2.repeated_foreign_message(i).c());
+ EXPECT_EQ(TestAllTypes::BAR, m2.repeated_nested_enum(i));
+ EXPECT_EQ(Func(i, 21), m2.repeated_int32(i + 10));
+ EXPECT_EQ(Func(i, 22), m2.repeated_double(i + 10));
+ EXPECT_EQ(StrFunc(i, 25), m2.repeated_string(i + 10));
+ EXPECT_EQ(Func(i, 26), m2.repeated_foreign_message(i + 10).c());
+ EXPECT_EQ(TestAllTypes::BAZ, m2.repeated_nested_enum(i + 10));
+ }
+}
+
+// Test that GetRepeatedFieldRef/MutableRepeatedFieldRef works with
+// DynamicMessage.
+TEST(RepeatedFieldReflectionTest, RepeatedFieldRefDynamicMessage) {
+ // DynamicMessage shares the same memory layout as generated message
+ // and use the same GeneratedMessageReflection code for reflection.
+ // All code paths should already be covered by the other tests for
+ // generated messages. Here we just test one field.
+
+ const Descriptor* desc = TestAllTypes::descriptor();
+ const FieldDescriptor* fd_repeated_int32 =
+ desc->FindFieldByName("repeated_int32");
+
+ DynamicMessageFactory factory;
+ std::unique_ptr<Message> dynamic_message(factory.GetPrototype(desc)->New());
+ const Reflection* refl = dynamic_message->GetReflection();
+
+ MutableRepeatedFieldRef<int32> rf_int32 =
+ refl->GetMutableRepeatedFieldRef<int32>(dynamic_message.get(),
+ fd_repeated_int32);
+ rf_int32.Add(1234);
+ EXPECT_EQ(1, refl->FieldSize(*dynamic_message, fd_repeated_int32));
+ EXPECT_EQ(1234,
+ refl->GetRepeatedInt32(*dynamic_message, fd_repeated_int32, 0));
+}
+
+} // namespace
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/repeated_field_unittest.cc b/NorthstarDedicatedTest/include/protobuf/repeated_field_unittest.cc
new file mode 100644
index 00000000..92b7e672
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/repeated_field_unittest.cc
@@ -0,0 +1,2187 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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.
+//
+// TODO(kenton): Improve this unittest to bring it up to the standards of
+// other proto2 unittests.
+
+#include <repeated_field.h>
+
+#include <algorithm>
+#include <cstdlib>
+#include <iterator>
+#include <limits>
+#include <list>
+#include <sstream>
+#include <type_traits>
+#include <vector>
+
+#include <stubs/logging.h>
+#include <stubs/common.h>
+#include <unittest.pb.h>
+#include <stubs/strutil.h>
+#include <gmock/gmock.h>
+#include <testing/googletest.h>
+#include <gtest/gtest.h>
+#include <stubs/stl_util.h>
+
+// Must be included last.
+#include <port_def.inc>
+
+namespace google {
+namespace protobuf {
+namespace {
+
+using ::protobuf_unittest::TestAllTypes;
+using ::testing::ElementsAre;
+
+TEST(RepeatedField, ConstInit) {
+ PROTOBUF_CONSTINIT static RepeatedField<int> field{}; // NOLINT
+ EXPECT_TRUE(field.empty());
+}
+
+// Test operations on a small RepeatedField.
+TEST(RepeatedField, Small) {
+ RepeatedField<int> field;
+
+ EXPECT_TRUE(field.empty());
+ EXPECT_EQ(field.size(), 0);
+
+ field.Add(5);
+
+ EXPECT_FALSE(field.empty());
+ EXPECT_EQ(field.size(), 1);
+ EXPECT_EQ(field.Get(0), 5);
+ EXPECT_EQ(field.at(0), 5);
+
+ field.Add(42);
+
+ EXPECT_FALSE(field.empty());
+ EXPECT_EQ(field.size(), 2);
+ EXPECT_EQ(field.Get(0), 5);
+ EXPECT_EQ(field.at(0), 5);
+ EXPECT_EQ(field.Get(1), 42);
+ EXPECT_EQ(field.at(1), 42);
+
+ field.Set(1, 23);
+
+ EXPECT_FALSE(field.empty());
+ EXPECT_EQ(field.size(), 2);
+ EXPECT_EQ(field.Get(0), 5);
+ EXPECT_EQ(field.at(0), 5);
+ EXPECT_EQ(field.Get(1), 23);
+ EXPECT_EQ(field.at(1), 23);
+
+ field.at(1) = 25;
+
+ EXPECT_FALSE(field.empty());
+ EXPECT_EQ(field.size(), 2);
+ EXPECT_EQ(field.Get(0), 5);
+ EXPECT_EQ(field.at(0), 5);
+ EXPECT_EQ(field.Get(1), 25);
+ EXPECT_EQ(field.at(1), 25);
+
+ field.RemoveLast();
+
+ EXPECT_FALSE(field.empty());
+ EXPECT_EQ(field.size(), 1);
+ EXPECT_EQ(field.Get(0), 5);
+ EXPECT_EQ(field.at(0), 5);
+
+ field.Clear();
+
+ EXPECT_TRUE(field.empty());
+ EXPECT_EQ(field.size(), 0);
+ // Additional bytes are for 'struct Rep' header.
+ int expected_usage = 4 * sizeof(int) + sizeof(Arena*);
+ EXPECT_GE(field.SpaceUsedExcludingSelf(), expected_usage);
+}
+
+
+// Test operations on a RepeatedField which is large enough to allocate a
+// separate array.
+TEST(RepeatedField, Large) {
+ RepeatedField<int> field;
+
+ for (int i = 0; i < 16; i++) {
+ field.Add(i * i);
+ }
+
+ EXPECT_FALSE(field.empty());
+ EXPECT_EQ(field.size(), 16);
+
+ for (int i = 0; i < 16; i++) {
+ EXPECT_EQ(field.Get(i), i * i);
+ }
+
+ int expected_usage = 16 * sizeof(int);
+ EXPECT_GE(field.SpaceUsedExcludingSelf(), expected_usage);
+}
+
+// Test swapping between various types of RepeatedFields.
+TEST(RepeatedField, SwapSmallSmall) {
+ RepeatedField<int> field1;
+ RepeatedField<int> field2;
+
+ field1.Add(5);
+ field1.Add(42);
+
+ EXPECT_FALSE(field1.empty());
+ EXPECT_EQ(field1.size(), 2);
+ EXPECT_EQ(field1.Get(0), 5);
+ EXPECT_EQ(field1.Get(1), 42);
+
+ EXPECT_TRUE(field2.empty());
+ EXPECT_EQ(field2.size(), 0);
+
+ field1.Swap(&field2);
+
+ EXPECT_TRUE(field1.empty());
+ EXPECT_EQ(field1.size(), 0);
+
+ EXPECT_FALSE(field2.empty());
+ EXPECT_EQ(field2.size(), 2);
+ EXPECT_EQ(field2.Get(0), 5);
+ EXPECT_EQ(field2.Get(1), 42);
+}
+
+TEST(RepeatedField, SwapLargeSmall) {
+ RepeatedField<int> field1;
+ RepeatedField<int> field2;
+
+ for (int i = 0; i < 16; i++) {
+ field1.Add(i * i);
+ }
+ field2.Add(5);
+ field2.Add(42);
+ field1.Swap(&field2);
+
+ EXPECT_EQ(field1.size(), 2);
+ EXPECT_EQ(field1.Get(0), 5);
+ EXPECT_EQ(field1.Get(1), 42);
+ EXPECT_EQ(field2.size(), 16);
+ for (int i = 0; i < 16; i++) {
+ EXPECT_EQ(field2.Get(i), i * i);
+ }
+}
+
+TEST(RepeatedField, SwapLargeLarge) {
+ RepeatedField<int> field1;
+ RepeatedField<int> field2;
+
+ field1.Add(5);
+ field1.Add(42);
+ for (int i = 0; i < 16; i++) {
+ field1.Add(i);
+ field2.Add(i * i);
+ }
+ field2.Swap(&field1);
+
+ EXPECT_EQ(field1.size(), 16);
+ for (int i = 0; i < 16; i++) {
+ EXPECT_EQ(field1.Get(i), i * i);
+ }
+ EXPECT_EQ(field2.size(), 18);
+ EXPECT_EQ(field2.Get(0), 5);
+ EXPECT_EQ(field2.Get(1), 42);
+ for (int i = 2; i < 18; i++) {
+ EXPECT_EQ(field2.Get(i), i - 2);
+ }
+}
+
+// Determines how much space was reserved by the given field by adding elements
+// to it until it re-allocates its space.
+static int ReservedSpace(RepeatedField<int>* field) {
+ const int* ptr = field->data();
+ do {
+ field->Add(0);
+ } while (field->data() == ptr);
+
+ return field->size() - 1;
+}
+
+TEST(RepeatedField, ReserveMoreThanDouble) {
+ // Reserve more than double the previous space in the field and expect the
+ // field to reserve exactly the amount specified.
+ RepeatedField<int> field;
+ field.Reserve(20);
+
+ EXPECT_LE(20, ReservedSpace(&field));
+}
+
+TEST(RepeatedField, ReserveLessThanDouble) {
+ // Reserve less than double the previous space in the field and expect the
+ // field to grow by double instead.
+ RepeatedField<int> field;
+ field.Reserve(20);
+ int capacity = field.Capacity();
+ field.Reserve(capacity * 1.5);
+
+ EXPECT_LE(2 * capacity, ReservedSpace(&field));
+}
+
+TEST(RepeatedField, ReserveLessThanExisting) {
+ // Reserve less than the previous space in the field and expect the
+ // field to not re-allocate at all.
+ RepeatedField<int> field;
+ field.Reserve(20);
+ const int* previous_ptr = field.data();
+ field.Reserve(10);
+
+ EXPECT_EQ(previous_ptr, field.data());
+ EXPECT_LE(20, ReservedSpace(&field));
+}
+
+TEST(RepeatedField, Resize) {
+ RepeatedField<int> field;
+ field.Resize(2, 1);
+ EXPECT_EQ(2, field.size());
+ field.Resize(5, 2);
+ EXPECT_EQ(5, field.size());
+ field.Resize(4, 3);
+ ASSERT_EQ(4, field.size());
+ EXPECT_EQ(1, field.Get(0));
+ EXPECT_EQ(1, field.Get(1));
+ EXPECT_EQ(2, field.Get(2));
+ EXPECT_EQ(2, field.Get(3));
+ field.Resize(0, 4);
+ EXPECT_TRUE(field.empty());
+}
+
+TEST(RepeatedField, ReserveNothing) {
+ RepeatedField<int> field;
+ EXPECT_EQ(0, field.Capacity());
+
+ field.Reserve(-1);
+ EXPECT_EQ(0, field.Capacity());
+}
+
+TEST(RepeatedField, ReserveLowerClamp) {
+ const int clamped_value = internal::CalculateReserveSize(0, 1);
+ EXPECT_EQ(internal::kRepeatedFieldLowerClampLimit, clamped_value);
+ EXPECT_EQ(clamped_value, internal::CalculateReserveSize(clamped_value, 2));
+}
+
+TEST(RepeatedField, ReserveGrowth) {
+ // Make sure the field capacity doubles in size on repeated reservation.
+ for (int size = internal::kRepeatedFieldLowerClampLimit, i = 0; i < 4;
+ ++i, size *= 2) {
+ EXPECT_EQ(size * 2, internal::CalculateReserveSize(size, size + 1));
+ }
+}
+
+TEST(RepeatedField, ReserveLarge) {
+ const int old_size = 10;
+ // This is a size we won't get by doubling:
+ const int new_size = old_size * 3 + 1;
+
+ // Reserving more than 2x current capacity should grow directly to that size.
+ EXPECT_EQ(new_size, internal::CalculateReserveSize(old_size, new_size));
+}
+
+TEST(RepeatedField, ReserveHuge) {
+ // Largest value that does not clamp to the large limit:
+ constexpr int non_clamping_limit = std::numeric_limits<int>::max() / 2;
+ ASSERT_LT(2 * non_clamping_limit, std::numeric_limits<int>::max());
+ EXPECT_LT(internal::CalculateReserveSize(non_clamping_limit,
+ non_clamping_limit + 1),
+ std::numeric_limits<int>::max());
+
+ // Smallest size that *will* clamp to the upper limit:
+ constexpr int min_clamping_size = std::numeric_limits<int>::max() / 2 + 1;
+ EXPECT_EQ(
+ internal::CalculateReserveSize(min_clamping_size, min_clamping_size + 1),
+ std::numeric_limits<int>::max());
+
+#ifdef PROTOBUF_TEST_ALLOW_LARGE_ALLOC
+ // The rest of this test may allocate several GB of memory, so it is only
+ // built if explicitly requested.
+ RepeatedField<int> huge_field;
+
+ // Reserve a size for huge_field that will clamp.
+ huge_field.Reserve(min_clamping_size);
+ EXPECT_GE(huge_field.Capacity(), min_clamping_size);
+ ASSERT_LT(huge_field.Capacity(), std::numeric_limits<int>::max() - 1);
+
+#ifndef PROTOBUF_ASAN
+ // The array containing all the fields is, in theory, up to MAXINT-1 in size.
+ // However, some compilers can't handle a struct whose size is larger
+ // than 2GB, and the protocol buffer format doesn't handle more than 2GB of
+ // data at once, either. So we limit it, but the code below accesses beyond
+ // that limit.
+
+ // Allocation may return more memory than we requested. However, the updated
+ // size must still be clamped to a valid range.
+ huge_field.Reserve(huge_field.Capacity() + 1);
+ EXPECT_EQ(huge_field.Capacity(), std::numeric_limits<int>::max());
+#endif // PROTOBUF_ASAN
+#endif // PROTOBUF_TEST_ALLOW_LARGE_ALLOC
+}
+
+TEST(RepeatedField, MergeFrom) {
+ RepeatedField<int> source, destination;
+ source.Add(4);
+ source.Add(5);
+ destination.Add(1);
+ destination.Add(2);
+ destination.Add(3);
+
+ destination.MergeFrom(source);
+
+ ASSERT_EQ(5, destination.size());
+ EXPECT_EQ(1, destination.Get(0));
+ EXPECT_EQ(2, destination.Get(1));
+ EXPECT_EQ(3, destination.Get(2));
+ EXPECT_EQ(4, destination.Get(3));
+ EXPECT_EQ(5, destination.Get(4));
+}
+
+
+TEST(RepeatedField, CopyFrom) {
+ RepeatedField<int> source, destination;
+ source.Add(4);
+ source.Add(5);
+ destination.Add(1);
+ destination.Add(2);
+ destination.Add(3);
+
+ destination.CopyFrom(source);
+
+ ASSERT_EQ(2, destination.size());
+ EXPECT_EQ(4, destination.Get(0));
+ EXPECT_EQ(5, destination.Get(1));
+}
+
+TEST(RepeatedField, CopyFromSelf) {
+ RepeatedField<int> me;
+ me.Add(3);
+ me.CopyFrom(me);
+ ASSERT_EQ(1, me.size());
+ EXPECT_EQ(3, me.Get(0));
+}
+
+TEST(RepeatedField, Erase) {
+ RepeatedField<int> me;
+ RepeatedField<int>::iterator it = me.erase(me.begin(), me.end());
+ EXPECT_TRUE(me.begin() == it);
+ EXPECT_EQ(0, me.size());
+
+ me.Add(1);
+ me.Add(2);
+ me.Add(3);
+ it = me.erase(me.begin(), me.end());
+ EXPECT_TRUE(me.begin() == it);
+ EXPECT_EQ(0, me.size());
+
+ me.Add(4);
+ me.Add(5);
+ me.Add(6);
+ it = me.erase(me.begin() + 2, me.end());
+ EXPECT_TRUE(me.begin() + 2 == it);
+ EXPECT_EQ(2, me.size());
+ EXPECT_EQ(4, me.Get(0));
+ EXPECT_EQ(5, me.Get(1));
+
+ me.Add(6);
+ me.Add(7);
+ me.Add(8);
+ it = me.erase(me.begin() + 1, me.begin() + 3);
+ EXPECT_TRUE(me.begin() + 1 == it);
+ EXPECT_EQ(3, me.size());
+ EXPECT_EQ(4, me.Get(0));
+ EXPECT_EQ(7, me.Get(1));
+ EXPECT_EQ(8, me.Get(2));
+}
+
+// Add contents of empty container to an empty field.
+TEST(RepeatedField, AddRange1) {
+ RepeatedField<int> me;
+ std::vector<int> values;
+
+ me.Add(values.begin(), values.end());
+ ASSERT_EQ(me.size(), 0);
+}
+
+// Add contents of container with one thing to an empty field.
+TEST(RepeatedField, AddRange2) {
+ RepeatedField<int> me;
+ std::vector<int> values;
+ values.push_back(-1);
+
+ me.Add(values.begin(), values.end());
+ ASSERT_EQ(me.size(), 1);
+ ASSERT_EQ(me.Get(0), values[0]);
+}
+
+// Add contents of container with more than one thing to an empty field.
+TEST(RepeatedField, AddRange3) {
+ RepeatedField<int> me;
+ std::vector<int> values;
+ values.push_back(0);
+ values.push_back(1);
+
+ me.Add(values.begin(), values.end());
+ ASSERT_EQ(me.size(), 2);
+ ASSERT_EQ(me.Get(0), values[0]);
+ ASSERT_EQ(me.Get(1), values[1]);
+}
+
+// Add contents of container with more than one thing to a non-empty field.
+TEST(RepeatedField, AddRange4) {
+ RepeatedField<int> me;
+ me.Add(0);
+ me.Add(1);
+
+ std::vector<int> values;
+ values.push_back(2);
+ values.push_back(3);
+
+ me.Add(values.begin(), values.end());
+ ASSERT_EQ(me.size(), 4);
+ ASSERT_EQ(me.Get(0), 0);
+ ASSERT_EQ(me.Get(1), 1);
+ ASSERT_EQ(me.Get(2), values[0]);
+ ASSERT_EQ(me.Get(3), values[1]);
+}
+
+// Add contents of a stringstream in order to test code paths where there is
+// an input iterator.
+TEST(RepeatedField, AddRange5) {
+ RepeatedField<int> me;
+
+ std::stringstream ss;
+ ss << 1 << ' ' << 2;
+
+ me.Add(std::istream_iterator<int>(ss), std::istream_iterator<int>());
+ ASSERT_EQ(me.size(), 2);
+ ASSERT_EQ(me.Get(0), 1);
+ ASSERT_EQ(me.Get(1), 2);
+}
+
+TEST(RepeatedField, AddAndAssignRanges) {
+ RepeatedField<int> field;
+
+ int vals[] = {2, 27, 2875, 609250};
+ field.Assign(std::begin(vals), std::end(vals));
+
+ ASSERT_EQ(field.size(), 4);
+ EXPECT_EQ(field.Get(0), 2);
+ EXPECT_EQ(field.Get(1), 27);
+ EXPECT_EQ(field.Get(2), 2875);
+ EXPECT_EQ(field.Get(3), 609250);
+
+ field.Add(std::begin(vals), std::end(vals));
+ ASSERT_EQ(field.size(), 8);
+ EXPECT_EQ(field.Get(0), 2);
+ EXPECT_EQ(field.Get(1), 27);
+ EXPECT_EQ(field.Get(2), 2875);
+ EXPECT_EQ(field.Get(3), 609250);
+ EXPECT_EQ(field.Get(4), 2);
+ EXPECT_EQ(field.Get(5), 27);
+ EXPECT_EQ(field.Get(6), 2875);
+ EXPECT_EQ(field.Get(7), 609250);
+}
+
+TEST(RepeatedField, CopyConstruct) {
+ RepeatedField<int> source;
+ source.Add(1);
+ source.Add(2);
+
+ RepeatedField<int> destination(source);
+
+ ASSERT_EQ(2, destination.size());
+ EXPECT_EQ(1, destination.Get(0));
+ EXPECT_EQ(2, destination.Get(1));
+}
+
+TEST(RepeatedField, IteratorConstruct) {
+ std::vector<int> values;
+ RepeatedField<int> empty(values.begin(), values.end());
+ ASSERT_EQ(values.size(), empty.size());
+
+ values.push_back(1);
+ values.push_back(2);
+
+ RepeatedField<int> field(values.begin(), values.end());
+ ASSERT_EQ(values.size(), field.size());
+ EXPECT_EQ(values[0], field.Get(0));
+ EXPECT_EQ(values[1], field.Get(1));
+
+ RepeatedField<int> other(field.begin(), field.end());
+ ASSERT_EQ(values.size(), other.size());
+ EXPECT_EQ(values[0], other.Get(0));
+ EXPECT_EQ(values[1], other.Get(1));
+}
+
+TEST(RepeatedField, CopyAssign) {
+ RepeatedField<int> source, destination;
+ source.Add(4);
+ source.Add(5);
+ destination.Add(1);
+ destination.Add(2);
+ destination.Add(3);
+
+ destination = source;
+
+ ASSERT_EQ(2, destination.size());
+ EXPECT_EQ(4, destination.Get(0));
+ EXPECT_EQ(5, destination.Get(1));
+}
+
+TEST(RepeatedField, SelfAssign) {
+ // Verify that assignment to self does not destroy data.
+ RepeatedField<int> source, *p;
+ p = &source;
+ source.Add(7);
+ source.Add(8);
+
+ *p = source;
+
+ ASSERT_EQ(2, source.size());
+ EXPECT_EQ(7, source.Get(0));
+ EXPECT_EQ(8, source.Get(1));
+}
+
+TEST(RepeatedField, MoveConstruct) {
+ {
+ RepeatedField<int> source;
+ source.Add(1);
+ source.Add(2);
+ const int* data = source.data();
+ RepeatedField<int> destination = std::move(source);
+ EXPECT_EQ(data, destination.data());
+ EXPECT_THAT(destination, ElementsAre(1, 2));
+ // This property isn't guaranteed but it's useful to have a test that would
+ // catch changes in this area.
+ EXPECT_TRUE(source.empty());
+ }
+ {
+ Arena arena;
+ RepeatedField<int>* source =
+ Arena::CreateMessage<RepeatedField<int>>(&arena);
+ source->Add(1);
+ source->Add(2);
+ RepeatedField<int> destination = std::move(*source);
+ EXPECT_EQ(nullptr, destination.GetArena());
+ EXPECT_THAT(destination, ElementsAre(1, 2));
+ // This property isn't guaranteed but it's useful to have a test that would
+ // catch changes in this area.
+ EXPECT_THAT(*source, ElementsAre(1, 2));
+ }
+}
+
+TEST(RepeatedField, MoveAssign) {
+ {
+ RepeatedField<int> source;
+ source.Add(1);
+ source.Add(2);
+ RepeatedField<int> destination;
+ destination.Add(3);
+ const int* source_data = source.data();
+ const int* destination_data = destination.data();
+ destination = std::move(source);
+ EXPECT_EQ(source_data, destination.data());
+ EXPECT_THAT(destination, ElementsAre(1, 2));
+ // This property isn't guaranteed but it's useful to have a test that would
+ // catch changes in this area.
+ EXPECT_EQ(destination_data, source.data());
+ EXPECT_THAT(source, ElementsAre(3));
+ }
+ {
+ Arena arena;
+ RepeatedField<int>* source =
+ Arena::CreateMessage<RepeatedField<int>>(&arena);
+ source->Add(1);
+ source->Add(2);
+ RepeatedField<int>* destination =
+ Arena::CreateMessage<RepeatedField<int>>(&arena);
+ destination->Add(3);
+ const int* source_data = source->data();
+ const int* destination_data = destination->data();
+ *destination = std::move(*source);
+ EXPECT_EQ(source_data, destination->data());
+ EXPECT_THAT(*destination, ElementsAre(1, 2));
+ // This property isn't guaranteed but it's useful to have a test that would
+ // catch changes in this area.
+ EXPECT_EQ(destination_data, source->data());
+ EXPECT_THAT(*source, ElementsAre(3));
+ }
+ {
+ Arena source_arena;
+ RepeatedField<int>* source =
+ Arena::CreateMessage<RepeatedField<int>>(&source_arena);
+ source->Add(1);
+ source->Add(2);
+ Arena destination_arena;
+ RepeatedField<int>* destination =
+ Arena::CreateMessage<RepeatedField<int>>(&destination_arena);
+ destination->Add(3);
+ *destination = std::move(*source);
+ EXPECT_THAT(*destination, ElementsAre(1, 2));
+ // This property isn't guaranteed but it's useful to have a test that would
+ // catch changes in this area.
+ EXPECT_THAT(*source, ElementsAre(1, 2));
+ }
+ {
+ Arena arena;
+ RepeatedField<int>* source =
+ Arena::CreateMessage<RepeatedField<int>>(&arena);
+ source->Add(1);
+ source->Add(2);
+ RepeatedField<int> destination;
+ destination.Add(3);
+ destination = std::move(*source);
+ EXPECT_THAT(destination, ElementsAre(1, 2));
+ // This property isn't guaranteed but it's useful to have a test that would
+ // catch changes in this area.
+ EXPECT_THAT(*source, ElementsAre(1, 2));
+ }
+ {
+ RepeatedField<int> source;
+ source.Add(1);
+ source.Add(2);
+ Arena arena;
+ RepeatedField<int>* destination =
+ Arena::CreateMessage<RepeatedField<int>>(&arena);
+ destination->Add(3);
+ *destination = std::move(source);
+ EXPECT_THAT(*destination, ElementsAre(1, 2));
+ // This property isn't guaranteed but it's useful to have a test that would
+ // catch changes in this area.
+ EXPECT_THAT(source, ElementsAre(1, 2));
+ }
+ {
+ RepeatedField<int> field;
+ // An alias to defeat -Wself-move.
+ RepeatedField<int>& alias = field;
+ field.Add(1);
+ field.Add(2);
+ const int* data = field.data();
+ field = std::move(alias);
+ EXPECT_EQ(data, field.data());
+ EXPECT_THAT(field, ElementsAre(1, 2));
+ }
+ {
+ Arena arena;
+ RepeatedField<int>* field =
+ Arena::CreateMessage<RepeatedField<int>>(&arena);
+ field->Add(1);
+ field->Add(2);
+ const int* data = field->data();
+ *field = std::move(*field);
+ EXPECT_EQ(data, field->data());
+ EXPECT_THAT(*field, ElementsAre(1, 2));
+ }
+}
+
+TEST(Movable, Works) {
+ class NonMoveConstructible {
+ public:
+ NonMoveConstructible(NonMoveConstructible&&) = delete;
+ NonMoveConstructible& operator=(NonMoveConstructible&&) { return *this; }
+ };
+ class NonMoveAssignable {
+ public:
+ NonMoveAssignable(NonMoveAssignable&&) {}
+ NonMoveAssignable& operator=(NonMoveConstructible&&) = delete;
+ };
+ class NonMovable {
+ public:
+ NonMovable(NonMovable&&) = delete;
+ NonMovable& operator=(NonMovable&&) = delete;
+ };
+
+ EXPECT_TRUE(internal::IsMovable<std::string>::value);
+
+ EXPECT_FALSE(std::is_move_constructible<NonMoveConstructible>::value);
+ EXPECT_TRUE(std::is_move_assignable<NonMoveConstructible>::value);
+ EXPECT_FALSE(internal::IsMovable<NonMoveConstructible>::value);
+
+ EXPECT_TRUE(std::is_move_constructible<NonMoveAssignable>::value);
+ EXPECT_FALSE(std::is_move_assignable<NonMoveAssignable>::value);
+ EXPECT_FALSE(internal::IsMovable<NonMoveAssignable>::value);
+
+ EXPECT_FALSE(internal::IsMovable<NonMovable>::value);
+}
+
+TEST(RepeatedField, MoveAdd) {
+ RepeatedPtrField<TestAllTypes> field;
+ TestAllTypes test_all_types;
+ auto* optional_nested_message =
+ test_all_types.mutable_optional_nested_message();
+ optional_nested_message->set_bb(42);
+ field.Add(std::move(test_all_types));
+
+ EXPECT_EQ(optional_nested_message,
+ field.Mutable(0)->mutable_optional_nested_message());
+}
+
+TEST(RepeatedField, MutableDataIsMutable) {
+ RepeatedField<int> field;
+ field.Add(1);
+ EXPECT_EQ(1, field.Get(0));
+ // The fact that this line compiles would be enough, but we'll check the
+ // value anyway.
+ *field.mutable_data() = 2;
+ EXPECT_EQ(2, field.Get(0));
+}
+
+TEST(RepeatedField, SubscriptOperators) {
+ RepeatedField<int> field;
+ field.Add(1);
+ EXPECT_EQ(1, field.Get(0));
+ EXPECT_EQ(1, field[0]);
+ EXPECT_EQ(field.Mutable(0), &field[0]);
+ const RepeatedField<int>& const_field = field;
+ EXPECT_EQ(field.data(), &const_field[0]);
+}
+
+TEST(RepeatedField, Truncate) {
+ RepeatedField<int> field;
+
+ field.Add(12);
+ field.Add(34);
+ field.Add(56);
+ field.Add(78);
+ EXPECT_EQ(4, field.size());
+
+ field.Truncate(3);
+ EXPECT_EQ(3, field.size());
+
+ field.Add(90);
+ EXPECT_EQ(4, field.size());
+ EXPECT_EQ(90, field.Get(3));
+
+ // Truncations that don't change the size are allowed, but growing is not
+ // allowed.
+ field.Truncate(field.size());
+#ifdef PROTOBUF_HAS_DEATH_TEST
+ EXPECT_DEBUG_DEATH(field.Truncate(field.size() + 1), "new_size");
+#endif
+}
+
+
+TEST(RepeatedField, ExtractSubrange) {
+ // Exhaustively test every subrange in arrays of all sizes from 0 through 9.
+ for (int sz = 0; sz < 10; ++sz) {
+ for (int num = 0; num <= sz; ++num) {
+ for (int start = 0; start < sz - num; ++start) {
+ // Create RepeatedField with sz elements having values 0 through sz-1.
+ RepeatedField<int32> field;
+ for (int i = 0; i < sz; ++i) field.Add(i);
+ EXPECT_EQ(field.size(), sz);
+
+ // Create a catcher array and call ExtractSubrange.
+ int32 catcher[10];
+ for (int i = 0; i < 10; ++i) catcher[i] = -1;
+ field.ExtractSubrange(start, num, catcher);
+
+ // Does the resulting array have the right size?
+ EXPECT_EQ(field.size(), sz - num);
+
+ // Were the removed elements extracted into the catcher array?
+ for (int i = 0; i < num; ++i) EXPECT_EQ(catcher[i], start + i);
+ EXPECT_EQ(catcher[num], -1);
+
+ // Does the resulting array contain the right values?
+ for (int i = 0; i < start; ++i) EXPECT_EQ(field.Get(i), i);
+ for (int i = start; i < field.size(); ++i)
+ EXPECT_EQ(field.Get(i), i + num);
+ }
+ }
+ }
+}
+
+TEST(RepeatedField, ClearThenReserveMore) {
+ // Test that Reserve properly destroys the old internal array when it's forced
+ // to allocate a new one, even when cleared-but-not-deleted objects are
+ // present. Use a 'string' and > 16 bytes length so that the elements are
+ // non-POD and allocate -- the leak checker will catch any skipped destructor
+ // calls here.
+ RepeatedField<std::string> field;
+ for (int i = 0; i < 32; i++) {
+ field.Add(std::string("abcdefghijklmnopqrstuvwxyz0123456789"));
+ }
+ EXPECT_EQ(32, field.size());
+ field.Clear();
+ EXPECT_EQ(0, field.size());
+ EXPECT_LE(32, field.Capacity());
+
+ field.Reserve(1024);
+ EXPECT_EQ(0, field.size());
+ EXPECT_LE(1024, field.Capacity());
+ // Finish test -- |field| should destroy the cleared-but-not-yet-destroyed
+ // strings.
+}
+
+TEST(RepeatedField, TestSAddFromSelf) {
+ RepeatedField<int> field;
+ field.Add(0);
+ for (int i = 0; i < 1000; i++) {
+ field.Add(field[0]);
+ }
+}
+
+// ===================================================================
+// RepeatedPtrField tests. These pretty much just mirror the RepeatedField
+// tests above.
+
+TEST(RepeatedPtrField, ConstInit) {
+ PROTOBUF_CONSTINIT static RepeatedPtrField<std::string> field{}; // NOLINT
+ EXPECT_TRUE(field.empty());
+}
+
+// This helper overload set tests whether X::f can be called with a braced pair,
+// X::f({a, b}) of std::string iterators (specifically, pointers: That call is
+// ambiguous if and only if the call to ValidResolutionPointerRange is not.
+template <typename X>
+auto ValidResolutionPointerRange(const std::string* p)
+ -> decltype(X::f({p, p + 2}), std::true_type{});
+template <typename X>
+std::false_type ValidResolutionPointerRange(void*);
+
+TEST(RepeatedPtrField, UnambiguousConstructor) {
+ struct X {
+ static bool f(std::vector<std::string>) { return false; }
+ static bool f(google::protobuf::RepeatedPtrField<std::string>) { return true; }
+
+ static bool g(std::vector<int>) { return false; }
+ static bool g(google::protobuf::RepeatedPtrField<std::string>) { return true; }
+ };
+
+ // RepeatedPtrField has no initializer-list constructor, and a constructor
+ // from to const char* values is excluded by its constraints.
+ EXPECT_FALSE(X::f({"abc", "xyz"}));
+
+ // Construction from a pair of int* is also not ambiguous.
+ int a[5] = {};
+ EXPECT_FALSE(X::g({a, a + 5}));
+
+ // Construction from string iterators for the unique string overload "g"
+ // works.
+ // Disabling this for now, this is actually ambiguous with libstdc++.
+ // std::string b[2] = {"abc", "xyz"};
+ // EXPECT_TRUE(X::g({b, b + 2}));
+
+ // Construction from string iterators for "f" is ambiguous, since both
+ // containers are equally good.
+ //
+ // X::f({b, b + 2}); // error => ValidResolutionPointerRange is unambiguous.
+ EXPECT_FALSE(decltype(ValidResolutionPointerRange<X>(nullptr))::value);
+}
+
+TEST(RepeatedPtrField, Small) {
+ RepeatedPtrField<std::string> field;
+
+ EXPECT_TRUE(field.empty());
+ EXPECT_EQ(field.size(), 0);
+
+ field.Add()->assign("foo");
+
+ EXPECT_FALSE(field.empty());
+ EXPECT_EQ(field.size(), 1);
+ EXPECT_EQ(field.Get(0), "foo");
+ EXPECT_EQ(field.at(0), "foo");
+
+ field.Add()->assign("bar");
+
+ EXPECT_FALSE(field.empty());
+ EXPECT_EQ(field.size(), 2);
+ EXPECT_EQ(field.Get(0), "foo");
+ EXPECT_EQ(field.at(0), "foo");
+ EXPECT_EQ(field.Get(1), "bar");
+ EXPECT_EQ(field.at(1), "bar");
+
+ field.Mutable(1)->assign("baz");
+
+ EXPECT_FALSE(field.empty());
+ EXPECT_EQ(field.size(), 2);
+ EXPECT_EQ(field.Get(0), "foo");
+ EXPECT_EQ(field.at(0), "foo");
+ EXPECT_EQ(field.Get(1), "baz");
+ EXPECT_EQ(field.at(1), "baz");
+
+ field.RemoveLast();
+
+ EXPECT_FALSE(field.empty());
+ EXPECT_EQ(field.size(), 1);
+ EXPECT_EQ(field.Get(0), "foo");
+ EXPECT_EQ(field.at(0), "foo");
+
+ field.Clear();
+
+ EXPECT_TRUE(field.empty());
+ EXPECT_EQ(field.size(), 0);
+}
+
+TEST(RepeatedPtrField, Large) {
+ RepeatedPtrField<std::string> field;
+
+ for (int i = 0; i < 16; i++) {
+ *field.Add() += 'a' + i;
+ }
+
+ EXPECT_EQ(field.size(), 16);
+
+ for (int i = 0; i < 16; i++) {
+ EXPECT_EQ(field.Get(i).size(), 1);
+ EXPECT_EQ(field.Get(i)[0], 'a' + i);
+ }
+
+ int min_expected_usage = 16 * sizeof(std::string);
+ EXPECT_GE(field.SpaceUsedExcludingSelf(), min_expected_usage);
+}
+
+TEST(RepeatedPtrField, AddAndAssignRanges) {
+ RepeatedPtrField<std::string> field;
+
+ const char* vals[] = {"abc", "x", "yz", "xyzzy"};
+ field.Assign(std::begin(vals), std::end(vals));
+
+ ASSERT_EQ(field.size(), 4);
+ EXPECT_EQ(field.Get(0), "abc");
+ EXPECT_EQ(field.Get(1), "x");
+ EXPECT_EQ(field.Get(2), "yz");
+ EXPECT_EQ(field.Get(3), "xyzzy");
+
+ field.Add(std::begin(vals), std::end(vals));
+ ASSERT_EQ(field.size(), 8);
+ EXPECT_EQ(field.Get(0), "abc");
+ EXPECT_EQ(field.Get(1), "x");
+ EXPECT_EQ(field.Get(2), "yz");
+ EXPECT_EQ(field.Get(3), "xyzzy");
+ EXPECT_EQ(field.Get(4), "abc");
+ EXPECT_EQ(field.Get(5), "x");
+ EXPECT_EQ(field.Get(6), "yz");
+ EXPECT_EQ(field.Get(7), "xyzzy");
+}
+
+TEST(RepeatedPtrField, SwapSmallSmall) {
+ RepeatedPtrField<std::string> field1;
+ RepeatedPtrField<std::string> field2;
+
+ EXPECT_TRUE(field1.empty());
+ EXPECT_EQ(field1.size(), 0);
+ EXPECT_TRUE(field2.empty());
+ EXPECT_EQ(field2.size(), 0);
+
+ field1.Add()->assign("foo");
+ field1.Add()->assign("bar");
+
+ EXPECT_FALSE(field1.empty());
+ EXPECT_EQ(field1.size(), 2);
+ EXPECT_EQ(field1.Get(0), "foo");
+ EXPECT_EQ(field1.Get(1), "bar");
+
+ EXPECT_TRUE(field2.empty());
+ EXPECT_EQ(field2.size(), 0);
+
+ field1.Swap(&field2);
+
+ EXPECT_TRUE(field1.empty());
+ EXPECT_EQ(field1.size(), 0);
+
+ EXPECT_EQ(field2.size(), 2);
+ EXPECT_EQ(field2.Get(0), "foo");
+ EXPECT_EQ(field2.Get(1), "bar");
+}
+
+TEST(RepeatedPtrField, SwapLargeSmall) {
+ RepeatedPtrField<std::string> field1;
+ RepeatedPtrField<std::string> field2;
+
+ field2.Add()->assign("foo");
+ field2.Add()->assign("bar");
+ for (int i = 0; i < 16; i++) {
+ *field1.Add() += 'a' + i;
+ }
+ field1.Swap(&field2);
+
+ EXPECT_EQ(field1.size(), 2);
+ EXPECT_EQ(field1.Get(0), "foo");
+ EXPECT_EQ(field1.Get(1), "bar");
+ EXPECT_EQ(field2.size(), 16);
+ for (int i = 0; i < 16; i++) {
+ EXPECT_EQ(field2.Get(i).size(), 1);
+ EXPECT_EQ(field2.Get(i)[0], 'a' + i);
+ }
+}
+
+TEST(RepeatedPtrField, SwapLargeLarge) {
+ RepeatedPtrField<std::string> field1;
+ RepeatedPtrField<std::string> field2;
+
+ field1.Add()->assign("foo");
+ field1.Add()->assign("bar");
+ for (int i = 0; i < 16; i++) {
+ *field1.Add() += 'A' + i;
+ *field2.Add() += 'a' + i;
+ }
+ field2.Swap(&field1);
+
+ EXPECT_EQ(field1.size(), 16);
+ for (int i = 0; i < 16; i++) {
+ EXPECT_EQ(field1.Get(i).size(), 1);
+ EXPECT_EQ(field1.Get(i)[0], 'a' + i);
+ }
+ EXPECT_EQ(field2.size(), 18);
+ EXPECT_EQ(field2.Get(0), "foo");
+ EXPECT_EQ(field2.Get(1), "bar");
+ for (int i = 2; i < 18; i++) {
+ EXPECT_EQ(field2.Get(i).size(), 1);
+ EXPECT_EQ(field2.Get(i)[0], 'A' + i - 2);
+ }
+}
+
+static int ReservedSpace(RepeatedPtrField<std::string>* field) {
+ const std::string* const* ptr = field->data();
+ do {
+ field->Add();
+ } while (field->data() == ptr);
+
+ return field->size() - 1;
+}
+
+TEST(RepeatedPtrField, ReserveMoreThanDouble) {
+ RepeatedPtrField<std::string> field;
+ field.Reserve(20);
+
+ EXPECT_LE(20, ReservedSpace(&field));
+}
+
+TEST(RepeatedPtrField, ReserveLessThanDouble) {
+ RepeatedPtrField<std::string> field;
+ field.Reserve(20);
+
+ int capacity = field.Capacity();
+ // Grow by 1.5x
+ field.Reserve(capacity + (capacity >> 2));
+
+ EXPECT_LE(2 * capacity, ReservedSpace(&field));
+}
+
+TEST(RepeatedPtrField, ReserveLessThanExisting) {
+ RepeatedPtrField<std::string> field;
+ field.Reserve(20);
+ const std::string* const* previous_ptr = field.data();
+ field.Reserve(10);
+
+ EXPECT_EQ(previous_ptr, field.data());
+ EXPECT_LE(20, ReservedSpace(&field));
+}
+
+TEST(RepeatedPtrField, ReserveDoesntLoseAllocated) {
+ // Check that a bug is fixed: An earlier implementation of Reserve()
+ // failed to copy pointers to allocated-but-cleared objects, possibly
+ // leading to segfaults.
+ RepeatedPtrField<std::string> field;
+ std::string* first = field.Add();
+ field.RemoveLast();
+
+ field.Reserve(20);
+ EXPECT_EQ(first, field.Add());
+}
+
+// Clearing elements is tricky with RepeatedPtrFields since the memory for
+// the elements is retained and reused.
+TEST(RepeatedPtrField, ClearedElements) {
+ RepeatedPtrField<std::string> field;
+
+ std::string* original = field.Add();
+ *original = "foo";
+
+ EXPECT_EQ(field.ClearedCount(), 0);
+
+ field.RemoveLast();
+ EXPECT_TRUE(original->empty());
+ EXPECT_EQ(field.ClearedCount(), 1);
+
+ EXPECT_EQ(field.Add(),
+ original); // Should return same string for reuse.
+ EXPECT_EQ(field.UnsafeArenaReleaseLast(), original); // We take ownership.
+ EXPECT_EQ(field.ClearedCount(), 0);
+
+ EXPECT_NE(field.Add(), original); // Should NOT return the same string.
+ EXPECT_EQ(field.ClearedCount(), 0);
+
+ field.UnsafeArenaAddAllocated(original); // Give ownership back.
+ EXPECT_EQ(field.ClearedCount(), 0);
+ EXPECT_EQ(field.Mutable(1), original);
+
+ field.Clear();
+ EXPECT_EQ(field.ClearedCount(), 2);
+#ifndef PROTOBUF_FUTURE_BREAKING_CHANGES
+ EXPECT_EQ(field.ReleaseCleared(), original); // Take ownership again.
+ EXPECT_EQ(field.ClearedCount(), 1);
+ EXPECT_NE(field.Add(), original);
+ EXPECT_EQ(field.ClearedCount(), 0);
+ EXPECT_NE(field.Add(), original);
+ EXPECT_EQ(field.ClearedCount(), 0);
+
+ field.AddCleared(original); // Give ownership back, but as a cleared object.
+ EXPECT_EQ(field.ClearedCount(), 1);
+ EXPECT_EQ(field.Add(), original);
+ EXPECT_EQ(field.ClearedCount(), 0);
+#endif // !PROTOBUF_FUTURE_BREAKING_CHANGES
+}
+
+// Test all code paths in AddAllocated().
+TEST(RepeatedPtrField, AddAllocated) {
+ RepeatedPtrField<std::string> field;
+ while (field.size() < field.Capacity()) {
+ field.Add()->assign("filler");
+ }
+
+ int index = field.size();
+
+ // First branch: Field is at capacity with no cleared objects.
+ std::string* foo = new std::string("foo");
+ field.AddAllocated(foo);
+ EXPECT_EQ(index + 1, field.size());
+ EXPECT_EQ(0, field.ClearedCount());
+ EXPECT_EQ(foo, &field.Get(index));
+
+ // Last branch: Field is not at capacity and there are no cleared objects.
+ std::string* bar = new std::string("bar");
+ field.AddAllocated(bar);
+ ++index;
+ EXPECT_EQ(index + 1, field.size());
+ EXPECT_EQ(0, field.ClearedCount());
+ EXPECT_EQ(bar, &field.Get(index));
+
+ // Third branch: Field is not at capacity and there are no cleared objects.
+ field.RemoveLast();
+ std::string* baz = new std::string("baz");
+ field.AddAllocated(baz);
+ EXPECT_EQ(index + 1, field.size());
+ EXPECT_EQ(1, field.ClearedCount());
+ EXPECT_EQ(baz, &field.Get(index));
+
+ // Second branch: Field is at capacity but has some cleared objects.
+ while (field.size() < field.Capacity()) {
+ field.Add()->assign("filler2");
+ }
+ field.RemoveLast();
+ index = field.size();
+ std::string* qux = new std::string("qux");
+ field.AddAllocated(qux);
+ EXPECT_EQ(index + 1, field.size());
+ // We should have discarded the cleared object.
+ EXPECT_EQ(0, field.ClearedCount());
+ EXPECT_EQ(qux, &field.Get(index));
+}
+
+TEST(RepeatedPtrField, AddAllocatedDifferentArena) {
+ RepeatedPtrField<TestAllTypes> field;
+ Arena arena;
+ auto* msg = Arena::CreateMessage<TestAllTypes>(&arena);
+ field.AddAllocated(msg);
+}
+
+TEST(RepeatedPtrField, MergeFrom) {
+ RepeatedPtrField<std::string> source, destination;
+ source.Add()->assign("4");
+ source.Add()->assign("5");
+ destination.Add()->assign("1");
+ destination.Add()->assign("2");
+ destination.Add()->assign("3");
+
+ destination.MergeFrom(source);
+
+ ASSERT_EQ(5, destination.size());
+ EXPECT_EQ("1", destination.Get(0));
+ EXPECT_EQ("2", destination.Get(1));
+ EXPECT_EQ("3", destination.Get(2));
+ EXPECT_EQ("4", destination.Get(3));
+ EXPECT_EQ("5", destination.Get(4));
+}
+
+
+TEST(RepeatedPtrField, CopyFrom) {
+ RepeatedPtrField<std::string> source, destination;
+ source.Add()->assign("4");
+ source.Add()->assign("5");
+ destination.Add()->assign("1");
+ destination.Add()->assign("2");
+ destination.Add()->assign("3");
+
+ destination.CopyFrom(source);
+
+ ASSERT_EQ(2, destination.size());
+ EXPECT_EQ("4", destination.Get(0));
+ EXPECT_EQ("5", destination.Get(1));
+}
+
+TEST(RepeatedPtrField, CopyFromSelf) {
+ RepeatedPtrField<std::string> me;
+ me.Add()->assign("1");
+ me.CopyFrom(me);
+ ASSERT_EQ(1, me.size());
+ EXPECT_EQ("1", me.Get(0));
+}
+
+TEST(RepeatedPtrField, Erase) {
+ RepeatedPtrField<std::string> me;
+ RepeatedPtrField<std::string>::iterator it = me.erase(me.begin(), me.end());
+ EXPECT_TRUE(me.begin() == it);
+ EXPECT_EQ(0, me.size());
+
+ *me.Add() = "1";
+ *me.Add() = "2";
+ *me.Add() = "3";
+ it = me.erase(me.begin(), me.end());
+ EXPECT_TRUE(me.begin() == it);
+ EXPECT_EQ(0, me.size());
+
+ *me.Add() = "4";
+ *me.Add() = "5";
+ *me.Add() = "6";
+ it = me.erase(me.begin() + 2, me.end());
+ EXPECT_TRUE(me.begin() + 2 == it);
+ EXPECT_EQ(2, me.size());
+ EXPECT_EQ("4", me.Get(0));
+ EXPECT_EQ("5", me.Get(1));
+
+ *me.Add() = "6";
+ *me.Add() = "7";
+ *me.Add() = "8";
+ it = me.erase(me.begin() + 1, me.begin() + 3);
+ EXPECT_TRUE(me.begin() + 1 == it);
+ EXPECT_EQ(3, me.size());
+ EXPECT_EQ("4", me.Get(0));
+ EXPECT_EQ("7", me.Get(1));
+ EXPECT_EQ("8", me.Get(2));
+}
+
+TEST(RepeatedPtrField, CopyConstruct) {
+ RepeatedPtrField<std::string> source;
+ source.Add()->assign("1");
+ source.Add()->assign("2");
+
+ RepeatedPtrField<std::string> destination(source);
+
+ ASSERT_EQ(2, destination.size());
+ EXPECT_EQ("1", destination.Get(0));
+ EXPECT_EQ("2", destination.Get(1));
+}
+
+TEST(RepeatedPtrField, IteratorConstruct_String) {
+ std::vector<std::string> values;
+ values.push_back("1");
+ values.push_back("2");
+
+ RepeatedPtrField<std::string> field(values.begin(), values.end());
+ ASSERT_EQ(values.size(), field.size());
+ EXPECT_EQ(values[0], field.Get(0));
+ EXPECT_EQ(values[1], field.Get(1));
+
+ RepeatedPtrField<std::string> other(field.begin(), field.end());
+ ASSERT_EQ(values.size(), other.size());
+ EXPECT_EQ(values[0], other.Get(0));
+ EXPECT_EQ(values[1], other.Get(1));
+}
+
+TEST(RepeatedPtrField, IteratorConstruct_Proto) {
+ typedef TestAllTypes::NestedMessage Nested;
+ std::vector<Nested> values;
+ values.push_back(Nested());
+ values.back().set_bb(1);
+ values.push_back(Nested());
+ values.back().set_bb(2);
+
+ RepeatedPtrField<Nested> field(values.begin(), values.end());
+ ASSERT_EQ(values.size(), field.size());
+ EXPECT_EQ(values[0].bb(), field.Get(0).bb());
+ EXPECT_EQ(values[1].bb(), field.Get(1).bb());
+
+ RepeatedPtrField<Nested> other(field.begin(), field.end());
+ ASSERT_EQ(values.size(), other.size());
+ EXPECT_EQ(values[0].bb(), other.Get(0).bb());
+ EXPECT_EQ(values[1].bb(), other.Get(1).bb());
+}
+
+TEST(RepeatedPtrField, CopyAssign) {
+ RepeatedPtrField<std::string> source, destination;
+ source.Add()->assign("4");
+ source.Add()->assign("5");
+ destination.Add()->assign("1");
+ destination.Add()->assign("2");
+ destination.Add()->assign("3");
+
+ destination = source;
+
+ ASSERT_EQ(2, destination.size());
+ EXPECT_EQ("4", destination.Get(0));
+ EXPECT_EQ("5", destination.Get(1));
+}
+
+TEST(RepeatedPtrField, SelfAssign) {
+ // Verify that assignment to self does not destroy data.
+ RepeatedPtrField<std::string> source, *p;
+ p = &source;
+ source.Add()->assign("7");
+ source.Add()->assign("8");
+
+ *p = source;
+
+ ASSERT_EQ(2, source.size());
+ EXPECT_EQ("7", source.Get(0));
+ EXPECT_EQ("8", source.Get(1));
+}
+
+TEST(RepeatedPtrField, MoveConstruct) {
+ {
+ RepeatedPtrField<std::string> source;
+ *source.Add() = "1";
+ *source.Add() = "2";
+ const std::string* const* data = source.data();
+ RepeatedPtrField<std::string> destination = std::move(source);
+ EXPECT_EQ(data, destination.data());
+ EXPECT_THAT(destination, ElementsAre("1", "2"));
+ // This property isn't guaranteed but it's useful to have a test that would
+ // catch changes in this area.
+ EXPECT_TRUE(source.empty());
+ }
+ {
+ Arena arena;
+ RepeatedPtrField<std::string>* source =
+ Arena::CreateMessage<RepeatedPtrField<std::string>>(&arena);
+ *source->Add() = "1";
+ *source->Add() = "2";
+ RepeatedPtrField<std::string> destination = std::move(*source);
+ EXPECT_EQ(nullptr, destination.GetArena());
+ EXPECT_THAT(destination, ElementsAre("1", "2"));
+ // This property isn't guaranteed but it's useful to have a test that would
+ // catch changes in this area.
+ EXPECT_THAT(*source, ElementsAre("1", "2"));
+ }
+}
+
+TEST(RepeatedPtrField, MoveAssign) {
+ {
+ RepeatedPtrField<std::string> source;
+ *source.Add() = "1";
+ *source.Add() = "2";
+ RepeatedPtrField<std::string> destination;
+ *destination.Add() = "3";
+ const std::string* const* source_data = source.data();
+ const std::string* const* destination_data = destination.data();
+ destination = std::move(source);
+ EXPECT_EQ(source_data, destination.data());
+ EXPECT_THAT(destination, ElementsAre("1", "2"));
+ // This property isn't guaranteed but it's useful to have a test that would
+ // catch changes in this area.
+ EXPECT_EQ(destination_data, source.data());
+ EXPECT_THAT(source, ElementsAre("3"));
+ }
+ {
+ Arena arena;
+ RepeatedPtrField<std::string>* source =
+ Arena::CreateMessage<RepeatedPtrField<std::string>>(&arena);
+ *source->Add() = "1";
+ *source->Add() = "2";
+ RepeatedPtrField<std::string>* destination =
+ Arena::CreateMessage<RepeatedPtrField<std::string>>(&arena);
+ *destination->Add() = "3";
+ const std::string* const* source_data = source->data();
+ const std::string* const* destination_data = destination->data();
+ *destination = std::move(*source);
+ EXPECT_EQ(source_data, destination->data());
+ EXPECT_THAT(*destination, ElementsAre("1", "2"));
+ // This property isn't guaranteed but it's useful to have a test that would
+ // catch changes in this area.
+ EXPECT_EQ(destination_data, source->data());
+ EXPECT_THAT(*source, ElementsAre("3"));
+ }
+ {
+ Arena source_arena;
+ RepeatedPtrField<std::string>* source =
+ Arena::CreateMessage<RepeatedPtrField<std::string>>(&source_arena);
+ *source->Add() = "1";
+ *source->Add() = "2";
+ Arena destination_arena;
+ RepeatedPtrField<std::string>* destination =
+ Arena::CreateMessage<RepeatedPtrField<std::string>>(&destination_arena);
+ *destination->Add() = "3";
+ *destination = std::move(*source);
+ EXPECT_THAT(*destination, ElementsAre("1", "2"));
+ // This property isn't guaranteed but it's useful to have a test that would
+ // catch changes in this area.
+ EXPECT_THAT(*source, ElementsAre("1", "2"));
+ }
+ {
+ Arena arena;
+ RepeatedPtrField<std::string>* source =
+ Arena::CreateMessage<RepeatedPtrField<std::string>>(&arena);
+ *source->Add() = "1";
+ *source->Add() = "2";
+ RepeatedPtrField<std::string> destination;
+ *destination.Add() = "3";
+ destination = std::move(*source);
+ EXPECT_THAT(destination, ElementsAre("1", "2"));
+ // This property isn't guaranteed but it's useful to have a test that would
+ // catch changes in this area.
+ EXPECT_THAT(*source, ElementsAre("1", "2"));
+ }
+ {
+ RepeatedPtrField<std::string> source;
+ *source.Add() = "1";
+ *source.Add() = "2";
+ Arena arena;
+ RepeatedPtrField<std::string>* destination =
+ Arena::CreateMessage<RepeatedPtrField<std::string>>(&arena);
+ *destination->Add() = "3";
+ *destination = std::move(source);
+ EXPECT_THAT(*destination, ElementsAre("1", "2"));
+ // This property isn't guaranteed but it's useful to have a test that would
+ // catch changes in this area.
+ EXPECT_THAT(source, ElementsAre("1", "2"));
+ }
+ {
+ RepeatedPtrField<std::string> field;
+ // An alias to defeat -Wself-move.
+ RepeatedPtrField<std::string>& alias = field;
+ *field.Add() = "1";
+ *field.Add() = "2";
+ const std::string* const* data = field.data();
+ field = std::move(alias);
+ EXPECT_EQ(data, field.data());
+ EXPECT_THAT(field, ElementsAre("1", "2"));
+ }
+ {
+ Arena arena;
+ RepeatedPtrField<std::string>* field =
+ Arena::CreateMessage<RepeatedPtrField<std::string>>(&arena);
+ *field->Add() = "1";
+ *field->Add() = "2";
+ const std::string* const* data = field->data();
+ *field = std::move(*field);
+ EXPECT_EQ(data, field->data());
+ EXPECT_THAT(*field, ElementsAre("1", "2"));
+ }
+}
+
+TEST(RepeatedPtrField, MutableDataIsMutable) {
+ RepeatedPtrField<std::string> field;
+ *field.Add() = "1";
+ EXPECT_EQ("1", field.Get(0));
+ // The fact that this line compiles would be enough, but we'll check the
+ // value anyway.
+ std::string** data = field.mutable_data();
+ **data = "2";
+ EXPECT_EQ("2", field.Get(0));
+}
+
+TEST(RepeatedPtrField, SubscriptOperators) {
+ RepeatedPtrField<std::string> field;
+ *field.Add() = "1";
+ EXPECT_EQ("1", field.Get(0));
+ EXPECT_EQ("1", field[0]);
+ EXPECT_EQ(field.Mutable(0), &field[0]);
+ const RepeatedPtrField<std::string>& const_field = field;
+ EXPECT_EQ(*field.data(), &const_field[0]);
+}
+
+TEST(RepeatedPtrField, ExtractSubrange) {
+ // Exhaustively test every subrange in arrays of all sizes from 0 through 9
+ // with 0 through 3 cleared elements at the end.
+ for (int sz = 0; sz < 10; ++sz) {
+ for (int num = 0; num <= sz; ++num) {
+ for (int start = 0; start < sz - num; ++start) {
+ for (int extra = 0; extra < 4; ++extra) {
+ std::vector<std::string*> subject;
+
+ // Create an array with "sz" elements and "extra" cleared elements.
+ // Use an arena to avoid copies from debug-build stability checks.
+ Arena arena;
+ RepeatedPtrField<std::string> field(&arena);
+ for (int i = 0; i < sz + extra; ++i) {
+ subject.push_back(new std::string());
+ field.AddAllocated(subject[i]);
+ }
+ EXPECT_EQ(field.size(), sz + extra);
+ for (int i = 0; i < extra; ++i) field.RemoveLast();
+ EXPECT_EQ(field.size(), sz);
+ EXPECT_EQ(field.ClearedCount(), extra);
+
+ // Create a catcher array and call ExtractSubrange.
+ std::string* catcher[10];
+ for (int i = 0; i < 10; ++i) catcher[i] = nullptr;
+ field.ExtractSubrange(start, num, catcher);
+
+ // Does the resulting array have the right size?
+ EXPECT_EQ(field.size(), sz - num);
+
+ // Were the removed elements extracted into the catcher array?
+ for (int i = 0; i < num; ++i)
+ EXPECT_EQ(*catcher[i], *subject[start + i]);
+ EXPECT_EQ(nullptr, catcher[num]);
+
+ // Does the resulting array contain the right values?
+ for (int i = 0; i < start; ++i)
+ EXPECT_EQ(field.Mutable(i), subject[i]);
+ for (int i = start; i < field.size(); ++i)
+ EXPECT_EQ(field.Mutable(i), subject[i + num]);
+
+ // Reinstate the cleared elements.
+ EXPECT_EQ(field.ClearedCount(), extra);
+ for (int i = 0; i < extra; ++i) field.Add();
+ EXPECT_EQ(field.ClearedCount(), 0);
+ EXPECT_EQ(field.size(), sz - num + extra);
+
+ // Make sure the extra elements are all there (in some order).
+ for (int i = sz; i < sz + extra; ++i) {
+ int count = 0;
+ for (int j = sz; j < sz + extra; ++j) {
+ if (field.Mutable(j - num) == subject[i]) count += 1;
+ }
+ EXPECT_EQ(count, 1);
+ }
+
+ // Release the caught elements.
+ for (int i = 0; i < num; ++i) delete catcher[i];
+ }
+ }
+ }
+ }
+}
+
+TEST(RepeatedPtrField, DeleteSubrange) {
+ // DeleteSubrange is a trivial extension of ExtendSubrange.
+}
+
+// ===================================================================
+
+// Iterator tests stolen from net/proto/proto-array_unittest.
+class RepeatedFieldIteratorTest : public testing::Test {
+ protected:
+ virtual void SetUp() {
+ for (int i = 0; i < 3; ++i) {
+ proto_array_.Add(i);
+ }
+ }
+
+ RepeatedField<int> proto_array_;
+};
+
+TEST_F(RepeatedFieldIteratorTest, Convertible) {
+ RepeatedField<int>::iterator iter = proto_array_.begin();
+ RepeatedField<int>::const_iterator c_iter = iter;
+ RepeatedField<int>::value_type value = *c_iter;
+ EXPECT_EQ(0, value);
+}
+
+TEST_F(RepeatedFieldIteratorTest, MutableIteration) {
+ RepeatedField<int>::iterator iter = proto_array_.begin();
+ EXPECT_EQ(0, *iter);
+ ++iter;
+ EXPECT_EQ(1, *iter++);
+ EXPECT_EQ(2, *iter);
+ ++iter;
+ EXPECT_TRUE(proto_array_.end() == iter);
+
+ EXPECT_EQ(2, *(proto_array_.end() - 1));
+}
+
+TEST_F(RepeatedFieldIteratorTest, ConstIteration) {
+ const RepeatedField<int>& const_proto_array = proto_array_;
+ RepeatedField<int>::const_iterator iter = const_proto_array.begin();
+ EXPECT_EQ(0, *iter);
+ ++iter;
+ EXPECT_EQ(1, *iter++);
+ EXPECT_EQ(2, *iter);
+ ++iter;
+ EXPECT_TRUE(proto_array_.end() == iter);
+ EXPECT_EQ(2, *(proto_array_.end() - 1));
+}
+
+TEST_F(RepeatedFieldIteratorTest, Mutation) {
+ RepeatedField<int>::iterator iter = proto_array_.begin();
+ *iter = 7;
+ EXPECT_EQ(7, proto_array_.Get(0));
+}
+
+// -------------------------------------------------------------------
+
+class RepeatedPtrFieldIteratorTest : public testing::Test {
+ protected:
+ virtual void SetUp() {
+ proto_array_.Add()->assign("foo");
+ proto_array_.Add()->assign("bar");
+ proto_array_.Add()->assign("baz");
+ }
+
+ RepeatedPtrField<std::string> proto_array_;
+};
+
+TEST_F(RepeatedPtrFieldIteratorTest, Convertible) {
+ RepeatedPtrField<std::string>::iterator iter = proto_array_.begin();
+ RepeatedPtrField<std::string>::const_iterator c_iter = iter;
+ RepeatedPtrField<std::string>::value_type value = *c_iter;
+ EXPECT_EQ("foo", value);
+}
+
+TEST_F(RepeatedPtrFieldIteratorTest, MutableIteration) {
+ RepeatedPtrField<std::string>::iterator iter = proto_array_.begin();
+ EXPECT_EQ("foo", *iter);
+ ++iter;
+ EXPECT_EQ("bar", *(iter++));
+ EXPECT_EQ("baz", *iter);
+ ++iter;
+ EXPECT_TRUE(proto_array_.end() == iter);
+ EXPECT_EQ("baz", *(--proto_array_.end()));
+}
+
+TEST_F(RepeatedPtrFieldIteratorTest, ConstIteration) {
+ const RepeatedPtrField<std::string>& const_proto_array = proto_array_;
+ RepeatedPtrField<std::string>::const_iterator iter =
+ const_proto_array.begin();
+ EXPECT_EQ("foo", *iter);
+ ++iter;
+ EXPECT_EQ("bar", *(iter++));
+ EXPECT_EQ("baz", *iter);
+ ++iter;
+ EXPECT_TRUE(const_proto_array.end() == iter);
+ EXPECT_EQ("baz", *(--const_proto_array.end()));
+}
+
+TEST_F(RepeatedPtrFieldIteratorTest, MutableReverseIteration) {
+ RepeatedPtrField<std::string>::reverse_iterator iter = proto_array_.rbegin();
+ EXPECT_EQ("baz", *iter);
+ ++iter;
+ EXPECT_EQ("bar", *(iter++));
+ EXPECT_EQ("foo", *iter);
+ ++iter;
+ EXPECT_TRUE(proto_array_.rend() == iter);
+ EXPECT_EQ("foo", *(--proto_array_.rend()));
+}
+
+TEST_F(RepeatedPtrFieldIteratorTest, ConstReverseIteration) {
+ const RepeatedPtrField<std::string>& const_proto_array = proto_array_;
+ RepeatedPtrField<std::string>::const_reverse_iterator iter =
+ const_proto_array.rbegin();
+ EXPECT_EQ("baz", *iter);
+ ++iter;
+ EXPECT_EQ("bar", *(iter++));
+ EXPECT_EQ("foo", *iter);
+ ++iter;
+ EXPECT_TRUE(const_proto_array.rend() == iter);
+ EXPECT_EQ("foo", *(--const_proto_array.rend()));
+}
+
+TEST_F(RepeatedPtrFieldIteratorTest, RandomAccess) {
+ RepeatedPtrField<std::string>::iterator iter = proto_array_.begin();
+ RepeatedPtrField<std::string>::iterator iter2 = iter;
+ ++iter2;
+ ++iter2;
+ EXPECT_TRUE(iter + 2 == iter2);
+ EXPECT_TRUE(iter == iter2 - 2);
+ EXPECT_EQ("baz", iter[2]);
+ EXPECT_EQ("baz", *(iter + 2));
+ EXPECT_EQ(3, proto_array_.end() - proto_array_.begin());
+}
+
+TEST_F(RepeatedPtrFieldIteratorTest, Comparable) {
+ RepeatedPtrField<std::string>::const_iterator iter = proto_array_.begin();
+ RepeatedPtrField<std::string>::const_iterator iter2 = iter + 1;
+ EXPECT_TRUE(iter == iter);
+ EXPECT_TRUE(iter != iter2);
+ EXPECT_TRUE(iter < iter2);
+ EXPECT_TRUE(iter <= iter2);
+ EXPECT_TRUE(iter <= iter);
+ EXPECT_TRUE(iter2 > iter);
+ EXPECT_TRUE(iter2 >= iter);
+ EXPECT_TRUE(iter >= iter);
+}
+
+// Uninitialized iterator does not point to any of the RepeatedPtrField.
+TEST_F(RepeatedPtrFieldIteratorTest, UninitializedIterator) {
+ RepeatedPtrField<std::string>::iterator iter;
+ EXPECT_TRUE(iter != proto_array_.begin());
+ EXPECT_TRUE(iter != proto_array_.begin() + 1);
+ EXPECT_TRUE(iter != proto_array_.begin() + 2);
+ EXPECT_TRUE(iter != proto_array_.begin() + 3);
+ EXPECT_TRUE(iter != proto_array_.end());
+}
+
+TEST_F(RepeatedPtrFieldIteratorTest, STLAlgorithms_lower_bound) {
+ proto_array_.Clear();
+ proto_array_.Add()->assign("a");
+ proto_array_.Add()->assign("c");
+ proto_array_.Add()->assign("d");
+ proto_array_.Add()->assign("n");
+ proto_array_.Add()->assign("p");
+ proto_array_.Add()->assign("x");
+ proto_array_.Add()->assign("y");
+
+ std::string v = "f";
+ RepeatedPtrField<std::string>::const_iterator it =
+ std::lower_bound(proto_array_.begin(), proto_array_.end(), v);
+
+ EXPECT_EQ(*it, "n");
+ EXPECT_TRUE(it == proto_array_.begin() + 3);
+}
+
+TEST_F(RepeatedPtrFieldIteratorTest, Mutation) {
+ RepeatedPtrField<std::string>::iterator iter = proto_array_.begin();
+ *iter = "qux";
+ EXPECT_EQ("qux", proto_array_.Get(0));
+}
+
+// -------------------------------------------------------------------
+
+class RepeatedPtrFieldPtrsIteratorTest : public testing::Test {
+ protected:
+ virtual void SetUp() {
+ proto_array_.Add()->assign("foo");
+ proto_array_.Add()->assign("bar");
+ proto_array_.Add()->assign("baz");
+ const_proto_array_ = &proto_array_;
+ }
+
+ RepeatedPtrField<std::string> proto_array_;
+ const RepeatedPtrField<std::string>* const_proto_array_;
+};
+
+TEST_F(RepeatedPtrFieldPtrsIteratorTest, ConvertiblePtr) {
+ RepeatedPtrField<std::string>::pointer_iterator iter =
+ proto_array_.pointer_begin();
+ static_cast<void>(iter);
+}
+
+TEST_F(RepeatedPtrFieldPtrsIteratorTest, ConvertibleConstPtr) {
+ RepeatedPtrField<std::string>::const_pointer_iterator iter =
+ const_proto_array_->pointer_begin();
+ static_cast<void>(iter);
+}
+
+TEST_F(RepeatedPtrFieldPtrsIteratorTest, MutablePtrIteration) {
+ RepeatedPtrField<std::string>::pointer_iterator iter =
+ proto_array_.pointer_begin();
+ EXPECT_EQ("foo", **iter);
+ ++iter;
+ EXPECT_EQ("bar", **(iter++));
+ EXPECT_EQ("baz", **iter);
+ ++iter;
+ EXPECT_TRUE(proto_array_.pointer_end() == iter);
+ EXPECT_EQ("baz", **(--proto_array_.pointer_end()));
+}
+
+TEST_F(RepeatedPtrFieldPtrsIteratorTest, MutableConstPtrIteration) {
+ RepeatedPtrField<std::string>::const_pointer_iterator iter =
+ const_proto_array_->pointer_begin();
+ EXPECT_EQ("foo", **iter);
+ ++iter;
+ EXPECT_EQ("bar", **(iter++));
+ EXPECT_EQ("baz", **iter);
+ ++iter;
+ EXPECT_TRUE(const_proto_array_->pointer_end() == iter);
+ EXPECT_EQ("baz", **(--const_proto_array_->pointer_end()));
+}
+
+TEST_F(RepeatedPtrFieldPtrsIteratorTest, RandomPtrAccess) {
+ RepeatedPtrField<std::string>::pointer_iterator iter =
+ proto_array_.pointer_begin();
+ RepeatedPtrField<std::string>::pointer_iterator iter2 = iter;
+ ++iter2;
+ ++iter2;
+ EXPECT_TRUE(iter + 2 == iter2);
+ EXPECT_TRUE(iter == iter2 - 2);
+ EXPECT_EQ("baz", *iter[2]);
+ EXPECT_EQ("baz", **(iter + 2));
+ EXPECT_EQ(3, proto_array_.end() - proto_array_.begin());
+}
+
+TEST_F(RepeatedPtrFieldPtrsIteratorTest, RandomConstPtrAccess) {
+ RepeatedPtrField<std::string>::const_pointer_iterator iter =
+ const_proto_array_->pointer_begin();
+ RepeatedPtrField<std::string>::const_pointer_iterator iter2 = iter;
+ ++iter2;
+ ++iter2;
+ EXPECT_TRUE(iter + 2 == iter2);
+ EXPECT_TRUE(iter == iter2 - 2);
+ EXPECT_EQ("baz", *iter[2]);
+ EXPECT_EQ("baz", **(iter + 2));
+ EXPECT_EQ(3, const_proto_array_->end() - const_proto_array_->begin());
+}
+
+TEST_F(RepeatedPtrFieldPtrsIteratorTest, ComparablePtr) {
+ RepeatedPtrField<std::string>::pointer_iterator iter =
+ proto_array_.pointer_begin();
+ RepeatedPtrField<std::string>::pointer_iterator iter2 = iter + 1;
+ EXPECT_TRUE(iter == iter);
+ EXPECT_TRUE(iter != iter2);
+ EXPECT_TRUE(iter < iter2);
+ EXPECT_TRUE(iter <= iter2);
+ EXPECT_TRUE(iter <= iter);
+ EXPECT_TRUE(iter2 > iter);
+ EXPECT_TRUE(iter2 >= iter);
+ EXPECT_TRUE(iter >= iter);
+}
+
+TEST_F(RepeatedPtrFieldPtrsIteratorTest, ComparableConstPtr) {
+ RepeatedPtrField<std::string>::const_pointer_iterator iter =
+ const_proto_array_->pointer_begin();
+ RepeatedPtrField<std::string>::const_pointer_iterator iter2 = iter + 1;
+ EXPECT_TRUE(iter == iter);
+ EXPECT_TRUE(iter != iter2);
+ EXPECT_TRUE(iter < iter2);
+ EXPECT_TRUE(iter <= iter2);
+ EXPECT_TRUE(iter <= iter);
+ EXPECT_TRUE(iter2 > iter);
+ EXPECT_TRUE(iter2 >= iter);
+ EXPECT_TRUE(iter >= iter);
+}
+
+// Uninitialized iterator does not point to any of the RepeatedPtrOverPtrs.
+// Dereferencing an uninitialized iterator crashes the process.
+TEST_F(RepeatedPtrFieldPtrsIteratorTest, UninitializedPtrIterator) {
+ RepeatedPtrField<std::string>::pointer_iterator iter;
+ EXPECT_TRUE(iter != proto_array_.pointer_begin());
+ EXPECT_TRUE(iter != proto_array_.pointer_begin() + 1);
+ EXPECT_TRUE(iter != proto_array_.pointer_begin() + 2);
+ EXPECT_TRUE(iter != proto_array_.pointer_begin() + 3);
+ EXPECT_TRUE(iter != proto_array_.pointer_end());
+}
+
+TEST_F(RepeatedPtrFieldPtrsIteratorTest, UninitializedConstPtrIterator) {
+ RepeatedPtrField<std::string>::const_pointer_iterator iter;
+ EXPECT_TRUE(iter != const_proto_array_->pointer_begin());
+ EXPECT_TRUE(iter != const_proto_array_->pointer_begin() + 1);
+ EXPECT_TRUE(iter != const_proto_array_->pointer_begin() + 2);
+ EXPECT_TRUE(iter != const_proto_array_->pointer_begin() + 3);
+ EXPECT_TRUE(iter != const_proto_array_->pointer_end());
+}
+
+// This comparison functor is required by the tests for RepeatedPtrOverPtrs.
+// They operate on strings and need to compare strings as strings in
+// any stl algorithm, even though the iterator returns a pointer to a
+// string
+// - i.e. *iter has type std::string*.
+struct StringLessThan {
+ bool operator()(const std::string* z, const std::string* y) const {
+ return *z < *y;
+ }
+};
+
+TEST_F(RepeatedPtrFieldPtrsIteratorTest, PtrSTLAlgorithms_lower_bound) {
+ proto_array_.Clear();
+ proto_array_.Add()->assign("a");
+ proto_array_.Add()->assign("c");
+ proto_array_.Add()->assign("d");
+ proto_array_.Add()->assign("n");
+ proto_array_.Add()->assign("p");
+ proto_array_.Add()->assign("x");
+ proto_array_.Add()->assign("y");
+
+ {
+ std::string v = "f";
+ RepeatedPtrField<std::string>::pointer_iterator it =
+ std::lower_bound(proto_array_.pointer_begin(),
+ proto_array_.pointer_end(), &v, StringLessThan());
+
+ GOOGLE_CHECK(*it != nullptr);
+
+ EXPECT_EQ(**it, "n");
+ EXPECT_TRUE(it == proto_array_.pointer_begin() + 3);
+ }
+ {
+ std::string v = "f";
+ RepeatedPtrField<std::string>::const_pointer_iterator it = std::lower_bound(
+ const_proto_array_->pointer_begin(), const_proto_array_->pointer_end(),
+ &v, StringLessThan());
+
+ GOOGLE_CHECK(*it != nullptr);
+
+ EXPECT_EQ(**it, "n");
+ EXPECT_TRUE(it == const_proto_array_->pointer_begin() + 3);
+ }
+}
+
+TEST_F(RepeatedPtrFieldPtrsIteratorTest, PtrMutation) {
+ RepeatedPtrField<std::string>::pointer_iterator iter =
+ proto_array_.pointer_begin();
+ **iter = "qux";
+ EXPECT_EQ("qux", proto_array_.Get(0));
+
+ EXPECT_EQ("bar", proto_array_.Get(1));
+ EXPECT_EQ("baz", proto_array_.Get(2));
+ ++iter;
+ delete *iter;
+ *iter = new std::string("a");
+ ++iter;
+ delete *iter;
+ *iter = new std::string("b");
+ EXPECT_EQ("a", proto_array_.Get(1));
+ EXPECT_EQ("b", proto_array_.Get(2));
+}
+
+TEST_F(RepeatedPtrFieldPtrsIteratorTest, Sort) {
+ proto_array_.Add()->assign("c");
+ proto_array_.Add()->assign("d");
+ proto_array_.Add()->assign("n");
+ proto_array_.Add()->assign("p");
+ proto_array_.Add()->assign("a");
+ proto_array_.Add()->assign("y");
+ proto_array_.Add()->assign("x");
+ EXPECT_EQ("foo", proto_array_.Get(0));
+ EXPECT_EQ("n", proto_array_.Get(5));
+ EXPECT_EQ("x", proto_array_.Get(9));
+ std::sort(proto_array_.pointer_begin(), proto_array_.pointer_end(),
+ StringLessThan());
+ EXPECT_EQ("a", proto_array_.Get(0));
+ EXPECT_EQ("baz", proto_array_.Get(2));
+ EXPECT_EQ("y", proto_array_.Get(9));
+}
+
+// -----------------------------------------------------------------------------
+// Unit-tests for the insert iterators
+// google::protobuf::RepeatedFieldBackInserter,
+// google::protobuf::AllocatedRepeatedPtrFieldBackInserter
+// Ported from util/gtl/proto-array-iterators_unittest.
+
+class RepeatedFieldInsertionIteratorsTest : public testing::Test {
+ protected:
+ std::list<double> halves;
+ std::list<int> fibonacci;
+ std::vector<std::string> words;
+ typedef TestAllTypes::NestedMessage Nested;
+ Nested nesteds[2];
+ std::vector<Nested*> nested_ptrs;
+ TestAllTypes protobuffer;
+
+ virtual void SetUp() {
+ fibonacci.push_back(1);
+ fibonacci.push_back(1);
+ fibonacci.push_back(2);
+ fibonacci.push_back(3);
+ fibonacci.push_back(5);
+ fibonacci.push_back(8);
+ std::copy(fibonacci.begin(), fibonacci.end(),
+ RepeatedFieldBackInserter(protobuffer.mutable_repeated_int32()));
+
+ halves.push_back(1.0);
+ halves.push_back(0.5);
+ halves.push_back(0.25);
+ halves.push_back(0.125);
+ halves.push_back(0.0625);
+ std::copy(halves.begin(), halves.end(),
+ RepeatedFieldBackInserter(protobuffer.mutable_repeated_double()));
+
+ words.push_back("Able");
+ words.push_back("was");
+ words.push_back("I");
+ words.push_back("ere");
+ words.push_back("I");
+ words.push_back("saw");
+ words.push_back("Elba");
+ std::copy(words.begin(), words.end(),
+ RepeatedFieldBackInserter(protobuffer.mutable_repeated_string()));
+
+ nesteds[0].set_bb(17);
+ nesteds[1].set_bb(4711);
+ std::copy(&nesteds[0], &nesteds[2],
+ RepeatedFieldBackInserter(
+ protobuffer.mutable_repeated_nested_message()));
+
+ nested_ptrs.push_back(new Nested);
+ nested_ptrs.back()->set_bb(170);
+ nested_ptrs.push_back(new Nested);
+ nested_ptrs.back()->set_bb(47110);
+ std::copy(nested_ptrs.begin(), nested_ptrs.end(),
+ RepeatedFieldBackInserter(
+ protobuffer.mutable_repeated_nested_message()));
+ }
+
+ virtual void TearDown() {
+ for (auto ptr : nested_ptrs) {
+ delete ptr;
+ }
+ }
+};
+
+TEST_F(RepeatedFieldInsertionIteratorsTest, Fibonacci) {
+ EXPECT_TRUE(std::equal(fibonacci.begin(), fibonacci.end(),
+ protobuffer.repeated_int32().begin()));
+ EXPECT_TRUE(std::equal(protobuffer.repeated_int32().begin(),
+ protobuffer.repeated_int32().end(),
+ fibonacci.begin()));
+}
+
+TEST_F(RepeatedFieldInsertionIteratorsTest, Halves) {
+ EXPECT_TRUE(std::equal(halves.begin(), halves.end(),
+ protobuffer.repeated_double().begin()));
+ EXPECT_TRUE(std::equal(protobuffer.repeated_double().begin(),
+ protobuffer.repeated_double().end(), halves.begin()));
+}
+
+TEST_F(RepeatedFieldInsertionIteratorsTest, Words) {
+ ASSERT_EQ(words.size(), protobuffer.repeated_string_size());
+ for (int i = 0; i < words.size(); ++i)
+ EXPECT_EQ(words.at(i), protobuffer.repeated_string(i));
+}
+
+TEST_F(RepeatedFieldInsertionIteratorsTest, Words2) {
+ words.clear();
+ words.push_back("sing");
+ words.push_back("a");
+ words.push_back("song");
+ words.push_back("of");
+ words.push_back("six");
+ words.push_back("pence");
+ protobuffer.mutable_repeated_string()->Clear();
+ std::copy(
+ words.begin(), words.end(),
+ RepeatedPtrFieldBackInserter(protobuffer.mutable_repeated_string()));
+ ASSERT_EQ(words.size(), protobuffer.repeated_string_size());
+ for (int i = 0; i < words.size(); ++i)
+ EXPECT_EQ(words.at(i), protobuffer.repeated_string(i));
+}
+
+TEST_F(RepeatedFieldInsertionIteratorsTest, Nesteds) {
+ ASSERT_EQ(protobuffer.repeated_nested_message_size(), 4);
+ EXPECT_EQ(protobuffer.repeated_nested_message(0).bb(), 17);
+ EXPECT_EQ(protobuffer.repeated_nested_message(1).bb(), 4711);
+ EXPECT_EQ(protobuffer.repeated_nested_message(2).bb(), 170);
+ EXPECT_EQ(protobuffer.repeated_nested_message(3).bb(), 47110);
+}
+
+TEST_F(RepeatedFieldInsertionIteratorsTest,
+ AllocatedRepeatedPtrFieldWithStringIntData) {
+ std::vector<Nested*> data;
+ TestAllTypes goldenproto;
+ for (int i = 0; i < 10; ++i) {
+ Nested* new_data = new Nested;
+ new_data->set_bb(i);
+ data.push_back(new_data);
+
+ new_data = goldenproto.add_repeated_nested_message();
+ new_data->set_bb(i);
+ }
+ TestAllTypes testproto;
+ std::copy(data.begin(), data.end(),
+ AllocatedRepeatedPtrFieldBackInserter(
+ testproto.mutable_repeated_nested_message()));
+ EXPECT_EQ(testproto.DebugString(), goldenproto.DebugString());
+}
+
+TEST_F(RepeatedFieldInsertionIteratorsTest,
+ AllocatedRepeatedPtrFieldWithString) {
+ std::vector<std::string*> data;
+ TestAllTypes goldenproto;
+ for (int i = 0; i < 10; ++i) {
+ std::string* new_data = new std::string;
+ *new_data = "name-" + StrCat(i);
+ data.push_back(new_data);
+
+ new_data = goldenproto.add_repeated_string();
+ *new_data = "name-" + StrCat(i);
+ }
+ TestAllTypes testproto;
+ std::copy(data.begin(), data.end(),
+ AllocatedRepeatedPtrFieldBackInserter(
+ testproto.mutable_repeated_string()));
+ EXPECT_EQ(testproto.DebugString(), goldenproto.DebugString());
+}
+
+TEST_F(RepeatedFieldInsertionIteratorsTest,
+ UnsafeArenaAllocatedRepeatedPtrFieldWithStringIntData) {
+ std::vector<Nested*> data;
+ Arena arena;
+ auto* goldenproto = Arena::CreateMessage<TestAllTypes>(&arena);
+ for (int i = 0; i < 10; ++i) {
+ auto* new_data = goldenproto->add_repeated_nested_message();
+ new_data->set_bb(i);
+ data.push_back(new_data);
+ }
+ auto* testproto = Arena::CreateMessage<TestAllTypes>(&arena);
+ std::copy(data.begin(), data.end(),
+ UnsafeArenaAllocatedRepeatedPtrFieldBackInserter(
+ testproto->mutable_repeated_nested_message()));
+ EXPECT_EQ(testproto->DebugString(), goldenproto->DebugString());
+}
+
+TEST_F(RepeatedFieldInsertionIteratorsTest,
+ UnsafeArenaAllocatedRepeatedPtrFieldWithString) {
+ std::vector<std::string*> data;
+ Arena arena;
+ auto* goldenproto = Arena::CreateMessage<TestAllTypes>(&arena);
+ for (int i = 0; i < 10; ++i) {
+ auto* new_data = goldenproto->add_repeated_string();
+ *new_data = "name-" + StrCat(i);
+ data.push_back(new_data);
+ }
+ auto* testproto = Arena::CreateMessage<TestAllTypes>(&arena);
+ std::copy(data.begin(), data.end(),
+ UnsafeArenaAllocatedRepeatedPtrFieldBackInserter(
+ testproto->mutable_repeated_string()));
+ EXPECT_EQ(testproto->DebugString(), goldenproto->DebugString());
+}
+
+TEST_F(RepeatedFieldInsertionIteratorsTest, MoveStrings) {
+ std::vector<std::string> src = {"a", "b", "c", "d"};
+ std::vector<std::string> copy =
+ src; // copy since move leaves in undefined state
+ TestAllTypes testproto;
+ std::move(copy.begin(), copy.end(),
+ RepeatedFieldBackInserter(testproto.mutable_repeated_string()));
+
+ ASSERT_THAT(testproto.repeated_string(), testing::ElementsAreArray(src));
+}
+
+TEST_F(RepeatedFieldInsertionIteratorsTest, MoveProtos) {
+ auto make_nested = [](int32 x) {
+ Nested ret;
+ ret.set_bb(x);
+ return ret;
+ };
+ std::vector<Nested> src = {make_nested(3), make_nested(5), make_nested(7)};
+ std::vector<Nested> copy = src; // copy since move leaves in undefined state
+ TestAllTypes testproto;
+ std::move(
+ copy.begin(), copy.end(),
+ RepeatedFieldBackInserter(testproto.mutable_repeated_nested_message()));
+
+ ASSERT_EQ(src.size(), testproto.repeated_nested_message_size());
+ for (int i = 0; i < src.size(); ++i) {
+ EXPECT_EQ(src[i].DebugString(),
+ testproto.repeated_nested_message(i).DebugString());
+ }
+}
+
+} // namespace
+
+} // namespace protobuf
+} // namespace google
+
+#include <port_undef.inc>
diff --git a/NorthstarDedicatedTest/include/protobuf/repeated_ptr_field.cc b/NorthstarDedicatedTest/include/protobuf/repeated_ptr_field.cc
new file mode 100644
index 00000000..05941e91
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/repeated_ptr_field.cc
@@ -0,0 +1,157 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <repeated_field.h>
+
+#include <algorithm>
+
+#include <stubs/logging.h>
+#include <stubs/common.h>
+#include <implicit_weak_message.h>
+
+#include <port_def.inc>
+
+namespace google {
+namespace protobuf {
+
+namespace internal {
+
+void** RepeatedPtrFieldBase::InternalExtend(int extend_amount) {
+ int new_size = current_size_ + extend_amount;
+ if (total_size_ >= new_size) {
+ // N.B.: rep_ is non-nullptr because extend_amount is always > 0, hence
+ // total_size must be non-zero since it is lower-bounded by new_size.
+ return &rep_->elements[current_size_];
+ }
+ Rep* old_rep = rep_;
+ Arena* arena = GetArena();
+ new_size = std::max(internal::kRepeatedFieldLowerClampLimit,
+ std::max(total_size_ * 2, new_size));
+ GOOGLE_CHECK_LE(static_cast<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));
+ }
+#if defined(__GXX_DELETE_WITH_SIZE__) || defined(__cpp_sized_deallocation)
+ const int old_total_size = total_size_;
+#endif
+ total_size_ = new_size;
+ if (old_rep && old_rep->allocated_size > 0) {
+ memcpy(rep_->elements, old_rep->elements,
+ old_rep->allocated_size * sizeof(rep_->elements[0]));
+ rep_->allocated_size = old_rep->allocated_size;
+ } else {
+ rep_->allocated_size = 0;
+ }
+ if (arena == nullptr) {
+#if defined(__GXX_DELETE_WITH_SIZE__) || defined(__cpp_sized_deallocation)
+ const size_t old_size =
+ old_total_size * sizeof(rep_->elements[0]) + kRepHeaderSize;
+ ::operator delete(static_cast<void*>(old_rep), old_size);
+#else
+ ::operator delete(static_cast<void*>(old_rep));
+#endif
+ }
+ return &rep_->elements[current_size_];
+}
+
+void RepeatedPtrFieldBase::Reserve(int new_size) {
+ if (new_size > current_size_) {
+ InternalExtend(new_size - current_size_);
+ }
+}
+
+void RepeatedPtrFieldBase::DestroyProtos() {
+ GOOGLE_DCHECK(rep_);
+ GOOGLE_DCHECK(arena_ == nullptr);
+ int n = rep_->allocated_size;
+ void* const* elements = rep_->elements;
+ for (int i = 0; i < n; i++) {
+ delete static_cast<MessageLite*>(elements[i]);
+ }
+#if defined(__GXX_DELETE_WITH_SIZE__) || defined(__cpp_sized_deallocation)
+ const size_t size = total_size_ * sizeof(elements[0]) + kRepHeaderSize;
+ ::operator delete(static_cast<void*>(rep_), size);
+ rep_ = nullptr;
+#else
+ ::operator delete(static_cast<void*>(rep_));
+ rep_ = nullptr;
+#endif
+}
+
+void* RepeatedPtrFieldBase::AddOutOfLineHelper(void* obj) {
+ if (!rep_ || rep_->allocated_size == total_size_) {
+ InternalExtend(1); // Equivalent to "Reserve(total_size_ + 1)"
+ }
+ ++rep_->allocated_size;
+ rep_->elements[current_size_++] = obj;
+ return obj;
+}
+
+void RepeatedPtrFieldBase::CloseGap(int start, int num) {
+ if (rep_ == nullptr) return;
+ // Close up a gap of "num" elements starting at offset "start".
+ for (int i = start + num; i < rep_->allocated_size; ++i)
+ rep_->elements[i - num] = rep_->elements[i];
+ current_size_ -= num;
+ rep_->allocated_size -= num;
+}
+
+MessageLite* RepeatedPtrFieldBase::AddWeak(const MessageLite* prototype) {
+ if (rep_ != nullptr && current_size_ < rep_->allocated_size) {
+ return reinterpret_cast<MessageLite*>(rep_->elements[current_size_++]);
+ }
+ if (!rep_ || rep_->allocated_size == total_size_) {
+ Reserve(total_size_ + 1);
+ }
+ ++rep_->allocated_size;
+ MessageLite* result = prototype
+ ? prototype->New(arena_)
+ : Arena::CreateMessage<ImplicitWeakMessage>(arena_);
+ rep_->elements[current_size_++] = result;
+ return result;
+}
+
+} // namespace internal
+
+} // namespace protobuf
+} // namespace google
+
+#include <port_undef.inc>
diff --git a/NorthstarDedicatedTest/include/protobuf/repeated_ptr_field.h b/NorthstarDedicatedTest/include/protobuf/repeated_ptr_field.h
new file mode 100644
index 00000000..3f3e30e0
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/repeated_ptr_field.h
@@ -0,0 +1,2014 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// RepeatedField and RepeatedPtrField are used by generated protocol message
+// classes to manipulate repeated fields. These classes are very similar to
+// STL's vector, but include a number of optimizations found to be useful
+// specifically in the case of Protocol Buffers. RepeatedPtrField is
+// particularly different from STL vector as it manages ownership of the
+// pointers that it contains.
+//
+// Typically, clients should not need to access RepeatedField objects directly,
+// but should instead use the accessor functions generated automatically by the
+// protocol compiler.
+//
+// This header covers RepeatedPtrField.
+
+#ifndef GOOGLE_PROTOBUF_REPEATED_PTR_FIELD_H__
+#define GOOGLE_PROTOBUF_REPEATED_PTR_FIELD_H__
+
+#include <utility>
+#ifdef _MSC_VER
+// This is required for min/max on VS2013 only.
+#include <algorithm>
+#endif
+
+#include <iterator>
+#include <limits>
+#include <string>
+#include <type_traits>
+
+#include <stubs/logging.h>
+#include <stubs/common.h>
+#include <arena.h>
+#include <message_lite.h>
+#include <port.h>
+
+
+// Must be included last.
+#include <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();
+ explicit RepeatedPtrFieldBase(Arena* arena);
+ ~RepeatedPtrFieldBase() {
+#ifndef NDEBUG
+ // Try to trigger segfault / asan failure in non-opt builds. If arena_
+ // lifetime has ended before the destructor.
+ if (arena_) (void)arena_->SpaceAllocated();
+#endif
+ }
+
+ // Must be called from destructor.
+ template <typename TypeHandler>
+ void Destroy();
+ bool NeedsDestroy() const { return rep_ != nullptr && arena_ == nullptr; }
+ void DestroyProtos();
+
+ bool empty() const;
+ int size() const;
+
+ template <typename TypeHandler>
+ const typename TypeHandler::Type& at(int index) const;
+ template <typename TypeHandler>
+ typename TypeHandler::Type& at(int index);
+
+ template <typename TypeHandler>
+ typename TypeHandler::Type* Mutable(int index);
+ template <typename TypeHandler>
+ void Delete(int index);
+ template <typename TypeHandler>
+ typename TypeHandler::Type* Add(
+ typename TypeHandler::Type* prototype = nullptr);
+
+ public:
+ // The next few methods are public so that they can be called from generated
+ // code when implicit weak fields are used, but they should never be called by
+ // application code.
+
+ template <typename TypeHandler>
+ const typename TypeHandler::Type& Get(int index) const;
+
+ // Creates and adds an element using the given prototype, without introducing
+ // a link-time dependency on the concrete message type. This method is used to
+ // implement implicit weak fields. The prototype may be nullptr, in which case
+ // an ImplicitWeakMessage will be used as a placeholder.
+ MessageLite* AddWeak(const MessageLite* prototype);
+
+ template <typename TypeHandler>
+ void Clear();
+
+ template <typename TypeHandler>
+ void MergeFrom(const RepeatedPtrFieldBase& other);
+
+ inline void InternalSwap(RepeatedPtrFieldBase*);
+
+ protected:
+ template <
+ typename TypeHandler,
+ typename std::enable_if<TypeHandler::Movable::value>::type* = nullptr>
+ void Add(typename TypeHandler::Type&& value);
+
+ template <typename TypeHandler>
+ void RemoveLast();
+ template <typename TypeHandler>
+ void CopyFrom(const RepeatedPtrFieldBase& other);
+
+ void CloseGap(int start, int num);
+
+ void Reserve(int new_size);
+
+ int Capacity() const;
+
+ template <typename TypeHandler>
+ static inline typename TypeHandler::Type* copy(
+ typename TypeHandler::Type* value) {
+ auto* new_value = TypeHandler::NewFromPrototype(value, nullptr);
+ TypeHandler::Merge(*value, new_value);
+ return new_value;
+ }
+
+ // Used for constructing iterators.
+ void* const* raw_data() const;
+ void** raw_mutable_data() const;
+
+ template <typename TypeHandler>
+ typename TypeHandler::Type** mutable_data();
+ template <typename TypeHandler>
+ const typename TypeHandler::Type* const* data() const;
+
+ template <typename TypeHandler>
+ PROTOBUF_NDEBUG_INLINE void Swap(RepeatedPtrFieldBase* other);
+
+ void SwapElements(int index1, int index2);
+
+ template <typename TypeHandler>
+ size_t SpaceUsedExcludingSelfLong() const;
+
+ // Advanced memory management --------------------------------------
+
+ // Like Add(), but if there are no cleared objects to use, returns nullptr.
+ template <typename TypeHandler>
+ typename TypeHandler::Type* AddFromCleared();
+
+ template <typename TypeHandler>
+ void AddAllocated(typename TypeHandler::Type* value) {
+ typename TypeImplementsMergeBehavior<typename TypeHandler::Type>::type t;
+ AddAllocatedInternal<TypeHandler>(value, t);
+ }
+
+ template <typename TypeHandler>
+ void UnsafeArenaAddAllocated(typename TypeHandler::Type* value);
+
+ template <typename TypeHandler>
+ PROTOBUF_NODISCARD typename TypeHandler::Type* ReleaseLast() {
+ typename TypeImplementsMergeBehavior<typename TypeHandler::Type>::type t;
+ return ReleaseLastInternal<TypeHandler>(t);
+ }
+
+ // Releases last element and returns it, but does not do out-of-arena copy.
+ // And just returns the raw pointer to the contained element in the arena.
+ template <typename TypeHandler>
+ typename TypeHandler::Type* UnsafeArenaReleaseLast();
+
+ int ClearedCount() const;
+ template <typename TypeHandler>
+ void AddCleared(typename TypeHandler::Type* value);
+ template <typename TypeHandler>
+ PROTOBUF_NODISCARD typename TypeHandler::Type* ReleaseCleared();
+
+ template <typename TypeHandler>
+ void AddAllocatedInternal(typename TypeHandler::Type* value, std::true_type);
+ template <typename TypeHandler>
+ void AddAllocatedInternal(typename TypeHandler::Type* value, std::false_type);
+
+ template <typename TypeHandler>
+ PROTOBUF_NOINLINE void AddAllocatedSlowWithCopy(
+ typename TypeHandler::Type* value, Arena* value_arena, Arena* my_arena);
+ template <typename TypeHandler>
+ PROTOBUF_NOINLINE void AddAllocatedSlowWithoutCopy(
+ typename TypeHandler::Type* value);
+
+ template <typename TypeHandler>
+ typename TypeHandler::Type* ReleaseLastInternal(std::true_type);
+ template <typename TypeHandler>
+ typename TypeHandler::Type* ReleaseLastInternal(std::false_type);
+
+ template <typename TypeHandler>
+ PROTOBUF_NOINLINE void SwapFallback(RepeatedPtrFieldBase* other);
+
+ inline Arena* GetArena() const { return arena_; }
+
+ private:
+ static constexpr int kInitialSize = 0;
+ // A few notes on internal representation:
+ //
+ // We use an indirected approach, with struct Rep, to keep
+ // sizeof(RepeatedPtrFieldBase) equivalent to what it was before arena support
+ // was added, namely, 3 8-byte machine words on x86-64. An instance of Rep is
+ // allocated only when the repeated field is non-empty, and it is a
+ // dynamically-sized struct (the header is directly followed by elements[]).
+ // We place arena_ and current_size_ directly in the object to avoid cache
+ // misses due to the indirection, because these fields are checked frequently.
+ // Placing all fields directly in the RepeatedPtrFieldBase instance costs
+ // significant performance for memory-sensitive workloads.
+ Arena* arena_;
+ int current_size_;
+ int total_size_;
+ struct Rep {
+ int allocated_size;
+ // Here we declare a huge array as a way of approximating C's "flexible
+ // array member" feature without relying on undefined behavior.
+ void* elements[(std::numeric_limits<int>::max() - 2 * sizeof(int)) /
+ sizeof(void*)];
+ };
+ static constexpr size_t kRepHeaderSize = offsetof(Rep, elements);
+ Rep* rep_;
+
+ template <typename TypeHandler>
+ static inline typename TypeHandler::Type* cast(void* element) {
+ return reinterpret_cast<typename TypeHandler::Type*>(element);
+ }
+ template <typename TypeHandler>
+ static inline const typename TypeHandler::Type* cast(const void* element) {
+ return reinterpret_cast<const typename TypeHandler::Type*>(element);
+ }
+
+ // Non-templated inner function to avoid code duplication. Takes a function
+ // pointer to the type-specific (templated) inner allocate/merge loop.
+ void MergeFromInternal(const RepeatedPtrFieldBase& other,
+ void (RepeatedPtrFieldBase::*inner_loop)(void**,
+ void**, int,
+ int));
+
+ template <typename TypeHandler>
+ PROTOBUF_NOINLINE void MergeFromInnerLoop(void** our_elems,
+ void** other_elems, int length,
+ int already_allocated);
+
+ // Internal helper: extend array space if necessary to contain |extend_amount|
+ // more elements, and return a pointer to the element immediately following
+ // the old list of elements. This interface factors out common behavior from
+ // Reserve() and MergeFrom() to reduce code size. |extend_amount| must be > 0.
+ void** InternalExtend(int extend_amount);
+
+ // Internal helper for Add: add "obj" as the next element in the
+ // array, including potentially resizing the array with Reserve if
+ // needed
+ void* AddOutOfLineHelper(void* obj);
+
+ // The reflection implementation needs to call protected methods directly,
+ // reinterpreting pointers as being to Message instead of a specific Message
+ // subclass.
+ friend class ::PROTOBUF_NAMESPACE_ID::Reflection;
+ friend class ::PROTOBUF_NAMESPACE_ID::internal::SwapFieldHelper;
+
+ // ExtensionSet stores repeated message extensions as
+ // RepeatedPtrField<MessageLite>, but non-lite ExtensionSets need to implement
+ // SpaceUsedLong(), and thus need to call SpaceUsedExcludingSelfLong()
+ // reinterpreting MessageLite as Message. ExtensionSet also needs to make use
+ // of AddFromCleared(), which is not part of the public interface.
+ friend class ExtensionSet;
+
+ // The MapFieldBase implementation needs to call protected methods directly,
+ // reinterpreting pointers as being to Message instead of a specific Message
+ // subclass.
+ friend class MapFieldBase;
+ friend class MapFieldBaseStub;
+
+ // The table-driven MergePartialFromCodedStream implementation needs to
+ // operate on RepeatedPtrField<MessageLite>.
+ friend class MergePartialFromCodedStreamHelper;
+ friend class AccessorHelper;
+ template <typename T>
+ friend struct google::protobuf::WeakRepeatedPtrField;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedPtrFieldBase);
+};
+
+template <typename GenericType>
+class GenericTypeHandler {
+ public:
+ typedef GenericType Type;
+ using Movable = IsMovable<GenericType>;
+
+ static inline GenericType* New(Arena* arena) {
+ return Arena::CreateMaybeMessage<Type>(arena);
+ }
+ static inline GenericType* New(Arena* arena, GenericType&& value) {
+ return Arena::Create<GenericType>(arena, std::move(value));
+ }
+ static inline GenericType* NewFromPrototype(const GenericType* prototype,
+ Arena* arena = nullptr);
+ static inline void Delete(GenericType* value, Arena* arena) {
+ if (arena == nullptr) {
+ delete value;
+ }
+ }
+ static inline Arena* GetOwningArena(GenericType* value) {
+ return Arena::GetOwningArena<Type>(value);
+ }
+
+ static inline void Clear(GenericType* value) { value->Clear(); }
+ PROTOBUF_NOINLINE
+ static void Merge(const GenericType& from, GenericType* to);
+ static inline size_t SpaceUsedLong(const GenericType& value) {
+ return value.SpaceUsedLong();
+ }
+};
+
+template <typename GenericType>
+GenericType* GenericTypeHandler<GenericType>::NewFromPrototype(
+ const GenericType* /* prototype */, Arena* arena) {
+ return New(arena);
+}
+template <typename GenericType>
+void GenericTypeHandler<GenericType>::Merge(const GenericType& from,
+ GenericType* to) {
+ to->MergeFrom(from);
+}
+
+// NewFromPrototype() and Merge() are not defined inline here, as we will need
+// to do a virtual function dispatch anyways to go from Message* to call
+// New/Merge.
+template <>
+MessageLite* GenericTypeHandler<MessageLite>::NewFromPrototype(
+ const MessageLite* prototype, Arena* arena);
+template <>
+inline Arena* GenericTypeHandler<MessageLite>::GetOwningArena(
+ MessageLite* value) {
+ return value->GetOwningArena();
+}
+template <>
+void GenericTypeHandler<MessageLite>::Merge(const MessageLite& from,
+ MessageLite* to);
+template <>
+inline void GenericTypeHandler<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);
+ Element* Add();
+ void Add(Element&& value);
+ // Append elements in the range [begin, end) after reserving
+ // the appropriate number of elements.
+ template <typename Iter>
+ void Add(Iter begin, Iter end);
+
+ const Element& operator[](int index) const { return Get(index); }
+ Element& operator[](int index) { return *Mutable(index); }
+
+ const Element& at(int index) const;
+ Element& at(int index);
+
+ // Remove the last element in the array.
+ // Ownership of the element is retained by the array.
+ void RemoveLast();
+
+ // Delete elements with indices in the range [start .. start+num-1].
+ // Caution: implementation moves all elements with indices [start+num .. ].
+ // Calling this routine inside a loop can cause quadratic behavior.
+ void DeleteSubrange(int start, int num);
+
+ PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear();
+ void MergeFrom(const RepeatedPtrField& other);
+ PROTOBUF_ATTRIBUTE_REINITIALIZES void CopyFrom(const RepeatedPtrField& other);
+
+ // Replaces the contents with RepeatedPtrField(begin, end).
+ template <typename Iter>
+ PROTOBUF_ATTRIBUTE_REINITIALIZES void Assign(Iter begin, Iter end);
+
+ // Reserve space to expand the field to at least the given size. This only
+ // resizes the pointer array; it doesn't allocate any objects. If the
+ // array is grown, it will always be at least doubled in size.
+ void Reserve(int new_size);
+
+ int Capacity() const;
+
+ // Gets the underlying array. This pointer is possibly invalidated by
+ // any add or remove operation.
+ Element** mutable_data();
+ const Element* const* data() const;
+
+ // Swap entire contents with "other". If they are on separate arenas, then
+ // copies data.
+ void Swap(RepeatedPtrField* other);
+
+ // Swap entire contents with "other". Caller should guarantee that either both
+ // fields are on the same arena or both are on the heap. Swapping between
+ // different arenas with this function is disallowed and is caught via
+ // GOOGLE_DCHECK.
+ void UnsafeArenaSwap(RepeatedPtrField* other);
+
+ // Swap two elements.
+ void SwapElements(int index1, int index2);
+
+ // STL-like iterator support
+ typedef internal::RepeatedPtrIterator<Element> iterator;
+ typedef internal::RepeatedPtrIterator<const Element> const_iterator;
+ typedef Element value_type;
+ typedef value_type& reference;
+ typedef const value_type& const_reference;
+ typedef value_type* pointer;
+ typedef const value_type* const_pointer;
+ typedef int size_type;
+ typedef ptrdiff_t difference_type;
+
+ iterator begin();
+ const_iterator begin() const;
+ const_iterator cbegin() const;
+ iterator end();
+ const_iterator end() const;
+ const_iterator cend() const;
+
+ // Reverse iterator support
+ typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+ typedef std::reverse_iterator<iterator> reverse_iterator;
+ reverse_iterator rbegin() { return reverse_iterator(end()); }
+ const_reverse_iterator rbegin() const {
+ return const_reverse_iterator(end());
+ }
+ reverse_iterator rend() { return reverse_iterator(begin()); }
+ const_reverse_iterator rend() const {
+ return const_reverse_iterator(begin());
+ }
+
+ // Custom STL-like iterator that iterates over and returns the underlying
+ // pointers to Element rather than Element itself.
+ typedef internal::RepeatedPtrOverPtrsIterator<Element*, void*>
+ pointer_iterator;
+ typedef internal::RepeatedPtrOverPtrsIterator<const Element* const,
+ const void* const>
+ const_pointer_iterator;
+ pointer_iterator pointer_begin();
+ const_pointer_iterator pointer_begin() const;
+ pointer_iterator pointer_end();
+ const_pointer_iterator pointer_end() const;
+
+ // Returns (an estimate of) the number of bytes used by the repeated field,
+ // excluding sizeof(*this).
+ size_t SpaceUsedExcludingSelfLong() const;
+
+ int SpaceUsedExcludingSelf() const {
+ return internal::ToIntSize(SpaceUsedExcludingSelfLong());
+ }
+
+ // Advanced memory management --------------------------------------
+ // When hardcore memory management becomes necessary -- as it sometimes
+ // does here at Google -- the following methods may be useful.
+
+ // Add an already-allocated object, passing ownership to the
+ // RepeatedPtrField.
+ //
+ // Note that some special behavior occurs with respect to arenas:
+ //
+ // (i) if this field holds submessages, the new submessage will be copied if
+ // the original is in an arena and this RepeatedPtrField is either in a
+ // different arena, or on the heap.
+ // (ii) if this field holds strings, the passed-in string *must* be
+ // heap-allocated, not arena-allocated. There is no way to dynamically check
+ // this at runtime, so User Beware.
+ void AddAllocated(Element* value);
+
+ // Remove the last element and return it, passing ownership to the caller.
+ // Requires: size() > 0
+ //
+ // If this RepeatedPtrField is on an arena, an object copy is required to pass
+ // ownership back to the user (for compatible semantics). Use
+ // UnsafeArenaReleaseLast() if this behavior is undesired.
+ PROTOBUF_NODISCARD Element* ReleaseLast();
+
+ // Add an already-allocated object, skipping arena-ownership checks. The user
+ // must guarantee that the given object is in the same arena as this
+ // RepeatedPtrField.
+ // It is also useful in legacy code that uses temporary ownership to avoid
+ // copies. Example:
+ // RepeatedPtrField<T> temp_field;
+ // temp_field.UnsafeArenaAddAllocated(new T);
+ // ... // Do something with temp_field
+ // temp_field.UnsafeArenaExtractSubrange(0, temp_field.size(), nullptr);
+ // If you put temp_field on the arena this fails, because the ownership
+ // transfers to the arena at the "AddAllocated" call and is not released
+ // anymore causing a double delete. UnsafeArenaAddAllocated prevents this.
+ void UnsafeArenaAddAllocated(Element* value);
+
+ // Remove the last element and return it. Unlike ReleaseLast, the returned
+ // pointer is always to the original object. This may be in an arena, and
+ // therefore have the arena's lifetime.
+ // Requires: current_size_ > 0
+ Element* UnsafeArenaReleaseLast();
+
+ // Extract elements with indices in the range "[start .. start+num-1]".
+ // The caller assumes ownership of the extracted elements and is responsible
+ // for deleting them when they are no longer needed.
+ // If "elements" is non-nullptr, then pointers to the extracted elements
+ // are stored in "elements[0 .. num-1]" for the convenience of the caller.
+ // If "elements" is nullptr, then the caller must use some other mechanism
+ // to perform any further operations (like deletion) on these elements.
+ // Caution: implementation also moves elements with indices [start+num ..].
+ // Calling this routine inside a loop can cause quadratic behavior.
+ //
+ // Memory copying behavior is identical to ReleaseLast(), described above: if
+ // this RepeatedPtrField is on an arena, an object copy is performed for each
+ // returned element, so that all returned element pointers are to
+ // heap-allocated copies. If this copy is not desired, the user should call
+ // UnsafeArenaExtractSubrange().
+ void ExtractSubrange(int start, int num, Element** elements);
+
+ // Identical to ExtractSubrange() described above, except that no object
+ // copies are ever performed. Instead, the raw object pointers are returned.
+ // Thus, if on an arena, the returned objects must not be freed, because they
+ // will not be heap-allocated objects.
+ void UnsafeArenaExtractSubrange(int start, int num, Element** elements);
+
+ // When elements are removed by calls to RemoveLast() or Clear(), they
+ // are not actually freed. Instead, they are cleared and kept so that
+ // they can be reused later. This can save lots of CPU time when
+ // repeatedly reusing a protocol message for similar purposes.
+ //
+ // Hardcore programs may choose to manipulate these cleared objects
+ // to better optimize memory management using the following routines.
+
+ // Get the number of cleared objects that are currently being kept
+ // around for reuse.
+ int ClearedCount() const;
+#ifndef PROTOBUF_FUTURE_BREAKING_CHANGES
+ // Add an element to the pool of cleared objects, passing ownership to
+ // the RepeatedPtrField. The element must be cleared prior to calling
+ // this method.
+ //
+ // This method cannot be called when the repeated field is on an arena or when
+ // |value| is; both cases will trigger a GOOGLE_DCHECK-failure.
+ void AddCleared(Element* value);
+ // Remove a single element from the cleared pool and return it, passing
+ // ownership to the caller. The element is guaranteed to be cleared.
+ // Requires: ClearedCount() > 0
+ //
+ //
+ // This method cannot be called when the repeated field is on an arena; doing
+ // so will trigger a GOOGLE_DCHECK-failure.
+ PROTOBUF_NODISCARD Element* ReleaseCleared();
+#endif // !PROTOBUF_FUTURE_BREAKING_CHANGES
+
+ // Removes the element referenced by position.
+ //
+ // Returns an iterator to the element immediately following the removed
+ // element.
+ //
+ // Invalidates all iterators at or after the removed element, including end().
+ iterator erase(const_iterator position);
+
+ // Removes the elements in the range [first, last).
+ //
+ // Returns an iterator to the element immediately following the removed range.
+ //
+ // Invalidates all iterators at or after the removed range, including end().
+ iterator erase(const_iterator first, const_iterator last);
+
+ // Gets the arena on which this RepeatedPtrField stores its elements.
+ inline Arena* GetArena() const;
+
+ // For internal use only.
+ //
+ // This is public due to it being called by generated code.
+ void InternalSwap(RepeatedPtrField* other) {
+ internal::RepeatedPtrFieldBase::InternalSwap(other);
+ }
+
+ private:
+ // Note: RepeatedPtrField SHOULD NOT be subclassed by users.
+ class TypeHandler;
+
+ // Implementations for ExtractSubrange(). The copying behavior must be
+ // included only if the type supports the necessary operations (e.g.,
+ // MergeFrom()), so we must resolve this at compile time. ExtractSubrange()
+ // uses SFINAE to choose one of the below implementations.
+ void ExtractSubrangeInternal(int start, int num, Element** elements,
+ std::true_type);
+ void ExtractSubrangeInternal(int start, int num, Element** elements,
+ std::false_type);
+
+ friend class Arena;
+
+ template <typename T>
+ friend struct WeakRepeatedPtrField;
+
+ typedef void InternalArenaConstructable_;
+
+};
+
+// implementation ====================================================
+
+namespace internal {
+
+constexpr RepeatedPtrFieldBase::RepeatedPtrFieldBase()
+ : arena_(nullptr), current_size_(0), total_size_(0), rep_(nullptr) {}
+
+inline RepeatedPtrFieldBase::RepeatedPtrFieldBase(Arena* arena)
+ : arena_(arena), current_size_(0), total_size_(0), rep_(nullptr) {}
+
+template <typename TypeHandler>
+void RepeatedPtrFieldBase::Destroy() {
+ if (rep_ != nullptr && arena_ == nullptr) {
+ int n = rep_->allocated_size;
+ void* const* elements = rep_->elements;
+ for (int i = 0; i < n; i++) {
+ TypeHandler::Delete(cast<TypeHandler>(elements[i]), nullptr);
+ }
+#if defined(__GXX_DELETE_WITH_SIZE__) || defined(__cpp_sized_deallocation)
+ const size_t size = total_size_ * sizeof(elements[0]) + kRepHeaderSize;
+ ::operator delete(static_cast<void*>(rep_), size);
+#else
+ ::operator delete(static_cast<void*>(rep_));
+#endif
+ }
+ rep_ = nullptr;
+}
+
+template <typename TypeHandler>
+inline void RepeatedPtrFieldBase::Swap(RepeatedPtrFieldBase* other) {
+#ifdef PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetArena() != nullptr && GetArena() == other->GetArena()) {
+#else // PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetArena() == other->GetArena()) {
+#endif // !PROTOBUF_FORCE_COPY_IN_SWAP
+ InternalSwap(other);
+ } else {
+ SwapFallback<TypeHandler>(other);
+ }
+}
+
+template <typename TypeHandler>
+void RepeatedPtrFieldBase::SwapFallback(RepeatedPtrFieldBase* other) {
+#ifdef PROTOBUF_FORCE_COPY_IN_SWAP
+ GOOGLE_DCHECK(GetArena() == nullptr || other->GetArena() != GetArena());
+#else // PROTOBUF_FORCE_COPY_IN_SWAP
+ GOOGLE_DCHECK(other->GetArena() != GetArena());
+#endif // !PROTOBUF_FORCE_COPY_IN_SWAP
+
+ // Copy semantics in this case. We try to improve efficiency by placing the
+ // temporary on |other|'s arena so that messages are copied twice rather than
+ // three times.
+ RepeatedPtrFieldBase temp(other->GetArena());
+ temp.MergeFrom<TypeHandler>(*this);
+ this->Clear<TypeHandler>();
+ this->MergeFrom<TypeHandler>(*other);
+ other->InternalSwap(&temp);
+ temp.Destroy<TypeHandler>(); // Frees rep_ if `other` had no arena.
+}
+
+inline bool RepeatedPtrFieldBase::empty() const { return current_size_ == 0; }
+
+inline int RepeatedPtrFieldBase::size() const { return current_size_; }
+
+template <typename TypeHandler>
+inline const typename TypeHandler::Type& RepeatedPtrFieldBase::Get(
+ int index) const {
+ GOOGLE_DCHECK_GE(index, 0);
+ GOOGLE_DCHECK_LT(index, current_size_);
+ return *cast<TypeHandler>(rep_->elements[index]);
+}
+
+template <typename TypeHandler>
+inline const typename TypeHandler::Type& RepeatedPtrFieldBase::at(
+ int index) const {
+ GOOGLE_CHECK_GE(index, 0);
+ GOOGLE_CHECK_LT(index, current_size_);
+ return *cast<TypeHandler>(rep_->elements[index]);
+}
+
+template <typename TypeHandler>
+inline typename TypeHandler::Type& RepeatedPtrFieldBase::at(int index) {
+ GOOGLE_CHECK_GE(index, 0);
+ GOOGLE_CHECK_LT(index, current_size_);
+ return *cast<TypeHandler>(rep_->elements[index]);
+}
+
+template <typename TypeHandler>
+inline typename TypeHandler::Type* RepeatedPtrFieldBase::Mutable(int index) {
+ GOOGLE_DCHECK_GE(index, 0);
+ GOOGLE_DCHECK_LT(index, current_size_);
+ return cast<TypeHandler>(rep_->elements[index]);
+}
+
+template <typename TypeHandler>
+inline void RepeatedPtrFieldBase::Delete(int index) {
+ GOOGLE_DCHECK_GE(index, 0);
+ GOOGLE_DCHECK_LT(index, current_size_);
+ TypeHandler::Delete(cast<TypeHandler>(rep_->elements[index]), arena_);
+}
+
+template <typename TypeHandler>
+inline typename TypeHandler::Type* RepeatedPtrFieldBase::Add(
+ typename TypeHandler::Type* prototype) {
+ if (rep_ != nullptr && current_size_ < rep_->allocated_size) {
+ return cast<TypeHandler>(rep_->elements[current_size_++]);
+ }
+ typename TypeHandler::Type* result =
+ TypeHandler::NewFromPrototype(prototype, arena_);
+ return reinterpret_cast<typename TypeHandler::Type*>(
+ AddOutOfLineHelper(result));
+}
+
+template <typename TypeHandler,
+ typename std::enable_if<TypeHandler::Movable::value>::type*>
+inline void RepeatedPtrFieldBase::Add(typename TypeHandler::Type&& value) {
+ if (rep_ != nullptr && current_size_ < rep_->allocated_size) {
+ *cast<TypeHandler>(rep_->elements[current_size_++]) = std::move(value);
+ return;
+ }
+ if (!rep_ || rep_->allocated_size == total_size_) {
+ Reserve(total_size_ + 1);
+ }
+ ++rep_->allocated_size;
+ typename TypeHandler::Type* result =
+ TypeHandler::New(arena_, std::move(value));
+ rep_->elements[current_size_++] = result;
+}
+
+template <typename TypeHandler>
+inline void RepeatedPtrFieldBase::RemoveLast() {
+ GOOGLE_DCHECK_GT(current_size_, 0);
+ TypeHandler::Clear(cast<TypeHandler>(rep_->elements[--current_size_]));
+}
+
+template <typename TypeHandler>
+void RepeatedPtrFieldBase::Clear() {
+ const int n = current_size_;
+ GOOGLE_DCHECK_GE(n, 0);
+ if (n > 0) {
+ void* const* elements = rep_->elements;
+ int i = 0;
+ do {
+ TypeHandler::Clear(cast<TypeHandler>(elements[i++]));
+ } while (i < n);
+ current_size_ = 0;
+ }
+}
+
+// To avoid unnecessary code duplication and reduce binary size, we use a
+// layered approach to implementing MergeFrom(). The toplevel method is
+// templated, so we get a small thunk per concrete message type in the binary.
+// This calls a shared implementation with most of the logic, passing a function
+// pointer to another type-specific piece of code that calls the object-allocate
+// and merge handlers.
+template <typename TypeHandler>
+inline void RepeatedPtrFieldBase::MergeFrom(const RepeatedPtrFieldBase& other) {
+ GOOGLE_DCHECK_NE(&other, this);
+ if (other.current_size_ == 0) return;
+ MergeFromInternal(other,
+ &RepeatedPtrFieldBase::MergeFromInnerLoop<TypeHandler>);
+}
+
+inline void RepeatedPtrFieldBase::MergeFromInternal(
+ const RepeatedPtrFieldBase& other,
+ void (RepeatedPtrFieldBase::*inner_loop)(void**, void**, int, int)) {
+ // Note: wrapper has already guaranteed that other.rep_ != nullptr here.
+ int other_size = other.current_size_;
+ void** other_elements = other.rep_->elements;
+ void** new_elements = InternalExtend(other_size);
+ int allocated_elems = rep_->allocated_size - current_size_;
+ (this->*inner_loop)(new_elements, other_elements, other_size,
+ allocated_elems);
+ current_size_ += other_size;
+ if (rep_->allocated_size < current_size_) {
+ rep_->allocated_size = current_size_;
+ }
+}
+
+// Merges other_elems to our_elems.
+template <typename TypeHandler>
+void RepeatedPtrFieldBase::MergeFromInnerLoop(void** our_elems,
+ void** other_elems, int length,
+ int already_allocated) {
+ if (already_allocated < length) {
+ Arena* arena = GetArena();
+ typename TypeHandler::Type* elem_prototype =
+ reinterpret_cast<typename TypeHandler::Type*>(other_elems[0]);
+ for (int i = already_allocated; i < length; i++) {
+ // Allocate a new empty element that we'll merge into below
+ typename TypeHandler::Type* new_elem =
+ TypeHandler::NewFromPrototype(elem_prototype, arena);
+ our_elems[i] = new_elem;
+ }
+ }
+ // Main loop that does the actual merging
+ for (int i = 0; i < length; i++) {
+ // Already allocated: use existing element.
+ typename TypeHandler::Type* other_elem =
+ reinterpret_cast<typename TypeHandler::Type*>(other_elems[i]);
+ typename TypeHandler::Type* new_elem =
+ reinterpret_cast<typename TypeHandler::Type*>(our_elems[i]);
+ TypeHandler::Merge(*other_elem, new_elem);
+ }
+}
+
+template <typename TypeHandler>
+inline void RepeatedPtrFieldBase::CopyFrom(const RepeatedPtrFieldBase& other) {
+ if (&other == this) return;
+ RepeatedPtrFieldBase::Clear<TypeHandler>();
+ RepeatedPtrFieldBase::MergeFrom<TypeHandler>(other);
+}
+
+inline int RepeatedPtrFieldBase::Capacity() const { return total_size_; }
+
+inline void* const* RepeatedPtrFieldBase::raw_data() const {
+ return rep_ ? rep_->elements : nullptr;
+}
+
+inline void** RepeatedPtrFieldBase::raw_mutable_data() const {
+ return rep_ ? const_cast<void**>(rep_->elements) : nullptr;
+}
+
+template <typename TypeHandler>
+inline typename TypeHandler::Type** RepeatedPtrFieldBase::mutable_data() {
+ // TODO(kenton): Breaks C++ aliasing rules. We should probably remove this
+ // method entirely.
+ return reinterpret_cast<typename TypeHandler::Type**>(raw_mutable_data());
+}
+
+template <typename TypeHandler>
+inline const typename TypeHandler::Type* const* RepeatedPtrFieldBase::data()
+ const {
+ // TODO(kenton): Breaks C++ aliasing rules. We should probably remove this
+ // method entirely.
+ return reinterpret_cast<const typename TypeHandler::Type* const*>(raw_data());
+}
+
+inline void RepeatedPtrFieldBase::SwapElements(int index1, int index2) {
+ using std::swap; // enable ADL with fallback
+ swap(rep_->elements[index1], rep_->elements[index2]);
+}
+
+template <typename TypeHandler>
+inline size_t RepeatedPtrFieldBase::SpaceUsedExcludingSelfLong() const {
+ size_t allocated_bytes = static_cast<size_t>(total_size_) * sizeof(void*);
+ if (rep_ != nullptr) {
+ for (int i = 0; i < rep_->allocated_size; ++i) {
+ allocated_bytes +=
+ TypeHandler::SpaceUsedLong(*cast<TypeHandler>(rep_->elements[i]));
+ }
+ allocated_bytes += kRepHeaderSize;
+ }
+ return allocated_bytes;
+}
+
+template <typename TypeHandler>
+inline typename TypeHandler::Type* RepeatedPtrFieldBase::AddFromCleared() {
+ if (rep_ != nullptr && current_size_ < rep_->allocated_size) {
+ return cast<TypeHandler>(rep_->elements[current_size_++]);
+ } else {
+ return nullptr;
+ }
+}
+
+// AddAllocated version that implements arena-safe copying behavior.
+template <typename TypeHandler>
+void RepeatedPtrFieldBase::AddAllocatedInternal(
+ typename TypeHandler::Type* value, std::true_type) {
+ Arena* element_arena =
+ reinterpret_cast<Arena*>(TypeHandler::GetOwningArena(value));
+ Arena* arena = GetArena();
+ if (arena == element_arena && rep_ && rep_->allocated_size < total_size_) {
+ // Fast path: underlying arena representation (tagged pointer) is equal to
+ // our arena pointer, and we can add to array without resizing it (at least
+ // one slot that is not allocated).
+ void** elems = rep_->elements;
+ if (current_size_ < rep_->allocated_size) {
+ // Make space at [current] by moving first allocated element to end of
+ // allocated list.
+ elems[rep_->allocated_size] = elems[current_size_];
+ }
+ elems[current_size_] = value;
+ current_size_ = current_size_ + 1;
+ rep_->allocated_size = rep_->allocated_size + 1;
+ } else {
+ AddAllocatedSlowWithCopy<TypeHandler>(value, element_arena, arena);
+ }
+}
+
+// Slowpath handles all cases, copying if necessary.
+template <typename TypeHandler>
+void RepeatedPtrFieldBase::AddAllocatedSlowWithCopy(
+ // Pass value_arena and my_arena to avoid duplicate virtual call (value) or
+ // load (mine).
+ typename TypeHandler::Type* value, Arena* value_arena, Arena* my_arena) {
+ // Ensure that either the value is in the same arena, or if not, we do the
+ // appropriate thing: Own() it (if it's on heap and we're in an arena) or copy
+ // it to our arena/heap (otherwise).
+ if (my_arena != nullptr && value_arena == nullptr) {
+ my_arena->Own(value);
+ } else if (my_arena != value_arena) {
+ typename TypeHandler::Type* new_value =
+ TypeHandler::NewFromPrototype(value, my_arena);
+ TypeHandler::Merge(*value, new_value);
+ TypeHandler::Delete(value, value_arena);
+ value = new_value;
+ }
+
+ UnsafeArenaAddAllocated<TypeHandler>(value);
+}
+
+// AddAllocated version that does not implement arena-safe copying behavior.
+template <typename TypeHandler>
+void RepeatedPtrFieldBase::AddAllocatedInternal(
+ typename TypeHandler::Type* value, std::false_type) {
+ if (rep_ && rep_->allocated_size < total_size_) {
+ // Fast path: underlying arena representation (tagged pointer) is equal to
+ // our arena pointer, and we can add to array without resizing it (at least
+ // one slot that is not allocated).
+ void** elems = rep_->elements;
+ if (current_size_ < rep_->allocated_size) {
+ // Make space at [current] by moving first allocated element to end of
+ // allocated list.
+ elems[rep_->allocated_size] = elems[current_size_];
+ }
+ elems[current_size_] = value;
+ current_size_ = current_size_ + 1;
+ ++rep_->allocated_size;
+ } else {
+ UnsafeArenaAddAllocated<TypeHandler>(value);
+ }
+}
+
+template <typename TypeHandler>
+void RepeatedPtrFieldBase::UnsafeArenaAddAllocated(
+ typename TypeHandler::Type* value) {
+ // Make room for the new pointer.
+ if (!rep_ || current_size_ == total_size_) {
+ // The array is completely full with no cleared objects, so grow it.
+ Reserve(total_size_ + 1);
+ ++rep_->allocated_size;
+ } else if (rep_->allocated_size == total_size_) {
+ // There is no more space in the pointer array because it contains some
+ // cleared objects awaiting reuse. We don't want to grow the array in this
+ // case because otherwise a loop calling AddAllocated() followed by Clear()
+ // would leak memory.
+ TypeHandler::Delete(cast<TypeHandler>(rep_->elements[current_size_]),
+ arena_);
+ } else if (current_size_ < rep_->allocated_size) {
+ // We have some cleared objects. We don't care about their order, so we
+ // can just move the first one to the end to make space.
+ rep_->elements[rep_->allocated_size] = rep_->elements[current_size_];
+ ++rep_->allocated_size;
+ } else {
+ // There are no cleared objects.
+ ++rep_->allocated_size;
+ }
+
+ rep_->elements[current_size_++] = value;
+}
+
+// ReleaseLast() for types that implement merge/copy behavior.
+template <typename TypeHandler>
+inline typename TypeHandler::Type* RepeatedPtrFieldBase::ReleaseLastInternal(
+ std::true_type) {
+ // First, release an element.
+ typename TypeHandler::Type* result = UnsafeArenaReleaseLast<TypeHandler>();
+ // Now perform a copy if we're on an arena.
+ Arena* arena = GetArena();
+
+ typename TypeHandler::Type* new_result;
+#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE
+ new_result = copy<TypeHandler>(result);
+ if (arena == nullptr) delete result;
+#else // PROTOBUF_FORCE_COPY_IN_RELEASE
+ new_result = (arena == nullptr) ? result : copy<TypeHandler>(result);
+#endif // !PROTOBUF_FORCE_COPY_IN_RELEASE
+ return new_result;
+}
+
+// ReleaseLast() for types that *do not* implement merge/copy behavior -- this
+// is the same as UnsafeArenaReleaseLast(). Note that we GOOGLE_DCHECK-fail if we're on
+// an arena, since the user really should implement the copy operation in this
+// case.
+template <typename TypeHandler>
+inline typename TypeHandler::Type* RepeatedPtrFieldBase::ReleaseLastInternal(
+ std::false_type) {
+ GOOGLE_DCHECK(GetArena() == nullptr)
+ << "ReleaseLast() called on a RepeatedPtrField that is on an arena, "
+ << "with a type that does not implement MergeFrom. This is unsafe; "
+ << "please implement MergeFrom for your type.";
+ return UnsafeArenaReleaseLast<TypeHandler>();
+}
+
+template <typename TypeHandler>
+inline typename TypeHandler::Type*
+RepeatedPtrFieldBase::UnsafeArenaReleaseLast() {
+ GOOGLE_DCHECK_GT(current_size_, 0);
+ typename TypeHandler::Type* result =
+ cast<TypeHandler>(rep_->elements[--current_size_]);
+ --rep_->allocated_size;
+ if (current_size_ < rep_->allocated_size) {
+ // There are cleared elements on the end; replace the removed element
+ // with the last allocated element.
+ rep_->elements[current_size_] = rep_->elements[rep_->allocated_size];
+ }
+ return result;
+}
+
+inline int RepeatedPtrFieldBase::ClearedCount() const {
+ return rep_ ? (rep_->allocated_size - current_size_) : 0;
+}
+
+template <typename TypeHandler>
+inline void RepeatedPtrFieldBase::AddCleared(
+ typename TypeHandler::Type* value) {
+ GOOGLE_DCHECK(GetArena() == nullptr)
+ << "AddCleared() can only be used on a RepeatedPtrField not on an arena.";
+ GOOGLE_DCHECK(TypeHandler::GetOwningArena(value) == nullptr)
+ << "AddCleared() can only accept values not on an arena.";
+ if (!rep_ || rep_->allocated_size == total_size_) {
+ Reserve(total_size_ + 1);
+ }
+ rep_->elements[rep_->allocated_size++] = value;
+}
+
+template <typename TypeHandler>
+inline typename TypeHandler::Type* RepeatedPtrFieldBase::ReleaseCleared() {
+ GOOGLE_DCHECK(GetArena() == nullptr)
+ << "ReleaseCleared() can only be used on a RepeatedPtrField not on "
+ << "an arena.";
+ GOOGLE_DCHECK(GetArena() == nullptr);
+ GOOGLE_DCHECK(rep_ != nullptr);
+ GOOGLE_DCHECK_GT(rep_->allocated_size, current_size_);
+ return cast<TypeHandler>(rep_->elements[--rep_->allocated_size]);
+}
+
+} // namespace internal
+
+// -------------------------------------------------------------------
+
+template <typename Element>
+class RepeatedPtrField<Element>::TypeHandler
+ : public internal::GenericTypeHandler<Element> {};
+
+template <>
+class RepeatedPtrField<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.GetArena()) {
+ CopyFrom(other);
+ } else {
+ InternalSwap(&other);
+ }
+#endif // !PROTOBUF_FORCE_COPY_IN_MOVE
+}
+
+template <typename Element>
+inline RepeatedPtrField<Element>& RepeatedPtrField<Element>::operator=(
+ RepeatedPtrField&& other) noexcept {
+ // We don't just call Swap(&other) here because it would perform 3 copies if
+ // the two fields are on different arenas.
+ if (this != &other) {
+ if (GetArena() != other.GetArena()
+#ifdef PROTOBUF_FORCE_COPY_IN_MOVE
+ || GetArena() == nullptr
+#endif // !PROTOBUF_FORCE_COPY_IN_MOVE
+ ) {
+ CopyFrom(other);
+ } else {
+ InternalSwap(&other);
+ }
+ }
+ return *this;
+}
+
+template <typename Element>
+inline bool RepeatedPtrField<Element>::empty() const {
+ return RepeatedPtrFieldBase::empty();
+}
+
+template <typename Element>
+inline int RepeatedPtrField<Element>::size() const {
+ return RepeatedPtrFieldBase::size();
+}
+
+template <typename Element>
+inline const Element& RepeatedPtrField<Element>::Get(int index) const {
+ return RepeatedPtrFieldBase::Get<TypeHandler>(index);
+}
+
+template <typename Element>
+inline const Element& RepeatedPtrField<Element>::at(int index) const {
+ return RepeatedPtrFieldBase::at<TypeHandler>(index);
+}
+
+template <typename Element>
+inline Element& RepeatedPtrField<Element>::at(int index) {
+ return RepeatedPtrFieldBase::at<TypeHandler>(index);
+}
+
+
+template <typename Element>
+inline Element* RepeatedPtrField<Element>::Mutable(int index) {
+ return RepeatedPtrFieldBase::Mutable<TypeHandler>(index);
+}
+
+template <typename Element>
+inline Element* RepeatedPtrField<Element>::Add() {
+ return RepeatedPtrFieldBase::Add<TypeHandler>();
+}
+
+template <typename Element>
+inline void RepeatedPtrField<Element>::Add(Element&& value) {
+ RepeatedPtrFieldBase::Add<TypeHandler>(std::move(value));
+}
+
+template <typename Element>
+template <typename Iter>
+inline void RepeatedPtrField<Element>::Add(Iter begin, Iter end) {
+ if (std::is_base_of<
+ std::forward_iterator_tag,
+ typename std::iterator_traits<Iter>::iterator_category>::value) {
+ int reserve = std::distance(begin, end);
+ Reserve(size() + reserve);
+ }
+ for (; begin != end; ++begin) {
+ *Add() = *begin;
+ }
+}
+
+template <typename Element>
+inline void RepeatedPtrField<Element>::RemoveLast() {
+ RepeatedPtrFieldBase::RemoveLast<TypeHandler>();
+}
+
+template <typename Element>
+inline void RepeatedPtrField<Element>::DeleteSubrange(int start, int num) {
+ GOOGLE_DCHECK_GE(start, 0);
+ GOOGLE_DCHECK_GE(num, 0);
+ GOOGLE_DCHECK_LE(start + num, size());
+ for (int i = 0; i < num; ++i) {
+ RepeatedPtrFieldBase::Delete<TypeHandler>(start + i);
+ }
+ UnsafeArenaExtractSubrange(start, num, nullptr);
+}
+
+template <typename Element>
+inline void RepeatedPtrField<Element>::ExtractSubrange(int start, int num,
+ Element** elements) {
+ typename internal::TypeImplementsMergeBehavior<
+ typename TypeHandler::Type>::type t;
+ ExtractSubrangeInternal(start, num, elements, t);
+}
+
+// ExtractSubrange() implementation for types that implement merge/copy
+// behavior.
+template <typename Element>
+inline void RepeatedPtrField<Element>::ExtractSubrangeInternal(
+ int start, int num, Element** elements, std::true_type) {
+ GOOGLE_DCHECK_GE(start, 0);
+ GOOGLE_DCHECK_GE(num, 0);
+ GOOGLE_DCHECK_LE(start + num, size());
+
+ if (num == 0) return;
+
+ GOOGLE_DCHECK_NE(elements, nullptr)
+ << "Releasing elements without transferring ownership is an unsafe "
+ "operation. Use UnsafeArenaExtractSubrange.";
+ if (elements == nullptr) {
+ CloseGap(start, num);
+ return;
+ }
+
+ Arena* arena = GetArena();
+#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE
+ // Always copy.
+ for (int i = 0; i < num; ++i) {
+ elements[i] = copy<TypeHandler>(
+ RepeatedPtrFieldBase::Mutable<TypeHandler>(i + start));
+ }
+ if (arena == nullptr) {
+ for (int i = 0; i < num; ++i) {
+ delete RepeatedPtrFieldBase::Mutable<TypeHandler>(i + start);
+ }
+ }
+#else // PROTOBUF_FORCE_COPY_IN_RELEASE
+ // If we're on an arena, we perform a copy for each element so that the
+ // returned elements are heap-allocated. Otherwise, just forward it.
+ if (arena != nullptr) {
+ for (int i = 0; i < num; ++i) {
+ elements[i] = copy<TypeHandler>(
+ RepeatedPtrFieldBase::Mutable<TypeHandler>(i + start));
+ }
+ } else {
+ for (int i = 0; i < num; ++i) {
+ elements[i] = RepeatedPtrFieldBase::Mutable<TypeHandler>(i + start);
+ }
+ }
+#endif // !PROTOBUF_FORCE_COPY_IN_RELEASE
+ CloseGap(start, num);
+}
+
+// ExtractSubrange() implementation for types that do not implement merge/copy
+// behavior.
+template <typename Element>
+inline void RepeatedPtrField<Element>::ExtractSubrangeInternal(
+ int start, int num, Element** elements, std::false_type) {
+ // This case is identical to UnsafeArenaExtractSubrange(). However, since
+ // ExtractSubrange() must return heap-allocated objects by contract, and we
+ // cannot fulfill this contract if we are an on arena, we must GOOGLE_DCHECK() that
+ // we are not on an arena.
+ GOOGLE_DCHECK(GetArena() == nullptr)
+ << "ExtractSubrange() when arena is non-nullptr is only supported when "
+ << "the Element type supplies a MergeFrom() operation to make copies.";
+ UnsafeArenaExtractSubrange(start, num, elements);
+}
+
+template <typename Element>
+inline void RepeatedPtrField<Element>::UnsafeArenaExtractSubrange(
+ int start, int num, Element** elements) {
+ GOOGLE_DCHECK_GE(start, 0);
+ GOOGLE_DCHECK_GE(num, 0);
+ GOOGLE_DCHECK_LE(start + num, size());
+
+ if (num > 0) {
+ // Save the values of the removed elements if requested.
+ if (elements != nullptr) {
+ for (int i = 0; i < num; ++i) {
+ elements[i] = RepeatedPtrFieldBase::Mutable<TypeHandler>(i + start);
+ }
+ }
+ CloseGap(start, num);
+ }
+}
+
+template <typename Element>
+inline void RepeatedPtrField<Element>::Clear() {
+ RepeatedPtrFieldBase::Clear<TypeHandler>();
+}
+
+template <typename Element>
+inline void RepeatedPtrField<Element>::MergeFrom(
+ const RepeatedPtrField& other) {
+ RepeatedPtrFieldBase::MergeFrom<TypeHandler>(other);
+}
+
+template <typename Element>
+inline void RepeatedPtrField<Element>::CopyFrom(const RepeatedPtrField& other) {
+ RepeatedPtrFieldBase::CopyFrom<TypeHandler>(other);
+}
+
+template <typename Element>
+template <typename Iter>
+inline void RepeatedPtrField<Element>::Assign(Iter begin, Iter end) {
+ Clear();
+ Add(begin, end);
+}
+
+template <typename Element>
+inline typename RepeatedPtrField<Element>::iterator
+RepeatedPtrField<Element>::erase(const_iterator position) {
+ return erase(position, position + 1);
+}
+
+template <typename Element>
+inline typename RepeatedPtrField<Element>::iterator
+RepeatedPtrField<Element>::erase(const_iterator first, const_iterator last) {
+ size_type pos_offset = std::distance(cbegin(), first);
+ size_type last_offset = std::distance(cbegin(), last);
+ DeleteSubrange(pos_offset, last_offset - pos_offset);
+ return begin() + pos_offset;
+}
+
+template <typename Element>
+inline Element** RepeatedPtrField<Element>::mutable_data() {
+ return RepeatedPtrFieldBase::mutable_data<TypeHandler>();
+}
+
+template <typename Element>
+inline const Element* const* RepeatedPtrField<Element>::data() const {
+ return RepeatedPtrFieldBase::data<TypeHandler>();
+}
+
+template <typename Element>
+inline void RepeatedPtrField<Element>::Swap(RepeatedPtrField* other) {
+ if (this == other) return;
+ RepeatedPtrFieldBase::Swap<TypeHandler>(other);
+}
+
+template <typename Element>
+inline void RepeatedPtrField<Element>::UnsafeArenaSwap(
+ RepeatedPtrField* other) {
+ if (this == other) return;
+ RepeatedPtrFieldBase::InternalSwap(other);
+}
+
+template <typename Element>
+inline void RepeatedPtrField<Element>::SwapElements(int index1, int index2) {
+ RepeatedPtrFieldBase::SwapElements(index1, index2);
+}
+
+template <typename Element>
+inline Arena* RepeatedPtrField<Element>::GetArena() const {
+ return RepeatedPtrFieldBase::GetArena();
+}
+
+template <typename Element>
+inline size_t RepeatedPtrField<Element>::SpaceUsedExcludingSelfLong() const {
+ return RepeatedPtrFieldBase::SpaceUsedExcludingSelfLong<TypeHandler>();
+}
+
+template <typename Element>
+inline void RepeatedPtrField<Element>::AddAllocated(Element* value) {
+ RepeatedPtrFieldBase::AddAllocated<TypeHandler>(value);
+}
+
+template <typename Element>
+inline void RepeatedPtrField<Element>::UnsafeArenaAddAllocated(Element* value) {
+ RepeatedPtrFieldBase::UnsafeArenaAddAllocated<TypeHandler>(value);
+}
+
+template <typename Element>
+inline Element* RepeatedPtrField<Element>::ReleaseLast() {
+ return RepeatedPtrFieldBase::ReleaseLast<TypeHandler>();
+}
+
+template <typename Element>
+inline Element* RepeatedPtrField<Element>::UnsafeArenaReleaseLast() {
+ return RepeatedPtrFieldBase::UnsafeArenaReleaseLast<TypeHandler>();
+}
+
+template <typename Element>
+inline int RepeatedPtrField<Element>::ClearedCount() const {
+ return RepeatedPtrFieldBase::ClearedCount();
+}
+
+#ifndef PROTOBUF_FUTURE_BREAKING_CHANGES
+template <typename Element>
+inline void RepeatedPtrField<Element>::AddCleared(Element* value) {
+ return RepeatedPtrFieldBase::AddCleared<TypeHandler>(value);
+}
+
+template <typename Element>
+inline Element* RepeatedPtrField<Element>::ReleaseCleared() {
+ return RepeatedPtrFieldBase::ReleaseCleared<TypeHandler>();
+}
+#endif // !PROTOBUF_FUTURE_BREAKING_CHANGES
+
+template <typename Element>
+inline void RepeatedPtrField<Element>::Reserve(int new_size) {
+ return RepeatedPtrFieldBase::Reserve(new_size);
+}
+
+template <typename Element>
+inline int RepeatedPtrField<Element>::Capacity() const {
+ return RepeatedPtrFieldBase::Capacity();
+}
+
+// -------------------------------------------------------------------
+
+namespace internal {
+
+// STL-like iterator implementation for RepeatedPtrField. You should not
+// refer to this class directly; use RepeatedPtrField<T>::iterator instead.
+//
+// The iterator for RepeatedPtrField<T>, RepeatedPtrIterator<T>, is
+// very similar to iterator_ptr<T**> in util/gtl/iterator_adaptors.h,
+// but adds random-access operators and is modified to wrap a void** base
+// iterator (since RepeatedPtrField stores its array as a void* array and
+// casting void** to T** would violate C++ aliasing rules).
+//
+// This code based on net/proto/proto-array-internal.h by Jeffrey Yasskin
+// (jyasskin@google.com).
+template <typename Element>
+class RepeatedPtrIterator {
+ public:
+ using iterator = RepeatedPtrIterator<Element>;
+ using iterator_category = std::random_access_iterator_tag;
+ using value_type = typename std::remove_const<Element>::type;
+ using difference_type = std::ptrdiff_t;
+ using pointer = Element*;
+ using reference = Element&;
+
+ RepeatedPtrIterator() : it_(nullptr) {}
+ explicit RepeatedPtrIterator(void* const* it) : it_(it) {}
+
+ // Allow "upcasting" from RepeatedPtrIterator<T**> to
+ // RepeatedPtrIterator<const T*const*>.
+ template <typename OtherElement>
+ RepeatedPtrIterator(const RepeatedPtrIterator<OtherElement>& other)
+ : it_(other.it_) {
+ // Force a compiler error if the other type is not convertible to ours.
+ if (false) {
+ static_cast<void>([](OtherElement* from) -> Element* { return from; });
+ }
+ }
+
+ // dereferenceable
+ reference operator*() const { return *reinterpret_cast<Element*>(*it_); }
+ pointer operator->() const { return &(operator*()); }
+
+ // {inc,dec}rementable
+ iterator& operator++() {
+ ++it_;
+ return *this;
+ }
+ iterator operator++(int) { return iterator(it_++); }
+ iterator& operator--() {
+ --it_;
+ return *this;
+ }
+ iterator operator--(int) { return iterator(it_--); }
+
+ // equality_comparable
+ bool operator==(const iterator& x) const { return it_ == x.it_; }
+ bool operator!=(const iterator& x) const { return it_ != x.it_; }
+
+ // less_than_comparable
+ bool operator<(const iterator& x) const { return it_ < x.it_; }
+ bool operator<=(const iterator& x) const { return it_ <= x.it_; }
+ bool operator>(const iterator& x) const { return it_ > x.it_; }
+ bool operator>=(const iterator& x) const { return it_ >= x.it_; }
+
+ // addable, subtractable
+ iterator& operator+=(difference_type d) {
+ it_ += d;
+ return *this;
+ }
+ friend iterator operator+(iterator it, const difference_type d) {
+ it += d;
+ return it;
+ }
+ friend iterator operator+(const difference_type d, iterator it) {
+ it += d;
+ return it;
+ }
+ iterator& operator-=(difference_type d) {
+ it_ -= d;
+ return *this;
+ }
+ friend iterator operator-(iterator it, difference_type d) {
+ it -= d;
+ return it;
+ }
+
+ // indexable
+ reference operator[](difference_type d) const { return *(*this + d); }
+
+ // random access iterator
+ difference_type operator-(const iterator& x) const { return it_ - x.it_; }
+
+ private:
+ template <typename OtherElement>
+ friend class RepeatedPtrIterator;
+
+ // The internal iterator.
+ void* const* it_;
+};
+
+// Provide an iterator that operates on pointers to the underlying objects
+// rather than the objects themselves as RepeatedPtrIterator does.
+// Consider using this when working with stl algorithms that change
+// the array.
+// The VoidPtr template parameter holds the type-agnostic pointer value
+// referenced by the iterator. It should either be "void *" for a mutable
+// iterator, or "const void* const" for a constant iterator.
+template <typename Element, typename VoidPtr>
+class RepeatedPtrOverPtrsIterator {
+ public:
+ using iterator = RepeatedPtrOverPtrsIterator<Element, VoidPtr>;
+ using iterator_category = std::random_access_iterator_tag;
+ using value_type = typename std::remove_const<Element>::type;
+ using difference_type = std::ptrdiff_t;
+ using pointer = Element*;
+ using reference = Element&;
+
+ RepeatedPtrOverPtrsIterator() : it_(nullptr) {}
+ explicit RepeatedPtrOverPtrsIterator(VoidPtr* it) : it_(it) {}
+
+ // dereferenceable
+ reference operator*() const { return *reinterpret_cast<Element*>(it_); }
+ pointer operator->() const { return &(operator*()); }
+
+ // {inc,dec}rementable
+ iterator& operator++() {
+ ++it_;
+ return *this;
+ }
+ iterator operator++(int) { return iterator(it_++); }
+ iterator& operator--() {
+ --it_;
+ return *this;
+ }
+ iterator operator--(int) { return iterator(it_--); }
+
+ // equality_comparable
+ bool operator==(const iterator& x) const { return it_ == x.it_; }
+ bool operator!=(const iterator& x) const { return it_ != x.it_; }
+
+ // less_than_comparable
+ bool operator<(const iterator& x) const { return it_ < x.it_; }
+ bool operator<=(const iterator& x) const { return it_ <= x.it_; }
+ bool operator>(const iterator& x) const { return it_ > x.it_; }
+ bool operator>=(const iterator& x) const { return it_ >= x.it_; }
+
+ // addable, subtractable
+ iterator& operator+=(difference_type d) {
+ it_ += d;
+ return *this;
+ }
+ friend iterator operator+(iterator it, difference_type d) {
+ it += d;
+ return it;
+ }
+ friend iterator operator+(difference_type d, iterator it) {
+ it += d;
+ return it;
+ }
+ iterator& operator-=(difference_type d) {
+ it_ -= d;
+ return *this;
+ }
+ friend iterator operator-(iterator it, difference_type d) {
+ it -= d;
+ return it;
+ }
+
+ // indexable
+ reference operator[](difference_type d) const { return *(*this + d); }
+
+ // random access iterator
+ difference_type operator-(const iterator& x) const { return it_ - x.it_; }
+
+ private:
+ template <typename OtherElement>
+ friend class RepeatedPtrIterator;
+
+ // The internal iterator.
+ VoidPtr* it_;
+};
+
+void RepeatedPtrFieldBase::InternalSwap(RepeatedPtrFieldBase* rhs) {
+ GOOGLE_DCHECK(this != rhs);
+
+ // Swap all fields at once.
+ auto temp = std::make_tuple(rhs->arena_, rhs->current_size_, rhs->total_size_,
+ rhs->rep_);
+ std::tie(rhs->arena_, rhs->current_size_, rhs->total_size_, rhs->rep_) =
+ std::make_tuple(arena_, current_size_, total_size_, rep_);
+ std::tie(arena_, current_size_, total_size_, rep_) = temp;
+}
+
+} // namespace internal
+
+template <typename Element>
+inline typename RepeatedPtrField<Element>::iterator
+RepeatedPtrField<Element>::begin() {
+ return iterator(raw_data());
+}
+template <typename Element>
+inline typename RepeatedPtrField<Element>::const_iterator
+RepeatedPtrField<Element>::begin() const {
+ return iterator(raw_data());
+}
+template <typename Element>
+inline typename RepeatedPtrField<Element>::const_iterator
+RepeatedPtrField<Element>::cbegin() const {
+ return begin();
+}
+template <typename Element>
+inline typename RepeatedPtrField<Element>::iterator
+RepeatedPtrField<Element>::end() {
+ return iterator(raw_data() + size());
+}
+template <typename Element>
+inline typename RepeatedPtrField<Element>::const_iterator
+RepeatedPtrField<Element>::end() const {
+ return iterator(raw_data() + size());
+}
+template <typename Element>
+inline typename RepeatedPtrField<Element>::const_iterator
+RepeatedPtrField<Element>::cend() const {
+ return end();
+}
+
+template <typename Element>
+inline typename RepeatedPtrField<Element>::pointer_iterator
+RepeatedPtrField<Element>::pointer_begin() {
+ return pointer_iterator(raw_mutable_data());
+}
+template <typename Element>
+inline typename RepeatedPtrField<Element>::const_pointer_iterator
+RepeatedPtrField<Element>::pointer_begin() const {
+ return const_pointer_iterator(const_cast<const void* const*>(raw_data()));
+}
+template <typename Element>
+inline typename RepeatedPtrField<Element>::pointer_iterator
+RepeatedPtrField<Element>::pointer_end() {
+ return pointer_iterator(raw_mutable_data() + size());
+}
+template <typename Element>
+inline typename RepeatedPtrField<Element>::const_pointer_iterator
+RepeatedPtrField<Element>::pointer_end() const {
+ return const_pointer_iterator(
+ const_cast<const void* const*>(raw_data() + size()));
+}
+
+// Iterators and helper functions that follow the spirit of the STL
+// std::back_insert_iterator and std::back_inserter but are tailor-made
+// for RepeatedField and RepeatedPtrField. Typical usage would be:
+//
+// std::copy(some_sequence.begin(), some_sequence.end(),
+// RepeatedFieldBackInserter(proto.mutable_sequence()));
+//
+// Ported by johannes from util/gtl/proto-array-iterators.h
+
+namespace internal {
+
+// A back inserter for RepeatedPtrField objects.
+template <typename T>
+class RepeatedPtrFieldBackInsertIterator {
+ public:
+ using iterator_category = std::output_iterator_tag;
+ using value_type = T;
+ using pointer = void;
+ using reference = void;
+ using difference_type = std::ptrdiff_t;
+
+ RepeatedPtrFieldBackInsertIterator(RepeatedPtrField<T>* const mutable_field)
+ : field_(mutable_field) {}
+ RepeatedPtrFieldBackInsertIterator<T>& operator=(const T& value) {
+ *field_->Add() = value;
+ return *this;
+ }
+ RepeatedPtrFieldBackInsertIterator<T>& operator=(
+ const T* const ptr_to_value) {
+ *field_->Add() = *ptr_to_value;
+ return *this;
+ }
+ RepeatedPtrFieldBackInsertIterator<T>& operator=(T&& value) {
+ *field_->Add() = std::move(value);
+ return *this;
+ }
+ RepeatedPtrFieldBackInsertIterator<T>& operator*() { return *this; }
+ RepeatedPtrFieldBackInsertIterator<T>& operator++() { return *this; }
+ RepeatedPtrFieldBackInsertIterator<T>& operator++(int /* unused */) {
+ return *this;
+ }
+
+ private:
+ RepeatedPtrField<T>* field_;
+};
+
+// A back inserter for RepeatedPtrFields that inserts by transferring ownership
+// of a pointer.
+template <typename T>
+class AllocatedRepeatedPtrFieldBackInsertIterator {
+ public:
+ using iterator_category = std::output_iterator_tag;
+ using value_type = T;
+ using pointer = void;
+ using reference = void;
+ using difference_type = std::ptrdiff_t;
+
+ explicit AllocatedRepeatedPtrFieldBackInsertIterator(
+ RepeatedPtrField<T>* const mutable_field)
+ : field_(mutable_field) {}
+ AllocatedRepeatedPtrFieldBackInsertIterator<T>& operator=(
+ T* const ptr_to_value) {
+ field_->AddAllocated(ptr_to_value);
+ return *this;
+ }
+ AllocatedRepeatedPtrFieldBackInsertIterator<T>& operator*() { return *this; }
+ AllocatedRepeatedPtrFieldBackInsertIterator<T>& operator++() { return *this; }
+ AllocatedRepeatedPtrFieldBackInsertIterator<T>& operator++(int /* unused */) {
+ return *this;
+ }
+
+ private:
+ RepeatedPtrField<T>* field_;
+};
+
+// Almost identical to AllocatedRepeatedPtrFieldBackInsertIterator. This one
+// uses the UnsafeArenaAddAllocated instead.
+template <typename T>
+class UnsafeArenaAllocatedRepeatedPtrFieldBackInsertIterator {
+ public:
+ using iterator_category = std::output_iterator_tag;
+ using value_type = T;
+ using pointer = void;
+ using reference = void;
+ using difference_type = std::ptrdiff_t;
+
+ explicit UnsafeArenaAllocatedRepeatedPtrFieldBackInsertIterator(
+ RepeatedPtrField<T>* const mutable_field)
+ : field_(mutable_field) {}
+ UnsafeArenaAllocatedRepeatedPtrFieldBackInsertIterator<T>& operator=(
+ T const* const ptr_to_value) {
+ field_->UnsafeArenaAddAllocated(const_cast<T*>(ptr_to_value));
+ return *this;
+ }
+ UnsafeArenaAllocatedRepeatedPtrFieldBackInsertIterator<T>& operator*() {
+ return *this;
+ }
+ UnsafeArenaAllocatedRepeatedPtrFieldBackInsertIterator<T>& operator++() {
+ return *this;
+ }
+ UnsafeArenaAllocatedRepeatedPtrFieldBackInsertIterator<T>& operator++(
+ int /* unused */) {
+ return *this;
+ }
+
+ private:
+ RepeatedPtrField<T>* field_;
+};
+
+} // namespace internal
+
+// Provides a back insert iterator for RepeatedPtrField instances,
+// similar to std::back_inserter().
+template <typename T>
+internal::RepeatedPtrFieldBackInsertIterator<T> RepeatedPtrFieldBackInserter(
+ RepeatedPtrField<T>* const mutable_field) {
+ return internal::RepeatedPtrFieldBackInsertIterator<T>(mutable_field);
+}
+
+// Special back insert iterator for RepeatedPtrField instances, just in
+// case someone wants to write generic template code that can access both
+// RepeatedFields and RepeatedPtrFields using a common name.
+template <typename T>
+internal::RepeatedPtrFieldBackInsertIterator<T> RepeatedFieldBackInserter(
+ RepeatedPtrField<T>* const mutable_field) {
+ return internal::RepeatedPtrFieldBackInsertIterator<T>(mutable_field);
+}
+
+// Provides a back insert iterator for RepeatedPtrField instances
+// similar to std::back_inserter() which transfers the ownership while
+// copying elements.
+template <typename T>
+internal::AllocatedRepeatedPtrFieldBackInsertIterator<T>
+AllocatedRepeatedPtrFieldBackInserter(
+ RepeatedPtrField<T>* const mutable_field) {
+ return internal::AllocatedRepeatedPtrFieldBackInsertIterator<T>(
+ mutable_field);
+}
+
+// Similar to AllocatedRepeatedPtrFieldBackInserter, using
+// UnsafeArenaAddAllocated instead of AddAllocated.
+// This is slightly faster if that matters. It is also useful in legacy code
+// that uses temporary ownership to avoid copies. Example:
+// RepeatedPtrField<T> temp_field;
+// temp_field.UnsafeArenaAddAllocated(new T);
+// ... // Do something with temp_field
+// temp_field.UnsafeArenaExtractSubrange(0, temp_field.size(), nullptr);
+// If you put temp_field on the arena this fails, because the ownership
+// transfers to the arena at the "AddAllocated" call and is not released anymore
+// causing a double delete. Using UnsafeArenaAddAllocated prevents this.
+template <typename T>
+internal::UnsafeArenaAllocatedRepeatedPtrFieldBackInsertIterator<T>
+UnsafeArenaAllocatedRepeatedPtrFieldBackInserter(
+ RepeatedPtrField<T>* const mutable_field) {
+ return internal::UnsafeArenaAllocatedRepeatedPtrFieldBackInsertIterator<T>(
+ mutable_field);
+}
+
+extern template class PROTOBUF_EXPORT_TEMPLATE_DECLARE
+ RepeatedPtrField<std::string>;
+
+} // namespace protobuf
+} // namespace google
+
+#include <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_REPEATED_PTR_FIELD_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/service.cc b/NorthstarDedicatedTest/include/protobuf/service.cc
new file mode 100644
index 00000000..2fe1c6f6
--- /dev/null
+++ b/NorthstarDedicatedTest/include/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 <service.h>
+
+namespace google {
+namespace protobuf {
+
+Service::~Service() {}
+RpcChannel::~RpcChannel() {}
+RpcController::~RpcController() {}
+
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/service.h b/NorthstarDedicatedTest/include/protobuf/service.h
new file mode 100644
index 00000000..743b5318
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/service.h
@@ -0,0 +1,293 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// DEPRECATED: This module declares the abstract interfaces underlying proto2
+// RPC services. These are intended to be independent of any particular RPC
+// implementation, so that proto2 services can be used on top of a variety
+// of implementations. Starting with version 2.3.0, RPC implementations should
+// not try to build on these, but should instead provide code generator plugins
+// which generate code specific to the particular RPC implementation. This way
+// the generated code can be more appropriate for the implementation in use
+// and can avoid unnecessary layers of indirection.
+//
+//
+// When you use the protocol compiler to compile a service definition, it
+// generates two classes: An abstract interface for the service (with
+// methods matching the service definition) and a "stub" implementation.
+// A stub is just a type-safe wrapper around an RpcChannel which emulates a
+// local implementation of the service.
+//
+// For example, the service definition:
+// service MyService {
+// rpc Foo(MyRequest) returns(MyResponse);
+// }
+// will generate abstract interface "MyService" and class "MyService::Stub".
+// You could implement a MyService as follows:
+// class MyServiceImpl : public MyService {
+// public:
+// MyServiceImpl() {}
+// ~MyServiceImpl() {}
+//
+// // implements MyService ---------------------------------------
+//
+// void Foo(google::protobuf::RpcController* controller,
+// const MyRequest* request,
+// MyResponse* response,
+// Closure* done) {
+// // ... read request and fill in response ...
+// done->Run();
+// }
+// };
+// You would then register an instance of MyServiceImpl with your RPC server
+// implementation. (How to do that depends on the implementation.)
+//
+// To call a remote MyServiceImpl, first you need an RpcChannel connected to it.
+// How to construct a channel depends, again, on your RPC implementation.
+// Here we use a hypothetical "MyRpcChannel" as an example:
+// MyRpcChannel channel("rpc:hostname:1234/myservice");
+// MyRpcController controller;
+// MyServiceImpl::Stub stub(&channel);
+// FooRequest request;
+// FooResponse response;
+//
+// // ... fill in request ...
+//
+// stub.Foo(&controller, request, &response, NewCallback(HandleResponse));
+//
+// On Thread-Safety:
+//
+// Different RPC implementations may make different guarantees about what
+// threads they may run callbacks on, and what threads the application is
+// allowed to use to call the RPC system. Portable software should be ready
+// for callbacks to be called on any thread, but should not try to call the
+// RPC system from any thread except for the ones on which it received the
+// callbacks. Realistically, though, simple software will probably want to
+// use a single-threaded RPC system while high-end software will want to
+// use multiple threads. RPC implementations should provide multiple
+// choices.
+
+#ifndef GOOGLE_PROTOBUF_SERVICE_H__
+#define GOOGLE_PROTOBUF_SERVICE_H__
+
+#include <string>
+#include <stubs/callback.h>
+#include <stubs/common.h>
+
+#ifdef SWIG
+#error "You cannot SWIG proto headers"
+#endif
+
+#include <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 <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_SERVICE_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/source_context.pb.cc b/NorthstarDedicatedTest/include/protobuf/source_context.pb.cc
new file mode 100644
index 00000000..f08dcf83
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/source_context.pb.cc
@@ -0,0 +1,289 @@
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+// source: google/protobuf/source_context.proto
+
+#include <source_context.pb.h>
+
+#include <algorithm>
+
+#include <io/coded_stream.h>
+#include <extension_set.h>
+#include <wire_format_lite.h>
+#include <descriptor.h>
+#include <generated_message_reflection.h>
+#include <reflection_ops.h>
+#include <wire_format.h>
+// @@protoc_insertion_point(includes)
+#include <port_def.inc>
+
+PROTOBUF_PRAGMA_INIT_SEG
+PROTOBUF_NAMESPACE_OPEN
+constexpr SourceContext::SourceContext(
+ ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized)
+ : file_name_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string){}
+struct SourceContextDefaultTypeInternal {
+ constexpr SourceContextDefaultTypeInternal()
+ : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {}
+ ~SourceContextDefaultTypeInternal() {}
+ union {
+ SourceContext _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT SourceContextDefaultTypeInternal _SourceContext_default_instance_;
+PROTOBUF_NAMESPACE_CLOSE
+static ::PROTOBUF_NAMESPACE_ID::Metadata file_level_metadata_google_2fprotobuf_2fsource_5fcontext_2eproto[1];
+static constexpr ::PROTOBUF_NAMESPACE_ID::EnumDescriptor const** file_level_enum_descriptors_google_2fprotobuf_2fsource_5fcontext_2eproto = nullptr;
+static constexpr ::PROTOBUF_NAMESPACE_ID::ServiceDescriptor const** file_level_service_descriptors_google_2fprotobuf_2fsource_5fcontext_2eproto = nullptr;
+
+const 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, file_name_),
+};
+static const ::PROTOBUF_NAMESPACE_ID::internal::MigrationSchema schemas[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = {
+ { 0, -1, -1, sizeof(::PROTOBUF_NAMESPACE_ID::SourceContext)},
+};
+
+static ::PROTOBUF_NAMESPACE_ID::Message const * const file_default_instances[] = {
+ reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_SourceContext_default_instance_),
+};
+
+const char descriptor_table_protodef_google_2fprotobuf_2fsource_5fcontext_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) =
+ "\n$google/protobuf/source_context.proto\022\017"
+ "google.protobuf\"\"\n\rSourceContext\022\021\n\tfile"
+ "_name\030\001 \001(\tB\212\001\n\023com.google.protobufB\022Sou"
+ "rceContextProtoP\001Z6google.golang.org/pro"
+ "tobuf/types/known/sourcecontextpb\242\002\003GPB\252"
+ "\002\036Google.Protobuf.WellKnownTypesb\006proto3"
+ ;
+static ::PROTOBUF_NAMESPACE_ID::internal::once_flag descriptor_table_google_2fprotobuf_2fsource_5fcontext_2eproto_once;
+const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fsource_5fcontext_2eproto = {
+ false, false, 240, descriptor_table_protodef_google_2fprotobuf_2fsource_5fcontext_2eproto, "google/protobuf/source_context.proto",
+ &descriptor_table_google_2fprotobuf_2fsource_5fcontext_2eproto_once, nullptr, 0, 1,
+ schemas, file_default_instances, TableStruct_google_2fprotobuf_2fsource_5fcontext_2eproto::offsets,
+ file_level_metadata_google_2fprotobuf_2fsource_5fcontext_2eproto, file_level_enum_descriptors_google_2fprotobuf_2fsource_5fcontext_2eproto, file_level_service_descriptors_google_2fprotobuf_2fsource_5fcontext_2eproto,
+};
+PROTOBUF_ATTRIBUTE_WEAK const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable* descriptor_table_google_2fprotobuf_2fsource_5fcontext_2eproto_getter() {
+ return &descriptor_table_google_2fprotobuf_2fsource_5fcontext_2eproto;
+}
+
+// Force running AddDescriptors() at dynamic initialization time.
+PROTOBUF_ATTRIBUTE_INIT_PRIORITY static ::PROTOBUF_NAMESPACE_ID::internal::AddDescriptorsRunner dynamic_init_dummy_google_2fprotobuf_2fsource_5fcontext_2eproto(&descriptor_table_google_2fprotobuf_2fsource_5fcontext_2eproto);
+PROTOBUF_NAMESPACE_OPEN
+
+// ===================================================================
+
+class SourceContext::_Internal {
+ public:
+};
+
+SourceContext::SourceContext(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned)
+ : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) {
+ SharedCtor();
+ if (!is_message_owned) {
+ RegisterArenaDtor(arena);
+ }
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.SourceContext)
+}
+SourceContext::SourceContext(const SourceContext& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message() {
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ file_name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ file_name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (!from._internal_file_name().empty()) {
+ file_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_file_name(),
+ GetArenaForAllocation());
+ }
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.SourceContext)
+}
+
+inline void SourceContext::SharedCtor() {
+file_name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ file_name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+}
+
+SourceContext::~SourceContext() {
+ // @@protoc_insertion_point(destructor:google.protobuf.SourceContext)
+ if (GetArenaForAllocation() != nullptr) return;
+ SharedDtor();
+ _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+inline void SourceContext::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+ file_name_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+}
+
+void SourceContext::ArenaDtor(void* object) {
+ SourceContext* _this = reinterpret_cast< SourceContext* >(object);
+ (void)_this;
+}
+void SourceContext::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) {
+}
+void SourceContext::SetCachedSize(int size) const {
+ _cached_size_.Set(size);
+}
+
+void SourceContext::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.SourceContext)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ file_name_.ClearToEmpty();
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* SourceContext::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag);
+ switch (tag >> 3) {
+ // string file_name = 1;
+ case 1:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 10)) {
+ auto str = _internal_mutable_file_name();
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx);
+ CHK_(::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.SourceContext.file_name"));
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ default:
+ goto handle_unusual;
+ } // switch
+ handle_unusual:
+ if ((tag == 0) || ((tag & 7) == 4)) {
+ CHK_(ptr);
+ ctx->SetLastTag(tag);
+ goto message_done;
+ }
+ ptr = UnknownFieldParse(
+ tag,
+ _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(),
+ ptr, ctx);
+ CHK_(ptr != nullptr);
+ } // while
+message_done:
+ return ptr;
+failure:
+ ptr = nullptr;
+ goto message_done;
+#undef CHK_
+}
+
+uint8_t* SourceContext::_InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const {
+ // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.SourceContext)
+ 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 = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray(
+ _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.SourceContext)
+ return target;
+}
+
+size_t SourceContext::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.SourceContext)
+ size_t total_size = 0;
+
+ 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, &_cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData SourceContext::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck,
+ SourceContext::MergeImpl
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*SourceContext::GetClassData() const { return &_class_data_; }
+
+void SourceContext::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to,
+ const ::PROTOBUF_NAMESPACE_ID::Message& from) {
+ static_cast<SourceContext *>(to)->MergeFrom(
+ static_cast<const SourceContext &>(from));
+}
+
+
+void SourceContext::MergeFrom(const SourceContext& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.SourceContext)
+ GOOGLE_DCHECK_NE(&from, this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ if (!from._internal_file_name().empty()) {
+ _internal_set_file_name(from._internal_file_name());
+ }
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+}
+
+void SourceContext::CopyFrom(const SourceContext& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.SourceContext)
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+bool SourceContext::IsInitialized() const {
+ return true;
+}
+
+void SourceContext::InternalSwap(SourceContext* other) {
+ using std::swap;
+ auto* lhs_arena = GetArenaForAllocation();
+ auto* rhs_arena = other->GetArenaForAllocation();
+ _internal_metadata_.InternalSwap(&other->_internal_metadata_);
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(),
+ &file_name_, lhs_arena,
+ &other->file_name_, rhs_arena
+ );
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata SourceContext::GetMetadata() const {
+ return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(
+ &descriptor_table_google_2fprotobuf_2fsource_5fcontext_2eproto_getter, &descriptor_table_google_2fprotobuf_2fsource_5fcontext_2eproto_once,
+ file_level_metadata_google_2fprotobuf_2fsource_5fcontext_2eproto[0]);
+}
+
+// @@protoc_insertion_point(namespace_scope)
+PROTOBUF_NAMESPACE_CLOSE
+PROTOBUF_NAMESPACE_OPEN
+template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::SourceContext* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::SourceContext >(Arena* arena) {
+ return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::SourceContext >(arena);
+}
+PROTOBUF_NAMESPACE_CLOSE
+
+// @@protoc_insertion_point(global_scope)
+#include <port_undef.inc>
diff --git a/NorthstarDedicatedTest/include/protobuf/source_context.pb.h b/NorthstarDedicatedTest/include/protobuf/source_context.pb.h
new file mode 100644
index 00000000..374e61ad
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/source_context.pb.h
@@ -0,0 +1,290 @@
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+// source: google/protobuf/source_context.proto
+
+#ifndef GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fsource_5fcontext_2eproto
+#define GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fsource_5fcontext_2eproto
+
+#include <limits>
+#include <string>
+
+#include <port_def.inc>
+#if PROTOBUF_VERSION < 3019000
+#error This file was generated by a newer version of protoc which is
+#error incompatible with your Protocol Buffer headers. Please update
+#error your headers.
+#endif
+#if 3019004 < 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 <port_undef.inc>
+#include <io/coded_stream.h>
+#include <arena.h>
+#include <arenastring.h>
+#include <generated_message_table_driven.h>
+#include <generated_message_util.h>
+#include <metadata_lite.h>
+#include <generated_message_reflection.h>
+#include <message.h>
+#include <repeated_field.h> // IWYU pragma: export
+#include <extension_set.h> // IWYU pragma: export
+#include <unknown_field_set.h>
+// @@protoc_insertion_point(includes)
+#include <port_def.inc>
+#define PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fsource_5fcontext_2eproto PROTOBUF_EXPORT
+PROTOBUF_NAMESPACE_OPEN
+namespace internal {
+class AnyMetadata;
+} // namespace internal
+PROTOBUF_NAMESPACE_CLOSE
+
+// Internal implementation detail -- do not use these members.
+struct PROTOBUF_EXPORT TableStruct_google_2fprotobuf_2fsource_5fcontext_2eproto {
+ static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTableField entries[]
+ PROTOBUF_SECTION_VARIABLE(protodesc_cold);
+ static const ::PROTOBUF_NAMESPACE_ID::internal::AuxiliaryParseTableField aux[]
+ PROTOBUF_SECTION_VARIABLE(protodesc_cold);
+ static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTable schema[1]
+ PROTOBUF_SECTION_VARIABLE(protodesc_cold);
+ static const ::PROTOBUF_NAMESPACE_ID::internal::FieldMetadata field_metadata[];
+ static const ::PROTOBUF_NAMESPACE_ID::internal::SerializationTable serialization_table[];
+ static const 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 constexpr SourceContext(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
+
+ SourceContext(const SourceContext& from);
+ SourceContext(SourceContext&& from) noexcept
+ : SourceContext() {
+ *this = ::std::move(from);
+ }
+
+ inline SourceContext& operator=(const SourceContext& from) {
+ CopyFrom(from);
+ return *this;
+ }
+ inline SourceContext& operator=(SourceContext&& from) noexcept {
+ if (this == &from) return *this;
+ if (GetOwningArena() == from.GetOwningArena()
+ #ifdef PROTOBUF_FORCE_COPY_IN_MOVE
+ && GetOwningArena() != nullptr
+ #endif // !PROTOBUF_FORCE_COPY_IN_MOVE
+ ) {
+ InternalSwap(&from);
+ } else {
+ CopyFrom(from);
+ }
+ return *this;
+ }
+
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
+ return GetDescriptor();
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
+ return default_instance().GetMetadata().descriptor;
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
+ return default_instance().GetMetadata().reflection;
+ }
+ static const SourceContext& default_instance() {
+ return *internal_default_instance();
+ }
+ static inline const SourceContext* internal_default_instance() {
+ return reinterpret_cast<const SourceContext*>(
+ &_SourceContext_default_instance_);
+ }
+ static constexpr int kIndexInFileMessages =
+ 0;
+
+ friend void swap(SourceContext& a, SourceContext& b) {
+ a.Swap(&b);
+ }
+ inline void Swap(SourceContext* other) {
+ if (other == this) return;
+ #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() != nullptr &&
+ GetOwningArena() == other->GetOwningArena()) {
+ #else // PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() == other->GetOwningArena()) {
+ #endif // !PROTOBUF_FORCE_COPY_IN_SWAP
+ InternalSwap(other);
+ } else {
+ ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
+ }
+ }
+ void UnsafeArenaSwap(SourceContext* other) {
+ if (other == this) return;
+ GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena());
+ InternalSwap(other);
+ }
+
+ // implements Message ----------------------------------------------
+
+ SourceContext* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
+ return CreateMaybeMessage<SourceContext>(arena);
+ }
+ using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
+ void CopyFrom(const SourceContext& from);
+ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
+ void MergeFrom(const SourceContext& from);
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from);
+ public:
+ PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+ bool IsInitialized() const final;
+
+ size_t ByteSizeLong() const final;
+ const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
+ uint8_t* _InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
+ int GetCachedSize() const final { return _cached_size_.Get(); }
+
+ private:
+ void SharedCtor();
+ void SharedDtor();
+ void SetCachedSize(int size) const final;
+ void InternalSwap(SourceContext* other);
+
+ private:
+ friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
+ static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
+ return "google.protobuf.SourceContext";
+ }
+ protected:
+ explicit SourceContext(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned = false);
+ private:
+ static void ArenaDtor(void* object);
+ inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
+ public:
+
+ static const ClassData _class_data_;
+ const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;
+
+ ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;
+
+ // nested types ----------------------------------------------------
+
+ // accessors -------------------------------------------------------
+
+ enum : int {
+ kFileNameFieldNumber = 1,
+ };
+ // string file_name = 1;
+ void clear_file_name();
+ const 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_;
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr file_name_;
+ mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
+ friend struct ::TableStruct_google_2fprotobuf_2fsource_5fcontext_2eproto;
+};
+// ===================================================================
+
+
+// ===================================================================
+
+#ifdef __GNUC__
+ #pragma GCC diagnostic push
+ #pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#endif // __GNUC__
+// SourceContext
+
+// string file_name = 1;
+inline void SourceContext::clear_file_name() {
+ file_name_.ClearToEmpty();
+}
+inline const 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) {
+
+ file_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
+ // @@protoc_insertion_point(field_set:google.protobuf.SourceContext.file_name)
+}
+inline 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 file_name_.Get();
+}
+inline void SourceContext::_internal_set_file_name(const std::string& value) {
+
+ file_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation());
+}
+inline std::string* SourceContext::_internal_mutable_file_name() {
+
+ return file_name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation());
+}
+inline std::string* SourceContext::release_file_name() {
+ // @@protoc_insertion_point(field_release:google.protobuf.SourceContext.file_name)
+ return file_name_.Release(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
+}
+inline void SourceContext::set_allocated_file_name(std::string* file_name) {
+ if (file_name != nullptr) {
+
+ } else {
+
+ }
+ file_name_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), file_name,
+ GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (file_name_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
+ file_name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.SourceContext.file_name)
+}
+
+#ifdef __GNUC__
+ #pragma GCC diagnostic pop
+#endif // __GNUC__
+
+// @@protoc_insertion_point(namespace_scope)
+
+PROTOBUF_NAMESPACE_CLOSE
+
+// @@protoc_insertion_point(global_scope)
+
+#include <port_undef.inc>
+#endif // GOOGLE_PROTOBUF_INCLUDED_GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fsource_5fcontext_2eproto
diff --git a/NorthstarDedicatedTest/include/protobuf/source_context.proto b/NorthstarDedicatedTest/include/protobuf/source_context.proto
new file mode 100644
index 00000000..06bfc43a
--- /dev/null
+++ b/NorthstarDedicatedTest/include/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/NorthstarDedicatedTest/include/protobuf/string_member_robber.h b/NorthstarDedicatedTest/include/protobuf/string_member_robber.h
new file mode 100644
index 00000000..a4c1051e
--- /dev/null
+++ b/NorthstarDedicatedTest/include/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/NorthstarDedicatedTest/include/protobuf/struct.pb.cc b/NorthstarDedicatedTest/include/protobuf/struct.pb.cc
new file mode 100644
index 00000000..3254402e
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/struct.pb.cc
@@ -0,0 +1,1048 @@
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+// source: google/protobuf/struct.proto
+
+#include <struct.pb.h>
+
+#include <algorithm>
+
+#include <io/coded_stream.h>
+#include <extension_set.h>
+#include <wire_format_lite.h>
+#include <descriptor.h>
+#include <generated_message_reflection.h>
+#include <reflection_ops.h>
+#include <wire_format.h>
+// @@protoc_insertion_point(includes)
+#include <port_def.inc>
+
+PROTOBUF_PRAGMA_INIT_SEG
+PROTOBUF_NAMESPACE_OPEN
+constexpr Struct_FieldsEntry_DoNotUse::Struct_FieldsEntry_DoNotUse(
+ ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized){}
+struct Struct_FieldsEntry_DoNotUseDefaultTypeInternal {
+ constexpr Struct_FieldsEntry_DoNotUseDefaultTypeInternal()
+ : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {}
+ ~Struct_FieldsEntry_DoNotUseDefaultTypeInternal() {}
+ union {
+ Struct_FieldsEntry_DoNotUse _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT Struct_FieldsEntry_DoNotUseDefaultTypeInternal _Struct_FieldsEntry_DoNotUse_default_instance_;
+constexpr Struct::Struct(
+ ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized)
+ : fields_(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}){}
+struct StructDefaultTypeInternal {
+ constexpr StructDefaultTypeInternal()
+ : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {}
+ ~StructDefaultTypeInternal() {}
+ union {
+ Struct _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT StructDefaultTypeInternal _Struct_default_instance_;
+constexpr Value::Value(
+ ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized)
+ : _oneof_case_{}{}
+struct ValueDefaultTypeInternal {
+ constexpr ValueDefaultTypeInternal()
+ : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {}
+ ~ValueDefaultTypeInternal() {}
+ union {
+ Value _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT ValueDefaultTypeInternal _Value_default_instance_;
+constexpr ListValue::ListValue(
+ ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized)
+ : values_(){}
+struct ListValueDefaultTypeInternal {
+ constexpr ListValueDefaultTypeInternal()
+ : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {}
+ ~ListValueDefaultTypeInternal() {}
+ union {
+ ListValue _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT ListValueDefaultTypeInternal _ListValue_default_instance_;
+PROTOBUF_NAMESPACE_CLOSE
+static ::PROTOBUF_NAMESPACE_ID::Metadata file_level_metadata_google_2fprotobuf_2fstruct_2eproto[4];
+static const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* file_level_enum_descriptors_google_2fprotobuf_2fstruct_2eproto[1];
+static constexpr ::PROTOBUF_NAMESPACE_ID::ServiceDescriptor const** file_level_service_descriptors_google_2fprotobuf_2fstruct_2eproto = nullptr;
+
+const 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, fields_),
+ ~0u, // no _has_bits_
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Value, _internal_metadata_),
+ ~0u, // no _extensions_
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Value, _oneof_case_[0]),
+ ~0u, // no _weak_field_map_
+ ~0u, // no _inlined_string_donated_
+ ::PROTOBUF_NAMESPACE_ID::internal::kInvalidFieldOffsetTag,
+ ::PROTOBUF_NAMESPACE_ID::internal::kInvalidFieldOffsetTag,
+ ::PROTOBUF_NAMESPACE_ID::internal::kInvalidFieldOffsetTag,
+ ::PROTOBUF_NAMESPACE_ID::internal::kInvalidFieldOffsetTag,
+ ::PROTOBUF_NAMESPACE_ID::internal::kInvalidFieldOffsetTag,
+ ::PROTOBUF_NAMESPACE_ID::internal::kInvalidFieldOffsetTag,
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Value, kind_),
+ ~0u, // no _has_bits_
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::ListValue, _internal_metadata_),
+ ~0u, // no _extensions_
+ ~0u, // no _oneof_case_
+ ~0u, // no _weak_field_map_
+ ~0u, // no _inlined_string_donated_
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::ListValue, values_),
+};
+static const ::PROTOBUF_NAMESPACE_ID::internal::MigrationSchema schemas[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = {
+ { 0, 8, -1, sizeof(::PROTOBUF_NAMESPACE_ID::Struct_FieldsEntry_DoNotUse)},
+ { 10, -1, -1, sizeof(::PROTOBUF_NAMESPACE_ID::Struct)},
+ { 17, -1, -1, sizeof(::PROTOBUF_NAMESPACE_ID::Value)},
+ { 30, -1, -1, sizeof(::PROTOBUF_NAMESPACE_ID::ListValue)},
+};
+
+static ::PROTOBUF_NAMESPACE_ID::Message const * const file_default_instances[] = {
+ reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_Struct_FieldsEntry_DoNotUse_default_instance_),
+ reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_Struct_default_instance_),
+ reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_Value_default_instance_),
+ reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_ListValue_default_instance_),
+};
+
+const char descriptor_table_protodef_google_2fprotobuf_2fstruct_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) =
+ "\n\034google/protobuf/struct.proto\022\017google.p"
+ "rotobuf\"\204\001\n\006Struct\0223\n\006fields\030\001 \003(\0132#.goo"
+ "gle.protobuf.Struct.FieldsEntry\032E\n\013Field"
+ "sEntry\022\013\n\003key\030\001 \001(\t\022%\n\005value\030\002 \001(\0132\026.goo"
+ "gle.protobuf.Value:\0028\001\"\352\001\n\005Value\0220\n\nnull"
+ "_value\030\001 \001(\0162\032.google.protobuf.NullValue"
+ "H\000\022\026\n\014number_value\030\002 \001(\001H\000\022\026\n\014string_val"
+ "ue\030\003 \001(\tH\000\022\024\n\nbool_value\030\004 \001(\010H\000\022/\n\014stru"
+ "ct_value\030\005 \001(\0132\027.google.protobuf.StructH"
+ "\000\0220\n\nlist_value\030\006 \001(\0132\032.google.protobuf."
+ "ListValueH\000B\006\n\004kind\"3\n\tListValue\022&\n\006valu"
+ "es\030\001 \003(\0132\026.google.protobuf.Value*\033\n\tNull"
+ "Value\022\016\n\nNULL_VALUE\020\000B\177\n\023com.google.prot"
+ "obufB\013StructProtoP\001Z/google.golang.org/p"
+ "rotobuf/types/known/structpb\370\001\001\242\002\003GPB\252\002\036"
+ "Google.Protobuf.WellKnownTypesb\006proto3"
+ ;
+static ::PROTOBUF_NAMESPACE_ID::internal::once_flag descriptor_table_google_2fprotobuf_2fstruct_2eproto_once;
+const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fstruct_2eproto = {
+ false, false, 638, descriptor_table_protodef_google_2fprotobuf_2fstruct_2eproto, "google/protobuf/struct.proto",
+ &descriptor_table_google_2fprotobuf_2fstruct_2eproto_once, nullptr, 0, 4,
+ schemas, file_default_instances, TableStruct_google_2fprotobuf_2fstruct_2eproto::offsets,
+ file_level_metadata_google_2fprotobuf_2fstruct_2eproto, file_level_enum_descriptors_google_2fprotobuf_2fstruct_2eproto, file_level_service_descriptors_google_2fprotobuf_2fstruct_2eproto,
+};
+PROTOBUF_ATTRIBUTE_WEAK const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable* descriptor_table_google_2fprotobuf_2fstruct_2eproto_getter() {
+ return &descriptor_table_google_2fprotobuf_2fstruct_2eproto;
+}
+
+// Force running AddDescriptors() at dynamic initialization time.
+PROTOBUF_ATTRIBUTE_INIT_PRIORITY static ::PROTOBUF_NAMESPACE_ID::internal::AddDescriptorsRunner dynamic_init_dummy_google_2fprotobuf_2fstruct_2eproto(&descriptor_table_google_2fprotobuf_2fstruct_2eproto);
+PROTOBUF_NAMESPACE_OPEN
+const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* NullValue_descriptor() {
+ ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fstruct_2eproto);
+ return file_level_enum_descriptors_google_2fprotobuf_2fstruct_2eproto[0];
+}
+bool NullValue_IsValid(int value) {
+ switch (value) {
+ case 0:
+ return true;
+ default:
+ return false;
+ }
+}
+
+
+// ===================================================================
+
+Struct_FieldsEntry_DoNotUse::Struct_FieldsEntry_DoNotUse() {}
+Struct_FieldsEntry_DoNotUse::Struct_FieldsEntry_DoNotUse(::PROTOBUF_NAMESPACE_ID::Arena* arena)
+ : SuperType(arena) {}
+void Struct_FieldsEntry_DoNotUse::MergeFrom(const Struct_FieldsEntry_DoNotUse& other) {
+ MergeFromInternal(other);
+}
+::PROTOBUF_NAMESPACE_ID::Metadata Struct_FieldsEntry_DoNotUse::GetMetadata() const {
+ return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(
+ &descriptor_table_google_2fprotobuf_2fstruct_2eproto_getter, &descriptor_table_google_2fprotobuf_2fstruct_2eproto_once,
+ file_level_metadata_google_2fprotobuf_2fstruct_2eproto[0]);
+}
+
+// ===================================================================
+
+class Struct::_Internal {
+ public:
+};
+
+Struct::Struct(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned)
+ : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned),
+ fields_(arena) {
+ SharedCtor();
+ if (!is_message_owned) {
+ RegisterArenaDtor(arena);
+ }
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.Struct)
+}
+Struct::Struct(const Struct& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message() {
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ fields_.MergeFrom(from.fields_);
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.Struct)
+}
+
+inline void Struct::SharedCtor() {
+}
+
+Struct::~Struct() {
+ // @@protoc_insertion_point(destructor:google.protobuf.Struct)
+ if (GetArenaForAllocation() != nullptr) return;
+ SharedDtor();
+ _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+inline void Struct::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+}
+
+void Struct::ArenaDtor(void* object) {
+ Struct* _this = reinterpret_cast< Struct* >(object);
+ (void)_this;
+ _this->fields_. ~MapField();
+}
+inline void Struct::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena) {
+ if (arena != nullptr) {
+ arena->OwnCustomDestructor(this, &Struct::ArenaDtor);
+ }
+}
+void Struct::SetCachedSize(int size) const {
+ _cached_size_.Set(size);
+}
+
+void Struct::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.Struct)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ fields_.Clear();
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* Struct::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag);
+ switch (tag >> 3) {
+ // map<string, .google.protobuf.Value> fields = 1;
+ case 1:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 10)) {
+ ptr -= 1;
+ do {
+ ptr += 1;
+ ptr = ctx->ParseMessage(&fields_, ptr);
+ CHK_(ptr);
+ if (!ctx->DataAvailable(ptr)) break;
+ } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<10>(ptr));
+ } else
+ goto handle_unusual;
+ continue;
+ default:
+ goto handle_unusual;
+ } // switch
+ handle_unusual:
+ if ((tag == 0) || ((tag & 7) == 4)) {
+ CHK_(ptr);
+ ctx->SetLastTag(tag);
+ goto message_done;
+ }
+ ptr = UnknownFieldParse(
+ tag,
+ _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(),
+ ptr, ctx);
+ CHK_(ptr != nullptr);
+ } // while
+message_done:
+ return ptr;
+failure:
+ ptr = nullptr;
+ goto message_done;
+#undef CHK_
+}
+
+uint8_t* Struct::_InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const {
+ // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Struct)
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ // map<string, .google.protobuf.Value> fields = 1;
+ if (!this->_internal_fields().empty()) {
+ typedef ::PROTOBUF_NAMESPACE_ID::Map< std::string, ::PROTOBUF_NAMESPACE_ID::Value >::const_pointer
+ ConstPtr;
+ typedef ConstPtr SortItem;
+ typedef ::PROTOBUF_NAMESPACE_ID::internal::CompareByDerefFirst<SortItem> Less;
+ struct Utf8Check {
+ static void Check(ConstPtr p) {
+ (void)p;
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::VerifyUtf8String(
+ p->first.data(), static_cast<int>(p->first.length()),
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SERIALIZE,
+ "google.protobuf.Struct.FieldsEntry.key");
+ }
+ };
+
+ if (stream->IsSerializationDeterministic() &&
+ this->_internal_fields().size() > 1) {
+ ::std::unique_ptr<SortItem[]> items(
+ new SortItem[this->_internal_fields().size()]);
+ typedef ::PROTOBUF_NAMESPACE_ID::Map< std::string, ::PROTOBUF_NAMESPACE_ID::Value >::size_type size_type;
+ size_type n = 0;
+ for (::PROTOBUF_NAMESPACE_ID::Map< std::string, ::PROTOBUF_NAMESPACE_ID::Value >::const_iterator
+ it = this->_internal_fields().begin();
+ it != this->_internal_fields().end(); ++it, ++n) {
+ items[static_cast<ptrdiff_t>(n)] = SortItem(&*it);
+ }
+ ::std::sort(&items[0], &items[static_cast<ptrdiff_t>(n)], Less());
+ for (size_type i = 0; i < n; i++) {
+ target = Struct_FieldsEntry_DoNotUse::Funcs::InternalSerialize(1, items[static_cast<ptrdiff_t>(i)]->first, items[static_cast<ptrdiff_t>(i)]->second, target, stream);
+ Utf8Check::Check(&(*items[static_cast<ptrdiff_t>(i)]));
+ }
+ } else {
+ for (::PROTOBUF_NAMESPACE_ID::Map< std::string, ::PROTOBUF_NAMESPACE_ID::Value >::const_iterator
+ it = this->_internal_fields().begin();
+ it != this->_internal_fields().end(); ++it) {
+ target = Struct_FieldsEntry_DoNotUse::Funcs::InternalSerialize(1, it->first, it->second, target, stream);
+ Utf8Check::Check(&(*it));
+ }
+ }
+ }
+
+ if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray(
+ _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Struct)
+ return target;
+}
+
+size_t Struct::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.Struct)
+ size_t total_size = 0;
+
+ 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, &_cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData Struct::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck,
+ Struct::MergeImpl
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*Struct::GetClassData() const { return &_class_data_; }
+
+void Struct::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to,
+ const ::PROTOBUF_NAMESPACE_ID::Message& from) {
+ static_cast<Struct *>(to)->MergeFrom(
+ static_cast<const Struct &>(from));
+}
+
+
+void Struct::MergeFrom(const Struct& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Struct)
+ GOOGLE_DCHECK_NE(&from, this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ fields_.MergeFrom(from.fields_);
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+}
+
+void Struct::CopyFrom(const Struct& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.Struct)
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+bool Struct::IsInitialized() const {
+ return true;
+}
+
+void Struct::InternalSwap(Struct* other) {
+ using std::swap;
+ _internal_metadata_.InternalSwap(&other->_internal_metadata_);
+ fields_.InternalSwap(&other->fields_);
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata Struct::GetMetadata() const {
+ return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(
+ &descriptor_table_google_2fprotobuf_2fstruct_2eproto_getter, &descriptor_table_google_2fprotobuf_2fstruct_2eproto_once,
+ file_level_metadata_google_2fprotobuf_2fstruct_2eproto[1]);
+}
+
+// ===================================================================
+
+class Value::_Internal {
+ public:
+ static const ::PROTOBUF_NAMESPACE_ID::Struct& struct_value(const Value* msg);
+ static const ::PROTOBUF_NAMESPACE_ID::ListValue& list_value(const Value* msg);
+};
+
+const ::PROTOBUF_NAMESPACE_ID::Struct&
+Value::_Internal::struct_value(const Value* msg) {
+ return *msg->kind_.struct_value_;
+}
+const ::PROTOBUF_NAMESPACE_ID::ListValue&
+Value::_Internal::list_value(const Value* msg) {
+ return *msg->kind_.list_value_;
+}
+void Value::set_allocated_struct_value(::PROTOBUF_NAMESPACE_ID::Struct* struct_value) {
+ ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaForAllocation();
+ clear_kind();
+ if (struct_value) {
+ ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
+ ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper<::PROTOBUF_NAMESPACE_ID::Struct>::GetOwningArena(struct_value);
+ if (message_arena != submessage_arena) {
+ struct_value = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
+ message_arena, struct_value, submessage_arena);
+ }
+ set_has_struct_value();
+ kind_.struct_value_ = struct_value;
+ }
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.Value.struct_value)
+}
+void Value::set_allocated_list_value(::PROTOBUF_NAMESPACE_ID::ListValue* list_value) {
+ ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaForAllocation();
+ clear_kind();
+ if (list_value) {
+ ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
+ ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper<::PROTOBUF_NAMESPACE_ID::ListValue>::GetOwningArena(list_value);
+ if (message_arena != submessage_arena) {
+ list_value = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
+ message_arena, list_value, submessage_arena);
+ }
+ set_has_list_value();
+ kind_.list_value_ = list_value;
+ }
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.Value.list_value)
+}
+Value::Value(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned)
+ : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) {
+ SharedCtor();
+ if (!is_message_owned) {
+ RegisterArenaDtor(arena);
+ }
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.Value)
+}
+Value::Value(const Value& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message() {
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ clear_has_kind();
+ switch (from.kind_case()) {
+ case kNullValue: {
+ _internal_set_null_value(from._internal_null_value());
+ break;
+ }
+ case kNumberValue: {
+ _internal_set_number_value(from._internal_number_value());
+ break;
+ }
+ case kStringValue: {
+ _internal_set_string_value(from._internal_string_value());
+ break;
+ }
+ case kBoolValue: {
+ _internal_set_bool_value(from._internal_bool_value());
+ break;
+ }
+ case kStructValue: {
+ _internal_mutable_struct_value()->::PROTOBUF_NAMESPACE_ID::Struct::MergeFrom(from._internal_struct_value());
+ break;
+ }
+ case kListValue: {
+ _internal_mutable_list_value()->::PROTOBUF_NAMESPACE_ID::ListValue::MergeFrom(from._internal_list_value());
+ break;
+ }
+ case KIND_NOT_SET: {
+ break;
+ }
+ }
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.Value)
+}
+
+inline void Value::SharedCtor() {
+clear_has_kind();
+}
+
+Value::~Value() {
+ // @@protoc_insertion_point(destructor:google.protobuf.Value)
+ if (GetArenaForAllocation() != nullptr) return;
+ SharedDtor();
+ _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+inline void Value::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+ if (has_kind()) {
+ clear_kind();
+ }
+}
+
+void Value::ArenaDtor(void* object) {
+ Value* _this = reinterpret_cast< Value* >(object);
+ (void)_this;
+}
+void Value::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) {
+}
+void Value::SetCachedSize(int size) const {
+ _cached_size_.Set(size);
+}
+
+void Value::clear_kind() {
+// @@protoc_insertion_point(one_of_clear_start:google.protobuf.Value)
+ switch (kind_case()) {
+ case kNullValue: {
+ // No need to clear
+ break;
+ }
+ case kNumberValue: {
+ // No need to clear
+ break;
+ }
+ case kStringValue: {
+ kind_.string_value_.Destroy(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation());
+ break;
+ }
+ case kBoolValue: {
+ // No need to clear
+ break;
+ }
+ case kStructValue: {
+ if (GetArenaForAllocation() == nullptr) {
+ delete kind_.struct_value_;
+ }
+ break;
+ }
+ case kListValue: {
+ if (GetArenaForAllocation() == nullptr) {
+ delete kind_.list_value_;
+ }
+ break;
+ }
+ case KIND_NOT_SET: {
+ break;
+ }
+ }
+ _oneof_case_[0] = KIND_NOT_SET;
+}
+
+
+void Value::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.Value)
+ 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, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag);
+ switch (tag >> 3) {
+ // .google.protobuf.NullValue null_value = 1;
+ case 1:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 8)) {
+ 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 = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx);
+ CHK_(::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.Value.string_value"));
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // bool bool_value = 4;
+ case 4:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 32)) {
+ _internal_set_bool_value(::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr));
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // .google.protobuf.Struct struct_value = 5;
+ case 5:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 42)) {
+ ptr = ctx->ParseMessage(_internal_mutable_struct_value(), ptr);
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // .google.protobuf.ListValue list_value = 6;
+ case 6:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 50)) {
+ ptr = ctx->ParseMessage(_internal_mutable_list_value(), ptr);
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ default:
+ goto handle_unusual;
+ } // switch
+ handle_unusual:
+ if ((tag == 0) || ((tag & 7) == 4)) {
+ CHK_(ptr);
+ ctx->SetLastTag(tag);
+ goto message_done;
+ }
+ ptr = UnknownFieldParse(
+ tag,
+ _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(),
+ ptr, ctx);
+ CHK_(ptr != nullptr);
+ } // while
+message_done:
+ return ptr;
+failure:
+ ptr = nullptr;
+ goto message_done;
+#undef CHK_
+}
+
+uint8_t* Value::_InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const {
+ // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Value)
+ 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 = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteEnumToArray(
+ 1, this->_internal_null_value(), target);
+ }
+
+ // double number_value = 2;
+ if (_internal_has_number_value()) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteDoubleToArray(2, this->_internal_number_value(), target);
+ }
+
+ // string string_value = 3;
+ if (_internal_has_string_value()) {
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::VerifyUtf8String(
+ this->_internal_string_value().data(), static_cast<int>(this->_internal_string_value().length()),
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SERIALIZE,
+ "google.protobuf.Value.string_value");
+ target = stream->WriteStringMaybeAliased(
+ 3, this->_internal_string_value(), target);
+ }
+
+ // bool bool_value = 4;
+ if (_internal_has_bool_value()) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBoolToArray(4, this->_internal_bool_value(), target);
+ }
+
+ // .google.protobuf.Struct struct_value = 5;
+ if (_internal_has_struct_value()) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(
+ 5, _Internal::struct_value(this), target, stream);
+ }
+
+ // .google.protobuf.ListValue list_value = 6;
+ if (_internal_has_list_value()) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(
+ 6, _Internal::list_value(this), target, stream);
+ }
+
+ if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray(
+ _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Value)
+ return target;
+}
+
+size_t Value::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.Value)
+ size_t total_size = 0;
+
+ 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 +
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::EnumSize(this->_internal_null_value());
+ break;
+ }
+ // double number_value = 2;
+ case kNumberValue: {
+ total_size += 1 + 8;
+ break;
+ }
+ // string string_value = 3;
+ case kStringValue: {
+ total_size += 1 +
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
+ this->_internal_string_value());
+ break;
+ }
+ // bool bool_value = 4;
+ case kBoolValue: {
+ total_size += 1 + 1;
+ break;
+ }
+ // .google.protobuf.Struct struct_value = 5;
+ case kStructValue: {
+ total_size += 1 +
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(
+ *kind_.struct_value_);
+ break;
+ }
+ // .google.protobuf.ListValue list_value = 6;
+ case kListValue: {
+ total_size += 1 +
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(
+ *kind_.list_value_);
+ break;
+ }
+ case KIND_NOT_SET: {
+ break;
+ }
+ }
+ return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData Value::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck,
+ Value::MergeImpl
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*Value::GetClassData() const { return &_class_data_; }
+
+void Value::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to,
+ const ::PROTOBUF_NAMESPACE_ID::Message& from) {
+ static_cast<Value *>(to)->MergeFrom(
+ static_cast<const Value &>(from));
+}
+
+
+void Value::MergeFrom(const Value& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Value)
+ GOOGLE_DCHECK_NE(&from, this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ switch (from.kind_case()) {
+ case kNullValue: {
+ _internal_set_null_value(from._internal_null_value());
+ break;
+ }
+ case kNumberValue: {
+ _internal_set_number_value(from._internal_number_value());
+ break;
+ }
+ case kStringValue: {
+ _internal_set_string_value(from._internal_string_value());
+ break;
+ }
+ case kBoolValue: {
+ _internal_set_bool_value(from._internal_bool_value());
+ break;
+ }
+ case kStructValue: {
+ _internal_mutable_struct_value()->::PROTOBUF_NAMESPACE_ID::Struct::MergeFrom(from._internal_struct_value());
+ break;
+ }
+ case kListValue: {
+ _internal_mutable_list_value()->::PROTOBUF_NAMESPACE_ID::ListValue::MergeFrom(from._internal_list_value());
+ break;
+ }
+ case KIND_NOT_SET: {
+ break;
+ }
+ }
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+}
+
+void Value::CopyFrom(const Value& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.Value)
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+bool Value::IsInitialized() const {
+ return true;
+}
+
+void Value::InternalSwap(Value* other) {
+ using std::swap;
+ _internal_metadata_.InternalSwap(&other->_internal_metadata_);
+ swap(kind_, other->kind_);
+ swap(_oneof_case_[0], other->_oneof_case_[0]);
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata Value::GetMetadata() const {
+ return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(
+ &descriptor_table_google_2fprotobuf_2fstruct_2eproto_getter, &descriptor_table_google_2fprotobuf_2fstruct_2eproto_once,
+ file_level_metadata_google_2fprotobuf_2fstruct_2eproto[2]);
+}
+
+// ===================================================================
+
+class ListValue::_Internal {
+ public:
+};
+
+ListValue::ListValue(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned)
+ : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned),
+ values_(arena) {
+ SharedCtor();
+ if (!is_message_owned) {
+ RegisterArenaDtor(arena);
+ }
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.ListValue)
+}
+ListValue::ListValue(const ListValue& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message(),
+ values_(from.values_) {
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.ListValue)
+}
+
+inline void ListValue::SharedCtor() {
+}
+
+ListValue::~ListValue() {
+ // @@protoc_insertion_point(destructor:google.protobuf.ListValue)
+ if (GetArenaForAllocation() != nullptr) return;
+ SharedDtor();
+ _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+inline void ListValue::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+}
+
+void ListValue::ArenaDtor(void* object) {
+ ListValue* _this = reinterpret_cast< ListValue* >(object);
+ (void)_this;
+}
+void ListValue::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) {
+}
+void ListValue::SetCachedSize(int size) const {
+ _cached_size_.Set(size);
+}
+
+void ListValue::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.ListValue)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ values_.Clear();
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* ListValue::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag);
+ switch (tag >> 3) {
+ // repeated .google.protobuf.Value values = 1;
+ case 1:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 10)) {
+ ptr -= 1;
+ do {
+ ptr += 1;
+ ptr = ctx->ParseMessage(_internal_add_values(), ptr);
+ CHK_(ptr);
+ if (!ctx->DataAvailable(ptr)) break;
+ } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<10>(ptr));
+ } else
+ goto handle_unusual;
+ continue;
+ default:
+ goto handle_unusual;
+ } // switch
+ handle_unusual:
+ if ((tag == 0) || ((tag & 7) == 4)) {
+ CHK_(ptr);
+ ctx->SetLastTag(tag);
+ goto message_done;
+ }
+ ptr = UnknownFieldParse(
+ tag,
+ _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(),
+ ptr, ctx);
+ CHK_(ptr != nullptr);
+ } // while
+message_done:
+ return ptr;
+failure:
+ ptr = nullptr;
+ goto message_done;
+#undef CHK_
+}
+
+uint8_t* ListValue::_InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const {
+ // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.ListValue)
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ // repeated .google.protobuf.Value values = 1;
+ for (unsigned int i = 0,
+ n = static_cast<unsigned int>(this->_internal_values_size()); i < n; i++) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(1, this->_internal_values(i), target, stream);
+ }
+
+ if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray(
+ _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.ListValue)
+ return target;
+}
+
+size_t ListValue::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.ListValue)
+ size_t total_size = 0;
+
+ 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->values_) {
+ total_size +=
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg);
+ }
+
+ return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData ListValue::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck,
+ ListValue::MergeImpl
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*ListValue::GetClassData() const { return &_class_data_; }
+
+void ListValue::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to,
+ const ::PROTOBUF_NAMESPACE_ID::Message& from) {
+ static_cast<ListValue *>(to)->MergeFrom(
+ static_cast<const ListValue &>(from));
+}
+
+
+void ListValue::MergeFrom(const ListValue& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.ListValue)
+ GOOGLE_DCHECK_NE(&from, this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ values_.MergeFrom(from.values_);
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+}
+
+void ListValue::CopyFrom(const ListValue& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.ListValue)
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+bool ListValue::IsInitialized() const {
+ return true;
+}
+
+void ListValue::InternalSwap(ListValue* other) {
+ using std::swap;
+ _internal_metadata_.InternalSwap(&other->_internal_metadata_);
+ values_.InternalSwap(&other->values_);
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata ListValue::GetMetadata() const {
+ return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(
+ &descriptor_table_google_2fprotobuf_2fstruct_2eproto_getter, &descriptor_table_google_2fprotobuf_2fstruct_2eproto_once,
+ file_level_metadata_google_2fprotobuf_2fstruct_2eproto[3]);
+}
+
+// @@protoc_insertion_point(namespace_scope)
+PROTOBUF_NAMESPACE_CLOSE
+PROTOBUF_NAMESPACE_OPEN
+template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::Struct_FieldsEntry_DoNotUse* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::Struct_FieldsEntry_DoNotUse >(Arena* arena) {
+ return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::Struct_FieldsEntry_DoNotUse >(arena);
+}
+template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::Struct* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::Struct >(Arena* arena) {
+ return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::Struct >(arena);
+}
+template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::Value* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::Value >(Arena* arena) {
+ return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::Value >(arena);
+}
+template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::ListValue* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::ListValue >(Arena* arena) {
+ return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::ListValue >(arena);
+}
+PROTOBUF_NAMESPACE_CLOSE
+
+// @@protoc_insertion_point(global_scope)
+#include <port_undef.inc>
diff --git a/NorthstarDedicatedTest/include/protobuf/struct.pb.h b/NorthstarDedicatedTest/include/protobuf/struct.pb.h
new file mode 100644
index 00000000..9b8d1b96
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/struct.pb.h
@@ -0,0 +1,1182 @@
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+// source: google/protobuf/struct.proto
+
+#ifndef GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fstruct_2eproto
+#define GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fstruct_2eproto
+
+#include <limits>
+#include <string>
+
+#include <port_def.inc>
+#if PROTOBUF_VERSION < 3019000
+#error This file was generated by a newer version of protoc which is
+#error incompatible with your Protocol Buffer headers. Please update
+#error your headers.
+#endif
+#if 3019004 < 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 <port_undef.inc>
+#include <io/coded_stream.h>
+#include <arena.h>
+#include <arenastring.h>
+#include <generated_message_table_driven.h>
+#include <generated_message_util.h>
+#include <metadata_lite.h>
+#include <generated_message_reflection.h>
+#include <message.h>
+#include <repeated_field.h> // IWYU pragma: export
+#include <extension_set.h> // IWYU pragma: export
+#include <map.h> // IWYU pragma: export
+#include <map_entry.h>
+#include <map_field_inl.h>
+#include <generated_enum_reflection.h>
+#include <unknown_field_set.h>
+// @@protoc_insertion_point(includes)
+#include <port_def.inc>
+#define PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fstruct_2eproto PROTOBUF_EXPORT
+PROTOBUF_NAMESPACE_OPEN
+namespace internal {
+class AnyMetadata;
+} // namespace internal
+PROTOBUF_NAMESPACE_CLOSE
+
+// Internal implementation detail -- do not use these members.
+struct PROTOBUF_EXPORT TableStruct_google_2fprotobuf_2fstruct_2eproto {
+ static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTableField entries[]
+ PROTOBUF_SECTION_VARIABLE(protodesc_cold);
+ static const ::PROTOBUF_NAMESPACE_ID::internal::AuxiliaryParseTableField aux[]
+ PROTOBUF_SECTION_VARIABLE(protodesc_cold);
+ static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTable schema[4]
+ PROTOBUF_SECTION_VARIABLE(protodesc_cold);
+ static const ::PROTOBUF_NAMESPACE_ID::internal::FieldMetadata field_metadata[];
+ static const ::PROTOBUF_NAMESPACE_ID::internal::SerializationTable serialization_table[];
+ static const 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 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;
+};
+
+// -------------------------------------------------------------------
+
+class PROTOBUF_EXPORT Struct final :
+ public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Struct) */ {
+ public:
+ inline Struct() : Struct(nullptr) {}
+ ~Struct() override;
+ explicit constexpr Struct(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
+
+ Struct(const Struct& from);
+ Struct(Struct&& from) noexcept
+ : Struct() {
+ *this = ::std::move(from);
+ }
+
+ inline Struct& operator=(const Struct& from) {
+ CopyFrom(from);
+ return *this;
+ }
+ inline Struct& operator=(Struct&& from) noexcept {
+ if (this == &from) return *this;
+ if (GetOwningArena() == from.GetOwningArena()
+ #ifdef PROTOBUF_FORCE_COPY_IN_MOVE
+ && GetOwningArena() != nullptr
+ #endif // !PROTOBUF_FORCE_COPY_IN_MOVE
+ ) {
+ InternalSwap(&from);
+ } else {
+ CopyFrom(from);
+ }
+ return *this;
+ }
+
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
+ return GetDescriptor();
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
+ return default_instance().GetMetadata().descriptor;
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
+ return default_instance().GetMetadata().reflection;
+ }
+ static const Struct& default_instance() {
+ return *internal_default_instance();
+ }
+ static inline const Struct* internal_default_instance() {
+ return reinterpret_cast<const Struct*>(
+ &_Struct_default_instance_);
+ }
+ static constexpr int kIndexInFileMessages =
+ 1;
+
+ friend void swap(Struct& a, Struct& b) {
+ a.Swap(&b);
+ }
+ inline void Swap(Struct* other) {
+ if (other == this) return;
+ #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() != nullptr &&
+ GetOwningArena() == other->GetOwningArena()) {
+ #else // PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() == other->GetOwningArena()) {
+ #endif // !PROTOBUF_FORCE_COPY_IN_SWAP
+ InternalSwap(other);
+ } else {
+ ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
+ }
+ }
+ void UnsafeArenaSwap(Struct* other) {
+ if (other == this) return;
+ GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena());
+ InternalSwap(other);
+ }
+
+ // implements Message ----------------------------------------------
+
+ Struct* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
+ return CreateMaybeMessage<Struct>(arena);
+ }
+ using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
+ void CopyFrom(const Struct& from);
+ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
+ void MergeFrom(const Struct& from);
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from);
+ public:
+ PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+ bool IsInitialized() const final;
+
+ size_t ByteSizeLong() const final;
+ const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
+ uint8_t* _InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
+ int GetCachedSize() const final { return _cached_size_.Get(); }
+
+ private:
+ void SharedCtor();
+ void SharedDtor();
+ void SetCachedSize(int size) const final;
+ void InternalSwap(Struct* other);
+
+ private:
+ friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
+ static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
+ return "google.protobuf.Struct";
+ }
+ protected:
+ explicit Struct(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned = false);
+ private:
+ static void ArenaDtor(void* object);
+ inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
+ public:
+
+ static const ClassData _class_data_;
+ const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;
+
+ ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;
+
+ // nested types ----------------------------------------------------
+
+
+ // accessors -------------------------------------------------------
+
+ enum : int {
+ kFieldsFieldNumber = 1,
+ };
+ // map<string, .google.protobuf.Value> fields = 1;
+ int fields_size() const;
+ private:
+ int _internal_fields_size() const;
+ public:
+ void clear_fields();
+ private:
+ const ::PROTOBUF_NAMESPACE_ID::Map< 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_;
+ ::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_;
+ friend struct ::TableStruct_google_2fprotobuf_2fstruct_2eproto;
+};
+// -------------------------------------------------------------------
+
+class PROTOBUF_EXPORT Value final :
+ public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Value) */ {
+ public:
+ inline Value() : Value(nullptr) {}
+ ~Value() override;
+ explicit constexpr Value(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
+
+ Value(const Value& from);
+ Value(Value&& from) noexcept
+ : Value() {
+ *this = ::std::move(from);
+ }
+
+ inline Value& operator=(const Value& from) {
+ CopyFrom(from);
+ return *this;
+ }
+ inline Value& operator=(Value&& from) noexcept {
+ if (this == &from) return *this;
+ if (GetOwningArena() == from.GetOwningArena()
+ #ifdef PROTOBUF_FORCE_COPY_IN_MOVE
+ && GetOwningArena() != nullptr
+ #endif // !PROTOBUF_FORCE_COPY_IN_MOVE
+ ) {
+ InternalSwap(&from);
+ } else {
+ CopyFrom(from);
+ }
+ return *this;
+ }
+
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
+ return GetDescriptor();
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
+ return default_instance().GetMetadata().descriptor;
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
+ return default_instance().GetMetadata().reflection;
+ }
+ static const Value& default_instance() {
+ return *internal_default_instance();
+ }
+ enum KindCase {
+ kNullValue = 1,
+ kNumberValue = 2,
+ kStringValue = 3,
+ kBoolValue = 4,
+ kStructValue = 5,
+ kListValue = 6,
+ KIND_NOT_SET = 0,
+ };
+
+ static inline const Value* internal_default_instance() {
+ return reinterpret_cast<const Value*>(
+ &_Value_default_instance_);
+ }
+ static constexpr int kIndexInFileMessages =
+ 2;
+
+ friend void swap(Value& a, Value& b) {
+ a.Swap(&b);
+ }
+ inline void Swap(Value* other) {
+ if (other == this) return;
+ #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() != nullptr &&
+ GetOwningArena() == other->GetOwningArena()) {
+ #else // PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() == other->GetOwningArena()) {
+ #endif // !PROTOBUF_FORCE_COPY_IN_SWAP
+ InternalSwap(other);
+ } else {
+ ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
+ }
+ }
+ void UnsafeArenaSwap(Value* other) {
+ if (other == this) return;
+ GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena());
+ InternalSwap(other);
+ }
+
+ // implements Message ----------------------------------------------
+
+ Value* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
+ return CreateMaybeMessage<Value>(arena);
+ }
+ using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
+ void CopyFrom(const Value& from);
+ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
+ void MergeFrom(const Value& from);
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from);
+ public:
+ PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+ bool IsInitialized() const final;
+
+ size_t ByteSizeLong() const final;
+ const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
+ uint8_t* _InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
+ int GetCachedSize() const final { return _cached_size_.Get(); }
+
+ private:
+ void SharedCtor();
+ void SharedDtor();
+ void SetCachedSize(int size) const final;
+ void InternalSwap(Value* other);
+
+ private:
+ friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
+ static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
+ return "google.protobuf.Value";
+ }
+ protected:
+ explicit Value(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned = false);
+ private:
+ static void ArenaDtor(void* object);
+ inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
+ public:
+
+ static const ClassData _class_data_;
+ const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;
+
+ ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;
+
+ // nested types ----------------------------------------------------
+
+ // accessors -------------------------------------------------------
+
+ enum : int {
+ kNullValueFieldNumber = 1,
+ kNumberValueFieldNumber = 2,
+ kStringValueFieldNumber = 3,
+ kBoolValueFieldNumber = 4,
+ kStructValueFieldNumber = 5,
+ kListValueFieldNumber = 6,
+ };
+ // .google.protobuf.NullValue null_value = 1;
+ bool has_null_value() const;
+ private:
+ bool _internal_has_null_value() const;
+ public:
+ void clear_null_value();
+ ::PROTOBUF_NAMESPACE_ID::NullValue null_value() const;
+ void set_null_value(::PROTOBUF_NAMESPACE_ID::NullValue value);
+ private:
+ ::PROTOBUF_NAMESPACE_ID::NullValue _internal_null_value() const;
+ void _internal_set_null_value(::PROTOBUF_NAMESPACE_ID::NullValue value);
+ public:
+
+ // double number_value = 2;
+ bool has_number_value() const;
+ private:
+ bool _internal_has_number_value() const;
+ public:
+ void clear_number_value();
+ double number_value() const;
+ void set_number_value(double value);
+ private:
+ double _internal_number_value() const;
+ void _internal_set_number_value(double value);
+ public:
+
+ // string string_value = 3;
+ bool has_string_value() const;
+ private:
+ bool _internal_has_string_value() const;
+ public:
+ void clear_string_value();
+ const 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_;
+ 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];
+
+ friend struct ::TableStruct_google_2fprotobuf_2fstruct_2eproto;
+};
+// -------------------------------------------------------------------
+
+class PROTOBUF_EXPORT ListValue final :
+ public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.ListValue) */ {
+ public:
+ inline ListValue() : ListValue(nullptr) {}
+ ~ListValue() override;
+ explicit constexpr ListValue(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
+
+ ListValue(const ListValue& from);
+ ListValue(ListValue&& from) noexcept
+ : ListValue() {
+ *this = ::std::move(from);
+ }
+
+ inline ListValue& operator=(const ListValue& from) {
+ CopyFrom(from);
+ return *this;
+ }
+ inline ListValue& operator=(ListValue&& from) noexcept {
+ if (this == &from) return *this;
+ if (GetOwningArena() == from.GetOwningArena()
+ #ifdef PROTOBUF_FORCE_COPY_IN_MOVE
+ && GetOwningArena() != nullptr
+ #endif // !PROTOBUF_FORCE_COPY_IN_MOVE
+ ) {
+ InternalSwap(&from);
+ } else {
+ CopyFrom(from);
+ }
+ return *this;
+ }
+
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
+ return GetDescriptor();
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
+ return default_instance().GetMetadata().descriptor;
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
+ return default_instance().GetMetadata().reflection;
+ }
+ static const ListValue& default_instance() {
+ return *internal_default_instance();
+ }
+ static inline const ListValue* internal_default_instance() {
+ return reinterpret_cast<const ListValue*>(
+ &_ListValue_default_instance_);
+ }
+ static constexpr int kIndexInFileMessages =
+ 3;
+
+ friend void swap(ListValue& a, ListValue& b) {
+ a.Swap(&b);
+ }
+ inline void Swap(ListValue* other) {
+ if (other == this) return;
+ #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() != nullptr &&
+ GetOwningArena() == other->GetOwningArena()) {
+ #else // PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() == other->GetOwningArena()) {
+ #endif // !PROTOBUF_FORCE_COPY_IN_SWAP
+ InternalSwap(other);
+ } else {
+ ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
+ }
+ }
+ void UnsafeArenaSwap(ListValue* other) {
+ if (other == this) return;
+ GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena());
+ InternalSwap(other);
+ }
+
+ // implements Message ----------------------------------------------
+
+ ListValue* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
+ return CreateMaybeMessage<ListValue>(arena);
+ }
+ using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
+ void CopyFrom(const ListValue& from);
+ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
+ void MergeFrom(const ListValue& from);
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from);
+ public:
+ PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+ bool IsInitialized() const final;
+
+ size_t ByteSizeLong() const final;
+ const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
+ uint8_t* _InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
+ int GetCachedSize() const final { return _cached_size_.Get(); }
+
+ private:
+ void SharedCtor();
+ void SharedDtor();
+ void SetCachedSize(int size) const final;
+ void InternalSwap(ListValue* other);
+
+ private:
+ friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
+ static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
+ return "google.protobuf.ListValue";
+ }
+ protected:
+ explicit ListValue(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned = false);
+ private:
+ static void ArenaDtor(void* object);
+ inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
+ public:
+
+ static const ClassData _class_data_;
+ const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;
+
+ ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;
+
+ // nested types ----------------------------------------------------
+
+ // accessors -------------------------------------------------------
+
+ enum : int {
+ kValuesFieldNumber = 1,
+ };
+ // repeated .google.protobuf.Value values = 1;
+ int values_size() const;
+ private:
+ int _internal_values_size() const;
+ public:
+ void clear_values();
+ ::PROTOBUF_NAMESPACE_ID::Value* mutable_values(int index);
+ ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Value >*
+ mutable_values();
+ private:
+ const ::PROTOBUF_NAMESPACE_ID::Value& _internal_values(int index) const;
+ ::PROTOBUF_NAMESPACE_ID::Value* _internal_add_values();
+ public:
+ const ::PROTOBUF_NAMESPACE_ID::Value& values(int index) const;
+ ::PROTOBUF_NAMESPACE_ID::Value* add_values();
+ const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Value >&
+ values() const;
+
+ // @@protoc_insertion_point(class_scope:google.protobuf.ListValue)
+ private:
+ class _Internal;
+
+ template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
+ typedef void InternalArenaConstructable_;
+ typedef void DestructorSkippable_;
+ ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Value > values_;
+ mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
+ friend struct ::TableStruct_google_2fprotobuf_2fstruct_2eproto;
+};
+// ===================================================================
+
+
+// ===================================================================
+
+#ifdef __GNUC__
+ #pragma GCC diagnostic push
+ #pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#endif // __GNUC__
+// -------------------------------------------------------------------
+
+// Struct
+
+// map<string, .google.protobuf.Value> fields = 1;
+inline int Struct::_internal_fields_size() const {
+ return fields_.size();
+}
+inline int Struct::fields_size() const {
+ return _internal_fields_size();
+}
+inline void Struct::clear_fields() {
+ fields_.Clear();
+}
+inline const ::PROTOBUF_NAMESPACE_ID::Map< std::string, ::PROTOBUF_NAMESPACE_ID::Value >&
+Struct::_internal_fields() const {
+ return 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 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() {
+ _oneof_case_[0] = kNullValue;
+}
+inline void Value::clear_null_value() {
+ if (_internal_has_null_value()) {
+ kind_.null_value_ = 0;
+ clear_has_kind();
+ }
+}
+inline ::PROTOBUF_NAMESPACE_ID::NullValue Value::_internal_null_value() const {
+ if (_internal_has_null_value()) {
+ return static_cast< ::PROTOBUF_NAMESPACE_ID::NullValue >(kind_.null_value_);
+ }
+ return static_cast< ::PROTOBUF_NAMESPACE_ID::NullValue >(0);
+}
+inline ::PROTOBUF_NAMESPACE_ID::NullValue Value::null_value() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.Value.null_value)
+ return _internal_null_value();
+}
+inline void Value::_internal_set_null_value(::PROTOBUF_NAMESPACE_ID::NullValue value) {
+ if (!_internal_has_null_value()) {
+ clear_kind();
+ set_has_null_value();
+ }
+ kind_.null_value_ = value;
+}
+inline void Value::set_null_value(::PROTOBUF_NAMESPACE_ID::NullValue value) {
+ _internal_set_null_value(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.Value.null_value)
+}
+
+// double number_value = 2;
+inline bool Value::_internal_has_number_value() const {
+ return kind_case() == kNumberValue;
+}
+inline bool Value::has_number_value() const {
+ return _internal_has_number_value();
+}
+inline void Value::set_has_number_value() {
+ _oneof_case_[0] = kNumberValue;
+}
+inline void Value::clear_number_value() {
+ if (_internal_has_number_value()) {
+ kind_.number_value_ = 0;
+ clear_has_kind();
+ }
+}
+inline double Value::_internal_number_value() const {
+ if (_internal_has_number_value()) {
+ return kind_.number_value_;
+ }
+ return 0;
+}
+inline void Value::_internal_set_number_value(double value) {
+ if (!_internal_has_number_value()) {
+ clear_kind();
+ set_has_number_value();
+ }
+ kind_.number_value_ = value;
+}
+inline double Value::number_value() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.Value.number_value)
+ return _internal_number_value();
+}
+inline void Value::set_number_value(double value) {
+ _internal_set_number_value(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.Value.number_value)
+}
+
+// string string_value = 3;
+inline bool Value::_internal_has_string_value() const {
+ return kind_case() == kStringValue;
+}
+inline bool Value::has_string_value() const {
+ return _internal_has_string_value();
+}
+inline void Value::set_has_string_value() {
+ _oneof_case_[0] = kStringValue;
+}
+inline void Value::clear_string_value() {
+ if (_internal_has_string_value()) {
+ kind_.string_value_.Destroy(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation());
+ clear_has_kind();
+ }
+}
+inline const 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();
+ kind_.string_value_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ }
+ kind_.string_value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
+ // @@protoc_insertion_point(field_set:google.protobuf.Value.string_value)
+}
+inline 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 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();
+ kind_.string_value_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ }
+ kind_.string_value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation());
+}
+inline std::string* Value::_internal_mutable_string_value() {
+ if (!_internal_has_string_value()) {
+ clear_kind();
+ set_has_string_value();
+ kind_.string_value_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ }
+ return kind_.string_value_.Mutable(
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation());
+}
+inline 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 kind_.string_value_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
+ } 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();
+ kind_.string_value_.UnsafeSetDefault(string_value);
+ ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArenaForAllocation();
+ if (arena != nullptr) {
+ arena->Own(string_value);
+ }
+ }
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.Value.string_value)
+}
+
+// bool bool_value = 4;
+inline bool Value::_internal_has_bool_value() const {
+ return kind_case() == kBoolValue;
+}
+inline bool Value::has_bool_value() const {
+ return _internal_has_bool_value();
+}
+inline void Value::set_has_bool_value() {
+ _oneof_case_[0] = kBoolValue;
+}
+inline void Value::clear_bool_value() {
+ if (_internal_has_bool_value()) {
+ kind_.bool_value_ = false;
+ clear_has_kind();
+ }
+}
+inline bool Value::_internal_bool_value() const {
+ if (_internal_has_bool_value()) {
+ return kind_.bool_value_;
+ }
+ return false;
+}
+inline void Value::_internal_set_bool_value(bool value) {
+ if (!_internal_has_bool_value()) {
+ clear_kind();
+ set_has_bool_value();
+ }
+ kind_.bool_value_ = value;
+}
+inline bool Value::bool_value() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.Value.bool_value)
+ return _internal_bool_value();
+}
+inline void Value::set_bool_value(bool value) {
+ _internal_set_bool_value(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.Value.bool_value)
+}
+
+// .google.protobuf.Struct struct_value = 5;
+inline bool Value::_internal_has_struct_value() const {
+ return kind_case() == kStructValue;
+}
+inline bool Value::has_struct_value() const {
+ return _internal_has_struct_value();
+}
+inline void Value::set_has_struct_value() {
+ _oneof_case_[0] = kStructValue;
+}
+inline void Value::clear_struct_value() {
+ if (_internal_has_struct_value()) {
+ if (GetArenaForAllocation() == nullptr) {
+ delete kind_.struct_value_;
+ }
+ clear_has_kind();
+ }
+}
+inline ::PROTOBUF_NAMESPACE_ID::Struct* Value::release_struct_value() {
+ // @@protoc_insertion_point(field_release:google.protobuf.Value.struct_value)
+ if (_internal_has_struct_value()) {
+ clear_has_kind();
+ ::PROTOBUF_NAMESPACE_ID::Struct* temp = kind_.struct_value_;
+ if (GetArenaForAllocation() != nullptr) {
+ temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
+ }
+ kind_.struct_value_ = nullptr;
+ return temp;
+ } else {
+ return nullptr;
+ }
+}
+inline const ::PROTOBUF_NAMESPACE_ID::Struct& Value::_internal_struct_value() const {
+ return _internal_has_struct_value()
+ ? *kind_.struct_value_
+ : reinterpret_cast< ::PROTOBUF_NAMESPACE_ID::Struct&>(::PROTOBUF_NAMESPACE_ID::_Struct_default_instance_);
+}
+inline const ::PROTOBUF_NAMESPACE_ID::Struct& Value::struct_value() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.Value.struct_value)
+ return _internal_struct_value();
+}
+inline ::PROTOBUF_NAMESPACE_ID::Struct* Value::unsafe_arena_release_struct_value() {
+ // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.Value.struct_value)
+ if (_internal_has_struct_value()) {
+ clear_has_kind();
+ ::PROTOBUF_NAMESPACE_ID::Struct* temp = kind_.struct_value_;
+ kind_.struct_value_ = nullptr;
+ return temp;
+ } else {
+ return nullptr;
+ }
+}
+inline void Value::unsafe_arena_set_allocated_struct_value(::PROTOBUF_NAMESPACE_ID::Struct* struct_value) {
+ clear_kind();
+ if (struct_value) {
+ set_has_struct_value();
+ kind_.struct_value_ = struct_value;
+ }
+ // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.Value.struct_value)
+}
+inline ::PROTOBUF_NAMESPACE_ID::Struct* Value::_internal_mutable_struct_value() {
+ if (!_internal_has_struct_value()) {
+ clear_kind();
+ set_has_struct_value();
+ kind_.struct_value_ = CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::Struct >(GetArenaForAllocation());
+ }
+ return kind_.struct_value_;
+}
+inline ::PROTOBUF_NAMESPACE_ID::Struct* Value::mutable_struct_value() {
+ ::PROTOBUF_NAMESPACE_ID::Struct* _msg = _internal_mutable_struct_value();
+ // @@protoc_insertion_point(field_mutable:google.protobuf.Value.struct_value)
+ return _msg;
+}
+
+// .google.protobuf.ListValue list_value = 6;
+inline bool Value::_internal_has_list_value() const {
+ return kind_case() == kListValue;
+}
+inline bool Value::has_list_value() const {
+ return _internal_has_list_value();
+}
+inline void Value::set_has_list_value() {
+ _oneof_case_[0] = kListValue;
+}
+inline void Value::clear_list_value() {
+ if (_internal_has_list_value()) {
+ if (GetArenaForAllocation() == nullptr) {
+ delete kind_.list_value_;
+ }
+ clear_has_kind();
+ }
+}
+inline ::PROTOBUF_NAMESPACE_ID::ListValue* Value::release_list_value() {
+ // @@protoc_insertion_point(field_release:google.protobuf.Value.list_value)
+ if (_internal_has_list_value()) {
+ clear_has_kind();
+ ::PROTOBUF_NAMESPACE_ID::ListValue* temp = kind_.list_value_;
+ if (GetArenaForAllocation() != nullptr) {
+ temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
+ }
+ kind_.list_value_ = nullptr;
+ return temp;
+ } else {
+ return nullptr;
+ }
+}
+inline const ::PROTOBUF_NAMESPACE_ID::ListValue& Value::_internal_list_value() const {
+ return _internal_has_list_value()
+ ? *kind_.list_value_
+ : reinterpret_cast< ::PROTOBUF_NAMESPACE_ID::ListValue&>(::PROTOBUF_NAMESPACE_ID::_ListValue_default_instance_);
+}
+inline const ::PROTOBUF_NAMESPACE_ID::ListValue& Value::list_value() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.Value.list_value)
+ return _internal_list_value();
+}
+inline ::PROTOBUF_NAMESPACE_ID::ListValue* Value::unsafe_arena_release_list_value() {
+ // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.Value.list_value)
+ if (_internal_has_list_value()) {
+ clear_has_kind();
+ ::PROTOBUF_NAMESPACE_ID::ListValue* temp = kind_.list_value_;
+ kind_.list_value_ = nullptr;
+ return temp;
+ } else {
+ return nullptr;
+ }
+}
+inline void Value::unsafe_arena_set_allocated_list_value(::PROTOBUF_NAMESPACE_ID::ListValue* list_value) {
+ clear_kind();
+ if (list_value) {
+ set_has_list_value();
+ kind_.list_value_ = list_value;
+ }
+ // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.Value.list_value)
+}
+inline ::PROTOBUF_NAMESPACE_ID::ListValue* Value::_internal_mutable_list_value() {
+ if (!_internal_has_list_value()) {
+ clear_kind();
+ set_has_list_value();
+ kind_.list_value_ = CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::ListValue >(GetArenaForAllocation());
+ }
+ return kind_.list_value_;
+}
+inline ::PROTOBUF_NAMESPACE_ID::ListValue* Value::mutable_list_value() {
+ ::PROTOBUF_NAMESPACE_ID::ListValue* _msg = _internal_mutable_list_value();
+ // @@protoc_insertion_point(field_mutable:google.protobuf.Value.list_value)
+ return _msg;
+}
+
+inline bool Value::has_kind() const {
+ return kind_case() != KIND_NOT_SET;
+}
+inline void Value::clear_has_kind() {
+ _oneof_case_[0] = KIND_NOT_SET;
+}
+inline Value::KindCase Value::kind_case() const {
+ return Value::KindCase(_oneof_case_[0]);
+}
+// -------------------------------------------------------------------
+
+// ListValue
+
+// repeated .google.protobuf.Value values = 1;
+inline int ListValue::_internal_values_size() const {
+ return values_.size();
+}
+inline int ListValue::values_size() const {
+ return _internal_values_size();
+}
+inline void ListValue::clear_values() {
+ values_.Clear();
+}
+inline ::PROTOBUF_NAMESPACE_ID::Value* ListValue::mutable_values(int index) {
+ // @@protoc_insertion_point(field_mutable:google.protobuf.ListValue.values)
+ return values_.Mutable(index);
+}
+inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Value >*
+ListValue::mutable_values() {
+ // @@protoc_insertion_point(field_mutable_list:google.protobuf.ListValue.values)
+ return &values_;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::Value& ListValue::_internal_values(int index) const {
+ return values_.Get(index);
+}
+inline const ::PROTOBUF_NAMESPACE_ID::Value& ListValue::values(int index) const {
+ // @@protoc_insertion_point(field_get:google.protobuf.ListValue.values)
+ return _internal_values(index);
+}
+inline ::PROTOBUF_NAMESPACE_ID::Value* ListValue::_internal_add_values() {
+ return values_.Add();
+}
+inline ::PROTOBUF_NAMESPACE_ID::Value* ListValue::add_values() {
+ ::PROTOBUF_NAMESPACE_ID::Value* _add = _internal_add_values();
+ // @@protoc_insertion_point(field_add:google.protobuf.ListValue.values)
+ return _add;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Value >&
+ListValue::values() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.ListValue.values)
+ return values_;
+}
+
+#ifdef __GNUC__
+ #pragma GCC diagnostic pop
+#endif // __GNUC__
+// -------------------------------------------------------------------
+
+// -------------------------------------------------------------------
+
+// -------------------------------------------------------------------
+
+
+// @@protoc_insertion_point(namespace_scope)
+
+PROTOBUF_NAMESPACE_CLOSE
+
+PROTOBUF_NAMESPACE_OPEN
+
+template <> struct is_proto_enum< ::PROTOBUF_NAMESPACE_ID::NullValue> : ::std::true_type {};
+template <>
+inline const EnumDescriptor* GetEnumDescriptor< ::PROTOBUF_NAMESPACE_ID::NullValue>() {
+ return ::PROTOBUF_NAMESPACE_ID::NullValue_descriptor();
+}
+
+PROTOBUF_NAMESPACE_CLOSE
+
+// @@protoc_insertion_point(global_scope)
+
+#include <port_undef.inc>
+#endif // GOOGLE_PROTOBUF_INCLUDED_GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fstruct_2eproto
diff --git a/NorthstarDedicatedTest/include/protobuf/struct.proto b/NorthstarDedicatedTest/include/protobuf/struct.proto
new file mode 100644
index 00000000..0ac843ca
--- /dev/null
+++ b/NorthstarDedicatedTest/include/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/NorthstarDedicatedTest/include/protobuf/stubs/bytestream.cc b/NorthstarDedicatedTest/include/protobuf/stubs/bytestream.cc
new file mode 100644
index 00000000..64723180
--- /dev/null
+++ b/NorthstarDedicatedTest/include/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 <stubs/bytestream.h>
+
+#include <string.h>
+#include <algorithm>
+
+#include <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/NorthstarDedicatedTest/include/protobuf/stubs/bytestream.h b/NorthstarDedicatedTest/include/protobuf/stubs/bytestream.h
new file mode 100644
index 00000000..b22dd2af
--- /dev/null
+++ b/NorthstarDedicatedTest/include/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 <stubs/common.h>
+#include <stubs/stringpiece.h>
+
+#include <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 <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_STUBS_BYTESTREAM_H_
diff --git a/NorthstarDedicatedTest/include/protobuf/stubs/bytestream_unittest.cc b/NorthstarDedicatedTest/include/protobuf/stubs/bytestream_unittest.cc
new file mode 100644
index 00000000..056d5495
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/stubs/bytestream_unittest.cc
@@ -0,0 +1,146 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <stubs/bytestream.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <algorithm>
+
+#include <testing/googletest.h>
+#include <gtest/gtest.h>
+
+namespace google {
+namespace protobuf {
+namespace strings {
+namespace {
+
+// We use this class instead of ArrayByteSource to simulate a ByteSource that
+// contains multiple fragments. ArrayByteSource returns the entire array in
+// one fragment.
+class MockByteSource : public ByteSource {
+ public:
+ MockByteSource(StringPiece data, int block_size)
+ : data_(data), block_size_(block_size) {}
+
+ size_t Available() const { return data_.size(); }
+ StringPiece Peek() {
+ return data_.substr(0, block_size_);
+ }
+ void Skip(size_t n) { data_.remove_prefix(n); }
+
+ private:
+ StringPiece data_;
+ int block_size_;
+};
+
+TEST(ByteSourceTest, CopyTo) {
+ StringPiece data("Hello world!");
+ MockByteSource source(data, 3);
+ std::string str;
+ StringByteSink sink(&str);
+
+ source.CopyTo(&sink, data.size());
+ EXPECT_EQ(data, str);
+}
+
+TEST(ByteSourceTest, CopySubstringTo) {
+ StringPiece data("Hello world!");
+ MockByteSource source(data, 3);
+ source.Skip(1);
+ std::string str;
+ StringByteSink sink(&str);
+
+ source.CopyTo(&sink, data.size() - 2);
+ EXPECT_EQ(data.substr(1, data.size() - 2), str);
+ EXPECT_EQ("!", source.Peek());
+}
+
+TEST(ByteSourceTest, LimitByteSource) {
+ StringPiece data("Hello world!");
+ MockByteSource source(data, 3);
+ LimitByteSource limit_source(&source, 6);
+ EXPECT_EQ(6, limit_source.Available());
+ limit_source.Skip(1);
+ EXPECT_EQ(5, limit_source.Available());
+
+ {
+ std::string str;
+ StringByteSink sink(&str);
+ limit_source.CopyTo(&sink, limit_source.Available());
+ EXPECT_EQ("ello ", str);
+ EXPECT_EQ(0, limit_source.Available());
+ EXPECT_EQ(6, source.Available());
+ }
+
+ {
+ std::string str;
+ StringByteSink sink(&str);
+ source.CopyTo(&sink, source.Available());
+ EXPECT_EQ("world!", str);
+ EXPECT_EQ(0, source.Available());
+ }
+}
+
+TEST(ByteSourceTest, CopyToStringByteSink) {
+ StringPiece data("Hello world!");
+ MockByteSource source(data, 3);
+ std::string str;
+ StringByteSink sink(&str);
+ source.CopyTo(&sink, data.size());
+ EXPECT_EQ(data, str);
+}
+
+// Verify that ByteSink is subclassable and Flush() overridable.
+class FlushingByteSink : public StringByteSink {
+ public:
+ explicit FlushingByteSink(std::string* dest) : StringByteSink(dest) {}
+ virtual void Flush() { Append("z", 1); }
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FlushingByteSink);
+};
+
+// Write and Flush via the ByteSink superclass interface.
+void WriteAndFlush(ByteSink* s) {
+ s->Append("abc", 3);
+ s->Flush();
+}
+
+TEST(ByteSinkTest, Flush) {
+ std::string str;
+ FlushingByteSink f_sink(&str);
+ WriteAndFlush(&f_sink);
+ EXPECT_STREQ("abcz", str.c_str());
+}
+
+} // namespace
+} // namespace strings
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/stubs/callback.h b/NorthstarDedicatedTest/include/protobuf/stubs/callback.h
new file mode 100644
index 00000000..e6856537
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/stubs/callback.h
@@ -0,0 +1,583 @@
+#ifndef GOOGLE_PROTOBUF_STUBS_CALLBACK_H_
+#define GOOGLE_PROTOBUF_STUBS_CALLBACK_H_
+
+#include <type_traits>
+
+#include <stubs/macros.h>
+
+#include <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 <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_STUBS_CALLBACK_H_
diff --git a/NorthstarDedicatedTest/include/protobuf/stubs/casts.h b/NorthstarDedicatedTest/include/protobuf/stubs/casts.h
new file mode 100644
index 00000000..e1673165
--- /dev/null
+++ b/NorthstarDedicatedTest/include/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 <stubs/common.h>
+
+#include <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 <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_CASTS_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/stubs/common.cc b/NorthstarDedicatedTest/include/protobuf/stubs/common.cc
new file mode 100644
index 00000000..49ecfdd1
--- /dev/null
+++ b/NorthstarDedicatedTest/include/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 <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 <stubs/callback.h>
+#include <stubs/logging.h>
+#include <stubs/once.h>
+#include <stubs/status.h>
+#include <stubs/stringpiece.h>
+#include <stubs/strutil.h>
+#include <stubs/int128.h>
+
+#include <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 ghtonl(uint32 x) {
+ union {
+ uint32 result;
+ uint8 result_array[4];
+ };
+ result_array[0] = static_cast<uint8>(x >> 24);
+ result_array[1] = static_cast<uint8>((x >> 16) & 0xFF);
+ result_array[2] = static_cast<uint8>((x >> 8) & 0xFF);
+ result_array[3] = static_cast<uint8>(x & 0xFF);
+ return result;
+}
+
+#if PROTOBUF_USE_EXCEPTIONS
+FatalException::~FatalException() throw() {}
+
+const char* FatalException::what() const throw() {
+ return message_.c_str();
+}
+#endif
+
+} // namespace protobuf
+} // namespace google
+
+#include <port_undef.inc>
diff --git a/NorthstarDedicatedTest/include/protobuf/stubs/common.h b/NorthstarDedicatedTest/include/protobuf/stubs/common.h
new file mode 100644
index 00000000..885a623f
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/stubs/common.h
@@ -0,0 +1,201 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda) and others
+//
+// Contains basic types and utilities used by the rest of the library.
+
+#ifndef GOOGLE_PROTOBUF_COMMON_H__
+#define GOOGLE_PROTOBUF_COMMON_H__
+
+#include <algorithm>
+#include <iostream>
+#include <map>
+#include <memory>
+#include <set>
+#include <string>
+#include <vector>
+
+#include <stubs/macros.h>
+#include <stubs/platform_macros.h>
+#include <stubs/port.h>
+#include <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 <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 3019004
+
+// A suffix string for alpha, beta or rc releases. Empty for stable releases.
+#define GOOGLE_PROTOBUF_VERSION_SUFFIX ""
+
+// The minimum header version which works with the current version of
+// the library. This constant should only be used by protoc's C++ code
+// generator.
+static const int kMinHeaderVersionForLibrary = 3019000;
+
+// The minimum protoc version which works with the current version of the
+// headers.
+#define GOOGLE_PROTOBUF_MIN_PROTOC_VERSION 3019000
+
+// The minimum header version which works with the current version of
+// protoc. This constant should only be used in VerifyVersion().
+static const int kMinHeaderVersionForProtoc = 3019000;
+
+// Verifies that the headers and libraries are compatible. Use the macro
+// below to call this.
+void PROTOBUF_EXPORT VerifyVersion(int headerVersion, int minLibraryVersion,
+ const char* filename);
+
+// Converts a numeric version number to a string.
+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
+
+// This is at the end of the file instead of the beginning to work around a bug
+// in some versions of MSVC.
+using std::string;
+
+} // namespace protobuf
+} // namespace google
+
+#include <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_COMMON_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/stubs/common_unittest.cc b/NorthstarDedicatedTest/include/protobuf/stubs/common_unittest.cc
new file mode 100644
index 00000000..4ff7b8ce
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/stubs/common_unittest.cc
@@ -0,0 +1,358 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 <vector>
+#include <stubs/callback.h>
+#include <stubs/casts.h>
+#include <stubs/common.h>
+#include <stubs/logging.h>
+#include <stubs/strutil.h>
+#include <stubs/substitute.h>
+
+#include <testing/googletest.h>
+#include <gtest/gtest.h>
+
+namespace google {
+namespace protobuf {
+namespace {
+
+// TODO(kenton): More tests.
+
+#ifdef PACKAGE_VERSION // only defined when using automake, not MSVC
+
+TEST(VersionTest, VersionMatchesConfig) {
+ // Verify that the version string specified in config.h matches the one
+ // in common.h. The config.h version is a string which may have a suffix
+ // like "beta" or "rc1", so we remove that.
+ std::string version = PACKAGE_VERSION;
+ int pos = 0;
+ while (pos < version.size() &&
+ (ascii_isdigit(version[pos]) || version[pos] == '.')) {
+ ++pos;
+ }
+ version.erase(pos);
+
+ EXPECT_EQ(version, internal::VersionString(GOOGLE_PROTOBUF_VERSION));
+}
+
+#endif // PACKAGE_VERSION
+
+TEST(CommonTest, IntMinMaxConstants) {
+ // kint32min was declared incorrectly in the first release of protobufs.
+ // Ugh.
+ EXPECT_LT(kint32min, kint32max);
+ EXPECT_EQ(static_cast<uint32>(kint32min), static_cast<uint32>(kint32max) + 1);
+ EXPECT_LT(kint64min, kint64max);
+ EXPECT_EQ(static_cast<uint64>(kint64min), static_cast<uint64>(kint64max) + 1);
+ EXPECT_EQ(0, kuint32max + 1);
+ EXPECT_EQ(0, kuint64max + 1);
+}
+
+std::vector<std::string> captured_messages_;
+
+void CaptureLog(LogLevel level, const char* filename, int line,
+ const std::string& message) {
+ captured_messages_.push_back(
+ strings::Substitute("$0 $1:$2: $3",
+ implicit_cast<int>(level), filename, line, message));
+}
+
+TEST(LoggingTest, DefaultLogging) {
+ CaptureTestStderr();
+ int line = __LINE__;
+ GOOGLE_LOG(INFO ) << "A message.";
+ GOOGLE_LOG(WARNING) << "A warning.";
+ GOOGLE_LOG(ERROR ) << "An error.";
+
+ std::string text = GetCapturedTestStderr();
+ EXPECT_EQ(
+ "[libprotobuf INFO " __FILE__ ":" + SimpleItoa(line + 1) + "] A message.\n"
+ "[libprotobuf WARNING " __FILE__ ":" + SimpleItoa(line + 2) + "] A warning.\n"
+ "[libprotobuf ERROR " __FILE__ ":" + SimpleItoa(line + 3) + "] An error.\n",
+ text);
+}
+
+TEST(LoggingTest, NullLogging) {
+ LogHandler* old_handler = SetLogHandler(nullptr);
+
+ CaptureTestStderr();
+ GOOGLE_LOG(INFO ) << "A message.";
+ GOOGLE_LOG(WARNING) << "A warning.";
+ GOOGLE_LOG(ERROR ) << "An error.";
+
+ EXPECT_TRUE(SetLogHandler(old_handler) == nullptr);
+
+ std::string text = GetCapturedTestStderr();
+ EXPECT_EQ("", text);
+}
+
+TEST(LoggingTest, CaptureLogging) {
+ captured_messages_.clear();
+
+ LogHandler* old_handler = SetLogHandler(&CaptureLog);
+
+ int start_line = __LINE__;
+ GOOGLE_LOG(ERROR) << "An error.";
+ GOOGLE_LOG(WARNING) << "A warning.";
+
+ EXPECT_TRUE(SetLogHandler(old_handler) == &CaptureLog);
+
+ ASSERT_EQ(2, captured_messages_.size());
+ EXPECT_EQ(
+ "2 " __FILE__ ":" + SimpleItoa(start_line + 1) + ": An error.",
+ captured_messages_[0]);
+ EXPECT_EQ(
+ "1 " __FILE__ ":" + SimpleItoa(start_line + 2) + ": A warning.",
+ captured_messages_[1]);
+}
+
+TEST(LoggingTest, SilenceLogging) {
+ captured_messages_.clear();
+
+ LogHandler* old_handler = SetLogHandler(&CaptureLog);
+
+ int line1 = __LINE__; GOOGLE_LOG(INFO) << "Visible1";
+ LogSilencer* silencer1 = new LogSilencer;
+ GOOGLE_LOG(INFO) << "Not visible.";
+ LogSilencer* silencer2 = new LogSilencer;
+ GOOGLE_LOG(INFO) << "Not visible.";
+ delete silencer1;
+ GOOGLE_LOG(INFO) << "Not visible.";
+ delete silencer2;
+ int line2 = __LINE__; GOOGLE_LOG(INFO) << "Visible2";
+
+ EXPECT_TRUE(SetLogHandler(old_handler) == &CaptureLog);
+
+ ASSERT_EQ(2, captured_messages_.size());
+ EXPECT_EQ(
+ "0 " __FILE__ ":" + SimpleItoa(line1) + ": Visible1",
+ captured_messages_[0]);
+ EXPECT_EQ(
+ "0 " __FILE__ ":" + SimpleItoa(line2) + ": Visible2",
+ captured_messages_[1]);
+}
+
+class ClosureTest : public testing::Test {
+ public:
+ void SetA123Method() { a_ = 123; }
+ static void SetA123Function() { current_instance_->a_ = 123; }
+
+ void SetAMethod(int a) { a_ = a; }
+ void SetCMethod(std::string c) { c_ = c; }
+
+ static void SetAFunction(int a) { current_instance_->a_ = a; }
+ static void SetCFunction(std::string c) { current_instance_->c_ = c; }
+
+ void SetABMethod(int a, const char* b) { a_ = a; b_ = b; }
+ static void SetABFunction(int a, const char* b) {
+ current_instance_->a_ = a;
+ current_instance_->b_ = b;
+ }
+
+ virtual void SetUp() {
+ current_instance_ = this;
+ a_ = 0;
+ b_ = nullptr;
+ c_.clear();
+ permanent_closure_ = nullptr;
+ }
+
+ void DeleteClosureInCallback() {
+ delete permanent_closure_;
+ }
+
+ int a_;
+ const char* b_;
+ std::string c_;
+ Closure* permanent_closure_;
+
+ static ClosureTest* current_instance_;
+};
+
+ClosureTest* ClosureTest::current_instance_ = nullptr;
+
+TEST_F(ClosureTest, TestClosureFunction0) {
+ Closure* closure = NewCallback(&SetA123Function);
+ EXPECT_NE(123, a_);
+ closure->Run();
+ EXPECT_EQ(123, a_);
+}
+
+TEST_F(ClosureTest, TestClosureMethod0) {
+ Closure* closure = NewCallback(current_instance_,
+ &ClosureTest::SetA123Method);
+ EXPECT_NE(123, a_);
+ closure->Run();
+ EXPECT_EQ(123, a_);
+}
+
+TEST_F(ClosureTest, TestClosureFunction1) {
+ Closure* closure = NewCallback(&SetAFunction, 456);
+ EXPECT_NE(456, a_);
+ closure->Run();
+ EXPECT_EQ(456, a_);
+}
+
+TEST_F(ClosureTest, TestClosureMethod1) {
+ Closure* closure = NewCallback(current_instance_,
+ &ClosureTest::SetAMethod, 456);
+ EXPECT_NE(456, a_);
+ closure->Run();
+ EXPECT_EQ(456, a_);
+}
+
+TEST_F(ClosureTest, TestClosureFunction1String) {
+ Closure* closure = NewCallback(&SetCFunction, std::string("test"));
+ EXPECT_NE("test", c_);
+ closure->Run();
+ EXPECT_EQ("test", c_);
+}
+
+TEST_F(ClosureTest, TestClosureMethod1String) {
+ Closure* closure = NewCallback(current_instance_, &ClosureTest::SetCMethod,
+ std::string("test"));
+ EXPECT_NE("test", c_);
+ closure->Run();
+ EXPECT_EQ("test", c_);
+}
+
+TEST_F(ClosureTest, TestClosureFunction2) {
+ const char* cstr = "hello";
+ Closure* closure = NewCallback(&SetABFunction, 789, cstr);
+ EXPECT_NE(789, a_);
+ EXPECT_NE(cstr, b_);
+ closure->Run();
+ EXPECT_EQ(789, a_);
+ EXPECT_EQ(cstr, b_);
+}
+
+TEST_F(ClosureTest, TestClosureMethod2) {
+ const char* cstr = "hello";
+ Closure* closure = NewCallback(current_instance_,
+ &ClosureTest::SetABMethod, 789, cstr);
+ EXPECT_NE(789, a_);
+ EXPECT_NE(cstr, b_);
+ closure->Run();
+ EXPECT_EQ(789, a_);
+ EXPECT_EQ(cstr, b_);
+}
+
+// Repeat all of the above with NewPermanentCallback()
+
+TEST_F(ClosureTest, TestPermanentClosureFunction0) {
+ Closure* closure = NewPermanentCallback(&SetA123Function);
+ EXPECT_NE(123, a_);
+ closure->Run();
+ EXPECT_EQ(123, a_);
+ a_ = 0;
+ closure->Run();
+ EXPECT_EQ(123, a_);
+ delete closure;
+}
+
+TEST_F(ClosureTest, TestPermanentClosureMethod0) {
+ Closure* closure = NewPermanentCallback(current_instance_,
+ &ClosureTest::SetA123Method);
+ EXPECT_NE(123, a_);
+ closure->Run();
+ EXPECT_EQ(123, a_);
+ a_ = 0;
+ closure->Run();
+ EXPECT_EQ(123, a_);
+ delete closure;
+}
+
+TEST_F(ClosureTest, TestPermanentClosureFunction1) {
+ Closure* closure = NewPermanentCallback(&SetAFunction, 456);
+ EXPECT_NE(456, a_);
+ closure->Run();
+ EXPECT_EQ(456, a_);
+ a_ = 0;
+ closure->Run();
+ EXPECT_EQ(456, a_);
+ delete closure;
+}
+
+TEST_F(ClosureTest, TestPermanentClosureMethod1) {
+ Closure* closure = NewPermanentCallback(current_instance_,
+ &ClosureTest::SetAMethod, 456);
+ EXPECT_NE(456, a_);
+ closure->Run();
+ EXPECT_EQ(456, a_);
+ a_ = 0;
+ closure->Run();
+ EXPECT_EQ(456, a_);
+ delete closure;
+}
+
+TEST_F(ClosureTest, TestPermanentClosureFunction2) {
+ const char* cstr = "hello";
+ Closure* closure = NewPermanentCallback(&SetABFunction, 789, cstr);
+ EXPECT_NE(789, a_);
+ EXPECT_NE(cstr, b_);
+ closure->Run();
+ EXPECT_EQ(789, a_);
+ EXPECT_EQ(cstr, b_);
+ a_ = 0;
+ b_ = nullptr;
+ closure->Run();
+ EXPECT_EQ(789, a_);
+ EXPECT_EQ(cstr, b_);
+ delete closure;
+}
+
+TEST_F(ClosureTest, TestPermanentClosureMethod2) {
+ const char* cstr = "hello";
+ Closure* closure = NewPermanentCallback(current_instance_,
+ &ClosureTest::SetABMethod, 789, cstr);
+ EXPECT_NE(789, a_);
+ EXPECT_NE(cstr, b_);
+ closure->Run();
+ EXPECT_EQ(789, a_);
+ EXPECT_EQ(cstr, b_);
+ a_ = 0;
+ b_ = nullptr;
+ closure->Run();
+ EXPECT_EQ(789, a_);
+ EXPECT_EQ(cstr, b_);
+ delete closure;
+}
+
+TEST_F(ClosureTest, TestPermanentClosureDeleteInCallback) {
+ permanent_closure_ = NewPermanentCallback((ClosureTest*) this,
+ &ClosureTest::DeleteClosureInCallback);
+ permanent_closure_->Run();
+}
+
+} // anonymous namespace
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/stubs/hash.h b/NorthstarDedicatedTest/include/protobuf/stubs/hash.h
new file mode 100644
index 00000000..a7ec0680
--- /dev/null
+++ b/NorthstarDedicatedTest/include/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/NorthstarDedicatedTest/include/protobuf/stubs/int128.cc b/NorthstarDedicatedTest/include/protobuf/stubs/int128.cc
new file mode 100644
index 00000000..bc7e8554
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/stubs/int128.cc
@@ -0,0 +1,192 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <stubs/int128.h>
+
+#include <iomanip>
+#include <ostream> // NOLINT(readability/streams)
+#include <sstream>
+
+#include <stubs/logging.h>
+
+#include <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 n) {
+ GOOGLE_DCHECK_NE(0, n);
+ int pos = 0;
+ STEP(uint64, n, pos, 0x20);
+ uint32 n32 = n;
+ STEP(uint32, n32, pos, 0x10);
+ STEP(uint32, n32, pos, 0x08);
+ STEP(uint32, n32, pos, 0x04);
+ return pos + ((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 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>(uint64_t{0x1000000000000000u}); // 16^15
+ div_base_log = 15;
+ break;
+ case std::ios::oct:
+ div = static_cast<uint64>(
+ uint64_t{01000000000000000000000u}); // 8^21
+ div_base_log = 21;
+ break;
+ default: // std::ios::dec
+ div = static_cast<uint64>(
+ 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);
+ if (width > rep.size()) {
+ if ((flags & std::ios::adjustfield) == std::ios::left) {
+ rep.append(width - rep.size(), o.fill());
+ } else {
+ rep.insert(static_cast<std::string::size_type>(0),
+ width - rep.size(), o.fill());
+ }
+ }
+
+ // Stream the final representation in a single "<<" call.
+ return o << rep;
+}
+
+} // namespace protobuf
+} // namespace google
+
+#include <port_undef.inc> // NOLINT
diff --git a/NorthstarDedicatedTest/include/protobuf/stubs/int128.h b/NorthstarDedicatedTest/include/protobuf/stubs/int128.h
new file mode 100644
index 00000000..52d5fb10
--- /dev/null
+++ b/NorthstarDedicatedTest/include/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 <stubs/common.h>
+
+#include <iosfwd>
+
+#include <port_def.inc>
+
+namespace google {
+namespace protobuf {
+
+struct uint128_pod;
+
+// TODO(xiaofeng): Define GOOGLE_PROTOBUF_HAS_CONSTEXPR when constexpr is
+// available.
+#ifdef GOOGLE_PROTOBUF_HAS_CONSTEXPR
+# define UINT128_CONSTEXPR constexpr
+#else
+# define UINT128_CONSTEXPR
+#endif
+
+// An unsigned 128-bit integer type. Thread-compatible.
+class PROTOBUF_EXPORT uint128 {
+ public:
+ UINT128_CONSTEXPR uint128(); // Sets to 0, but don't trust on this behavior.
+ UINT128_CONSTEXPR uint128(uint64 top, uint64 bottom);
+#ifndef SWIG
+ UINT128_CONSTEXPR uint128(int bottom);
+ UINT128_CONSTEXPR uint128(uint32 bottom); // Top 96 bits = 0
+#endif
+ UINT128_CONSTEXPR uint128(uint64 bottom); // hi_ = 0
+ UINT128_CONSTEXPR uint128(const uint128_pod &val);
+
+ // Trivial copy constructor, assignment operator and destructor.
+
+ void Initialize(uint64 top, uint64 bottom);
+
+ // Arithmetic operators.
+ uint128& operator+=(const uint128& b);
+ uint128& operator-=(const uint128& b);
+ uint128& operator*=(const uint128& b);
+ // Long division/modulo for uint128.
+ uint128& operator/=(const uint128& b);
+ uint128& operator%=(const uint128& b);
+ uint128 operator++(int);
+ uint128 operator--(int);
+ uint128& operator<<=(int);
+ uint128& operator>>=(int);
+ uint128& operator&=(const uint128& b);
+ uint128& operator|=(const uint128& b);
+ uint128& operator^=(const uint128& b);
+ uint128& operator++();
+ uint128& operator--();
+
+ friend uint64 Uint128Low64(const uint128& v);
+ friend uint64 Uint128High64(const uint128& v);
+
+ // We add "std::" to avoid including all of port.h.
+ PROTOBUF_EXPORT friend std::ostream& operator<<(std::ostream& o,
+ const uint128& b);
+
+ private:
+ static void DivModImpl(uint128 dividend, uint128 divisor,
+ uint128* quotient_ret, uint128* remainder_ret);
+
+ // Little-endian memory order optimizations can benefit from
+ // having lo_ first, hi_ last.
+ // See util/endian/endian.h and Load128/Store128 for storing a uint128.
+ uint64 lo_;
+ uint64 hi_;
+
+ // Not implemented, just declared for catching automatic type conversions.
+ uint128(uint8);
+ uint128(uint16);
+ uint128(float v);
+ uint128(double v);
+};
+
+// This is a POD form of uint128 which can be used for static variables which
+// need to be operated on as uint128.
+struct uint128_pod {
+ // Note: The ordering of fields is different than 'class uint128' but the
+ // same as its 2-arg constructor. This enables more obvious initialization
+ // of static instances, which is the primary reason for this struct in the
+ // first place. This does not seem to defeat any optimizations wrt
+ // operations involving this struct.
+ uint64 hi;
+ uint64 lo;
+};
+
+PROTOBUF_EXPORT extern const uint128_pod kuint128max;
+
+// allow uint128 to be logged
+PROTOBUF_EXPORT extern std::ostream& operator<<(std::ostream& o,
+ const uint128& b);
+
+// Methods to access low and high pieces of 128-bit value.
+// Defined externally from uint128 to facilitate conversion
+// to native 128-bit types when compilers support them.
+inline uint64 Uint128Low64(const uint128& v) { return v.lo_; }
+inline uint64 Uint128High64(const uint128& v) { return v.hi_; }
+
+// TODO: perhaps it would be nice to have int128, a signed 128-bit type?
+
+// --------------------------------------------------------------------------
+// Implementation details follow
+// --------------------------------------------------------------------------
+inline bool operator==(const uint128& lhs, const uint128& rhs) {
+ return (Uint128Low64(lhs) == Uint128Low64(rhs) &&
+ Uint128High64(lhs) == Uint128High64(rhs));
+}
+inline bool operator!=(const uint128& lhs, const uint128& rhs) {
+ return !(lhs == rhs);
+}
+
+inline UINT128_CONSTEXPR uint128::uint128() : lo_(0), hi_(0) {}
+inline UINT128_CONSTEXPR uint128::uint128(uint64 top, uint64 bottom)
+ : lo_(bottom), hi_(top) {}
+inline UINT128_CONSTEXPR uint128::uint128(const uint128_pod& v)
+ : lo_(v.lo), hi_(v.hi) {}
+inline UINT128_CONSTEXPR uint128::uint128(uint64 bottom)
+ : lo_(bottom), hi_(0) {}
+#ifndef SWIG
+inline UINT128_CONSTEXPR uint128::uint128(uint32 bottom)
+ : lo_(bottom), hi_(0) {}
+inline UINT128_CONSTEXPR uint128::uint128(int bottom)
+ : lo_(bottom), hi_(static_cast<int64>((bottom < 0) ? -1 : 0)) {}
+#endif
+
+#undef UINT128_CONSTEXPR
+
+inline void uint128::Initialize(uint64 top, uint64 bottom) {
+ hi_ = top;
+ lo_ = bottom;
+}
+
+// Comparison operators.
+
+#define CMP128(op) \
+inline bool operator op(const uint128& lhs, const uint128& rhs) { \
+ return (Uint128High64(lhs) == Uint128High64(rhs)) ? \
+ (Uint128Low64(lhs) op Uint128Low64(rhs)) : \
+ (Uint128High64(lhs) op Uint128High64(rhs)); \
+}
+
+CMP128(<)
+CMP128(>)
+CMP128(>=)
+CMP128(<=)
+
+#undef CMP128
+
+// Unary operators
+
+inline uint128 operator-(const uint128& val) {
+ const uint64 hi_flip = ~Uint128High64(val);
+ const uint64 lo_flip = ~Uint128Low64(val);
+ const uint64 lo_add = lo_flip + 1;
+ if (lo_add < lo_flip) {
+ return uint128(hi_flip + 1, lo_add);
+ }
+ return uint128(hi_flip, lo_add);
+}
+
+inline bool operator!(const uint128& val) {
+ return !Uint128High64(val) && !Uint128Low64(val);
+}
+
+// Logical operators.
+
+inline uint128 operator~(const uint128& val) {
+ return uint128(~Uint128High64(val), ~Uint128Low64(val));
+}
+
+#define LOGIC128(op) \
+inline uint128 operator op(const uint128& lhs, const uint128& rhs) { \
+ return uint128(Uint128High64(lhs) op Uint128High64(rhs), \
+ Uint128Low64(lhs) op Uint128Low64(rhs)); \
+}
+
+LOGIC128(|)
+LOGIC128(&)
+LOGIC128(^)
+
+#undef LOGIC128
+
+#define LOGICASSIGN128(op) \
+inline uint128& uint128::operator op(const uint128& other) { \
+ hi_ op other.hi_; \
+ lo_ op other.lo_; \
+ return *this; \
+}
+
+LOGICASSIGN128(|=)
+LOGICASSIGN128(&=)
+LOGICASSIGN128(^=)
+
+#undef LOGICASSIGN128
+
+// Shift operators.
+
+inline uint128 operator<<(const uint128& val, int amount) {
+ // uint64 shifts of >= 64 are undefined, so we will need some special-casing.
+ if (amount < 64) {
+ if (amount == 0) {
+ return val;
+ }
+ uint64 new_hi = (Uint128High64(val) << amount) |
+ (Uint128Low64(val) >> (64 - amount));
+ uint64 new_lo = Uint128Low64(val) << amount;
+ return uint128(new_hi, new_lo);
+ } else if (amount < 128) {
+ return uint128(Uint128Low64(val) << (amount - 64), 0);
+ } else {
+ return uint128(0, 0);
+ }
+}
+
+inline uint128 operator>>(const uint128& val, int amount) {
+ // uint64 shifts of >= 64 are undefined, so we will need some special-casing.
+ if (amount < 64) {
+ if (amount == 0) {
+ return val;
+ }
+ uint64 new_hi = Uint128High64(val) >> amount;
+ uint64 new_lo = (Uint128Low64(val) >> amount) |
+ (Uint128High64(val) << (64 - amount));
+ return uint128(new_hi, new_lo);
+ } else if (amount < 128) {
+ return uint128(0, Uint128High64(val) >> (amount - 64));
+ } else {
+ return uint128(0, 0);
+ }
+}
+
+inline uint128& uint128::operator<<=(int amount) {
+ // uint64 shifts of >= 64 are undefined, so we will need some special-casing.
+ if (amount < 64) {
+ if (amount != 0) {
+ hi_ = (hi_ << amount) | (lo_ >> (64 - amount));
+ lo_ = lo_ << amount;
+ }
+ } else if (amount < 128) {
+ hi_ = lo_ << (amount - 64);
+ lo_ = 0;
+ } else {
+ hi_ = 0;
+ lo_ = 0;
+ }
+ return *this;
+}
+
+inline uint128& uint128::operator>>=(int amount) {
+ // uint64 shifts of >= 64 are undefined, so we will need some special-casing.
+ if (amount < 64) {
+ if (amount != 0) {
+ lo_ = (lo_ >> amount) | (hi_ << (64 - amount));
+ hi_ = hi_ >> amount;
+ }
+ } else if (amount < 128) {
+ lo_ = hi_ >> (amount - 64);
+ hi_ = 0;
+ } else {
+ lo_ = 0;
+ hi_ = 0;
+ }
+ return *this;
+}
+
+inline uint128 operator+(const uint128& lhs, const uint128& rhs) {
+ return uint128(lhs) += rhs;
+}
+
+inline uint128 operator-(const uint128& lhs, const uint128& rhs) {
+ return uint128(lhs) -= rhs;
+}
+
+inline uint128 operator*(const uint128& lhs, const uint128& rhs) {
+ return uint128(lhs) *= rhs;
+}
+
+inline uint128 operator/(const uint128& lhs, const uint128& rhs) {
+ return uint128(lhs) /= rhs;
+}
+
+inline uint128 operator%(const uint128& lhs, const uint128& rhs) {
+ return uint128(lhs) %= rhs;
+}
+
+inline uint128& uint128::operator+=(const uint128& b) {
+ hi_ += b.hi_;
+ uint64 lolo = lo_ + b.lo_;
+ if (lolo < lo_)
+ ++hi_;
+ lo_ = lolo;
+ return *this;
+}
+
+inline uint128& uint128::operator-=(const uint128& b) {
+ hi_ -= b.hi_;
+ if (b.lo_ > lo_)
+ --hi_;
+ lo_ -= b.lo_;
+ return *this;
+}
+
+inline uint128& uint128::operator*=(const uint128& b) {
+ uint64 a96 = hi_ >> 32;
+ uint64 a64 = hi_ & 0xffffffffu;
+ uint64 a32 = lo_ >> 32;
+ uint64 a00 = lo_ & 0xffffffffu;
+ uint64 b96 = b.hi_ >> 32;
+ uint64 b64 = b.hi_ & 0xffffffffu;
+ uint64 b32 = b.lo_ >> 32;
+ uint64 b00 = b.lo_ & 0xffffffffu;
+ // multiply [a96 .. a00] x [b96 .. b00]
+ // terms higher than c96 disappear off the high side
+ // terms c96 and c64 are safe to ignore carry bit
+ uint64 c96 = a96 * b00 + a64 * b32 + a32 * b64 + a00 * b96;
+ uint64 c64 = a64 * b00 + a32 * b32 + a00 * b64;
+ this->hi_ = (c96 << 32) + c64;
+ this->lo_ = 0;
+ // add terms after this one at a time to capture carry
+ *this += uint128(a32 * b00) << 32;
+ *this += uint128(a00 * b32) << 32;
+ *this += a00 * b00;
+ return *this;
+}
+
+inline uint128 uint128::operator++(int) {
+ uint128 tmp(*this);
+ *this += 1;
+ return tmp;
+}
+
+inline uint128 uint128::operator--(int) {
+ uint128 tmp(*this);
+ *this -= 1;
+ return tmp;
+}
+
+inline uint128& uint128::operator++() {
+ *this += 1;
+ return *this;
+}
+
+inline uint128& uint128::operator--() {
+ *this -= 1;
+ return *this;
+}
+
+} // namespace protobuf
+} // namespace google
+
+#include <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_STUBS_INT128_H_
diff --git a/NorthstarDedicatedTest/include/protobuf/stubs/int128_unittest.cc b/NorthstarDedicatedTest/include/protobuf/stubs/int128_unittest.cc
new file mode 100644
index 00000000..41f2d177
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/stubs/int128_unittest.cc
@@ -0,0 +1,511 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <stubs/int128.h>
+
+#include <algorithm>
+#include <sstream>
+#include <utility>
+
+#include <testing/googletest.h>
+#include <gtest/gtest.h>
+
+#include <port_def.inc>
+
+namespace google {
+namespace protobuf {
+
+TEST(Int128, AllTests) {
+ uint128 zero(0);
+ uint128 one(1);
+ uint128 one_2arg(0, 1);
+ uint128 two(0, 2);
+ uint128 three(0, 3);
+ uint128 big(2000, 2);
+ uint128 big_minus_one(2000, 1);
+ uint128 bigger(2001, 1);
+ uint128 biggest(kuint128max);
+ uint128 high_low(1, 0);
+ uint128 low_high(0, kuint64max);
+ EXPECT_LT(one, two);
+ EXPECT_GT(two, one);
+ EXPECT_LT(one, big);
+ EXPECT_LT(one, big);
+ EXPECT_EQ(one, one_2arg);
+ EXPECT_NE(one, two);
+ EXPECT_GT(big, one);
+ EXPECT_GE(big, two);
+ EXPECT_GE(big, big_minus_one);
+ EXPECT_GT(big, big_minus_one);
+ EXPECT_LT(big_minus_one, big);
+ EXPECT_LE(big_minus_one, big);
+ EXPECT_NE(big_minus_one, big);
+ EXPECT_LT(big, biggest);
+ EXPECT_LE(big, biggest);
+ EXPECT_GT(biggest, big);
+ EXPECT_GE(biggest, big);
+ EXPECT_EQ(big, ~~big);
+ EXPECT_EQ(one, one | one);
+ EXPECT_EQ(big, big | big);
+ EXPECT_EQ(one, one | zero);
+ EXPECT_EQ(one, one & one);
+ EXPECT_EQ(big, big & big);
+ EXPECT_EQ(zero, one & zero);
+ EXPECT_EQ(zero, big & ~big);
+ EXPECT_EQ(zero, one ^ one);
+ EXPECT_EQ(zero, big ^ big);
+ EXPECT_EQ(one, one ^ zero);
+
+ // Shift operators.
+ EXPECT_EQ(big, big << 0);
+ EXPECT_EQ(big, big >> 0);
+ EXPECT_GT(big << 1, big);
+ EXPECT_LT(big >> 1, big);
+ EXPECT_EQ(big, (big << 10) >> 10);
+ EXPECT_EQ(big, (big >> 1) << 1);
+ EXPECT_EQ(one, (one << 80) >> 80);
+ EXPECT_EQ(zero, (one >> 80) << 80);
+ EXPECT_EQ(zero, big >> 128);
+ EXPECT_EQ(zero, big << 128);
+
+ // Shift assignments.
+ uint128 big_copy = big;
+ EXPECT_EQ(big << 0, big_copy <<= 0);
+ big_copy = big;
+ EXPECT_EQ(big >> 0, big_copy >>= 0);
+ big_copy = big;
+ EXPECT_EQ(big << 1, big_copy <<= 1);
+ big_copy = big;
+ EXPECT_EQ(big >> 1, big_copy >>= 1);
+ big_copy = big;
+ EXPECT_EQ(big << 10, big_copy <<= 10);
+ big_copy = big;
+ EXPECT_EQ(big >> 10, big_copy >>= 10);
+ big_copy = big;
+ EXPECT_EQ(big << 64, big_copy <<= 64);
+ big_copy = big;
+ EXPECT_EQ(big >> 64, big_copy >>= 64);
+ big_copy = big;
+ EXPECT_EQ(big << 73, big_copy <<= 73);
+ big_copy = big;
+ EXPECT_EQ(big >> 73, big_copy >>= 73);
+ big_copy = big;
+ EXPECT_EQ(big << 128, big_copy <<= 128);
+ big_copy = big;
+ EXPECT_EQ(big >> 128, big_copy >>= 128);
+
+ EXPECT_EQ(Uint128High64(biggest), kuint64max);
+ EXPECT_EQ(Uint128Low64(biggest), kuint64max);
+ EXPECT_EQ(zero + one, one);
+ EXPECT_EQ(one + one, two);
+ EXPECT_EQ(big_minus_one + one, big);
+ EXPECT_EQ(one - one, zero);
+ EXPECT_EQ(one - zero, one);
+ EXPECT_EQ(zero - one, biggest);
+ EXPECT_EQ(big - big, zero);
+ EXPECT_EQ(big - one, big_minus_one);
+ EXPECT_EQ(big + kuint64max, bigger);
+ EXPECT_EQ(biggest + 1, zero);
+ EXPECT_EQ(zero - 1, biggest);
+ EXPECT_EQ(high_low - one, low_high);
+ EXPECT_EQ(low_high + one, high_low);
+ EXPECT_EQ(Uint128High64((uint128(1) << 64) - 1), 0);
+ EXPECT_EQ(Uint128Low64((uint128(1) << 64) - 1), kuint64max);
+ EXPECT_TRUE(!!one);
+ EXPECT_TRUE(!!high_low);
+ EXPECT_FALSE(!!zero);
+ EXPECT_FALSE(!one);
+ EXPECT_FALSE(!high_low);
+ EXPECT_TRUE(!zero);
+ EXPECT_TRUE(zero == 0);
+ EXPECT_FALSE(zero != 0);
+ EXPECT_FALSE(one == 0);
+ EXPECT_TRUE(one != 0);
+
+ uint128 test = zero;
+ EXPECT_EQ(++test, one);
+ EXPECT_EQ(test, one);
+ EXPECT_EQ(test++, one);
+ EXPECT_EQ(test, two);
+ EXPECT_EQ(test -= 2, zero);
+ EXPECT_EQ(test, zero);
+ EXPECT_EQ(test += 2, two);
+ EXPECT_EQ(test, two);
+ EXPECT_EQ(--test, one);
+ EXPECT_EQ(test, one);
+ EXPECT_EQ(test--, one);
+ EXPECT_EQ(test, zero);
+ EXPECT_EQ(test |= three, three);
+ EXPECT_EQ(test &= one, one);
+ EXPECT_EQ(test ^= three, two);
+ EXPECT_EQ(test >>= 1, one);
+ EXPECT_EQ(test <<= 1, two);
+
+ EXPECT_EQ(big, -(-big));
+ EXPECT_EQ(two, -((-one) - 1));
+ EXPECT_EQ(kuint128max, -one);
+ EXPECT_EQ(zero, -zero);
+
+ GOOGLE_LOG(INFO) << one;
+ GOOGLE_LOG(INFO) << big_minus_one;
+}
+
+TEST(Int128, PodTests) {
+ uint128_pod pod = { 12345, 67890 };
+ uint128 from_pod(pod);
+ EXPECT_EQ(12345, Uint128High64(from_pod));
+ EXPECT_EQ(67890, Uint128Low64(from_pod));
+
+ uint128 zero(0);
+ uint128_pod zero_pod = {0, 0};
+ uint128 one(1);
+ uint128_pod one_pod = {0, 1};
+ uint128 two(2);
+ uint128_pod two_pod = {0, 2};
+ uint128 three(3);
+ uint128_pod three_pod = {0, 3};
+ uint128 big(1, 0);
+ uint128_pod big_pod = {1, 0};
+
+ EXPECT_EQ(zero, zero_pod);
+ EXPECT_EQ(zero_pod, zero);
+ EXPECT_EQ(zero_pod, zero_pod);
+ EXPECT_EQ(one, one_pod);
+ EXPECT_EQ(one_pod, one);
+ EXPECT_EQ(one_pod, one_pod);
+ EXPECT_EQ(two, two_pod);
+ EXPECT_EQ(two_pod, two);
+ EXPECT_EQ(two_pod, two_pod);
+
+ EXPECT_NE(one, two_pod);
+ EXPECT_NE(one_pod, two);
+ EXPECT_NE(one_pod, two_pod);
+
+ EXPECT_LT(one, two_pod);
+ EXPECT_LT(one_pod, two);
+ EXPECT_LT(one_pod, two_pod);
+ EXPECT_LE(one, one_pod);
+ EXPECT_LE(one_pod, one);
+ EXPECT_LE(one_pod, one_pod);
+ EXPECT_LE(one, two_pod);
+ EXPECT_LE(one_pod, two);
+ EXPECT_LE(one_pod, two_pod);
+
+ EXPECT_GT(two, one_pod);
+ EXPECT_GT(two_pod, one);
+ EXPECT_GT(two_pod, one_pod);
+ EXPECT_GE(two, two_pod);
+ EXPECT_GE(two_pod, two);
+ EXPECT_GE(two_pod, two_pod);
+ EXPECT_GE(two, one_pod);
+ EXPECT_GE(two_pod, one);
+ EXPECT_GE(two_pod, one_pod);
+
+ EXPECT_EQ(three, one | two_pod);
+ EXPECT_EQ(three, one_pod | two);
+ EXPECT_EQ(three, one_pod | two_pod);
+ EXPECT_EQ(one, three & one_pod);
+ EXPECT_EQ(one, three_pod & one);
+ EXPECT_EQ(one, three_pod & one_pod);
+ EXPECT_EQ(two, three ^ one_pod);
+ EXPECT_EQ(two, three_pod ^ one);
+ EXPECT_EQ(two, three_pod ^ one_pod);
+ EXPECT_EQ(two, three & (~one));
+ EXPECT_EQ(three, ~~three);
+
+ EXPECT_EQ(two, two_pod << 0);
+ EXPECT_EQ(two, one_pod << 1);
+ EXPECT_EQ(big, one_pod << 64);
+ EXPECT_EQ(zero, one_pod << 128);
+ EXPECT_EQ(two, two_pod >> 0);
+ EXPECT_EQ(one, two_pod >> 1);
+ EXPECT_EQ(one, big_pod >> 64);
+
+ EXPECT_EQ(one, zero + one_pod);
+ EXPECT_EQ(one, zero_pod + one);
+ EXPECT_EQ(one, zero_pod + one_pod);
+ EXPECT_EQ(one, two - one_pod);
+ EXPECT_EQ(one, two_pod - one);
+ EXPECT_EQ(one, two_pod - one_pod);
+}
+
+TEST(Int128, OperatorAssignReturnRef) {
+ uint128 v(1);
+ (v += 4) -= 3;
+ EXPECT_EQ(2, v);
+}
+
+TEST(Int128, Multiply) {
+ uint128 a, b, c;
+
+ // Zero test.
+ a = 0;
+ b = 0;
+ c = a * b;
+ EXPECT_EQ(0, c);
+
+ // Max carries.
+ a = uint128(0) - 1;
+ b = uint128(0) - 1;
+ c = a * b;
+ EXPECT_EQ(1, c);
+
+ // Self-operation with max carries.
+ c = uint128(0) - 1;
+ c *= c;
+ EXPECT_EQ(1, c);
+
+ // 1-bit x 1-bit.
+ for (int i = 0; i < 64; ++i) {
+ for (int j = 0; j < 64; ++j) {
+ a = uint128(1) << i;
+ b = uint128(1) << j;
+ c = a * b;
+ EXPECT_EQ(uint128(1) << (i+j), c);
+ }
+ }
+
+ // Verified with dc.
+ a = uint128(uint64_t{0xffffeeeeddddccccu}, uint64_t{0xbbbbaaaa99998888u});
+ b = uint128(uint64_t{0x7777666655554444u}, uint64_t{0x3333222211110000u});
+ c = a * b;
+ EXPECT_EQ(
+ uint128(uint64_t{0x530EDA741C71D4C3u}, uint64_t{0xBF25975319080000u}), c);
+ EXPECT_EQ(0, c - b * a);
+ EXPECT_EQ(a * a - b * b, (a + b) * (a - b));
+
+ // Verified with dc.
+ a = uint128(uint64_t{0x0123456789abcdefu}, uint64_t{0xfedcba9876543210u});
+ b = uint128(uint64_t{0x02468ace13579bdfu}, uint64_t{0xfdb97531eca86420u});
+ c = a * b;
+ EXPECT_EQ(
+ uint128(uint64_t{0x97a87f4f261ba3f2u}, uint64_t{0x342d0bbf48948200u}), c);
+ EXPECT_EQ(0, c - b * a);
+ EXPECT_EQ(a*a - b*b, (a+b) * (a-b));
+}
+
+TEST(Int128, AliasTests) {
+ uint128 x1(1, 2);
+ uint128 x2(2, 4);
+ x1 += x1;
+ EXPECT_EQ(x2, x1);
+
+ uint128 x3(1, static_cast<uint64>(1) << 63);
+ uint128 x4(3, 0);
+ x3 += x3;
+ EXPECT_EQ(x4, x3);
+}
+
+#ifdef PROTOBUF_HAS_DEATH_TEST
+TEST(Int128, DivideByZeroCheckFails) {
+ uint128 a = 0;
+ uint128 b = 0;
+ EXPECT_DEATH(a / b, "Division or mod by zero:");
+ a = 123;
+ EXPECT_DEATH(a / b, "Division or mod by zero:");
+}
+
+TEST(Int128, ModByZeroCheckFails) {
+ uint128 a = 0;
+ uint128 b = 0;
+ EXPECT_DEATH(a % b, "Division or mod by zero:");
+ a = 123;
+ EXPECT_DEATH(a % b, "Division or mod by zero:");
+}
+#endif // PROTOBUF_HAS_DEATH_TEST
+
+TEST(Int128, DivideAndMod) {
+ // a := q * b + r
+ uint128 a, b, q, r;
+
+ // Zero test.
+ a = 0;
+ b = 123;
+ q = a / b;
+ r = a % b;
+ EXPECT_EQ(0, q);
+ EXPECT_EQ(0, r);
+
+ a = uint128(uint64_t{0x530eda741c71d4c3u}, uint64_t{0xbf25975319080000u});
+ q = uint128(uint64_t{0x4de2cab081u}, uint64_t{0x14c34ab4676e4babu});
+ b = uint128(0x1110001);
+ r = uint128(0x3eb455);
+ ASSERT_EQ(a, q * b + r); // Sanity-check.
+
+ uint128 result_q, result_r;
+ result_q = a / b;
+ result_r = a % b;
+ EXPECT_EQ(q, result_q);
+ EXPECT_EQ(r, result_r);
+
+ // Try the other way around.
+ std::swap(q, b);
+ result_q = a / b;
+ result_r = a % b;
+ EXPECT_EQ(q, result_q);
+ EXPECT_EQ(r, result_r);
+ // Restore.
+ std::swap(b, q);
+
+ // Dividend < divisor; result should be q:0 r:<dividend>.
+ std::swap(a, b);
+ result_q = a / b;
+ result_r = a % b;
+ EXPECT_EQ(0, result_q);
+ EXPECT_EQ(a, result_r);
+ // Try the other way around.
+ std::swap(a, q);
+ result_q = a / b;
+ result_r = a % b;
+ EXPECT_EQ(0, result_q);
+ EXPECT_EQ(a, result_r);
+ // Restore.
+ std::swap(q, a);
+ std::swap(b, a);
+
+ // Try a large remainder.
+ b = a / 2 + 1;
+ uint128 expected_r(uint64_t{0x29876d3a0e38ea61u},
+ uint64_t{0xdf92cba98c83ffffu});
+ // Sanity checks.
+ ASSERT_EQ(a / 2 - 1, expected_r);
+ ASSERT_EQ(a, b + expected_r);
+ result_q = a / b;
+ result_r = a % b;
+ EXPECT_EQ(1, result_q);
+ EXPECT_EQ(expected_r, result_r);
+}
+
+static uint64 RandomUint64() {
+ uint64 v1 = rand();
+ uint64 v2 = rand();
+ uint64 v3 = rand();
+ return v1 * v2 + v3;
+}
+
+TEST(Int128, DivideAndModRandomInputs) {
+ const int kNumIters = 1 << 18;
+ for (int i = 0; i < kNumIters; ++i) {
+ const uint128 a(RandomUint64(), RandomUint64());
+ const uint128 b(RandomUint64(), RandomUint64());
+ if (b == 0) {
+ continue; // Avoid a div-by-zero.
+ }
+ const uint128 q = a / b;
+ const uint128 r = a % b;
+ ASSERT_EQ(a, b * q + r);
+ }
+}
+
+#ifdef GOOGLE_PROTOBUF_HAS_CONSTEXPR
+TEST(Int128, ConstexprTest) {
+ constexpr uint128 zero;
+ constexpr uint128 one = 1;
+ constexpr uint128_pod pod = {2, 3};
+ constexpr uint128 from_pod = pod;
+ constexpr uint128 minus_two = -2;
+ EXPECT_EQ(one, uint128(1));
+ EXPECT_EQ(from_pod, uint128(2, 3));
+ EXPECT_EQ(minus_two, uint128(-1ULL, -2ULL));
+}
+
+TEST(Int128, Traits) {
+ EXPECT_TRUE(std::is_trivially_copy_constructible<uint128>::value);
+ EXPECT_TRUE(std::is_trivially_copy_assignable<uint128>::value);
+ EXPECT_TRUE(std::is_trivially_destructible<uint128>::value);
+}
+#endif // GOOGLE_PROTOBUF_HAS_CONSTEXPR
+
+TEST(Int128, OStream) {
+ struct {
+ uint128 val;
+ std::ios_base::fmtflags flags;
+ std::streamsize width;
+ char fill;
+ const char* rep;
+ } cases[] = {
+ // zero with different bases
+ {uint128(0), std::ios::dec, 0, '_', "0"},
+ {uint128(0), std::ios::oct, 0, '_', "0"},
+ {uint128(0), std::ios::hex, 0, '_', "0"},
+ // crossover between lo_ and hi_
+ {uint128(0, -1), std::ios::dec, 0, '_', "18446744073709551615"},
+ {uint128(0, -1), std::ios::oct, 0, '_', "1777777777777777777777"},
+ {uint128(0, -1), std::ios::hex, 0, '_', "ffffffffffffffff"},
+ {uint128(1, 0), std::ios::dec, 0, '_', "18446744073709551616"},
+ {uint128(1, 0), std::ios::oct, 0, '_', "2000000000000000000000"},
+ {uint128(1, 0), std::ios::hex, 0, '_', "10000000000000000"},
+ // just the top bit
+ {uint128(uint64_t{0x8000000000000000u}, 0), std::ios::dec, 0, '_',
+ "170141183460469231731687303715884105728"},
+ {uint128(uint64_t{0x8000000000000000u}, 0), std::ios::oct, 0, '_',
+ "2000000000000000000000000000000000000000000"},
+ {uint128(uint64_t{0x8000000000000000u}, 0), std::ios::hex, 0, '_',
+ "80000000000000000000000000000000"},
+ // maximum uint128 value
+ {uint128(-1, -1), std::ios::dec, 0, '_',
+ "340282366920938463463374607431768211455"},
+ {uint128(-1, -1), std::ios::oct, 0, '_',
+ "3777777777777777777777777777777777777777777"},
+ {uint128(-1, -1), std::ios::hex, 0, '_',
+ "ffffffffffffffffffffffffffffffff"},
+ // uppercase
+ {uint128(-1, -1), std::ios::hex | std::ios::uppercase, 0, '_',
+ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"},
+ // showbase
+ {uint128(1), std::ios::dec | std::ios::showbase, 0, '_', "1"},
+ {uint128(1), std::ios::oct | std::ios::showbase, 0, '_', "01"},
+ {uint128(1), std::ios::hex | std::ios::showbase, 0, '_', "0x1"},
+ // showbase does nothing on zero
+ {uint128(0), std::ios::dec | std::ios::showbase, 0, '_', "0"},
+ {uint128(0), std::ios::oct | std::ios::showbase, 0, '_', "0"},
+ {uint128(0), std::ios::hex | std::ios::showbase, 0, '_', "0"},
+ // showpos does nothing on unsigned types
+ {uint128(1), std::ios::dec | std::ios::showpos, 0, '_', "1"},
+ // padding
+ {uint128(9), std::ios::dec, 6, '_', "_____9"},
+ {uint128(12345), std::ios::dec, 6, '_', "_12345"},
+ // left adjustment
+ {uint128(9), std::ios::dec | std::ios::left, 6, '_', "9_____"},
+ {uint128(12345), std::ios::dec | std::ios::left, 6, '_', "12345_"},
+ };
+ for (size_t i = 0; i < GOOGLE_ARRAYSIZE(cases); ++i) {
+ std::ostringstream os;
+ os.flags(cases[i].flags);
+ os.width(cases[i].width);
+ os.fill(cases[i].fill);
+ os << cases[i].val;
+ EXPECT_EQ(cases[i].rep, os.str());
+ }
+}
+} // namespace protobuf
+} // namespace google
+
+#include <port_undef.inc>
diff --git a/NorthstarDedicatedTest/include/protobuf/stubs/logging.h b/NorthstarDedicatedTest/include/protobuf/stubs/logging.h
new file mode 100644
index 00000000..664f7350
--- /dev/null
+++ b/NorthstarDedicatedTest/include/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 <stubs/macros.h>
+#include <stubs/port.h>
+#include <stubs/status.h>
+#include <stubs/stringpiece.h>
+
+#include <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 <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_STUBS_LOGGING_H_
diff --git a/NorthstarDedicatedTest/include/protobuf/stubs/macros.h b/NorthstarDedicatedTest/include/protobuf/stubs/macros.h
new file mode 100644
index 00000000..ae9a8b98
--- /dev/null
+++ b/NorthstarDedicatedTest/include/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/NorthstarDedicatedTest/include/protobuf/stubs/map_util.h b/NorthstarDedicatedTest/include/protobuf/stubs/map_util.h
new file mode 100644
index 00000000..a4829141
--- /dev/null
+++ b/NorthstarDedicatedTest/include/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 <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/NorthstarDedicatedTest/include/protobuf/stubs/mathutil.h b/NorthstarDedicatedTest/include/protobuf/stubs/mathutil.h
new file mode 100644
index 00000000..e75cf728
--- /dev/null
+++ b/NorthstarDedicatedTest/include/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 <stubs/common.h>
+#include <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/NorthstarDedicatedTest/include/protobuf/stubs/mutex.h b/NorthstarDedicatedTest/include/protobuf/stubs/mutex.h
new file mode 100644
index 00000000..c213d215
--- /dev/null
+++ b/NorthstarDedicatedTest/include/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 <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 <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 <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_STUBS_MUTEX_H_
diff --git a/NorthstarDedicatedTest/include/protobuf/stubs/once.h b/NorthstarDedicatedTest/include/protobuf/stubs/once.h
new file mode 100644
index 00000000..3769844a
--- /dev/null
+++ b/NorthstarDedicatedTest/include/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 <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 <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_STUBS_ONCE_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/stubs/platform_macros.h b/NorthstarDedicatedTest/include/protobuf/stubs/platform_macros.h
new file mode 100644
index 00000000..24799600
--- /dev/null
+++ b/NorthstarDedicatedTest/include/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/NorthstarDedicatedTest/include/protobuf/stubs/port.h b/NorthstarDedicatedTest/include/protobuf/stubs/port.h
new file mode 100644
index 00000000..d3be5cda
--- /dev/null
+++ b/NorthstarDedicatedTest/include/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 <stubs/platform_macros.h>
+
+#include <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 GOOGLE_UNALIGNED_LOAD16(const void *p) {
+ return __sanitizer_unaligned_load16(p);
+}
+
+inline uint32 GOOGLE_UNALIGNED_LOAD32(const void *p) {
+ return __sanitizer_unaligned_load32(p);
+}
+
+inline uint64 GOOGLE_UNALIGNED_LOAD64(const void *p) {
+ return __sanitizer_unaligned_load64(p);
+}
+
+inline void GOOGLE_UNALIGNED_STORE16(void *p, uint16 v) {
+ __sanitizer_unaligned_store16(p, v);
+}
+
+inline void GOOGLE_UNALIGNED_STORE32(void *p, uint32 v) {
+ __sanitizer_unaligned_store32(p, v);
+}
+
+inline void GOOGLE_UNALIGNED_STORE64(void *p, uint64 v) {
+ __sanitizer_unaligned_store64(p, v);
+}
+
+#elif defined(GOOGLE_PROTOBUF_USE_UNALIGNED) && GOOGLE_PROTOBUF_USE_UNALIGNED
+
+#define GOOGLE_UNALIGNED_LOAD16(_p) (*reinterpret_cast<const uint16 *>(_p))
+#define GOOGLE_UNALIGNED_LOAD32(_p) (*reinterpret_cast<const uint32 *>(_p))
+#define GOOGLE_UNALIGNED_LOAD64(_p) (*reinterpret_cast<const uint64 *>(_p))
+
+#define GOOGLE_UNALIGNED_STORE16(_p, _val) (*reinterpret_cast<uint16 *>(_p) = (_val))
+#define GOOGLE_UNALIGNED_STORE32(_p, _val) (*reinterpret_cast<uint32 *>(_p) = (_val))
+#define GOOGLE_UNALIGNED_STORE64(_p, _val) (*reinterpret_cast<uint64 *>(_p) = (_val))
+
+#else
+inline uint16 GOOGLE_UNALIGNED_LOAD16(const void *p) {
+ uint16 t;
+ memcpy(&t, p, sizeof t);
+ return t;
+}
+
+inline uint32 GOOGLE_UNALIGNED_LOAD32(const void *p) {
+ uint32 t;
+ memcpy(&t, p, sizeof t);
+ return t;
+}
+
+inline uint64 GOOGLE_UNALIGNED_LOAD64(const void *p) {
+ uint64 t;
+ memcpy(&t, p, sizeof t);
+ return t;
+}
+
+inline void GOOGLE_UNALIGNED_STORE16(void *p, uint16 v) {
+ memcpy(p, &v, sizeof v);
+}
+
+inline void GOOGLE_UNALIGNED_STORE32(void *p, uint32 v) {
+ memcpy(p, &v, sizeof v);
+}
+
+inline void GOOGLE_UNALIGNED_STORE64(void *p, uint64 v) {
+ memcpy(p, &v, sizeof v);
+}
+#endif
+
+#if defined(GOOGLE_PROTOBUF_OS_NACL) \
+ || (defined(__ANDROID__) && defined(__clang__) \
+ && (__clang_major__ == 3 && __clang_minor__ == 8) \
+ && (__clang_patchlevel__ < 275480))
+# define GOOGLE_PROTOBUF_USE_PORTABLE_LOG2
+#endif
+
+// The following guarantees declaration of the byte swap functions.
+#ifdef _MSC_VER
+#define bswap_16(x) _byteswap_ushort(x)
+#define bswap_32(x) _byteswap_ulong(x)
+#define bswap_64(x) _byteswap_uint64(x)
+
+#elif defined(__APPLE__)
+// Mac OS X / Darwin features
+#define bswap_16(x) OSSwapInt16(x)
+#define bswap_32(x) OSSwapInt32(x)
+#define bswap_64(x) OSSwapInt64(x)
+
+#elif !defined(__linux__) && !defined(__ANDROID__) && !defined(__CYGWIN__)
+
+#ifndef bswap_16
+static inline uint16 bswap_16(uint16 x) {
+ return static_cast<uint16>(((x & 0xFF) << 8) | ((x & 0xFF00) >> 8));
+}
+#define bswap_16(x) bswap_16(x)
+#endif
+
+#ifndef bswap_32
+static inline uint32 bswap_32(uint32 x) {
+ return (((x & 0xFF) << 24) |
+ ((x & 0xFF00) << 8) |
+ ((x & 0xFF0000) >> 8) |
+ ((x & 0xFF000000) >> 24));
+}
+#define bswap_32(x) bswap_32(x)
+#endif
+
+#ifndef bswap_64
+static inline uint64 bswap_64(uint64 x) {
+ return (((x & 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 Log2FloorNonZero(uint32 n) {
+#if defined(__GNUC__)
+ return 31 ^ static_cast<uint32>(__builtin_clz(n));
+#elif defined(_MSC_VER)
+ unsigned long where;
+ _BitScanReverse(&where, n);
+ return where;
+#else
+ return Log2FloorNonZero_Portable(n);
+#endif
+ }
+
+ static uint32 Log2FloorNonZero64(uint64 n) {
+ // Older versions of clang run into an instruction-selection failure when
+ // it encounters __builtin_clzll:
+ // https://bugs.chromium.org/p/nativeclient/issues/detail?id=4395
+ // This includes arm-nacl-clang and clang in older Android NDK versions.
+ // To work around this, when we build with those we use the portable
+ // implementation instead.
+#if defined(__GNUC__) && !defined(GOOGLE_PROTOBUF_USE_PORTABLE_LOG2)
+ return 63 ^ static_cast<uint32>(__builtin_clzll(n));
+#elif defined(_MSC_VER) && defined(_M_X64)
+ unsigned long where;
+ _BitScanReverse64(&where, n);
+ return where;
+#else
+ return Log2FloorNonZero64_Portable(n);
+#endif
+ }
+ private:
+ static int Log2FloorNonZero_Portable(uint32 n) {
+ if (n == 0)
+ return -1;
+ int log = 0;
+ uint32 value = n;
+ for (int i = 4; i >= 0; --i) {
+ int shift = (1 << i);
+ uint32 x = value >> shift;
+ if (x != 0) {
+ value = x;
+ log += shift;
+ }
+ }
+ assert(value == 1);
+ return log;
+ }
+
+ static int Log2FloorNonZero64_Portable(uint64 n) {
+ const uint32 topbits = static_cast<uint32>(n >> 32);
+ if (topbits == 0) {
+ // Top bits are zero, so scan in bottom bits
+ return static_cast<int>(Log2FloorNonZero(static_cast<uint32>(n)));
+ } else {
+ return 32 + static_cast<int>(Log2FloorNonZero(topbits));
+ }
+ }
+};
+
+// ===================================================================
+// from google3/util/endian/endian.h
+PROTOBUF_EXPORT uint32 ghtonl(uint32 x);
+
+class BigEndian {
+ public:
+#ifdef PROTOBUF_LITTLE_ENDIAN
+
+ static uint16 FromHost16(uint16 x) { return bswap_16(x); }
+ static uint16 ToHost16(uint16 x) { return bswap_16(x); }
+
+ static uint32 FromHost32(uint32 x) { return bswap_32(x); }
+ static uint32 ToHost32(uint32 x) { return bswap_32(x); }
+
+ static uint64 FromHost64(uint64 x) { return bswap_64(x); }
+ static uint64 ToHost64(uint64 x) { return bswap_64(x); }
+
+ static bool IsLittleEndian() { return true; }
+
+#else
+
+ static uint16 FromHost16(uint16 x) { return x; }
+ static uint16 ToHost16(uint16 x) { return x; }
+
+ static uint32 FromHost32(uint32 x) { return x; }
+ static uint32 ToHost32(uint32 x) { return x; }
+
+ static uint64 FromHost64(uint64 x) { return x; }
+ static uint64 ToHost64(uint64 x) { return x; }
+
+ static bool IsLittleEndian() { return false; }
+
+#endif /* ENDIAN */
+
+ // Functions to do unaligned loads and stores in big-endian order.
+ static uint16 Load16(const void *p) {
+ return ToHost16(GOOGLE_UNALIGNED_LOAD16(p));
+ }
+
+ static void Store16(void *p, uint16 v) {
+ GOOGLE_UNALIGNED_STORE16(p, FromHost16(v));
+ }
+
+ static uint32 Load32(const void *p) {
+ return ToHost32(GOOGLE_UNALIGNED_LOAD32(p));
+ }
+
+ static void Store32(void *p, uint32 v) {
+ GOOGLE_UNALIGNED_STORE32(p, FromHost32(v));
+ }
+
+ static uint64 Load64(const void *p) {
+ return ToHost64(GOOGLE_UNALIGNED_LOAD64(p));
+ }
+
+ static void Store64(void *p, uint64 v) {
+ GOOGLE_UNALIGNED_STORE64(p, FromHost64(v));
+ }
+};
+
+} // namespace protobuf
+} // namespace google
+
+#include <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_STUBS_PORT_H_
diff --git a/NorthstarDedicatedTest/include/protobuf/stubs/status.cc b/NorthstarDedicatedTest/include/protobuf/stubs/status.cc
new file mode 100644
index 00000000..2ecd0dc0
--- /dev/null
+++ b/NorthstarDedicatedTest/include/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 <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/NorthstarDedicatedTest/include/protobuf/stubs/status.h b/NorthstarDedicatedTest/include/protobuf/stubs/status.h
new file mode 100644
index 00000000..365ff046
--- /dev/null
+++ b/NorthstarDedicatedTest/include/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 <stubs/stringpiece.h>
+
+#include <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 <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_STUBS_STATUS_H_
diff --git a/NorthstarDedicatedTest/include/protobuf/stubs/status_macros.h b/NorthstarDedicatedTest/include/protobuf/stubs/status_macros.h
new file mode 100644
index 00000000..befebc6f
--- /dev/null
+++ b/NorthstarDedicatedTest/include/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 <stubs/common.h>
+#include <stubs/status.h>
+#include <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/NorthstarDedicatedTest/include/protobuf/stubs/status_test.cc b/NorthstarDedicatedTest/include/protobuf/stubs/status_test.cc
new file mode 100644
index 00000000..5ed8a64d
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/stubs/status_test.cc
@@ -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.
+#include <stubs/status.h>
+
+#include <stdio.h>
+
+#include <testing/googletest.h>
+#include <gtest/gtest.h>
+
+namespace google {
+namespace protobuf {
+namespace {
+
+TEST(Status, Constructor) {
+ EXPECT_EQ(util::StatusCode::kOk,
+ util::Status(util::StatusCode::kOk, "").code());
+ EXPECT_EQ(util::StatusCode::kCancelled,
+ util::Status(util::StatusCode::kCancelled, "").code());
+ EXPECT_EQ(util::StatusCode::kUnknown,
+ util::Status(util::StatusCode::kUnknown, "").code());
+ EXPECT_EQ(util::StatusCode::kInvalidArgument,
+ util::Status(util::StatusCode::kInvalidArgument, "").code());
+ EXPECT_EQ(util::StatusCode::kDeadlineExceeded,
+ util::Status(util::StatusCode::kDeadlineExceeded, "").code());
+ EXPECT_EQ(util::StatusCode::kNotFound,
+ util::Status(util::StatusCode::kNotFound, "").code());
+ EXPECT_EQ(util::StatusCode::kAlreadyExists,
+ util::Status(util::StatusCode::kAlreadyExists, "").code());
+ EXPECT_EQ(util::StatusCode::kPermissionDenied,
+ util::Status(util::StatusCode::kPermissionDenied, "").code());
+ EXPECT_EQ(util::StatusCode::kUnauthenticated,
+ util::Status(util::StatusCode::kUnauthenticated, "").code());
+ EXPECT_EQ(util::StatusCode::kResourceExhausted,
+ util::Status(util::StatusCode::kResourceExhausted, "").code());
+ EXPECT_EQ(util::StatusCode::kFailedPrecondition,
+ util::Status(util::StatusCode::kFailedPrecondition, "").code());
+ EXPECT_EQ(util::StatusCode::kAborted,
+ util::Status(util::StatusCode::kAborted, "").code());
+ EXPECT_EQ(util::StatusCode::kOutOfRange,
+ util::Status(util::StatusCode::kOutOfRange, "").code());
+ EXPECT_EQ(util::StatusCode::kUnimplemented,
+ util::Status(util::StatusCode::kUnimplemented, "").code());
+ EXPECT_EQ(util::StatusCode::kInternal,
+ util::Status(util::StatusCode::kInternal, "").code());
+ EXPECT_EQ(util::StatusCode::kUnavailable,
+ util::Status(util::StatusCode::kUnavailable, "").code());
+ EXPECT_EQ(util::StatusCode::kDataLoss,
+ util::Status(util::StatusCode::kDataLoss, "").code());
+}
+
+TEST(Status, ConstructorZero) {
+ util::Status status(util::StatusCode::kOk, "msg");
+ EXPECT_TRUE(status.ok());
+ EXPECT_EQ("OK", status.ToString());
+ EXPECT_EQ(util::OkStatus(), status);
+}
+
+TEST(Status, ConvenienceConstructors) {
+ EXPECT_EQ(util::StatusCode::kOk, util::OkStatus().code());
+ EXPECT_EQ("", util::OkStatus().message());
+
+ EXPECT_EQ(util::StatusCode::kCancelled, util::CancelledError("").code());
+ EXPECT_EQ("", util::CancelledError("").message());
+ EXPECT_EQ("foo", util::CancelledError("foo").message());
+ EXPECT_EQ("bar", util::CancelledError("bar").message());
+
+ EXPECT_EQ(util::StatusCode::kUnknown, util::UnknownError("").code());
+ EXPECT_EQ("", util::UnknownError("").message());
+ EXPECT_EQ("foo", util::UnknownError("foo").message());
+ EXPECT_EQ("bar", util::UnknownError("bar").message());
+
+ EXPECT_EQ(util::StatusCode::kInvalidArgument,
+ util::InvalidArgumentError("").code());
+ EXPECT_EQ("", util::InvalidArgumentError("").message());
+ EXPECT_EQ("foo", util::InvalidArgumentError("foo").message());
+ EXPECT_EQ("bar", util::InvalidArgumentError("bar").message());
+
+ EXPECT_EQ(util::StatusCode::kDeadlineExceeded,
+ util::DeadlineExceededError("").code());
+ EXPECT_EQ("", util::DeadlineExceededError("").message());
+ EXPECT_EQ("foo", util::DeadlineExceededError("foo").message());
+ EXPECT_EQ("bar", util::DeadlineExceededError("bar").message());
+
+ EXPECT_EQ(util::StatusCode::kNotFound, util::NotFoundError("").code());
+ EXPECT_EQ("", util::NotFoundError("").message());
+ EXPECT_EQ("foo", util::NotFoundError("foo").message());
+ EXPECT_EQ("bar", util::NotFoundError("bar").message());
+
+ EXPECT_EQ(util::StatusCode::kAlreadyExists,
+ util::AlreadyExistsError("").code());
+ EXPECT_EQ("", util::AlreadyExistsError("").message());
+ EXPECT_EQ("foo", util::AlreadyExistsError("foo").message());
+ EXPECT_EQ("bar", util::AlreadyExistsError("bar").message());
+
+ EXPECT_EQ(util::StatusCode::kPermissionDenied,
+ util::PermissionDeniedError("").code());
+ EXPECT_EQ("", util::PermissionDeniedError("").message());
+ EXPECT_EQ("foo", util::PermissionDeniedError("foo").message());
+ EXPECT_EQ("bar", util::PermissionDeniedError("bar").message());
+
+ EXPECT_EQ(util::StatusCode::kUnauthenticated,
+ util::UnauthenticatedError("").code());
+ EXPECT_EQ("", util::UnauthenticatedError("").message());
+ EXPECT_EQ("foo", util::UnauthenticatedError("foo").message());
+ EXPECT_EQ("bar", util::UnauthenticatedError("bar").message());
+
+ EXPECT_EQ(util::StatusCode::kResourceExhausted,
+ util::ResourceExhaustedError("").code());
+ EXPECT_EQ("", util::ResourceExhaustedError("").message());
+ EXPECT_EQ("foo", util::ResourceExhaustedError("foo").message());
+ EXPECT_EQ("bar", util::ResourceExhaustedError("bar").message());
+
+ EXPECT_EQ(util::StatusCode::kFailedPrecondition,
+ util::FailedPreconditionError("").code());
+ EXPECT_EQ("", util::FailedPreconditionError("").message());
+ EXPECT_EQ("foo", util::FailedPreconditionError("foo").message());
+ EXPECT_EQ("bar", util::FailedPreconditionError("bar").message());
+
+ EXPECT_EQ(util::StatusCode::kAborted, util::AbortedError("").code());
+ EXPECT_EQ("", util::AbortedError("").message());
+ EXPECT_EQ("foo", util::AbortedError("foo").message());
+ EXPECT_EQ("bar", util::AbortedError("bar").message());
+
+ EXPECT_EQ(util::StatusCode::kOutOfRange, util::OutOfRangeError("").code());
+ EXPECT_EQ("", util::OutOfRangeError("").message());
+ EXPECT_EQ("foo", util::OutOfRangeError("foo").message());
+ EXPECT_EQ("bar", util::OutOfRangeError("bar").message());
+
+ EXPECT_EQ(util::StatusCode::kUnimplemented,
+ util::UnimplementedError("").code());
+ EXPECT_EQ("", util::UnimplementedError("").message());
+ EXPECT_EQ("foo", util::UnimplementedError("foo").message());
+ EXPECT_EQ("bar", util::UnimplementedError("bar").message());
+
+ EXPECT_EQ(util::StatusCode::kInternal, util::InternalError("").code());
+ EXPECT_EQ("", util::InternalError("").message());
+ EXPECT_EQ("foo", util::InternalError("foo").message());
+ EXPECT_EQ("bar", util::InternalError("bar").message());
+
+ EXPECT_EQ(util::StatusCode::kUnavailable, util::UnavailableError("").code());
+ EXPECT_EQ("", util::UnavailableError("").message());
+ EXPECT_EQ("foo", util::UnavailableError("foo").message());
+ EXPECT_EQ("bar", util::UnavailableError("bar").message());
+
+ EXPECT_EQ(util::StatusCode::kDataLoss, util::DataLossError("").code());
+ EXPECT_EQ("", util::DataLossError("").message());
+ EXPECT_EQ("foo", util::DataLossError("foo").message());
+ EXPECT_EQ("bar", util::DataLossError("bar").message());
+}
+
+TEST(Status, ConvenienceTests) {
+ EXPECT_TRUE(util::OkStatus().ok());
+ EXPECT_TRUE(util::IsCancelled(util::CancelledError("")));
+ EXPECT_TRUE(util::IsUnknown(util::UnknownError("")));
+ EXPECT_TRUE(util::IsInvalidArgument(util::InvalidArgumentError("")));
+ EXPECT_TRUE(util::IsDeadlineExceeded(util::DeadlineExceededError("")));
+ EXPECT_TRUE(util::IsNotFound(util::NotFoundError("")));
+ EXPECT_TRUE(util::IsAlreadyExists(util::AlreadyExistsError("")));
+ EXPECT_TRUE(util::IsPermissionDenied(util::PermissionDeniedError("")));
+ EXPECT_TRUE(util::IsUnauthenticated(util::UnauthenticatedError("")));
+ EXPECT_TRUE(util::IsResourceExhausted(util::ResourceExhaustedError("")));
+ EXPECT_TRUE(util::IsFailedPrecondition(util::FailedPreconditionError("")));
+ EXPECT_TRUE(util::IsAborted(util::AbortedError("")));
+ EXPECT_TRUE(util::IsOutOfRange(util::OutOfRangeError("")));
+ EXPECT_TRUE(util::IsUnimplemented(util::UnimplementedError("")));
+ EXPECT_TRUE(util::IsInternal(util::InternalError("")));
+ EXPECT_TRUE(util::IsUnavailable(util::UnavailableError("")));
+ EXPECT_TRUE(util::IsDataLoss(util::DataLossError("")));
+}
+
+TEST(Status, Empty) {
+ util::Status status;
+ EXPECT_TRUE(status.ok());
+ EXPECT_EQ(util::OkStatus(), status);
+ EXPECT_EQ(util::StatusCode::kOk, status.code());
+ EXPECT_EQ("OK", status.ToString());
+}
+
+TEST(Status, CheckOK) {
+ util::Status status;
+ GOOGLE_CHECK_OK(status);
+ GOOGLE_CHECK_OK(status) << "Failed";
+ GOOGLE_DCHECK_OK(status) << "Failed";
+}
+
+TEST(Status, ErrorMessage) {
+ util::Status status = util::InvalidArgumentError("");
+ EXPECT_FALSE(status.ok());
+ EXPECT_EQ("", status.message().ToString());
+ EXPECT_EQ("INVALID_ARGUMENT", status.ToString());
+ status = util::InvalidArgumentError("msg");
+ EXPECT_FALSE(status.ok());
+ EXPECT_EQ("msg", status.message().ToString());
+ EXPECT_EQ("INVALID_ARGUMENT:msg", status.ToString());
+ status = util::Status(util::StatusCode::kOk, "msg");
+ EXPECT_TRUE(status.ok());
+ EXPECT_EQ("", status.message().ToString());
+ EXPECT_EQ("OK", status.ToString());
+}
+
+TEST(Status, Copy) {
+ util::Status a = util::UnknownError("message");
+ util::Status b(a);
+ ASSERT_EQ(a.ToString(), b.ToString());
+}
+
+TEST(Status, Assign) {
+ util::Status a = util::UnknownError("message");
+ util::Status b;
+ b = a;
+ ASSERT_EQ(a.ToString(), b.ToString());
+}
+
+TEST(Status, AssignEmpty) {
+ util::Status a = util::UnknownError("message");
+ util::Status b;
+ a = b;
+ ASSERT_EQ(std::string("OK"), a.ToString());
+ ASSERT_TRUE(b.ok());
+ ASSERT_TRUE(a.ok());
+}
+
+TEST(Status, EqualsOK) { ASSERT_EQ(util::OkStatus(), util::Status()); }
+
+TEST(Status, EqualsSame) {
+ const util::Status a = util::CancelledError("message");
+ const util::Status b = util::CancelledError("message");
+ ASSERT_EQ(a, b);
+}
+
+TEST(Status, EqualsCopy) {
+ const util::Status a = util::CancelledError("message");
+ const util::Status b = a;
+ ASSERT_EQ(a, b);
+}
+
+TEST(Status, EqualsDifferentCode) {
+ const util::Status a = util::CancelledError("message");
+ const util::Status b = util::UnknownError("message");
+ ASSERT_NE(a, b);
+}
+
+TEST(Status, EqualsDifferentMessage) {
+ const util::Status a = util::CancelledError("message");
+ const util::Status b = util::CancelledError("another");
+ ASSERT_NE(a, b);
+}
+
+} // namespace
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/stubs/statusor.cc b/NorthstarDedicatedTest/include/protobuf/stubs/statusor.cc
new file mode 100644
index 00000000..cdc3faef
--- /dev/null
+++ b/NorthstarDedicatedTest/include/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 <stubs/statusor.h>
+
+#include <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/NorthstarDedicatedTest/include/protobuf/stubs/statusor.h b/NorthstarDedicatedTest/include/protobuf/stubs/statusor.h
new file mode 100644
index 00000000..55aa4f73
--- /dev/null
+++ b/NorthstarDedicatedTest/include/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 <stubs/status.h>
+
+#include <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 <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_STUBS_STATUSOR_H_
diff --git a/NorthstarDedicatedTest/include/protobuf/stubs/statusor_test.cc b/NorthstarDedicatedTest/include/protobuf/stubs/statusor_test.cc
new file mode 100644
index 00000000..741afd67
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/stubs/statusor_test.cc
@@ -0,0 +1,272 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 <stubs/statusor.h>
+
+#include <errno.h>
+#include <memory>
+
+#include <testing/googletest.h>
+#include <gtest/gtest.h>
+
+namespace google {
+namespace protobuf {
+namespace util {
+namespace {
+
+class Base1 {
+ public:
+ virtual ~Base1() {}
+ int pad;
+};
+
+class Base2 {
+ public:
+ virtual ~Base2() {}
+ int yetotherpad;
+};
+
+class Derived : public Base1, public Base2 {
+ public:
+ virtual ~Derived() {}
+ int evenmorepad;
+};
+
+class CopyNoAssign {
+ public:
+ explicit CopyNoAssign(int value) : foo(value) {}
+ CopyNoAssign(const CopyNoAssign& other) : foo(other.foo) {}
+ int foo;
+ private:
+ const CopyNoAssign& operator=(const CopyNoAssign&);
+};
+
+TEST(StatusOr, TestDefaultCtor) {
+ StatusOr<int> thing;
+ EXPECT_FALSE(thing.ok());
+ EXPECT_EQ(util::UnknownError(""), thing.status());
+}
+
+TEST(StatusOr, TestStatusCtor) {
+ StatusOr<int> thing(util::CancelledError(""));
+ EXPECT_FALSE(thing.ok());
+ EXPECT_EQ(util::CancelledError(""), thing.status());
+}
+
+TEST(StatusOr, TestValueCtor) {
+ const int kI = 4;
+ StatusOr<int> thing(kI);
+ EXPECT_TRUE(thing.ok());
+ EXPECT_EQ(kI, thing.value());
+}
+
+TEST(StatusOr, TestCopyCtorStatusOk) {
+ const int kI = 4;
+ StatusOr<int> original(kI);
+ StatusOr<int> copy(original);
+ EXPECT_EQ(original.status(), copy.status());
+ EXPECT_EQ(original.value(), copy.value());
+}
+
+TEST(StatusOr, TestCopyCtorStatusNotOk) {
+ StatusOr<int> original(util::CancelledError(""));
+ StatusOr<int> copy(original);
+ EXPECT_EQ(original.status(), copy.status());
+}
+
+TEST(StatusOr, TestCopyCtorStatusOKConverting) {
+ const int kI = 4;
+ StatusOr<int> original(kI);
+ StatusOr<double> copy(original);
+ EXPECT_EQ(original.status(), copy.status());
+ EXPECT_EQ(original.value(), copy.value());
+}
+
+TEST(StatusOr, TestCopyCtorStatusNotOkConverting) {
+ StatusOr<int> original(util::CancelledError(""));
+ StatusOr<double> copy(original);
+ EXPECT_EQ(original.status(), copy.status());
+}
+
+TEST(StatusOr, TestAssignmentStatusOk) {
+ const int kI = 4;
+ StatusOr<int> source(kI);
+ StatusOr<int> target;
+ target = source;
+ EXPECT_EQ(source.status(), target.status());
+ EXPECT_EQ(source.value(), target.value());
+}
+
+TEST(StatusOr, TestAssignmentStatusNotOk) {
+ StatusOr<int> source(util::CancelledError(""));
+ StatusOr<int> target;
+ target = source;
+ EXPECT_EQ(source.status(), target.status());
+}
+
+TEST(StatusOr, TestAssignmentStatusOKConverting) {
+ const int kI = 4;
+ StatusOr<int> source(kI);
+ StatusOr<double> target;
+ target = source;
+ EXPECT_EQ(source.status(), target.status());
+ EXPECT_DOUBLE_EQ(source.value(), target.value());
+}
+
+TEST(StatusOr, TestAssignmentStatusNotOkConverting) {
+ StatusOr<int> source(util::CancelledError(""));
+ StatusOr<double> target;
+ target = source;
+ EXPECT_EQ(source.status(), target.status());
+}
+
+TEST(StatusOr, TestStatus) {
+ StatusOr<int> good(4);
+ EXPECT_TRUE(good.ok());
+ StatusOr<int> bad(util::CancelledError(""));
+ EXPECT_FALSE(bad.ok());
+ EXPECT_EQ(util::CancelledError(""), bad.status());
+}
+
+TEST(StatusOr, TestValue) {
+ const int kI = 4;
+ StatusOr<int> thing(kI);
+ EXPECT_EQ(kI, thing.value());
+}
+
+TEST(StatusOr, TestValueConst) {
+ const int kI = 4;
+ const StatusOr<int> thing(kI);
+ EXPECT_EQ(kI, thing.value());
+}
+
+TEST(StatusOr, TestPointerDefaultCtor) {
+ StatusOr<int*> thing;
+ EXPECT_FALSE(thing.ok());
+ EXPECT_EQ(util::UnknownError(""), thing.status());
+}
+
+TEST(StatusOr, TestPointerStatusCtor) {
+ StatusOr<int*> thing(util::CancelledError(""));
+ EXPECT_FALSE(thing.ok());
+ EXPECT_EQ(util::CancelledError(""), thing.status());
+}
+
+TEST(StatusOr, TestPointerValueCtor) {
+ const int kI = 4;
+ StatusOr<const int*> thing(&kI);
+ EXPECT_TRUE(thing.ok());
+ EXPECT_EQ(&kI, thing.value());
+}
+
+TEST(StatusOr, TestPointerCopyCtorStatusOk) {
+ const int kI = 0;
+ StatusOr<const int*> original(&kI);
+ StatusOr<const int*> copy(original);
+ EXPECT_EQ(original.status(), copy.status());
+ EXPECT_EQ(original.value(), copy.value());
+}
+
+TEST(StatusOr, TestPointerCopyCtorStatusNotOk) {
+ StatusOr<int*> original(util::CancelledError(""));
+ StatusOr<int*> copy(original);
+ EXPECT_EQ(original.status(), copy.status());
+}
+
+TEST(StatusOr, TestPointerCopyCtorStatusOKConverting) {
+ Derived derived;
+ StatusOr<Derived*> original(&derived);
+ StatusOr<Base2*> copy(original);
+ EXPECT_EQ(original.status(), copy.status());
+ EXPECT_EQ(static_cast<const Base2*>(original.value()), copy.value());
+}
+
+TEST(StatusOr, TestPointerCopyCtorStatusNotOkConverting) {
+ StatusOr<Derived*> original(util::CancelledError(""));
+ StatusOr<Base2*> copy(original);
+ EXPECT_EQ(original.status(), copy.status());
+}
+
+TEST(StatusOr, TestPointerAssignmentStatusOk) {
+ const int kI = 0;
+ StatusOr<const int*> source(&kI);
+ StatusOr<const int*> target;
+ target = source;
+ EXPECT_EQ(source.status(), target.status());
+ EXPECT_EQ(source.value(), target.value());
+}
+
+TEST(StatusOr, TestPointerAssignmentStatusNotOk) {
+ StatusOr<int*> source(util::CancelledError(""));
+ StatusOr<int*> target;
+ target = source;
+ EXPECT_EQ(source.status(), target.status());
+}
+
+TEST(StatusOr, TestPointerAssignmentStatusOKConverting) {
+ Derived derived;
+ StatusOr<Derived*> source(&derived);
+ StatusOr<Base2*> target;
+ target = source;
+ EXPECT_EQ(source.status(), target.status());
+ EXPECT_EQ(static_cast<const Base2*>(source.value()), target.value());
+}
+
+TEST(StatusOr, TestPointerAssignmentStatusNotOkConverting) {
+ StatusOr<Derived*> source(util::CancelledError(""));
+ StatusOr<Base2*> target;
+ target = source;
+ EXPECT_EQ(source.status(), target.status());
+}
+
+TEST(StatusOr, TestPointerStatus) {
+ const int kI = 0;
+ StatusOr<const int*> good(&kI);
+ EXPECT_TRUE(good.ok());
+ StatusOr<const int*> bad(util::CancelledError(""));
+ EXPECT_EQ(util::CancelledError(""), bad.status());
+}
+
+TEST(StatusOr, TestPointerValue) {
+ const int kI = 0;
+ StatusOr<const int*> thing(&kI);
+ EXPECT_EQ(&kI, thing.value());
+}
+
+TEST(StatusOr, TestPointerValueConst) {
+ const int kI = 0;
+ const StatusOr<const int*> thing(&kI);
+ EXPECT_EQ(&kI, thing.value());
+}
+
+} // namespace
+} // namespace util
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/stubs/stl_util.h b/NorthstarDedicatedTest/include/protobuf/stubs/stl_util.h
new file mode 100644
index 00000000..c1904d01
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/stubs/stl_util.h
@@ -0,0 +1,85 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// from google3/util/gtl/stl_util.h
+
+#ifndef GOOGLE_PROTOBUF_STUBS_STL_UTIL_H__
+#define GOOGLE_PROTOBUF_STUBS_STL_UTIL_H__
+
+#include <stubs/common.h>
+
+#include <algorithm>
+
+namespace google {
+namespace protobuf {
+
+// Inside Google, this function implements a horrible, disgusting hack in which
+// we reach into the string's private implementation and resize it without
+// initializing the new bytes. In some cases doing this can significantly
+// improve performance. However, since it's totally non-portable it has no
+// place in open source code. Feel free to fill this function in with your
+// own disgusting hack if you want the perf boost.
+inline void STLStringResizeUninitialized(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(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
+
+#endif // GOOGLE_PROTOBUF_STUBS_STL_UTIL_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/stubs/stringpiece.cc b/NorthstarDedicatedTest/include/protobuf/stubs/stringpiece.cc
new file mode 100644
index 00000000..1da6d171
--- /dev/null
+++ b/NorthstarDedicatedTest/include/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 <stubs/stringpiece.h>
+
+#include <string.h>
+#include <algorithm>
+#include <climits>
+#include <string>
+#include <ostream>
+
+#include <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/NorthstarDedicatedTest/include/protobuf/stubs/stringpiece.h b/NorthstarDedicatedTest/include/protobuf/stubs/stringpiece.h
new file mode 100644
index 00000000..c5137aaa
--- /dev/null
+++ b/NorthstarDedicatedTest/include/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 <stubs/hash.h>
+
+#include <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 <port_undef.inc>
+
+#endif // STRINGS_STRINGPIECE_H_
diff --git a/NorthstarDedicatedTest/include/protobuf/stubs/stringpiece_unittest.cc b/NorthstarDedicatedTest/include/protobuf/stubs/stringpiece_unittest.cc
new file mode 100644
index 00000000..60c410c3
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/stubs/stringpiece_unittest.cc
@@ -0,0 +1,695 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 <stubs/stringpiece.h>
+
+#include <iterator>
+#include <map>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include <testing/googletest.h>
+#include <stubs/hash.h>
+#include <gtest/gtest.h>
+
+namespace google {
+namespace protobuf {
+namespace {
+TEST(StringPiece, Ctor) {
+ {
+ // Null.
+ StringPiece s10;
+ EXPECT_TRUE(s10.data() == nullptr);
+ EXPECT_EQ(0, s10.length());
+ }
+
+ {
+ // const char* without length.
+ const char* hello = "hello";
+ StringPiece s20(hello);
+ EXPECT_TRUE(s20.data() == hello);
+ EXPECT_EQ(5, s20.length());
+
+ // const char* with length.
+ StringPiece s21(hello, 4);
+ EXPECT_TRUE(s21.data() == hello);
+ EXPECT_EQ(4, s21.length());
+
+ // Not recommended, but valid C++
+ StringPiece s22(hello, 6);
+ EXPECT_TRUE(s22.data() == hello);
+ EXPECT_EQ(6, s22.length());
+ }
+
+ {
+ // std::string.
+ std::string hola = "hola";
+ StringPiece s30(hola);
+ EXPECT_TRUE(s30.data() == hola.data());
+ EXPECT_EQ(4, s30.length());
+
+ // std::string with embedded '\0'.
+ hola.push_back('\0');
+ hola.append("h2");
+ hola.push_back('\0');
+ StringPiece s31(hola);
+ EXPECT_TRUE(s31.data() == hola.data());
+ EXPECT_EQ(8, s31.length());
+ }
+
+#if defined(HAS_GLOBAL_STRING)
+ {
+ // ::string
+ std::string bonjour = "bonjour";
+ StringPiece s40(bonjour);
+ EXPECT_TRUE(s40.data() == bonjour.data());
+ EXPECT_EQ(7, s40.length());
+ }
+#endif
+
+ // TODO(mec): StringPiece(StringPiece x, int pos);
+ // TODO(mec): StringPiece(StringPiece x, int pos, int len);
+ // TODO(mec): StringPiece(const StringPiece&);
+}
+
+TEST(StringPiece, STLComparator) {
+ std::string s1("foo");
+ std::string s2("bar");
+ std::string s3("baz");
+
+ StringPiece p1(s1);
+ StringPiece p2(s2);
+ StringPiece p3(s3);
+
+ typedef std::map<StringPiece, int> TestMap;
+ TestMap map;
+
+ map.insert(std::make_pair(p1, 0));
+ map.insert(std::make_pair(p2, 1));
+ map.insert(std::make_pair(p3, 2));
+ EXPECT_EQ(map.size(), 3);
+
+ TestMap::const_iterator iter = map.begin();
+ EXPECT_EQ(iter->second, 1);
+ ++iter;
+ EXPECT_EQ(iter->second, 2);
+ ++iter;
+ EXPECT_EQ(iter->second, 0);
+ ++iter;
+ EXPECT_TRUE(iter == map.end());
+
+ TestMap::iterator new_iter = map.find("zot");
+ EXPECT_TRUE(new_iter == map.end());
+
+ new_iter = map.find("bar");
+ EXPECT_TRUE(new_iter != map.end());
+
+ map.erase(new_iter);
+ EXPECT_EQ(map.size(), 2);
+
+ iter = map.begin();
+ EXPECT_EQ(iter->second, 2);
+ ++iter;
+ EXPECT_EQ(iter->second, 0);
+ ++iter;
+ EXPECT_TRUE(iter == map.end());
+}
+
+TEST(StringPiece, ComparisonOperators) {
+#define COMPARE(result, op, x, y) \
+ EXPECT_EQ(result, StringPiece((x)) op StringPiece((y))); \
+ EXPECT_EQ(result, StringPiece((x)).compare(StringPiece((y))) op 0)
+
+ COMPARE(true, ==, "", "");
+ COMPARE(true, ==, "", nullptr);
+ COMPARE(true, ==, nullptr, "");
+ COMPARE(true, ==, "a", "a");
+ COMPARE(true, ==, "aa", "aa");
+ COMPARE(false, ==, "a", "");
+ COMPARE(false, ==, "", "a");
+ COMPARE(false, ==, "a", "b");
+ COMPARE(false, ==, "a", "aa");
+ COMPARE(false, ==, "aa", "a");
+
+ COMPARE(false, !=, "", "");
+ COMPARE(false, !=, "a", "a");
+ COMPARE(false, !=, "aa", "aa");
+ COMPARE(true, !=, "a", "");
+ COMPARE(true, !=, "", "a");
+ COMPARE(true, !=, "a", "b");
+ COMPARE(true, !=, "a", "aa");
+ COMPARE(true, !=, "aa", "a");
+
+ COMPARE(true, <, "a", "b");
+ COMPARE(true, <, "a", "aa");
+ COMPARE(true, <, "aa", "b");
+ COMPARE(true, <, "aa", "bb");
+ COMPARE(false, <, "a", "a");
+ COMPARE(false, <, "b", "a");
+ COMPARE(false, <, "aa", "a");
+ COMPARE(false, <, "b", "aa");
+ COMPARE(false, <, "bb", "aa");
+
+ COMPARE(true, <=, "a", "a");
+ COMPARE(true, <=, "a", "b");
+ COMPARE(true, <=, "a", "aa");
+ COMPARE(true, <=, "aa", "b");
+ COMPARE(true, <=, "aa", "bb");
+ COMPARE(false, <=, "b", "a");
+ COMPARE(false, <=, "aa", "a");
+ COMPARE(false, <=, "b", "aa");
+ COMPARE(false, <=, "bb", "aa");
+
+ COMPARE(false, >=, "a", "b");
+ COMPARE(false, >=, "a", "aa");
+ COMPARE(false, >=, "aa", "b");
+ COMPARE(false, >=, "aa", "bb");
+ COMPARE(true, >=, "a", "a");
+ COMPARE(true, >=, "b", "a");
+ COMPARE(true, >=, "aa", "a");
+ COMPARE(true, >=, "b", "aa");
+ COMPARE(true, >=, "bb", "aa");
+
+ COMPARE(false, >, "a", "a");
+ COMPARE(false, >, "a", "b");
+ COMPARE(false, >, "a", "aa");
+ COMPARE(false, >, "aa", "b");
+ COMPARE(false, >, "aa", "bb");
+ COMPARE(true, >, "b", "a");
+ COMPARE(true, >, "aa", "a");
+ COMPARE(true, >, "b", "aa");
+ COMPARE(true, >, "bb", "aa");
+
+ std::string x;
+ for (int i = 0; i < 256; i++) {
+ x += 'a';
+ std::string y = x;
+ COMPARE(true, ==, x, y);
+ for (int j = 0; j < i; j++) {
+ std::string z = x;
+ z[j] = 'b'; // Differs in position 'j'
+ COMPARE(false, ==, x, z);
+ COMPARE(true, <, x, z);
+ COMPARE(true, >, z, x);
+ if (j + 1 < i) {
+ z[j + 1] = 'A'; // Differs in position 'j+1' as well
+ COMPARE(false, ==, x, z);
+ COMPARE(true, <, x, z);
+ COMPARE(true, >, z, x);
+ z[j + 1] = 'z'; // Differs in position 'j+1' as well
+ COMPARE(false, ==, x, z);
+ COMPARE(true, <, x, z);
+ COMPARE(true, >, z, x);
+ }
+ }
+ }
+
+#undef COMPARE
+}
+
+TEST(StringPiece, STL1) {
+ const StringPiece a("abcdefghijklmnopqrstuvwxyz");
+ const StringPiece b("abc");
+ const StringPiece c("xyz");
+ const StringPiece d("foobar");
+ const StringPiece e;
+ std::string temp("123");
+ temp += '\0';
+ temp += "456";
+ const StringPiece f(temp);
+
+ EXPECT_EQ(a[6], 'g');
+ EXPECT_EQ(b[0], 'a');
+ EXPECT_EQ(c[2], 'z');
+ EXPECT_EQ(f[3], '\0');
+ EXPECT_EQ(f[5], '5');
+
+ EXPECT_EQ(*d.data(), 'f');
+ EXPECT_EQ(d.data()[5], 'r');
+ EXPECT_TRUE(e.data() == nullptr);
+
+ EXPECT_EQ(*a.begin(), 'a');
+ EXPECT_EQ(*(b.begin() + 2), 'c');
+ EXPECT_EQ(*(c.end() - 1), 'z');
+
+ EXPECT_EQ(*a.rbegin(), 'z');
+ EXPECT_EQ(*(b.rbegin() + 2), 'a');
+ EXPECT_EQ(*(c.rend() - 1), 'x');
+ EXPECT_TRUE(a.rbegin() + 26 == a.rend());
+
+ EXPECT_EQ(a.size(), 26);
+ EXPECT_EQ(b.size(), 3);
+ EXPECT_EQ(c.size(), 3);
+ EXPECT_EQ(d.size(), 6);
+ EXPECT_EQ(e.size(), 0);
+ EXPECT_EQ(f.size(), 7);
+
+ EXPECT_TRUE(!d.empty());
+ EXPECT_TRUE(d.begin() != d.end());
+ EXPECT_TRUE(d.begin() + 6 == d.end());
+
+ EXPECT_TRUE(e.empty());
+ EXPECT_TRUE(e.begin() == e.end());
+
+ EXPECT_GE(a.max_size(), a.capacity());
+ EXPECT_GE(a.capacity(), a.size());
+
+ char buf[4] = { '%', '%', '%', '%' };
+ EXPECT_EQ(a.copy(buf, 4), 4);
+ EXPECT_EQ(buf[0], a[0]);
+ EXPECT_EQ(buf[1], a[1]);
+ EXPECT_EQ(buf[2], a[2]);
+ EXPECT_EQ(buf[3], a[3]);
+ EXPECT_EQ(a.copy(buf, 3, 7), 3);
+ EXPECT_EQ(buf[0], a[7]);
+ EXPECT_EQ(buf[1], a[8]);
+ EXPECT_EQ(buf[2], a[9]);
+ EXPECT_EQ(buf[3], a[3]);
+ EXPECT_EQ(c.copy(buf, 99), 3);
+ EXPECT_EQ(buf[0], c[0]);
+ EXPECT_EQ(buf[1], c[1]);
+ EXPECT_EQ(buf[2], c[2]);
+ EXPECT_EQ(buf[3], a[3]);
+}
+
+// Separated from STL1() because some compilers produce an overly
+// large stack frame for the combined function.
+TEST(StringPiece, STL2) {
+ const StringPiece a("abcdefghijklmnopqrstuvwxyz");
+ const StringPiece b("abc");
+ const StringPiece c("xyz");
+ const StringPiece e;
+ const StringPiece f("123" "\0" "456", 7);
+
+ EXPECT_EQ(StringPiece::npos, std::string::npos);
+
+ EXPECT_EQ(a.find(b), 0);
+ EXPECT_EQ(a.find(b, 1), StringPiece::npos);
+ EXPECT_EQ(a.find(c), 23);
+ EXPECT_EQ(a.find(c, 9), 23);
+ EXPECT_EQ(a.find(c, StringPiece::npos), StringPiece::npos);
+ EXPECT_EQ(b.find(c), StringPiece::npos);
+ EXPECT_EQ(b.find(c, StringPiece::npos), StringPiece::npos);
+ EXPECT_EQ(a.find(e), 0);
+ EXPECT_EQ(a.find(e, 17), 17);
+ StringPiece g("xx not found bb");
+ EXPECT_EQ(a.find(g), StringPiece::npos);
+ // empty string nonsense
+ EXPECT_EQ(e.find(b), StringPiece::npos);
+ EXPECT_EQ(e.find(b, 7), StringPiece::npos);
+
+ size_t empty_search_pos = std::string().find(std::string());
+ EXPECT_EQ(e.find(e), empty_search_pos);
+ EXPECT_EQ(e.find(e, 4), std::string().find(std::string(), 4));
+
+ EXPECT_EQ(a.find('a'), 0);
+ EXPECT_EQ(a.find('c'), 2);
+ EXPECT_EQ(a.find('z'), 25);
+ EXPECT_EQ(a.find('$'), StringPiece::npos);
+ EXPECT_EQ(a.find('\0'), StringPiece::npos);
+ EXPECT_EQ(f.find('\0'), 3);
+ EXPECT_EQ(f.find('3'), 2);
+ EXPECT_EQ(f.find('5'), 5);
+ EXPECT_EQ(g.find('o'), 4);
+ EXPECT_EQ(g.find('o', 4), 4);
+ EXPECT_EQ(g.find('o', 5), 8);
+ EXPECT_EQ(a.find('b', 5), StringPiece::npos);
+ // empty string nonsense
+ EXPECT_EQ(e.find('\0'), StringPiece::npos);
+ EXPECT_EQ(e.find('\0', 7), StringPiece::npos);
+ EXPECT_EQ(e.find('x'), StringPiece::npos);
+ EXPECT_EQ(e.find('x', 7), StringPiece::npos);
+
+ EXPECT_EQ(a.rfind(b), 0);
+ EXPECT_EQ(a.rfind(b, 1), 0);
+ EXPECT_EQ(a.rfind(c), 23);
+ EXPECT_EQ(a.rfind(c, 22), StringPiece::npos);
+ EXPECT_EQ(a.rfind(c, 1), StringPiece::npos);
+ EXPECT_EQ(a.rfind(c, 0), StringPiece::npos);
+ EXPECT_EQ(b.rfind(c), StringPiece::npos);
+ EXPECT_EQ(b.rfind(c, 0), StringPiece::npos);
+ EXPECT_EQ(a.rfind(e), a.as_string().rfind(std::string()));
+ EXPECT_EQ(a.rfind(e, 17), 17);
+ EXPECT_EQ(a.rfind(g), StringPiece::npos);
+ EXPECT_EQ(e.rfind(b), StringPiece::npos);
+ EXPECT_EQ(e.rfind(b, 7), StringPiece::npos);
+ // empty string nonsense
+ EXPECT_EQ(e.rfind(e, 7), std::string().rfind(std::string()));
+ EXPECT_EQ(e.rfind(e), std::string().rfind(std::string()));
+
+ EXPECT_EQ(g.rfind('o'), 8);
+ EXPECT_EQ(g.rfind('q'), StringPiece::npos);
+ EXPECT_EQ(g.rfind('o', 8), 8);
+ EXPECT_EQ(g.rfind('o', 7), 4);
+ EXPECT_EQ(g.rfind('o', 3), StringPiece::npos);
+ EXPECT_EQ(f.rfind('\0'), 3);
+ EXPECT_EQ(f.rfind('\0', 12), 3);
+ EXPECT_EQ(f.rfind('3'), 2);
+ EXPECT_EQ(f.rfind('5'), 5);
+ // empty string nonsense
+ EXPECT_EQ(e.rfind('o'), StringPiece::npos);
+ EXPECT_EQ(e.rfind('o', 7), StringPiece::npos);
+
+ EXPECT_EQ(a.find_first_of(b), 0);
+ EXPECT_EQ(a.find_first_of(b, 0), 0);
+ EXPECT_EQ(a.find_first_of(b, 1), 1);
+ EXPECT_EQ(a.find_first_of(b, 2), 2);
+ EXPECT_EQ(a.find_first_of(b, 3), StringPiece::npos);
+ EXPECT_EQ(a.find_first_of(c), 23);
+ EXPECT_EQ(a.find_first_of(c, 23), 23);
+ EXPECT_EQ(a.find_first_of(c, 24), 24);
+ EXPECT_EQ(a.find_first_of(c, 25), 25);
+ EXPECT_EQ(a.find_first_of(c, 26), StringPiece::npos);
+ EXPECT_EQ(g.find_first_of(b), 13);
+ EXPECT_EQ(g.find_first_of(c), 0);
+ EXPECT_EQ(a.find_first_of(f), StringPiece::npos);
+ EXPECT_EQ(f.find_first_of(a), StringPiece::npos);
+ // empty string nonsense
+ EXPECT_EQ(a.find_first_of(e), StringPiece::npos);
+ EXPECT_EQ(e.find_first_of(b), StringPiece::npos);
+ EXPECT_EQ(e.find_first_of(e), StringPiece::npos);
+
+ EXPECT_EQ(a.find_first_not_of(b), 3);
+ EXPECT_EQ(a.find_first_not_of(c), 0);
+ EXPECT_EQ(b.find_first_not_of(a), StringPiece::npos);
+ EXPECT_EQ(c.find_first_not_of(a), StringPiece::npos);
+ EXPECT_EQ(f.find_first_not_of(a), 0);
+ EXPECT_EQ(a.find_first_not_of(f), 0);
+ EXPECT_EQ(a.find_first_not_of(e), 0);
+ // empty string nonsense
+ EXPECT_EQ(e.find_first_not_of(a), StringPiece::npos);
+ EXPECT_EQ(e.find_first_not_of(e), StringPiece::npos);
+
+ StringPiece h("====");
+ EXPECT_EQ(h.find_first_not_of('='), StringPiece::npos);
+ EXPECT_EQ(h.find_first_not_of('=', 3), StringPiece::npos);
+ EXPECT_EQ(h.find_first_not_of('\0'), 0);
+ EXPECT_EQ(g.find_first_not_of('x'), 2);
+ EXPECT_EQ(f.find_first_not_of('\0'), 0);
+ EXPECT_EQ(f.find_first_not_of('\0', 3), 4);
+ EXPECT_EQ(f.find_first_not_of('\0', 2), 2);
+ // empty string nonsense
+ EXPECT_EQ(e.find_first_not_of('x'), StringPiece::npos);
+ EXPECT_EQ(e.find_first_not_of('\0'), StringPiece::npos);
+
+ // StringPiece g("xx not found bb");
+ StringPiece i("56");
+ EXPECT_EQ(h.find_last_of(a), StringPiece::npos);
+ EXPECT_EQ(g.find_last_of(a), g.size()-1);
+ EXPECT_EQ(a.find_last_of(b), 2);
+ EXPECT_EQ(a.find_last_of(c), a.size()-1);
+ EXPECT_EQ(f.find_last_of(i), 6);
+ EXPECT_EQ(a.find_last_of('a'), 0);
+ EXPECT_EQ(a.find_last_of('b'), 1);
+ EXPECT_EQ(a.find_last_of('z'), 25);
+ EXPECT_EQ(a.find_last_of('a', 5), 0);
+ EXPECT_EQ(a.find_last_of('b', 5), 1);
+ EXPECT_EQ(a.find_last_of('b', 0), StringPiece::npos);
+ EXPECT_EQ(a.find_last_of('z', 25), 25);
+ EXPECT_EQ(a.find_last_of('z', 24), StringPiece::npos);
+ EXPECT_EQ(f.find_last_of(i, 5), 5);
+ EXPECT_EQ(f.find_last_of(i, 6), 6);
+ EXPECT_EQ(f.find_last_of(a, 4), StringPiece::npos);
+ // empty string nonsense
+ EXPECT_EQ(f.find_last_of(e), StringPiece::npos);
+ EXPECT_EQ(f.find_last_of(e, 4), StringPiece::npos);
+ EXPECT_EQ(e.find_last_of(e), StringPiece::npos);
+ EXPECT_EQ(e.find_last_of(f), StringPiece::npos);
+ EXPECT_EQ(e.find_last_of(e, 4), StringPiece::npos);
+ EXPECT_EQ(e.find_last_of(f, 4), StringPiece::npos);
+
+ EXPECT_EQ(a.find_last_not_of(b), a.size()-1);
+ EXPECT_EQ(a.find_last_not_of(c), 22);
+ EXPECT_EQ(b.find_last_not_of(a), StringPiece::npos);
+ EXPECT_EQ(b.find_last_not_of(b), StringPiece::npos);
+ EXPECT_EQ(f.find_last_not_of(i), 4);
+ EXPECT_EQ(a.find_last_not_of(c, 24), 22);
+ EXPECT_EQ(a.find_last_not_of(b, 3), 3);
+ EXPECT_EQ(a.find_last_not_of(b, 2), StringPiece::npos);
+ // empty string nonsense
+ EXPECT_EQ(f.find_last_not_of(e), f.size()-1);
+ EXPECT_EQ(f.find_last_not_of(e, 4), 4);
+ EXPECT_EQ(e.find_last_not_of(e), StringPiece::npos);
+ EXPECT_EQ(e.find_last_not_of(f), StringPiece::npos);
+ EXPECT_EQ(e.find_last_not_of(e, 4), StringPiece::npos);
+ EXPECT_EQ(e.find_last_not_of(f, 4), StringPiece::npos);
+
+ EXPECT_EQ(h.find_last_not_of('x'), h.size() - 1);
+ EXPECT_EQ(h.find_last_not_of('='), StringPiece::npos);
+ EXPECT_EQ(b.find_last_not_of('c'), 1);
+ EXPECT_EQ(h.find_last_not_of('x', 2), 2);
+ EXPECT_EQ(h.find_last_not_of('=', 2), StringPiece::npos);
+ EXPECT_EQ(b.find_last_not_of('b', 1), 0);
+ // empty string nonsense
+ EXPECT_EQ(e.find_last_not_of('x'), StringPiece::npos);
+ EXPECT_EQ(e.find_last_not_of('\0'), StringPiece::npos);
+
+ EXPECT_EQ(a.substr(0, 3), b);
+ EXPECT_EQ(a.substr(23), c);
+ EXPECT_EQ(a.substr(23, 3), c);
+ EXPECT_EQ(a.substr(23, 99), c);
+ EXPECT_EQ(a.substr(0), a);
+ EXPECT_EQ(a.substr(3, 2), "de");
+ // empty string nonsense
+ EXPECT_EQ(a.substr(99, 2), e);
+ EXPECT_EQ(e.substr(99), e);
+ EXPECT_EQ(e.substr(0, 99), e);
+ EXPECT_EQ(e.substr(99, 99), e);
+ // use of npos
+ EXPECT_EQ(a.substr(0, StringPiece::npos), a);
+ EXPECT_EQ(a.substr(23, StringPiece::npos), c);
+ EXPECT_EQ(a.substr(StringPiece::npos, 0), e);
+ EXPECT_EQ(a.substr(StringPiece::npos, 1), e);
+ EXPECT_EQ(a.substr(StringPiece::npos, StringPiece::npos), e);
+}
+
+TEST(StringPiece, Custom) {
+ StringPiece a("foobar");
+ std::string s1("123");
+ s1 += '\0';
+ s1 += "456";
+ StringPiece b(s1);
+ StringPiece e;
+ std::string s2;
+
+ // CopyToString
+ a.CopyToString(&s2);
+ EXPECT_EQ(s2.size(), 6);
+ EXPECT_EQ(s2, "foobar");
+ b.CopyToString(&s2);
+ EXPECT_EQ(s2.size(), 7);
+ EXPECT_EQ(s1, s2);
+ e.CopyToString(&s2);
+ EXPECT_TRUE(s2.empty());
+
+ // AppendToString
+ s2.erase();
+ a.AppendToString(&s2);
+ EXPECT_EQ(s2.size(), 6);
+ EXPECT_EQ(s2, "foobar");
+ a.AppendToString(&s2);
+ EXPECT_EQ(s2.size(), 12);
+ EXPECT_EQ(s2, "foobarfoobar");
+
+ // starts_with
+ EXPECT_TRUE(a.starts_with(a));
+ EXPECT_TRUE(a.starts_with("foo"));
+ EXPECT_TRUE(a.starts_with(e));
+ EXPECT_TRUE(b.starts_with(s1));
+ EXPECT_TRUE(b.starts_with(b));
+ EXPECT_TRUE(b.starts_with(e));
+ EXPECT_TRUE(e.starts_with(""));
+ EXPECT_TRUE(!a.starts_with(b));
+ EXPECT_TRUE(!b.starts_with(a));
+ EXPECT_TRUE(!e.starts_with(a));
+
+ // ends with
+ EXPECT_TRUE(a.ends_with(a));
+ EXPECT_TRUE(a.ends_with("bar"));
+ EXPECT_TRUE(a.ends_with(e));
+ EXPECT_TRUE(b.ends_with(s1));
+ EXPECT_TRUE(b.ends_with(b));
+ EXPECT_TRUE(b.ends_with(e));
+ EXPECT_TRUE(e.ends_with(""));
+ EXPECT_TRUE(!a.ends_with(b));
+ EXPECT_TRUE(!b.ends_with(a));
+ EXPECT_TRUE(!e.ends_with(a));
+
+ // remove_prefix
+ StringPiece c(a);
+ c.remove_prefix(3);
+ EXPECT_EQ(c, "bar");
+ c = a;
+ c.remove_prefix(0);
+ EXPECT_EQ(c, a);
+ c.remove_prefix(c.size());
+ EXPECT_EQ(c, e);
+
+ // remove_suffix
+ c = a;
+ c.remove_suffix(3);
+ EXPECT_EQ(c, "foo");
+ c = a;
+ c.remove_suffix(0);
+ EXPECT_EQ(c, a);
+ c.remove_suffix(c.size());
+ EXPECT_EQ(c, e);
+
+ c = StringPiece("foobar", 7);
+
+ // as_string
+ std::string s3(a.as_string().c_str(), 7);
+ EXPECT_EQ(c, s3);
+ std::string s4(e.as_string());
+ EXPECT_TRUE(s4.empty());
+
+ // ToString
+ {
+ std::string s5(a.ToString().c_str(), 7);
+ EXPECT_EQ(c, s5);
+ std::string s6(e.ToString());
+ EXPECT_TRUE(s6.empty());
+ }
+
+ // Consume
+ {
+ StringPiece str("foobar");
+ EXPECT_TRUE(str.Consume("foo"));
+ EXPECT_EQ(str, "bar");
+ EXPECT_FALSE(str.Consume("foo"));
+ EXPECT_FALSE(str.Consume("barbar"));
+ EXPECT_FALSE(str.Consume("ar"));
+ EXPECT_EQ(str, "bar");
+ }
+
+ {
+ StringPiece str("foobar");
+ EXPECT_TRUE(str.ConsumeFromEnd("bar"));
+ EXPECT_EQ(str, "foo");
+ EXPECT_FALSE(str.ConsumeFromEnd("bar"));
+ EXPECT_FALSE(str.ConsumeFromEnd("foofoo"));
+ EXPECT_FALSE(str.ConsumeFromEnd("fo"));
+ EXPECT_EQ(str, "foo");
+ }
+}
+
+TEST(StringPiece, Contains) {
+ StringPiece a("abcdefg");
+ StringPiece b("abcd");
+ StringPiece c("efg");
+ StringPiece d("gh");
+ EXPECT_TRUE(a.contains(b));
+ EXPECT_TRUE(a.contains(c));
+ EXPECT_TRUE(!a.contains(d));
+}
+
+TEST(StringPiece, NullInput) {
+ // we used to crash here, but now we don't.
+ StringPiece s(nullptr);
+ EXPECT_EQ(s.data(), (const char*)nullptr);
+ EXPECT_EQ(s.size(), 0);
+
+ // .ToString() on a StringPiece with nullptr should produce the empty string.
+ EXPECT_EQ("", s.ToString());
+ EXPECT_EQ("", s.as_string());
+}
+
+TEST(StringPiece, Comparisons2) {
+ StringPiece abc("abcdefghijklmnopqrstuvwxyz");
+
+ // check comparison operations on strings longer than 4 bytes.
+ EXPECT_EQ(abc, StringPiece("abcdefghijklmnopqrstuvwxyz"));
+ EXPECT_EQ(abc.compare(StringPiece("abcdefghijklmnopqrstuvwxyz")), 0);
+
+ EXPECT_LT(abc, StringPiece("abcdefghijklmnopqrstuvwxzz"));
+ EXPECT_LT(abc.compare(StringPiece("abcdefghijklmnopqrstuvwxzz")), 0);
+
+ EXPECT_GT(abc, StringPiece("abcdefghijklmnopqrstuvwxyy"));
+ EXPECT_GT(abc.compare(StringPiece("abcdefghijklmnopqrstuvwxyy")), 0);
+
+ // starts_with
+ EXPECT_TRUE(abc.starts_with(abc));
+ EXPECT_TRUE(abc.starts_with("abcdefghijklm"));
+ EXPECT_TRUE(!abc.starts_with("abcdefguvwxyz"));
+
+ // ends_with
+ EXPECT_TRUE(abc.ends_with(abc));
+ EXPECT_TRUE(!abc.ends_with("abcdefguvwxyz"));
+ EXPECT_TRUE(abc.ends_with("nopqrstuvwxyz"));
+}
+
+TEST(ComparisonOpsTest, StringCompareNotAmbiguous) {
+ EXPECT_EQ("hello", std::string("hello"));
+ EXPECT_LT("hello", std::string("world"));
+}
+
+TEST(ComparisonOpsTest, HeterogenousStringPieceEquals) {
+ EXPECT_EQ(StringPiece("hello"), std::string("hello"));
+ EXPECT_EQ("hello", StringPiece("hello"));
+}
+
+TEST(FindOneCharTest, EdgeCases) {
+ StringPiece a("xxyyyxx");
+
+ // Set a = "xyyyx".
+ a.remove_prefix(1);
+ a.remove_suffix(1);
+
+ EXPECT_EQ(0, a.find('x'));
+ EXPECT_EQ(0, a.find('x', 0));
+ EXPECT_EQ(4, a.find('x', 1));
+ EXPECT_EQ(4, a.find('x', 4));
+ EXPECT_EQ(StringPiece::npos, a.find('x', 5));
+
+ EXPECT_EQ(4, a.rfind('x'));
+ EXPECT_EQ(4, a.rfind('x', 5));
+ EXPECT_EQ(4, a.rfind('x', 4));
+ EXPECT_EQ(0, a.rfind('x', 3));
+ EXPECT_EQ(0, a.rfind('x', 0));
+
+ // Set a = "yyy".
+ a.remove_prefix(1);
+ a.remove_suffix(1);
+
+ EXPECT_EQ(StringPiece::npos, a.find('x'));
+ EXPECT_EQ(StringPiece::npos, a.rfind('x'));
+}
+
+#ifdef PROTOBUF_HAS_DEATH_TEST
+#ifndef NDEBUG
+TEST(NonNegativeLenTest, NonNegativeLen) {
+ EXPECT_DEATH(StringPiece("xyz", -1), "string length exceeds max size");
+}
+#endif // ndef DEBUG
+#endif // PROTOBUF_HAS_DEATH_TEST
+
+} // namespace
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/stubs/stringprintf.cc b/NorthstarDedicatedTest/include/protobuf/stubs/stringprintf.cc
new file mode 100644
index 00000000..fce21859
--- /dev/null
+++ b/NorthstarDedicatedTest/include/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 <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 <stubs/common.h>
+#include <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/NorthstarDedicatedTest/include/protobuf/stubs/stringprintf.h b/NorthstarDedicatedTest/include/protobuf/stubs/stringprintf.h
new file mode 100644
index 00000000..d119eb8e
--- /dev/null
+++ b/NorthstarDedicatedTest/include/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 <stubs/common.h>
+
+#include <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 <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_STUBS_STRINGPRINTF_H
diff --git a/NorthstarDedicatedTest/include/protobuf/stubs/stringprintf_unittest.cc b/NorthstarDedicatedTest/include/protobuf/stubs/stringprintf_unittest.cc
new file mode 100644
index 00000000..1736b3d5
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/stubs/stringprintf_unittest.cc
@@ -0,0 +1,155 @@
+// 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_unittest.cc
+
+#include <stubs/stringprintf.h>
+#include <testing/googletest.h>
+#include <gtest/gtest.h>
+
+#include <array>
+#include <cerrno>
+#include <string>
+
+namespace google {
+namespace protobuf {
+namespace {
+
+TEST(StringPrintfTest, Empty) {
+#if 0
+ // gcc 2.95.3, gcc 4.1.0, and gcc 4.2.2 all warn about this:
+ // warning: zero-length printf format string.
+ // so we do not allow them in google3.
+ EXPECT_EQ("", StringPrintf(""));
+#endif
+ EXPECT_EQ("", StringPrintf("%s", std::string().c_str()));
+ EXPECT_EQ("", StringPrintf("%s", ""));
+}
+
+TEST(StringPrintfTest, Misc) {
+// MSVC and mingw does not support $ format specifier.
+#if !defined(_MSC_VER) && !defined(__MINGW32__)
+ EXPECT_EQ("123hello w", StringPrintf("%3$d%2$s %1$c", 'w', "hello", 123));
+#endif // !_MSC_VER
+}
+
+TEST(StringAppendFTest, Empty) {
+ std::string value("Hello");
+ const char* empty = "";
+ StringAppendF(&value, "%s", empty);
+ EXPECT_EQ("Hello", value);
+}
+
+TEST(StringAppendFTest, EmptyString) {
+ std::string value("Hello");
+ StringAppendF(&value, "%s", "");
+ EXPECT_EQ("Hello", value);
+}
+
+TEST(StringAppendFTest, String) {
+ std::string value("Hello");
+ StringAppendF(&value, " %s", "World");
+ EXPECT_EQ("Hello World", value);
+}
+
+TEST(StringAppendFTest, Int) {
+ std::string value("Hello");
+ StringAppendF(&value, " %d", 123);
+ EXPECT_EQ("Hello 123", value);
+}
+
+TEST(StringPrintfTest, Multibyte) {
+ // If we are in multibyte mode and feed invalid multibyte sequence,
+ // StringPrintf should return an empty string instead of running
+ // out of memory while trying to determine destination buffer size.
+ // see b/4194543.
+
+ char* old_locale_c = setlocale(LC_CTYPE, nullptr);
+ ASSERT_TRUE(old_locale_c != nullptr);
+ std::string old_locale = old_locale_c;
+ // Push locale with multibyte mode
+ setlocale(LC_CTYPE, "en_US.utf8");
+
+ const char kInvalidCodePoint[] = "\375\067s";
+ std::string value = StringPrintf("%.*s", 3, kInvalidCodePoint);
+
+ // In some versions of glibc (e.g. eglibc-2.11.1, aka GRTEv2), snprintf
+ // returns error given an invalid codepoint. Other versions
+ // (e.g. eglibc-2.15, aka pre-GRTEv3) emit the codepoint verbatim.
+ // We test that the output is one of the above.
+ EXPECT_TRUE(value.empty() || value == kInvalidCodePoint);
+
+ // Repeat with longer string, to make sure that the dynamically
+ // allocated path in StringAppendV is handled correctly.
+ const size_t n = 2048;
+ std::array<char, n + 1> buf;
+ memset(&buf[0], ' ', n - 3);
+ memcpy(&buf[0] + n - 3, kInvalidCodePoint, 4);
+ value = StringPrintf("%.*s", n, &buf[0]);
+ // See GRTEv2 vs. GRTEv3 comment above.
+ EXPECT_TRUE(value.empty() || value == &buf[0]);
+
+ setlocale(LC_CTYPE, old_locale.c_str());
+}
+
+TEST(StringPrintfTest, NoMultibyte) {
+ // No multibyte handling, but the string contains funny chars.
+ char* old_locale_c = setlocale(LC_CTYPE, nullptr);
+ ASSERT_TRUE(old_locale_c != nullptr);
+ std::string old_locale = old_locale_c;
+ setlocale(LC_CTYPE, "POSIX");
+ std::string value = StringPrintf("%.*s", 3, "\375\067s");
+ setlocale(LC_CTYPE, old_locale.c_str());
+ EXPECT_EQ("\375\067s", value);
+}
+
+TEST(StringPrintfTest, DontOverwriteErrno) {
+ // Check that errno isn't overwritten unless we're printing
+ // something significantly larger than what people are normally
+ // printing in their badly written PLOG() statements.
+ errno = ECHILD;
+ std::string value = StringPrintf("Hello, %s!", "World");
+ EXPECT_EQ(ECHILD, errno);
+}
+
+TEST(StringPrintfTest, LargeBuf) {
+ // Check that the large buffer is handled correctly.
+ int n = 2048;
+ char* buf = new char[n+1];
+ memset(buf, ' ', n);
+ buf[n] = 0;
+ std::string value = StringPrintf("%s", buf);
+ EXPECT_EQ(buf, value);
+ delete[] buf;
+}
+
+} // anonymous namespace
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/stubs/structurally_valid.cc b/NorthstarDedicatedTest/include/protobuf/stubs/structurally_valid.cc
new file mode 100644
index 00000000..09d956d1
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/stubs/structurally_valid.cc
@@ -0,0 +1,615 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: jrm@google.com (Jim Meehan)
+
+#include <stubs/common.h>
+
+#include <stubs/stringpiece.h>
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+// These four-byte entries compactly encode how many bytes 0..255 to delete
+// in making a string replacement, how many bytes to add 0..255, and the offset
+// 0..64k-1 of the replacement string in remap_string.
+struct RemapEntry {
+ uint8 delete_bytes;
+ uint8 add_bytes;
+ uint16 bytes_offset;
+};
+
+// Exit type codes for state tables. All but the first get stuffed into
+// signed one-byte entries. The first is only generated by executable code.
+// To distinguish from next-state entries, these must be contiguous and
+// all <= kExitNone
+typedef enum {
+ kExitDstSpaceFull = 239,
+ kExitIllegalStructure, // 240
+ kExitOK, // 241
+ kExitReject, // ...
+ kExitReplace1,
+ kExitReplace2,
+ kExitReplace3,
+ kExitReplace21,
+ kExitReplace31,
+ kExitReplace32,
+ kExitReplaceOffset1,
+ kExitReplaceOffset2,
+ kExitReplace1S0,
+ kExitSpecial,
+ kExitDoAgain,
+ kExitRejectAlt,
+ kExitNone // 255
+} ExitReason;
+
+
+// This struct represents one entire state table. The three initialized byte
+// areas are state_table, remap_base, and remap_string. state0 and state0_size
+// give the byte offset and length within state_table of the initial state --
+// table lookups are expected to start and end in this state, but for
+// truncated UTF-8 strings, may end in a different state. These allow a quick
+// test for that condition. entry_shift is 8 for tables subscripted by a full
+// byte value and 6 for space-optimized tables subscripted by only six
+// significant bits in UTF-8 continuation bytes.
+typedef struct {
+ const uint32 state0;
+ const uint32 state0_size;
+ const uint32 total_size;
+ const int max_expand;
+ const int entry_shift;
+ const int bytes_per_entry;
+ const uint32 losub;
+ const uint32 hiadd;
+ const uint8* state_table;
+ const RemapEntry* remap_base;
+ const uint8* remap_string;
+ const uint8* fast_state;
+} UTF8StateMachineObj;
+
+typedef UTF8StateMachineObj UTF8ScanObj;
+
+#define X__ (kExitIllegalStructure)
+#define RJ_ (kExitReject)
+#define S1_ (kExitReplace1)
+#define S2_ (kExitReplace2)
+#define S3_ (kExitReplace3)
+#define S21 (kExitReplace21)
+#define S31 (kExitReplace31)
+#define S32 (kExitReplace32)
+#define T1_ (kExitReplaceOffset1)
+#define T2_ (kExitReplaceOffset2)
+#define S11 (kExitReplace1S0)
+#define SP_ (kExitSpecial)
+#define D__ (kExitDoAgain)
+#define RJA (kExitRejectAlt)
+
+// Entire table has 9 state blocks of 256 entries each
+static const unsigned int utf8acceptnonsurrogates_STATE0 = 0; // state[0]
+static const unsigned int utf8acceptnonsurrogates_STATE0_SIZE = 256; // =[1]
+static const unsigned int utf8acceptnonsurrogates_TOTAL_SIZE = 2304;
+static const unsigned int utf8acceptnonsurrogates_MAX_EXPAND_X4 = 0;
+static const unsigned int utf8acceptnonsurrogates_SHIFT = 8;
+static const unsigned int utf8acceptnonsurrogates_BYTES = 1;
+static const unsigned int utf8acceptnonsurrogates_LOSUB = 0x20202020;
+static const unsigned int utf8acceptnonsurrogates_HIADD = 0x00000000;
+
+static const uint8 utf8acceptnonsurrogates[] = {
+// state[0] 0x000000 Byte 1
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+
+X__, X__, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 7, 3, 3,
+ 4, 5, 5, 5, 6, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+
+// state[1] 0x000080 Byte 2 of 2
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+
+// state[2] 0x000000 Byte 2 of 3
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+
+// state[3] 0x001000 Byte 2 of 3
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+
+// state[4] 0x000000 Byte 2 of 4
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+
+// state[5] 0x040000 Byte 2 of 4
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+
+// state[6] 0x100000 Byte 2 of 4
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+
+// state[7] 0x00d000 Byte 2 of 3
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+
+// state[8] 0x00d800 Byte 3 of 3
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+
+RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_,
+RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_,
+RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_,
+RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_,
+
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+};
+
+// Remap base[0] = (del, add, string_offset)
+static const RemapEntry utf8acceptnonsurrogates_remap_base[] = {
+{0, 0, 0} };
+
+// Remap string[0]
+static const unsigned char utf8acceptnonsurrogates_remap_string[] = {
+0 };
+
+static const unsigned char utf8acceptnonsurrogates_fast[256] = {
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+};
+
+static const UTF8ScanObj utf8acceptnonsurrogates_obj = {
+ utf8acceptnonsurrogates_STATE0,
+ utf8acceptnonsurrogates_STATE0_SIZE,
+ utf8acceptnonsurrogates_TOTAL_SIZE,
+ utf8acceptnonsurrogates_MAX_EXPAND_X4,
+ utf8acceptnonsurrogates_SHIFT,
+ utf8acceptnonsurrogates_BYTES,
+ utf8acceptnonsurrogates_LOSUB,
+ utf8acceptnonsurrogates_HIADD,
+ utf8acceptnonsurrogates,
+ utf8acceptnonsurrogates_remap_base,
+ utf8acceptnonsurrogates_remap_string,
+ utf8acceptnonsurrogates_fast
+};
+
+
+#undef X__
+#undef RJ_
+#undef S1_
+#undef S2_
+#undef S3_
+#undef S21
+#undef S31
+#undef S32
+#undef T1_
+#undef T2_
+#undef S11
+#undef SP_
+#undef D__
+#undef RJA
+
+// Return true if current Tbl pointer is within state0 range
+// Note that unsigned compare checks both ends of range simultaneously
+static inline bool InStateZero(const UTF8ScanObj* st, const uint8* Tbl) {
+ const uint8* Tbl0 = &st->state_table[st->state0];
+ return (static_cast<uint32>(Tbl - Tbl0) < st->state0_size);
+}
+
+// Scan a UTF-8 string based on state table.
+// Always scan complete UTF-8 characters
+// Set number of bytes scanned. Return reason for exiting
+int UTF8GenericScan(const UTF8ScanObj* st,
+ const char * str,
+ int str_length,
+ int* bytes_consumed) {
+ *bytes_consumed = 0;
+ if (str_length == 0) return kExitOK;
+
+ int eshift = st->entry_shift;
+ const uint8* isrc = reinterpret_cast<const uint8*>(str);
+ const uint8* src = isrc;
+ const uint8* srclimit = isrc + str_length;
+ const uint8* srclimit8 = str_length < 7 ? isrc : srclimit - 7;
+ const uint8* Tbl_0 = &st->state_table[st->state0];
+
+ DoAgain:
+ // Do state-table scan
+ int e = 0;
+ uint8 c;
+ const uint8* Tbl2 = &st->fast_state[0];
+ const uint32 losub = st->losub;
+ const uint32 hiadd = st->hiadd;
+ // Check initial few bytes one at a time until 8-byte aligned
+ //----------------------------
+ while ((((uintptr_t)src & 0x07) != 0) &&
+ (src < srclimit) &&
+ Tbl2[src[0]] == 0) {
+ src++;
+ }
+ if (((uintptr_t)src & 0x07) == 0) {
+ // Do fast for groups of 8 identity bytes.
+ // This covers a lot of 7-bit ASCII ~8x faster then the 1-byte loop,
+ // including slowing slightly on cr/lf/ht
+ //----------------------------
+ while (src < srclimit8) {
+ uint32 s0123 = (reinterpret_cast<const uint32 *>(src))[0];
+ uint32 s4567 = (reinterpret_cast<const uint32 *>(src))[1];
+ src += 8;
+ // This is a fast range check for all bytes in [lowsub..0x80-hiadd)
+ uint32 temp = (s0123 - losub) | (s0123 + hiadd) |
+ (s4567 - losub) | (s4567 + hiadd);
+ if ((temp & 0x80808080) != 0) {
+ // We typically end up here on cr/lf/ht; src was incremented
+ int e0123 = (Tbl2[src[-8]] | Tbl2[src[-7]]) |
+ (Tbl2[src[-6]] | Tbl2[src[-5]]);
+ if (e0123 != 0) {
+ src -= 8;
+ break;
+ } // Exit on Non-interchange
+ e0123 = (Tbl2[src[-4]] | Tbl2[src[-3]]) |
+ (Tbl2[src[-2]] | Tbl2[src[-1]]);
+ if (e0123 != 0) {
+ src -= 4;
+ break;
+ } // Exit on Non-interchange
+ // Else OK, go around again
+ }
+ }
+ }
+ //----------------------------
+
+ // Byte-at-a-time scan
+ //----------------------------
+ const uint8* Tbl = Tbl_0;
+ while (src < srclimit) {
+ c = *src;
+ e = Tbl[c];
+ src++;
+ if (e >= kExitIllegalStructure) {break;}
+ Tbl = &Tbl_0[e << eshift];
+ }
+ //----------------------------
+
+ // Exit possibilities:
+ // Some exit code, !state0, back up over last char
+ // Some exit code, state0, back up one byte exactly
+ // source consumed, !state0, back up over partial char
+ // source consumed, state0, exit OK
+ // For illegal byte in state0, avoid backup up over PREVIOUS char
+ // For truncated last char, back up to beginning of it
+
+ if (e >= kExitIllegalStructure) {
+ // Back up over exactly one byte of rejected/illegal UTF-8 character
+ src--;
+ // Back up more if needed
+ if (!InStateZero(st, Tbl)) {
+ do {
+ src--;
+ } while ((src > isrc) && ((src[0] & 0xc0) == 0x80));
+ }
+ } else if (!InStateZero(st, Tbl)) {
+ // Back up over truncated UTF-8 character
+ e = kExitIllegalStructure;
+ do {
+ src--;
+ } while ((src > isrc) && ((src[0] & 0xc0) == 0x80));
+ } else {
+ // Normal termination, source fully consumed
+ e = kExitOK;
+ }
+
+ if (e == kExitDoAgain) {
+ // Loop back up to the fast scan
+ goto DoAgain;
+ }
+
+ *bytes_consumed = src - isrc;
+ return e;
+}
+
+int UTF8GenericScanFastAscii(const UTF8ScanObj* st,
+ const char * str,
+ int str_length,
+ int* bytes_consumed) {
+ *bytes_consumed = 0;
+ if (str_length == 0) return kExitOK;
+
+ const uint8* isrc = reinterpret_cast<const uint8*>(str);
+ const uint8* src = isrc;
+ const uint8* srclimit = isrc + str_length;
+ const uint8* srclimit8 = str_length < 7 ? isrc : srclimit - 7;
+ int n;
+ int rest_consumed;
+ int exit_reason;
+ do {
+ // Check initial few bytes one at a time until 8-byte aligned
+ while ((((uintptr_t)src & 0x07) != 0) &&
+ (src < srclimit) && (src[0] < 0x80)) {
+ src++;
+ }
+ if (((uintptr_t)src & 0x07) == 0) {
+ while ((src < srclimit8) &&
+ (((reinterpret_cast<const uint32*>(src)[0] |
+ reinterpret_cast<const uint32*>(src)[1]) & 0x80808080) == 0)) {
+ src += 8;
+ }
+ }
+ while ((src < srclimit) && (src[0] < 0x80)) {
+ src++;
+ }
+ // Run state table on the rest
+ n = src - isrc;
+ exit_reason = UTF8GenericScan(st, str + n, str_length - n, &rest_consumed);
+ src += rest_consumed;
+ } while ( exit_reason == kExitDoAgain );
+
+ *bytes_consumed = src - isrc;
+ return exit_reason;
+}
+
+// Hack: On some compilers the static tables are initialized at startup.
+// We can't use them until they are initialized. However, some Protocol
+// Buffer parsing happens at static init time and may try to validate
+// UTF-8 strings. Since UTF-8 validation is only used for debugging
+// anyway, we simply always return success if initialization hasn't
+// occurred yet.
+namespace {
+
+bool module_initialized_ = false;
+
+struct InitDetector {
+ InitDetector() {
+ module_initialized_ = true;
+ }
+};
+InitDetector init_detector;
+
+} // namespace
+
+bool IsStructurallyValidUTF8(const char* buf, int len) {
+ if (!module_initialized_) return true;
+
+ int bytes_consumed = 0;
+ UTF8GenericScanFastAscii(&utf8acceptnonsurrogates_obj,
+ buf, len, &bytes_consumed);
+ return (bytes_consumed == len);
+}
+
+int UTF8SpnStructurallyValid(StringPiece str) {
+ if (!module_initialized_) return str.size();
+
+ int bytes_consumed = 0;
+ UTF8GenericScanFastAscii(&utf8acceptnonsurrogates_obj,
+ str.data(), str.size(), &bytes_consumed);
+ return bytes_consumed;
+}
+
+// Coerce UTF-8 byte string in src_str to be
+// a structurally-valid equal-length string by selectively
+// overwriting illegal bytes with replace_char (typically blank).
+// replace_char must be legal printable 7-bit Ascii 0x20..0x7e.
+// src_str is read-only. If any overwriting is needed, a modified byte string
+// is created in idst, length isrclen.
+//
+// Returns pointer to output buffer, isrc if no changes were made,
+// or idst if some bytes were changed.
+//
+// Fast case: all is structurally valid and no byte copying is done.
+//
+char* UTF8CoerceToStructurallyValid(StringPiece src_str, char* idst,
+ const char replace_char) {
+ const char* isrc = src_str.data();
+ const int len = src_str.length();
+ int n = UTF8SpnStructurallyValid(src_str);
+ if (n == len) { // Normal case -- all is cool, return
+ return const_cast<char*>(isrc);
+ } else { // Unusual case -- copy w/o bad bytes
+ const char* src = isrc;
+ const char* srclimit = isrc + len;
+ char* dst = idst;
+ memmove(dst, src, n); // Copy initial good chunk
+ src += n;
+ dst += n;
+ while (src < srclimit) { // src points to bogus byte or is off the end
+ dst[0] = replace_char; // replace one bad byte
+ src++;
+ dst++;
+ StringPiece str2(src, srclimit - src);
+ n = UTF8SpnStructurallyValid(str2); // scan the remainder
+ memmove(dst, src, n); // copy next good chunk
+ src += n;
+ dst += n;
+ }
+ }
+ return idst;
+}
+
+} // namespace internal
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/stubs/structurally_valid_unittest.cc b/NorthstarDedicatedTest/include/protobuf/stubs/structurally_valid_unittest.cc
new file mode 100644
index 00000000..05d9adf4
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/stubs/structurally_valid_unittest.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.
+
+// Copyright 2008 Google Inc. All Rights Reserved.
+// Author: xpeng@google.com (Peter Peng)
+
+#include <stubs/common.h>
+#include <gtest/gtest.h>
+
+namespace google {
+namespace protobuf {
+namespace internal {
+namespace {
+
+TEST(StructurallyValidTest, ValidUTF8String) {
+ // On GCC, this string can be written as:
+ // "abcd 1234 - \u2014\u2013\u2212"
+ // MSVC seems to interpret \u differently.
+ std::string valid_str(
+ "abcd 1234 - \342\200\224\342\200\223\342\210\222 - xyz789");
+ EXPECT_TRUE(IsStructurallyValidUTF8(valid_str.data(),
+ valid_str.size()));
+ // Additional check for pointer alignment
+ for (int i = 1; i < 8; ++i) {
+ EXPECT_TRUE(IsStructurallyValidUTF8(valid_str.data() + i,
+ valid_str.size() - i));
+ }
+}
+
+TEST(StructurallyValidTest, InvalidUTF8String) {
+ const std::string invalid_str("abcd\xA0\xB0\xA0\xB0\xA0\xB0 - xyz789");
+ EXPECT_FALSE(IsStructurallyValidUTF8(invalid_str.data(),
+ invalid_str.size()));
+ // Additional check for pointer alignment
+ for (int i = 1; i < 8; ++i) {
+ EXPECT_FALSE(IsStructurallyValidUTF8(invalid_str.data() + i,
+ invalid_str.size() - i));
+ }
+}
+
+} // namespace
+} // namespace internal
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/stubs/strutil.cc b/NorthstarDedicatedTest/include/protobuf/stubs/strutil.cc
new file mode 100644
index 00000000..9e979529
--- /dev/null
+++ b/NorthstarDedicatedTest/include/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 <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 <stubs/logging.h>
+#include <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>(*src) < 0x80) &&
+ (!isprint(*src) ||
+ (last_hex_escape && isxdigit(*src)))) {
+ if (dest_len - used < 4) // need space for 4 letter escape
+ return -1;
+ sprintf(dest + used, (use_hex ? "\\x%02x" : "\\%03o"),
+ static_cast<uint8>(*src));
+ is_hex_escape = use_hex;
+ used += 4;
+ } else {
+ dest[used++] = *src; break;
+ }
+ }
+ last_hex_escape = is_hex_escape;
+ }
+
+ if (dest_len - used < 1) // make sure that there is room for \0
+ return -1;
+
+ dest[used] = '\0'; // doesn't count towards return value though
+ return used;
+}
+
+// Calculates the length of the C-style escaped version of 'src'.
+// Assumes that non-printable characters are escaped using octal sequences, and
+// that UTF-8 bytes are not handled specially.
+static inline size_t CEscapedLength(StringPiece src) {
+ static char c_escaped_len[256] = {
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 4, 4, 2, 4, 4, // \t, \n, \r
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, // ", '
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // '0'..'9'
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 'A'..'O'
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, // 'P'..'Z', '\'
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 'a'..'o'
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, // 'p'..'z', DEL
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ };
+
+ size_t escaped_len = 0;
+ for (StringPiece::size_type i = 0; i < src.size(); ++i) {
+ unsigned char c = static_cast<unsigned char>(src[i]);
+ escaped_len += c_escaped_len[c];
+ }
+ return escaped_len;
+}
+
+// ----------------------------------------------------------------------
+// Escapes 'src' using C-style escape sequences, and appends the escaped string
+// to 'dest'. This version is faster than calling CEscapeInternal as it computes
+// the required space using a lookup table, and also does not do any special
+// handling for Hex or UTF-8 characters.
+// ----------------------------------------------------------------------
+void CEscapeAndAppend(StringPiece src, 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 strto32_adaptor(const char *nptr, char **endptr, int base) {
+ const int saved_errno = errno;
+ errno = 0;
+ const long result = strtol(nptr, endptr, base);
+ if (errno == ERANGE && result == LONG_MIN) {
+ return kint32min;
+ } else if (errno == ERANGE && result == LONG_MAX) {
+ return kint32max;
+ } else if (errno == 0 && result < kint32min) {
+ errno = ERANGE;
+ return kint32min;
+ } else if (errno == 0 && result > kint32max) {
+ errno = ERANGE;
+ return kint32max;
+ }
+ if (errno == 0)
+ errno = saved_errno;
+ return static_cast<int32>(result);
+}
+
+uint32 strtou32_adaptor(const char *nptr, char **endptr, int base) {
+ const int saved_errno = errno;
+ errno = 0;
+ const unsigned long result = strtoul(nptr, endptr, base);
+ if (errno == ERANGE && result == ULONG_MAX) {
+ return kuint32max;
+ } else if (errno == 0 && result > kuint32max) {
+ errno = ERANGE;
+ return kuint32max;
+ }
+ if (errno == 0)
+ errno = saved_errno;
+ return static_cast<uint32>(result);
+}
+
+inline bool safe_parse_sign(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 i, char* buffer) {
+ // We could collapse the positive and negative sections, but that
+ // would be slightly slower for positive numbers...
+ // 22 bytes is enough to store -2**64, -18446744073709551616.
+ char* p = buffer + kFastInt64ToBufferOffset;
+ *p-- = '\0';
+ if (i >= 0) {
+ do {
+ *p-- = '0' + i % 10;
+ i /= 10;
+ } while (i > 0);
+ return p + 1;
+ } else {
+ // On different platforms, % and / have different behaviors for
+ // negative numbers, so we need to jump through hoops to make sure
+ // we don't divide negative numbers.
+ if (i > -10) {
+ i = -i;
+ *p-- = '0' + i;
+ *p = '-';
+ return p;
+ } else {
+ // Make sure we aren't at MIN_INT, in which case we can't say i = -i
+ i = i + 10;
+ i = -i;
+ *p-- = '0' + i % 10;
+ // Undo what we did a moment ago
+ i = i / 10 + 1;
+ do {
+ *p-- = '0' + i % 10;
+ i /= 10;
+ } while (i > 0);
+ *p = '-';
+ return p;
+ }
+ }
+}
+
+// Offset into buffer where FastInt32ToBuffer places the end of string
+// null character. Also used by FastInt32ToBufferLeft
+static const int kFastInt32ToBufferOffset = 11;
+
+// Yes, this is a duplicate of FastInt64ToBuffer. But, we need this for the
+// compiler to generate 32 bit arithmetic instructions. It's much faster, at
+// least with 32 bit binaries.
+char *FastInt32ToBuffer(int32 i, char* buffer) {
+ // We could collapse the positive and negative sections, but that
+ // would be slightly slower for positive numbers...
+ // 12 bytes is enough to store -2**32, -4294967296.
+ char* p = buffer + kFastInt32ToBufferOffset;
+ *p-- = '\0';
+ if (i >= 0) {
+ do {
+ *p-- = '0' + i % 10;
+ i /= 10;
+ } while (i > 0);
+ return p + 1;
+ } else {
+ // On different platforms, % and / have different behaviors for
+ // negative numbers, so we need to jump through hoops to make sure
+ // we don't divide negative numbers.
+ if (i > -10) {
+ i = -i;
+ *p-- = '0' + i;
+ *p = '-';
+ return p;
+ } else {
+ // Make sure we aren't at MIN_INT, in which case we can't say i = -i
+ i = i + 10;
+ i = -i;
+ *p-- = '0' + i % 10;
+ // Undo what we did a moment ago
+ i = i / 10 + 1;
+ do {
+ *p-- = '0' + i % 10;
+ i /= 10;
+ } while (i > 0);
+ *p = '-';
+ return p;
+ }
+ }
+}
+
+char *FastHexToBuffer(int i, char* buffer) {
+ GOOGLE_CHECK(i >= 0) << "FastHexToBuffer() wants non-negative integers, not " << i;
+
+ static const char *hexdigits = "0123456789abcdef";
+ char *p = buffer + 21;
+ *p-- = '\0';
+ do {
+ *p-- = hexdigits[i & 15]; // mod by 16
+ i >>= 4; // divide by 16
+ } while (i > 0);
+ return p + 1;
+}
+
+char *InternalFastHexToBuffer(uint64 value, char* buffer, int num_byte) {
+ static const char *hexdigits = "0123456789abcdef";
+ buffer[num_byte] = '\0';
+ for (int i = num_byte - 1; i >= 0; i--) {
+#ifdef _M_X64
+ // MSVC x64 platform has a bug optimizing the uint32(value) in the #else
+ // block. Given that the uint32 cast was to improve performance on 32-bit
+ // platforms, we use 64-bit '&' directly.
+ buffer[i] = hexdigits[value & 0xf];
+#else
+ buffer[i] = hexdigits[uint32(value) & 0xf];
+#endif
+ value >>= 4;
+ }
+ return buffer;
+}
+
+char *FastHex64ToBuffer(uint64 value, char* buffer) {
+ return InternalFastHexToBuffer(value, buffer, 16);
+}
+
+char *FastHex32ToBuffer(uint32 value, char* buffer) {
+ return InternalFastHexToBuffer(value, buffer, 8);
+}
+
+// ----------------------------------------------------------------------
+// FastInt32ToBufferLeft()
+// FastUInt32ToBufferLeft()
+// FastInt64ToBufferLeft()
+// FastUInt64ToBufferLeft()
+//
+// Like the Fast*ToBuffer() functions above, these are intended for speed.
+// Unlike the Fast*ToBuffer() functions, however, these functions write
+// their output to the beginning of the buffer (hence the name, as the
+// output is left-aligned). The caller is responsible for ensuring that
+// the buffer has enough space to hold the output.
+//
+// Returns a pointer to the end of the string (i.e. the null character
+// terminating the string).
+// ----------------------------------------------------------------------
+
+static const char two_ASCII_digits[100][2] = {
+ {'0','0'}, {'0','1'}, {'0','2'}, {'0','3'}, {'0','4'},
+ {'0','5'}, {'0','6'}, {'0','7'}, {'0','8'}, {'0','9'},
+ {'1','0'}, {'1','1'}, {'1','2'}, {'1','3'}, {'1','4'},
+ {'1','5'}, {'1','6'}, {'1','7'}, {'1','8'}, {'1','9'},
+ {'2','0'}, {'2','1'}, {'2','2'}, {'2','3'}, {'2','4'},
+ {'2','5'}, {'2','6'}, {'2','7'}, {'2','8'}, {'2','9'},
+ {'3','0'}, {'3','1'}, {'3','2'}, {'3','3'}, {'3','4'},
+ {'3','5'}, {'3','6'}, {'3','7'}, {'3','8'}, {'3','9'},
+ {'4','0'}, {'4','1'}, {'4','2'}, {'4','3'}, {'4','4'},
+ {'4','5'}, {'4','6'}, {'4','7'}, {'4','8'}, {'4','9'},
+ {'5','0'}, {'5','1'}, {'5','2'}, {'5','3'}, {'5','4'},
+ {'5','5'}, {'5','6'}, {'5','7'}, {'5','8'}, {'5','9'},
+ {'6','0'}, {'6','1'}, {'6','2'}, {'6','3'}, {'6','4'},
+ {'6','5'}, {'6','6'}, {'6','7'}, {'6','8'}, {'6','9'},
+ {'7','0'}, {'7','1'}, {'7','2'}, {'7','3'}, {'7','4'},
+ {'7','5'}, {'7','6'}, {'7','7'}, {'7','8'}, {'7','9'},
+ {'8','0'}, {'8','1'}, {'8','2'}, {'8','3'}, {'8','4'},
+ {'8','5'}, {'8','6'}, {'8','7'}, {'8','8'}, {'8','9'},
+ {'9','0'}, {'9','1'}, {'9','2'}, {'9','3'}, {'9','4'},
+ {'9','5'}, {'9','6'}, {'9','7'}, {'9','8'}, {'9','9'}
+};
+
+char* FastUInt32ToBufferLeft(uint32 u, char* buffer) {
+ uint32 digits;
+ const char *ASCII_digits = nullptr;
+ // The idea of this implementation is to trim the number of divides to as few
+ // as possible by using multiplication and subtraction rather than mod (%),
+ // and by outputting two digits at a time rather than one.
+ // The huge-number case is first, in the hopes that the compiler will output
+ // that case in one branch-free block of code, and only output conditional
+ // branches into it from below.
+ if (u >= 1000000000) { // >= 1,000,000,000
+ digits = u / 100000000; // 100,000,000
+ ASCII_digits = two_ASCII_digits[digits];
+ buffer[0] = ASCII_digits[0];
+ buffer[1] = ASCII_digits[1];
+ buffer += 2;
+sublt100_000_000:
+ u -= digits * 100000000; // 100,000,000
+lt100_000_000:
+ digits = u / 1000000; // 1,000,000
+ ASCII_digits = two_ASCII_digits[digits];
+ buffer[0] = ASCII_digits[0];
+ buffer[1] = ASCII_digits[1];
+ buffer += 2;
+sublt1_000_000:
+ u -= digits * 1000000; // 1,000,000
+lt1_000_000:
+ digits = u / 10000; // 10,000
+ ASCII_digits = two_ASCII_digits[digits];
+ buffer[0] = ASCII_digits[0];
+ buffer[1] = ASCII_digits[1];
+ buffer += 2;
+sublt10_000:
+ u -= digits * 10000; // 10,000
+lt10_000:
+ digits = u / 100;
+ ASCII_digits = two_ASCII_digits[digits];
+ buffer[0] = ASCII_digits[0];
+ buffer[1] = ASCII_digits[1];
+ buffer += 2;
+sublt100:
+ u -= digits * 100;
+lt100:
+ digits = u;
+ ASCII_digits = two_ASCII_digits[digits];
+ buffer[0] = ASCII_digits[0];
+ buffer[1] = ASCII_digits[1];
+ buffer += 2;
+done:
+ *buffer = 0;
+ return buffer;
+ }
+
+ if (u < 100) {
+ digits = u;
+ if (u >= 10) goto lt100;
+ *buffer++ = '0' + digits;
+ goto done;
+ }
+ if (u < 10000) { // 10,000
+ if (u >= 1000) goto lt10_000;
+ digits = u / 100;
+ *buffer++ = '0' + digits;
+ goto sublt100;
+ }
+ if (u < 1000000) { // 1,000,000
+ if (u >= 100000) goto lt1_000_000;
+ digits = u / 10000; // 10,000
+ *buffer++ = '0' + digits;
+ goto sublt10_000;
+ }
+ if (u < 100000000) { // 100,000,000
+ if (u >= 10000000) goto lt100_000_000;
+ digits = u / 1000000; // 1,000,000
+ *buffer++ = '0' + digits;
+ goto sublt1_000_000;
+ }
+ // we already know that u < 1,000,000,000
+ digits = u / 100000000; // 100,000,000
+ *buffer++ = '0' + digits;
+ goto sublt100_000_000;
+}
+
+char* FastInt32ToBufferLeft(int32 i, char* buffer) {
+ uint32 u = 0;
+ if (i < 0) {
+ *buffer++ = '-';
+ u -= i;
+ } else {
+ u = i;
+ }
+ return FastUInt32ToBufferLeft(u, buffer);
+}
+
+char* FastUInt64ToBufferLeft(uint64 u64, char* buffer) {
+ int digits;
+ const char *ASCII_digits = nullptr;
+
+ uint32 u = static_cast<uint32>(u64);
+ if (u == u64) return FastUInt32ToBufferLeft(u, buffer);
+
+ uint64 top_11_digits = u64 / 1000000000;
+ buffer = FastUInt64ToBufferLeft(top_11_digits, buffer);
+ u = u64 - (top_11_digits * 1000000000);
+
+ digits = u / 10000000; // 10,000,000
+ GOOGLE_DCHECK_LT(digits, 100);
+ ASCII_digits = two_ASCII_digits[digits];
+ buffer[0] = ASCII_digits[0];
+ buffer[1] = ASCII_digits[1];
+ buffer += 2;
+ u -= digits * 10000000; // 10,000,000
+ digits = u / 100000; // 100,000
+ ASCII_digits = two_ASCII_digits[digits];
+ buffer[0] = ASCII_digits[0];
+ buffer[1] = ASCII_digits[1];
+ buffer += 2;
+ u -= digits * 100000; // 100,000
+ digits = u / 1000; // 1,000
+ ASCII_digits = two_ASCII_digits[digits];
+ buffer[0] = ASCII_digits[0];
+ buffer[1] = ASCII_digits[1];
+ buffer += 2;
+ u -= digits * 1000; // 1,000
+ digits = u / 10;
+ ASCII_digits = two_ASCII_digits[digits];
+ buffer[0] = ASCII_digits[0];
+ buffer[1] = ASCII_digits[1];
+ buffer += 2;
+ u -= digits * 10;
+ digits = u;
+ *buffer++ = '0' + digits;
+ *buffer = 0;
+ return buffer;
+}
+
+char* FastInt64ToBufferLeft(int64 i, char* buffer) {
+ uint64 u = 0;
+ if (i < 0) {
+ *buffer++ = '-';
+ u -= i;
+ } else {
+ u = i;
+ }
+ return FastUInt64ToBufferLeft(u, buffer);
+}
+
+// ----------------------------------------------------------------------
+// SimpleItoa()
+// Description: converts an integer to a string.
+//
+// Return value: string
+// ----------------------------------------------------------------------
+
+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 *value) {
+ return safe_int_internal(str, value);
+}
+
+bool safe_strtou32(const std::string &str, uint32 *value) {
+ return safe_uint_internal(str, value);
+}
+
+bool safe_strto64(const std::string &str, int64 *value) {
+ return safe_int_internal(str, value);
+}
+
+bool safe_strtou64(const std::string &str, uint64 *value) {
+ return safe_uint_internal(str, value);
+}
+
+char* FloatToBuffer(float value, char* buffer) {
+ // FLT_DIG is 6 for IEEE-754 floats, which are used on almost all
+ // platforms these days. Just in case some system exists where FLT_DIG
+ // is significantly larger -- and risks overflowing our buffer -- we have
+ // this assert.
+ static_assert(FLT_DIG < 10, "FLT_DIG_is_too_big");
+
+ if (value == std::numeric_limits<double>::infinity()) {
+ strcpy(buffer, "inf");
+ return buffer;
+ } else if (value == -std::numeric_limits<double>::infinity()) {
+ strcpy(buffer, "-inf");
+ return buffer;
+ } else if (std::isnan(value)) {
+ strcpy(buffer, "nan");
+ return buffer;
+ }
+
+ int snprintf_result =
+ snprintf(buffer, kFloatToBufferSize, "%.*g", FLT_DIG, value);
+
+ // The snprintf should never overflow because the buffer is significantly
+ // larger than the precision we asked for.
+ GOOGLE_DCHECK(snprintf_result > 0 && snprintf_result < kFloatToBufferSize);
+
+ float parsed_value;
+ if (!safe_strtof(buffer, &parsed_value) || parsed_value != value) {
+ snprintf_result =
+ snprintf(buffer, kFloatToBufferSize, "%.*g", FLT_DIG + 3, value);
+
+ // Should never overflow; see above.
+ GOOGLE_DCHECK(snprintf_result > 0 && snprintf_result < kFloatToBufferSize);
+ }
+
+ DelocalizeRadix(buffer);
+ return buffer;
+}
+
+namespace strings {
+
+AlphaNum::AlphaNum(strings::Hex hex) {
+ char *const end = &digits[kFastToBufferSize];
+ char *writer = end;
+ uint64 value = hex.value;
+ uint64 width = hex.spec;
+ // We accomplish minimum width by OR'ing in 0x10000 to the user's value,
+ // where 0x10000 is the smallest hex number that is as wide as the user
+ // asked for.
+ uint64 mask = ((static_cast<uint64>(1) << (width - 1) * 4)) | value;
+ static const char hexdigits[] = "0123456789abcdef";
+ do {
+ *--writer = hexdigits[value & 0xF];
+ value >>= 4;
+ mask >>= 4;
+ } while (mask != 0);
+ piece_data_ = writer;
+ piece_size_ = end - writer;
+}
+
+} // namespace strings
+
+// ----------------------------------------------------------------------
+// StrCat()
+// This merges the given strings or integers, with no delimiter. This
+// is designed to be the fastest possible way to construct a string out
+// of a mix of raw C strings, C++ strings, and integer values.
+// ----------------------------------------------------------------------
+
+// Append is merely a version of memcpy that returns the address of the byte
+// after the area just overwritten. It comes in multiple flavors to minimize
+// call overhead.
+static char *Append1(char *out, const AlphaNum &x) {
+ if (x.size() > 0) {
+ memcpy(out, x.data(), x.size());
+ out += x.size();
+ }
+ return out;
+}
+
+static char *Append2(char *out, const AlphaNum &x1, const AlphaNum &x2) {
+ if (x1.size() > 0) {
+ memcpy(out, x1.data(), x1.size());
+ out += x1.size();
+ }
+ if (x2.size() > 0) {
+ memcpy(out, x2.data(), x2.size());
+ out += x2.size();
+ }
+ return out;
+}
+
+static char *Append4(char *out, const AlphaNum &x1, const AlphaNum &x2,
+ const AlphaNum &x3, const AlphaNum &x4) {
+ if (x1.size() > 0) {
+ memcpy(out, x1.data(), x1.size());
+ out += x1.size();
+ }
+ if (x2.size() > 0) {
+ memcpy(out, x2.data(), x2.size());
+ out += x2.size();
+ }
+ if (x3.size() > 0) {
+ memcpy(out, x3.data(), x3.size());
+ out += x3.size();
+ }
+ if (x4.size() > 0) {
+ memcpy(out, x4.data(), x4.size());
+ out += x4.size();
+ }
+ return out;
+}
+
+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 in = BigEndian::Load32(cur_src) >> 8;
+
+ cur_dest[0] = base64[in >> 18];
+ in &= 0x3FFFF;
+ cur_dest[1] = base64[in >> 12];
+ in &= 0xFFF;
+ cur_dest[2] = base64[in >> 6];
+ in &= 0x3F;
+ cur_dest[3] = base64[in];
+
+ cur_dest += 4;
+ cur_src += 3;
+ }
+ // To save time, we didn't update szdest or szsrc in the loop. So do it now.
+ szdest = limit_dest - cur_dest;
+ szsrc = limit_src - cur_src;
+
+ /* now deal with the tail (<=3 bytes) */
+ switch (szsrc) {
+ case 0:
+ // Nothing left; nothing more to do.
+ break;
+ case 1: {
+ // One byte left: this encodes to two characters, and (optionally)
+ // two pad characters to round out the four-character cipherblock.
+ if ((szdest -= 2) < 0) return 0;
+ uint32 in = cur_src[0];
+ cur_dest[0] = base64[in >> 2];
+ in &= 0x3;
+ cur_dest[1] = base64[in << 4];
+ cur_dest += 2;
+ if (do_padding) {
+ if ((szdest -= 2) < 0) return 0;
+ cur_dest[0] = kPad64;
+ cur_dest[1] = kPad64;
+ cur_dest += 2;
+ }
+ break;
+ }
+ case 2: {
+ // Two bytes left: this encodes to three characters, and (optionally)
+ // one pad character to round out the four-character cipherblock.
+ if ((szdest -= 3) < 0) return 0;
+ uint32 in = BigEndian::Load16(cur_src);
+ cur_dest[0] = base64[in >> 10];
+ in &= 0x3FF;
+ cur_dest[1] = base64[in >> 4];
+ in &= 0x00F;
+ cur_dest[2] = base64[in << 2];
+ cur_dest += 3;
+ if (do_padding) {
+ if ((szdest -= 1) < 0) return 0;
+ cur_dest[0] = kPad64;
+ cur_dest += 1;
+ }
+ break;
+ }
+ case 3: {
+ // Three bytes left: same as in the big loop above. We can't do this in
+ // the loop because the loop above always reads 4 bytes, and the fourth
+ // byte is past the end of the input.
+ if ((szdest -= 4) < 0) return 0;
+ uint32 in = (cur_src[0] << 16) + BigEndian::Load16(cur_src + 1);
+ cur_dest[0] = base64[in >> 18];
+ in &= 0x3FFFF;
+ cur_dest[1] = base64[in >> 12];
+ in &= 0xFFF;
+ cur_dest[2] = base64[in >> 6];
+ in &= 0x3F;
+ cur_dest[3] = base64[in];
+ cur_dest += 4;
+ break;
+ }
+ default:
+ // Should not be reached: blocks of 4 bytes are handled
+ // in the while loop before this switch statement.
+ GOOGLE_LOG(FATAL) << "Logic problem? szsrc = " << szsrc;
+ break;
+ }
+ return (cur_dest - dest);
+}
+
+static const char kBase64Chars[] =
+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+static const char kWebSafeBase64Chars[] =
+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
+
+int Base64Escape(const unsigned char *src, int szsrc, char *dest, int szdest) {
+ return Base64EscapeInternal(src, szsrc, dest, szdest, kBase64Chars, true);
+}
+int WebSafeBase64Escape(const unsigned char *src, int szsrc, char *dest,
+ int szdest, bool do_padding) {
+ return Base64EscapeInternal(src, szsrc, dest, szdest,
+ kWebSafeBase64Chars, do_padding);
+}
+
+void Base64EscapeInternal(const unsigned char *src, int szsrc,
+ 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 code_point, char* output) {
+ uint32 tmp = 0;
+ int len = 0;
+ if (code_point <= 0x7f) {
+ tmp = code_point;
+ len = 1;
+ } else if (code_point <= 0x07ff) {
+ tmp = 0x0000c080 |
+ ((code_point & 0x07c0) << 2) |
+ (code_point & 0x003f);
+ len = 2;
+ } else if (code_point <= 0xffff) {
+ tmp = 0x00e08080 |
+ ((code_point & 0xf000) << 4) |
+ ((code_point & 0x0fc0) << 2) |
+ (code_point & 0x003f);
+ len = 3;
+ } else {
+ // UTF-16 is only defined for code points up to 0x10FFFF, and UTF-8 is
+ // normally only defined up to there as well.
+ tmp = 0xf0808080 |
+ ((code_point & 0x1c0000) << 6) |
+ ((code_point & 0x03f000) << 4) |
+ ((code_point & 0x000fc0) << 2) |
+ (code_point & 0x003f);
+ len = 4;
+ }
+ tmp = ghtonl(tmp);
+ memcpy(output, reinterpret_cast<const char*>(&tmp) + sizeof(tmp) - len, len);
+ return len;
+}
+
+// Table of UTF-8 character lengths, based on first byte
+static const unsigned char kUTF8LenTbl[256] = {
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 4, 4, 4, 4, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
+
+// Return length of a single UTF-8 source character
+int UTF8FirstLetterNumBytes(const char* src, int len) {
+ if (len == 0) {
+ return 0;
+ }
+ return kUTF8LenTbl[*reinterpret_cast<const uint8*>(src)];
+}
+
+// ----------------------------------------------------------------------
+// CleanStringLineEndings()
+// Clean up a multi-line string to conform to Unix line endings.
+// Reads from src and appends to dst, so usually dst should be empty.
+//
+// If there is no line ending at the end of a non-empty string, it can
+// be added automatically.
+//
+// Four different types of input are correctly handled:
+//
+// - Unix/Linux files: line ending is LF: pass through unchanged
+//
+// - DOS/Windows files: line ending is CRLF: convert to LF
+//
+// - Legacy Mac files: line ending is CR: convert to LF
+//
+// - Garbled files: random line endings: convert gracefully
+// lonely CR, lonely LF, CRLF: convert to LF
+//
+// @param src The multi-line string to convert
+// @param dst The converted string is appended to this string
+// @param auto_end_last_line Automatically terminate the last line
+//
+// Limitations:
+//
+// This does not do the right thing for CRCRLF files created by
+// broken programs that do another Unix->DOS conversion on files
+// that are already in CRLF format. For this, a two-pass approach
+// brute-force would be needed that
+//
+// (1) determines the presence of LF (first one is ok)
+// (2) if yes, removes any CR, else convert every CR to LF
+
+void CleanStringLineEndings(const 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/NorthstarDedicatedTest/include/protobuf/stubs/strutil.h b/NorthstarDedicatedTest/include/protobuf/stubs/strutil.h
new file mode 100644
index 00000000..8f58b735
--- /dev/null
+++ b/NorthstarDedicatedTest/include/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 <stubs/common.h>
+#include <stubs/stringpiece.h>
+#include <stdlib.h>
+
+#include <cstring>
+#include <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 strto32_adaptor(const char* nptr, char** endptr,
+ int base);
+PROTOBUF_EXPORT uint32 strtou32_adaptor(const char* nptr, char** endptr,
+ int base);
+
+inline int32 strto32(const char *nptr, char **endptr, int base) {
+ if (sizeof(int32) == sizeof(long))
+ return strtol(nptr, endptr, base);
+ else
+ return strto32_adaptor(nptr, endptr, base);
+}
+
+inline uint32 strtou32(const char *nptr, char **endptr, int base) {
+ if (sizeof(uint32) == sizeof(unsigned long))
+ return strtoul(nptr, endptr, base);
+ else
+ return strtou32_adaptor(nptr, endptr, base);
+}
+
+// For now, long long is 64-bit on all the platforms we care about, so these
+// functions can simply pass the call to strto[u]ll.
+inline int64 strto64(const char *nptr, char **endptr, int base) {
+ static_assert(sizeof(int64) == sizeof(long long),
+ "sizeof_int64_is_not_sizeof_long_long");
+ return strtoll(nptr, endptr, base);
+}
+
+inline uint64 strtou64(const char *nptr, char **endptr, int base) {
+ static_assert(sizeof(uint64) == sizeof(unsigned long long),
+ "sizeof_uint64_is_not_sizeof_long_long");
+ return strtoull(nptr, endptr, base);
+}
+
+// ----------------------------------------------------------------------
+// safe_strtob()
+// safe_strto32()
+// safe_strtou32()
+// safe_strto64()
+// safe_strtou64()
+// safe_strtof()
+// safe_strtod()
+// ----------------------------------------------------------------------
+PROTOBUF_EXPORT bool safe_strtob(StringPiece str, bool* value);
+
+PROTOBUF_EXPORT bool safe_strto32(const std::string& str, int32* value);
+PROTOBUF_EXPORT bool safe_strtou32(const std::string& str, uint32* value);
+inline bool safe_strto32(const char* str, int32* value) {
+ return safe_strto32(std::string(str), value);
+}
+inline bool safe_strto32(StringPiece str, int32* value) {
+ return safe_strto32(str.ToString(), value);
+}
+inline bool safe_strtou32(const char* str, uint32* value) {
+ return safe_strtou32(std::string(str), value);
+}
+inline bool safe_strtou32(StringPiece str, uint32* value) {
+ return safe_strtou32(str.ToString(), value);
+}
+
+PROTOBUF_EXPORT bool safe_strto64(const std::string& str, int64* value);
+PROTOBUF_EXPORT bool safe_strtou64(const std::string& str, uint64* value);
+inline bool safe_strto64(const char* str, int64* value) {
+ return safe_strto64(std::string(str), value);
+}
+inline bool safe_strto64(StringPiece str, int64* value) {
+ return safe_strto64(str.ToString(), value);
+}
+inline bool safe_strtou64(const char* str, uint64* value) {
+ return safe_strtou64(std::string(str), value);
+}
+inline bool safe_strtou64(StringPiece str, uint64* value) {
+ return safe_strtou64(str.ToString(), value);
+}
+
+PROTOBUF_EXPORT bool safe_strtof(const char* str, float* value);
+PROTOBUF_EXPORT bool safe_strtod(const char* str, double* value);
+inline bool safe_strtof(const 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 i, char* buffer);
+PROTOBUF_EXPORT char* FastInt64ToBuffer(int64 i, char* buffer);
+char* FastUInt32ToBuffer(uint32 i, char* buffer); // inline below
+char* FastUInt64ToBuffer(uint64 i, char* buffer); // inline below
+PROTOBUF_EXPORT char* FastHexToBuffer(int i, char* buffer);
+PROTOBUF_EXPORT char* FastHex64ToBuffer(uint64 i, char* buffer);
+PROTOBUF_EXPORT char* FastHex32ToBuffer(uint32 i, char* buffer);
+
+// at least 22 bytes long
+inline char* FastIntToBuffer(int i, char* buffer) {
+ return (sizeof(i) == 4 ?
+ FastInt32ToBuffer(i, buffer) : FastInt64ToBuffer(i, buffer));
+}
+inline char* FastUIntToBuffer(unsigned int i, char* buffer) {
+ return (sizeof(i) == 4 ?
+ FastUInt32ToBuffer(i, buffer) : FastUInt64ToBuffer(i, buffer));
+}
+inline char* FastLongToBuffer(long i, char* buffer) {
+ return (sizeof(i) == 4 ?
+ FastInt32ToBuffer(i, buffer) : FastInt64ToBuffer(i, buffer));
+}
+inline char* FastULongToBuffer(unsigned long i, char* buffer) {
+ return (sizeof(i) == 4 ?
+ FastUInt32ToBuffer(i, buffer) : FastUInt64ToBuffer(i, buffer));
+}
+
+// ----------------------------------------------------------------------
+// FastInt32ToBufferLeft()
+// FastUInt32ToBufferLeft()
+// FastInt64ToBufferLeft()
+// FastUInt64ToBufferLeft()
+//
+// Like the Fast*ToBuffer() functions above, these are intended for speed.
+// Unlike the Fast*ToBuffer() functions, however, these functions write
+// their output to the beginning of the buffer (hence the name, as the
+// output is left-aligned). The caller is responsible for ensuring that
+// the buffer has enough space to hold the output.
+//
+// Returns a pointer to the end of the string (i.e. the null character
+// terminating the string).
+// ----------------------------------------------------------------------
+
+PROTOBUF_EXPORT char* FastInt32ToBufferLeft(int32 i, char* buffer);
+PROTOBUF_EXPORT char* FastUInt32ToBufferLeft(uint32 i, char* buffer);
+PROTOBUF_EXPORT char* FastInt64ToBufferLeft(int64 i, char* buffer);
+PROTOBUF_EXPORT char* FastUInt64ToBufferLeft(uint64 i, char* buffer);
+
+// Just define these in terms of the above.
+inline char* FastUInt32ToBuffer(uint32 i, char* buffer) {
+ FastUInt32ToBufferLeft(i, buffer);
+ return buffer;
+}
+inline char* FastUInt64ToBuffer(uint64 i, char* buffer) {
+ FastUInt64ToBufferLeft(i, buffer);
+ return buffer;
+}
+
+inline 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 value;
+ enum PadSpec spec;
+ template <class Int>
+ explicit Hex(Int v, PadSpec s = NO_PAD)
+ : spec(s) {
+ // Prevent sign-extension by casting integers to
+ // their unsigned counterparts.
+#ifdef LANG_CXX11
+ static_assert(
+ sizeof(v) == 1 || sizeof(v) == 2 || sizeof(v) == 4 || sizeof(v) == 8,
+ "Unknown integer type");
+#endif
+ value = sizeof(v) == 1 ? static_cast<uint8>(v)
+ : sizeof(v) == 2 ? static_cast<uint16>(v)
+ : sizeof(v) == 4 ? static_cast<uint32>(v)
+ : static_cast<uint64>(v);
+ }
+};
+
+struct PROTOBUF_EXPORT AlphaNum {
+ const char *piece_data_; // move these to string_ref eventually
+ size_t piece_size_; // move these to string_ref eventually
+
+ char digits[kFastToBufferSize];
+
+ // No bool ctor -- bools convert to an integral type.
+ // A bool ctor would also convert incoming pointers (bletch).
+
+ AlphaNum(int i32)
+ : piece_data_(digits),
+ piece_size_(FastInt32ToBufferLeft(i32, digits) - &digits[0]) {}
+ AlphaNum(unsigned int u32)
+ : piece_data_(digits),
+ piece_size_(FastUInt32ToBufferLeft(u32, digits) - &digits[0]) {}
+ AlphaNum(long long i64)
+ : piece_data_(digits),
+ piece_size_(FastInt64ToBufferLeft(i64, digits) - &digits[0]) {}
+ AlphaNum(unsigned long long u64)
+ : piece_data_(digits),
+ piece_size_(FastUInt64ToBufferLeft(u64, digits) - &digits[0]) {}
+
+ // Note: on some architectures, "long" is only 32 bits, not 64, but the
+ // performance hit of using FastInt64ToBufferLeft to handle 32-bit values
+ // is quite minor.
+ AlphaNum(long i64)
+ : piece_data_(digits),
+ piece_size_(FastInt64ToBufferLeft(i64, digits) - &digits[0]) {}
+ AlphaNum(unsigned long u64)
+ : piece_data_(digits),
+ piece_size_(FastUInt64ToBufferLeft(u64, digits) - &digits[0]) {}
+
+ AlphaNum(float f)
+ : piece_data_(digits), piece_size_(strlen(FloatToBuffer(f, digits))) {}
+ AlphaNum(double f)
+ : piece_data_(digits), piece_size_(strlen(DoubleToBuffer(f, digits))) {}
+
+ AlphaNum(Hex hex);
+
+ AlphaNum(const char* c_str)
+ : piece_data_(c_str), piece_size_(strlen(c_str)) {}
+ // TODO: Add a string_ref constructor, eventually
+ // AlphaNum(const StringPiece &pc) : piece(pc) {}
+
+ AlphaNum(const 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 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 code_point) {
+ return code_point < 0xD800 ||
+ (code_point >= 0xE000 && code_point <= 0x10FFFF);
+}
+
+static const int UTFmax = 4;
+// ----------------------------------------------------------------------
+// EncodeAsUTF8Char()
+// Helper to append a Unicode code point to a string as UTF8, without bringing
+// in any external dependencies. The output buffer must be as least 4 bytes
+// large.
+// ----------------------------------------------------------------------
+PROTOBUF_EXPORT int EncodeAsUTF8Char(uint32 code_point, char* output);
+
+// ----------------------------------------------------------------------
+// UTF8FirstLetterNumBytes()
+// Length of the first UTF-8 character.
+// ----------------------------------------------------------------------
+PROTOBUF_EXPORT int UTF8FirstLetterNumBytes(const char* src, int len);
+
+// From google3/third_party/absl/strings/escaping.h
+
+// ----------------------------------------------------------------------
+// CleanStringLineEndings()
+// Clean up a multi-line string to conform to Unix line endings.
+// Reads from src and appends to dst, so usually dst should be empty.
+//
+// If there is no line ending at the end of a non-empty string, it can
+// be added automatically.
+//
+// Four different types of input are correctly handled:
+//
+// - Unix/Linux files: line ending is LF: pass through unchanged
+//
+// - DOS/Windows files: line ending is CRLF: convert to LF
+//
+// - Legacy Mac files: line ending is CR: convert to LF
+//
+// - Garbled files: random line endings: convert gracefully
+// lonely CR, lonely LF, CRLF: convert to LF
+//
+// @param src The multi-line string to convert
+// @param dst The converted string is appended to this string
+// @param auto_end_last_line Automatically terminate the last line
+//
+// Limitations:
+//
+// This does not do the right thing for CRCRLF files created by
+// broken programs that do another Unix->DOS conversion on files
+// that are already in CRLF format. For this, a two-pass approach
+// brute-force would be needed that
+//
+// (1) determines the presence of LF (first one is ok)
+// (2) if yes, removes any CR, else convert every CR to LF
+PROTOBUF_EXPORT void CleanStringLineEndings(const 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 <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_STUBS_STRUTIL_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/stubs/strutil_unittest.cc b/NorthstarDedicatedTest/include/protobuf/stubs/strutil_unittest.cc
new file mode 100644
index 00000000..6be887c7
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/stubs/strutil_unittest.cc
@@ -0,0 +1,884 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 <stubs/strutil.h>
+
+#include <locale.h>
+
+#include <stubs/stl_util.h>
+#include <testing/googletest.h>
+#include <gtest/gtest.h>
+
+#ifdef _WIN32
+#define snprintf _snprintf
+#endif
+
+namespace google {
+namespace protobuf {
+namespace {
+
+// TODO(kenton): Copy strutil tests from google3?
+
+TEST(StringUtilityTest, ImmuneToLocales) {
+ // Remember the old locale.
+ char* old_locale_cstr = setlocale(LC_NUMERIC, nullptr);
+ ASSERT_TRUE(old_locale_cstr != nullptr);
+ std::string old_locale = old_locale_cstr;
+
+ // Set the locale to "C".
+ ASSERT_TRUE(setlocale(LC_NUMERIC, "C") != nullptr);
+
+ EXPECT_EQ("1.5", SimpleDtoa(1.5));
+ EXPECT_EQ("1.5", SimpleFtoa(1.5));
+
+ if (setlocale(LC_NUMERIC, "es_ES") == nullptr &&
+ setlocale(LC_NUMERIC, "es_ES.utf8") == nullptr) {
+ // Some systems may not have the desired locale available.
+ GOOGLE_LOG(WARNING)
+ << "Couldn't set locale to es_ES. Skipping this test.";
+ } else {
+ EXPECT_EQ("1.5", SimpleDtoa(1.5));
+ EXPECT_EQ("1.5", SimpleFtoa(1.5));
+ }
+
+ // Return to original locale.
+ setlocale(LC_NUMERIC, old_locale.c_str());
+}
+
+#define EXPECT_EQ_ARRAY(len, x, y, msg) \
+ for (int j = 0; j < len; ++j) { \
+ EXPECT_EQ(x[j], y[j]) << "" # x << " != " # y \
+ << " byte " << j << ": " << msg; \
+ }
+
+static struct {
+ int plain_length;
+ const char* plaintext;
+ const char* ciphertext;
+} base64_tests[] = {
+ // Empty string.
+ { 0, "", ""},
+
+ // Basic bit patterns;
+ // values obtained with "echo -n '...' | uuencode -m test"
+
+ { 1, "\000", "AA==" },
+ { 1, "\001", "AQ==" },
+ { 1, "\002", "Ag==" },
+ { 1, "\004", "BA==" },
+ { 1, "\010", "CA==" },
+ { 1, "\020", "EA==" },
+ { 1, "\040", "IA==" },
+ { 1, "\100", "QA==" },
+ { 1, "\200", "gA==" },
+
+ { 1, "\377", "/w==" },
+ { 1, "\376", "/g==" },
+ { 1, "\375", "/Q==" },
+ { 1, "\373", "+w==" },
+ { 1, "\367", "9w==" },
+ { 1, "\357", "7w==" },
+ { 1, "\337", "3w==" },
+ { 1, "\277", "vw==" },
+ { 1, "\177", "fw==" },
+ { 2, "\000\000", "AAA=" },
+ { 2, "\000\001", "AAE=" },
+ { 2, "\000\002", "AAI=" },
+ { 2, "\000\004", "AAQ=" },
+ { 2, "\000\010", "AAg=" },
+ { 2, "\000\020", "ABA=" },
+ { 2, "\000\040", "ACA=" },
+ { 2, "\000\100", "AEA=" },
+ { 2, "\000\200", "AIA=" },
+ { 2, "\001\000", "AQA=" },
+ { 2, "\002\000", "AgA=" },
+ { 2, "\004\000", "BAA=" },
+ { 2, "\010\000", "CAA=" },
+ { 2, "\020\000", "EAA=" },
+ { 2, "\040\000", "IAA=" },
+ { 2, "\100\000", "QAA=" },
+ { 2, "\200\000", "gAA=" },
+
+ { 2, "\377\377", "//8=" },
+ { 2, "\377\376", "//4=" },
+ { 2, "\377\375", "//0=" },
+ { 2, "\377\373", "//s=" },
+ { 2, "\377\367", "//c=" },
+ { 2, "\377\357", "/+8=" },
+ { 2, "\377\337", "/98=" },
+ { 2, "\377\277", "/78=" },
+ { 2, "\377\177", "/38=" },
+ { 2, "\376\377", "/v8=" },
+ { 2, "\375\377", "/f8=" },
+ { 2, "\373\377", "+/8=" },
+ { 2, "\367\377", "9/8=" },
+ { 2, "\357\377", "7/8=" },
+ { 2, "\337\377", "3/8=" },
+ { 2, "\277\377", "v/8=" },
+ { 2, "\177\377", "f/8=" },
+
+ { 3, "\000\000\000", "AAAA" },
+ { 3, "\000\000\001", "AAAB" },
+ { 3, "\000\000\002", "AAAC" },
+ { 3, "\000\000\004", "AAAE" },
+ { 3, "\000\000\010", "AAAI" },
+ { 3, "\000\000\020", "AAAQ" },
+ { 3, "\000\000\040", "AAAg" },
+ { 3, "\000\000\100", "AABA" },
+ { 3, "\000\000\200", "AACA" },
+ { 3, "\000\001\000", "AAEA" },
+ { 3, "\000\002\000", "AAIA" },
+ { 3, "\000\004\000", "AAQA" },
+ { 3, "\000\010\000", "AAgA" },
+ { 3, "\000\020\000", "ABAA" },
+ { 3, "\000\040\000", "ACAA" },
+ { 3, "\000\100\000", "AEAA" },
+ { 3, "\000\200\000", "AIAA" },
+ { 3, "\001\000\000", "AQAA" },
+ { 3, "\002\000\000", "AgAA" },
+ { 3, "\004\000\000", "BAAA" },
+ { 3, "\010\000\000", "CAAA" },
+ { 3, "\020\000\000", "EAAA" },
+ { 3, "\040\000\000", "IAAA" },
+ { 3, "\100\000\000", "QAAA" },
+ { 3, "\200\000\000", "gAAA" },
+
+ { 3, "\377\377\377", "////" },
+ { 3, "\377\377\376", "///+" },
+ { 3, "\377\377\375", "///9" },
+ { 3, "\377\377\373", "///7" },
+ { 3, "\377\377\367", "///3" },
+ { 3, "\377\377\357", "///v" },
+ { 3, "\377\377\337", "///f" },
+ { 3, "\377\377\277", "//+/" },
+ { 3, "\377\377\177", "//9/" },
+ { 3, "\377\376\377", "//7/" },
+ { 3, "\377\375\377", "//3/" },
+ { 3, "\377\373\377", "//v/" },
+ { 3, "\377\367\377", "//f/" },
+ { 3, "\377\357\377", "/+//" },
+ { 3, "\377\337\377", "/9//" },
+ { 3, "\377\277\377", "/7//" },
+ { 3, "\377\177\377", "/3//" },
+ { 3, "\376\377\377", "/v//" },
+ { 3, "\375\377\377", "/f//" },
+ { 3, "\373\377\377", "+///" },
+ { 3, "\367\377\377", "9///" },
+ { 3, "\357\377\377", "7///" },
+ { 3, "\337\377\377", "3///" },
+ { 3, "\277\377\377", "v///" },
+ { 3, "\177\377\377", "f///" },
+
+ // Random numbers: values obtained with
+ //
+ // #! /bin/bash
+ // dd bs=$1 count=1 if=/dev/random of=/tmp/bar.random
+ // od -N $1 -t o1 /tmp/bar.random
+ // uuencode -m test < /tmp/bar.random
+ //
+ // where $1 is the number of bytes (2, 3)
+
+ { 2, "\243\361", "o/E=" },
+ { 2, "\024\167", "FHc=" },
+ { 2, "\313\252", "y6o=" },
+ { 2, "\046\041", "JiE=" },
+ { 2, "\145\236", "ZZ4=" },
+ { 2, "\254\325", "rNU=" },
+ { 2, "\061\330", "Mdg=" },
+ { 2, "\245\032", "pRo=" },
+ { 2, "\006\000", "BgA=" },
+ { 2, "\375\131", "/Vk=" },
+ { 2, "\303\210", "w4g=" },
+ { 2, "\040\037", "IB8=" },
+ { 2, "\261\372", "sfo=" },
+ { 2, "\335\014", "3Qw=" },
+ { 2, "\233\217", "m48=" },
+ { 2, "\373\056", "+y4=" },
+ { 2, "\247\232", "p5o=" },
+ { 2, "\107\053", "Rys=" },
+ { 2, "\204\077", "hD8=" },
+ { 2, "\276\211", "vok=" },
+ { 2, "\313\110", "y0g=" },
+ { 2, "\363\376", "8/4=" },
+ { 2, "\251\234", "qZw=" },
+ { 2, "\103\262", "Q7I=" },
+ { 2, "\142\312", "Yso=" },
+ { 2, "\067\211", "N4k=" },
+ { 2, "\220\001", "kAE=" },
+ { 2, "\152\240", "aqA=" },
+ { 2, "\367\061", "9zE=" },
+ { 2, "\133\255", "W60=" },
+ { 2, "\176\035", "fh0=" },
+ { 2, "\032\231", "Gpk=" },
+
+ { 3, "\013\007\144", "Cwdk" },
+ { 3, "\030\112\106", "GEpG" },
+ { 3, "\047\325\046", "J9Um" },
+ { 3, "\310\160\022", "yHAS" },
+ { 3, "\131\100\237", "WUCf" },
+ { 3, "\064\342\134", "NOJc" },
+ { 3, "\010\177\004", "CH8E" },
+ { 3, "\345\147\205", "5WeF" },
+ { 3, "\300\343\360", "wOPw" },
+ { 3, "\061\240\201", "MaCB" },
+ { 3, "\225\333\044", "ldsk" },
+ { 3, "\215\137\352", "jV/q" },
+ { 3, "\371\147\160", "+Wdw" },
+ { 3, "\030\320\051", "GNAp" },
+ { 3, "\044\174\241", "JHyh" },
+ { 3, "\260\127\037", "sFcf" },
+ { 3, "\111\045\033", "SSUb" },
+ { 3, "\202\114\107", "gkxH" },
+ { 3, "\057\371\042", "L/ki" },
+ { 3, "\223\247\244", "k6ek" },
+ { 3, "\047\216\144", "J45k" },
+ { 3, "\203\070\327", "gzjX" },
+ { 3, "\247\140\072", "p2A6" },
+ { 3, "\124\115\116", "VE1O" },
+ { 3, "\157\162\050", "b3Io" },
+ { 3, "\357\223\004", "75ME" },
+ { 3, "\052\117\156", "Kk9u" },
+ { 3, "\347\154\000", "52wA" },
+ { 3, "\303\012\142", "wwpi" },
+ { 3, "\060\035\362", "MB3y" },
+ { 3, "\130\226\361", "WJbx" },
+ { 3, "\173\013\071", "ews5" },
+ { 3, "\336\004\027", "3gQX" },
+ { 3, "\357\366\234", "7/ac" },
+ { 3, "\353\304\111", "68RJ" },
+ { 3, "\024\264\131", "FLRZ" },
+ { 3, "\075\114\251", "PUyp" },
+ { 3, "\315\031\225", "zRmV" },
+ { 3, "\154\201\276", "bIG+" },
+ { 3, "\200\066\072", "gDY6" },
+ { 3, "\142\350\267", "Yui3" },
+ { 3, "\033\000\166", "GwB2" },
+ { 3, "\210\055\077", "iC0/" },
+ { 3, "\341\037\124", "4R9U" },
+ { 3, "\161\103\152", "cUNq" },
+ { 3, "\270\142\131", "uGJZ" },
+ { 3, "\337\076\074", "3z48" },
+ { 3, "\375\106\362", "/Uby" },
+ { 3, "\227\301\127", "l8FX" },
+ { 3, "\340\002\234", "4AKc" },
+ { 3, "\121\064\033", "UTQb" },
+ { 3, "\157\134\143", "b1xj" },
+ { 3, "\247\055\327", "py3X" },
+ { 3, "\340\142\005", "4GIF" },
+ { 3, "\060\260\143", "MLBj" },
+ { 3, "\075\203\170", "PYN4" },
+ { 3, "\143\160\016", "Y3AO" },
+ { 3, "\313\013\063", "ywsz" },
+ { 3, "\174\236\135", "fJ5d" },
+ { 3, "\103\047\026", "QycW" },
+ { 3, "\365\005\343", "9QXj" },
+ { 3, "\271\160\223", "uXCT" },
+ { 3, "\362\255\172", "8q16" },
+ { 3, "\113\012\015", "SwoN" },
+
+ // various lengths, generated by this python script:
+ //
+ // from string import lowercase as lc
+ // for i in range(27):
+ // print '{ %2d, "%s",%s "%s" },' % (i, lc[:i], ' ' * (26-i),
+ // lc[:i].encode('base64').strip())
+
+ { 0, "", "" },
+ { 1, "a", "YQ==" },
+ { 2, "ab", "YWI=" },
+ { 3, "abc", "YWJj" },
+ { 4, "abcd", "YWJjZA==" },
+ { 5, "abcde", "YWJjZGU=" },
+ { 6, "abcdef", "YWJjZGVm" },
+ { 7, "abcdefg", "YWJjZGVmZw==" },
+ { 8, "abcdefgh", "YWJjZGVmZ2g=" },
+ { 9, "abcdefghi", "YWJjZGVmZ2hp" },
+ { 10, "abcdefghij", "YWJjZGVmZ2hpag==" },
+ { 11, "abcdefghijk", "YWJjZGVmZ2hpams=" },
+ { 12, "abcdefghijkl", "YWJjZGVmZ2hpamts" },
+ { 13, "abcdefghijklm", "YWJjZGVmZ2hpamtsbQ==" },
+ { 14, "abcdefghijklmn", "YWJjZGVmZ2hpamtsbW4=" },
+ { 15, "abcdefghijklmno", "YWJjZGVmZ2hpamtsbW5v" },
+ { 16, "abcdefghijklmnop", "YWJjZGVmZ2hpamtsbW5vcA==" },
+ { 17, "abcdefghijklmnopq", "YWJjZGVmZ2hpamtsbW5vcHE=" },
+ { 18, "abcdefghijklmnopqr", "YWJjZGVmZ2hpamtsbW5vcHFy" },
+ { 19, "abcdefghijklmnopqrs", "YWJjZGVmZ2hpamtsbW5vcHFycw==" },
+ { 20, "abcdefghijklmnopqrst", "YWJjZGVmZ2hpamtsbW5vcHFyc3Q=" },
+ { 21, "abcdefghijklmnopqrstu", "YWJjZGVmZ2hpamtsbW5vcHFyc3R1" },
+ { 22, "abcdefghijklmnopqrstuv", "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dg==" },
+ { 23, "abcdefghijklmnopqrstuvw", "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnc=" },
+ { 24, "abcdefghijklmnopqrstuvwx", "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4" },
+ { 25, "abcdefghijklmnopqrstuvwxy", "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eQ==" },
+ { 26, "abcdefghijklmnopqrstuvwxyz", "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXo=" },
+};
+
+static struct {
+ const char* plaintext;
+ const char* ciphertext;
+} base64_strings[] = {
+ // Some google quotes
+ // Ciphertext created with "uuencode (GNU sharutils) 4.6.3"
+ // (Note that we're testing the websafe encoding, though, so if
+ // you add messages, be sure to run "tr -- '+/' '-_'" on the output)
+ {"I was always good at math and science, and I never realized "
+ "that was unusual or somehow undesirable. So one of the things "
+ "I care a lot about is helping to remove that stigma, "
+ "to show girls that you can be feminine, you can like the things "
+ "that girls like, but you can also be really good at technology. "
+ "You can be really good at building things."
+ " - Marissa Meyer, Newsweek, 2010-12-22"
+ "\n",
+
+ "SSB3YXMgYWx3YXlzIGdvb2QgYXQgbWF0aCBhbmQgc2NpZW5jZSwgYW5kIEkg"
+ "bmV2ZXIgcmVhbGl6ZWQgdGhhdCB3YXMgdW51c3VhbCBvciBzb21laG93IHVu"
+ "ZGVzaXJhYmxlLiBTbyBvbmUgb2YgdGhlIHRoaW5ncyBJIGNhcmUgYSBsb3Qg"
+ "YWJvdXQgaXMgaGVscGluZyB0byByZW1vdmUgdGhhdCBzdGlnbWEsIHRvIHNo"
+ "b3cgZ2lybHMgdGhhdCB5b3UgY2FuIGJlIGZlbWluaW5lLCB5b3UgY2FuIGxp"
+ "a2UgdGhlIHRoaW5ncyB0aGF0IGdpcmxzIGxpa2UsIGJ1dCB5b3UgY2FuIGFs"
+ "c28gYmUgcmVhbGx5IGdvb2QgYXQgdGVjaG5vbG9neS4gWW91IGNhbiBiZSBy"
+ "ZWFsbHkgZ29vZCBhdCBidWlsZGluZyB0aGluZ3MuIC0gTWFyaXNzYSBNZXll"
+ "ciwgTmV3c3dlZWssIDIwMTAtMTItMjIK"},
+
+ {"Typical first year for a new cluster: "
+ "~0.5 overheating "
+ "~1 PDU failure "
+ "~1 rack-move "
+ "~1 network rewiring "
+ "~20 rack failures "
+ "~5 racks go wonky "
+ "~8 network maintenances "
+ "~12 router reloads "
+ "~3 router failures "
+ "~dozens of minor 30-second blips for dns "
+ "~1000 individual machine failures "
+ "~thousands of hard drive failures "
+ "slow disks, bad memory, misconfigured machines, flaky machines, etc."
+ " - Jeff Dean, The Joys of Real Hardware"
+ "\n",
+
+ "VHlwaWNhbCBmaXJzdCB5ZWFyIGZvciBhIG5ldyBjbHVzdGVyOiB-MC41IG92"
+ "ZXJoZWF0aW5nIH4xIFBEVSBmYWlsdXJlIH4xIHJhY2stbW92ZSB-MSBuZXR3"
+ "b3JrIHJld2lyaW5nIH4yMCByYWNrIGZhaWx1cmVzIH41IHJhY2tzIGdvIHdv"
+ "bmt5IH44IG5ldHdvcmsgbWFpbnRlbmFuY2VzIH4xMiByb3V0ZXIgcmVsb2Fk"
+ "cyB-MyByb3V0ZXIgZmFpbHVyZXMgfmRvemVucyBvZiBtaW5vciAzMC1zZWNv"
+ "bmQgYmxpcHMgZm9yIGRucyB-MTAwMCBpbmRpdmlkdWFsIG1hY2hpbmUgZmFp"
+ "bHVyZXMgfnRob3VzYW5kcyBvZiBoYXJkIGRyaXZlIGZhaWx1cmVzIHNsb3cg"
+ "ZGlza3MsIGJhZCBtZW1vcnksIG1pc2NvbmZpZ3VyZWQgbWFjaGluZXMsIGZs"
+ "YWt5IG1hY2hpbmVzLCBldGMuIC0gSmVmZiBEZWFuLCBUaGUgSm95cyBvZiBS"
+ "ZWFsIEhhcmR3YXJlCg"},
+
+ {"I'm the head of the webspam team at Google. "
+ "That means that if you type your name into Google and get porn back, "
+ "it's my fault. Unless you're a porn star, in which case porn is a "
+ "completely reasonable response."
+ " - Matt Cutts, Google Plus"
+ "\n",
+
+ "SSdtIHRoZSBoZWFkIG9mIHRoZSB3ZWJzcGFtIHRlYW0gYXQgR29vZ2xlLiAg"
+ "VGhhdCBtZWFucyB0aGF0IGlmIHlvdSB0eXBlIHlvdXIgbmFtZSBpbnRvIEdv"
+ "b2dsZSBhbmQgZ2V0IHBvcm4gYmFjaywgaXQncyBteSBmYXVsdC4gVW5sZXNz"
+ "IHlvdSdyZSBhIHBvcm4gc3RhciwgaW4gd2hpY2ggY2FzZSBwb3JuIGlzIGEg"
+ "Y29tcGxldGVseSByZWFzb25hYmxlIHJlc3BvbnNlLiAtIE1hdHQgQ3V0dHMs"
+ "IEdvb2dsZSBQbHVzCg"},
+
+ {"It will still be a long time before machines approach human "
+ "intelligence. "
+ "But luckily, machines don't actually have to be intelligent; "
+ "they just have to fake it. Access to a wealth of information, "
+ "combined with a rudimentary decision-making capacity, "
+ "can often be almost as useful. Of course, the results are better yet "
+ "when coupled with intelligence. A reference librarian with access to "
+ "a good search engine is a formidable tool."
+ " - Craig Silverstein, Siemens Pictures of the Future, Spring 2004"
+ "\n",
+
+ "SXQgd2lsbCBzdGlsbCBiZSBhIGxvbmcgdGltZSBiZWZvcmUgbWFjaGluZXMg"
+ "YXBwcm9hY2ggaHVtYW4gaW50ZWxsaWdlbmNlLiBCdXQgbHVja2lseSwgbWFj"
+ "aGluZXMgZG9uJ3QgYWN0dWFsbHkgaGF2ZSB0byBiZSBpbnRlbGxpZ2VudDsg"
+ "dGhleSBqdXN0IGhhdmUgdG8gZmFrZSBpdC4gQWNjZXNzIHRvIGEgd2VhbHRo"
+ "IG9mIGluZm9ybWF0aW9uLCBjb21iaW5lZCB3aXRoIGEgcnVkaW1lbnRhcnkg"
+ "ZGVjaXNpb24tbWFraW5nIGNhcGFjaXR5LCBjYW4gb2Z0ZW4gYmUgYWxtb3N0"
+ "IGFzIHVzZWZ1bC4gT2YgY291cnNlLCB0aGUgcmVzdWx0cyBhcmUgYmV0dGVy"
+ "IHlldCB3aGVuIGNvdXBsZWQgd2l0aCBpbnRlbGxpZ2VuY2UuIEEgcmVmZXJl"
+ "bmNlIGxpYnJhcmlhbiB3aXRoIGFjY2VzcyB0byBhIGdvb2Qgc2VhcmNoIGVu"
+ "Z2luZSBpcyBhIGZvcm1pZGFibGUgdG9vbC4gLSBDcmFpZyBTaWx2ZXJzdGVp"
+ "biwgU2llbWVucyBQaWN0dXJlcyBvZiB0aGUgRnV0dXJlLCBTcHJpbmcgMjAw"
+ "NAo"},
+
+ // Degenerate edge case
+ {"", ""},
+};
+
+TEST(Base64, EscapeAndUnescape) {
+ // Check the short strings; this tests the math (and boundaries)
+ for (int i = 0; i < sizeof(base64_tests) / sizeof(base64_tests[0]); ++i) {
+ char encode_buffer[100];
+ int encode_length;
+ char decode_buffer[100];
+ int decode_length;
+ int cipher_length;
+ std::string decode_str;
+
+ const unsigned char* unsigned_plaintext =
+ reinterpret_cast<const unsigned char*>(base64_tests[i].plaintext);
+
+ StringPiece plaintext(base64_tests[i].plaintext,
+ base64_tests[i].plain_length);
+
+ cipher_length = strlen(base64_tests[i].ciphertext);
+
+ // The basic escape function:
+ memset(encode_buffer, 0, sizeof(encode_buffer));
+ encode_length = Base64Escape(unsigned_plaintext,
+ base64_tests[i].plain_length,
+ encode_buffer,
+ sizeof(encode_buffer));
+ // Is it of the expected length?
+ EXPECT_EQ(encode_length, cipher_length);
+ // Would it have been okay to allocate only CalculateBase64EscapeLen()?
+ EXPECT_EQ(CalculateBase64EscapedLen(base64_tests[i].plain_length),
+ encode_length);
+
+ // Is it the expected encoded value?
+ ASSERT_STREQ(encode_buffer, base64_tests[i].ciphertext);
+
+ // If we encode it into a buffer of exactly the right length...
+ memset(encode_buffer, 0, sizeof(encode_buffer));
+ encode_length =
+ Base64Escape(unsigned_plaintext, base64_tests[i].plain_length,
+ encode_buffer, cipher_length);
+ // Is it still of the expected length?
+ EXPECT_EQ(encode_length, cipher_length);
+
+ // And is the value still correct? (i.e., not losing the last byte)
+ EXPECT_STREQ(encode_buffer, base64_tests[i].ciphertext);
+
+ // If we decode it back:
+ decode_str.clear();
+ EXPECT_TRUE(
+ Base64Unescape(StringPiece(encode_buffer, cipher_length), &decode_str));
+
+ // Is it of the expected length?
+ EXPECT_EQ(base64_tests[i].plain_length, decode_str.length());
+
+ // Is it the expected decoded value?
+ EXPECT_EQ(plaintext, decode_str);
+
+ // Let's try with a pre-populated string.
+ std::string encoded("this junk should be ignored");
+ Base64Escape(
+ std::string(base64_tests[i].plaintext, base64_tests[i].plain_length),
+ &encoded);
+ EXPECT_EQ(encoded, std::string(encode_buffer, cipher_length));
+
+ std::string decoded("this junk should be ignored");
+ EXPECT_TRUE(
+ Base64Unescape(StringPiece(encode_buffer, cipher_length), &decoded));
+ EXPECT_EQ(decoded.size(), base64_tests[i].plain_length);
+ EXPECT_EQ_ARRAY(decoded.size(), decoded, base64_tests[i].plaintext, i);
+
+ // Our decoder treats the padding '=' characters at the end as
+ // optional (but if there are any, there must be the correct
+ // number of them.) If encode_buffer has any, run some additional
+ // tests that fiddle with them.
+ char* first_equals = strchr(encode_buffer, '=');
+ if (first_equals) {
+ // How many equals signs does the string start with?
+ int equals = (*(first_equals+1) == '=') ? 2 : 1;
+
+ // Try chopping off the equals sign(s) entirely. The decoder
+ // should still be okay with this.
+ std::string decoded2("this junk should also be ignored");
+ *first_equals = '\0';
+ EXPECT_TRUE(Base64Unescape(
+ StringPiece(encode_buffer, first_equals - encode_buffer), &decoded2));
+ EXPECT_EQ(decoded.size(), base64_tests[i].plain_length);
+ EXPECT_EQ_ARRAY(decoded.size(), decoded, base64_tests[i].plaintext, i);
+
+ // Now test chopping off the equals sign(s) and adding
+ // whitespace. Our decoder should still accept this.
+ decoded2.assign("this junk should be ignored");
+ *first_equals = ' ';
+ *(first_equals+1) = '\0';
+ EXPECT_TRUE(Base64Unescape(
+ StringPiece(encode_buffer, first_equals - encode_buffer + 1),
+ &decoded2));
+ EXPECT_EQ(decoded.size(), base64_tests[i].plain_length);
+ EXPECT_EQ_ARRAY(decoded.size(), decoded, base64_tests[i].plaintext, i);
+
+ // Now stick a bad character at the end of the string. The decoder
+ // should refuse this string.
+ decoded2.assign("this junk should be ignored");
+ *first_equals = '?';
+ *(first_equals+1) = '\0';
+ EXPECT_TRUE(
+ !Base64Unescape(
+ StringPiece(encode_buffer, first_equals - encode_buffer + 1),
+ &decoded2));
+
+ int len;
+
+ // Test whitespace mixed with the padding. (eg "AA = = ") The
+ // decoder should accept this.
+ if (equals == 2) {
+ snprintf(first_equals, 6, " = = ");
+ len = first_equals - encode_buffer + 5;
+ } else {
+ snprintf(first_equals, 6, " = ");
+ len = first_equals - encode_buffer + 3;
+ }
+ decoded2.assign("this junk should be ignored");
+ EXPECT_TRUE(
+ Base64Unescape(StringPiece(encode_buffer, len), &decoded2));
+ EXPECT_EQ(decoded.size(), base64_tests[i].plain_length);
+ EXPECT_EQ_ARRAY(decoded.size(), decoded, base64_tests[i].plaintext, i);
+
+ // Test whitespace mixed with the padding, but with the wrong
+ // number of equals signs (eg "AA = "). The decoder should
+ // refuse these strings.
+ if (equals == 1) {
+ snprintf(first_equals, 6, " = = ");
+ len = first_equals - encode_buffer + 5;
+ } else {
+ snprintf(first_equals, 6, " = ");
+ len = first_equals - encode_buffer + 3;
+ }
+ EXPECT_TRUE(
+ !Base64Unescape(StringPiece(encode_buffer, len), &decoded2));
+ }
+
+ // Cool! the basic Base64 encoder/decoder works.
+ // Let's try the alternate alphabet: tr -- '+/' '-_'
+
+ char websafe[100];
+ memset(websafe, 0, sizeof(websafe));
+ strncpy(websafe, base64_tests[i].ciphertext, cipher_length);
+ for (int c = 0; c < sizeof(websafe); ++c) {
+ if ('+' == websafe[c]) { websafe[c] = '-'; }
+ if ('/' == websafe[c]) { websafe[c] = '_'; }
+ }
+
+ // The websafe escape function:
+ memset(encode_buffer, 0, sizeof(encode_buffer));
+ encode_length = WebSafeBase64Escape(unsigned_plaintext,
+ base64_tests[i].plain_length,
+ encode_buffer,
+ sizeof(encode_buffer),
+ true);
+ // Is it of the expected length?
+ EXPECT_EQ(encode_length, cipher_length);
+ EXPECT_EQ(
+ CalculateBase64EscapedLen(base64_tests[i].plain_length, true),
+ encode_length);
+
+ // Is it the expected encoded value?
+ EXPECT_STREQ(encode_buffer, websafe);
+
+ // If we encode it into a buffer of exactly the right length...
+ memset(encode_buffer, 0, sizeof(encode_buffer));
+ encode_length =
+ WebSafeBase64Escape(unsigned_plaintext, base64_tests[i].plain_length,
+ encode_buffer, cipher_length, true);
+ // Is it still of the expected length?
+ EXPECT_EQ(encode_length, cipher_length);
+
+ // And is the value still correct? (i.e., not losing the last byte)
+ EXPECT_STREQ(encode_buffer, websafe);
+
+ // Let's try the string version of the encoder
+ encoded = "this junk should be ignored";
+ WebSafeBase64Escape(
+ unsigned_plaintext, base64_tests[i].plain_length,
+ &encoded, true);
+ EXPECT_EQ(encoded.size(), cipher_length);
+ EXPECT_STREQ(encoded.c_str(), websafe);
+
+ // If we decode it back:
+ memset(decode_buffer, 0, sizeof(decode_buffer));
+ decode_length = WebSafeBase64Unescape(encode_buffer, cipher_length,
+ decode_buffer, sizeof(decode_buffer));
+
+ // Is it of the expected length?
+ EXPECT_EQ(decode_length, base64_tests[i].plain_length);
+
+ // Is it the expected decoded value?
+ EXPECT_EQ(0,
+ memcmp(decode_buffer, base64_tests[i].plaintext, decode_length));
+
+ // If we decode it into a buffer of exactly the right length...
+ memset(decode_buffer, 0, sizeof(decode_buffer));
+ decode_length = WebSafeBase64Unescape(encode_buffer, cipher_length,
+ decode_buffer, decode_length);
+
+ // Is it still of the expected length?
+ EXPECT_EQ(decode_length, base64_tests[i].plain_length);
+
+ // And is it the expected decoded value?
+ EXPECT_EQ(0,
+ memcmp(decode_buffer, base64_tests[i].plaintext, decode_length));
+
+ // Try using '.' for the pad character.
+ for (int c = cipher_length - 1; c >= 0 && '=' == encode_buffer[c]; --c) {
+ encode_buffer[c] = '.';
+ }
+
+ // If we decode it back:
+ memset(decode_buffer, 0, sizeof(decode_buffer));
+ decode_length = WebSafeBase64Unescape(encode_buffer, cipher_length,
+ decode_buffer, sizeof(decode_buffer));
+
+ // Is it of the expected length?
+ EXPECT_EQ(decode_length, base64_tests[i].plain_length);
+
+ // Is it the expected decoded value?
+ EXPECT_EQ(0,
+ memcmp(decode_buffer, base64_tests[i].plaintext, decode_length));
+
+ // If we decode it into a buffer of exactly the right length...
+ memset(decode_buffer, 0, sizeof(decode_buffer));
+ decode_length = WebSafeBase64Unescape(encode_buffer, cipher_length,
+ decode_buffer, decode_length);
+
+ // Is it still of the expected length?
+ EXPECT_EQ(decode_length, base64_tests[i].plain_length);
+
+ // And is it the expected decoded value?
+ EXPECT_EQ(0,
+ memcmp(decode_buffer, base64_tests[i].plaintext, decode_length));
+
+ // Let's try the string version of the decoder
+ decoded = "this junk should be ignored";
+ EXPECT_TRUE(WebSafeBase64Unescape(StringPiece(encode_buffer, cipher_length),
+ &decoded));
+ EXPECT_EQ(decoded.size(), base64_tests[i].plain_length);
+ EXPECT_EQ_ARRAY(decoded.size(), decoded, base64_tests[i].plaintext, i);
+
+ // Okay! the websafe Base64 encoder/decoder works.
+ // Let's try the unpadded version
+
+ for (int c = 0; c < sizeof(websafe); ++c) {
+ if ('=' == websafe[c]) {
+ websafe[c] = '\0';
+ cipher_length = c;
+ break;
+ }
+ }
+
+ // The websafe escape function:
+ memset(encode_buffer, 0, sizeof(encode_buffer));
+ encode_length = WebSafeBase64Escape(unsigned_plaintext,
+ base64_tests[i].plain_length,
+ encode_buffer,
+ sizeof(encode_buffer),
+ false);
+ // Is it of the expected length?
+ EXPECT_EQ(encode_length, cipher_length);
+ EXPECT_EQ(
+ CalculateBase64EscapedLen(base64_tests[i].plain_length, false),
+ encode_length);
+
+ // Is it the expected encoded value?
+ EXPECT_STREQ(encode_buffer, websafe);
+
+ // If we encode it into a buffer of exactly the right length...
+ memset(encode_buffer, 0, sizeof(encode_buffer));
+ encode_length =
+ WebSafeBase64Escape(unsigned_plaintext, base64_tests[i].plain_length,
+ encode_buffer, cipher_length, false);
+ // Is it still of the expected length?
+ EXPECT_EQ(encode_length, cipher_length);
+
+ // And is the value still correct? (i.e., not losing the last byte)
+ EXPECT_STREQ(encode_buffer, websafe);
+
+ // Let's try the (other) string version of the encoder
+ std::string plain(base64_tests[i].plaintext, base64_tests[i].plain_length);
+ encoded = "this junk should be ignored";
+ WebSafeBase64Escape(plain, &encoded);
+ EXPECT_EQ(encoded.size(), cipher_length);
+ EXPECT_STREQ(encoded.c_str(), websafe);
+
+ // If we decode it back:
+ memset(decode_buffer, 0, sizeof(decode_buffer));
+ decode_length = WebSafeBase64Unescape(encode_buffer, cipher_length,
+ decode_buffer, sizeof(decode_buffer));
+
+ // Is it of the expected length?
+ EXPECT_EQ(decode_length, base64_tests[i].plain_length);
+
+ // Is it the expected decoded value?
+ EXPECT_EQ(0,
+ memcmp(decode_buffer, base64_tests[i].plaintext, decode_length));
+
+ // If we decode it into a buffer of exactly the right length...
+ memset(decode_buffer, 0, sizeof(decode_buffer));
+ decode_length = WebSafeBase64Unescape(encode_buffer, cipher_length,
+ decode_buffer, decode_length);
+
+ // Is it still of the expected length?
+ EXPECT_EQ(decode_length, base64_tests[i].plain_length);
+
+ // And is it the expected decoded value?
+ EXPECT_EQ(0,
+ memcmp(decode_buffer, base64_tests[i].plaintext, decode_length));
+
+
+ // Let's try the string version of the decoder
+ decoded = "this junk should be ignored";
+ EXPECT_TRUE(WebSafeBase64Unescape(StringPiece(encode_buffer, cipher_length),
+ &decoded));
+ EXPECT_EQ(decoded.size(), base64_tests[i].plain_length);
+ EXPECT_EQ_ARRAY(decoded.size(), decoded, base64_tests[i].plaintext, i);
+
+ // This value works. Try the next.
+ }
+
+ // Now try the long strings, this tests the streaming
+ for (int i = 0; i < sizeof(base64_strings) / sizeof(base64_strings[0]);
+ ++i) {
+ const unsigned char* unsigned_plaintext =
+ reinterpret_cast<const unsigned char*>(base64_strings[i].plaintext);
+ int plain_length = strlen(base64_strings[i].plaintext);
+ int cipher_length = strlen(base64_strings[i].ciphertext);
+ std::vector<char> buffer(cipher_length + 1);
+ int encode_length = WebSafeBase64Escape(unsigned_plaintext,
+ plain_length,
+ &buffer[0],
+ buffer.size(),
+ false);
+ EXPECT_EQ(cipher_length, encode_length);
+ EXPECT_EQ(
+ CalculateBase64EscapedLen(plain_length, false), encode_length);
+ buffer[ encode_length ] = '\0';
+ EXPECT_STREQ(base64_strings[i].ciphertext, &buffer[0]);
+ }
+
+ // Verify the behavior when decoding bad data
+ {
+ const char* bad_data = "ab-/";
+ std::string buf;
+ EXPECT_FALSE(Base64Unescape(StringPiece(bad_data), &buf));
+ EXPECT_TRUE(!WebSafeBase64Unescape(bad_data, &buf));
+ EXPECT_TRUE(buf.empty());
+ }
+}
+
+// Test StrCat of ints and longs of various sizes and signdedness.
+TEST(StrCat, Ints) {
+ const short s = -1; // NOLINT(runtime/int)
+ const uint16_t us = 2;
+ const int i = -3;
+ const unsigned int ui = 4;
+ const long l = -5; // NOLINT(runtime/int)
+ const unsigned long ul = 6; // NOLINT(runtime/int)
+ const long long ll = -7; // NOLINT(runtime/int)
+ const unsigned long long ull = 8; // NOLINT(runtime/int)
+ const ptrdiff_t ptrdiff = -9;
+ const size_t size = 10;
+ const intptr_t intptr = -12;
+ const uintptr_t uintptr = 13;
+ std::string answer;
+ answer = StrCat(s, us);
+ EXPECT_EQ(answer, "-12");
+ answer = StrCat(i, ui);
+ EXPECT_EQ(answer, "-34");
+ answer = StrCat(l, ul);
+ EXPECT_EQ(answer, "-56");
+ answer = StrCat(ll, ull);
+ EXPECT_EQ(answer, "-78");
+ answer = StrCat(ptrdiff, size);
+ EXPECT_EQ(answer, "-910");
+ answer = StrCat(ptrdiff, intptr);
+ EXPECT_EQ(answer, "-9-12");
+ answer = StrCat(uintptr, 0);
+ EXPECT_EQ(answer, "130");
+}
+
+class ReplaceChars
+ : public ::testing::TestWithParam<
+ std::tuple<std::string, std::string, const char*, char>> {};
+
+TEST_P(ReplaceChars, ReplacesAllOccurencesOfAnyCharInReplaceWithAReplaceChar) {
+ std::string expected = std::get<0>(GetParam());
+ std::string string_to_replace_in = std::get<1>(GetParam());
+ const char* what_to_replace = std::get<2>(GetParam());
+ char replacement = std::get<3>(GetParam());
+ ReplaceCharacters(&string_to_replace_in, what_to_replace, replacement);
+ ASSERT_EQ(expected, string_to_replace_in);
+}
+
+INSTANTIATE_TEST_CASE_P(
+ Replace, ReplaceChars,
+ ::testing::Values(
+ std::make_tuple("", "", "", '_'), // empty string should remain empty
+ std::make_tuple(" ", " ", "", '_'), // no replacement string
+ std::make_tuple(" ", " ", "_-abcedf",
+ '*'), // replacement character not in string
+ std::make_tuple("replace", "Replace", "R",
+ 'r'), // replace one character
+ std::make_tuple("not_spaces__", "not\nspaces\t ", " \t\r\n",
+ '_'), // replace some special characters
+ std::make_tuple("c++", "cxx", "x",
+ '+'), // same character multiple times
+ std::make_tuple("qvvvvvng v T", "queueing a T", "aeiou",
+ 'v'))); // replace all voewls
+
+class StripWs
+ : public ::testing::TestWithParam<std::tuple<std::string, std::string>> {};
+
+TEST_P(StripWs, AlwaysStripsLeadingAndTrailingWhitespace) {
+ std::string expected = std::get<0>(GetParam());
+ std::string string_to_strip = std::get<1>(GetParam());
+ StripWhitespace(&string_to_strip);
+ ASSERT_EQ(expected, string_to_strip);
+}
+
+INSTANTIATE_TEST_CASE_P(
+ Strip, StripWs,
+ ::testing::Values(
+ std::make_tuple("", ""), // empty string should remain empty
+ std::make_tuple("", " "), // only ws should become empty
+ std::make_tuple("no whitespace",
+ " no whitespace"), // leading ws removed
+ std::make_tuple("no whitespace",
+ "no whitespace "), // trailing ws removed
+ std::make_tuple("no whitespace",
+ " no whitespace "), // same nb. of leading and trailing
+ std::make_tuple(
+ "no whitespace",
+ " no whitespace "), // different nb. of leading/trailing
+ std::make_tuple("no whitespace",
+ " no whitespace "))); // more trailing than leading
+
+} // anonymous namespace
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/stubs/substitute.cc b/NorthstarDedicatedTest/include/protobuf/stubs/substitute.cc
new file mode 100644
index 00000000..5524def2
--- /dev/null
+++ b/NorthstarDedicatedTest/include/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 <stubs/substitute.h>
+
+#include <stubs/logging.h>
+#include <stubs/strutil.h>
+#include <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/NorthstarDedicatedTest/include/protobuf/stubs/substitute.h b/NorthstarDedicatedTest/include/protobuf/stubs/substitute.h
new file mode 100644
index 00000000..a7f560af
--- /dev/null
+++ b/NorthstarDedicatedTest/include/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 <stubs/common.h>
+#include <stubs/stringpiece.h>
+#include <stubs/strutil.h>
+
+#include <string>
+
+#ifndef GOOGLE_PROTOBUF_STUBS_SUBSTITUTE_H_
+#define GOOGLE_PROTOBUF_STUBS_SUBSTITUTE_H_
+
+#include <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 <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_STUBS_SUBSTITUTE_H_
diff --git a/NorthstarDedicatedTest/include/protobuf/stubs/template_util.h b/NorthstarDedicatedTest/include/protobuf/stubs/template_util.h
new file mode 100644
index 00000000..feef904b
--- /dev/null
+++ b/NorthstarDedicatedTest/include/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/NorthstarDedicatedTest/include/protobuf/stubs/template_util_unittest.cc b/NorthstarDedicatedTest/include/protobuf/stubs/template_util_unittest.cc
new file mode 100644
index 00000000..e5238a16
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/stubs/template_util_unittest.cc
@@ -0,0 +1,130 @@
+// 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)
+//
+// These tests are really compile time tests.
+// If you try to step through this in a debugger
+// you will not see any evaluations, merely that
+// value is assigned true or false sequentially.
+
+#include <stubs/template_util.h>
+
+#include <testing/googletest.h>
+#include <gtest/gtest.h>
+
+namespace GOOGLE_NAMESPACE = google::protobuf::internal;
+
+namespace google {
+namespace protobuf {
+namespace internal {
+namespace {
+
+TEST(TemplateUtilTest, TestSize) {
+ EXPECT_GT(sizeof(GOOGLE_NAMESPACE::big_), sizeof(GOOGLE_NAMESPACE::small_));
+}
+
+TEST(TemplateUtilTest, TestIntegralConstants) {
+ // test the built-in types.
+ EXPECT_TRUE(true_type::value);
+ EXPECT_FALSE(false_type::value);
+
+ typedef integral_constant<int, 1> one_type;
+ EXPECT_EQ(1, one_type::value);
+}
+
+TEST(TemplateUtilTest, TestTemplateIf) {
+ typedef if_<true, true_type, false_type>::type if_true;
+ EXPECT_TRUE(if_true::value);
+
+ typedef if_<false, true_type, false_type>::type if_false;
+ EXPECT_FALSE(if_false::value);
+}
+
+TEST(TemplateUtilTest, TestTemplateTypeEquals) {
+ // Check that the TemplateTypeEquals works correctly.
+ bool value = false;
+
+ // Test the same type is true.
+ value = type_equals_<int, int>::value;
+ EXPECT_TRUE(value);
+
+ // Test different types are false.
+ value = type_equals_<float, int>::value;
+ EXPECT_FALSE(value);
+
+ // Test type aliasing.
+ typedef const int foo;
+ value = type_equals_<const foo, const int>::value;
+ EXPECT_TRUE(value);
+}
+
+TEST(TemplateUtilTest, TestTemplateAndOr) {
+ // Check that the TemplateTypeEquals works correctly.
+ bool value = false;
+
+ // Yes && Yes == true.
+ value = and_<true_, true_>::value;
+ EXPECT_TRUE(value);
+ // Yes && No == false.
+ value = and_<true_, false_>::value;
+ EXPECT_FALSE(value);
+ // No && Yes == false.
+ value = and_<false_, true_>::value;
+ EXPECT_FALSE(value);
+ // No && No == false.
+ value = and_<false_, false_>::value;
+ EXPECT_FALSE(value);
+
+ // Yes || Yes == true.
+ value = or_<true_, true_>::value;
+ EXPECT_TRUE(value);
+ // Yes || No == true.
+ value = or_<true_, false_>::value;
+ EXPECT_TRUE(value);
+ // No || Yes == true.
+ value = or_<false_, true_>::value;
+ EXPECT_TRUE(value);
+ // No || No == false.
+ value = or_<false_, false_>::value;
+ EXPECT_FALSE(value);
+}
+
+TEST(TemplateUtilTest, TestIdentity) {
+ EXPECT_TRUE(
+ (type_equals_<GOOGLE_NAMESPACE::identity_<int>::type, int>::value));
+ EXPECT_TRUE(
+ (type_equals_<GOOGLE_NAMESPACE::identity_<void>::type, void>::value));
+}
+
+} // anonymous namespace
+} // namespace internal
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/stubs/time.cc b/NorthstarDedicatedTest/include/protobuf/stubs/time.cc
new file mode 100644
index 00000000..ff83dd0d
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/stubs/time.cc
@@ -0,0 +1,365 @@
+#include <stubs/time.h>
+
+#include <ctime>
+
+#include <stubs/stringprintf.h>
+#include <stubs/strutil.h>
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+namespace {
+static const int64 kSecondsPerMinute = 60;
+static const int64 kSecondsPerHour = 3600;
+static const int64 kSecondsPerDay = kSecondsPerHour * 24;
+static const int64 kSecondsPer400Years =
+ kSecondsPerDay * (400 * 365 + 400 / 4 - 3);
+// Seconds from 0001-01-01T00:00:00 to 1970-01-01T:00:00:00
+static const int64 kSecondsFromEraToEpoch = 62135596800LL;
+// The range of timestamp values we support.
+static const int64 kMinTime = -62135596800LL; // 0001-01-01T00:00:00
+static const int64 kMaxTime = 253402300799LL; // 9999-12-31T23:59:59
+
+static const int kNanosPerMillisecond = 1000000;
+static const int kNanosPerMicrosecond = 1000;
+
+// Count the seconds from the given year (start at Jan 1, 00:00) to 100 years
+// after.
+int64 SecondsPer100Years(int year) {
+ if (year % 400 == 0 || year % 400 > 300) {
+ return kSecondsPerDay * (100 * 365 + 100 / 4);
+ } else {
+ return kSecondsPerDay * (100 * 365 + 100 / 4 - 1);
+ }
+}
+
+// Count the seconds from the given year (start at Jan 1, 00:00) to 4 years
+// after.
+int64 SecondsPer4Years(int year) {
+ if ((year % 100 == 0 || year % 100 > 96) &&
+ !(year % 400 == 0 || year % 400 > 396)) {
+ // No leap years.
+ return kSecondsPerDay * (4 * 365);
+ } else {
+ // One leap years.
+ return kSecondsPerDay * (4 * 365 + 1);
+ }
+}
+
+bool IsLeapYear(int year) {
+ return year % 400 == 0 || (year % 4 == 0 && year % 100 != 0);
+}
+
+int64 SecondsPerYear(int year) {
+ return kSecondsPerDay * (IsLeapYear(year) ? 366 : 365);
+}
+
+static const int kDaysInMonth[13] = {
+ 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
+};
+
+int64 SecondsPerMonth(int month, bool leap) {
+ if (month == 2 && leap) {
+ return kSecondsPerDay * (kDaysInMonth[month] + 1);
+ }
+ return kSecondsPerDay * kDaysInMonth[month];
+}
+
+static const int kDaysSinceJan[13] = {
+ 0, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334,
+};
+
+bool ValidateDateTime(const DateTime& time) {
+ if (time.year < 1 || time.year > 9999 ||
+ time.month < 1 || time.month > 12 ||
+ time.day < 1 || time.day > 31 ||
+ time.hour < 0 || time.hour > 23 ||
+ time.minute < 0 || time.minute > 59 ||
+ time.second < 0 || time.second > 59) {
+ return false;
+ }
+ if (time.month == 2 && IsLeapYear(time.year)) {
+ return time.day <= kDaysInMonth[time.month] + 1;
+ } else {
+ return time.day <= kDaysInMonth[time.month];
+ }
+}
+
+// Count the number of seconds elapsed from 0001-01-01T00:00:00 to the given
+// time.
+int64 SecondsSinceCommonEra(const DateTime& time) {
+ int64 result = 0;
+ // Years should be between 1 and 9999.
+ assert(time.year >= 1 && time.year <= 9999);
+ int year = 1;
+ if ((time.year - year) >= 400) {
+ int count_400years = (time.year - year) / 400;
+ result += kSecondsPer400Years * count_400years;
+ year += count_400years * 400;
+ }
+ while ((time.year - year) >= 100) {
+ result += SecondsPer100Years(year);
+ year += 100;
+ }
+ while ((time.year - year) >= 4) {
+ result += SecondsPer4Years(year);
+ year += 4;
+ }
+ while (time.year > year) {
+ result += SecondsPerYear(year);
+ ++year;
+ }
+ // Months should be between 1 and 12.
+ assert(time.month >= 1 && time.month <= 12);
+ int month = time.month;
+ result += kSecondsPerDay * kDaysSinceJan[month];
+ if (month > 2 && IsLeapYear(year)) {
+ result += kSecondsPerDay;
+ }
+ assert(time.day >= 1 &&
+ time.day <= (month == 2 && IsLeapYear(year)
+ ? kDaysInMonth[month] + 1
+ : kDaysInMonth[month]));
+ result += kSecondsPerDay * (time.day - 1);
+ result += kSecondsPerHour * time.hour +
+ kSecondsPerMinute * time.minute +
+ time.second;
+ return result;
+}
+
+// Format nanoseconds with either 3, 6, or 9 digits depending on the required
+// precision to represent the exact value.
+std::string FormatNanos(int32 nanos) {
+ if (nanos % kNanosPerMillisecond == 0) {
+ return StringPrintf("%03d", nanos / kNanosPerMillisecond);
+ } else if (nanos % kNanosPerMicrosecond == 0) {
+ return StringPrintf("%06d", nanos / kNanosPerMicrosecond);
+ } else {
+ return StringPrintf("%09d", nanos);
+ }
+}
+
+// Parses an integer from a null-terminated char sequence. The method
+// consumes at most "width" chars. Returns a pointer after the consumed
+// integer, or nullptr if the data does not start with an integer or the
+// integer value does not fall in the range of [min_value, max_value].
+const char* ParseInt(const char* data, int width, int min_value,
+ int max_value, int* result) {
+ if (!ascii_isdigit(*data)) {
+ return nullptr;
+ }
+ int value = 0;
+ for (int i = 0; i < width; ++i, ++data) {
+ if (ascii_isdigit(*data)) {
+ value = value * 10 + (*data - '0');
+ } else {
+ break;
+ }
+ }
+ if (value >= min_value && value <= max_value) {
+ *result = value;
+ return data;
+ } else {
+ return nullptr;
+ }
+}
+
+// Consumes the fractional parts of a second into nanos. For example,
+// "010" will be parsed to 10000000 nanos.
+const char* ParseNanos(const char* data, int32* nanos) {
+ if (!ascii_isdigit(*data)) {
+ return nullptr;
+ }
+ int value = 0;
+ int len = 0;
+ // Consume as many digits as there are but only take the first 9 into
+ // account.
+ while (ascii_isdigit(*data)) {
+ if (len < 9) {
+ value = value * 10 + *data - '0';
+ }
+ ++len;
+ ++data;
+ }
+ while (len < 9) {
+ value = value * 10;
+ ++len;
+ }
+ *nanos = value;
+ return data;
+}
+
+const char* ParseTimezoneOffset(const char* data, int64* offset) {
+ // Accept format "HH:MM". E.g., "08:00"
+ int hour;
+ if ((data = ParseInt(data, 2, 0, 23, &hour)) == nullptr) {
+ return nullptr;
+ }
+ if (*data++ != ':') {
+ return nullptr;
+ }
+ int minute;
+ if ((data = ParseInt(data, 2, 0, 59, &minute)) == nullptr) {
+ return nullptr;
+ }
+ *offset = (hour * 60 + minute) * 60;
+ return data;
+}
+} // namespace
+
+bool SecondsToDateTime(int64 seconds, DateTime* time) {
+ if (seconds < kMinTime || seconds > kMaxTime) {
+ return false;
+ }
+ // It's easier to calculate the DateTime starting from 0001-01-01T00:00:00
+ seconds = seconds + kSecondsFromEraToEpoch;
+ int year = 1;
+ if (seconds >= kSecondsPer400Years) {
+ int count_400years = seconds / kSecondsPer400Years;
+ year += 400 * count_400years;
+ seconds %= kSecondsPer400Years;
+ }
+ while (seconds >= SecondsPer100Years(year)) {
+ seconds -= SecondsPer100Years(year);
+ year += 100;
+ }
+ while (seconds >= SecondsPer4Years(year)) {
+ seconds -= SecondsPer4Years(year);
+ year += 4;
+ }
+ while (seconds >= SecondsPerYear(year)) {
+ seconds -= SecondsPerYear(year);
+ year += 1;
+ }
+ bool leap = IsLeapYear(year);
+ int month = 1;
+ while (seconds >= SecondsPerMonth(month, leap)) {
+ seconds -= SecondsPerMonth(month, leap);
+ ++month;
+ }
+ int day = 1 + seconds / kSecondsPerDay;
+ seconds %= kSecondsPerDay;
+ int hour = seconds / kSecondsPerHour;
+ seconds %= kSecondsPerHour;
+ int minute = seconds / kSecondsPerMinute;
+ seconds %= kSecondsPerMinute;
+ time->year = year;
+ time->month = month;
+ time->day = day;
+ time->hour = hour;
+ time->minute = minute;
+ time->second = static_cast<int>(seconds);
+ return true;
+}
+
+bool DateTimeToSeconds(const DateTime& time, int64* seconds) {
+ if (!ValidateDateTime(time)) {
+ return false;
+ }
+ *seconds = SecondsSinceCommonEra(time) - kSecondsFromEraToEpoch;
+ return true;
+}
+
+void GetCurrentTime(int64* seconds, int32* nanos) {
+ // TODO(xiaofeng): Improve the accuracy of this implementation (or just
+ // remove this method from protobuf).
+ *seconds = time(nullptr);
+ *nanos = 0;
+}
+
+std::string FormatTime(int64 seconds, int32 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* seconds, int32* nanos) {
+ DateTime time;
+ const char* data = value.c_str();
+ // We only accept:
+ // Z-normalized: 2015-05-20T13:29:35.120Z
+ // With UTC offset: 2015-05-20T13:29:35.120-08:00
+
+ // Parse year
+ if ((data = ParseInt(data, 4, 1, 9999, &time.year)) == nullptr) {
+ return false;
+ }
+ // Expect '-'
+ if (*data++ != '-') return false;
+ // Parse month
+ if ((data = ParseInt(data, 2, 1, 12, &time.month)) == nullptr) {
+ return false;
+ }
+ // Expect '-'
+ if (*data++ != '-') return false;
+ // Parse day
+ if ((data = ParseInt(data, 2, 1, 31, &time.day)) == nullptr) {
+ return false;
+ }
+ // Expect 'T'
+ if (*data++ != 'T') return false;
+ // Parse hour
+ if ((data = ParseInt(data, 2, 0, 23, &time.hour)) == nullptr) {
+ return false;
+ }
+ // Expect ':'
+ if (*data++ != ':') return false;
+ // Parse minute
+ if ((data = ParseInt(data, 2, 0, 59, &time.minute)) == nullptr) {
+ return false;
+ }
+ // Expect ':'
+ if (*data++ != ':') return false;
+ // Parse second
+ if ((data = ParseInt(data, 2, 0, 59, &time.second)) == nullptr) {
+ return false;
+ }
+ if (!DateTimeToSeconds(time, seconds)) {
+ return false;
+ }
+ // Parse nanoseconds.
+ if (*data == '.') {
+ ++data;
+ // Parse nanoseconds.
+ if ((data = ParseNanos(data, nanos)) == nullptr) {
+ return false;
+ }
+ } else {
+ *nanos = 0;
+ }
+ // Parse UTC offsets.
+ if (*data == 'Z') {
+ ++data;
+ } else if (*data == '+') {
+ ++data;
+ int64 offset;
+ if ((data = ParseTimezoneOffset(data, &offset)) == nullptr) {
+ return false;
+ }
+ *seconds -= offset;
+ } else if (*data == '-') {
+ ++data;
+ int64 offset;
+ if ((data = ParseTimezoneOffset(data, &offset)) == nullptr) {
+ return false;
+ }
+ *seconds += offset;
+ } else {
+ return false;
+ }
+ // Done with parsing.
+ return *data == 0;
+}
+
+} // namespace internal
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/stubs/time.h b/NorthstarDedicatedTest/include/protobuf/stubs/time.h
new file mode 100644
index 00000000..fc074974
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/stubs/time.h
@@ -0,0 +1,80 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#ifndef GOOGLE_PROTOBUF_STUBS_TIME_H_
+#define GOOGLE_PROTOBUF_STUBS_TIME_H_
+
+#include <stubs/common.h>
+
+#include <port_def.inc>
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+struct DateTime {
+ int year;
+ int month;
+ int day;
+ int hour;
+ int minute;
+ int second;
+};
+
+// Converts a timestamp (seconds elapsed since 1970-01-01T00:00:00, could be
+// negative to represent time before 1970-01-01) to DateTime. Returns false
+// if the timestamp is not in the range between 0001-01-01T00:00:00 and
+// 9999-12-31T23:59:59.
+bool PROTOBUF_EXPORT SecondsToDateTime(int64 seconds, DateTime* time);
+// Converts DateTime to a timestamp (seconds since 1970-01-01T00:00:00).
+// Returns false if the DateTime is not valid or is not in the valid range.
+bool PROTOBUF_EXPORT DateTimeToSeconds(const DateTime& time, int64* seconds);
+
+void PROTOBUF_EXPORT GetCurrentTime(int64* seconds, int32* nanos);
+
+// Formats a time string in RFC3339 format.
+//
+// For example, "2015-05-20T13:29:35.120Z". For nanos, 0, 3, 6 or 9 fractional
+// digits will be used depending on how many are required to represent the exact
+// value.
+//
+// Note that "nanos" must in the range of [0, 999999999].
+std::string PROTOBUF_EXPORT FormatTime(int64 seconds, int32 nanos);
+// Parses a time string. This method accepts RFC3339 date/time string with UTC
+// offset. For example, "2015-05-20T13:29:35.120-08:00".
+bool PROTOBUF_EXPORT ParseTime(const std::string& value, int64* seconds,
+ int32* nanos);
+
+} // namespace internal
+} // namespace protobuf
+} // namespace google
+
+#include <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_STUBS_TIME_H_
diff --git a/NorthstarDedicatedTest/include/protobuf/stubs/time_test.cc b/NorthstarDedicatedTest/include/protobuf/stubs/time_test.cc
new file mode 100644
index 00000000..0210f8b4
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/stubs/time_test.cc
@@ -0,0 +1,261 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 <stubs/time.h>
+
+#include <testing/googletest.h>
+#include <gtest/gtest.h>
+
+namespace google {
+namespace protobuf {
+namespace internal {
+namespace {
+static const int64 kSecondsPerDay = 3600 * 24;
+
+// For DateTime, tests will mostly focus on the date part because that's
+// the tricky one.
+int64 CreateTimestamp(int year, int month, int day) {
+ DateTime time;
+ time.year = year;
+ time.month = month;
+ time.day = day;
+ time.hour = time.minute = time.second = 0;
+ int64 result;
+ GOOGLE_CHECK(DateTimeToSeconds(time, &result));
+ // Check that a roundtrip produces the same result.
+ GOOGLE_CHECK(SecondsToDateTime(result, &time));
+ GOOGLE_CHECK(time.year == year);
+ GOOGLE_CHECK(time.month == month);
+ GOOGLE_CHECK(time.day == day);
+ return result;
+}
+
+TEST(DateTimeTest, SimpleTime) {
+ DateTime time;
+ ASSERT_TRUE(SecondsToDateTime(1, &time));
+ EXPECT_EQ(1970, time.year);
+ EXPECT_EQ(1, time.month);
+ EXPECT_EQ(1, time.day);
+ EXPECT_EQ(0, time.hour);
+ EXPECT_EQ(0, time.minute);
+ EXPECT_EQ(1, time.second);
+ int64 seconds;
+ ASSERT_TRUE(DateTimeToSeconds(time, &seconds));
+ EXPECT_EQ(1, seconds);
+
+ ASSERT_TRUE(SecondsToDateTime(-1, &time));
+ EXPECT_EQ(1969, time.year);
+ EXPECT_EQ(12, time.month);
+ EXPECT_EQ(31, time.day);
+ EXPECT_EQ(23, time.hour);
+ EXPECT_EQ(59, time.minute);
+ EXPECT_EQ(59, time.second);
+ ASSERT_TRUE(DateTimeToSeconds(time, &seconds));
+ EXPECT_EQ(-1, seconds);
+
+ DateTime start, end;
+ start.year = 1;
+ start.month = 1;
+ start.day = 1;
+ start.hour = 0;
+ start.minute = 0;
+ start.second = 0;
+ end.year = 9999;
+ end.month = 12;
+ end.day = 31;
+ end.hour = 23;
+ end.minute = 59;
+ end.second = 59;
+ int64 start_time, end_time;
+ ASSERT_TRUE(DateTimeToSeconds(start, &start_time));
+ ASSERT_TRUE(DateTimeToSeconds(end, &end_time));
+ EXPECT_EQ(315537897599LL, end_time - start_time);
+ ASSERT_TRUE(SecondsToDateTime(start_time, &time));
+ ASSERT_TRUE(DateTimeToSeconds(time, &seconds));
+ EXPECT_EQ(start_time, seconds);
+ ASSERT_TRUE(SecondsToDateTime(end_time, &time));
+ ASSERT_TRUE(DateTimeToSeconds(time, &seconds));
+ EXPECT_EQ(end_time, seconds);
+}
+
+TEST(DateTimeTest, DayInMonths) {
+ // Check that month boundaries are handled correctly.
+ EXPECT_EQ(kSecondsPerDay,
+ CreateTimestamp(2015, 1, 1) - CreateTimestamp(2014, 12, 31));
+ EXPECT_EQ(kSecondsPerDay,
+ CreateTimestamp(2015, 2, 1) - CreateTimestamp(2015, 1, 31));
+ EXPECT_EQ(kSecondsPerDay,
+ CreateTimestamp(2015, 3, 1) - CreateTimestamp(2015, 2, 28));
+ EXPECT_EQ(kSecondsPerDay,
+ CreateTimestamp(2015, 4, 1) - CreateTimestamp(2015, 3, 31));
+ EXPECT_EQ(kSecondsPerDay,
+ CreateTimestamp(2015, 5, 1) - CreateTimestamp(2015, 4, 30));
+ EXPECT_EQ(kSecondsPerDay,
+ CreateTimestamp(2015, 6, 1) - CreateTimestamp(2015, 5, 31));
+ EXPECT_EQ(kSecondsPerDay,
+ CreateTimestamp(2015, 7, 1) - CreateTimestamp(2015, 6, 30));
+ EXPECT_EQ(kSecondsPerDay,
+ CreateTimestamp(2015, 8, 1) - CreateTimestamp(2015, 7, 31));
+ EXPECT_EQ(kSecondsPerDay,
+ CreateTimestamp(2015, 9, 1) - CreateTimestamp(2015, 8, 31));
+ EXPECT_EQ(kSecondsPerDay,
+ CreateTimestamp(2015, 10, 1) - CreateTimestamp(2015, 9, 30));
+ EXPECT_EQ(kSecondsPerDay,
+ CreateTimestamp(2015, 11, 1) - CreateTimestamp(2015, 10, 31));
+ EXPECT_EQ(kSecondsPerDay,
+ CreateTimestamp(2015, 12, 1) - CreateTimestamp(2015, 11, 30));
+ EXPECT_EQ(kSecondsPerDay,
+ CreateTimestamp(2016, 1, 1) - CreateTimestamp(2015, 12, 31));
+}
+
+TEST(DateTimeTest, LeapYear) {
+ // Non-leap year.
+ EXPECT_EQ(kSecondsPerDay,
+ CreateTimestamp(2015, 3, 1) - CreateTimestamp(2015, 2, 28));
+ // Leap year.
+ EXPECT_EQ(kSecondsPerDay,
+ CreateTimestamp(2016, 3, 1) - CreateTimestamp(2016, 2, 29));
+ // Non-leap year.
+ EXPECT_EQ(kSecondsPerDay,
+ CreateTimestamp(2100, 3, 1) - CreateTimestamp(2100, 2, 28));
+ // Leap year.
+ EXPECT_EQ(kSecondsPerDay,
+ CreateTimestamp(2400, 3, 1) - CreateTimestamp(2400, 2, 29));
+}
+
+TEST(DateTimeTest, WrongDays) {
+ int64 seconds;
+ DateTime time;
+ time.hour = 0;
+ time.minute = 0;
+ time.second = 0;
+ time.month = 2;
+
+ // Non-leap year.
+ time.year = 2015;
+ time.day = 29;
+ ASSERT_FALSE(DateTimeToSeconds(time, &seconds));
+
+ // Leap year.
+ time.year = 2016;
+ time.day = 29;
+ ASSERT_TRUE(DateTimeToSeconds(time, &seconds));
+ time.day = 30;
+ ASSERT_FALSE(DateTimeToSeconds(time, &seconds));
+
+ // Non-leap year.
+ time.year = 2100;
+ time.day = 29;
+ ASSERT_FALSE(DateTimeToSeconds(time, &seconds));
+
+ // Leap year.
+ time.year = 2400;
+ time.day = 29;
+ ASSERT_TRUE(DateTimeToSeconds(time, &seconds));
+ time.day = 30;
+ ASSERT_FALSE(DateTimeToSeconds(time, &seconds));
+
+ // Non-february
+ time.year = 2015;
+ time.month = 1;
+ time.day = 0;
+ ASSERT_FALSE(DateTimeToSeconds(time, &seconds));
+ time.day = 1;
+ ASSERT_TRUE(DateTimeToSeconds(time, &seconds));
+ time.day = 31;
+ ASSERT_TRUE(DateTimeToSeconds(time, &seconds));
+ time.day = 32;
+ ASSERT_FALSE(DateTimeToSeconds(time, &seconds));
+
+ // Bad month
+ time.year = 2015;
+ time.month = 0;
+ time.day = 1;
+ ASSERT_FALSE(DateTimeToSeconds(time, &seconds));
+ time.month = 13;
+ ASSERT_FALSE(DateTimeToSeconds(time, &seconds));
+}
+
+TEST(DateTimeTest, StringFormat) {
+ DateTime start, end;
+ start.year = 1;
+ start.month = 1;
+ start.day = 1;
+ start.hour = 0;
+ start.minute = 0;
+ start.second = 0;
+ end.year = 9999;
+ end.month = 12;
+ end.day = 31;
+ end.hour = 23;
+ end.minute = 59;
+ end.second = 59;
+ int64 start_time, end_time;
+ ASSERT_TRUE(DateTimeToSeconds(start, &start_time));
+ ASSERT_TRUE(DateTimeToSeconds(end, &end_time));
+
+ EXPECT_EQ("0001-01-01T00:00:00Z", FormatTime(start_time, 0));
+ EXPECT_EQ("9999-12-31T23:59:59Z", FormatTime(end_time, 0));
+
+ // Make sure the nanoseconds part is formatted correctly.
+ EXPECT_EQ("1970-01-01T00:00:00.010Z", FormatTime(0, 10000000));
+ EXPECT_EQ("1970-01-01T00:00:00.000010Z", FormatTime(0, 10000));
+ EXPECT_EQ("1970-01-01T00:00:00.000000010Z", FormatTime(0, 10));
+}
+
+TEST(DateTimeTest, ParseString) {
+ int64 seconds;
+ int32 nanos;
+ ASSERT_TRUE(ParseTime("0001-01-01T00:00:00Z", &seconds, &nanos));
+ EXPECT_EQ("0001-01-01T00:00:00Z", FormatTime(seconds, nanos));
+ ASSERT_TRUE(ParseTime("9999-12-31T23:59:59.999999999Z", &seconds, &nanos));
+ EXPECT_EQ("9999-12-31T23:59:59.999999999Z", FormatTime(seconds, nanos));
+
+ // Test time zone offsets.
+ ASSERT_TRUE(ParseTime("1970-01-01T00:00:00-08:00", &seconds, &nanos));
+ EXPECT_EQ("1970-01-01T08:00:00Z", FormatTime(seconds, nanos));
+ ASSERT_TRUE(ParseTime("1970-01-01T00:00:00+08:00", &seconds, &nanos));
+ EXPECT_EQ("1969-12-31T16:00:00Z", FormatTime(seconds, nanos));
+
+ // Test nanoseconds.
+ ASSERT_TRUE(ParseTime("1970-01-01T00:00:00.01Z", &seconds, &nanos));
+ EXPECT_EQ("1970-01-01T00:00:00.010Z", FormatTime(seconds, nanos));
+ ASSERT_TRUE(ParseTime("1970-01-01T00:00:00.00001-08:00", &seconds, &nanos));
+ EXPECT_EQ("1970-01-01T08:00:00.000010Z", FormatTime(seconds, nanos));
+ ASSERT_TRUE(ParseTime("1970-01-01T00:00:00.00000001+08:00", &seconds, &nanos));
+ EXPECT_EQ("1969-12-31T16:00:00.000000010Z", FormatTime(seconds, nanos));
+ // Fractional parts less than 1 nanosecond will be ignored.
+ ASSERT_TRUE(ParseTime("1970-01-01T00:00:00.0123456789Z", &seconds, &nanos));
+ EXPECT_EQ("1970-01-01T00:00:00.012345678Z", FormatTime(seconds, nanos));
+}
+
+} // namespace
+} // namespace internal
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/test_messages_proto2.proto b/NorthstarDedicatedTest/include/protobuf/test_messages_proto2.proto
new file mode 100644
index 00000000..39fc123f
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/test_messages_proto2.proto
@@ -0,0 +1,292 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Test schema for proto2 messages. This test schema is used by:
+//
+// - conformance tests
+//
+
+// LINT: ALLOW_GROUPS
+
+syntax = "proto2";
+
+package protobuf_test_messages.proto2;
+
+option java_package = "com.google.protobuf_test_messages.proto2";
+
+// This is the default, but we specify it here explicitly.
+option optimize_for = SPEED;
+
+option cc_enable_arenas = true;
+
+// This proto includes every type of field in both singular and repeated
+// forms.
+//
+// Also, crucially, all messages and enums in this file are eventually
+// submessages of this message. So for example, a fuzz test of TestAllTypes
+// could trigger bugs that occur in any message type in this file. We verify
+// this stays true in a unit test.
+message TestAllTypesProto2 {
+ message NestedMessage {
+ optional int32 a = 1;
+ optional TestAllTypesProto2 corecursive = 2;
+ }
+
+ enum NestedEnum {
+ FOO = 0;
+ BAR = 1;
+ BAZ = 2;
+ NEG = -1; // Intentionally negative.
+ }
+
+ // Singular
+ optional int32 optional_int32 = 1;
+ optional int64 optional_int64 = 2;
+ optional uint32 optional_uint32 = 3;
+ optional uint64 optional_uint64 = 4;
+ optional sint32 optional_sint32 = 5;
+ optional sint64 optional_sint64 = 6;
+ optional fixed32 optional_fixed32 = 7;
+ optional fixed64 optional_fixed64 = 8;
+ optional sfixed32 optional_sfixed32 = 9;
+ optional sfixed64 optional_sfixed64 = 10;
+ optional float optional_float = 11;
+ optional double optional_double = 12;
+ optional bool optional_bool = 13;
+ optional string optional_string = 14;
+ optional bytes optional_bytes = 15;
+
+ optional NestedMessage optional_nested_message = 18;
+ optional ForeignMessageProto2 optional_foreign_message = 19;
+
+ optional NestedEnum optional_nested_enum = 21;
+ optional ForeignEnumProto2 optional_foreign_enum = 22;
+
+ optional string optional_string_piece = 24 [ctype = STRING_PIECE];
+ optional string optional_cord = 25 [ctype = CORD];
+
+ optional TestAllTypesProto2 recursive_message = 27;
+
+ // Repeated
+ repeated int32 repeated_int32 = 31;
+ repeated int64 repeated_int64 = 32;
+ repeated uint32 repeated_uint32 = 33;
+ repeated uint64 repeated_uint64 = 34;
+ repeated sint32 repeated_sint32 = 35;
+ repeated sint64 repeated_sint64 = 36;
+ repeated fixed32 repeated_fixed32 = 37;
+ repeated fixed64 repeated_fixed64 = 38;
+ repeated sfixed32 repeated_sfixed32 = 39;
+ repeated sfixed64 repeated_sfixed64 = 40;
+ repeated float repeated_float = 41;
+ repeated double repeated_double = 42;
+ repeated bool repeated_bool = 43;
+ repeated string repeated_string = 44;
+ repeated bytes repeated_bytes = 45;
+
+ repeated NestedMessage repeated_nested_message = 48;
+ repeated ForeignMessageProto2 repeated_foreign_message = 49;
+
+ repeated NestedEnum repeated_nested_enum = 51;
+ repeated ForeignEnumProto2 repeated_foreign_enum = 52;
+
+ repeated string repeated_string_piece = 54 [ctype = STRING_PIECE];
+ repeated string repeated_cord = 55 [ctype = CORD];
+
+ // Packed
+ repeated int32 packed_int32 = 75 [packed = true];
+ repeated int64 packed_int64 = 76 [packed = true];
+ repeated uint32 packed_uint32 = 77 [packed = true];
+ repeated uint64 packed_uint64 = 78 [packed = true];
+ repeated sint32 packed_sint32 = 79 [packed = true];
+ repeated sint64 packed_sint64 = 80 [packed = true];
+ repeated fixed32 packed_fixed32 = 81 [packed = true];
+ repeated fixed64 packed_fixed64 = 82 [packed = true];
+ repeated sfixed32 packed_sfixed32 = 83 [packed = true];
+ repeated sfixed64 packed_sfixed64 = 84 [packed = true];
+ repeated float packed_float = 85 [packed = true];
+ repeated double packed_double = 86 [packed = true];
+ repeated bool packed_bool = 87 [packed = true];
+ repeated NestedEnum packed_nested_enum = 88 [packed = true];
+
+ // Unpacked
+ repeated int32 unpacked_int32 = 89 [packed = false];
+ repeated int64 unpacked_int64 = 90 [packed = false];
+ repeated uint32 unpacked_uint32 = 91 [packed = false];
+ repeated uint64 unpacked_uint64 = 92 [packed = false];
+ repeated sint32 unpacked_sint32 = 93 [packed = false];
+ repeated sint64 unpacked_sint64 = 94 [packed = false];
+ repeated fixed32 unpacked_fixed32 = 95 [packed = false];
+ repeated fixed64 unpacked_fixed64 = 96 [packed = false];
+ repeated sfixed32 unpacked_sfixed32 = 97 [packed = false];
+ repeated sfixed64 unpacked_sfixed64 = 98 [packed = false];
+ repeated float unpacked_float = 99 [packed = false];
+ repeated double unpacked_double = 100 [packed = false];
+ repeated bool unpacked_bool = 101 [packed = false];
+ repeated NestedEnum unpacked_nested_enum = 102 [packed = false];
+
+ // Map
+ map<int32, int32> map_int32_int32 = 56;
+ map<int64, int64> map_int64_int64 = 57;
+ map<uint32, uint32> map_uint32_uint32 = 58;
+ map<uint64, uint64> map_uint64_uint64 = 59;
+ map<sint32, sint32> map_sint32_sint32 = 60;
+ map<sint64, sint64> map_sint64_sint64 = 61;
+ map<fixed32, fixed32> map_fixed32_fixed32 = 62;
+ map<fixed64, fixed64> map_fixed64_fixed64 = 63;
+ map<sfixed32, sfixed32> map_sfixed32_sfixed32 = 64;
+ map<sfixed64, sfixed64> map_sfixed64_sfixed64 = 65;
+ map<int32, float> map_int32_float = 66;
+ map<int32, double> map_int32_double = 67;
+ map<bool, bool> map_bool_bool = 68;
+ map<string, string> map_string_string = 69;
+ map<string, bytes> map_string_bytes = 70;
+ map<string, NestedMessage> map_string_nested_message = 71;
+ map<string, ForeignMessageProto2> map_string_foreign_message = 72;
+ map<string, NestedEnum> map_string_nested_enum = 73;
+ map<string, ForeignEnumProto2> map_string_foreign_enum = 74;
+
+ oneof oneof_field {
+ uint32 oneof_uint32 = 111;
+ NestedMessage oneof_nested_message = 112;
+ string oneof_string = 113;
+ bytes oneof_bytes = 114;
+ bool oneof_bool = 115;
+ uint64 oneof_uint64 = 116;
+ float oneof_float = 117;
+ double oneof_double = 118;
+ NestedEnum oneof_enum = 119;
+ }
+
+ // extensions
+ extensions 120 to 200;
+
+ // groups
+ optional group Data = 201 {
+ optional int32 group_int32 = 202;
+ optional uint32 group_uint32 = 203;
+ }
+
+ // default values
+ optional int32 default_int32 = 241 [ default = -123456789];
+ optional int64 default_int64 = 242 [ default = -9123456789123456789];
+ optional uint32 default_uint32 = 243 [ default = 2123456789];
+ optional uint64 default_uint64 = 244 [ default = 10123456789123456789];
+ optional sint32 default_sint32 = 245 [ default = -123456789];
+ optional sint64 default_sint64 = 246 [default = -9123456789123456789];
+ optional fixed32 default_fixed32 = 247 [ default = 2123456789];
+ optional fixed64 default_fixed64 = 248 [ default = 10123456789123456789];
+ optional sfixed32 default_sfixed32 = 249 [ default = -123456789];
+ optional sfixed64 default_sfixed64 = 250 [default = -9123456789123456789];
+ optional float default_float = 251 [ default = 9e9];
+ optional double default_double = 252 [ default = 7e22];
+ optional bool default_bool = 253 [ default = true];
+ optional string default_string = 254 [ default = "Rosebud"];
+
+ // Test field-name-to-JSON-name convention.
+ // (protobuf says names can be any valid C/C++ identifier.)
+ optional int32 fieldname1 = 401;
+ optional int32 field_name2 = 402;
+ optional int32 _field_name3 = 403;
+ optional int32 field__name4_ = 404;
+ optional int32 field0name5 = 405;
+ optional int32 field_0_name6 = 406;
+ optional int32 fieldName7 = 407;
+ optional int32 FieldName8 = 408;
+ optional int32 field_Name9 = 409;
+ optional int32 Field_Name10 = 410;
+ optional int32 FIELD_NAME11 = 411;
+ optional int32 FIELD_name12 = 412;
+ optional int32 __field_name13 = 413;
+ optional int32 __Field_name14 = 414;
+ optional int32 field__name15 = 415;
+ optional int32 field__Name16 = 416;
+ optional int32 field_name17__ = 417;
+ optional int32 Field_name18__ = 418;
+
+ // Reserved for unknown fields test.
+ reserved 1000 to 9999;
+
+ // message_set test case.
+ message MessageSetCorrect {
+ option message_set_wire_format = true;
+
+ extensions 4 to max;
+ }
+
+ message MessageSetCorrectExtension1 {
+ extend MessageSetCorrect {
+ optional MessageSetCorrectExtension1 message_set_extension = 1547769;
+ }
+ optional string str = 25;
+ }
+
+ message MessageSetCorrectExtension2 {
+ extend MessageSetCorrect {
+ optional MessageSetCorrectExtension2 message_set_extension = 4135312;
+ }
+ optional int32 i = 9;
+ }
+}
+
+message ForeignMessageProto2 {
+ optional int32 c = 1;
+}
+
+enum ForeignEnumProto2 {
+ FOREIGN_FOO = 0;
+ FOREIGN_BAR = 1;
+ FOREIGN_BAZ = 2;
+}
+
+extend TestAllTypesProto2 {
+ optional int32 extension_int32 = 120;
+}
+
+message UnknownToTestAllTypes {
+ optional int32 optional_int32 = 1001;
+ optional string optional_string = 1002;
+ optional ForeignMessageProto2 nested_message = 1003;
+ optional group OptionalGroup = 1004 {
+ optional int32 a = 1;
+ }
+ optional bool optional_bool = 1006;
+ repeated int32 repeated_int32 = 1011;
+}
+
+message NullHypothesisProto2 {
+}
+
+message EnumOnlyProto2 {
+ enum Bool {
+ kFalse = 0;
+ kTrue = 1;
+ }
+}
diff --git a/NorthstarDedicatedTest/include/protobuf/test_messages_proto3.proto b/NorthstarDedicatedTest/include/protobuf/test_messages_proto3.proto
new file mode 100644
index 00000000..278ee4f9
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/test_messages_proto3.proto
@@ -0,0 +1,289 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Test schema for proto3 messages. This test schema is used by:
+//
+// - benchmarks
+// - fuzz tests
+// - conformance tests
+//
+
+syntax = "proto3";
+
+package protobuf_test_messages.proto3;
+
+option java_package = "com.google.protobuf_test_messages.proto3";
+option objc_class_prefix = "Proto3";
+
+// This is the default, but we specify it here explicitly.
+option optimize_for = SPEED;
+
+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";
+
+option cc_enable_arenas = true;
+
+// This proto includes every type of field in both singular and repeated
+// forms.
+//
+// Also, crucially, all messages and enums in this file are eventually
+// submessages of this message. So for example, a fuzz test of TestAllTypes
+// could trigger bugs that occur in any message type in this file. We verify
+// this stays true in a unit test.
+message TestAllTypesProto3 {
+ message NestedMessage {
+ int32 a = 1;
+ TestAllTypesProto3 corecursive = 2;
+ }
+
+ enum NestedEnum {
+ FOO = 0;
+ BAR = 1;
+ BAZ = 2;
+ NEG = -1; // Intentionally negative.
+ }
+
+ enum AliasedEnum {
+ option allow_alias = true;
+
+ ALIAS_FOO = 0;
+ ALIAS_BAR = 1;
+ ALIAS_BAZ = 2;
+ QUX = 2;
+ qux = 2;
+ bAz = 2;
+ }
+
+ // Singular
+ int32 optional_int32 = 1;
+ int64 optional_int64 = 2;
+ uint32 optional_uint32 = 3;
+ uint64 optional_uint64 = 4;
+ sint32 optional_sint32 = 5;
+ sint64 optional_sint64 = 6;
+ fixed32 optional_fixed32 = 7;
+ fixed64 optional_fixed64 = 8;
+ sfixed32 optional_sfixed32 = 9;
+ sfixed64 optional_sfixed64 = 10;
+ float optional_float = 11;
+ double optional_double = 12;
+ bool optional_bool = 13;
+ string optional_string = 14;
+ bytes optional_bytes = 15;
+
+ NestedMessage optional_nested_message = 18;
+ ForeignMessage optional_foreign_message = 19;
+
+ NestedEnum optional_nested_enum = 21;
+ ForeignEnum optional_foreign_enum = 22;
+ AliasedEnum optional_aliased_enum = 23;
+
+ string optional_string_piece = 24 [ctype = STRING_PIECE];
+ string optional_cord = 25 [ctype = CORD];
+
+ TestAllTypesProto3 recursive_message = 27;
+
+ // Repeated
+ repeated int32 repeated_int32 = 31;
+ repeated int64 repeated_int64 = 32;
+ repeated uint32 repeated_uint32 = 33;
+ repeated uint64 repeated_uint64 = 34;
+ repeated sint32 repeated_sint32 = 35;
+ repeated sint64 repeated_sint64 = 36;
+ repeated fixed32 repeated_fixed32 = 37;
+ repeated fixed64 repeated_fixed64 = 38;
+ repeated sfixed32 repeated_sfixed32 = 39;
+ repeated sfixed64 repeated_sfixed64 = 40;
+ repeated float repeated_float = 41;
+ repeated double repeated_double = 42;
+ repeated bool repeated_bool = 43;
+ repeated string repeated_string = 44;
+ repeated bytes repeated_bytes = 45;
+
+ repeated NestedMessage repeated_nested_message = 48;
+ repeated ForeignMessage repeated_foreign_message = 49;
+
+ repeated NestedEnum repeated_nested_enum = 51;
+ repeated ForeignEnum repeated_foreign_enum = 52;
+
+ repeated string repeated_string_piece = 54 [ctype = STRING_PIECE];
+ repeated string repeated_cord = 55 [ctype = CORD];
+
+ // Packed
+ repeated int32 packed_int32 = 75 [packed = true];
+ repeated int64 packed_int64 = 76 [packed = true];
+ repeated uint32 packed_uint32 = 77 [packed = true];
+ repeated uint64 packed_uint64 = 78 [packed = true];
+ repeated sint32 packed_sint32 = 79 [packed = true];
+ repeated sint64 packed_sint64 = 80 [packed = true];
+ repeated fixed32 packed_fixed32 = 81 [packed = true];
+ repeated fixed64 packed_fixed64 = 82 [packed = true];
+ repeated sfixed32 packed_sfixed32 = 83 [packed = true];
+ repeated sfixed64 packed_sfixed64 = 84 [packed = true];
+ repeated float packed_float = 85 [packed = true];
+ repeated double packed_double = 86 [packed = true];
+ repeated bool packed_bool = 87 [packed = true];
+ repeated NestedEnum packed_nested_enum = 88 [packed = true];
+
+ // Unpacked
+ repeated int32 unpacked_int32 = 89 [packed = false];
+ repeated int64 unpacked_int64 = 90 [packed = false];
+ repeated uint32 unpacked_uint32 = 91 [packed = false];
+ repeated uint64 unpacked_uint64 = 92 [packed = false];
+ repeated sint32 unpacked_sint32 = 93 [packed = false];
+ repeated sint64 unpacked_sint64 = 94 [packed = false];
+ repeated fixed32 unpacked_fixed32 = 95 [packed = false];
+ repeated fixed64 unpacked_fixed64 = 96 [packed = false];
+ repeated sfixed32 unpacked_sfixed32 = 97 [packed = false];
+ repeated sfixed64 unpacked_sfixed64 = 98 [packed = false];
+ repeated float unpacked_float = 99 [packed = false];
+ repeated double unpacked_double = 100 [packed = false];
+ repeated bool unpacked_bool = 101 [packed = false];
+ repeated NestedEnum unpacked_nested_enum = 102 [packed = false];
+
+ // Map
+ map<int32, int32> map_int32_int32 = 56;
+ map<int64, int64> map_int64_int64 = 57;
+ map<uint32, uint32> map_uint32_uint32 = 58;
+ map<uint64, uint64> map_uint64_uint64 = 59;
+ map<sint32, sint32> map_sint32_sint32 = 60;
+ map<sint64, sint64> map_sint64_sint64 = 61;
+ map<fixed32, fixed32> map_fixed32_fixed32 = 62;
+ map<fixed64, fixed64> map_fixed64_fixed64 = 63;
+ map<sfixed32, sfixed32> map_sfixed32_sfixed32 = 64;
+ map<sfixed64, sfixed64> map_sfixed64_sfixed64 = 65;
+ map<int32, float> map_int32_float = 66;
+ map<int32, double> map_int32_double = 67;
+ map<bool, bool> map_bool_bool = 68;
+ map<string, string> map_string_string = 69;
+ map<string, bytes> map_string_bytes = 70;
+ map<string, NestedMessage> map_string_nested_message = 71;
+ map<string, ForeignMessage> map_string_foreign_message = 72;
+ map<string, NestedEnum> map_string_nested_enum = 73;
+ map<string, ForeignEnum> map_string_foreign_enum = 74;
+
+ oneof oneof_field {
+ uint32 oneof_uint32 = 111;
+ NestedMessage oneof_nested_message = 112;
+ string oneof_string = 113;
+ bytes oneof_bytes = 114;
+ bool oneof_bool = 115;
+ uint64 oneof_uint64 = 116;
+ float oneof_float = 117;
+ double oneof_double = 118;
+ NestedEnum oneof_enum = 119;
+ google.protobuf.NullValue oneof_null_value = 120;
+ }
+
+ // Well-known types
+ google.protobuf.BoolValue optional_bool_wrapper = 201;
+ google.protobuf.Int32Value optional_int32_wrapper = 202;
+ google.protobuf.Int64Value optional_int64_wrapper = 203;
+ google.protobuf.UInt32Value optional_uint32_wrapper = 204;
+ google.protobuf.UInt64Value optional_uint64_wrapper = 205;
+ google.protobuf.FloatValue optional_float_wrapper = 206;
+ google.protobuf.DoubleValue optional_double_wrapper = 207;
+ google.protobuf.StringValue optional_string_wrapper = 208;
+ google.protobuf.BytesValue optional_bytes_wrapper = 209;
+
+ repeated google.protobuf.BoolValue repeated_bool_wrapper = 211;
+ repeated google.protobuf.Int32Value repeated_int32_wrapper = 212;
+ repeated google.protobuf.Int64Value repeated_int64_wrapper = 213;
+ repeated google.protobuf.UInt32Value repeated_uint32_wrapper = 214;
+ repeated google.protobuf.UInt64Value repeated_uint64_wrapper = 215;
+ repeated google.protobuf.FloatValue repeated_float_wrapper = 216;
+ repeated google.protobuf.DoubleValue repeated_double_wrapper = 217;
+ repeated google.protobuf.StringValue repeated_string_wrapper = 218;
+ repeated google.protobuf.BytesValue repeated_bytes_wrapper = 219;
+
+ google.protobuf.Duration optional_duration = 301;
+ google.protobuf.Timestamp optional_timestamp = 302;
+ google.protobuf.FieldMask optional_field_mask = 303;
+ google.protobuf.Struct optional_struct = 304;
+ google.protobuf.Any optional_any = 305;
+ google.protobuf.Value optional_value = 306;
+ google.protobuf.NullValue optional_null_value = 307;
+
+ repeated google.protobuf.Duration repeated_duration = 311;
+ repeated google.protobuf.Timestamp repeated_timestamp = 312;
+ repeated google.protobuf.FieldMask repeated_fieldmask = 313;
+ repeated google.protobuf.Struct repeated_struct = 324;
+ repeated google.protobuf.Any repeated_any = 315;
+ repeated google.protobuf.Value repeated_value = 316;
+ repeated google.protobuf.ListValue repeated_list_value = 317;
+
+ // Test field-name-to-JSON-name convention.
+ // (protobuf says names can be any valid C/C++ identifier.)
+ int32 fieldname1 = 401;
+ int32 field_name2 = 402;
+ int32 _field_name3 = 403;
+ int32 field__name4_ = 404;
+ int32 field0name5 = 405;
+ int32 field_0_name6 = 406;
+ int32 fieldName7 = 407;
+ int32 FieldName8 = 408;
+ int32 field_Name9 = 409;
+ int32 Field_Name10 = 410;
+ int32 FIELD_NAME11 = 411;
+ int32 FIELD_name12 = 412;
+ int32 __field_name13 = 413;
+ int32 __Field_name14 = 414;
+ int32 field__name15 = 415;
+ int32 field__Name16 = 416;
+ int32 field_name17__ = 417;
+ int32 Field_name18__ = 418;
+
+ // Reserved for testing unknown fields
+ reserved 501 to 510;
+}
+
+message ForeignMessage {
+ int32 c = 1;
+}
+
+enum ForeignEnum {
+ FOREIGN_FOO = 0;
+ FOREIGN_BAR = 1;
+ FOREIGN_BAZ = 2;
+}
+
+message NullHypothesisProto3 {
+}
+
+message EnumOnlyProto3 {
+ enum Bool {
+ kFalse = 0;
+ kTrue = 1;
+ }
+}
diff --git a/NorthstarDedicatedTest/include/protobuf/test_util.cc b/NorthstarDedicatedTest/include/protobuf/test_util.cc
new file mode 100644
index 00000000..e610d83d
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/test_util.cc
@@ -0,0 +1,47 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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.
+
+#ifdef _WIN32
+// Verify that #including windows.h does not break anything (e.g. because
+// windows.h #defines GetMessage() as a macro).
+#include <windows.h>
+#endif
+
+#include <test_util.h>
+
+namespace google {
+namespace protobuf {
+
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/test_util.h b/NorthstarDedicatedTest/include/protobuf/test_util.h
new file mode 100644
index 00000000..7c39b098
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/test_util.h
@@ -0,0 +1,1257 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 GOOGLE_PROTOBUF_TEST_UTIL_H__
+#define GOOGLE_PROTOBUF_TEST_UTIL_H__
+
+#include <unittest.pb.h>
+
+#define UNITTEST ::protobuf_unittest
+#define UNITTEST_IMPORT ::protobuf_unittest_import
+// Must be included when the preprocessor symbols above are defined.
+#include <test_util.inc>
+#undef UNITTEST
+#undef UNITTEST_IMPORT
+
+#include <port_def.inc>
+
+namespace google {
+namespace protobuf {
+// This file doesn't use these declarations, but some .cc files do.
+namespace unittest = ::protobuf_unittest;
+namespace unittest_import = ::protobuf_unittest_import;
+
+namespace TestUtil {
+
+class ReflectionTester {
+ public:
+ // base_descriptor must be a descriptor for TestAllTypes or
+ // TestAllExtensions. In the former case, ReflectionTester fetches from
+ // it the FieldDescriptors needed to use the reflection interface. In
+ // the latter case, ReflectionTester searches for extension fields in
+ // its file.
+ explicit ReflectionTester(const Descriptor* base_descriptor);
+
+ void SetAllFieldsViaReflection(Message* message);
+ void ModifyRepeatedFieldsViaReflection(Message* message);
+ void ExpectAllFieldsSetViaReflection(const Message& message);
+ void ExpectClearViaReflection(const Message& message);
+
+ void SetPackedFieldsViaReflection(Message* message);
+ void ExpectPackedFieldsSetViaReflection(const Message& message);
+
+ void RemoveLastRepeatedsViaReflection(Message* message);
+ void ReleaseLastRepeatedsViaReflection(Message* message,
+ bool expect_extensions_notnull);
+ void SwapRepeatedsViaReflection(Message* message);
+ void SetAllocatedOptionalMessageFieldsToNullViaReflection(Message* message);
+ static void SetAllocatedOptionalMessageFieldsToMessageViaReflection(
+ Message* from_message, Message* to_message);
+
+ enum MessageReleaseState {
+ IS_NULL,
+ CAN_BE_NULL,
+ NOT_NULL,
+ };
+ void ExpectMessagesReleasedViaReflection(
+ Message* message, MessageReleaseState expected_release_state);
+
+ // Set and check functions for TestOneof2 messages. No need to construct
+ // the ReflectionTester by TestAllTypes nor TestAllExtensions.
+ static void SetOneofViaReflection(Message* message);
+ static void ExpectOneofSetViaReflection(const Message& message);
+
+ private:
+ const FieldDescriptor* F(const std::string& name);
+
+ const Descriptor* base_descriptor_;
+
+ const FieldDescriptor* group_a_;
+ const FieldDescriptor* repeated_group_a_;
+ const FieldDescriptor* nested_b_;
+ const FieldDescriptor* foreign_c_;
+ const FieldDescriptor* import_d_;
+ const FieldDescriptor* import_e_;
+
+ const EnumValueDescriptor* nested_foo_;
+ const EnumValueDescriptor* nested_bar_;
+ const EnumValueDescriptor* nested_baz_;
+ const EnumValueDescriptor* foreign_foo_;
+ const EnumValueDescriptor* foreign_bar_;
+ const EnumValueDescriptor* foreign_baz_;
+ const EnumValueDescriptor* import_foo_;
+ const EnumValueDescriptor* import_bar_;
+ const EnumValueDescriptor* import_baz_;
+
+ // We have to split this into three function otherwise it creates a stack
+ // frame so large that it triggers a warning.
+ void ExpectAllFieldsSetViaReflection1(const Message& message);
+ void ExpectAllFieldsSetViaReflection2(const Message& message);
+ void ExpectAllFieldsSetViaReflection3(const Message& message);
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ReflectionTester);
+};
+
+inline TestUtil::ReflectionTester::ReflectionTester(
+ const Descriptor* base_descriptor)
+ : base_descriptor_(base_descriptor) {
+ const DescriptorPool* pool = base_descriptor->file()->pool();
+ std::string package = base_descriptor->file()->package();
+ const FieldDescriptor* import_descriptor =
+ pool->FindFieldByName(package + ".TestAllTypes.optional_import_message");
+ std::string import_package =
+ import_descriptor->message_type()->file()->package();
+
+ nested_b_ = pool->FindFieldByName(package + ".TestAllTypes.NestedMessage.bb");
+ foreign_c_ = pool->FindFieldByName(package + ".ForeignMessage.c");
+ import_d_ = pool->FindFieldByName(import_package + ".ImportMessage.d");
+ import_e_ = pool->FindFieldByName(import_package + ".PublicImportMessage.e");
+ nested_foo_ = pool->FindEnumValueByName(package + ".TestAllTypes.FOO");
+ nested_bar_ = pool->FindEnumValueByName(package + ".TestAllTypes.BAR");
+ nested_baz_ = pool->FindEnumValueByName(package + ".TestAllTypes.BAZ");
+ foreign_foo_ = pool->FindEnumValueByName(package + ".FOREIGN_FOO");
+ foreign_bar_ = pool->FindEnumValueByName(package + ".FOREIGN_BAR");
+ foreign_baz_ = pool->FindEnumValueByName(package + ".FOREIGN_BAZ");
+ import_foo_ = pool->FindEnumValueByName(import_package + ".IMPORT_FOO");
+ import_bar_ = pool->FindEnumValueByName(import_package + ".IMPORT_BAR");
+ import_baz_ = pool->FindEnumValueByName(import_package + ".IMPORT_BAZ");
+
+ if (base_descriptor_->name() == "TestAllExtensions") {
+ group_a_ = pool->FindFieldByName(package + ".OptionalGroup_extension.a");
+ repeated_group_a_ =
+ pool->FindFieldByName(package + ".RepeatedGroup_extension.a");
+ } else {
+ group_a_ = pool->FindFieldByName(package + ".TestAllTypes.OptionalGroup.a");
+ repeated_group_a_ =
+ pool->FindFieldByName(package + ".TestAllTypes.RepeatedGroup.a");
+ }
+
+ EXPECT_TRUE(group_a_ != nullptr);
+ EXPECT_TRUE(repeated_group_a_ != nullptr);
+ EXPECT_TRUE(nested_b_ != nullptr);
+ EXPECT_TRUE(foreign_c_ != nullptr);
+ EXPECT_TRUE(import_d_ != nullptr);
+ EXPECT_TRUE(import_e_ != nullptr);
+ EXPECT_TRUE(nested_foo_ != nullptr);
+ EXPECT_TRUE(nested_bar_ != nullptr);
+ EXPECT_TRUE(nested_baz_ != nullptr);
+ EXPECT_TRUE(foreign_foo_ != nullptr);
+ EXPECT_TRUE(foreign_bar_ != nullptr);
+ EXPECT_TRUE(foreign_baz_ != nullptr);
+ EXPECT_TRUE(import_foo_ != nullptr);
+ EXPECT_TRUE(import_bar_ != nullptr);
+ EXPECT_TRUE(import_baz_ != nullptr);
+}
+
+// Shorthand to get a FieldDescriptor for a field of TestAllTypes.
+inline const FieldDescriptor* TestUtil::ReflectionTester::F(
+ const std::string& name) {
+ const FieldDescriptor* result = nullptr;
+ if (base_descriptor_->name() == "TestAllExtensions" ||
+ base_descriptor_->name() == "TestPackedExtensions") {
+ result = base_descriptor_->file()->FindExtensionByName(name + "_extension");
+ } else {
+ result = base_descriptor_->FindFieldByName(name);
+ }
+ GOOGLE_CHECK(result != nullptr);
+ return result;
+}
+
+// -------------------------------------------------------------------
+
+inline void TestUtil::ReflectionTester::SetAllFieldsViaReflection(
+ Message* message) {
+ const Reflection* reflection = message->GetReflection();
+ Message* sub_message;
+
+ reflection->SetInt32(message, F("optional_int32"), 101);
+ reflection->SetInt64(message, F("optional_int64"), 102);
+ reflection->SetUInt32(message, F("optional_uint32"), 103);
+ reflection->SetUInt64(message, F("optional_uint64"), 104);
+ reflection->SetInt32(message, F("optional_sint32"), 105);
+ reflection->SetInt64(message, F("optional_sint64"), 106);
+ reflection->SetUInt32(message, F("optional_fixed32"), 107);
+ reflection->SetUInt64(message, F("optional_fixed64"), 108);
+ reflection->SetInt32(message, F("optional_sfixed32"), 109);
+ reflection->SetInt64(message, F("optional_sfixed64"), 110);
+ reflection->SetFloat(message, F("optional_float"), 111);
+ reflection->SetDouble(message, F("optional_double"), 112);
+ reflection->SetBool(message, F("optional_bool"), true);
+ reflection->SetString(message, F("optional_string"), "115");
+ reflection->SetString(message, F("optional_bytes"), "116");
+
+ sub_message = reflection->MutableMessage(message, F("optionalgroup"));
+ sub_message->GetReflection()->SetInt32(sub_message, group_a_, 117);
+ sub_message =
+ reflection->MutableMessage(message, F("optional_nested_message"));
+ sub_message->GetReflection()->SetInt32(sub_message, nested_b_, 118);
+ sub_message =
+ reflection->MutableMessage(message, F("optional_foreign_message"));
+ sub_message->GetReflection()->SetInt32(sub_message, foreign_c_, 119);
+ sub_message =
+ reflection->MutableMessage(message, F("optional_import_message"));
+ sub_message->GetReflection()->SetInt32(sub_message, import_d_, 120);
+
+ reflection->SetEnum(message, F("optional_nested_enum"), nested_baz_);
+ reflection->SetEnum(message, F("optional_foreign_enum"), foreign_baz_);
+ reflection->SetEnum(message, F("optional_import_enum"), import_baz_);
+
+ reflection->SetString(message, F("optional_string_piece"), "124");
+ reflection->SetString(message, F("optional_cord"), "125");
+
+ sub_message =
+ reflection->MutableMessage(message, F("optional_public_import_message"));
+ sub_message->GetReflection()->SetInt32(sub_message, import_e_, 126);
+
+ sub_message = reflection->MutableMessage(message, F("optional_lazy_message"));
+ sub_message->GetReflection()->SetInt32(sub_message, nested_b_, 127);
+
+ // -----------------------------------------------------------------
+
+ reflection->AddInt32(message, F("repeated_int32"), 201);
+ reflection->AddInt64(message, F("repeated_int64"), 202);
+ reflection->AddUInt32(message, F("repeated_uint32"), 203);
+ reflection->AddUInt64(message, F("repeated_uint64"), 204);
+ reflection->AddInt32(message, F("repeated_sint32"), 205);
+ reflection->AddInt64(message, F("repeated_sint64"), 206);
+ reflection->AddUInt32(message, F("repeated_fixed32"), 207);
+ reflection->AddUInt64(message, F("repeated_fixed64"), 208);
+ reflection->AddInt32(message, F("repeated_sfixed32"), 209);
+ reflection->AddInt64(message, F("repeated_sfixed64"), 210);
+ reflection->AddFloat(message, F("repeated_float"), 211);
+ reflection->AddDouble(message, F("repeated_double"), 212);
+ reflection->AddBool(message, F("repeated_bool"), true);
+ reflection->AddString(message, F("repeated_string"), "215");
+ reflection->AddString(message, F("repeated_bytes"), "216");
+
+ sub_message = reflection->AddMessage(message, F("repeatedgroup"));
+ sub_message->GetReflection()->SetInt32(sub_message, repeated_group_a_, 217);
+ sub_message = reflection->AddMessage(message, F("repeated_nested_message"));
+ sub_message->GetReflection()->SetInt32(sub_message, nested_b_, 218);
+ sub_message = reflection->AddMessage(message, F("repeated_foreign_message"));
+ sub_message->GetReflection()->SetInt32(sub_message, foreign_c_, 219);
+ sub_message = reflection->AddMessage(message, F("repeated_import_message"));
+ sub_message->GetReflection()->SetInt32(sub_message, import_d_, 220);
+ sub_message = reflection->AddMessage(message, F("repeated_lazy_message"));
+ sub_message->GetReflection()->SetInt32(sub_message, nested_b_, 227);
+
+ reflection->AddEnum(message, F("repeated_nested_enum"), nested_bar_);
+ reflection->AddEnum(message, F("repeated_foreign_enum"), foreign_bar_);
+ reflection->AddEnum(message, F("repeated_import_enum"), import_bar_);
+
+ reflection->AddString(message, F("repeated_string_piece"), "224");
+ reflection->AddString(message, F("repeated_cord"), "225");
+
+ // Add a second one of each field.
+ reflection->AddInt32(message, F("repeated_int32"), 301);
+ reflection->AddInt64(message, F("repeated_int64"), 302);
+ reflection->AddUInt32(message, F("repeated_uint32"), 303);
+ reflection->AddUInt64(message, F("repeated_uint64"), 304);
+ reflection->AddInt32(message, F("repeated_sint32"), 305);
+ reflection->AddInt64(message, F("repeated_sint64"), 306);
+ reflection->AddUInt32(message, F("repeated_fixed32"), 307);
+ reflection->AddUInt64(message, F("repeated_fixed64"), 308);
+ reflection->AddInt32(message, F("repeated_sfixed32"), 309);
+ reflection->AddInt64(message, F("repeated_sfixed64"), 310);
+ reflection->AddFloat(message, F("repeated_float"), 311);
+ reflection->AddDouble(message, F("repeated_double"), 312);
+ reflection->AddBool(message, F("repeated_bool"), false);
+ reflection->AddString(message, F("repeated_string"), "315");
+ reflection->AddString(message, F("repeated_bytes"), "316");
+
+ sub_message = reflection->AddMessage(message, F("repeatedgroup"));
+ sub_message->GetReflection()->SetInt32(sub_message, repeated_group_a_, 317);
+ sub_message = reflection->AddMessage(message, F("repeated_nested_message"));
+ sub_message->GetReflection()->SetInt32(sub_message, nested_b_, 318);
+ sub_message = reflection->AddMessage(message, F("repeated_foreign_message"));
+ sub_message->GetReflection()->SetInt32(sub_message, foreign_c_, 319);
+ sub_message = reflection->AddMessage(message, F("repeated_import_message"));
+ sub_message->GetReflection()->SetInt32(sub_message, import_d_, 320);
+ sub_message = reflection->AddMessage(message, F("repeated_lazy_message"));
+ sub_message->GetReflection()->SetInt32(sub_message, nested_b_, 327);
+
+ reflection->AddEnum(message, F("repeated_nested_enum"), nested_baz_);
+ reflection->AddEnum(message, F("repeated_foreign_enum"), foreign_baz_);
+ reflection->AddEnum(message, F("repeated_import_enum"), import_baz_);
+
+ reflection->AddString(message, F("repeated_string_piece"), "324");
+ reflection->AddString(message, F("repeated_cord"), "325");
+
+ // -----------------------------------------------------------------
+
+ reflection->SetInt32(message, F("default_int32"), 401);
+ reflection->SetInt64(message, F("default_int64"), 402);
+ reflection->SetUInt32(message, F("default_uint32"), 403);
+ reflection->SetUInt64(message, F("default_uint64"), 404);
+ reflection->SetInt32(message, F("default_sint32"), 405);
+ reflection->SetInt64(message, F("default_sint64"), 406);
+ reflection->SetUInt32(message, F("default_fixed32"), 407);
+ reflection->SetUInt64(message, F("default_fixed64"), 408);
+ reflection->SetInt32(message, F("default_sfixed32"), 409);
+ reflection->SetInt64(message, F("default_sfixed64"), 410);
+ reflection->SetFloat(message, F("default_float"), 411);
+ reflection->SetDouble(message, F("default_double"), 412);
+ reflection->SetBool(message, F("default_bool"), false);
+ reflection->SetString(message, F("default_string"), "415");
+ reflection->SetString(message, F("default_bytes"), "416");
+
+ reflection->SetEnum(message, F("default_nested_enum"), nested_foo_);
+ reflection->SetEnum(message, F("default_foreign_enum"), foreign_foo_);
+ reflection->SetEnum(message, F("default_import_enum"), import_foo_);
+
+ reflection->SetString(message, F("default_string_piece"), "424");
+ reflection->SetString(message, F("default_cord"), "425");
+
+ reflection->SetUInt32(message, F("oneof_uint32"), 601);
+ sub_message = reflection->MutableMessage(message, F("oneof_nested_message"));
+ sub_message->GetReflection()->SetInt32(sub_message, nested_b_, 602);
+ reflection->SetString(message, F("oneof_string"), "603");
+ reflection->SetString(message, F("oneof_bytes"), "604");
+}
+
+inline void TestUtil::ReflectionTester::SetOneofViaReflection(
+ Message* message) {
+ const Descriptor* descriptor = message->GetDescriptor();
+ const Reflection* reflection = message->GetReflection();
+ Message* sub_message = reflection->MutableMessage(
+ message, descriptor->FindFieldByName("foo_lazy_message"));
+ sub_message->GetReflection()->SetInt64(
+ sub_message, sub_message->GetDescriptor()->FindFieldByName("qux_int"),
+ 100);
+
+ reflection->SetString(message, descriptor->FindFieldByName("bar_cord"),
+ "101");
+ reflection->SetInt32(message, descriptor->FindFieldByName("baz_int"), 102);
+ reflection->SetString(message, descriptor->FindFieldByName("baz_string"),
+ "103");
+}
+
+inline void TestUtil::ReflectionTester::ExpectOneofSetViaReflection(
+ const Message& message) {
+ const Descriptor* descriptor = message.GetDescriptor();
+ const Reflection* reflection = message.GetReflection();
+ std::string scratch;
+ EXPECT_TRUE(reflection->HasField(
+ message, descriptor->FindFieldByName("foo_lazy_message")));
+ EXPECT_TRUE(
+ reflection->HasField(message, descriptor->FindFieldByName("bar_cord")));
+ EXPECT_TRUE(
+ reflection->HasField(message, descriptor->FindFieldByName("baz_int")));
+ EXPECT_TRUE(
+ reflection->HasField(message, descriptor->FindFieldByName("baz_string")));
+
+ const Message* sub_message = &reflection->GetMessage(
+ message, descriptor->FindFieldByName("foo_lazy_message"));
+ EXPECT_EQ(100, sub_message->GetReflection()->GetInt64(
+ *sub_message,
+ sub_message->GetDescriptor()->FindFieldByName("qux_int")));
+
+ EXPECT_EQ("101", reflection->GetString(
+ message, descriptor->FindFieldByName("bar_cord")));
+ EXPECT_EQ("101",
+ reflection->GetStringReference(
+ message, descriptor->FindFieldByName("bar_cord"), &scratch));
+
+ EXPECT_EQ(102, reflection->GetInt32(message,
+ descriptor->FindFieldByName("baz_int")));
+
+ EXPECT_EQ("103", reflection->GetString(
+ message, descriptor->FindFieldByName("baz_string")));
+ EXPECT_EQ("103",
+ reflection->GetStringReference(
+ message, descriptor->FindFieldByName("baz_string"), &scratch));
+}
+
+inline void TestUtil::ReflectionTester::SetPackedFieldsViaReflection(
+ Message* message) {
+ const Reflection* reflection = message->GetReflection();
+ reflection->AddInt32(message, F("packed_int32"), 601);
+ reflection->AddInt64(message, F("packed_int64"), 602);
+ reflection->AddUInt32(message, F("packed_uint32"), 603);
+ reflection->AddUInt64(message, F("packed_uint64"), 604);
+ reflection->AddInt32(message, F("packed_sint32"), 605);
+ reflection->AddInt64(message, F("packed_sint64"), 606);
+ reflection->AddUInt32(message, F("packed_fixed32"), 607);
+ reflection->AddUInt64(message, F("packed_fixed64"), 608);
+ reflection->AddInt32(message, F("packed_sfixed32"), 609);
+ reflection->AddInt64(message, F("packed_sfixed64"), 610);
+ reflection->AddFloat(message, F("packed_float"), 611);
+ reflection->AddDouble(message, F("packed_double"), 612);
+ reflection->AddBool(message, F("packed_bool"), true);
+ reflection->AddEnum(message, F("packed_enum"), foreign_bar_);
+
+ reflection->AddInt32(message, F("packed_int32"), 701);
+ reflection->AddInt64(message, F("packed_int64"), 702);
+ reflection->AddUInt32(message, F("packed_uint32"), 703);
+ reflection->AddUInt64(message, F("packed_uint64"), 704);
+ reflection->AddInt32(message, F("packed_sint32"), 705);
+ reflection->AddInt64(message, F("packed_sint64"), 706);
+ reflection->AddUInt32(message, F("packed_fixed32"), 707);
+ reflection->AddUInt64(message, F("packed_fixed64"), 708);
+ reflection->AddInt32(message, F("packed_sfixed32"), 709);
+ reflection->AddInt64(message, F("packed_sfixed64"), 710);
+ reflection->AddFloat(message, F("packed_float"), 711);
+ reflection->AddDouble(message, F("packed_double"), 712);
+ reflection->AddBool(message, F("packed_bool"), false);
+ reflection->AddEnum(message, F("packed_enum"), foreign_baz_);
+}
+
+// -------------------------------------------------------------------
+
+inline void TestUtil::ReflectionTester::ExpectAllFieldsSetViaReflection(
+ const Message& message) {
+ // We have to split this into three function otherwise it creates a stack
+ // frame so large that it triggers a warning.
+ ExpectAllFieldsSetViaReflection1(message);
+ ExpectAllFieldsSetViaReflection2(message);
+ ExpectAllFieldsSetViaReflection3(message);
+}
+
+inline void TestUtil::ReflectionTester::ExpectAllFieldsSetViaReflection1(
+ const Message& message) {
+ const Reflection* reflection = message.GetReflection();
+ std::string scratch;
+ const Message* sub_message;
+
+ EXPECT_TRUE(reflection->HasField(message, F("optional_int32")));
+ EXPECT_TRUE(reflection->HasField(message, F("optional_int64")));
+ EXPECT_TRUE(reflection->HasField(message, F("optional_uint32")));
+ EXPECT_TRUE(reflection->HasField(message, F("optional_uint64")));
+ EXPECT_TRUE(reflection->HasField(message, F("optional_sint32")));
+ EXPECT_TRUE(reflection->HasField(message, F("optional_sint64")));
+ EXPECT_TRUE(reflection->HasField(message, F("optional_fixed32")));
+ EXPECT_TRUE(reflection->HasField(message, F("optional_fixed64")));
+ EXPECT_TRUE(reflection->HasField(message, F("optional_sfixed32")));
+ EXPECT_TRUE(reflection->HasField(message, F("optional_sfixed64")));
+ EXPECT_TRUE(reflection->HasField(message, F("optional_float")));
+ EXPECT_TRUE(reflection->HasField(message, F("optional_double")));
+ EXPECT_TRUE(reflection->HasField(message, F("optional_bool")));
+ EXPECT_TRUE(reflection->HasField(message, F("optional_string")));
+ EXPECT_TRUE(reflection->HasField(message, F("optional_bytes")));
+
+ EXPECT_TRUE(reflection->HasField(message, F("optionalgroup")));
+ EXPECT_TRUE(reflection->HasField(message, F("optional_nested_message")));
+ EXPECT_TRUE(reflection->HasField(message, F("optional_foreign_message")));
+ EXPECT_TRUE(reflection->HasField(message, F("optional_import_message")));
+ EXPECT_TRUE(
+ reflection->HasField(message, F("optional_public_import_message")));
+ EXPECT_TRUE(reflection->HasField(message, F("optional_lazy_message")));
+
+ sub_message = &reflection->GetMessage(message, F("optionalgroup"));
+ EXPECT_TRUE(sub_message->GetReflection()->HasField(*sub_message, group_a_));
+ sub_message = &reflection->GetMessage(message, F("optional_nested_message"));
+ EXPECT_TRUE(sub_message->GetReflection()->HasField(*sub_message, nested_b_));
+ sub_message = &reflection->GetMessage(message, F("optional_foreign_message"));
+ EXPECT_TRUE(sub_message->GetReflection()->HasField(*sub_message, foreign_c_));
+ sub_message = &reflection->GetMessage(message, F("optional_import_message"));
+ EXPECT_TRUE(sub_message->GetReflection()->HasField(*sub_message, import_d_));
+ sub_message =
+ &reflection->GetMessage(message, F("optional_public_import_message"));
+ EXPECT_TRUE(sub_message->GetReflection()->HasField(*sub_message, import_e_));
+ sub_message = &reflection->GetMessage(message, F("optional_lazy_message"));
+ EXPECT_TRUE(sub_message->GetReflection()->HasField(*sub_message, nested_b_));
+
+ EXPECT_TRUE(reflection->HasField(message, F("optional_nested_enum")));
+ EXPECT_TRUE(reflection->HasField(message, F("optional_foreign_enum")));
+ EXPECT_TRUE(reflection->HasField(message, F("optional_import_enum")));
+
+ EXPECT_TRUE(reflection->HasField(message, F("optional_string_piece")));
+ EXPECT_TRUE(reflection->HasField(message, F("optional_cord")));
+
+ EXPECT_EQ(101, reflection->GetInt32(message, F("optional_int32")));
+ EXPECT_EQ(102, reflection->GetInt64(message, F("optional_int64")));
+ EXPECT_EQ(103, reflection->GetUInt32(message, F("optional_uint32")));
+ EXPECT_EQ(104, reflection->GetUInt64(message, F("optional_uint64")));
+ EXPECT_EQ(105, reflection->GetInt32(message, F("optional_sint32")));
+ EXPECT_EQ(106, reflection->GetInt64(message, F("optional_sint64")));
+ EXPECT_EQ(107, reflection->GetUInt32(message, F("optional_fixed32")));
+ EXPECT_EQ(108, reflection->GetUInt64(message, F("optional_fixed64")));
+ EXPECT_EQ(109, reflection->GetInt32(message, F("optional_sfixed32")));
+ EXPECT_EQ(110, reflection->GetInt64(message, F("optional_sfixed64")));
+ EXPECT_EQ(111, reflection->GetFloat(message, F("optional_float")));
+ EXPECT_EQ(112, reflection->GetDouble(message, F("optional_double")));
+ EXPECT_TRUE(reflection->GetBool(message, F("optional_bool")));
+ EXPECT_EQ("115", reflection->GetString(message, F("optional_string")));
+ EXPECT_EQ("116", reflection->GetString(message, F("optional_bytes")));
+
+ EXPECT_EQ("115", reflection->GetStringReference(message, F("optional_string"),
+ &scratch));
+ EXPECT_EQ("116", reflection->GetStringReference(message, F("optional_bytes"),
+ &scratch));
+
+ sub_message = &reflection->GetMessage(message, F("optionalgroup"));
+ EXPECT_EQ(117,
+ sub_message->GetReflection()->GetInt32(*sub_message, group_a_));
+ sub_message = &reflection->GetMessage(message, F("optional_nested_message"));
+ EXPECT_EQ(118,
+ sub_message->GetReflection()->GetInt32(*sub_message, nested_b_));
+ sub_message = &reflection->GetMessage(message, F("optional_foreign_message"));
+ EXPECT_EQ(119,
+ sub_message->GetReflection()->GetInt32(*sub_message, foreign_c_));
+ sub_message = &reflection->GetMessage(message, F("optional_import_message"));
+ EXPECT_EQ(120,
+ sub_message->GetReflection()->GetInt32(*sub_message, import_d_));
+ sub_message =
+ &reflection->GetMessage(message, F("optional_public_import_message"));
+ EXPECT_EQ(126,
+ sub_message->GetReflection()->GetInt32(*sub_message, import_e_));
+ sub_message = &reflection->GetMessage(message, F("optional_lazy_message"));
+ EXPECT_EQ(127,
+ sub_message->GetReflection()->GetInt32(*sub_message, nested_b_));
+
+ EXPECT_EQ(nested_baz_,
+ reflection->GetEnum(message, F("optional_nested_enum")));
+ EXPECT_EQ(foreign_baz_,
+ reflection->GetEnum(message, F("optional_foreign_enum")));
+ EXPECT_EQ(import_baz_,
+ reflection->GetEnum(message, F("optional_import_enum")));
+
+ EXPECT_EQ("124", reflection->GetString(message, F("optional_string_piece")));
+ EXPECT_EQ("124", reflection->GetStringReference(
+ message, F("optional_string_piece"), &scratch));
+
+ EXPECT_EQ("125", reflection->GetString(message, F("optional_cord")));
+ EXPECT_EQ("125", reflection->GetStringReference(message, F("optional_cord"),
+ &scratch));
+
+ EXPECT_TRUE(reflection->HasField(message, F("oneof_bytes")));
+ EXPECT_EQ("604", reflection->GetString(message, F("oneof_bytes")));
+
+ if (base_descriptor_->name() == "TestAllTypes") {
+ EXPECT_FALSE(reflection->HasField(message, F("oneof_uint32")));
+ EXPECT_FALSE(reflection->HasField(message, F("oneof_string")));
+ } else {
+ EXPECT_TRUE(reflection->HasField(message, F("oneof_uint32")));
+ EXPECT_TRUE(reflection->HasField(message, F("oneof_string")));
+ EXPECT_EQ(601, reflection->GetUInt32(message, F("oneof_uint32")));
+ EXPECT_EQ("603", reflection->GetString(message, F("oneof_string")));
+ sub_message = &reflection->GetMessage(message, F("oneof_nested_message"));
+ EXPECT_EQ(602,
+ sub_message->GetReflection()->GetInt32(*sub_message, nested_b_));
+ }
+}
+
+inline void TestUtil::ReflectionTester::ExpectAllFieldsSetViaReflection2(
+ const Message& message) {
+ const Reflection* reflection = message.GetReflection();
+ std::string scratch;
+ const Message* sub_message;
+
+ // -----------------------------------------------------------------
+
+ ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_int32")));
+ ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_int64")));
+ ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_uint32")));
+ ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_uint64")));
+ ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_sint32")));
+ ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_sint64")));
+ ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_fixed32")));
+ ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_fixed64")));
+ ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_sfixed32")));
+ ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_sfixed64")));
+ ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_float")));
+ ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_double")));
+ ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_bool")));
+ ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_string")));
+ ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_bytes")));
+
+ ASSERT_EQ(2, reflection->FieldSize(message, F("repeatedgroup")));
+ ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_nested_message")));
+ ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_foreign_message")));
+ ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_import_message")));
+ ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_lazy_message")));
+ ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_nested_enum")));
+ ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_foreign_enum")));
+ ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_import_enum")));
+
+ ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_string_piece")));
+ ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_cord")));
+
+ EXPECT_EQ(201, reflection->GetRepeatedInt32(message, F("repeated_int32"), 0));
+ EXPECT_EQ(202, reflection->GetRepeatedInt64(message, F("repeated_int64"), 0));
+ EXPECT_EQ(203,
+ reflection->GetRepeatedUInt32(message, F("repeated_uint32"), 0));
+ EXPECT_EQ(204,
+ reflection->GetRepeatedUInt64(message, F("repeated_uint64"), 0));
+ EXPECT_EQ(205,
+ reflection->GetRepeatedInt32(message, F("repeated_sint32"), 0));
+ EXPECT_EQ(206,
+ reflection->GetRepeatedInt64(message, F("repeated_sint64"), 0));
+ EXPECT_EQ(207,
+ reflection->GetRepeatedUInt32(message, F("repeated_fixed32"), 0));
+ EXPECT_EQ(208,
+ reflection->GetRepeatedUInt64(message, F("repeated_fixed64"), 0));
+ EXPECT_EQ(209,
+ reflection->GetRepeatedInt32(message, F("repeated_sfixed32"), 0));
+ EXPECT_EQ(210,
+ reflection->GetRepeatedInt64(message, F("repeated_sfixed64"), 0));
+ EXPECT_EQ(211, reflection->GetRepeatedFloat(message, F("repeated_float"), 0));
+ EXPECT_EQ(212,
+ reflection->GetRepeatedDouble(message, F("repeated_double"), 0));
+ EXPECT_TRUE(reflection->GetRepeatedBool(message, F("repeated_bool"), 0));
+ EXPECT_EQ("215",
+ reflection->GetRepeatedString(message, F("repeated_string"), 0));
+ EXPECT_EQ("216",
+ reflection->GetRepeatedString(message, F("repeated_bytes"), 0));
+
+ EXPECT_EQ("215", reflection->GetRepeatedStringReference(
+ message, F("repeated_string"), 0, &scratch));
+ EXPECT_EQ("216", reflection->GetRepeatedStringReference(
+ message, F("repeated_bytes"), 0, &scratch));
+
+ sub_message = &reflection->GetRepeatedMessage(message, F("repeatedgroup"), 0);
+ EXPECT_EQ(217, sub_message->GetReflection()->GetInt32(*sub_message,
+ repeated_group_a_));
+ sub_message =
+ &reflection->GetRepeatedMessage(message, F("repeated_nested_message"), 0);
+ EXPECT_EQ(218,
+ sub_message->GetReflection()->GetInt32(*sub_message, nested_b_));
+ sub_message = &reflection->GetRepeatedMessage(
+ message, F("repeated_foreign_message"), 0);
+ EXPECT_EQ(219,
+ sub_message->GetReflection()->GetInt32(*sub_message, foreign_c_));
+ sub_message =
+ &reflection->GetRepeatedMessage(message, F("repeated_import_message"), 0);
+ EXPECT_EQ(220,
+ sub_message->GetReflection()->GetInt32(*sub_message, import_d_));
+ sub_message =
+ &reflection->GetRepeatedMessage(message, F("repeated_lazy_message"), 0);
+ EXPECT_EQ(227,
+ sub_message->GetReflection()->GetInt32(*sub_message, nested_b_));
+
+ EXPECT_EQ(nested_bar_,
+ reflection->GetRepeatedEnum(message, F("repeated_nested_enum"), 0));
+ EXPECT_EQ(foreign_bar_, reflection->GetRepeatedEnum(
+ message, F("repeated_foreign_enum"), 0));
+ EXPECT_EQ(import_bar_,
+ reflection->GetRepeatedEnum(message, F("repeated_import_enum"), 0));
+
+ EXPECT_EQ("224", reflection->GetRepeatedString(
+ message, F("repeated_string_piece"), 0));
+ EXPECT_EQ("224", reflection->GetRepeatedStringReference(
+ message, F("repeated_string_piece"), 0, &scratch));
+
+ EXPECT_EQ("225",
+ reflection->GetRepeatedString(message, F("repeated_cord"), 0));
+ EXPECT_EQ("225", reflection->GetRepeatedStringReference(
+ message, F("repeated_cord"), 0, &scratch));
+
+ EXPECT_EQ(301, reflection->GetRepeatedInt32(message, F("repeated_int32"), 1));
+ EXPECT_EQ(302, reflection->GetRepeatedInt64(message, F("repeated_int64"), 1));
+ EXPECT_EQ(303,
+ reflection->GetRepeatedUInt32(message, F("repeated_uint32"), 1));
+ EXPECT_EQ(304,
+ reflection->GetRepeatedUInt64(message, F("repeated_uint64"), 1));
+ EXPECT_EQ(305,
+ reflection->GetRepeatedInt32(message, F("repeated_sint32"), 1));
+ EXPECT_EQ(306,
+ reflection->GetRepeatedInt64(message, F("repeated_sint64"), 1));
+ EXPECT_EQ(307,
+ reflection->GetRepeatedUInt32(message, F("repeated_fixed32"), 1));
+ EXPECT_EQ(308,
+ reflection->GetRepeatedUInt64(message, F("repeated_fixed64"), 1));
+ EXPECT_EQ(309,
+ reflection->GetRepeatedInt32(message, F("repeated_sfixed32"), 1));
+ EXPECT_EQ(310,
+ reflection->GetRepeatedInt64(message, F("repeated_sfixed64"), 1));
+ EXPECT_EQ(311, reflection->GetRepeatedFloat(message, F("repeated_float"), 1));
+ EXPECT_EQ(312,
+ reflection->GetRepeatedDouble(message, F("repeated_double"), 1));
+ EXPECT_FALSE(reflection->GetRepeatedBool(message, F("repeated_bool"), 1));
+ EXPECT_EQ("315",
+ reflection->GetRepeatedString(message, F("repeated_string"), 1));
+ EXPECT_EQ("316",
+ reflection->GetRepeatedString(message, F("repeated_bytes"), 1));
+
+ EXPECT_EQ("315", reflection->GetRepeatedStringReference(
+ message, F("repeated_string"), 1, &scratch));
+ EXPECT_EQ("316", reflection->GetRepeatedStringReference(
+ message, F("repeated_bytes"), 1, &scratch));
+
+ sub_message = &reflection->GetRepeatedMessage(message, F("repeatedgroup"), 1);
+ EXPECT_EQ(317, sub_message->GetReflection()->GetInt32(*sub_message,
+ repeated_group_a_));
+ sub_message =
+ &reflection->GetRepeatedMessage(message, F("repeated_nested_message"), 1);
+ EXPECT_EQ(318,
+ sub_message->GetReflection()->GetInt32(*sub_message, nested_b_));
+ sub_message = &reflection->GetRepeatedMessage(
+ message, F("repeated_foreign_message"), 1);
+ EXPECT_EQ(319,
+ sub_message->GetReflection()->GetInt32(*sub_message, foreign_c_));
+ sub_message =
+ &reflection->GetRepeatedMessage(message, F("repeated_import_message"), 1);
+ EXPECT_EQ(320,
+ sub_message->GetReflection()->GetInt32(*sub_message, import_d_));
+ sub_message =
+ &reflection->GetRepeatedMessage(message, F("repeated_lazy_message"), 1);
+ EXPECT_EQ(327,
+ sub_message->GetReflection()->GetInt32(*sub_message, nested_b_));
+
+ EXPECT_EQ(nested_baz_,
+ reflection->GetRepeatedEnum(message, F("repeated_nested_enum"), 1));
+ EXPECT_EQ(foreign_baz_, reflection->GetRepeatedEnum(
+ message, F("repeated_foreign_enum"), 1));
+ EXPECT_EQ(import_baz_,
+ reflection->GetRepeatedEnum(message, F("repeated_import_enum"), 1));
+
+ EXPECT_EQ("324", reflection->GetRepeatedString(
+ message, F("repeated_string_piece"), 1));
+ EXPECT_EQ("324", reflection->GetRepeatedStringReference(
+ message, F("repeated_string_piece"), 1, &scratch));
+
+ EXPECT_EQ("325",
+ reflection->GetRepeatedString(message, F("repeated_cord"), 1));
+ EXPECT_EQ("325", reflection->GetRepeatedStringReference(
+ message, F("repeated_cord"), 1, &scratch));
+}
+
+inline void TestUtil::ReflectionTester::ExpectAllFieldsSetViaReflection3(
+ const Message& message) {
+ const Reflection* reflection = message.GetReflection();
+ std::string scratch;
+
+ // -----------------------------------------------------------------
+
+ EXPECT_TRUE(reflection->HasField(message, F("default_int32")));
+ EXPECT_TRUE(reflection->HasField(message, F("default_int64")));
+ EXPECT_TRUE(reflection->HasField(message, F("default_uint32")));
+ EXPECT_TRUE(reflection->HasField(message, F("default_uint64")));
+ EXPECT_TRUE(reflection->HasField(message, F("default_sint32")));
+ EXPECT_TRUE(reflection->HasField(message, F("default_sint64")));
+ EXPECT_TRUE(reflection->HasField(message, F("default_fixed32")));
+ EXPECT_TRUE(reflection->HasField(message, F("default_fixed64")));
+ EXPECT_TRUE(reflection->HasField(message, F("default_sfixed32")));
+ EXPECT_TRUE(reflection->HasField(message, F("default_sfixed64")));
+ EXPECT_TRUE(reflection->HasField(message, F("default_float")));
+ EXPECT_TRUE(reflection->HasField(message, F("default_double")));
+ EXPECT_TRUE(reflection->HasField(message, F("default_bool")));
+ EXPECT_TRUE(reflection->HasField(message, F("default_string")));
+ EXPECT_TRUE(reflection->HasField(message, F("default_bytes")));
+
+ EXPECT_TRUE(reflection->HasField(message, F("default_nested_enum")));
+ EXPECT_TRUE(reflection->HasField(message, F("default_foreign_enum")));
+ EXPECT_TRUE(reflection->HasField(message, F("default_import_enum")));
+
+ EXPECT_TRUE(reflection->HasField(message, F("default_string_piece")));
+ EXPECT_TRUE(reflection->HasField(message, F("default_cord")));
+
+ EXPECT_EQ(401, reflection->GetInt32(message, F("default_int32")));
+ EXPECT_EQ(402, reflection->GetInt64(message, F("default_int64")));
+ EXPECT_EQ(403, reflection->GetUInt32(message, F("default_uint32")));
+ EXPECT_EQ(404, reflection->GetUInt64(message, F("default_uint64")));
+ EXPECT_EQ(405, reflection->GetInt32(message, F("default_sint32")));
+ EXPECT_EQ(406, reflection->GetInt64(message, F("default_sint64")));
+ EXPECT_EQ(407, reflection->GetUInt32(message, F("default_fixed32")));
+ EXPECT_EQ(408, reflection->GetUInt64(message, F("default_fixed64")));
+ EXPECT_EQ(409, reflection->GetInt32(message, F("default_sfixed32")));
+ EXPECT_EQ(410, reflection->GetInt64(message, F("default_sfixed64")));
+ EXPECT_EQ(411, reflection->GetFloat(message, F("default_float")));
+ EXPECT_EQ(412, reflection->GetDouble(message, F("default_double")));
+ EXPECT_FALSE(reflection->GetBool(message, F("default_bool")));
+ EXPECT_EQ("415", reflection->GetString(message, F("default_string")));
+ EXPECT_EQ("416", reflection->GetString(message, F("default_bytes")));
+
+ EXPECT_EQ("415", reflection->GetStringReference(message, F("default_string"),
+ &scratch));
+ EXPECT_EQ("416", reflection->GetStringReference(message, F("default_bytes"),
+ &scratch));
+
+ EXPECT_EQ(nested_foo_,
+ reflection->GetEnum(message, F("default_nested_enum")));
+ EXPECT_EQ(foreign_foo_,
+ reflection->GetEnum(message, F("default_foreign_enum")));
+ EXPECT_EQ(import_foo_,
+ reflection->GetEnum(message, F("default_import_enum")));
+
+ EXPECT_EQ("424", reflection->GetString(message, F("default_string_piece")));
+ EXPECT_EQ("424", reflection->GetStringReference(
+ message, F("default_string_piece"), &scratch));
+
+ EXPECT_EQ("425", reflection->GetString(message, F("default_cord")));
+ EXPECT_EQ("425", reflection->GetStringReference(message, F("default_cord"),
+ &scratch));
+}
+
+inline void TestUtil::ReflectionTester::ExpectPackedFieldsSetViaReflection(
+ const Message& message) {
+ const Reflection* reflection = message.GetReflection();
+
+ ASSERT_EQ(2, reflection->FieldSize(message, F("packed_int32")));
+ ASSERT_EQ(2, reflection->FieldSize(message, F("packed_int64")));
+ ASSERT_EQ(2, reflection->FieldSize(message, F("packed_uint32")));
+ ASSERT_EQ(2, reflection->FieldSize(message, F("packed_uint64")));
+ ASSERT_EQ(2, reflection->FieldSize(message, F("packed_sint32")));
+ ASSERT_EQ(2, reflection->FieldSize(message, F("packed_sint64")));
+ ASSERT_EQ(2, reflection->FieldSize(message, F("packed_fixed32")));
+ ASSERT_EQ(2, reflection->FieldSize(message, F("packed_fixed64")));
+ ASSERT_EQ(2, reflection->FieldSize(message, F("packed_sfixed32")));
+ ASSERT_EQ(2, reflection->FieldSize(message, F("packed_sfixed64")));
+ ASSERT_EQ(2, reflection->FieldSize(message, F("packed_float")));
+ ASSERT_EQ(2, reflection->FieldSize(message, F("packed_double")));
+ ASSERT_EQ(2, reflection->FieldSize(message, F("packed_bool")));
+ ASSERT_EQ(2, reflection->FieldSize(message, F("packed_enum")));
+
+ EXPECT_EQ(601, reflection->GetRepeatedInt32(message, F("packed_int32"), 0));
+ EXPECT_EQ(602, reflection->GetRepeatedInt64(message, F("packed_int64"), 0));
+ EXPECT_EQ(603, reflection->GetRepeatedUInt32(message, F("packed_uint32"), 0));
+ EXPECT_EQ(604, reflection->GetRepeatedUInt64(message, F("packed_uint64"), 0));
+ EXPECT_EQ(605, reflection->GetRepeatedInt32(message, F("packed_sint32"), 0));
+ EXPECT_EQ(606, reflection->GetRepeatedInt64(message, F("packed_sint64"), 0));
+ EXPECT_EQ(607,
+ reflection->GetRepeatedUInt32(message, F("packed_fixed32"), 0));
+ EXPECT_EQ(608,
+ reflection->GetRepeatedUInt64(message, F("packed_fixed64"), 0));
+ EXPECT_EQ(609,
+ reflection->GetRepeatedInt32(message, F("packed_sfixed32"), 0));
+ EXPECT_EQ(610,
+ reflection->GetRepeatedInt64(message, F("packed_sfixed64"), 0));
+ EXPECT_EQ(611, reflection->GetRepeatedFloat(message, F("packed_float"), 0));
+ EXPECT_EQ(612, reflection->GetRepeatedDouble(message, F("packed_double"), 0));
+ EXPECT_TRUE(reflection->GetRepeatedBool(message, F("packed_bool"), 0));
+ EXPECT_EQ(foreign_bar_,
+ reflection->GetRepeatedEnum(message, F("packed_enum"), 0));
+
+ EXPECT_EQ(701, reflection->GetRepeatedInt32(message, F("packed_int32"), 1));
+ EXPECT_EQ(702, reflection->GetRepeatedInt64(message, F("packed_int64"), 1));
+ EXPECT_EQ(703, reflection->GetRepeatedUInt32(message, F("packed_uint32"), 1));
+ EXPECT_EQ(704, reflection->GetRepeatedUInt64(message, F("packed_uint64"), 1));
+ EXPECT_EQ(705, reflection->GetRepeatedInt32(message, F("packed_sint32"), 1));
+ EXPECT_EQ(706, reflection->GetRepeatedInt64(message, F("packed_sint64"), 1));
+ EXPECT_EQ(707,
+ reflection->GetRepeatedUInt32(message, F("packed_fixed32"), 1));
+ EXPECT_EQ(708,
+ reflection->GetRepeatedUInt64(message, F("packed_fixed64"), 1));
+ EXPECT_EQ(709,
+ reflection->GetRepeatedInt32(message, F("packed_sfixed32"), 1));
+ EXPECT_EQ(710,
+ reflection->GetRepeatedInt64(message, F("packed_sfixed64"), 1));
+ EXPECT_EQ(711, reflection->GetRepeatedFloat(message, F("packed_float"), 1));
+ EXPECT_EQ(712, reflection->GetRepeatedDouble(message, F("packed_double"), 1));
+ EXPECT_FALSE(reflection->GetRepeatedBool(message, F("packed_bool"), 1));
+ EXPECT_EQ(foreign_baz_,
+ reflection->GetRepeatedEnum(message, F("packed_enum"), 1));
+}
+
+// -------------------------------------------------------------------
+
+inline void TestUtil::ReflectionTester::ExpectClearViaReflection(
+ const Message& message) {
+ const Reflection* reflection = message.GetReflection();
+ std::string scratch;
+ const Message* sub_message;
+
+ // has_blah() should initially be false for all optional fields.
+ EXPECT_FALSE(reflection->HasField(message, F("optional_int32")));
+ EXPECT_FALSE(reflection->HasField(message, F("optional_int64")));
+ EXPECT_FALSE(reflection->HasField(message, F("optional_uint32")));
+ EXPECT_FALSE(reflection->HasField(message, F("optional_uint64")));
+ EXPECT_FALSE(reflection->HasField(message, F("optional_sint32")));
+ EXPECT_FALSE(reflection->HasField(message, F("optional_sint64")));
+ EXPECT_FALSE(reflection->HasField(message, F("optional_fixed32")));
+ EXPECT_FALSE(reflection->HasField(message, F("optional_fixed64")));
+ EXPECT_FALSE(reflection->HasField(message, F("optional_sfixed32")));
+ EXPECT_FALSE(reflection->HasField(message, F("optional_sfixed64")));
+ EXPECT_FALSE(reflection->HasField(message, F("optional_float")));
+ EXPECT_FALSE(reflection->HasField(message, F("optional_double")));
+ EXPECT_FALSE(reflection->HasField(message, F("optional_bool")));
+ EXPECT_FALSE(reflection->HasField(message, F("optional_string")));
+ EXPECT_FALSE(reflection->HasField(message, F("optional_bytes")));
+
+ EXPECT_FALSE(reflection->HasField(message, F("optionalgroup")));
+ EXPECT_FALSE(reflection->HasField(message, F("optional_nested_message")));
+ EXPECT_FALSE(reflection->HasField(message, F("optional_foreign_message")));
+ EXPECT_FALSE(reflection->HasField(message, F("optional_import_message")));
+ EXPECT_FALSE(
+ reflection->HasField(message, F("optional_public_import_message")));
+ EXPECT_FALSE(reflection->HasField(message, F("optional_lazy_message")));
+
+ EXPECT_FALSE(reflection->HasField(message, F("optional_nested_enum")));
+ EXPECT_FALSE(reflection->HasField(message, F("optional_foreign_enum")));
+ EXPECT_FALSE(reflection->HasField(message, F("optional_import_enum")));
+
+ EXPECT_FALSE(reflection->HasField(message, F("optional_string_piece")));
+ EXPECT_FALSE(reflection->HasField(message, F("optional_cord")));
+
+ // Optional fields without defaults are set to zero or something like it.
+ EXPECT_EQ(0, reflection->GetInt32(message, F("optional_int32")));
+ EXPECT_EQ(0, reflection->GetInt64(message, F("optional_int64")));
+ EXPECT_EQ(0, reflection->GetUInt32(message, F("optional_uint32")));
+ EXPECT_EQ(0, reflection->GetUInt64(message, F("optional_uint64")));
+ EXPECT_EQ(0, reflection->GetInt32(message, F("optional_sint32")));
+ EXPECT_EQ(0, reflection->GetInt64(message, F("optional_sint64")));
+ EXPECT_EQ(0, reflection->GetUInt32(message, F("optional_fixed32")));
+ EXPECT_EQ(0, reflection->GetUInt64(message, F("optional_fixed64")));
+ EXPECT_EQ(0, reflection->GetInt32(message, F("optional_sfixed32")));
+ EXPECT_EQ(0, reflection->GetInt64(message, F("optional_sfixed64")));
+ EXPECT_EQ(0, reflection->GetFloat(message, F("optional_float")));
+ EXPECT_EQ(0, reflection->GetDouble(message, F("optional_double")));
+ EXPECT_FALSE(reflection->GetBool(message, F("optional_bool")));
+ EXPECT_EQ("", reflection->GetString(message, F("optional_string")));
+ EXPECT_EQ("", reflection->GetString(message, F("optional_bytes")));
+
+ EXPECT_EQ("", reflection->GetStringReference(message, F("optional_string"),
+ &scratch));
+ EXPECT_EQ("", reflection->GetStringReference(message, F("optional_bytes"),
+ &scratch));
+
+ // Embedded messages should also be clear.
+ sub_message = &reflection->GetMessage(message, F("optionalgroup"));
+ EXPECT_FALSE(sub_message->GetReflection()->HasField(*sub_message, group_a_));
+ EXPECT_EQ(0, sub_message->GetReflection()->GetInt32(*sub_message, group_a_));
+ sub_message = &reflection->GetMessage(message, F("optional_nested_message"));
+ EXPECT_FALSE(sub_message->GetReflection()->HasField(*sub_message, nested_b_));
+ EXPECT_EQ(0, sub_message->GetReflection()->GetInt32(*sub_message, nested_b_));
+ sub_message = &reflection->GetMessage(message, F("optional_foreign_message"));
+ EXPECT_FALSE(
+ sub_message->GetReflection()->HasField(*sub_message, foreign_c_));
+ EXPECT_EQ(0,
+ sub_message->GetReflection()->GetInt32(*sub_message, foreign_c_));
+ sub_message = &reflection->GetMessage(message, F("optional_import_message"));
+ EXPECT_FALSE(sub_message->GetReflection()->HasField(*sub_message, import_d_));
+ EXPECT_EQ(0, sub_message->GetReflection()->GetInt32(*sub_message, import_d_));
+ sub_message =
+ &reflection->GetMessage(message, F("optional_public_import_message"));
+ EXPECT_FALSE(sub_message->GetReflection()->HasField(*sub_message, import_e_));
+ EXPECT_EQ(0, sub_message->GetReflection()->GetInt32(*sub_message, import_e_));
+ sub_message = &reflection->GetMessage(message, F("optional_lazy_message"));
+ EXPECT_FALSE(sub_message->GetReflection()->HasField(*sub_message, nested_b_));
+ EXPECT_EQ(0, sub_message->GetReflection()->GetInt32(*sub_message, nested_b_));
+
+ // Enums without defaults are set to the first value in the enum.
+ EXPECT_EQ(nested_foo_,
+ reflection->GetEnum(message, F("optional_nested_enum")));
+ EXPECT_EQ(foreign_foo_,
+ reflection->GetEnum(message, F("optional_foreign_enum")));
+ EXPECT_EQ(import_foo_,
+ reflection->GetEnum(message, F("optional_import_enum")));
+
+ EXPECT_EQ("", reflection->GetString(message, F("optional_string_piece")));
+ EXPECT_EQ("", reflection->GetStringReference(
+ message, F("optional_string_piece"), &scratch));
+
+ EXPECT_EQ("", reflection->GetString(message, F("optional_cord")));
+ EXPECT_EQ("", reflection->GetStringReference(message, F("optional_cord"),
+ &scratch));
+
+ // Repeated fields are empty.
+ EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_int32")));
+ EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_int64")));
+ EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_uint32")));
+ EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_uint64")));
+ EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_sint32")));
+ EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_sint64")));
+ EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_fixed32")));
+ EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_fixed64")));
+ EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_sfixed32")));
+ EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_sfixed64")));
+ EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_float")));
+ EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_double")));
+ EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_bool")));
+ EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_string")));
+ EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_bytes")));
+
+ EXPECT_EQ(0, reflection->FieldSize(message, F("repeatedgroup")));
+ EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_nested_message")));
+ EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_foreign_message")));
+ EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_import_message")));
+ EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_lazy_message")));
+ EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_nested_enum")));
+ EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_foreign_enum")));
+ EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_import_enum")));
+
+ EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_string_piece")));
+ EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_cord")));
+
+ // has_blah() should also be false for all default fields.
+ EXPECT_FALSE(reflection->HasField(message, F("default_int32")));
+ EXPECT_FALSE(reflection->HasField(message, F("default_int64")));
+ EXPECT_FALSE(reflection->HasField(message, F("default_uint32")));
+ EXPECT_FALSE(reflection->HasField(message, F("default_uint64")));
+ EXPECT_FALSE(reflection->HasField(message, F("default_sint32")));
+ EXPECT_FALSE(reflection->HasField(message, F("default_sint64")));
+ EXPECT_FALSE(reflection->HasField(message, F("default_fixed32")));
+ EXPECT_FALSE(reflection->HasField(message, F("default_fixed64")));
+ EXPECT_FALSE(reflection->HasField(message, F("default_sfixed32")));
+ EXPECT_FALSE(reflection->HasField(message, F("default_sfixed64")));
+ EXPECT_FALSE(reflection->HasField(message, F("default_float")));
+ EXPECT_FALSE(reflection->HasField(message, F("default_double")));
+ EXPECT_FALSE(reflection->HasField(message, F("default_bool")));
+ EXPECT_FALSE(reflection->HasField(message, F("default_string")));
+ EXPECT_FALSE(reflection->HasField(message, F("default_bytes")));
+
+ EXPECT_FALSE(reflection->HasField(message, F("default_nested_enum")));
+ EXPECT_FALSE(reflection->HasField(message, F("default_foreign_enum")));
+ EXPECT_FALSE(reflection->HasField(message, F("default_import_enum")));
+
+ EXPECT_FALSE(reflection->HasField(message, F("default_string_piece")));
+ EXPECT_FALSE(reflection->HasField(message, F("default_cord")));
+
+ // Fields with defaults have their default values (duh).
+ EXPECT_EQ(41, reflection->GetInt32(message, F("default_int32")));
+ EXPECT_EQ(42, reflection->GetInt64(message, F("default_int64")));
+ EXPECT_EQ(43, reflection->GetUInt32(message, F("default_uint32")));
+ EXPECT_EQ(44, reflection->GetUInt64(message, F("default_uint64")));
+ EXPECT_EQ(-45, reflection->GetInt32(message, F("default_sint32")));
+ EXPECT_EQ(46, reflection->GetInt64(message, F("default_sint64")));
+ EXPECT_EQ(47, reflection->GetUInt32(message, F("default_fixed32")));
+ EXPECT_EQ(48, reflection->GetUInt64(message, F("default_fixed64")));
+ EXPECT_EQ(49, reflection->GetInt32(message, F("default_sfixed32")));
+ EXPECT_EQ(-50, reflection->GetInt64(message, F("default_sfixed64")));
+ EXPECT_EQ(51.5, reflection->GetFloat(message, F("default_float")));
+ EXPECT_EQ(52e3, reflection->GetDouble(message, F("default_double")));
+ EXPECT_TRUE(reflection->GetBool(message, F("default_bool")));
+ EXPECT_EQ("hello", reflection->GetString(message, F("default_string")));
+ EXPECT_EQ("world", reflection->GetString(message, F("default_bytes")));
+
+ EXPECT_EQ("hello", reflection->GetStringReference(
+ message, F("default_string"), &scratch));
+ EXPECT_EQ("world", reflection->GetStringReference(message, F("default_bytes"),
+ &scratch));
+
+ EXPECT_EQ(nested_bar_,
+ reflection->GetEnum(message, F("default_nested_enum")));
+ EXPECT_EQ(foreign_bar_,
+ reflection->GetEnum(message, F("default_foreign_enum")));
+ EXPECT_EQ(import_bar_,
+ reflection->GetEnum(message, F("default_import_enum")));
+
+ EXPECT_EQ("abc", reflection->GetString(message, F("default_string_piece")));
+ EXPECT_EQ("abc", reflection->GetStringReference(
+ message, F("default_string_piece"), &scratch));
+
+ EXPECT_EQ("123", reflection->GetString(message, F("default_cord")));
+ EXPECT_EQ("123", reflection->GetStringReference(message, F("default_cord"),
+ &scratch));
+}
+
+// -------------------------------------------------------------------
+
+inline void TestUtil::ReflectionTester::ModifyRepeatedFieldsViaReflection(
+ Message* message) {
+ const Reflection* reflection = message->GetReflection();
+ Message* sub_message;
+
+ reflection->SetRepeatedInt32(message, F("repeated_int32"), 1, 501);
+ reflection->SetRepeatedInt64(message, F("repeated_int64"), 1, 502);
+ reflection->SetRepeatedUInt32(message, F("repeated_uint32"), 1, 503);
+ reflection->SetRepeatedUInt64(message, F("repeated_uint64"), 1, 504);
+ reflection->SetRepeatedInt32(message, F("repeated_sint32"), 1, 505);
+ reflection->SetRepeatedInt64(message, F("repeated_sint64"), 1, 506);
+ reflection->SetRepeatedUInt32(message, F("repeated_fixed32"), 1, 507);
+ reflection->SetRepeatedUInt64(message, F("repeated_fixed64"), 1, 508);
+ reflection->SetRepeatedInt32(message, F("repeated_sfixed32"), 1, 509);
+ reflection->SetRepeatedInt64(message, F("repeated_sfixed64"), 1, 510);
+ reflection->SetRepeatedFloat(message, F("repeated_float"), 1, 511);
+ reflection->SetRepeatedDouble(message, F("repeated_double"), 1, 512);
+ reflection->SetRepeatedBool(message, F("repeated_bool"), 1, true);
+ reflection->SetRepeatedString(message, F("repeated_string"), 1, "515");
+ reflection->SetRepeatedString(message, F("repeated_bytes"), 1, "516");
+
+ sub_message =
+ reflection->MutableRepeatedMessage(message, F("repeatedgroup"), 1);
+ sub_message->GetReflection()->SetInt32(sub_message, repeated_group_a_, 517);
+ sub_message = reflection->MutableRepeatedMessage(
+ message, F("repeated_nested_message"), 1);
+ sub_message->GetReflection()->SetInt32(sub_message, nested_b_, 518);
+ sub_message = reflection->MutableRepeatedMessage(
+ message, F("repeated_foreign_message"), 1);
+ sub_message->GetReflection()->SetInt32(sub_message, foreign_c_, 519);
+ sub_message = reflection->MutableRepeatedMessage(
+ message, F("repeated_import_message"), 1);
+ sub_message->GetReflection()->SetInt32(sub_message, import_d_, 520);
+ sub_message = reflection->MutableRepeatedMessage(
+ message, F("repeated_lazy_message"), 1);
+ sub_message->GetReflection()->SetInt32(sub_message, nested_b_, 527);
+
+ reflection->SetRepeatedEnum(message, F("repeated_nested_enum"), 1,
+ nested_foo_);
+ reflection->SetRepeatedEnum(message, F("repeated_foreign_enum"), 1,
+ foreign_foo_);
+ reflection->SetRepeatedEnum(message, F("repeated_import_enum"), 1,
+ import_foo_);
+
+ reflection->SetRepeatedString(message, F("repeated_string_piece"), 1, "524");
+ reflection->SetRepeatedString(message, F("repeated_cord"), 1, "525");
+}
+
+inline void TestUtil::ReflectionTester::RemoveLastRepeatedsViaReflection(
+ Message* message) {
+ const Reflection* reflection = message->GetReflection();
+
+ std::vector<const FieldDescriptor*> output;
+ reflection->ListFields(*message, &output);
+ for (int i = 0; i < output.size(); ++i) {
+ const FieldDescriptor* field = output[i];
+ if (!field->is_repeated()) continue;
+
+ reflection->RemoveLast(message, field);
+ }
+}
+
+inline void TestUtil::ReflectionTester::ReleaseLastRepeatedsViaReflection(
+ Message* message, bool expect_extensions_notnull) {
+ const Reflection* reflection = message->GetReflection();
+
+ std::vector<const FieldDescriptor*> output;
+ reflection->ListFields(*message, &output);
+ for (int i = 0; i < output.size(); ++i) {
+ const FieldDescriptor* field = output[i];
+ if (!field->is_repeated()) continue;
+ if (field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) continue;
+
+ Message* released = reflection->ReleaseLast(message, field);
+ if (!field->is_extension() || expect_extensions_notnull) {
+ ASSERT_TRUE(released != nullptr)
+ << "ReleaseLast returned nullptr for: " << field->name();
+ }
+ delete released;
+ }
+}
+
+inline void TestUtil::ReflectionTester::SwapRepeatedsViaReflection(
+ Message* message) {
+ const Reflection* reflection = message->GetReflection();
+
+ std::vector<const FieldDescriptor*> output;
+ reflection->ListFields(*message, &output);
+ for (int i = 0; i < output.size(); ++i) {
+ const FieldDescriptor* field = output[i];
+ if (!field->is_repeated()) continue;
+
+ reflection->SwapElements(message, field, 0, 1);
+ }
+}
+
+inline void TestUtil::ReflectionTester::
+ SetAllocatedOptionalMessageFieldsToNullViaReflection(Message* message) {
+ const Reflection* reflection = message->GetReflection();
+
+ std::vector<const FieldDescriptor*> fields;
+ reflection->ListFields(*message, &fields);
+
+ for (int i = 0; i < fields.size(); ++i) {
+ const FieldDescriptor* field = fields[i];
+ if (!field->is_optional() ||
+ field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE)
+ continue;
+
+ reflection->SetAllocatedMessage(message, nullptr, field);
+ }
+}
+
+inline void TestUtil::ReflectionTester::
+ SetAllocatedOptionalMessageFieldsToMessageViaReflection(
+ Message* from_message, Message* to_message) {
+ EXPECT_EQ(from_message->GetDescriptor(), to_message->GetDescriptor());
+ const Reflection* from_reflection = from_message->GetReflection();
+ const Reflection* to_reflection = to_message->GetReflection();
+
+ std::vector<const FieldDescriptor*> fields;
+ from_reflection->ListFields(*from_message, &fields);
+
+ for (int i = 0; i < fields.size(); ++i) {
+ const FieldDescriptor* field = fields[i];
+ if (!field->is_optional() ||
+ field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE)
+ continue;
+
+ Message* sub_message = from_reflection->ReleaseMessage(from_message, field);
+ to_reflection->SetAllocatedMessage(to_message, sub_message, field);
+ }
+}
+
+inline void TestUtil::ReflectionTester::ExpectMessagesReleasedViaReflection(
+ Message* message,
+ TestUtil::ReflectionTester::MessageReleaseState expected_release_state) {
+ const Reflection* reflection = message->GetReflection();
+
+ static const char* fields[] = {
+ "optionalgroup",
+ "optional_nested_message",
+ "optional_foreign_message",
+ "optional_import_message",
+ };
+ for (int i = 0; i < GOOGLE_ARRAYSIZE(fields); i++) {
+ Message* released = reflection->ReleaseMessage(message, F(fields[i]));
+ switch (expected_release_state) {
+ case IS_NULL:
+ EXPECT_TRUE(released == nullptr);
+ break;
+ case NOT_NULL:
+ EXPECT_TRUE(released != nullptr);
+ break;
+ case CAN_BE_NULL:
+ break;
+ }
+ delete released;
+ EXPECT_FALSE(reflection->HasField(*message, F(fields[i])));
+ }
+}
+
+// Check that the passed-in serialization is the canonical serialization we
+// expect for a TestFieldOrderings message filled in by
+// SetAllFieldsAndExtensions().
+inline void ExpectAllFieldsAndExtensionsInOrder(const std::string& serialized) {
+ // We set each field individually, serialize separately, and concatenate all
+ // the strings in canonical order to determine the expected serialization.
+ std::string expected;
+ unittest::TestFieldOrderings message;
+ message.set_my_int(1); // Field 1.
+ message.AppendToString(&expected);
+ message.Clear();
+ message.SetExtension(unittest::my_extension_int, 23); // Field 5.
+ message.AppendToString(&expected);
+ message.Clear();
+ message.set_my_string("foo"); // Field 11.
+ message.AppendToString(&expected);
+ message.Clear();
+ message.SetExtension(unittest::my_extension_string, "bar"); // Field 50.
+ message.AppendToString(&expected);
+ message.Clear();
+ message.set_my_float(1.0); // Field 101.
+ message.AppendToString(&expected);
+ message.Clear();
+
+ // We don't EXPECT_EQ() since we don't want to print raw bytes to stdout.
+ EXPECT_TRUE(serialized == expected);
+}
+
+} // namespace TestUtil
+} // namespace protobuf
+} // namespace google
+
+#include <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_TEST_UTIL_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/test_util.inc b/NorthstarDedicatedTest/include/protobuf/test_util.inc
new file mode 100644
index 00000000..8a9fab97
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/test_util.inc
@@ -0,0 +1,2406 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 needs to be included as .inc as it depends on the namespaces
+// (unittest and unittest_import) being set up properly. It is also included
+// within an enclosing namespace and requires header files to be included
+// out of this file.
+
+#include <stubs/logging.h>
+#include <stubs/common.h>
+#include <descriptor.h>
+#include <message.h>
+#include <gtest/gtest.h>
+
+namespace google {
+namespace protobuf {
+namespace TestUtil {
+
+// Set every field in the message to a unique value.
+inline void SetAllFields(UNITTEST::TestAllTypes* message);
+inline void SetOptionalFields(UNITTEST::TestAllTypes* message);
+inline void AddRepeatedFields1(UNITTEST::TestAllTypes* message);
+inline void AddRepeatedFields2(UNITTEST::TestAllTypes* message);
+inline void SetDefaultFields(UNITTEST::TestAllTypes* message);
+inline void SetOneofFields(UNITTEST::TestAllTypes* message);
+inline void SetAllExtensions(UNITTEST::TestAllExtensions* message);
+inline void SetOneofFields(UNITTEST::TestAllExtensions* message);
+inline void SetAllFieldsAndExtensions(UNITTEST::TestFieldOrderings* message);
+inline void SetPackedFields(UNITTEST::TestPackedTypes* message);
+inline void SetPackedExtensions(UNITTEST::TestPackedExtensions* message);
+inline void SetUnpackedFields(UNITTEST::TestUnpackedTypes* message);
+inline void SetOneof1(UNITTEST::TestOneof2* message);
+inline void SetOneof2(UNITTEST::TestOneof2* message);
+
+// Use the repeated versions of the set_*() accessors to modify all the
+// repeated fields of the message (which should already have been
+// initialized with Set*Fields()). Set*Fields() itself only tests
+// the add_*() accessors.
+inline void ModifyRepeatedFields(UNITTEST::TestAllTypes* message);
+inline void ModifyRepeatedExtensions(UNITTEST::TestAllExtensions* message);
+
+// Check that all fields have the values that they should have after
+// Set*Fields() is called.
+inline void ExpectAllFieldsSet(const UNITTEST::TestAllTypes& message);
+inline void ExpectAllExtensionsSet(const UNITTEST::TestAllExtensions& message);
+inline void ExpectPackedFieldsSet(const UNITTEST::TestPackedTypes& message);
+inline void ExpectPackedExtensionsSet(
+ const UNITTEST::TestPackedExtensions& message);
+inline void ExpectUnpackedFieldsSet(const UNITTEST::TestUnpackedTypes& message);
+inline void ExpectUnpackedExtensionsSet(
+ const UNITTEST::TestUnpackedExtensions& message);
+inline void ExpectOneofSet1(const UNITTEST::TestOneof2& message);
+inline void ExpectOneofSet2(const UNITTEST::TestOneof2& message);
+
+// Expect that the message is modified as would be expected from
+// Modify*Fields().
+inline void ExpectRepeatedFieldsModified(const UNITTEST::TestAllTypes& message);
+inline void ExpectRepeatedExtensionsModified(
+ const UNITTEST::TestAllExtensions& message);
+
+// Check that all fields have their default values.
+inline void ExpectClear(const UNITTEST::TestAllTypes& message);
+inline void ExpectExtensionsClear(const UNITTEST::TestAllExtensions& message);
+inline void ExpectOneofClear(const UNITTEST::TestOneof2& message);
+
+// Check that all repeated fields have had their last elements removed.
+inline void ExpectLastRepeatedsRemoved(const UNITTEST::TestAllTypes& message);
+inline void ExpectLastRepeatedExtensionsRemoved(
+ const UNITTEST::TestAllExtensions& message);
+inline void ExpectLastRepeatedsReleased(const UNITTEST::TestAllTypes& message);
+inline void ExpectLastRepeatedExtensionsReleased(
+ const UNITTEST::TestAllExtensions& message);
+
+// Check that all repeated fields have had their first and last elements
+// swapped.
+inline void ExpectRepeatedsSwapped(const UNITTEST::TestAllTypes& message);
+inline void ExpectRepeatedExtensionsSwapped(
+ const UNITTEST::TestAllExtensions& message);
+
+inline void ExpectAtMostOneFieldSetInOneof(const UNITTEST::TestOneof2& message);
+
+} // namespace TestUtil
+
+inline void TestUtil::SetAllFields(UNITTEST::TestAllTypes* message) {
+ SetOptionalFields(message);
+ AddRepeatedFields1(message);
+ AddRepeatedFields2(message);
+ SetDefaultFields(message);
+ SetOneofFields(message);
+}
+
+inline void TestUtil::SetOptionalFields(UNITTEST::TestAllTypes* message) {
+ message->set_optional_int32(101);
+ message->set_optional_int64(102);
+ message->set_optional_uint32(103);
+ message->set_optional_uint64(104);
+ message->set_optional_sint32(105);
+ message->set_optional_sint64(106);
+ message->set_optional_fixed32(107);
+ message->set_optional_fixed64(108);
+ message->set_optional_sfixed32(109);
+ message->set_optional_sfixed64(110);
+ message->set_optional_float(111);
+ message->set_optional_double(112);
+ message->set_optional_bool(true);
+ message->set_optional_string("115");
+ message->set_optional_bytes("116");
+
+ message->mutable_optionalgroup()->set_a(117);
+ message->mutable_optional_nested_message()->set_bb(118);
+ message->mutable_optional_foreign_message()->set_c(119);
+ message->mutable_optional_import_message()->set_d(120);
+ message->mutable_optional_public_import_message()->set_e(126);
+ message->mutable_optional_lazy_message()->set_bb(127);
+
+ message->set_optional_nested_enum(UNITTEST::TestAllTypes::BAZ);
+ message->set_optional_foreign_enum(UNITTEST::FOREIGN_BAZ);
+ message->set_optional_import_enum(UNITTEST_IMPORT::IMPORT_BAZ);
+
+ // StringPiece and Cord fields are only accessible via reflection in the
+ // open source release; see comments in compiler/cpp/string_field.cc.
+#ifndef PROTOBUF_TEST_NO_DESCRIPTORS
+ message->GetReflection()->SetString(
+ message,
+ message->GetDescriptor()->FindFieldByName("optional_string_piece"),
+ "124");
+ message->GetReflection()->SetString(
+ message, message->GetDescriptor()->FindFieldByName("optional_cord"),
+ "125");
+#endif // !PROTOBUF_TEST_NO_DESCRIPTORS
+}
+
+// -------------------------------------------------------------------
+
+inline void TestUtil::AddRepeatedFields1(UNITTEST::TestAllTypes* message) {
+ message->add_repeated_int32(201);
+ message->add_repeated_int64(202);
+ message->add_repeated_uint32(203);
+ message->add_repeated_uint64(204);
+ message->add_repeated_sint32(205);
+ message->add_repeated_sint64(206);
+ message->add_repeated_fixed32(207);
+ message->add_repeated_fixed64(208);
+ message->add_repeated_sfixed32(209);
+ message->add_repeated_sfixed64(210);
+ message->add_repeated_float(211);
+ message->add_repeated_double(212);
+ message->add_repeated_bool(true);
+ message->add_repeated_string("215");
+ message->add_repeated_bytes("216");
+
+ message->add_repeatedgroup()->set_a(217);
+ message->add_repeated_nested_message()->set_bb(218);
+ message->add_repeated_foreign_message()->set_c(219);
+ message->add_repeated_import_message()->set_d(220);
+ message->add_repeated_lazy_message()->set_bb(227);
+
+ message->add_repeated_nested_enum(UNITTEST::TestAllTypes::BAR);
+ message->add_repeated_foreign_enum(UNITTEST::FOREIGN_BAR);
+ message->add_repeated_import_enum(UNITTEST_IMPORT::IMPORT_BAR);
+
+#ifndef PROTOBUF_TEST_NO_DESCRIPTORS
+ message->GetReflection()->AddString(
+ message,
+ message->GetDescriptor()->FindFieldByName("repeated_string_piece"),
+ "224");
+ message->GetReflection()->AddString(
+ message, message->GetDescriptor()->FindFieldByName("repeated_cord"),
+ "225");
+#endif // !PROTOBUF_TEST_NO_DESCRIPTORS
+}
+
+inline void TestUtil::AddRepeatedFields2(UNITTEST::TestAllTypes* message) {
+ // Add a second one of each field.
+ message->add_repeated_int32(301);
+ message->add_repeated_int64(302);
+ message->add_repeated_uint32(303);
+ message->add_repeated_uint64(304);
+ message->add_repeated_sint32(305);
+ message->add_repeated_sint64(306);
+ message->add_repeated_fixed32(307);
+ message->add_repeated_fixed64(308);
+ message->add_repeated_sfixed32(309);
+ message->add_repeated_sfixed64(310);
+ message->add_repeated_float(311);
+ message->add_repeated_double(312);
+ message->add_repeated_bool(false);
+ message->add_repeated_string("315");
+ message->add_repeated_bytes("316");
+
+ message->add_repeatedgroup()->set_a(317);
+ message->add_repeated_nested_message()->set_bb(318);
+ message->add_repeated_foreign_message()->set_c(319);
+ message->add_repeated_import_message()->set_d(320);
+ message->add_repeated_lazy_message()->set_bb(327);
+
+ message->add_repeated_nested_enum(UNITTEST::TestAllTypes::BAZ);
+ message->add_repeated_foreign_enum(UNITTEST::FOREIGN_BAZ);
+ message->add_repeated_import_enum(UNITTEST_IMPORT::IMPORT_BAZ);
+
+#ifndef PROTOBUF_TEST_NO_DESCRIPTORS
+ message->GetReflection()->AddString(
+ message,
+ message->GetDescriptor()->FindFieldByName("repeated_string_piece"),
+ "324");
+ message->GetReflection()->AddString(
+ message, message->GetDescriptor()->FindFieldByName("repeated_cord"),
+ "325");
+#endif // !PROTOBUF_TEST_NO_DESCRIPTORS
+}
+
+// -------------------------------------------------------------------
+
+inline void TestUtil::SetDefaultFields(UNITTEST::TestAllTypes* message) {
+ message->set_default_int32(401);
+ message->set_default_int64(402);
+ message->set_default_uint32(403);
+ message->set_default_uint64(404);
+ message->set_default_sint32(405);
+ message->set_default_sint64(406);
+ message->set_default_fixed32(407);
+ message->set_default_fixed64(408);
+ message->set_default_sfixed32(409);
+ message->set_default_sfixed64(410);
+ message->set_default_float(411);
+ message->set_default_double(412);
+ message->set_default_bool(false);
+ message->set_default_string("415");
+ message->set_default_bytes("416");
+
+ message->set_default_nested_enum(UNITTEST::TestAllTypes::FOO);
+ message->set_default_foreign_enum(UNITTEST::FOREIGN_FOO);
+ message->set_default_import_enum(UNITTEST_IMPORT::IMPORT_FOO);
+
+#ifndef PROTOBUF_TEST_NO_DESCRIPTORS
+ message->GetReflection()->SetString(
+ message,
+ message->GetDescriptor()->FindFieldByName("default_string_piece"), "424");
+ message->GetReflection()->SetString(
+ message, message->GetDescriptor()->FindFieldByName("default_cord"),
+ "425");
+#endif // !PROTOBUF_TEST_NO_DESCRIPTORS
+}
+
+// -------------------------------------------------------------------
+
+inline void TestUtil::ModifyRepeatedFields(UNITTEST::TestAllTypes* message) {
+ message->set_repeated_int32(1, 501);
+ message->set_repeated_int64(1, 502);
+ message->set_repeated_uint32(1, 503);
+ message->set_repeated_uint64(1, 504);
+ message->set_repeated_sint32(1, 505);
+ message->set_repeated_sint64(1, 506);
+ message->set_repeated_fixed32(1, 507);
+ message->set_repeated_fixed64(1, 508);
+ message->set_repeated_sfixed32(1, 509);
+ message->set_repeated_sfixed64(1, 510);
+ message->set_repeated_float(1, 511);
+ message->set_repeated_double(1, 512);
+ message->set_repeated_bool(1, true);
+ message->set_repeated_string(1, "515");
+ message->set_repeated_bytes(1, "516");
+
+ message->mutable_repeatedgroup(1)->set_a(517);
+ message->mutable_repeated_nested_message(1)->set_bb(518);
+ message->mutable_repeated_foreign_message(1)->set_c(519);
+ message->mutable_repeated_import_message(1)->set_d(520);
+ message->mutable_repeated_lazy_message(1)->set_bb(527);
+
+ message->set_repeated_nested_enum(1, UNITTEST::TestAllTypes::FOO);
+ message->set_repeated_foreign_enum(1, UNITTEST::FOREIGN_FOO);
+ message->set_repeated_import_enum(1, UNITTEST_IMPORT::IMPORT_FOO);
+
+#ifndef PROTOBUF_TEST_NO_DESCRIPTORS
+ message->GetReflection()->SetRepeatedString(
+ message,
+ message->GetDescriptor()->FindFieldByName("repeated_string_piece"), 1,
+ "524");
+ message->GetReflection()->SetRepeatedString(
+ message, message->GetDescriptor()->FindFieldByName("repeated_cord"), 1,
+ "525");
+#endif // !PROTOBUF_TEST_NO_DESCRIPTORS
+}
+
+// ------------------------------------------------------------------
+inline void TestUtil::SetOneofFields(UNITTEST::TestAllTypes* message) {
+ message->set_oneof_uint32(601);
+ message->mutable_oneof_nested_message()->set_bb(602);
+ message->set_oneof_string("603");
+ message->set_oneof_bytes("604");
+}
+
+// -------------------------------------------------------------------
+
+inline void TestUtil::ExpectAllFieldsSet(
+ const UNITTEST::TestAllTypes& message) {
+ EXPECT_TRUE(message.has_optional_int32());
+ EXPECT_TRUE(message.has_optional_int64());
+ EXPECT_TRUE(message.has_optional_uint32());
+ EXPECT_TRUE(message.has_optional_uint64());
+ EXPECT_TRUE(message.has_optional_sint32());
+ EXPECT_TRUE(message.has_optional_sint64());
+ EXPECT_TRUE(message.has_optional_fixed32());
+ EXPECT_TRUE(message.has_optional_fixed64());
+ EXPECT_TRUE(message.has_optional_sfixed32());
+ EXPECT_TRUE(message.has_optional_sfixed64());
+ EXPECT_TRUE(message.has_optional_float());
+ EXPECT_TRUE(message.has_optional_double());
+ EXPECT_TRUE(message.has_optional_bool());
+ EXPECT_TRUE(message.has_optional_string());
+ EXPECT_TRUE(message.has_optional_bytes());
+
+ EXPECT_TRUE(message.has_optionalgroup());
+ EXPECT_TRUE(message.has_optional_nested_message());
+ EXPECT_TRUE(message.has_optional_foreign_message());
+ EXPECT_TRUE(message.has_optional_import_message());
+ EXPECT_TRUE(message.has_optional_public_import_message());
+ EXPECT_TRUE(message.has_optional_lazy_message());
+
+ EXPECT_TRUE(message.optionalgroup().has_a());
+ EXPECT_TRUE(message.optional_nested_message().has_bb());
+ EXPECT_TRUE(message.optional_foreign_message().has_c());
+ EXPECT_TRUE(message.optional_import_message().has_d());
+ EXPECT_TRUE(message.optional_public_import_message().has_e());
+ EXPECT_TRUE(message.optional_lazy_message().has_bb());
+
+ EXPECT_TRUE(message.has_optional_nested_enum());
+ EXPECT_TRUE(message.has_optional_foreign_enum());
+ EXPECT_TRUE(message.has_optional_import_enum());
+
+#ifndef PROTOBUF_TEST_NO_DESCRIPTORS
+ EXPECT_TRUE(message.has_optional_string_piece());
+ EXPECT_TRUE(message.has_optional_cord());
+#endif
+
+ EXPECT_EQ(101, message.optional_int32());
+ EXPECT_EQ(102, message.optional_int64());
+ EXPECT_EQ(103, message.optional_uint32());
+ EXPECT_EQ(104, message.optional_uint64());
+ EXPECT_EQ(105, message.optional_sint32());
+ EXPECT_EQ(106, message.optional_sint64());
+ EXPECT_EQ(107, message.optional_fixed32());
+ EXPECT_EQ(108, message.optional_fixed64());
+ EXPECT_EQ(109, message.optional_sfixed32());
+ EXPECT_EQ(110, message.optional_sfixed64());
+ EXPECT_EQ(111, message.optional_float());
+ EXPECT_EQ(112, message.optional_double());
+ EXPECT_TRUE(message.optional_bool());
+ EXPECT_EQ("115", message.optional_string());
+ EXPECT_EQ("116", message.optional_bytes());
+
+ EXPECT_EQ(117, message.optionalgroup().a());
+ EXPECT_EQ(118, message.optional_nested_message().bb());
+ EXPECT_EQ(119, message.optional_foreign_message().c());
+ EXPECT_EQ(120, message.optional_import_message().d());
+ EXPECT_EQ(126, message.optional_public_import_message().e());
+ EXPECT_EQ(127, message.optional_lazy_message().bb());
+
+ EXPECT_EQ(UNITTEST::TestAllTypes::BAZ, message.optional_nested_enum());
+ EXPECT_EQ(UNITTEST::FOREIGN_BAZ, message.optional_foreign_enum());
+ EXPECT_EQ(UNITTEST_IMPORT::IMPORT_BAZ, message.optional_import_enum());
+
+
+ // -----------------------------------------------------------------
+
+ ASSERT_EQ(2, message.repeated_int32_size());
+ ASSERT_EQ(2, message.repeated_int64_size());
+ ASSERT_EQ(2, message.repeated_uint32_size());
+ ASSERT_EQ(2, message.repeated_uint64_size());
+ ASSERT_EQ(2, message.repeated_sint32_size());
+ ASSERT_EQ(2, message.repeated_sint64_size());
+ ASSERT_EQ(2, message.repeated_fixed32_size());
+ ASSERT_EQ(2, message.repeated_fixed64_size());
+ ASSERT_EQ(2, message.repeated_sfixed32_size());
+ ASSERT_EQ(2, message.repeated_sfixed64_size());
+ ASSERT_EQ(2, message.repeated_float_size());
+ ASSERT_EQ(2, message.repeated_double_size());
+ ASSERT_EQ(2, message.repeated_bool_size());
+ ASSERT_EQ(2, message.repeated_string_size());
+ ASSERT_EQ(2, message.repeated_bytes_size());
+
+ ASSERT_EQ(2, message.repeatedgroup_size());
+ ASSERT_EQ(2, message.repeated_nested_message_size());
+ ASSERT_EQ(2, message.repeated_foreign_message_size());
+ ASSERT_EQ(2, message.repeated_import_message_size());
+ ASSERT_EQ(2, message.repeated_lazy_message_size());
+ ASSERT_EQ(2, message.repeated_nested_enum_size());
+ ASSERT_EQ(2, message.repeated_foreign_enum_size());
+ ASSERT_EQ(2, message.repeated_import_enum_size());
+
+#ifndef PROTOBUF_TEST_NO_DESCRIPTORS
+ ASSERT_EQ(2, message.repeated_string_piece_size());
+ ASSERT_EQ(2, message.repeated_cord_size());
+#endif
+
+ EXPECT_EQ(201, message.repeated_int32(0));
+ EXPECT_EQ(202, message.repeated_int64(0));
+ EXPECT_EQ(203, message.repeated_uint32(0));
+ EXPECT_EQ(204, message.repeated_uint64(0));
+ EXPECT_EQ(205, message.repeated_sint32(0));
+ EXPECT_EQ(206, message.repeated_sint64(0));
+ EXPECT_EQ(207, message.repeated_fixed32(0));
+ EXPECT_EQ(208, message.repeated_fixed64(0));
+ EXPECT_EQ(209, message.repeated_sfixed32(0));
+ EXPECT_EQ(210, message.repeated_sfixed64(0));
+ EXPECT_EQ(211, message.repeated_float(0));
+ EXPECT_EQ(212, message.repeated_double(0));
+ EXPECT_TRUE(message.repeated_bool(0));
+ EXPECT_EQ("215", message.repeated_string(0));
+ EXPECT_EQ("216", message.repeated_bytes(0));
+
+ EXPECT_EQ(217, message.repeatedgroup(0).a());
+ EXPECT_EQ(218, message.repeated_nested_message(0).bb());
+ EXPECT_EQ(219, message.repeated_foreign_message(0).c());
+ EXPECT_EQ(220, message.repeated_import_message(0).d());
+ EXPECT_EQ(227, message.repeated_lazy_message(0).bb());
+
+
+ EXPECT_EQ(UNITTEST::TestAllTypes::BAR, message.repeated_nested_enum(0));
+ EXPECT_EQ(UNITTEST::FOREIGN_BAR, message.repeated_foreign_enum(0));
+ EXPECT_EQ(UNITTEST_IMPORT::IMPORT_BAR, message.repeated_import_enum(0));
+
+ EXPECT_EQ(301, message.repeated_int32(1));
+ EXPECT_EQ(302, message.repeated_int64(1));
+ EXPECT_EQ(303, message.repeated_uint32(1));
+ EXPECT_EQ(304, message.repeated_uint64(1));
+ EXPECT_EQ(305, message.repeated_sint32(1));
+ EXPECT_EQ(306, message.repeated_sint64(1));
+ EXPECT_EQ(307, message.repeated_fixed32(1));
+ EXPECT_EQ(308, message.repeated_fixed64(1));
+ EXPECT_EQ(309, message.repeated_sfixed32(1));
+ EXPECT_EQ(310, message.repeated_sfixed64(1));
+ EXPECT_EQ(311, message.repeated_float(1));
+ EXPECT_EQ(312, message.repeated_double(1));
+ EXPECT_FALSE(message.repeated_bool(1));
+ EXPECT_EQ("315", message.repeated_string(1));
+ EXPECT_EQ("316", message.repeated_bytes(1));
+
+ EXPECT_EQ(317, message.repeatedgroup(1).a());
+ EXPECT_EQ(318, message.repeated_nested_message(1).bb());
+ EXPECT_EQ(319, message.repeated_foreign_message(1).c());
+ EXPECT_EQ(320, message.repeated_import_message(1).d());
+ EXPECT_EQ(327, message.repeated_lazy_message(1).bb());
+
+ EXPECT_EQ(UNITTEST::TestAllTypes::BAZ, message.repeated_nested_enum(1));
+ EXPECT_EQ(UNITTEST::FOREIGN_BAZ, message.repeated_foreign_enum(1));
+ EXPECT_EQ(UNITTEST_IMPORT::IMPORT_BAZ, message.repeated_import_enum(1));
+
+
+ // -----------------------------------------------------------------
+
+ EXPECT_TRUE(message.has_default_int32());
+ EXPECT_TRUE(message.has_default_int64());
+ EXPECT_TRUE(message.has_default_uint32());
+ EXPECT_TRUE(message.has_default_uint64());
+ EXPECT_TRUE(message.has_default_sint32());
+ EXPECT_TRUE(message.has_default_sint64());
+ EXPECT_TRUE(message.has_default_fixed32());
+ EXPECT_TRUE(message.has_default_fixed64());
+ EXPECT_TRUE(message.has_default_sfixed32());
+ EXPECT_TRUE(message.has_default_sfixed64());
+ EXPECT_TRUE(message.has_default_float());
+ EXPECT_TRUE(message.has_default_double());
+ EXPECT_TRUE(message.has_default_bool());
+ EXPECT_TRUE(message.has_default_string());
+ EXPECT_TRUE(message.has_default_bytes());
+
+ EXPECT_TRUE(message.has_default_nested_enum());
+ EXPECT_TRUE(message.has_default_foreign_enum());
+ EXPECT_TRUE(message.has_default_import_enum());
+
+
+ EXPECT_EQ(401, message.default_int32());
+ EXPECT_EQ(402, message.default_int64());
+ EXPECT_EQ(403, message.default_uint32());
+ EXPECT_EQ(404, message.default_uint64());
+ EXPECT_EQ(405, message.default_sint32());
+ EXPECT_EQ(406, message.default_sint64());
+ EXPECT_EQ(407, message.default_fixed32());
+ EXPECT_EQ(408, message.default_fixed64());
+ EXPECT_EQ(409, message.default_sfixed32());
+ EXPECT_EQ(410, message.default_sfixed64());
+ EXPECT_EQ(411, message.default_float());
+ EXPECT_EQ(412, message.default_double());
+ EXPECT_FALSE(message.default_bool());
+ EXPECT_EQ("415", message.default_string());
+ EXPECT_EQ("416", message.default_bytes());
+
+ EXPECT_EQ(UNITTEST::TestAllTypes::FOO, message.default_nested_enum());
+ EXPECT_EQ(UNITTEST::FOREIGN_FOO, message.default_foreign_enum());
+ EXPECT_EQ(UNITTEST_IMPORT::IMPORT_FOO, message.default_import_enum());
+
+
+ EXPECT_FALSE(message.has_oneof_uint32());
+ EXPECT_FALSE(message.has_oneof_nested_message());
+ EXPECT_FALSE(message.has_oneof_string());
+ EXPECT_TRUE(message.has_oneof_bytes());
+
+ EXPECT_EQ("604", message.oneof_bytes());
+}
+
+// -------------------------------------------------------------------
+
+inline void TestUtil::ExpectClear(const UNITTEST::TestAllTypes& message) {
+ // has_blah() should initially be false for all optional fields.
+ EXPECT_FALSE(message.has_optional_int32());
+ EXPECT_FALSE(message.has_optional_int64());
+ EXPECT_FALSE(message.has_optional_uint32());
+ EXPECT_FALSE(message.has_optional_uint64());
+ EXPECT_FALSE(message.has_optional_sint32());
+ EXPECT_FALSE(message.has_optional_sint64());
+ EXPECT_FALSE(message.has_optional_fixed32());
+ EXPECT_FALSE(message.has_optional_fixed64());
+ EXPECT_FALSE(message.has_optional_sfixed32());
+ EXPECT_FALSE(message.has_optional_sfixed64());
+ EXPECT_FALSE(message.has_optional_float());
+ EXPECT_FALSE(message.has_optional_double());
+ EXPECT_FALSE(message.has_optional_bool());
+ EXPECT_FALSE(message.has_optional_string());
+ EXPECT_FALSE(message.has_optional_bytes());
+
+ EXPECT_FALSE(message.has_optionalgroup());
+ EXPECT_FALSE(message.has_optional_nested_message());
+ EXPECT_FALSE(message.has_optional_foreign_message());
+ EXPECT_FALSE(message.has_optional_import_message());
+ EXPECT_FALSE(message.has_optional_public_import_message());
+ EXPECT_FALSE(message.has_optional_lazy_message());
+
+ EXPECT_FALSE(message.has_optional_nested_enum());
+ EXPECT_FALSE(message.has_optional_foreign_enum());
+ EXPECT_FALSE(message.has_optional_import_enum());
+
+ EXPECT_FALSE(message.has_optional_string_piece());
+ EXPECT_FALSE(message.has_optional_cord());
+
+ // Optional fields without defaults are set to zero or something like it.
+ EXPECT_EQ(0, message.optional_int32());
+ EXPECT_EQ(0, message.optional_int64());
+ EXPECT_EQ(0, message.optional_uint32());
+ EXPECT_EQ(0, message.optional_uint64());
+ EXPECT_EQ(0, message.optional_sint32());
+ EXPECT_EQ(0, message.optional_sint64());
+ EXPECT_EQ(0, message.optional_fixed32());
+ EXPECT_EQ(0, message.optional_fixed64());
+ EXPECT_EQ(0, message.optional_sfixed32());
+ EXPECT_EQ(0, message.optional_sfixed64());
+ EXPECT_EQ(0, message.optional_float());
+ EXPECT_EQ(0, message.optional_double());
+ EXPECT_FALSE(message.optional_bool());
+ EXPECT_EQ("", message.optional_string());
+ EXPECT_EQ("", message.optional_bytes());
+
+ // Embedded messages should also be clear.
+ EXPECT_FALSE(message.optionalgroup().has_a());
+ EXPECT_FALSE(message.optional_nested_message().has_bb());
+ EXPECT_FALSE(message.optional_foreign_message().has_c());
+ EXPECT_FALSE(message.optional_import_message().has_d());
+ EXPECT_FALSE(message.optional_public_import_message().has_e());
+ EXPECT_FALSE(message.optional_lazy_message().has_bb());
+
+ EXPECT_EQ(0, message.optionalgroup().a());
+ EXPECT_EQ(0, message.optional_nested_message().bb());
+ EXPECT_EQ(0, message.optional_foreign_message().c());
+ EXPECT_EQ(0, message.optional_import_message().d());
+ EXPECT_EQ(0, message.optional_public_import_message().e());
+ EXPECT_EQ(0, message.optional_lazy_message().bb());
+
+ // Enums without defaults are set to the first value in the enum.
+ EXPECT_EQ(UNITTEST::TestAllTypes::FOO, message.optional_nested_enum());
+ EXPECT_EQ(UNITTEST::FOREIGN_FOO, message.optional_foreign_enum());
+ EXPECT_EQ(UNITTEST_IMPORT::IMPORT_FOO, message.optional_import_enum());
+
+
+ // Repeated fields are empty.
+ EXPECT_EQ(0, message.repeated_int32_size());
+ EXPECT_EQ(0, message.repeated_int64_size());
+ EXPECT_EQ(0, message.repeated_uint32_size());
+ EXPECT_EQ(0, message.repeated_uint64_size());
+ EXPECT_EQ(0, message.repeated_sint32_size());
+ EXPECT_EQ(0, message.repeated_sint64_size());
+ EXPECT_EQ(0, message.repeated_fixed32_size());
+ EXPECT_EQ(0, message.repeated_fixed64_size());
+ EXPECT_EQ(0, message.repeated_sfixed32_size());
+ EXPECT_EQ(0, message.repeated_sfixed64_size());
+ EXPECT_EQ(0, message.repeated_float_size());
+ EXPECT_EQ(0, message.repeated_double_size());
+ EXPECT_EQ(0, message.repeated_bool_size());
+ EXPECT_EQ(0, message.repeated_string_size());
+ EXPECT_EQ(0, message.repeated_bytes_size());
+
+ EXPECT_EQ(0, message.repeatedgroup_size());
+ EXPECT_EQ(0, message.repeated_nested_message_size());
+ EXPECT_EQ(0, message.repeated_foreign_message_size());
+ EXPECT_EQ(0, message.repeated_import_message_size());
+ EXPECT_EQ(0, message.repeated_lazy_message_size());
+ EXPECT_EQ(0, message.repeated_nested_enum_size());
+ EXPECT_EQ(0, message.repeated_foreign_enum_size());
+ EXPECT_EQ(0, message.repeated_import_enum_size());
+
+ EXPECT_EQ(0, message.repeated_string_piece_size());
+ EXPECT_EQ(0, message.repeated_cord_size());
+
+ // has_blah() should also be false for all default fields.
+ EXPECT_FALSE(message.has_default_int32());
+ EXPECT_FALSE(message.has_default_int64());
+ EXPECT_FALSE(message.has_default_uint32());
+ EXPECT_FALSE(message.has_default_uint64());
+ EXPECT_FALSE(message.has_default_sint32());
+ EXPECT_FALSE(message.has_default_sint64());
+ EXPECT_FALSE(message.has_default_fixed32());
+ EXPECT_FALSE(message.has_default_fixed64());
+ EXPECT_FALSE(message.has_default_sfixed32());
+ EXPECT_FALSE(message.has_default_sfixed64());
+ EXPECT_FALSE(message.has_default_float());
+ EXPECT_FALSE(message.has_default_double());
+ EXPECT_FALSE(message.has_default_bool());
+ EXPECT_FALSE(message.has_default_string());
+ EXPECT_FALSE(message.has_default_bytes());
+
+ EXPECT_FALSE(message.has_default_nested_enum());
+ EXPECT_FALSE(message.has_default_foreign_enum());
+ EXPECT_FALSE(message.has_default_import_enum());
+
+
+ // Fields with defaults have their default values (duh).
+ EXPECT_EQ(41, message.default_int32());
+ EXPECT_EQ(42, message.default_int64());
+ EXPECT_EQ(43, message.default_uint32());
+ EXPECT_EQ(44, message.default_uint64());
+ EXPECT_EQ(-45, message.default_sint32());
+ EXPECT_EQ(46, message.default_sint64());
+ EXPECT_EQ(47, message.default_fixed32());
+ EXPECT_EQ(48, message.default_fixed64());
+ EXPECT_EQ(49, message.default_sfixed32());
+ EXPECT_EQ(-50, message.default_sfixed64());
+ EXPECT_EQ(51.5, message.default_float());
+ EXPECT_EQ(52e3, message.default_double());
+ EXPECT_TRUE(message.default_bool());
+ EXPECT_EQ("hello", message.default_string());
+ EXPECT_EQ("world", message.default_bytes());
+
+ EXPECT_EQ(UNITTEST::TestAllTypes::BAR, message.default_nested_enum());
+ EXPECT_EQ(UNITTEST::FOREIGN_BAR, message.default_foreign_enum());
+ EXPECT_EQ(UNITTEST_IMPORT::IMPORT_BAR, message.default_import_enum());
+
+
+ EXPECT_FALSE(message.has_oneof_uint32());
+ EXPECT_FALSE(message.has_oneof_nested_message());
+ EXPECT_FALSE(message.has_oneof_string());
+ EXPECT_FALSE(message.has_oneof_bytes());
+}
+
+// -------------------------------------------------------------------
+
+inline void TestUtil::ExpectRepeatedFieldsModified(
+ const UNITTEST::TestAllTypes& message) {
+ // ModifyRepeatedFields only sets the second repeated element of each
+ // field. In addition to verifying this, we also verify that the first
+ // element and size were *not* modified.
+ ASSERT_EQ(2, message.repeated_int32_size());
+ ASSERT_EQ(2, message.repeated_int64_size());
+ ASSERT_EQ(2, message.repeated_uint32_size());
+ ASSERT_EQ(2, message.repeated_uint64_size());
+ ASSERT_EQ(2, message.repeated_sint32_size());
+ ASSERT_EQ(2, message.repeated_sint64_size());
+ ASSERT_EQ(2, message.repeated_fixed32_size());
+ ASSERT_EQ(2, message.repeated_fixed64_size());
+ ASSERT_EQ(2, message.repeated_sfixed32_size());
+ ASSERT_EQ(2, message.repeated_sfixed64_size());
+ ASSERT_EQ(2, message.repeated_float_size());
+ ASSERT_EQ(2, message.repeated_double_size());
+ ASSERT_EQ(2, message.repeated_bool_size());
+ ASSERT_EQ(2, message.repeated_string_size());
+ ASSERT_EQ(2, message.repeated_bytes_size());
+
+ ASSERT_EQ(2, message.repeatedgroup_size());
+ ASSERT_EQ(2, message.repeated_nested_message_size());
+ ASSERT_EQ(2, message.repeated_foreign_message_size());
+ ASSERT_EQ(2, message.repeated_import_message_size());
+ ASSERT_EQ(2, message.repeated_lazy_message_size());
+ ASSERT_EQ(2, message.repeated_nested_enum_size());
+ ASSERT_EQ(2, message.repeated_foreign_enum_size());
+ ASSERT_EQ(2, message.repeated_import_enum_size());
+
+#ifndef PROTOBUF_TEST_NO_DESCRIPTORS
+ ASSERT_EQ(2, message.repeated_string_piece_size());
+ ASSERT_EQ(2, message.repeated_cord_size());
+#endif
+
+ EXPECT_EQ(201, message.repeated_int32(0));
+ EXPECT_EQ(202, message.repeated_int64(0));
+ EXPECT_EQ(203, message.repeated_uint32(0));
+ EXPECT_EQ(204, message.repeated_uint64(0));
+ EXPECT_EQ(205, message.repeated_sint32(0));
+ EXPECT_EQ(206, message.repeated_sint64(0));
+ EXPECT_EQ(207, message.repeated_fixed32(0));
+ EXPECT_EQ(208, message.repeated_fixed64(0));
+ EXPECT_EQ(209, message.repeated_sfixed32(0));
+ EXPECT_EQ(210, message.repeated_sfixed64(0));
+ EXPECT_EQ(211, message.repeated_float(0));
+ EXPECT_EQ(212, message.repeated_double(0));
+ EXPECT_TRUE(message.repeated_bool(0));
+ EXPECT_EQ("215", message.repeated_string(0));
+ EXPECT_EQ("216", message.repeated_bytes(0));
+
+ EXPECT_EQ(217, message.repeatedgroup(0).a());
+ EXPECT_EQ(218, message.repeated_nested_message(0).bb());
+ EXPECT_EQ(219, message.repeated_foreign_message(0).c());
+ EXPECT_EQ(220, message.repeated_import_message(0).d());
+ EXPECT_EQ(227, message.repeated_lazy_message(0).bb());
+
+ EXPECT_EQ(UNITTEST::TestAllTypes::BAR, message.repeated_nested_enum(0));
+ EXPECT_EQ(UNITTEST::FOREIGN_BAR, message.repeated_foreign_enum(0));
+ EXPECT_EQ(UNITTEST_IMPORT::IMPORT_BAR, message.repeated_import_enum(0));
+
+
+ // Actually verify the second (modified) elements now.
+ EXPECT_EQ(501, message.repeated_int32(1));
+ EXPECT_EQ(502, message.repeated_int64(1));
+ EXPECT_EQ(503, message.repeated_uint32(1));
+ EXPECT_EQ(504, message.repeated_uint64(1));
+ EXPECT_EQ(505, message.repeated_sint32(1));
+ EXPECT_EQ(506, message.repeated_sint64(1));
+ EXPECT_EQ(507, message.repeated_fixed32(1));
+ EXPECT_EQ(508, message.repeated_fixed64(1));
+ EXPECT_EQ(509, message.repeated_sfixed32(1));
+ EXPECT_EQ(510, message.repeated_sfixed64(1));
+ EXPECT_EQ(511, message.repeated_float(1));
+ EXPECT_EQ(512, message.repeated_double(1));
+ EXPECT_TRUE(message.repeated_bool(1));
+ EXPECT_EQ("515", message.repeated_string(1));
+ EXPECT_EQ("516", message.repeated_bytes(1));
+
+ EXPECT_EQ(517, message.repeatedgroup(1).a());
+ EXPECT_EQ(518, message.repeated_nested_message(1).bb());
+ EXPECT_EQ(519, message.repeated_foreign_message(1).c());
+ EXPECT_EQ(520, message.repeated_import_message(1).d());
+ EXPECT_EQ(527, message.repeated_lazy_message(1).bb());
+
+ EXPECT_EQ(UNITTEST::TestAllTypes::FOO, message.repeated_nested_enum(1));
+ EXPECT_EQ(UNITTEST::FOREIGN_FOO, message.repeated_foreign_enum(1));
+ EXPECT_EQ(UNITTEST_IMPORT::IMPORT_FOO, message.repeated_import_enum(1));
+
+}
+
+// -------------------------------------------------------------------
+
+inline void TestUtil::SetPackedFields(UNITTEST::TestPackedTypes* message) {
+ message->add_packed_int32(601);
+ message->add_packed_int64(602);
+ message->add_packed_uint32(603);
+ message->add_packed_uint64(604);
+ message->add_packed_sint32(605);
+ message->add_packed_sint64(606);
+ message->add_packed_fixed32(607);
+ message->add_packed_fixed64(608);
+ message->add_packed_sfixed32(609);
+ message->add_packed_sfixed64(610);
+ message->add_packed_float(611);
+ message->add_packed_double(612);
+ message->add_packed_bool(true);
+ message->add_packed_enum(UNITTEST::FOREIGN_BAR);
+ // add a second one of each field
+ message->add_packed_int32(701);
+ message->add_packed_int64(702);
+ message->add_packed_uint32(703);
+ message->add_packed_uint64(704);
+ message->add_packed_sint32(705);
+ message->add_packed_sint64(706);
+ message->add_packed_fixed32(707);
+ message->add_packed_fixed64(708);
+ message->add_packed_sfixed32(709);
+ message->add_packed_sfixed64(710);
+ message->add_packed_float(711);
+ message->add_packed_double(712);
+ message->add_packed_bool(false);
+ message->add_packed_enum(UNITTEST::FOREIGN_BAZ);
+}
+
+inline void TestUtil::SetUnpackedFields(UNITTEST::TestUnpackedTypes* message) {
+ // The values applied here must match those of SetPackedFields.
+
+ message->add_unpacked_int32(601);
+ message->add_unpacked_int64(602);
+ message->add_unpacked_uint32(603);
+ message->add_unpacked_uint64(604);
+ message->add_unpacked_sint32(605);
+ message->add_unpacked_sint64(606);
+ message->add_unpacked_fixed32(607);
+ message->add_unpacked_fixed64(608);
+ message->add_unpacked_sfixed32(609);
+ message->add_unpacked_sfixed64(610);
+ message->add_unpacked_float(611);
+ message->add_unpacked_double(612);
+ message->add_unpacked_bool(true);
+ message->add_unpacked_enum(UNITTEST::FOREIGN_BAR);
+ // add a second one of each field
+ message->add_unpacked_int32(701);
+ message->add_unpacked_int64(702);
+ message->add_unpacked_uint32(703);
+ message->add_unpacked_uint64(704);
+ message->add_unpacked_sint32(705);
+ message->add_unpacked_sint64(706);
+ message->add_unpacked_fixed32(707);
+ message->add_unpacked_fixed64(708);
+ message->add_unpacked_sfixed32(709);
+ message->add_unpacked_sfixed64(710);
+ message->add_unpacked_float(711);
+ message->add_unpacked_double(712);
+ message->add_unpacked_bool(false);
+ message->add_unpacked_enum(UNITTEST::FOREIGN_BAZ);
+}
+
+// -------------------------------------------------------------------
+
+inline void TestUtil::ExpectPackedFieldsSet(
+ const UNITTEST::TestPackedTypes& message) {
+ ASSERT_EQ(2, message.packed_int32_size());
+ ASSERT_EQ(2, message.packed_int64_size());
+ ASSERT_EQ(2, message.packed_uint32_size());
+ ASSERT_EQ(2, message.packed_uint64_size());
+ ASSERT_EQ(2, message.packed_sint32_size());
+ ASSERT_EQ(2, message.packed_sint64_size());
+ ASSERT_EQ(2, message.packed_fixed32_size());
+ ASSERT_EQ(2, message.packed_fixed64_size());
+ ASSERT_EQ(2, message.packed_sfixed32_size());
+ ASSERT_EQ(2, message.packed_sfixed64_size());
+ ASSERT_EQ(2, message.packed_float_size());
+ ASSERT_EQ(2, message.packed_double_size());
+ ASSERT_EQ(2, message.packed_bool_size());
+ ASSERT_EQ(2, message.packed_enum_size());
+
+ EXPECT_EQ(601, message.packed_int32(0));
+ EXPECT_EQ(602, message.packed_int64(0));
+ EXPECT_EQ(603, message.packed_uint32(0));
+ EXPECT_EQ(604, message.packed_uint64(0));
+ EXPECT_EQ(605, message.packed_sint32(0));
+ EXPECT_EQ(606, message.packed_sint64(0));
+ EXPECT_EQ(607, message.packed_fixed32(0));
+ EXPECT_EQ(608, message.packed_fixed64(0));
+ EXPECT_EQ(609, message.packed_sfixed32(0));
+ EXPECT_EQ(610, message.packed_sfixed64(0));
+ EXPECT_EQ(611, message.packed_float(0));
+ EXPECT_EQ(612, message.packed_double(0));
+ EXPECT_TRUE(message.packed_bool(0));
+ EXPECT_EQ(UNITTEST::FOREIGN_BAR, message.packed_enum(0));
+
+ EXPECT_EQ(701, message.packed_int32(1));
+ EXPECT_EQ(702, message.packed_int64(1));
+ EXPECT_EQ(703, message.packed_uint32(1));
+ EXPECT_EQ(704, message.packed_uint64(1));
+ EXPECT_EQ(705, message.packed_sint32(1));
+ EXPECT_EQ(706, message.packed_sint64(1));
+ EXPECT_EQ(707, message.packed_fixed32(1));
+ EXPECT_EQ(708, message.packed_fixed64(1));
+ EXPECT_EQ(709, message.packed_sfixed32(1));
+ EXPECT_EQ(710, message.packed_sfixed64(1));
+ EXPECT_EQ(711, message.packed_float(1));
+ EXPECT_EQ(712, message.packed_double(1));
+ EXPECT_FALSE(message.packed_bool(1));
+ EXPECT_EQ(UNITTEST::FOREIGN_BAZ, message.packed_enum(1));
+}
+
+inline void TestUtil::ExpectUnpackedFieldsSet(
+ const UNITTEST::TestUnpackedTypes& message) {
+ // The values expected here must match those of ExpectPackedFieldsSet.
+
+ ASSERT_EQ(2, message.unpacked_int32_size());
+ ASSERT_EQ(2, message.unpacked_int64_size());
+ ASSERT_EQ(2, message.unpacked_uint32_size());
+ ASSERT_EQ(2, message.unpacked_uint64_size());
+ ASSERT_EQ(2, message.unpacked_sint32_size());
+ ASSERT_EQ(2, message.unpacked_sint64_size());
+ ASSERT_EQ(2, message.unpacked_fixed32_size());
+ ASSERT_EQ(2, message.unpacked_fixed64_size());
+ ASSERT_EQ(2, message.unpacked_sfixed32_size());
+ ASSERT_EQ(2, message.unpacked_sfixed64_size());
+ ASSERT_EQ(2, message.unpacked_float_size());
+ ASSERT_EQ(2, message.unpacked_double_size());
+ ASSERT_EQ(2, message.unpacked_bool_size());
+ ASSERT_EQ(2, message.unpacked_enum_size());
+
+ EXPECT_EQ(601, message.unpacked_int32(0));
+ EXPECT_EQ(602, message.unpacked_int64(0));
+ EXPECT_EQ(603, message.unpacked_uint32(0));
+ EXPECT_EQ(604, message.unpacked_uint64(0));
+ EXPECT_EQ(605, message.unpacked_sint32(0));
+ EXPECT_EQ(606, message.unpacked_sint64(0));
+ EXPECT_EQ(607, message.unpacked_fixed32(0));
+ EXPECT_EQ(608, message.unpacked_fixed64(0));
+ EXPECT_EQ(609, message.unpacked_sfixed32(0));
+ EXPECT_EQ(610, message.unpacked_sfixed64(0));
+ EXPECT_EQ(611, message.unpacked_float(0));
+ EXPECT_EQ(612, message.unpacked_double(0));
+ EXPECT_TRUE(message.unpacked_bool(0));
+ EXPECT_EQ(UNITTEST::FOREIGN_BAR, message.unpacked_enum(0));
+
+ EXPECT_EQ(701, message.unpacked_int32(1));
+ EXPECT_EQ(702, message.unpacked_int64(1));
+ EXPECT_EQ(703, message.unpacked_uint32(1));
+ EXPECT_EQ(704, message.unpacked_uint64(1));
+ EXPECT_EQ(705, message.unpacked_sint32(1));
+ EXPECT_EQ(706, message.unpacked_sint64(1));
+ EXPECT_EQ(707, message.unpacked_fixed32(1));
+ EXPECT_EQ(708, message.unpacked_fixed64(1));
+ EXPECT_EQ(709, message.unpacked_sfixed32(1));
+ EXPECT_EQ(710, message.unpacked_sfixed64(1));
+ EXPECT_EQ(711, message.unpacked_float(1));
+ EXPECT_EQ(712, message.unpacked_double(1));
+ EXPECT_FALSE(message.unpacked_bool(1));
+ EXPECT_EQ(UNITTEST::FOREIGN_BAZ, message.unpacked_enum(1));
+}
+
+// ===================================================================
+// Extensions
+//
+// All this code is exactly equivalent to the above code except that it's
+// manipulating extension fields instead of normal ones.
+
+inline void TestUtil::SetAllExtensions(UNITTEST::TestAllExtensions* message) {
+ message->SetExtension(UNITTEST::optional_int32_extension, 101);
+ message->SetExtension(UNITTEST::optional_int64_extension, 102);
+ message->SetExtension(UNITTEST::optional_uint32_extension, 103);
+ message->SetExtension(UNITTEST::optional_uint64_extension, 104);
+ message->SetExtension(UNITTEST::optional_sint32_extension, 105);
+ message->SetExtension(UNITTEST::optional_sint64_extension, 106);
+ message->SetExtension(UNITTEST::optional_fixed32_extension, 107);
+ message->SetExtension(UNITTEST::optional_fixed64_extension, 108);
+ message->SetExtension(UNITTEST::optional_sfixed32_extension, 109);
+ message->SetExtension(UNITTEST::optional_sfixed64_extension, 110);
+ message->SetExtension(UNITTEST::optional_float_extension, 111);
+ message->SetExtension(UNITTEST::optional_double_extension, 112);
+ message->SetExtension(UNITTEST::optional_bool_extension, true);
+ message->SetExtension(UNITTEST::optional_string_extension, "115");
+ message->SetExtension(UNITTEST::optional_bytes_extension, "116");
+
+ message->MutableExtension(UNITTEST::optionalgroup_extension)->set_a(117);
+ message->MutableExtension(UNITTEST::optional_nested_message_extension)
+ ->set_bb(118);
+ message->MutableExtension(UNITTEST::optional_foreign_message_extension)
+ ->set_c(119);
+ message->MutableExtension(UNITTEST::optional_import_message_extension)
+ ->set_d(120);
+
+ message->SetExtension(UNITTEST::optional_nested_enum_extension,
+ UNITTEST::TestAllTypes::BAZ);
+ message->SetExtension(UNITTEST::optional_foreign_enum_extension,
+ UNITTEST::FOREIGN_BAZ);
+ message->SetExtension(UNITTEST::optional_import_enum_extension,
+ UNITTEST_IMPORT::IMPORT_BAZ);
+
+ message->SetExtension(UNITTEST::optional_string_piece_extension, "124");
+ message->SetExtension(UNITTEST::optional_cord_extension, "125");
+
+ message->MutableExtension(UNITTEST::optional_public_import_message_extension)
+ ->set_e(126);
+ message->MutableExtension(UNITTEST::optional_lazy_message_extension)
+ ->set_bb(127);
+
+ // -----------------------------------------------------------------
+
+ message->AddExtension(UNITTEST::repeated_int32_extension, 201);
+ message->AddExtension(UNITTEST::repeated_int64_extension, 202);
+ message->AddExtension(UNITTEST::repeated_uint32_extension, 203);
+ message->AddExtension(UNITTEST::repeated_uint64_extension, 204);
+ message->AddExtension(UNITTEST::repeated_sint32_extension, 205);
+ message->AddExtension(UNITTEST::repeated_sint64_extension, 206);
+ message->AddExtension(UNITTEST::repeated_fixed32_extension, 207);
+ message->AddExtension(UNITTEST::repeated_fixed64_extension, 208);
+ message->AddExtension(UNITTEST::repeated_sfixed32_extension, 209);
+ message->AddExtension(UNITTEST::repeated_sfixed64_extension, 210);
+ message->AddExtension(UNITTEST::repeated_float_extension, 211);
+ message->AddExtension(UNITTEST::repeated_double_extension, 212);
+ message->AddExtension(UNITTEST::repeated_bool_extension, true);
+ message->AddExtension(UNITTEST::repeated_string_extension, "215");
+ message->AddExtension(UNITTEST::repeated_bytes_extension, "216");
+
+ message->AddExtension(UNITTEST::repeatedgroup_extension)->set_a(217);
+ message->AddExtension(UNITTEST::repeated_nested_message_extension)
+ ->set_bb(218);
+ message->AddExtension(UNITTEST::repeated_foreign_message_extension)
+ ->set_c(219);
+ message->AddExtension(UNITTEST::repeated_import_message_extension)
+ ->set_d(220);
+ message->AddExtension(UNITTEST::repeated_lazy_message_extension)->set_bb(227);
+
+ message->AddExtension(UNITTEST::repeated_nested_enum_extension,
+ UNITTEST::TestAllTypes::BAR);
+ message->AddExtension(UNITTEST::repeated_foreign_enum_extension,
+ UNITTEST::FOREIGN_BAR);
+ message->AddExtension(UNITTEST::repeated_import_enum_extension,
+ UNITTEST_IMPORT::IMPORT_BAR);
+
+ message->AddExtension(UNITTEST::repeated_string_piece_extension, "224");
+ message->AddExtension(UNITTEST::repeated_cord_extension, "225");
+
+ // Add a second one of each field.
+ message->AddExtension(UNITTEST::repeated_int32_extension, 301);
+ message->AddExtension(UNITTEST::repeated_int64_extension, 302);
+ message->AddExtension(UNITTEST::repeated_uint32_extension, 303);
+ message->AddExtension(UNITTEST::repeated_uint64_extension, 304);
+ message->AddExtension(UNITTEST::repeated_sint32_extension, 305);
+ message->AddExtension(UNITTEST::repeated_sint64_extension, 306);
+ message->AddExtension(UNITTEST::repeated_fixed32_extension, 307);
+ message->AddExtension(UNITTEST::repeated_fixed64_extension, 308);
+ message->AddExtension(UNITTEST::repeated_sfixed32_extension, 309);
+ message->AddExtension(UNITTEST::repeated_sfixed64_extension, 310);
+ message->AddExtension(UNITTEST::repeated_float_extension, 311);
+ message->AddExtension(UNITTEST::repeated_double_extension, 312);
+ message->AddExtension(UNITTEST::repeated_bool_extension, false);
+ message->AddExtension(UNITTEST::repeated_string_extension, "315");
+ message->AddExtension(UNITTEST::repeated_bytes_extension, "316");
+
+ message->AddExtension(UNITTEST::repeatedgroup_extension)->set_a(317);
+ message->AddExtension(UNITTEST::repeated_nested_message_extension)
+ ->set_bb(318);
+ message->AddExtension(UNITTEST::repeated_foreign_message_extension)
+ ->set_c(319);
+ message->AddExtension(UNITTEST::repeated_import_message_extension)
+ ->set_d(320);
+ message->AddExtension(UNITTEST::repeated_lazy_message_extension)->set_bb(327);
+
+ message->AddExtension(UNITTEST::repeated_nested_enum_extension,
+ UNITTEST::TestAllTypes::BAZ);
+ message->AddExtension(UNITTEST::repeated_foreign_enum_extension,
+ UNITTEST::FOREIGN_BAZ);
+ message->AddExtension(UNITTEST::repeated_import_enum_extension,
+ UNITTEST_IMPORT::IMPORT_BAZ);
+
+ message->AddExtension(UNITTEST::repeated_string_piece_extension, "324");
+ message->AddExtension(UNITTEST::repeated_cord_extension, "325");
+
+ // -----------------------------------------------------------------
+
+ message->SetExtension(UNITTEST::default_int32_extension, 401);
+ message->SetExtension(UNITTEST::default_int64_extension, 402);
+ message->SetExtension(UNITTEST::default_uint32_extension, 403);
+ message->SetExtension(UNITTEST::default_uint64_extension, 404);
+ message->SetExtension(UNITTEST::default_sint32_extension, 405);
+ message->SetExtension(UNITTEST::default_sint64_extension, 406);
+ message->SetExtension(UNITTEST::default_fixed32_extension, 407);
+ message->SetExtension(UNITTEST::default_fixed64_extension, 408);
+ message->SetExtension(UNITTEST::default_sfixed32_extension, 409);
+ message->SetExtension(UNITTEST::default_sfixed64_extension, 410);
+ message->SetExtension(UNITTEST::default_float_extension, 411);
+ message->SetExtension(UNITTEST::default_double_extension, 412);
+ message->SetExtension(UNITTEST::default_bool_extension, false);
+ message->SetExtension(UNITTEST::default_string_extension, "415");
+ message->SetExtension(UNITTEST::default_bytes_extension, "416");
+
+ message->SetExtension(UNITTEST::default_nested_enum_extension,
+ UNITTEST::TestAllTypes::FOO);
+ message->SetExtension(UNITTEST::default_foreign_enum_extension,
+ UNITTEST::FOREIGN_FOO);
+ message->SetExtension(UNITTEST::default_import_enum_extension,
+ UNITTEST_IMPORT::IMPORT_FOO);
+
+ message->SetExtension(UNITTEST::default_string_piece_extension, "424");
+ message->SetExtension(UNITTEST::default_cord_extension, "425");
+
+ SetOneofFields(message);
+}
+
+inline void TestUtil::SetOneofFields(UNITTEST::TestAllExtensions* message) {
+ message->SetExtension(UNITTEST::oneof_uint32_extension, 601);
+ message->MutableExtension(UNITTEST::oneof_nested_message_extension)
+ ->set_bb(602);
+ message->SetExtension(UNITTEST::oneof_string_extension, "603");
+ message->SetExtension(UNITTEST::oneof_bytes_extension, "604");
+}
+
+// -------------------------------------------------------------------
+
+inline void TestUtil::SetAllFieldsAndExtensions(
+ UNITTEST::TestFieldOrderings* message) {
+ GOOGLE_CHECK(message);
+ message->set_my_int(1);
+ message->set_my_string("foo");
+ message->set_my_float(1.0);
+ message->SetExtension(UNITTEST::my_extension_int, 23);
+ message->SetExtension(UNITTEST::my_extension_string, "bar");
+}
+
+// -------------------------------------------------------------------
+
+inline void TestUtil::ModifyRepeatedExtensions(
+ UNITTEST::TestAllExtensions* message) {
+ message->SetExtension(UNITTEST::repeated_int32_extension, 1, 501);
+ message->SetExtension(UNITTEST::repeated_int64_extension, 1, 502);
+ message->SetExtension(UNITTEST::repeated_uint32_extension, 1, 503);
+ message->SetExtension(UNITTEST::repeated_uint64_extension, 1, 504);
+ message->SetExtension(UNITTEST::repeated_sint32_extension, 1, 505);
+ message->SetExtension(UNITTEST::repeated_sint64_extension, 1, 506);
+ message->SetExtension(UNITTEST::repeated_fixed32_extension, 1, 507);
+ message->SetExtension(UNITTEST::repeated_fixed64_extension, 1, 508);
+ message->SetExtension(UNITTEST::repeated_sfixed32_extension, 1, 509);
+ message->SetExtension(UNITTEST::repeated_sfixed64_extension, 1, 510);
+ message->SetExtension(UNITTEST::repeated_float_extension, 1, 511);
+ message->SetExtension(UNITTEST::repeated_double_extension, 1, 512);
+ message->SetExtension(UNITTEST::repeated_bool_extension, 1, true);
+ message->SetExtension(UNITTEST::repeated_string_extension, 1, "515");
+ message->SetExtension(UNITTEST::repeated_bytes_extension, 1, "516");
+
+ message->MutableExtension(UNITTEST::repeatedgroup_extension, 1)->set_a(517);
+ message->MutableExtension(UNITTEST::repeated_nested_message_extension, 1)
+ ->set_bb(518);
+ message->MutableExtension(UNITTEST::repeated_foreign_message_extension, 1)
+ ->set_c(519);
+ message->MutableExtension(UNITTEST::repeated_import_message_extension, 1)
+ ->set_d(520);
+ message->MutableExtension(UNITTEST::repeated_lazy_message_extension, 1)
+ ->set_bb(527);
+
+ message->SetExtension(UNITTEST::repeated_nested_enum_extension, 1,
+ UNITTEST::TestAllTypes::FOO);
+ message->SetExtension(UNITTEST::repeated_foreign_enum_extension, 1,
+ UNITTEST::FOREIGN_FOO);
+ message->SetExtension(UNITTEST::repeated_import_enum_extension, 1,
+ UNITTEST_IMPORT::IMPORT_FOO);
+
+ message->SetExtension(UNITTEST::repeated_string_piece_extension, 1, "524");
+ message->SetExtension(UNITTEST::repeated_cord_extension, 1, "525");
+}
+
+// -------------------------------------------------------------------
+
+inline void TestUtil::ExpectAllExtensionsSet(
+ const UNITTEST::TestAllExtensions& message) {
+ EXPECT_TRUE(message.HasExtension(UNITTEST::optional_int32_extension));
+ EXPECT_TRUE(message.HasExtension(UNITTEST::optional_int64_extension));
+ EXPECT_TRUE(message.HasExtension(UNITTEST::optional_uint32_extension));
+ EXPECT_TRUE(message.HasExtension(UNITTEST::optional_uint64_extension));
+ EXPECT_TRUE(message.HasExtension(UNITTEST::optional_sint32_extension));
+ EXPECT_TRUE(message.HasExtension(UNITTEST::optional_sint64_extension));
+ EXPECT_TRUE(message.HasExtension(UNITTEST::optional_fixed32_extension));
+ EXPECT_TRUE(message.HasExtension(UNITTEST::optional_fixed64_extension));
+ EXPECT_TRUE(message.HasExtension(UNITTEST::optional_sfixed32_extension));
+ EXPECT_TRUE(message.HasExtension(UNITTEST::optional_sfixed64_extension));
+ EXPECT_TRUE(message.HasExtension(UNITTEST::optional_float_extension));
+ EXPECT_TRUE(message.HasExtension(UNITTEST::optional_double_extension));
+ EXPECT_TRUE(message.HasExtension(UNITTEST::optional_bool_extension));
+ EXPECT_TRUE(message.HasExtension(UNITTEST::optional_string_extension));
+ EXPECT_TRUE(message.HasExtension(UNITTEST::optional_bytes_extension));
+
+ EXPECT_TRUE(message.HasExtension(UNITTEST::optionalgroup_extension));
+ EXPECT_TRUE(
+ message.HasExtension(UNITTEST::optional_nested_message_extension));
+ EXPECT_TRUE(
+ message.HasExtension(UNITTEST::optional_foreign_message_extension));
+ EXPECT_TRUE(
+ message.HasExtension(UNITTEST::optional_import_message_extension));
+ EXPECT_TRUE(
+ message.HasExtension(UNITTEST::optional_public_import_message_extension));
+ EXPECT_TRUE(message.HasExtension(UNITTEST::optional_lazy_message_extension));
+
+ EXPECT_TRUE(message.GetExtension(UNITTEST::optionalgroup_extension).has_a());
+ EXPECT_TRUE(message.GetExtension(UNITTEST::optional_nested_message_extension)
+ .has_bb());
+ EXPECT_TRUE(message.GetExtension(UNITTEST::optional_foreign_message_extension)
+ .has_c());
+ EXPECT_TRUE(message.GetExtension(UNITTEST::optional_import_message_extension)
+ .has_d());
+ EXPECT_TRUE(
+ message.GetExtension(UNITTEST::optional_public_import_message_extension)
+ .has_e());
+ EXPECT_TRUE(
+ message.GetExtension(UNITTEST::optional_lazy_message_extension).has_bb());
+
+ EXPECT_TRUE(message.HasExtension(UNITTEST::optional_nested_enum_extension));
+ EXPECT_TRUE(message.HasExtension(UNITTEST::optional_foreign_enum_extension));
+ EXPECT_TRUE(message.HasExtension(UNITTEST::optional_import_enum_extension));
+
+ EXPECT_TRUE(message.HasExtension(UNITTEST::optional_string_piece_extension));
+ EXPECT_TRUE(message.HasExtension(UNITTEST::optional_cord_extension));
+
+ EXPECT_EQ(101, message.GetExtension(UNITTEST::optional_int32_extension));
+ EXPECT_EQ(102, message.GetExtension(UNITTEST::optional_int64_extension));
+ EXPECT_EQ(103, message.GetExtension(UNITTEST::optional_uint32_extension));
+ EXPECT_EQ(104, message.GetExtension(UNITTEST::optional_uint64_extension));
+ EXPECT_EQ(105, message.GetExtension(UNITTEST::optional_sint32_extension));
+ EXPECT_EQ(106, message.GetExtension(UNITTEST::optional_sint64_extension));
+ EXPECT_EQ(107, message.GetExtension(UNITTEST::optional_fixed32_extension));
+ EXPECT_EQ(108, message.GetExtension(UNITTEST::optional_fixed64_extension));
+ EXPECT_EQ(109, message.GetExtension(UNITTEST::optional_sfixed32_extension));
+ EXPECT_EQ(110, message.GetExtension(UNITTEST::optional_sfixed64_extension));
+ EXPECT_EQ(111, message.GetExtension(UNITTEST::optional_float_extension));
+ EXPECT_EQ(112, message.GetExtension(UNITTEST::optional_double_extension));
+ EXPECT_TRUE(message.GetExtension(UNITTEST::optional_bool_extension));
+ EXPECT_EQ("115", message.GetExtension(UNITTEST::optional_string_extension));
+ EXPECT_EQ("116", message.GetExtension(UNITTEST::optional_bytes_extension));
+
+ EXPECT_EQ(117, message.GetExtension(UNITTEST::optionalgroup_extension).a());
+ EXPECT_EQ(
+ 118,
+ message.GetExtension(UNITTEST::optional_nested_message_extension).bb());
+ EXPECT_EQ(
+ 119,
+ message.GetExtension(UNITTEST::optional_foreign_message_extension).c());
+ EXPECT_EQ(
+ 120,
+ message.GetExtension(UNITTEST::optional_import_message_extension).d());
+
+ EXPECT_EQ(UNITTEST::TestAllTypes::BAZ,
+ message.GetExtension(UNITTEST::optional_nested_enum_extension));
+ EXPECT_EQ(UNITTEST::FOREIGN_BAZ,
+ message.GetExtension(UNITTEST::optional_foreign_enum_extension));
+ EXPECT_EQ(UNITTEST_IMPORT::IMPORT_BAZ,
+ message.GetExtension(UNITTEST::optional_import_enum_extension));
+
+ EXPECT_EQ("124",
+ message.GetExtension(UNITTEST::optional_string_piece_extension));
+ EXPECT_EQ("125", message.GetExtension(UNITTEST::optional_cord_extension));
+ EXPECT_EQ(
+ 126,
+ message.GetExtension(UNITTEST::optional_public_import_message_extension)
+ .e());
+ EXPECT_EQ(
+ 127,
+ message.GetExtension(UNITTEST::optional_lazy_message_extension).bb());
+
+ // -----------------------------------------------------------------
+
+ ASSERT_EQ(2, message.ExtensionSize(UNITTEST::repeated_int32_extension));
+ ASSERT_EQ(2, message.ExtensionSize(UNITTEST::repeated_int64_extension));
+ ASSERT_EQ(2, message.ExtensionSize(UNITTEST::repeated_uint32_extension));
+ ASSERT_EQ(2, message.ExtensionSize(UNITTEST::repeated_uint64_extension));
+ ASSERT_EQ(2, message.ExtensionSize(UNITTEST::repeated_sint32_extension));
+ ASSERT_EQ(2, message.ExtensionSize(UNITTEST::repeated_sint64_extension));
+ ASSERT_EQ(2, message.ExtensionSize(UNITTEST::repeated_fixed32_extension));
+ ASSERT_EQ(2, message.ExtensionSize(UNITTEST::repeated_fixed64_extension));
+ ASSERT_EQ(2, message.ExtensionSize(UNITTEST::repeated_sfixed32_extension));
+ ASSERT_EQ(2, message.ExtensionSize(UNITTEST::repeated_sfixed64_extension));
+ ASSERT_EQ(2, message.ExtensionSize(UNITTEST::repeated_float_extension));
+ ASSERT_EQ(2, message.ExtensionSize(UNITTEST::repeated_double_extension));
+ ASSERT_EQ(2, message.ExtensionSize(UNITTEST::repeated_bool_extension));
+ ASSERT_EQ(2, message.ExtensionSize(UNITTEST::repeated_string_extension));
+ ASSERT_EQ(2, message.ExtensionSize(UNITTEST::repeated_bytes_extension));
+
+ ASSERT_EQ(2, message.ExtensionSize(UNITTEST::repeatedgroup_extension));
+ ASSERT_EQ(2,
+ message.ExtensionSize(UNITTEST::repeated_nested_message_extension));
+ ASSERT_EQ(
+ 2, message.ExtensionSize(UNITTEST::repeated_foreign_message_extension));
+ ASSERT_EQ(2,
+ message.ExtensionSize(UNITTEST::repeated_import_message_extension));
+ ASSERT_EQ(2,
+ message.ExtensionSize(UNITTEST::repeated_lazy_message_extension));
+ ASSERT_EQ(2, message.ExtensionSize(UNITTEST::repeated_nested_enum_extension));
+ ASSERT_EQ(2,
+ message.ExtensionSize(UNITTEST::repeated_foreign_enum_extension));
+ ASSERT_EQ(2, message.ExtensionSize(UNITTEST::repeated_import_enum_extension));
+
+ ASSERT_EQ(2,
+ message.ExtensionSize(UNITTEST::repeated_string_piece_extension));
+ ASSERT_EQ(2, message.ExtensionSize(UNITTEST::repeated_cord_extension));
+
+ EXPECT_EQ(201, message.GetExtension(UNITTEST::repeated_int32_extension, 0));
+ EXPECT_EQ(202, message.GetExtension(UNITTEST::repeated_int64_extension, 0));
+ EXPECT_EQ(203, message.GetExtension(UNITTEST::repeated_uint32_extension, 0));
+ EXPECT_EQ(204, message.GetExtension(UNITTEST::repeated_uint64_extension, 0));
+ EXPECT_EQ(205, message.GetExtension(UNITTEST::repeated_sint32_extension, 0));
+ EXPECT_EQ(206, message.GetExtension(UNITTEST::repeated_sint64_extension, 0));
+ EXPECT_EQ(207, message.GetExtension(UNITTEST::repeated_fixed32_extension, 0));
+ EXPECT_EQ(208, message.GetExtension(UNITTEST::repeated_fixed64_extension, 0));
+ EXPECT_EQ(209,
+ message.GetExtension(UNITTEST::repeated_sfixed32_extension, 0));
+ EXPECT_EQ(210,
+ message.GetExtension(UNITTEST::repeated_sfixed64_extension, 0));
+ EXPECT_EQ(211, message.GetExtension(UNITTEST::repeated_float_extension, 0));
+ EXPECT_EQ(212, message.GetExtension(UNITTEST::repeated_double_extension, 0));
+ EXPECT_TRUE(message.GetExtension(UNITTEST::repeated_bool_extension, 0));
+ EXPECT_EQ("215",
+ message.GetExtension(UNITTEST::repeated_string_extension, 0));
+ EXPECT_EQ("216", message.GetExtension(UNITTEST::repeated_bytes_extension, 0));
+
+ EXPECT_EQ(217,
+ message.GetExtension(UNITTEST::repeatedgroup_extension, 0).a());
+ EXPECT_EQ(218,
+ message.GetExtension(UNITTEST::repeated_nested_message_extension, 0)
+ .bb());
+ EXPECT_EQ(
+ 219, message.GetExtension(UNITTEST::repeated_foreign_message_extension, 0)
+ .c());
+ EXPECT_EQ(
+ 220,
+ message.GetExtension(UNITTEST::repeated_import_message_extension, 0).d());
+ EXPECT_EQ(
+ 227,
+ message.GetExtension(UNITTEST::repeated_lazy_message_extension, 0).bb());
+
+ EXPECT_EQ(UNITTEST::TestAllTypes::BAR,
+ message.GetExtension(UNITTEST::repeated_nested_enum_extension, 0));
+ EXPECT_EQ(UNITTEST::FOREIGN_BAR,
+ message.GetExtension(UNITTEST::repeated_foreign_enum_extension, 0));
+ EXPECT_EQ(UNITTEST_IMPORT::IMPORT_BAR,
+ message.GetExtension(UNITTEST::repeated_import_enum_extension, 0));
+
+ EXPECT_EQ("224",
+ message.GetExtension(UNITTEST::repeated_string_piece_extension, 0));
+ EXPECT_EQ("225", message.GetExtension(UNITTEST::repeated_cord_extension, 0));
+
+ EXPECT_EQ(301, message.GetExtension(UNITTEST::repeated_int32_extension, 1));
+ EXPECT_EQ(302, message.GetExtension(UNITTEST::repeated_int64_extension, 1));
+ EXPECT_EQ(303, message.GetExtension(UNITTEST::repeated_uint32_extension, 1));
+ EXPECT_EQ(304, message.GetExtension(UNITTEST::repeated_uint64_extension, 1));
+ EXPECT_EQ(305, message.GetExtension(UNITTEST::repeated_sint32_extension, 1));
+ EXPECT_EQ(306, message.GetExtension(UNITTEST::repeated_sint64_extension, 1));
+ EXPECT_EQ(307, message.GetExtension(UNITTEST::repeated_fixed32_extension, 1));
+ EXPECT_EQ(308, message.GetExtension(UNITTEST::repeated_fixed64_extension, 1));
+ EXPECT_EQ(309,
+ message.GetExtension(UNITTEST::repeated_sfixed32_extension, 1));
+ EXPECT_EQ(310,
+ message.GetExtension(UNITTEST::repeated_sfixed64_extension, 1));
+ EXPECT_EQ(311, message.GetExtension(UNITTEST::repeated_float_extension, 1));
+ EXPECT_EQ(312, message.GetExtension(UNITTEST::repeated_double_extension, 1));
+ EXPECT_FALSE(message.GetExtension(UNITTEST::repeated_bool_extension, 1));
+ EXPECT_EQ("315",
+ message.GetExtension(UNITTEST::repeated_string_extension, 1));
+ EXPECT_EQ("316", message.GetExtension(UNITTEST::repeated_bytes_extension, 1));
+
+ EXPECT_EQ(317,
+ message.GetExtension(UNITTEST::repeatedgroup_extension, 1).a());
+ EXPECT_EQ(318,
+ message.GetExtension(UNITTEST::repeated_nested_message_extension, 1)
+ .bb());
+ EXPECT_EQ(
+ 319, message.GetExtension(UNITTEST::repeated_foreign_message_extension, 1)
+ .c());
+ EXPECT_EQ(
+ 320,
+ message.GetExtension(UNITTEST::repeated_import_message_extension, 1).d());
+ EXPECT_EQ(
+ 327,
+ message.GetExtension(UNITTEST::repeated_lazy_message_extension, 1).bb());
+
+ EXPECT_EQ(UNITTEST::TestAllTypes::BAZ,
+ message.GetExtension(UNITTEST::repeated_nested_enum_extension, 1));
+ EXPECT_EQ(UNITTEST::FOREIGN_BAZ,
+ message.GetExtension(UNITTEST::repeated_foreign_enum_extension, 1));
+ EXPECT_EQ(UNITTEST_IMPORT::IMPORT_BAZ,
+ message.GetExtension(UNITTEST::repeated_import_enum_extension, 1));
+
+ EXPECT_EQ("324",
+ message.GetExtension(UNITTEST::repeated_string_piece_extension, 1));
+ EXPECT_EQ("325", message.GetExtension(UNITTEST::repeated_cord_extension, 1));
+
+ // -----------------------------------------------------------------
+
+ EXPECT_TRUE(message.HasExtension(UNITTEST::default_int32_extension));
+ EXPECT_TRUE(message.HasExtension(UNITTEST::default_int64_extension));
+ EXPECT_TRUE(message.HasExtension(UNITTEST::default_uint32_extension));
+ EXPECT_TRUE(message.HasExtension(UNITTEST::default_uint64_extension));
+ EXPECT_TRUE(message.HasExtension(UNITTEST::default_sint32_extension));
+ EXPECT_TRUE(message.HasExtension(UNITTEST::default_sint64_extension));
+ EXPECT_TRUE(message.HasExtension(UNITTEST::default_fixed32_extension));
+ EXPECT_TRUE(message.HasExtension(UNITTEST::default_fixed64_extension));
+ EXPECT_TRUE(message.HasExtension(UNITTEST::default_sfixed32_extension));
+ EXPECT_TRUE(message.HasExtension(UNITTEST::default_sfixed64_extension));
+ EXPECT_TRUE(message.HasExtension(UNITTEST::default_float_extension));
+ EXPECT_TRUE(message.HasExtension(UNITTEST::default_double_extension));
+ EXPECT_TRUE(message.HasExtension(UNITTEST::default_bool_extension));
+ EXPECT_TRUE(message.HasExtension(UNITTEST::default_string_extension));
+ EXPECT_TRUE(message.HasExtension(UNITTEST::default_bytes_extension));
+
+ EXPECT_TRUE(message.HasExtension(UNITTEST::default_nested_enum_extension));
+ EXPECT_TRUE(message.HasExtension(UNITTEST::default_foreign_enum_extension));
+ EXPECT_TRUE(message.HasExtension(UNITTEST::default_import_enum_extension));
+
+ EXPECT_TRUE(message.HasExtension(UNITTEST::default_string_piece_extension));
+ EXPECT_TRUE(message.HasExtension(UNITTEST::default_cord_extension));
+
+ EXPECT_EQ(401, message.GetExtension(UNITTEST::default_int32_extension));
+ EXPECT_EQ(402, message.GetExtension(UNITTEST::default_int64_extension));
+ EXPECT_EQ(403, message.GetExtension(UNITTEST::default_uint32_extension));
+ EXPECT_EQ(404, message.GetExtension(UNITTEST::default_uint64_extension));
+ EXPECT_EQ(405, message.GetExtension(UNITTEST::default_sint32_extension));
+ EXPECT_EQ(406, message.GetExtension(UNITTEST::default_sint64_extension));
+ EXPECT_EQ(407, message.GetExtension(UNITTEST::default_fixed32_extension));
+ EXPECT_EQ(408, message.GetExtension(UNITTEST::default_fixed64_extension));
+ EXPECT_EQ(409, message.GetExtension(UNITTEST::default_sfixed32_extension));
+ EXPECT_EQ(410, message.GetExtension(UNITTEST::default_sfixed64_extension));
+ EXPECT_EQ(411, message.GetExtension(UNITTEST::default_float_extension));
+ EXPECT_EQ(412, message.GetExtension(UNITTEST::default_double_extension));
+ EXPECT_FALSE(message.GetExtension(UNITTEST::default_bool_extension));
+ EXPECT_EQ("415", message.GetExtension(UNITTEST::default_string_extension));
+ EXPECT_EQ("416", message.GetExtension(UNITTEST::default_bytes_extension));
+
+ EXPECT_EQ(UNITTEST::TestAllTypes::FOO,
+ message.GetExtension(UNITTEST::default_nested_enum_extension));
+ EXPECT_EQ(UNITTEST::FOREIGN_FOO,
+ message.GetExtension(UNITTEST::default_foreign_enum_extension));
+ EXPECT_EQ(UNITTEST_IMPORT::IMPORT_FOO,
+ message.GetExtension(UNITTEST::default_import_enum_extension));
+
+ EXPECT_EQ("424",
+ message.GetExtension(UNITTEST::default_string_piece_extension));
+ EXPECT_EQ("425", message.GetExtension(UNITTEST::default_cord_extension));
+
+ EXPECT_TRUE(message.HasExtension(UNITTEST::oneof_uint32_extension));
+ EXPECT_TRUE(
+ message.GetExtension(UNITTEST::oneof_nested_message_extension).has_bb());
+ EXPECT_TRUE(message.HasExtension(UNITTEST::oneof_string_extension));
+ EXPECT_TRUE(message.HasExtension(UNITTEST::oneof_bytes_extension));
+
+ EXPECT_EQ(601, message.GetExtension(UNITTEST::oneof_uint32_extension));
+ EXPECT_EQ(
+ 602, message.GetExtension(UNITTEST::oneof_nested_message_extension).bb());
+ EXPECT_EQ("603", message.GetExtension(UNITTEST::oneof_string_extension));
+ EXPECT_EQ("604", message.GetExtension(UNITTEST::oneof_bytes_extension));
+}
+
+// -------------------------------------------------------------------
+
+inline void TestUtil::ExpectExtensionsClear(
+ const UNITTEST::TestAllExtensions& message) {
+ std::string serialized;
+ ASSERT_TRUE(message.SerializeToString(&serialized));
+ EXPECT_EQ("", serialized);
+ EXPECT_EQ(0, message.ByteSizeLong());
+
+ // has_blah() should initially be false for all optional fields.
+ EXPECT_FALSE(message.HasExtension(UNITTEST::optional_int32_extension));
+ EXPECT_FALSE(message.HasExtension(UNITTEST::optional_int64_extension));
+ EXPECT_FALSE(message.HasExtension(UNITTEST::optional_uint32_extension));
+ EXPECT_FALSE(message.HasExtension(UNITTEST::optional_uint64_extension));
+ EXPECT_FALSE(message.HasExtension(UNITTEST::optional_sint32_extension));
+ EXPECT_FALSE(message.HasExtension(UNITTEST::optional_sint64_extension));
+ EXPECT_FALSE(message.HasExtension(UNITTEST::optional_fixed32_extension));
+ EXPECT_FALSE(message.HasExtension(UNITTEST::optional_fixed64_extension));
+ EXPECT_FALSE(message.HasExtension(UNITTEST::optional_sfixed32_extension));
+ EXPECT_FALSE(message.HasExtension(UNITTEST::optional_sfixed64_extension));
+ EXPECT_FALSE(message.HasExtension(UNITTEST::optional_float_extension));
+ EXPECT_FALSE(message.HasExtension(UNITTEST::optional_double_extension));
+ EXPECT_FALSE(message.HasExtension(UNITTEST::optional_bool_extension));
+ EXPECT_FALSE(message.HasExtension(UNITTEST::optional_string_extension));
+ EXPECT_FALSE(message.HasExtension(UNITTEST::optional_bytes_extension));
+
+ EXPECT_FALSE(message.HasExtension(UNITTEST::optionalgroup_extension));
+ EXPECT_FALSE(
+ message.HasExtension(UNITTEST::optional_nested_message_extension));
+ EXPECT_FALSE(
+ message.HasExtension(UNITTEST::optional_foreign_message_extension));
+ EXPECT_FALSE(
+ message.HasExtension(UNITTEST::optional_import_message_extension));
+ EXPECT_FALSE(
+ message.HasExtension(UNITTEST::optional_public_import_message_extension));
+ EXPECT_FALSE(message.HasExtension(UNITTEST::optional_lazy_message_extension));
+
+ EXPECT_FALSE(message.HasExtension(UNITTEST::optional_nested_enum_extension));
+ EXPECT_FALSE(message.HasExtension(UNITTEST::optional_foreign_enum_extension));
+ EXPECT_FALSE(message.HasExtension(UNITTEST::optional_import_enum_extension));
+
+ EXPECT_FALSE(message.HasExtension(UNITTEST::optional_string_piece_extension));
+ EXPECT_FALSE(message.HasExtension(UNITTEST::optional_cord_extension));
+
+ // Optional fields without defaults are set to zero or something like it.
+ EXPECT_EQ(0, message.GetExtension(UNITTEST::optional_int32_extension));
+ EXPECT_EQ(0, message.GetExtension(UNITTEST::optional_int64_extension));
+ EXPECT_EQ(0, message.GetExtension(UNITTEST::optional_uint32_extension));
+ EXPECT_EQ(0, message.GetExtension(UNITTEST::optional_uint64_extension));
+ EXPECT_EQ(0, message.GetExtension(UNITTEST::optional_sint32_extension));
+ EXPECT_EQ(0, message.GetExtension(UNITTEST::optional_sint64_extension));
+ EXPECT_EQ(0, message.GetExtension(UNITTEST::optional_fixed32_extension));
+ EXPECT_EQ(0, message.GetExtension(UNITTEST::optional_fixed64_extension));
+ EXPECT_EQ(0, message.GetExtension(UNITTEST::optional_sfixed32_extension));
+ EXPECT_EQ(0, message.GetExtension(UNITTEST::optional_sfixed64_extension));
+ EXPECT_EQ(0, message.GetExtension(UNITTEST::optional_float_extension));
+ EXPECT_EQ(0, message.GetExtension(UNITTEST::optional_double_extension));
+ EXPECT_FALSE(message.GetExtension(UNITTEST::optional_bool_extension));
+ EXPECT_EQ("", message.GetExtension(UNITTEST::optional_string_extension));
+ EXPECT_EQ("", message.GetExtension(UNITTEST::optional_bytes_extension));
+
+ // Embedded messages should also be clear.
+ EXPECT_FALSE(message.GetExtension(UNITTEST::optionalgroup_extension).has_a());
+ EXPECT_FALSE(message.GetExtension(UNITTEST::optional_nested_message_extension)
+ .has_bb());
+ EXPECT_FALSE(
+ message.GetExtension(UNITTEST::optional_foreign_message_extension)
+ .has_c());
+ EXPECT_FALSE(message.GetExtension(UNITTEST::optional_import_message_extension)
+ .has_d());
+ EXPECT_FALSE(
+ message.GetExtension(UNITTEST::optional_public_import_message_extension)
+ .has_e());
+ EXPECT_FALSE(
+ message.GetExtension(UNITTEST::optional_lazy_message_extension).has_bb());
+
+ EXPECT_EQ(0, message.GetExtension(UNITTEST::optionalgroup_extension).a());
+ EXPECT_EQ(
+ 0,
+ message.GetExtension(UNITTEST::optional_nested_message_extension).bb());
+ EXPECT_EQ(
+ 0,
+ message.GetExtension(UNITTEST::optional_foreign_message_extension).c());
+ EXPECT_EQ(
+ 0, message.GetExtension(UNITTEST::optional_import_message_extension).d());
+ EXPECT_EQ(
+ 0,
+ message.GetExtension(UNITTEST::optional_public_import_message_extension)
+ .e());
+ EXPECT_EQ(
+ 0, message.GetExtension(UNITTEST::optional_lazy_message_extension).bb());
+
+ // Enums without defaults are set to the first value in the enum.
+ EXPECT_EQ(UNITTEST::TestAllTypes::FOO,
+ message.GetExtension(UNITTEST::optional_nested_enum_extension));
+ EXPECT_EQ(UNITTEST::FOREIGN_FOO,
+ message.GetExtension(UNITTEST::optional_foreign_enum_extension));
+ EXPECT_EQ(UNITTEST_IMPORT::IMPORT_FOO,
+ message.GetExtension(UNITTEST::optional_import_enum_extension));
+
+ EXPECT_EQ("",
+ message.GetExtension(UNITTEST::optional_string_piece_extension));
+ EXPECT_EQ("", message.GetExtension(UNITTEST::optional_cord_extension));
+
+ // Repeated fields are empty.
+ EXPECT_EQ(0, message.ExtensionSize(UNITTEST::repeated_int32_extension));
+ EXPECT_EQ(0, message.ExtensionSize(UNITTEST::repeated_int64_extension));
+ EXPECT_EQ(0, message.ExtensionSize(UNITTEST::repeated_uint32_extension));
+ EXPECT_EQ(0, message.ExtensionSize(UNITTEST::repeated_uint64_extension));
+ EXPECT_EQ(0, message.ExtensionSize(UNITTEST::repeated_sint32_extension));
+ EXPECT_EQ(0, message.ExtensionSize(UNITTEST::repeated_sint64_extension));
+ EXPECT_EQ(0, message.ExtensionSize(UNITTEST::repeated_fixed32_extension));
+ EXPECT_EQ(0, message.ExtensionSize(UNITTEST::repeated_fixed64_extension));
+ EXPECT_EQ(0, message.ExtensionSize(UNITTEST::repeated_sfixed32_extension));
+ EXPECT_EQ(0, message.ExtensionSize(UNITTEST::repeated_sfixed64_extension));
+ EXPECT_EQ(0, message.ExtensionSize(UNITTEST::repeated_float_extension));
+ EXPECT_EQ(0, message.ExtensionSize(UNITTEST::repeated_double_extension));
+ EXPECT_EQ(0, message.ExtensionSize(UNITTEST::repeated_bool_extension));
+ EXPECT_EQ(0, message.ExtensionSize(UNITTEST::repeated_string_extension));
+ EXPECT_EQ(0, message.ExtensionSize(UNITTEST::repeated_bytes_extension));
+
+ EXPECT_EQ(0, message.ExtensionSize(UNITTEST::repeatedgroup_extension));
+ EXPECT_EQ(0,
+ message.ExtensionSize(UNITTEST::repeated_nested_message_extension));
+ EXPECT_EQ(
+ 0, message.ExtensionSize(UNITTEST::repeated_foreign_message_extension));
+ EXPECT_EQ(0,
+ message.ExtensionSize(UNITTEST::repeated_import_message_extension));
+ EXPECT_EQ(0,
+ message.ExtensionSize(UNITTEST::repeated_lazy_message_extension));
+ EXPECT_EQ(0, message.ExtensionSize(UNITTEST::repeated_nested_enum_extension));
+ EXPECT_EQ(0,
+ message.ExtensionSize(UNITTEST::repeated_foreign_enum_extension));
+ EXPECT_EQ(0, message.ExtensionSize(UNITTEST::repeated_import_enum_extension));
+
+ EXPECT_EQ(0,
+ message.ExtensionSize(UNITTEST::repeated_string_piece_extension));
+ EXPECT_EQ(0, message.ExtensionSize(UNITTEST::repeated_cord_extension));
+
+ // has_blah() should also be false for all default fields.
+ EXPECT_FALSE(message.HasExtension(UNITTEST::default_int32_extension));
+ EXPECT_FALSE(message.HasExtension(UNITTEST::default_int64_extension));
+ EXPECT_FALSE(message.HasExtension(UNITTEST::default_uint32_extension));
+ EXPECT_FALSE(message.HasExtension(UNITTEST::default_uint64_extension));
+ EXPECT_FALSE(message.HasExtension(UNITTEST::default_sint32_extension));
+ EXPECT_FALSE(message.HasExtension(UNITTEST::default_sint64_extension));
+ EXPECT_FALSE(message.HasExtension(UNITTEST::default_fixed32_extension));
+ EXPECT_FALSE(message.HasExtension(UNITTEST::default_fixed64_extension));
+ EXPECT_FALSE(message.HasExtension(UNITTEST::default_sfixed32_extension));
+ EXPECT_FALSE(message.HasExtension(UNITTEST::default_sfixed64_extension));
+ EXPECT_FALSE(message.HasExtension(UNITTEST::default_float_extension));
+ EXPECT_FALSE(message.HasExtension(UNITTEST::default_double_extension));
+ EXPECT_FALSE(message.HasExtension(UNITTEST::default_bool_extension));
+ EXPECT_FALSE(message.HasExtension(UNITTEST::default_string_extension));
+ EXPECT_FALSE(message.HasExtension(UNITTEST::default_bytes_extension));
+
+ EXPECT_FALSE(message.HasExtension(UNITTEST::default_nested_enum_extension));
+ EXPECT_FALSE(message.HasExtension(UNITTEST::default_foreign_enum_extension));
+ EXPECT_FALSE(message.HasExtension(UNITTEST::default_import_enum_extension));
+
+ EXPECT_FALSE(message.HasExtension(UNITTEST::default_string_piece_extension));
+ EXPECT_FALSE(message.HasExtension(UNITTEST::default_cord_extension));
+
+ // Fields with defaults have their default values (duh).
+ EXPECT_EQ(41, message.GetExtension(UNITTEST::default_int32_extension));
+ EXPECT_EQ(42, message.GetExtension(UNITTEST::default_int64_extension));
+ EXPECT_EQ(43, message.GetExtension(UNITTEST::default_uint32_extension));
+ EXPECT_EQ(44, message.GetExtension(UNITTEST::default_uint64_extension));
+ EXPECT_EQ(-45, message.GetExtension(UNITTEST::default_sint32_extension));
+ EXPECT_EQ(46, message.GetExtension(UNITTEST::default_sint64_extension));
+ EXPECT_EQ(47, message.GetExtension(UNITTEST::default_fixed32_extension));
+ EXPECT_EQ(48, message.GetExtension(UNITTEST::default_fixed64_extension));
+ EXPECT_EQ(49, message.GetExtension(UNITTEST::default_sfixed32_extension));
+ EXPECT_EQ(-50, message.GetExtension(UNITTEST::default_sfixed64_extension));
+ EXPECT_EQ(51.5, message.GetExtension(UNITTEST::default_float_extension));
+ EXPECT_EQ(52e3, message.GetExtension(UNITTEST::default_double_extension));
+ EXPECT_TRUE(message.GetExtension(UNITTEST::default_bool_extension));
+ EXPECT_EQ("hello", message.GetExtension(UNITTEST::default_string_extension));
+ EXPECT_EQ("world", message.GetExtension(UNITTEST::default_bytes_extension));
+
+ EXPECT_EQ(UNITTEST::TestAllTypes::BAR,
+ message.GetExtension(UNITTEST::default_nested_enum_extension));
+ EXPECT_EQ(UNITTEST::FOREIGN_BAR,
+ message.GetExtension(UNITTEST::default_foreign_enum_extension));
+ EXPECT_EQ(UNITTEST_IMPORT::IMPORT_BAR,
+ message.GetExtension(UNITTEST::default_import_enum_extension));
+
+ EXPECT_EQ("abc",
+ message.GetExtension(UNITTEST::default_string_piece_extension));
+ EXPECT_EQ("123", message.GetExtension(UNITTEST::default_cord_extension));
+
+ EXPECT_FALSE(message.HasExtension(UNITTEST::oneof_uint32_extension));
+ EXPECT_FALSE(
+ message.GetExtension(UNITTEST::oneof_nested_message_extension).has_bb());
+ EXPECT_FALSE(message.HasExtension(UNITTEST::oneof_string_extension));
+ EXPECT_FALSE(message.HasExtension(UNITTEST::oneof_bytes_extension));
+}
+
+// -------------------------------------------------------------------
+
+inline void TestUtil::ExpectRepeatedExtensionsModified(
+ const UNITTEST::TestAllExtensions& message) {
+ // ModifyRepeatedFields only sets the second repeated element of each
+ // field. In addition to verifying this, we also verify that the first
+ // element and size were *not* modified.
+ ASSERT_EQ(2, message.ExtensionSize(UNITTEST::repeated_int32_extension));
+ ASSERT_EQ(2, message.ExtensionSize(UNITTEST::repeated_int64_extension));
+ ASSERT_EQ(2, message.ExtensionSize(UNITTEST::repeated_uint32_extension));
+ ASSERT_EQ(2, message.ExtensionSize(UNITTEST::repeated_uint64_extension));
+ ASSERT_EQ(2, message.ExtensionSize(UNITTEST::repeated_sint32_extension));
+ ASSERT_EQ(2, message.ExtensionSize(UNITTEST::repeated_sint64_extension));
+ ASSERT_EQ(2, message.ExtensionSize(UNITTEST::repeated_fixed32_extension));
+ ASSERT_EQ(2, message.ExtensionSize(UNITTEST::repeated_fixed64_extension));
+ ASSERT_EQ(2, message.ExtensionSize(UNITTEST::repeated_sfixed32_extension));
+ ASSERT_EQ(2, message.ExtensionSize(UNITTEST::repeated_sfixed64_extension));
+ ASSERT_EQ(2, message.ExtensionSize(UNITTEST::repeated_float_extension));
+ ASSERT_EQ(2, message.ExtensionSize(UNITTEST::repeated_double_extension));
+ ASSERT_EQ(2, message.ExtensionSize(UNITTEST::repeated_bool_extension));
+ ASSERT_EQ(2, message.ExtensionSize(UNITTEST::repeated_string_extension));
+ ASSERT_EQ(2, message.ExtensionSize(UNITTEST::repeated_bytes_extension));
+
+ ASSERT_EQ(2, message.ExtensionSize(UNITTEST::repeatedgroup_extension));
+ ASSERT_EQ(2,
+ message.ExtensionSize(UNITTEST::repeated_nested_message_extension));
+ ASSERT_EQ(
+ 2, message.ExtensionSize(UNITTEST::repeated_foreign_message_extension));
+ ASSERT_EQ(2,
+ message.ExtensionSize(UNITTEST::repeated_import_message_extension));
+ ASSERT_EQ(2,
+ message.ExtensionSize(UNITTEST::repeated_lazy_message_extension));
+ ASSERT_EQ(2, message.ExtensionSize(UNITTEST::repeated_nested_enum_extension));
+ ASSERT_EQ(2,
+ message.ExtensionSize(UNITTEST::repeated_foreign_enum_extension));
+ ASSERT_EQ(2, message.ExtensionSize(UNITTEST::repeated_import_enum_extension));
+
+ ASSERT_EQ(2,
+ message.ExtensionSize(UNITTEST::repeated_string_piece_extension));
+ ASSERT_EQ(2, message.ExtensionSize(UNITTEST::repeated_cord_extension));
+
+ EXPECT_EQ(201, message.GetExtension(UNITTEST::repeated_int32_extension, 0));
+ EXPECT_EQ(202, message.GetExtension(UNITTEST::repeated_int64_extension, 0));
+ EXPECT_EQ(203, message.GetExtension(UNITTEST::repeated_uint32_extension, 0));
+ EXPECT_EQ(204, message.GetExtension(UNITTEST::repeated_uint64_extension, 0));
+ EXPECT_EQ(205, message.GetExtension(UNITTEST::repeated_sint32_extension, 0));
+ EXPECT_EQ(206, message.GetExtension(UNITTEST::repeated_sint64_extension, 0));
+ EXPECT_EQ(207, message.GetExtension(UNITTEST::repeated_fixed32_extension, 0));
+ EXPECT_EQ(208, message.GetExtension(UNITTEST::repeated_fixed64_extension, 0));
+ EXPECT_EQ(209,
+ message.GetExtension(UNITTEST::repeated_sfixed32_extension, 0));
+ EXPECT_EQ(210,
+ message.GetExtension(UNITTEST::repeated_sfixed64_extension, 0));
+ EXPECT_EQ(211, message.GetExtension(UNITTEST::repeated_float_extension, 0));
+ EXPECT_EQ(212, message.GetExtension(UNITTEST::repeated_double_extension, 0));
+ EXPECT_TRUE(message.GetExtension(UNITTEST::repeated_bool_extension, 0));
+ EXPECT_EQ("215",
+ message.GetExtension(UNITTEST::repeated_string_extension, 0));
+ EXPECT_EQ("216", message.GetExtension(UNITTEST::repeated_bytes_extension, 0));
+
+ EXPECT_EQ(217,
+ message.GetExtension(UNITTEST::repeatedgroup_extension, 0).a());
+ EXPECT_EQ(218,
+ message.GetExtension(UNITTEST::repeated_nested_message_extension, 0)
+ .bb());
+ EXPECT_EQ(
+ 219, message.GetExtension(UNITTEST::repeated_foreign_message_extension, 0)
+ .c());
+ EXPECT_EQ(
+ 220,
+ message.GetExtension(UNITTEST::repeated_import_message_extension, 0).d());
+ EXPECT_EQ(
+ 227,
+ message.GetExtension(UNITTEST::repeated_lazy_message_extension, 0).bb());
+
+ EXPECT_EQ(UNITTEST::TestAllTypes::BAR,
+ message.GetExtension(UNITTEST::repeated_nested_enum_extension, 0));
+ EXPECT_EQ(UNITTEST::FOREIGN_BAR,
+ message.GetExtension(UNITTEST::repeated_foreign_enum_extension, 0));
+ EXPECT_EQ(UNITTEST_IMPORT::IMPORT_BAR,
+ message.GetExtension(UNITTEST::repeated_import_enum_extension, 0));
+
+ EXPECT_EQ("224",
+ message.GetExtension(UNITTEST::repeated_string_piece_extension, 0));
+ EXPECT_EQ("225", message.GetExtension(UNITTEST::repeated_cord_extension, 0));
+
+ // Actually verify the second (modified) elements now.
+ EXPECT_EQ(501, message.GetExtension(UNITTEST::repeated_int32_extension, 1));
+ EXPECT_EQ(502, message.GetExtension(UNITTEST::repeated_int64_extension, 1));
+ EXPECT_EQ(503, message.GetExtension(UNITTEST::repeated_uint32_extension, 1));
+ EXPECT_EQ(504, message.GetExtension(UNITTEST::repeated_uint64_extension, 1));
+ EXPECT_EQ(505, message.GetExtension(UNITTEST::repeated_sint32_extension, 1));
+ EXPECT_EQ(506, message.GetExtension(UNITTEST::repeated_sint64_extension, 1));
+ EXPECT_EQ(507, message.GetExtension(UNITTEST::repeated_fixed32_extension, 1));
+ EXPECT_EQ(508, message.GetExtension(UNITTEST::repeated_fixed64_extension, 1));
+ EXPECT_EQ(509,
+ message.GetExtension(UNITTEST::repeated_sfixed32_extension, 1));
+ EXPECT_EQ(510,
+ message.GetExtension(UNITTEST::repeated_sfixed64_extension, 1));
+ EXPECT_EQ(511, message.GetExtension(UNITTEST::repeated_float_extension, 1));
+ EXPECT_EQ(512, message.GetExtension(UNITTEST::repeated_double_extension, 1));
+ EXPECT_TRUE(message.GetExtension(UNITTEST::repeated_bool_extension, 1));
+ EXPECT_EQ("515",
+ message.GetExtension(UNITTEST::repeated_string_extension, 1));
+ EXPECT_EQ("516", message.GetExtension(UNITTEST::repeated_bytes_extension, 1));
+
+ EXPECT_EQ(517,
+ message.GetExtension(UNITTEST::repeatedgroup_extension, 1).a());
+ EXPECT_EQ(518,
+ message.GetExtension(UNITTEST::repeated_nested_message_extension, 1)
+ .bb());
+ EXPECT_EQ(
+ 519, message.GetExtension(UNITTEST::repeated_foreign_message_extension, 1)
+ .c());
+ EXPECT_EQ(
+ 520,
+ message.GetExtension(UNITTEST::repeated_import_message_extension, 1).d());
+ EXPECT_EQ(
+ 527,
+ message.GetExtension(UNITTEST::repeated_lazy_message_extension, 1).bb());
+
+ EXPECT_EQ(UNITTEST::TestAllTypes::FOO,
+ message.GetExtension(UNITTEST::repeated_nested_enum_extension, 1));
+ EXPECT_EQ(UNITTEST::FOREIGN_FOO,
+ message.GetExtension(UNITTEST::repeated_foreign_enum_extension, 1));
+ EXPECT_EQ(UNITTEST_IMPORT::IMPORT_FOO,
+ message.GetExtension(UNITTEST::repeated_import_enum_extension, 1));
+
+ EXPECT_EQ("524",
+ message.GetExtension(UNITTEST::repeated_string_piece_extension, 1));
+ EXPECT_EQ("525", message.GetExtension(UNITTEST::repeated_cord_extension, 1));
+}
+
+// -------------------------------------------------------------------
+
+inline void TestUtil::SetPackedExtensions(
+ UNITTEST::TestPackedExtensions* message) {
+ message->AddExtension(UNITTEST::packed_int32_extension, 601);
+ message->AddExtension(UNITTEST::packed_int64_extension, 602);
+ message->AddExtension(UNITTEST::packed_uint32_extension, 603);
+ message->AddExtension(UNITTEST::packed_uint64_extension, 604);
+ message->AddExtension(UNITTEST::packed_sint32_extension, 605);
+ message->AddExtension(UNITTEST::packed_sint64_extension, 606);
+ message->AddExtension(UNITTEST::packed_fixed32_extension, 607);
+ message->AddExtension(UNITTEST::packed_fixed64_extension, 608);
+ message->AddExtension(UNITTEST::packed_sfixed32_extension, 609);
+ message->AddExtension(UNITTEST::packed_sfixed64_extension, 610);
+ message->AddExtension(UNITTEST::packed_float_extension, 611);
+ message->AddExtension(UNITTEST::packed_double_extension, 612);
+ message->AddExtension(UNITTEST::packed_bool_extension, true);
+ message->AddExtension(UNITTEST::packed_enum_extension, UNITTEST::FOREIGN_BAR);
+ // add a second one of each field
+ message->AddExtension(UNITTEST::packed_int32_extension, 701);
+ message->AddExtension(UNITTEST::packed_int64_extension, 702);
+ message->AddExtension(UNITTEST::packed_uint32_extension, 703);
+ message->AddExtension(UNITTEST::packed_uint64_extension, 704);
+ message->AddExtension(UNITTEST::packed_sint32_extension, 705);
+ message->AddExtension(UNITTEST::packed_sint64_extension, 706);
+ message->AddExtension(UNITTEST::packed_fixed32_extension, 707);
+ message->AddExtension(UNITTEST::packed_fixed64_extension, 708);
+ message->AddExtension(UNITTEST::packed_sfixed32_extension, 709);
+ message->AddExtension(UNITTEST::packed_sfixed64_extension, 710);
+ message->AddExtension(UNITTEST::packed_float_extension, 711);
+ message->AddExtension(UNITTEST::packed_double_extension, 712);
+ message->AddExtension(UNITTEST::packed_bool_extension, false);
+ message->AddExtension(UNITTEST::packed_enum_extension, UNITTEST::FOREIGN_BAZ);
+}
+
+// -------------------------------------------------------------------
+
+inline void TestUtil::ExpectPackedExtensionsSet(
+ const UNITTEST::TestPackedExtensions& message) {
+ ASSERT_EQ(2, message.ExtensionSize(UNITTEST::packed_int32_extension));
+ ASSERT_EQ(2, message.ExtensionSize(UNITTEST::packed_int64_extension));
+ ASSERT_EQ(2, message.ExtensionSize(UNITTEST::packed_uint32_extension));
+ ASSERT_EQ(2, message.ExtensionSize(UNITTEST::packed_uint64_extension));
+ ASSERT_EQ(2, message.ExtensionSize(UNITTEST::packed_sint32_extension));
+ ASSERT_EQ(2, message.ExtensionSize(UNITTEST::packed_sint64_extension));
+ ASSERT_EQ(2, message.ExtensionSize(UNITTEST::packed_fixed32_extension));
+ ASSERT_EQ(2, message.ExtensionSize(UNITTEST::packed_fixed64_extension));
+ ASSERT_EQ(2, message.ExtensionSize(UNITTEST::packed_sfixed32_extension));
+ ASSERT_EQ(2, message.ExtensionSize(UNITTEST::packed_sfixed64_extension));
+ ASSERT_EQ(2, message.ExtensionSize(UNITTEST::packed_float_extension));
+ ASSERT_EQ(2, message.ExtensionSize(UNITTEST::packed_double_extension));
+ ASSERT_EQ(2, message.ExtensionSize(UNITTEST::packed_bool_extension));
+ ASSERT_EQ(2, message.ExtensionSize(UNITTEST::packed_enum_extension));
+
+ EXPECT_EQ(601, message.GetExtension(UNITTEST::packed_int32_extension, 0));
+ EXPECT_EQ(602, message.GetExtension(UNITTEST::packed_int64_extension, 0));
+ EXPECT_EQ(603, message.GetExtension(UNITTEST::packed_uint32_extension, 0));
+ EXPECT_EQ(604, message.GetExtension(UNITTEST::packed_uint64_extension, 0));
+ EXPECT_EQ(605, message.GetExtension(UNITTEST::packed_sint32_extension, 0));
+ EXPECT_EQ(606, message.GetExtension(UNITTEST::packed_sint64_extension, 0));
+ EXPECT_EQ(607, message.GetExtension(UNITTEST::packed_fixed32_extension, 0));
+ EXPECT_EQ(608, message.GetExtension(UNITTEST::packed_fixed64_extension, 0));
+ EXPECT_EQ(609, message.GetExtension(UNITTEST::packed_sfixed32_extension, 0));
+ EXPECT_EQ(610, message.GetExtension(UNITTEST::packed_sfixed64_extension, 0));
+ EXPECT_EQ(611, message.GetExtension(UNITTEST::packed_float_extension, 0));
+ EXPECT_EQ(612, message.GetExtension(UNITTEST::packed_double_extension, 0));
+ EXPECT_TRUE(message.GetExtension(UNITTEST::packed_bool_extension, 0));
+ EXPECT_EQ(UNITTEST::FOREIGN_BAR,
+ message.GetExtension(UNITTEST::packed_enum_extension, 0));
+ EXPECT_EQ(701, message.GetExtension(UNITTEST::packed_int32_extension, 1));
+ EXPECT_EQ(702, message.GetExtension(UNITTEST::packed_int64_extension, 1));
+ EXPECT_EQ(703, message.GetExtension(UNITTEST::packed_uint32_extension, 1));
+ EXPECT_EQ(704, message.GetExtension(UNITTEST::packed_uint64_extension, 1));
+ EXPECT_EQ(705, message.GetExtension(UNITTEST::packed_sint32_extension, 1));
+ EXPECT_EQ(706, message.GetExtension(UNITTEST::packed_sint64_extension, 1));
+ EXPECT_EQ(707, message.GetExtension(UNITTEST::packed_fixed32_extension, 1));
+ EXPECT_EQ(708, message.GetExtension(UNITTEST::packed_fixed64_extension, 1));
+ EXPECT_EQ(709, message.GetExtension(UNITTEST::packed_sfixed32_extension, 1));
+ EXPECT_EQ(710, message.GetExtension(UNITTEST::packed_sfixed64_extension, 1));
+ EXPECT_EQ(711, message.GetExtension(UNITTEST::packed_float_extension, 1));
+ EXPECT_EQ(712, message.GetExtension(UNITTEST::packed_double_extension, 1));
+ EXPECT_FALSE(message.GetExtension(UNITTEST::packed_bool_extension, 1));
+ EXPECT_EQ(UNITTEST::FOREIGN_BAZ,
+ message.GetExtension(UNITTEST::packed_enum_extension, 1));
+}
+
+// -------------------------------------------------------------------
+
+inline void TestUtil::ExpectUnpackedExtensionsSet(
+ const UNITTEST::TestUnpackedExtensions& message) {
+ ASSERT_EQ(2, message.ExtensionSize(UNITTEST::unpacked_int32_extension));
+ ASSERT_EQ(2, message.ExtensionSize(UNITTEST::unpacked_int64_extension));
+ ASSERT_EQ(2, message.ExtensionSize(UNITTEST::unpacked_uint32_extension));
+ ASSERT_EQ(2, message.ExtensionSize(UNITTEST::unpacked_uint64_extension));
+ ASSERT_EQ(2, message.ExtensionSize(UNITTEST::unpacked_sint32_extension));
+ ASSERT_EQ(2, message.ExtensionSize(UNITTEST::unpacked_sint64_extension));
+ ASSERT_EQ(2, message.ExtensionSize(UNITTEST::unpacked_fixed32_extension));
+ ASSERT_EQ(2, message.ExtensionSize(UNITTEST::unpacked_fixed64_extension));
+ ASSERT_EQ(2, message.ExtensionSize(UNITTEST::unpacked_sfixed32_extension));
+ ASSERT_EQ(2, message.ExtensionSize(UNITTEST::unpacked_sfixed64_extension));
+ ASSERT_EQ(2, message.ExtensionSize(UNITTEST::unpacked_float_extension));
+ ASSERT_EQ(2, message.ExtensionSize(UNITTEST::unpacked_double_extension));
+ ASSERT_EQ(2, message.ExtensionSize(UNITTEST::unpacked_bool_extension));
+ ASSERT_EQ(2, message.ExtensionSize(UNITTEST::unpacked_enum_extension));
+
+ EXPECT_EQ(601, message.GetExtension(UNITTEST::unpacked_int32_extension, 0));
+ EXPECT_EQ(602, message.GetExtension(UNITTEST::unpacked_int64_extension, 0));
+ EXPECT_EQ(603, message.GetExtension(UNITTEST::unpacked_uint32_extension, 0));
+ EXPECT_EQ(604, message.GetExtension(UNITTEST::unpacked_uint64_extension, 0));
+ EXPECT_EQ(605, message.GetExtension(UNITTEST::unpacked_sint32_extension, 0));
+ EXPECT_EQ(606, message.GetExtension(UNITTEST::unpacked_sint64_extension, 0));
+ EXPECT_EQ(607, message.GetExtension(UNITTEST::unpacked_fixed32_extension, 0));
+ EXPECT_EQ(608, message.GetExtension(UNITTEST::unpacked_fixed64_extension, 0));
+ EXPECT_EQ(609,
+ message.GetExtension(UNITTEST::unpacked_sfixed32_extension, 0));
+ EXPECT_EQ(610,
+ message.GetExtension(UNITTEST::unpacked_sfixed64_extension, 0));
+ EXPECT_EQ(611, message.GetExtension(UNITTEST::unpacked_float_extension, 0));
+ EXPECT_EQ(612, message.GetExtension(UNITTEST::unpacked_double_extension, 0));
+ EXPECT_EQ(true, message.GetExtension(UNITTEST::unpacked_bool_extension, 0));
+ EXPECT_EQ(UNITTEST::FOREIGN_BAR,
+ message.GetExtension(UNITTEST::unpacked_enum_extension, 0));
+ EXPECT_EQ(701, message.GetExtension(UNITTEST::unpacked_int32_extension, 1));
+ EXPECT_EQ(702, message.GetExtension(UNITTEST::unpacked_int64_extension, 1));
+ EXPECT_EQ(703, message.GetExtension(UNITTEST::unpacked_uint32_extension, 1));
+ EXPECT_EQ(704, message.GetExtension(UNITTEST::unpacked_uint64_extension, 1));
+ EXPECT_EQ(705, message.GetExtension(UNITTEST::unpacked_sint32_extension, 1));
+ EXPECT_EQ(706, message.GetExtension(UNITTEST::unpacked_sint64_extension, 1));
+ EXPECT_EQ(707, message.GetExtension(UNITTEST::unpacked_fixed32_extension, 1));
+ EXPECT_EQ(708, message.GetExtension(UNITTEST::unpacked_fixed64_extension, 1));
+ EXPECT_EQ(709,
+ message.GetExtension(UNITTEST::unpacked_sfixed32_extension, 1));
+ EXPECT_EQ(710,
+ message.GetExtension(UNITTEST::unpacked_sfixed64_extension, 1));
+ EXPECT_EQ(711, message.GetExtension(UNITTEST::unpacked_float_extension, 1));
+ EXPECT_EQ(712, message.GetExtension(UNITTEST::unpacked_double_extension, 1));
+ EXPECT_EQ(false, message.GetExtension(UNITTEST::unpacked_bool_extension, 1));
+ EXPECT_EQ(UNITTEST::FOREIGN_BAZ,
+ message.GetExtension(UNITTEST::unpacked_enum_extension, 1));
+}
+
+// -------------------------------------------------------------------
+
+inline void TestUtil::ExpectLastRepeatedsRemoved(
+ const UNITTEST::TestAllTypes& message) {
+ ASSERT_EQ(1, message.repeated_int32_size());
+ ASSERT_EQ(1, message.repeated_int64_size());
+ ASSERT_EQ(1, message.repeated_uint32_size());
+ ASSERT_EQ(1, message.repeated_uint64_size());
+ ASSERT_EQ(1, message.repeated_sint32_size());
+ ASSERT_EQ(1, message.repeated_sint64_size());
+ ASSERT_EQ(1, message.repeated_fixed32_size());
+ ASSERT_EQ(1, message.repeated_fixed64_size());
+ ASSERT_EQ(1, message.repeated_sfixed32_size());
+ ASSERT_EQ(1, message.repeated_sfixed64_size());
+ ASSERT_EQ(1, message.repeated_float_size());
+ ASSERT_EQ(1, message.repeated_double_size());
+ ASSERT_EQ(1, message.repeated_bool_size());
+ ASSERT_EQ(1, message.repeated_string_size());
+ ASSERT_EQ(1, message.repeated_bytes_size());
+
+ ASSERT_EQ(1, message.repeatedgroup_size());
+ ASSERT_EQ(1, message.repeated_nested_message_size());
+ ASSERT_EQ(1, message.repeated_foreign_message_size());
+ ASSERT_EQ(1, message.repeated_import_message_size());
+ ASSERT_EQ(1, message.repeated_import_message_size());
+ ASSERT_EQ(1, message.repeated_nested_enum_size());
+ ASSERT_EQ(1, message.repeated_foreign_enum_size());
+ ASSERT_EQ(1, message.repeated_import_enum_size());
+
+#ifndef PROTOBUF_TEST_NO_DESCRIPTORS
+ ASSERT_EQ(1, message.repeated_string_piece_size());
+ ASSERT_EQ(1, message.repeated_cord_size());
+#endif
+
+ // Test that the remaining element is the correct one.
+ EXPECT_EQ(201, message.repeated_int32(0));
+ EXPECT_EQ(202, message.repeated_int64(0));
+ EXPECT_EQ(203, message.repeated_uint32(0));
+ EXPECT_EQ(204, message.repeated_uint64(0));
+ EXPECT_EQ(205, message.repeated_sint32(0));
+ EXPECT_EQ(206, message.repeated_sint64(0));
+ EXPECT_EQ(207, message.repeated_fixed32(0));
+ EXPECT_EQ(208, message.repeated_fixed64(0));
+ EXPECT_EQ(209, message.repeated_sfixed32(0));
+ EXPECT_EQ(210, message.repeated_sfixed64(0));
+ EXPECT_EQ(211, message.repeated_float(0));
+ EXPECT_EQ(212, message.repeated_double(0));
+ EXPECT_TRUE(message.repeated_bool(0));
+ EXPECT_EQ("215", message.repeated_string(0));
+ EXPECT_EQ("216", message.repeated_bytes(0));
+
+ EXPECT_EQ(217, message.repeatedgroup(0).a());
+ EXPECT_EQ(218, message.repeated_nested_message(0).bb());
+ EXPECT_EQ(219, message.repeated_foreign_message(0).c());
+ EXPECT_EQ(220, message.repeated_import_message(0).d());
+ EXPECT_EQ(220, message.repeated_import_message(0).d());
+
+ EXPECT_EQ(UNITTEST::TestAllTypes::BAR, message.repeated_nested_enum(0));
+ EXPECT_EQ(UNITTEST::FOREIGN_BAR, message.repeated_foreign_enum(0));
+ EXPECT_EQ(UNITTEST_IMPORT::IMPORT_BAR, message.repeated_import_enum(0));
+}
+
+inline void TestUtil::ExpectLastRepeatedExtensionsRemoved(
+ const UNITTEST::TestAllExtensions& message) {
+ // Test that one element was removed.
+ ASSERT_EQ(1, message.ExtensionSize(UNITTEST::repeated_int32_extension));
+ ASSERT_EQ(1, message.ExtensionSize(UNITTEST::repeated_int64_extension));
+ ASSERT_EQ(1, message.ExtensionSize(UNITTEST::repeated_uint32_extension));
+ ASSERT_EQ(1, message.ExtensionSize(UNITTEST::repeated_uint64_extension));
+ ASSERT_EQ(1, message.ExtensionSize(UNITTEST::repeated_sint32_extension));
+ ASSERT_EQ(1, message.ExtensionSize(UNITTEST::repeated_sint64_extension));
+ ASSERT_EQ(1, message.ExtensionSize(UNITTEST::repeated_fixed32_extension));
+ ASSERT_EQ(1, message.ExtensionSize(UNITTEST::repeated_fixed64_extension));
+ ASSERT_EQ(1, message.ExtensionSize(UNITTEST::repeated_sfixed32_extension));
+ ASSERT_EQ(1, message.ExtensionSize(UNITTEST::repeated_sfixed64_extension));
+ ASSERT_EQ(1, message.ExtensionSize(UNITTEST::repeated_float_extension));
+ ASSERT_EQ(1, message.ExtensionSize(UNITTEST::repeated_double_extension));
+ ASSERT_EQ(1, message.ExtensionSize(UNITTEST::repeated_bool_extension));
+ ASSERT_EQ(1, message.ExtensionSize(UNITTEST::repeated_string_extension));
+ ASSERT_EQ(1, message.ExtensionSize(UNITTEST::repeated_bytes_extension));
+
+ ASSERT_EQ(1, message.ExtensionSize(UNITTEST::repeatedgroup_extension));
+ ASSERT_EQ(1,
+ message.ExtensionSize(UNITTEST::repeated_nested_message_extension));
+ ASSERT_EQ(
+ 1, message.ExtensionSize(UNITTEST::repeated_foreign_message_extension));
+ ASSERT_EQ(1,
+ message.ExtensionSize(UNITTEST::repeated_import_message_extension));
+ ASSERT_EQ(1,
+ message.ExtensionSize(UNITTEST::repeated_lazy_message_extension));
+ ASSERT_EQ(1, message.ExtensionSize(UNITTEST::repeated_nested_enum_extension));
+ ASSERT_EQ(1,
+ message.ExtensionSize(UNITTEST::repeated_foreign_enum_extension));
+ ASSERT_EQ(1, message.ExtensionSize(UNITTEST::repeated_import_enum_extension));
+
+ ASSERT_EQ(1,
+ message.ExtensionSize(UNITTEST::repeated_string_piece_extension));
+ ASSERT_EQ(1, message.ExtensionSize(UNITTEST::repeated_cord_extension));
+
+ // Test that the remaining element is the correct one.
+ EXPECT_EQ(201, message.GetExtension(UNITTEST::repeated_int32_extension, 0));
+ EXPECT_EQ(202, message.GetExtension(UNITTEST::repeated_int64_extension, 0));
+ EXPECT_EQ(203, message.GetExtension(UNITTEST::repeated_uint32_extension, 0));
+ EXPECT_EQ(204, message.GetExtension(UNITTEST::repeated_uint64_extension, 0));
+ EXPECT_EQ(205, message.GetExtension(UNITTEST::repeated_sint32_extension, 0));
+ EXPECT_EQ(206, message.GetExtension(UNITTEST::repeated_sint64_extension, 0));
+ EXPECT_EQ(207, message.GetExtension(UNITTEST::repeated_fixed32_extension, 0));
+ EXPECT_EQ(208, message.GetExtension(UNITTEST::repeated_fixed64_extension, 0));
+ EXPECT_EQ(209,
+ message.GetExtension(UNITTEST::repeated_sfixed32_extension, 0));
+ EXPECT_EQ(210,
+ message.GetExtension(UNITTEST::repeated_sfixed64_extension, 0));
+ EXPECT_EQ(211, message.GetExtension(UNITTEST::repeated_float_extension, 0));
+ EXPECT_EQ(212, message.GetExtension(UNITTEST::repeated_double_extension, 0));
+ EXPECT_TRUE(message.GetExtension(UNITTEST::repeated_bool_extension, 0));
+ EXPECT_EQ("215",
+ message.GetExtension(UNITTEST::repeated_string_extension, 0));
+ EXPECT_EQ("216", message.GetExtension(UNITTEST::repeated_bytes_extension, 0));
+
+ EXPECT_EQ(217,
+ message.GetExtension(UNITTEST::repeatedgroup_extension, 0).a());
+ EXPECT_EQ(218,
+ message.GetExtension(UNITTEST::repeated_nested_message_extension, 0)
+ .bb());
+ EXPECT_EQ(
+ 219, message.GetExtension(UNITTEST::repeated_foreign_message_extension, 0)
+ .c());
+ EXPECT_EQ(
+ 220,
+ message.GetExtension(UNITTEST::repeated_import_message_extension, 0).d());
+ EXPECT_EQ(
+ 227,
+ message.GetExtension(UNITTEST::repeated_lazy_message_extension, 0).bb());
+
+ EXPECT_EQ(UNITTEST::TestAllTypes::BAR,
+ message.GetExtension(UNITTEST::repeated_nested_enum_extension, 0));
+ EXPECT_EQ(UNITTEST::FOREIGN_BAR,
+ message.GetExtension(UNITTEST::repeated_foreign_enum_extension, 0));
+ EXPECT_EQ(UNITTEST_IMPORT::IMPORT_BAR,
+ message.GetExtension(UNITTEST::repeated_import_enum_extension, 0));
+
+ EXPECT_EQ("224",
+ message.GetExtension(UNITTEST::repeated_string_piece_extension, 0));
+ EXPECT_EQ("225", message.GetExtension(UNITTEST::repeated_cord_extension, 0));
+}
+
+inline void TestUtil::ExpectLastRepeatedsReleased(
+ const UNITTEST::TestAllTypes& message) {
+ ASSERT_EQ(1, message.repeatedgroup_size());
+ ASSERT_EQ(1, message.repeated_nested_message_size());
+ ASSERT_EQ(1, message.repeated_foreign_message_size());
+ ASSERT_EQ(1, message.repeated_import_message_size());
+ ASSERT_EQ(1, message.repeated_import_message_size());
+
+ EXPECT_EQ(217, message.repeatedgroup(0).a());
+ EXPECT_EQ(218, message.repeated_nested_message(0).bb());
+ EXPECT_EQ(219, message.repeated_foreign_message(0).c());
+ EXPECT_EQ(220, message.repeated_import_message(0).d());
+ EXPECT_EQ(220, message.repeated_import_message(0).d());
+}
+
+inline void TestUtil::ExpectLastRepeatedExtensionsReleased(
+ const UNITTEST::TestAllExtensions& message) {
+ ASSERT_EQ(1, message.ExtensionSize(UNITTEST::repeatedgroup_extension));
+ ASSERT_EQ(1,
+ message.ExtensionSize(UNITTEST::repeated_nested_message_extension));
+ ASSERT_EQ(
+ 1, message.ExtensionSize(UNITTEST::repeated_foreign_message_extension));
+ ASSERT_EQ(1,
+ message.ExtensionSize(UNITTEST::repeated_import_message_extension));
+ ASSERT_EQ(1,
+ message.ExtensionSize(UNITTEST::repeated_lazy_message_extension));
+
+ EXPECT_EQ(217,
+ message.GetExtension(UNITTEST::repeatedgroup_extension, 0).a());
+ EXPECT_EQ(218,
+ message.GetExtension(UNITTEST::repeated_nested_message_extension, 0)
+ .bb());
+ EXPECT_EQ(
+ 219, message.GetExtension(UNITTEST::repeated_foreign_message_extension, 0)
+ .c());
+ EXPECT_EQ(
+ 220,
+ message.GetExtension(UNITTEST::repeated_import_message_extension, 0).d());
+ EXPECT_EQ(
+ 227,
+ message.GetExtension(UNITTEST::repeated_lazy_message_extension, 0).bb());
+}
+
+inline void TestUtil::ExpectRepeatedsSwapped(
+ const UNITTEST::TestAllTypes& message) {
+ ASSERT_EQ(2, message.repeated_int32_size());
+ ASSERT_EQ(2, message.repeated_int64_size());
+ ASSERT_EQ(2, message.repeated_uint32_size());
+ ASSERT_EQ(2, message.repeated_uint64_size());
+ ASSERT_EQ(2, message.repeated_sint32_size());
+ ASSERT_EQ(2, message.repeated_sint64_size());
+ ASSERT_EQ(2, message.repeated_fixed32_size());
+ ASSERT_EQ(2, message.repeated_fixed64_size());
+ ASSERT_EQ(2, message.repeated_sfixed32_size());
+ ASSERT_EQ(2, message.repeated_sfixed64_size());
+ ASSERT_EQ(2, message.repeated_float_size());
+ ASSERT_EQ(2, message.repeated_double_size());
+ ASSERT_EQ(2, message.repeated_bool_size());
+ ASSERT_EQ(2, message.repeated_string_size());
+ ASSERT_EQ(2, message.repeated_bytes_size());
+
+ ASSERT_EQ(2, message.repeatedgroup_size());
+ ASSERT_EQ(2, message.repeated_nested_message_size());
+ ASSERT_EQ(2, message.repeated_foreign_message_size());
+ ASSERT_EQ(2, message.repeated_import_message_size());
+ ASSERT_EQ(2, message.repeated_import_message_size());
+ ASSERT_EQ(2, message.repeated_nested_enum_size());
+ ASSERT_EQ(2, message.repeated_foreign_enum_size());
+ ASSERT_EQ(2, message.repeated_import_enum_size());
+
+#ifndef PROTOBUF_TEST_NO_DESCRIPTORS
+ ASSERT_EQ(2, message.repeated_string_piece_size());
+ ASSERT_EQ(2, message.repeated_cord_size());
+#endif
+
+ // Test that the first element and second element are flipped.
+ EXPECT_EQ(201, message.repeated_int32(1));
+ EXPECT_EQ(202, message.repeated_int64(1));
+ EXPECT_EQ(203, message.repeated_uint32(1));
+ EXPECT_EQ(204, message.repeated_uint64(1));
+ EXPECT_EQ(205, message.repeated_sint32(1));
+ EXPECT_EQ(206, message.repeated_sint64(1));
+ EXPECT_EQ(207, message.repeated_fixed32(1));
+ EXPECT_EQ(208, message.repeated_fixed64(1));
+ EXPECT_EQ(209, message.repeated_sfixed32(1));
+ EXPECT_EQ(210, message.repeated_sfixed64(1));
+ EXPECT_EQ(211, message.repeated_float(1));
+ EXPECT_EQ(212, message.repeated_double(1));
+ EXPECT_TRUE(message.repeated_bool(1));
+ EXPECT_EQ("215", message.repeated_string(1));
+ EXPECT_EQ("216", message.repeated_bytes(1));
+
+ EXPECT_EQ(217, message.repeatedgroup(1).a());
+ EXPECT_EQ(218, message.repeated_nested_message(1).bb());
+ EXPECT_EQ(219, message.repeated_foreign_message(1).c());
+ EXPECT_EQ(220, message.repeated_import_message(1).d());
+ EXPECT_EQ(220, message.repeated_import_message(1).d());
+
+ EXPECT_EQ(UNITTEST::TestAllTypes::BAR, message.repeated_nested_enum(1));
+ EXPECT_EQ(UNITTEST::FOREIGN_BAR, message.repeated_foreign_enum(1));
+ EXPECT_EQ(UNITTEST_IMPORT::IMPORT_BAR, message.repeated_import_enum(1));
+
+ EXPECT_EQ(301, message.repeated_int32(0));
+ EXPECT_EQ(302, message.repeated_int64(0));
+ EXPECT_EQ(303, message.repeated_uint32(0));
+ EXPECT_EQ(304, message.repeated_uint64(0));
+ EXPECT_EQ(305, message.repeated_sint32(0));
+ EXPECT_EQ(306, message.repeated_sint64(0));
+ EXPECT_EQ(307, message.repeated_fixed32(0));
+ EXPECT_EQ(308, message.repeated_fixed64(0));
+ EXPECT_EQ(309, message.repeated_sfixed32(0));
+ EXPECT_EQ(310, message.repeated_sfixed64(0));
+ EXPECT_EQ(311, message.repeated_float(0));
+ EXPECT_EQ(312, message.repeated_double(0));
+ EXPECT_FALSE(message.repeated_bool(0));
+ EXPECT_EQ("315", message.repeated_string(0));
+ EXPECT_EQ("316", message.repeated_bytes(0));
+
+ EXPECT_EQ(317, message.repeatedgroup(0).a());
+ EXPECT_EQ(318, message.repeated_nested_message(0).bb());
+ EXPECT_EQ(319, message.repeated_foreign_message(0).c());
+ EXPECT_EQ(320, message.repeated_import_message(0).d());
+ EXPECT_EQ(320, message.repeated_import_message(0).d());
+
+ EXPECT_EQ(UNITTEST::TestAllTypes::BAZ, message.repeated_nested_enum(0));
+ EXPECT_EQ(UNITTEST::FOREIGN_BAZ, message.repeated_foreign_enum(0));
+ EXPECT_EQ(UNITTEST_IMPORT::IMPORT_BAZ, message.repeated_import_enum(0));
+}
+
+inline void TestUtil::ExpectRepeatedExtensionsSwapped(
+ const UNITTEST::TestAllExtensions& message) {
+ ASSERT_EQ(2, message.ExtensionSize(UNITTEST::repeated_int32_extension));
+ ASSERT_EQ(2, message.ExtensionSize(UNITTEST::repeated_int64_extension));
+ ASSERT_EQ(2, message.ExtensionSize(UNITTEST::repeated_uint32_extension));
+ ASSERT_EQ(2, message.ExtensionSize(UNITTEST::repeated_uint64_extension));
+ ASSERT_EQ(2, message.ExtensionSize(UNITTEST::repeated_sint32_extension));
+ ASSERT_EQ(2, message.ExtensionSize(UNITTEST::repeated_sint64_extension));
+ ASSERT_EQ(2, message.ExtensionSize(UNITTEST::repeated_fixed32_extension));
+ ASSERT_EQ(2, message.ExtensionSize(UNITTEST::repeated_fixed64_extension));
+ ASSERT_EQ(2, message.ExtensionSize(UNITTEST::repeated_sfixed32_extension));
+ ASSERT_EQ(2, message.ExtensionSize(UNITTEST::repeated_sfixed64_extension));
+ ASSERT_EQ(2, message.ExtensionSize(UNITTEST::repeated_float_extension));
+ ASSERT_EQ(2, message.ExtensionSize(UNITTEST::repeated_double_extension));
+ ASSERT_EQ(2, message.ExtensionSize(UNITTEST::repeated_bool_extension));
+ ASSERT_EQ(2, message.ExtensionSize(UNITTEST::repeated_string_extension));
+ ASSERT_EQ(2, message.ExtensionSize(UNITTEST::repeated_bytes_extension));
+
+ ASSERT_EQ(2, message.ExtensionSize(UNITTEST::repeatedgroup_extension));
+ ASSERT_EQ(2,
+ message.ExtensionSize(UNITTEST::repeated_nested_message_extension));
+ ASSERT_EQ(
+ 2, message.ExtensionSize(UNITTEST::repeated_foreign_message_extension));
+ ASSERT_EQ(2,
+ message.ExtensionSize(UNITTEST::repeated_import_message_extension));
+ ASSERT_EQ(2,
+ message.ExtensionSize(UNITTEST::repeated_lazy_message_extension));
+ ASSERT_EQ(2, message.ExtensionSize(UNITTEST::repeated_nested_enum_extension));
+ ASSERT_EQ(2,
+ message.ExtensionSize(UNITTEST::repeated_foreign_enum_extension));
+ ASSERT_EQ(2, message.ExtensionSize(UNITTEST::repeated_import_enum_extension));
+
+ ASSERT_EQ(2,
+ message.ExtensionSize(UNITTEST::repeated_string_piece_extension));
+ ASSERT_EQ(2, message.ExtensionSize(UNITTEST::repeated_cord_extension));
+
+ EXPECT_EQ(201, message.GetExtension(UNITTEST::repeated_int32_extension, 1));
+ EXPECT_EQ(202, message.GetExtension(UNITTEST::repeated_int64_extension, 1));
+ EXPECT_EQ(203, message.GetExtension(UNITTEST::repeated_uint32_extension, 1));
+ EXPECT_EQ(204, message.GetExtension(UNITTEST::repeated_uint64_extension, 1));
+ EXPECT_EQ(205, message.GetExtension(UNITTEST::repeated_sint32_extension, 1));
+ EXPECT_EQ(206, message.GetExtension(UNITTEST::repeated_sint64_extension, 1));
+ EXPECT_EQ(207, message.GetExtension(UNITTEST::repeated_fixed32_extension, 1));
+ EXPECT_EQ(208, message.GetExtension(UNITTEST::repeated_fixed64_extension, 1));
+ EXPECT_EQ(209,
+ message.GetExtension(UNITTEST::repeated_sfixed32_extension, 1));
+ EXPECT_EQ(210,
+ message.GetExtension(UNITTEST::repeated_sfixed64_extension, 1));
+ EXPECT_EQ(211, message.GetExtension(UNITTEST::repeated_float_extension, 1));
+ EXPECT_EQ(212, message.GetExtension(UNITTEST::repeated_double_extension, 1));
+ EXPECT_TRUE(message.GetExtension(UNITTEST::repeated_bool_extension, 1));
+ EXPECT_EQ("215",
+ message.GetExtension(UNITTEST::repeated_string_extension, 1));
+ EXPECT_EQ("216", message.GetExtension(UNITTEST::repeated_bytes_extension, 1));
+
+ EXPECT_EQ(217,
+ message.GetExtension(UNITTEST::repeatedgroup_extension, 1).a());
+ EXPECT_EQ(218,
+ message.GetExtension(UNITTEST::repeated_nested_message_extension, 1)
+ .bb());
+ EXPECT_EQ(
+ 219, message.GetExtension(UNITTEST::repeated_foreign_message_extension, 1)
+ .c());
+ EXPECT_EQ(
+ 220,
+ message.GetExtension(UNITTEST::repeated_import_message_extension, 1).d());
+ EXPECT_EQ(
+ 227,
+ message.GetExtension(UNITTEST::repeated_lazy_message_extension, 1).bb());
+
+ EXPECT_EQ(UNITTEST::TestAllTypes::BAR,
+ message.GetExtension(UNITTEST::repeated_nested_enum_extension, 1));
+ EXPECT_EQ(UNITTEST::FOREIGN_BAR,
+ message.GetExtension(UNITTEST::repeated_foreign_enum_extension, 1));
+ EXPECT_EQ(UNITTEST_IMPORT::IMPORT_BAR,
+ message.GetExtension(UNITTEST::repeated_import_enum_extension, 1));
+
+ EXPECT_EQ("224",
+ message.GetExtension(UNITTEST::repeated_string_piece_extension, 1));
+ EXPECT_EQ("225", message.GetExtension(UNITTEST::repeated_cord_extension, 1));
+
+ EXPECT_EQ(301, message.GetExtension(UNITTEST::repeated_int32_extension, 0));
+ EXPECT_EQ(302, message.GetExtension(UNITTEST::repeated_int64_extension, 0));
+ EXPECT_EQ(303, message.GetExtension(UNITTEST::repeated_uint32_extension, 0));
+ EXPECT_EQ(304, message.GetExtension(UNITTEST::repeated_uint64_extension, 0));
+ EXPECT_EQ(305, message.GetExtension(UNITTEST::repeated_sint32_extension, 0));
+ EXPECT_EQ(306, message.GetExtension(UNITTEST::repeated_sint64_extension, 0));
+ EXPECT_EQ(307, message.GetExtension(UNITTEST::repeated_fixed32_extension, 0));
+ EXPECT_EQ(308, message.GetExtension(UNITTEST::repeated_fixed64_extension, 0));
+ EXPECT_EQ(309,
+ message.GetExtension(UNITTEST::repeated_sfixed32_extension, 0));
+ EXPECT_EQ(310,
+ message.GetExtension(UNITTEST::repeated_sfixed64_extension, 0));
+ EXPECT_EQ(311, message.GetExtension(UNITTEST::repeated_float_extension, 0));
+ EXPECT_EQ(312, message.GetExtension(UNITTEST::repeated_double_extension, 0));
+ EXPECT_FALSE(message.GetExtension(UNITTEST::repeated_bool_extension, 0));
+ EXPECT_EQ("315",
+ message.GetExtension(UNITTEST::repeated_string_extension, 0));
+ EXPECT_EQ("316", message.GetExtension(UNITTEST::repeated_bytes_extension, 0));
+
+ EXPECT_EQ(317,
+ message.GetExtension(UNITTEST::repeatedgroup_extension, 0).a());
+ EXPECT_EQ(318,
+ message.GetExtension(UNITTEST::repeated_nested_message_extension, 0)
+ .bb());
+ EXPECT_EQ(
+ 319, message.GetExtension(UNITTEST::repeated_foreign_message_extension, 0)
+ .c());
+ EXPECT_EQ(
+ 320,
+ message.GetExtension(UNITTEST::repeated_import_message_extension, 0).d());
+ EXPECT_EQ(
+ 327,
+ message.GetExtension(UNITTEST::repeated_lazy_message_extension, 0).bb());
+
+ EXPECT_EQ(UNITTEST::TestAllTypes::BAZ,
+ message.GetExtension(UNITTEST::repeated_nested_enum_extension, 0));
+ EXPECT_EQ(UNITTEST::FOREIGN_BAZ,
+ message.GetExtension(UNITTEST::repeated_foreign_enum_extension, 0));
+ EXPECT_EQ(UNITTEST_IMPORT::IMPORT_BAZ,
+ message.GetExtension(UNITTEST::repeated_import_enum_extension, 0));
+
+ EXPECT_EQ("324",
+ message.GetExtension(UNITTEST::repeated_string_piece_extension, 0));
+ EXPECT_EQ("325", message.GetExtension(UNITTEST::repeated_cord_extension, 0));
+}
+
+inline void TestUtil::SetOneof1(UNITTEST::TestOneof2* message) {
+ message->mutable_foo_lazy_message()->set_qux_int(100);
+ message->set_bar_string("101");
+ message->set_baz_int(102);
+ message->set_baz_string("103");
+}
+
+inline void TestUtil::SetOneof2(UNITTEST::TestOneof2* message) {
+ message->set_foo_int(200);
+ message->set_bar_enum(UNITTEST::TestOneof2::BAZ);
+ message->set_baz_int(202);
+ message->set_baz_string("203");
+}
+
+inline void TestUtil::ExpectOneofSet1(const UNITTEST::TestOneof2& message) {
+ ExpectAtMostOneFieldSetInOneof(message);
+
+ EXPECT_TRUE(message.has_foo_lazy_message());
+ EXPECT_TRUE(message.foo_lazy_message().has_qux_int());
+
+ EXPECT_TRUE(message.has_bar_string());
+ EXPECT_TRUE(message.has_baz_int());
+ EXPECT_TRUE(message.has_baz_string());
+
+ ASSERT_EQ(0, message.foo_lazy_message().corge_int_size());
+
+ EXPECT_EQ(100, message.foo_lazy_message().qux_int());
+ EXPECT_EQ("101", message.bar_string());
+ EXPECT_EQ(102, message.baz_int());
+ EXPECT_EQ("103", message.baz_string());
+}
+
+inline void TestUtil::ExpectOneofSet2(const UNITTEST::TestOneof2& message) {
+ ExpectAtMostOneFieldSetInOneof(message);
+
+ EXPECT_TRUE(message.has_foo_int());
+ EXPECT_TRUE(message.has_bar_enum());
+ EXPECT_TRUE(message.has_baz_int());
+ EXPECT_TRUE(message.has_baz_string());
+
+ EXPECT_EQ(200, message.foo_int());
+ EXPECT_EQ(UNITTEST::TestOneof2::BAZ, message.bar_enum());
+ EXPECT_EQ(202, message.baz_int());
+ EXPECT_EQ("203", message.baz_string());
+}
+
+inline void TestUtil::ExpectOneofClear(const UNITTEST::TestOneof2& message) {
+ EXPECT_FALSE(message.has_foo_int());
+ EXPECT_FALSE(message.has_foo_string());
+ EXPECT_FALSE(message.has_foo_bytes());
+ EXPECT_FALSE(message.has_foo_enum());
+ EXPECT_FALSE(message.has_foo_message());
+ EXPECT_FALSE(message.has_foogroup());
+ EXPECT_FALSE(message.has_foo_lazy_message());
+
+ EXPECT_FALSE(message.has_bar_int());
+ EXPECT_FALSE(message.has_bar_string());
+ EXPECT_FALSE(message.has_bar_bytes());
+ EXPECT_FALSE(message.has_bar_enum());
+
+ EXPECT_FALSE(message.has_baz_int());
+ EXPECT_FALSE(message.has_baz_string());
+
+ EXPECT_EQ(UNITTEST::TestOneof2::FOO_NOT_SET, message.foo_case());
+ EXPECT_EQ(UNITTEST::TestOneof2::BAR_NOT_SET, message.bar_case());
+}
+
+inline void TestUtil::ExpectAtMostOneFieldSetInOneof(
+ const UNITTEST::TestOneof2& message) {
+ int count = 0;
+ if (message.has_foo_int()) count++;
+ if (message.has_foo_string()) count++;
+ if (message.has_foo_bytes()) count++;
+ if (message.has_foo_enum()) count++;
+ if (message.has_foo_message()) count++;
+ if (message.has_foogroup()) count++;
+ if (message.has_foo_lazy_message()) count++;
+ EXPECT_LE(count, 1);
+ count = 0;
+ if (message.has_bar_int()) count++;
+ if (message.has_bar_string()) count++;
+ if (message.has_bar_bytes()) count++;
+ if (message.has_bar_enum()) count++;
+ EXPECT_TRUE(count == 0 || count == 1);
+}
+
+// ===================================================================
+
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/test_util2.h b/NorthstarDedicatedTest/include/protobuf/test_util2.h
new file mode 100644
index 00000000..642a79a8
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/test_util2.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_TEST_UTIL2_H__
+#define GOOGLE_PROTOBUF_TEST_UTIL2_H__
+
+#include <stubs/strutil.h>
+
+#include <util/message_differencer.h>
+#include <testing/googletest.h>
+
+namespace google {
+namespace protobuf {
+namespace TestUtil {
+
+// Translate net/proto2/* -> google/protobuf/*
+inline std::string TranslatePathToOpensource(const std::string& google3_path) {
+ const std::string prefix = "net/proto2/";
+ GOOGLE_CHECK(google3_path.find(prefix) == 0) << google3_path;
+ std::string path = google3_path.substr(prefix.size());
+
+ path = StringReplace(path, "internal/", "", false);
+ path = StringReplace(path, "proto/", "", false);
+ path = StringReplace(path, "public/", "", false);
+ return "google/protobuf/" + path;
+}
+
+inline std::string MaybeTranslatePath(const std::string& google3_path) {
+ std::string path = google3_path;
+ path = TranslatePathToOpensource(path);
+ return path;
+}
+
+inline std::string TestSourceDir() {
+ return google::protobuf::TestSourceDir();
+}
+
+inline std::string GetTestDataPath(const std::string& google3_path) {
+ return TestSourceDir() + "/" + MaybeTranslatePath(google3_path);
+}
+
+// Checks the equality of "message" and serialized proto of type "ProtoType".
+// Do not directly compare two serialized protos.
+template <typename ProtoType>
+bool EqualsToSerialized(const ProtoType& message, const std::string& data) {
+ ProtoType other;
+ other.ParsePartialFromString(data);
+ return util::MessageDifferencer::Equals(message, other);
+}
+
+} // namespace TestUtil
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_TEST_UTIL2_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/test_util_lite.cc b/NorthstarDedicatedTest/include/protobuf/test_util_lite.cc
new file mode 100644
index 00000000..0d5a8f37
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/test_util_lite.cc
@@ -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.
+
+#include <test_util_lite.h>
+
+#include <stubs/logging.h>
+#include <stubs/common.h>
+#include <gtest/gtest.h>
+#include <stubs/strutil.h>
+
+namespace google {
+namespace protobuf {
+
+void TestUtilLite::SetAllFields(unittest::TestAllTypesLite* message) {
+ message->set_optional_int32(101);
+ message->set_optional_int64(102);
+ message->set_optional_uint32(103);
+ message->set_optional_uint64(104);
+ message->set_optional_sint32(105);
+ message->set_optional_sint64(106);
+ message->set_optional_fixed32(107);
+ message->set_optional_fixed64(108);
+ message->set_optional_sfixed32(109);
+ message->set_optional_sfixed64(110);
+ message->set_optional_float(111);
+ message->set_optional_double(112);
+ message->set_optional_bool(true);
+ message->set_optional_string("115");
+ message->set_optional_bytes("116");
+
+ message->mutable_optionalgroup()->set_a(117);
+ message->mutable_optional_nested_message()->set_bb(118);
+ message->mutable_optional_foreign_message()->set_c(119);
+ message->mutable_optional_import_message()->set_d(120);
+ message->mutable_optional_public_import_message()->set_e(126);
+ message->mutable_optional_lazy_message()->set_bb(127);
+
+ message->set_optional_nested_enum(unittest::TestAllTypesLite::BAZ);
+ message->set_optional_foreign_enum(unittest::FOREIGN_LITE_BAZ);
+ message->set_optional_import_enum(unittest_import::IMPORT_LITE_BAZ);
+
+
+ // -----------------------------------------------------------------
+
+ message->add_repeated_int32(201);
+ message->add_repeated_int64(202);
+ message->add_repeated_uint32(203);
+ message->add_repeated_uint64(204);
+ message->add_repeated_sint32(205);
+ message->add_repeated_sint64(206);
+ message->add_repeated_fixed32(207);
+ message->add_repeated_fixed64(208);
+ message->add_repeated_sfixed32(209);
+ message->add_repeated_sfixed64(210);
+ message->add_repeated_float(211);
+ message->add_repeated_double(212);
+ message->add_repeated_bool(true);
+ message->add_repeated_string("215");
+ message->add_repeated_bytes("216");
+
+ message->add_repeatedgroup()->set_a(217);
+ message->add_repeated_nested_message()->set_bb(218);
+ message->add_repeated_foreign_message()->set_c(219);
+ message->add_repeated_import_message()->set_d(220);
+ message->add_repeated_lazy_message()->set_bb(227);
+
+ message->add_repeated_nested_enum(unittest::TestAllTypesLite::BAR);
+ message->add_repeated_foreign_enum(unittest::FOREIGN_LITE_BAR);
+ message->add_repeated_import_enum(unittest_import::IMPORT_LITE_BAR);
+
+
+ // Add a second one of each field.
+ message->add_repeated_int32(301);
+ message->add_repeated_int64(302);
+ message->add_repeated_uint32(303);
+ message->add_repeated_uint64(304);
+ message->add_repeated_sint32(305);
+ message->add_repeated_sint64(306);
+ message->add_repeated_fixed32(307);
+ message->add_repeated_fixed64(308);
+ message->add_repeated_sfixed32(309);
+ message->add_repeated_sfixed64(310);
+ message->add_repeated_float(311);
+ message->add_repeated_double(312);
+ message->add_repeated_bool(false);
+ message->add_repeated_string("315");
+ message->add_repeated_bytes("316");
+
+ message->add_repeatedgroup()->set_a(317);
+ message->add_repeated_nested_message()->set_bb(318);
+ message->add_repeated_foreign_message()->set_c(319);
+ message->add_repeated_import_message()->set_d(320);
+ message->add_repeated_lazy_message()->set_bb(327);
+
+ message->add_repeated_nested_enum(unittest::TestAllTypesLite::BAZ);
+ message->add_repeated_foreign_enum(unittest::FOREIGN_LITE_BAZ);
+ message->add_repeated_import_enum(unittest_import::IMPORT_LITE_BAZ);
+
+
+ // -----------------------------------------------------------------
+
+ message->set_default_int32(401);
+ message->set_default_int64(402);
+ message->set_default_uint32(403);
+ message->set_default_uint64(404);
+ message->set_default_sint32(405);
+ message->set_default_sint64(406);
+ message->set_default_fixed32(407);
+ message->set_default_fixed64(408);
+ message->set_default_sfixed32(409);
+ message->set_default_sfixed64(410);
+ message->set_default_float(411);
+ message->set_default_double(412);
+ message->set_default_bool(false);
+ message->set_default_string("415");
+ message->set_default_bytes("416");
+
+ message->set_default_nested_enum(unittest::TestAllTypesLite::FOO);
+ message->set_default_foreign_enum(unittest::FOREIGN_LITE_FOO);
+ message->set_default_import_enum(unittest_import::IMPORT_LITE_FOO);
+
+
+ message->set_oneof_uint32(601);
+ message->mutable_oneof_nested_message()->set_bb(602);
+ message->set_oneof_string("603");
+ message->set_oneof_bytes("604");
+}
+
+// -------------------------------------------------------------------
+
+void TestUtilLite::ModifyRepeatedFields(unittest::TestAllTypesLite* message) {
+ message->set_repeated_int32(1, 501);
+ message->set_repeated_int64(1, 502);
+ message->set_repeated_uint32(1, 503);
+ message->set_repeated_uint64(1, 504);
+ message->set_repeated_sint32(1, 505);
+ message->set_repeated_sint64(1, 506);
+ message->set_repeated_fixed32(1, 507);
+ message->set_repeated_fixed64(1, 508);
+ message->set_repeated_sfixed32(1, 509);
+ message->set_repeated_sfixed64(1, 510);
+ message->set_repeated_float(1, 511);
+ message->set_repeated_double(1, 512);
+ message->set_repeated_bool(1, true);
+ message->set_repeated_string(1, "515");
+ message->set_repeated_bytes(1, "516");
+
+ message->mutable_repeatedgroup(1)->set_a(517);
+ message->mutable_repeated_nested_message(1)->set_bb(518);
+ message->mutable_repeated_foreign_message(1)->set_c(519);
+ message->mutable_repeated_import_message(1)->set_d(520);
+ message->mutable_repeated_lazy_message(1)->set_bb(527);
+
+ message->set_repeated_nested_enum(1, unittest::TestAllTypesLite::FOO);
+ message->set_repeated_foreign_enum(1, unittest::FOREIGN_LITE_FOO);
+ message->set_repeated_import_enum(1, unittest_import::IMPORT_LITE_FOO);
+
+}
+
+// -------------------------------------------------------------------
+
+void TestUtilLite::ExpectAllFieldsSet(
+ const unittest::TestAllTypesLite& message) {
+ EXPECT_TRUE(message.has_optional_int32());
+ EXPECT_TRUE(message.has_optional_int64());
+ EXPECT_TRUE(message.has_optional_uint32());
+ EXPECT_TRUE(message.has_optional_uint64());
+ EXPECT_TRUE(message.has_optional_sint32());
+ EXPECT_TRUE(message.has_optional_sint64());
+ EXPECT_TRUE(message.has_optional_fixed32());
+ EXPECT_TRUE(message.has_optional_fixed64());
+ EXPECT_TRUE(message.has_optional_sfixed32());
+ EXPECT_TRUE(message.has_optional_sfixed64());
+ EXPECT_TRUE(message.has_optional_float());
+ EXPECT_TRUE(message.has_optional_double());
+ EXPECT_TRUE(message.has_optional_bool());
+ EXPECT_TRUE(message.has_optional_string());
+ EXPECT_TRUE(message.has_optional_bytes());
+
+ EXPECT_TRUE(message.has_optionalgroup());
+ EXPECT_TRUE(message.has_optional_nested_message());
+ EXPECT_TRUE(message.has_optional_foreign_message());
+ EXPECT_TRUE(message.has_optional_import_message());
+ EXPECT_TRUE(message.has_optional_public_import_message());
+ EXPECT_TRUE(message.has_optional_lazy_message());
+
+ EXPECT_TRUE(message.optionalgroup().has_a());
+ EXPECT_TRUE(message.optional_nested_message().has_bb());
+ EXPECT_TRUE(message.optional_foreign_message().has_c());
+ EXPECT_TRUE(message.optional_import_message().has_d());
+ EXPECT_TRUE(message.optional_public_import_message().has_e());
+ EXPECT_TRUE(message.optional_lazy_message().has_bb());
+
+ EXPECT_TRUE(message.has_optional_nested_enum());
+ EXPECT_TRUE(message.has_optional_foreign_enum());
+ EXPECT_TRUE(message.has_optional_import_enum());
+
+
+ EXPECT_EQ(101, message.optional_int32());
+ EXPECT_EQ(102, message.optional_int64());
+ EXPECT_EQ(103, message.optional_uint32());
+ EXPECT_EQ(104, message.optional_uint64());
+ EXPECT_EQ(105, message.optional_sint32());
+ EXPECT_EQ(106, message.optional_sint64());
+ EXPECT_EQ(107, message.optional_fixed32());
+ EXPECT_EQ(108, message.optional_fixed64());
+ EXPECT_EQ(109, message.optional_sfixed32());
+ EXPECT_EQ(110, message.optional_sfixed64());
+ EXPECT_EQ(111, message.optional_float());
+ EXPECT_EQ(112, message.optional_double());
+ EXPECT_EQ(true, message.optional_bool());
+ EXPECT_EQ("115", message.optional_string());
+ EXPECT_EQ("116", message.optional_bytes());
+
+ EXPECT_EQ(117, message.optionalgroup().a());
+ EXPECT_EQ(118, message.optional_nested_message().bb());
+ EXPECT_EQ(119, message.optional_foreign_message().c());
+ EXPECT_EQ(120, message.optional_import_message().d());
+ EXPECT_EQ(126, message.optional_public_import_message().e());
+ EXPECT_EQ(127, message.optional_lazy_message().bb());
+
+ EXPECT_EQ(unittest::TestAllTypesLite::BAZ, message.optional_nested_enum());
+ EXPECT_EQ(unittest::FOREIGN_LITE_BAZ, message.optional_foreign_enum());
+ EXPECT_EQ(unittest_import::IMPORT_LITE_BAZ, message.optional_import_enum());
+
+
+ // -----------------------------------------------------------------
+
+ ASSERT_EQ(2, message.repeated_int32_size());
+ ASSERT_EQ(2, message.repeated_int64_size());
+ ASSERT_EQ(2, message.repeated_uint32_size());
+ ASSERT_EQ(2, message.repeated_uint64_size());
+ ASSERT_EQ(2, message.repeated_sint32_size());
+ ASSERT_EQ(2, message.repeated_sint64_size());
+ ASSERT_EQ(2, message.repeated_fixed32_size());
+ ASSERT_EQ(2, message.repeated_fixed64_size());
+ ASSERT_EQ(2, message.repeated_sfixed32_size());
+ ASSERT_EQ(2, message.repeated_sfixed64_size());
+ ASSERT_EQ(2, message.repeated_float_size());
+ ASSERT_EQ(2, message.repeated_double_size());
+ ASSERT_EQ(2, message.repeated_bool_size());
+ ASSERT_EQ(2, message.repeated_string_size());
+ ASSERT_EQ(2, message.repeated_bytes_size());
+
+ ASSERT_EQ(2, message.repeatedgroup_size());
+ ASSERT_EQ(2, message.repeated_nested_message_size());
+ ASSERT_EQ(2, message.repeated_foreign_message_size());
+ ASSERT_EQ(2, message.repeated_import_message_size());
+ ASSERT_EQ(2, message.repeated_lazy_message_size());
+ ASSERT_EQ(2, message.repeated_nested_enum_size());
+ ASSERT_EQ(2, message.repeated_foreign_enum_size());
+ ASSERT_EQ(2, message.repeated_import_enum_size());
+
+
+ EXPECT_EQ(201, message.repeated_int32(0));
+ EXPECT_EQ(202, message.repeated_int64(0));
+ EXPECT_EQ(203, message.repeated_uint32(0));
+ EXPECT_EQ(204, message.repeated_uint64(0));
+ EXPECT_EQ(205, message.repeated_sint32(0));
+ EXPECT_EQ(206, message.repeated_sint64(0));
+ EXPECT_EQ(207, message.repeated_fixed32(0));
+ EXPECT_EQ(208, message.repeated_fixed64(0));
+ EXPECT_EQ(209, message.repeated_sfixed32(0));
+ EXPECT_EQ(210, message.repeated_sfixed64(0));
+ EXPECT_EQ(211, message.repeated_float(0));
+ EXPECT_EQ(212, message.repeated_double(0));
+ EXPECT_EQ(true, message.repeated_bool(0));
+ EXPECT_EQ("215", message.repeated_string(0));
+ EXPECT_EQ("216", message.repeated_bytes(0));
+
+ EXPECT_EQ(217, message.repeatedgroup(0).a());
+ EXPECT_EQ(218, message.repeated_nested_message(0).bb());
+ EXPECT_EQ(219, message.repeated_foreign_message(0).c());
+ EXPECT_EQ(220, message.repeated_import_message(0).d());
+ EXPECT_EQ(227, message.repeated_lazy_message(0).bb());
+
+
+ EXPECT_EQ(unittest::TestAllTypesLite::BAR, message.repeated_nested_enum(0));
+ EXPECT_EQ(unittest::FOREIGN_LITE_BAR, message.repeated_foreign_enum(0));
+ EXPECT_EQ(unittest_import::IMPORT_LITE_BAR, message.repeated_import_enum(0));
+
+ EXPECT_EQ(301, message.repeated_int32(1));
+ EXPECT_EQ(302, message.repeated_int64(1));
+ EXPECT_EQ(303, message.repeated_uint32(1));
+ EXPECT_EQ(304, message.repeated_uint64(1));
+ EXPECT_EQ(305, message.repeated_sint32(1));
+ EXPECT_EQ(306, message.repeated_sint64(1));
+ EXPECT_EQ(307, message.repeated_fixed32(1));
+ EXPECT_EQ(308, message.repeated_fixed64(1));
+ EXPECT_EQ(309, message.repeated_sfixed32(1));
+ EXPECT_EQ(310, message.repeated_sfixed64(1));
+ EXPECT_EQ(311, message.repeated_float(1));
+ EXPECT_EQ(312, message.repeated_double(1));
+ EXPECT_EQ(false, message.repeated_bool(1));
+ EXPECT_EQ("315", message.repeated_string(1));
+ EXPECT_EQ("316", message.repeated_bytes(1));
+
+ EXPECT_EQ(317, message.repeatedgroup(1).a());
+ EXPECT_EQ(318, message.repeated_nested_message(1).bb());
+ EXPECT_EQ(319, message.repeated_foreign_message(1).c());
+ EXPECT_EQ(320, message.repeated_import_message(1).d());
+ EXPECT_EQ(327, message.repeated_lazy_message(1).bb());
+
+ EXPECT_EQ(unittest::TestAllTypesLite::BAZ, message.repeated_nested_enum(1));
+ EXPECT_EQ(unittest::FOREIGN_LITE_BAZ, message.repeated_foreign_enum(1));
+ EXPECT_EQ(unittest_import::IMPORT_LITE_BAZ, message.repeated_import_enum(1));
+
+
+ // -----------------------------------------------------------------
+
+ EXPECT_TRUE(message.has_default_int32());
+ EXPECT_TRUE(message.has_default_int64());
+ EXPECT_TRUE(message.has_default_uint32());
+ EXPECT_TRUE(message.has_default_uint64());
+ EXPECT_TRUE(message.has_default_sint32());
+ EXPECT_TRUE(message.has_default_sint64());
+ EXPECT_TRUE(message.has_default_fixed32());
+ EXPECT_TRUE(message.has_default_fixed64());
+ EXPECT_TRUE(message.has_default_sfixed32());
+ EXPECT_TRUE(message.has_default_sfixed64());
+ EXPECT_TRUE(message.has_default_float());
+ EXPECT_TRUE(message.has_default_double());
+ EXPECT_TRUE(message.has_default_bool());
+ EXPECT_TRUE(message.has_default_string());
+ EXPECT_TRUE(message.has_default_bytes());
+
+ EXPECT_TRUE(message.has_default_nested_enum());
+ EXPECT_TRUE(message.has_default_foreign_enum());
+ EXPECT_TRUE(message.has_default_import_enum());
+
+
+ EXPECT_EQ(401, message.default_int32());
+ EXPECT_EQ(402, message.default_int64());
+ EXPECT_EQ(403, message.default_uint32());
+ EXPECT_EQ(404, message.default_uint64());
+ EXPECT_EQ(405, message.default_sint32());
+ EXPECT_EQ(406, message.default_sint64());
+ EXPECT_EQ(407, message.default_fixed32());
+ EXPECT_EQ(408, message.default_fixed64());
+ EXPECT_EQ(409, message.default_sfixed32());
+ EXPECT_EQ(410, message.default_sfixed64());
+ EXPECT_EQ(411, message.default_float());
+ EXPECT_EQ(412, message.default_double());
+ EXPECT_EQ(false, message.default_bool());
+ EXPECT_EQ("415", message.default_string());
+ EXPECT_EQ("416", message.default_bytes());
+
+ EXPECT_EQ(unittest::TestAllTypesLite::FOO, message.default_nested_enum());
+ EXPECT_EQ(unittest::FOREIGN_LITE_FOO, message.default_foreign_enum());
+ EXPECT_EQ(unittest_import::IMPORT_LITE_FOO, message.default_import_enum());
+
+
+ EXPECT_FALSE(message.has_oneof_uint32());
+ EXPECT_FALSE(message.has_oneof_nested_message());
+ EXPECT_FALSE(message.has_oneof_string());
+ EXPECT_TRUE(message.has_oneof_bytes());
+
+ EXPECT_EQ("604", message.oneof_bytes());
+}
+
+// -------------------------------------------------------------------
+
+void TestUtilLite::ExpectClear(const unittest::TestAllTypesLite& message) {
+ // has_blah() should initially be false for all optional fields.
+ EXPECT_FALSE(message.has_optional_int32());
+ EXPECT_FALSE(message.has_optional_int64());
+ EXPECT_FALSE(message.has_optional_uint32());
+ EXPECT_FALSE(message.has_optional_uint64());
+ EXPECT_FALSE(message.has_optional_sint32());
+ EXPECT_FALSE(message.has_optional_sint64());
+ EXPECT_FALSE(message.has_optional_fixed32());
+ EXPECT_FALSE(message.has_optional_fixed64());
+ EXPECT_FALSE(message.has_optional_sfixed32());
+ EXPECT_FALSE(message.has_optional_sfixed64());
+ EXPECT_FALSE(message.has_optional_float());
+ EXPECT_FALSE(message.has_optional_double());
+ EXPECT_FALSE(message.has_optional_bool());
+ EXPECT_FALSE(message.has_optional_string());
+ EXPECT_FALSE(message.has_optional_bytes());
+
+ EXPECT_FALSE(message.has_optionalgroup());
+ EXPECT_FALSE(message.has_optional_nested_message());
+ EXPECT_FALSE(message.has_optional_foreign_message());
+ EXPECT_FALSE(message.has_optional_import_message());
+ EXPECT_FALSE(message.has_optional_public_import_message());
+ EXPECT_FALSE(message.has_optional_lazy_message());
+
+ EXPECT_FALSE(message.has_optional_nested_enum());
+ EXPECT_FALSE(message.has_optional_foreign_enum());
+ EXPECT_FALSE(message.has_optional_import_enum());
+
+
+ // Optional fields without defaults are set to zero or something like it.
+ EXPECT_EQ(0, message.optional_int32());
+ EXPECT_EQ(0, message.optional_int64());
+ EXPECT_EQ(0, message.optional_uint32());
+ EXPECT_EQ(0, message.optional_uint64());
+ EXPECT_EQ(0, message.optional_sint32());
+ EXPECT_EQ(0, message.optional_sint64());
+ EXPECT_EQ(0, message.optional_fixed32());
+ EXPECT_EQ(0, message.optional_fixed64());
+ EXPECT_EQ(0, message.optional_sfixed32());
+ EXPECT_EQ(0, message.optional_sfixed64());
+ EXPECT_EQ(0, message.optional_float());
+ EXPECT_EQ(0, message.optional_double());
+ EXPECT_EQ(false, message.optional_bool());
+ EXPECT_EQ("", message.optional_string());
+ EXPECT_EQ("", message.optional_bytes());
+
+ // Embedded messages should also be clear.
+ EXPECT_FALSE(message.optionalgroup().has_a());
+ EXPECT_FALSE(message.optional_nested_message().has_bb());
+ EXPECT_FALSE(message.optional_foreign_message().has_c());
+ EXPECT_FALSE(message.optional_import_message().has_d());
+ EXPECT_FALSE(message.optional_public_import_message().has_e());
+ EXPECT_FALSE(message.optional_lazy_message().has_bb());
+
+ EXPECT_EQ(0, message.optionalgroup().a());
+ EXPECT_EQ(0, message.optional_nested_message().bb());
+ EXPECT_EQ(0, message.optional_foreign_message().c());
+ EXPECT_EQ(0, message.optional_import_message().d());
+
+ // Enums without defaults are set to the first value in the enum.
+ EXPECT_EQ(unittest::TestAllTypesLite::FOO, message.optional_nested_enum());
+ EXPECT_EQ(unittest::FOREIGN_LITE_FOO, message.optional_foreign_enum());
+ EXPECT_EQ(unittest_import::IMPORT_LITE_FOO, message.optional_import_enum());
+
+
+ // Repeated fields are empty.
+ EXPECT_EQ(0, message.repeated_int32_size());
+ EXPECT_EQ(0, message.repeated_int64_size());
+ EXPECT_EQ(0, message.repeated_uint32_size());
+ EXPECT_EQ(0, message.repeated_uint64_size());
+ EXPECT_EQ(0, message.repeated_sint32_size());
+ EXPECT_EQ(0, message.repeated_sint64_size());
+ EXPECT_EQ(0, message.repeated_fixed32_size());
+ EXPECT_EQ(0, message.repeated_fixed64_size());
+ EXPECT_EQ(0, message.repeated_sfixed32_size());
+ EXPECT_EQ(0, message.repeated_sfixed64_size());
+ EXPECT_EQ(0, message.repeated_float_size());
+ EXPECT_EQ(0, message.repeated_double_size());
+ EXPECT_EQ(0, message.repeated_bool_size());
+ EXPECT_EQ(0, message.repeated_string_size());
+ EXPECT_EQ(0, message.repeated_bytes_size());
+
+ EXPECT_EQ(0, message.repeatedgroup_size());
+ EXPECT_EQ(0, message.repeated_nested_message_size());
+ EXPECT_EQ(0, message.repeated_foreign_message_size());
+ EXPECT_EQ(0, message.repeated_import_message_size());
+ EXPECT_EQ(0, message.repeated_lazy_message_size());
+ EXPECT_EQ(0, message.repeated_nested_enum_size());
+ EXPECT_EQ(0, message.repeated_foreign_enum_size());
+ EXPECT_EQ(0, message.repeated_import_enum_size());
+
+
+ // has_blah() should also be false for all default fields.
+ EXPECT_FALSE(message.has_default_int32());
+ EXPECT_FALSE(message.has_default_int64());
+ EXPECT_FALSE(message.has_default_uint32());
+ EXPECT_FALSE(message.has_default_uint64());
+ EXPECT_FALSE(message.has_default_sint32());
+ EXPECT_FALSE(message.has_default_sint64());
+ EXPECT_FALSE(message.has_default_fixed32());
+ EXPECT_FALSE(message.has_default_fixed64());
+ EXPECT_FALSE(message.has_default_sfixed32());
+ EXPECT_FALSE(message.has_default_sfixed64());
+ EXPECT_FALSE(message.has_default_float());
+ EXPECT_FALSE(message.has_default_double());
+ EXPECT_FALSE(message.has_default_bool());
+ EXPECT_FALSE(message.has_default_string());
+ EXPECT_FALSE(message.has_default_bytes());
+
+ EXPECT_FALSE(message.has_default_nested_enum());
+ EXPECT_FALSE(message.has_default_foreign_enum());
+ EXPECT_FALSE(message.has_default_import_enum());
+
+
+ // Fields with defaults have their default values (duh).
+ EXPECT_EQ(41, message.default_int32());
+ EXPECT_EQ(42, message.default_int64());
+ EXPECT_EQ(43, message.default_uint32());
+ EXPECT_EQ(44, message.default_uint64());
+ EXPECT_EQ(-45, message.default_sint32());
+ EXPECT_EQ(46, message.default_sint64());
+ EXPECT_EQ(47, message.default_fixed32());
+ EXPECT_EQ(48, message.default_fixed64());
+ EXPECT_EQ(49, message.default_sfixed32());
+ EXPECT_EQ(-50, message.default_sfixed64());
+ EXPECT_EQ(51.5, message.default_float());
+ EXPECT_EQ(52e3, message.default_double());
+ EXPECT_EQ(true, message.default_bool());
+ EXPECT_EQ("hello", message.default_string());
+ EXPECT_EQ("world", message.default_bytes());
+
+ EXPECT_EQ(unittest::TestAllTypesLite::BAR, message.default_nested_enum());
+ EXPECT_EQ(unittest::FOREIGN_LITE_BAR, message.default_foreign_enum());
+ EXPECT_EQ(unittest_import::IMPORT_LITE_BAR, message.default_import_enum());
+
+
+ EXPECT_FALSE(message.has_oneof_uint32());
+ EXPECT_FALSE(message.has_oneof_nested_message());
+ EXPECT_FALSE(message.has_oneof_string());
+ EXPECT_FALSE(message.has_oneof_bytes());
+}
+
+// -------------------------------------------------------------------
+
+void TestUtilLite::ExpectRepeatedFieldsModified(
+ const unittest::TestAllTypesLite& message) {
+ // ModifyRepeatedFields only sets the second repeated element of each
+ // field. In addition to verifying this, we also verify that the first
+ // element and size were *not* modified.
+ ASSERT_EQ(2, message.repeated_int32_size());
+ ASSERT_EQ(2, message.repeated_int64_size());
+ ASSERT_EQ(2, message.repeated_uint32_size());
+ ASSERT_EQ(2, message.repeated_uint64_size());
+ ASSERT_EQ(2, message.repeated_sint32_size());
+ ASSERT_EQ(2, message.repeated_sint64_size());
+ ASSERT_EQ(2, message.repeated_fixed32_size());
+ ASSERT_EQ(2, message.repeated_fixed64_size());
+ ASSERT_EQ(2, message.repeated_sfixed32_size());
+ ASSERT_EQ(2, message.repeated_sfixed64_size());
+ ASSERT_EQ(2, message.repeated_float_size());
+ ASSERT_EQ(2, message.repeated_double_size());
+ ASSERT_EQ(2, message.repeated_bool_size());
+ ASSERT_EQ(2, message.repeated_string_size());
+ ASSERT_EQ(2, message.repeated_bytes_size());
+
+ ASSERT_EQ(2, message.repeatedgroup_size());
+ ASSERT_EQ(2, message.repeated_nested_message_size());
+ ASSERT_EQ(2, message.repeated_foreign_message_size());
+ ASSERT_EQ(2, message.repeated_import_message_size());
+ ASSERT_EQ(2, message.repeated_lazy_message_size());
+ ASSERT_EQ(2, message.repeated_nested_enum_size());
+ ASSERT_EQ(2, message.repeated_foreign_enum_size());
+ ASSERT_EQ(2, message.repeated_import_enum_size());
+
+
+ EXPECT_EQ(201, message.repeated_int32(0));
+ EXPECT_EQ(202, message.repeated_int64(0));
+ EXPECT_EQ(203, message.repeated_uint32(0));
+ EXPECT_EQ(204, message.repeated_uint64(0));
+ EXPECT_EQ(205, message.repeated_sint32(0));
+ EXPECT_EQ(206, message.repeated_sint64(0));
+ EXPECT_EQ(207, message.repeated_fixed32(0));
+ EXPECT_EQ(208, message.repeated_fixed64(0));
+ EXPECT_EQ(209, message.repeated_sfixed32(0));
+ EXPECT_EQ(210, message.repeated_sfixed64(0));
+ EXPECT_EQ(211, message.repeated_float(0));
+ EXPECT_EQ(212, message.repeated_double(0));
+ EXPECT_EQ(true, message.repeated_bool(0));
+ EXPECT_EQ("215", message.repeated_string(0));
+ EXPECT_EQ("216", message.repeated_bytes(0));
+
+ EXPECT_EQ(217, message.repeatedgroup(0).a());
+ EXPECT_EQ(218, message.repeated_nested_message(0).bb());
+ EXPECT_EQ(219, message.repeated_foreign_message(0).c());
+ EXPECT_EQ(220, message.repeated_import_message(0).d());
+ EXPECT_EQ(227, message.repeated_lazy_message(0).bb());
+
+ EXPECT_EQ(unittest::TestAllTypesLite::BAR, message.repeated_nested_enum(0));
+ EXPECT_EQ(unittest::FOREIGN_LITE_BAR, message.repeated_foreign_enum(0));
+ EXPECT_EQ(unittest_import::IMPORT_LITE_BAR, message.repeated_import_enum(0));
+
+
+ // Actually verify the second (modified) elements now.
+ EXPECT_EQ(501, message.repeated_int32(1));
+ EXPECT_EQ(502, message.repeated_int64(1));
+ EXPECT_EQ(503, message.repeated_uint32(1));
+ EXPECT_EQ(504, message.repeated_uint64(1));
+ EXPECT_EQ(505, message.repeated_sint32(1));
+ EXPECT_EQ(506, message.repeated_sint64(1));
+ EXPECT_EQ(507, message.repeated_fixed32(1));
+ EXPECT_EQ(508, message.repeated_fixed64(1));
+ EXPECT_EQ(509, message.repeated_sfixed32(1));
+ EXPECT_EQ(510, message.repeated_sfixed64(1));
+ EXPECT_EQ(511, message.repeated_float(1));
+ EXPECT_EQ(512, message.repeated_double(1));
+ EXPECT_EQ(true, message.repeated_bool(1));
+ EXPECT_EQ("515", message.repeated_string(1));
+ EXPECT_EQ("516", message.repeated_bytes(1));
+
+ EXPECT_EQ(517, message.repeatedgroup(1).a());
+ EXPECT_EQ(518, message.repeated_nested_message(1).bb());
+ EXPECT_EQ(519, message.repeated_foreign_message(1).c());
+ EXPECT_EQ(520, message.repeated_import_message(1).d());
+ EXPECT_EQ(527, message.repeated_lazy_message(1).bb());
+
+ EXPECT_EQ(unittest::TestAllTypesLite::FOO, message.repeated_nested_enum(1));
+ EXPECT_EQ(unittest::FOREIGN_LITE_FOO, message.repeated_foreign_enum(1));
+ EXPECT_EQ(unittest_import::IMPORT_LITE_FOO, message.repeated_import_enum(1));
+
+}
+
+// -------------------------------------------------------------------
+
+void TestUtilLite::SetPackedFields(unittest::TestPackedTypesLite* message) {
+ message->add_packed_int32(601);
+ message->add_packed_int64(602);
+ message->add_packed_uint32(603);
+ message->add_packed_uint64(604);
+ message->add_packed_sint32(605);
+ message->add_packed_sint64(606);
+ message->add_packed_fixed32(607);
+ message->add_packed_fixed64(608);
+ message->add_packed_sfixed32(609);
+ message->add_packed_sfixed64(610);
+ message->add_packed_float(611);
+ message->add_packed_double(612);
+ message->add_packed_bool(true);
+ message->add_packed_enum(unittest::FOREIGN_LITE_BAR);
+ // add a second one of each field
+ message->add_packed_int32(701);
+ message->add_packed_int64(702);
+ message->add_packed_uint32(703);
+ message->add_packed_uint64(704);
+ message->add_packed_sint32(705);
+ message->add_packed_sint64(706);
+ message->add_packed_fixed32(707);
+ message->add_packed_fixed64(708);
+ message->add_packed_sfixed32(709);
+ message->add_packed_sfixed64(710);
+ message->add_packed_float(711);
+ message->add_packed_double(712);
+ message->add_packed_bool(false);
+ message->add_packed_enum(unittest::FOREIGN_LITE_BAZ);
+}
+
+// -------------------------------------------------------------------
+
+void TestUtilLite::ModifyPackedFields(unittest::TestPackedTypesLite* message) {
+ message->set_packed_int32(1, 801);
+ message->set_packed_int64(1, 802);
+ message->set_packed_uint32(1, 803);
+ message->set_packed_uint64(1, 804);
+ message->set_packed_sint32(1, 805);
+ message->set_packed_sint64(1, 806);
+ message->set_packed_fixed32(1, 807);
+ message->set_packed_fixed64(1, 808);
+ message->set_packed_sfixed32(1, 809);
+ message->set_packed_sfixed64(1, 810);
+ message->set_packed_float(1, 811);
+ message->set_packed_double(1, 812);
+ message->set_packed_bool(1, true);
+ message->set_packed_enum(1, unittest::FOREIGN_LITE_FOO);
+}
+
+// -------------------------------------------------------------------
+
+void TestUtilLite::ExpectPackedFieldsSet(
+ const unittest::TestPackedTypesLite& message) {
+ ASSERT_EQ(2, message.packed_int32_size());
+ ASSERT_EQ(2, message.packed_int64_size());
+ ASSERT_EQ(2, message.packed_uint32_size());
+ ASSERT_EQ(2, message.packed_uint64_size());
+ ASSERT_EQ(2, message.packed_sint32_size());
+ ASSERT_EQ(2, message.packed_sint64_size());
+ ASSERT_EQ(2, message.packed_fixed32_size());
+ ASSERT_EQ(2, message.packed_fixed64_size());
+ ASSERT_EQ(2, message.packed_sfixed32_size());
+ ASSERT_EQ(2, message.packed_sfixed64_size());
+ ASSERT_EQ(2, message.packed_float_size());
+ ASSERT_EQ(2, message.packed_double_size());
+ ASSERT_EQ(2, message.packed_bool_size());
+ ASSERT_EQ(2, message.packed_enum_size());
+
+ EXPECT_EQ(601, message.packed_int32(0));
+ EXPECT_EQ(602, message.packed_int64(0));
+ EXPECT_EQ(603, message.packed_uint32(0));
+ EXPECT_EQ(604, message.packed_uint64(0));
+ EXPECT_EQ(605, message.packed_sint32(0));
+ EXPECT_EQ(606, message.packed_sint64(0));
+ EXPECT_EQ(607, message.packed_fixed32(0));
+ EXPECT_EQ(608, message.packed_fixed64(0));
+ EXPECT_EQ(609, message.packed_sfixed32(0));
+ EXPECT_EQ(610, message.packed_sfixed64(0));
+ EXPECT_EQ(611, message.packed_float(0));
+ EXPECT_EQ(612, message.packed_double(0));
+ EXPECT_EQ(true, message.packed_bool(0));
+ EXPECT_EQ(unittest::FOREIGN_LITE_BAR, message.packed_enum(0));
+
+ EXPECT_EQ(701, message.packed_int32(1));
+ EXPECT_EQ(702, message.packed_int64(1));
+ EXPECT_EQ(703, message.packed_uint32(1));
+ EXPECT_EQ(704, message.packed_uint64(1));
+ EXPECT_EQ(705, message.packed_sint32(1));
+ EXPECT_EQ(706, message.packed_sint64(1));
+ EXPECT_EQ(707, message.packed_fixed32(1));
+ EXPECT_EQ(708, message.packed_fixed64(1));
+ EXPECT_EQ(709, message.packed_sfixed32(1));
+ EXPECT_EQ(710, message.packed_sfixed64(1));
+ EXPECT_EQ(711, message.packed_float(1));
+ EXPECT_EQ(712, message.packed_double(1));
+ EXPECT_EQ(false, message.packed_bool(1));
+ EXPECT_EQ(unittest::FOREIGN_LITE_BAZ, message.packed_enum(1));
+}
+
+// -------------------------------------------------------------------
+
+void TestUtilLite::ExpectPackedClear(
+ const unittest::TestPackedTypesLite& message) {
+ // Packed repeated fields are empty.
+ EXPECT_EQ(0, message.packed_int32_size());
+ EXPECT_EQ(0, message.packed_int64_size());
+ EXPECT_EQ(0, message.packed_uint32_size());
+ EXPECT_EQ(0, message.packed_uint64_size());
+ EXPECT_EQ(0, message.packed_sint32_size());
+ EXPECT_EQ(0, message.packed_sint64_size());
+ EXPECT_EQ(0, message.packed_fixed32_size());
+ EXPECT_EQ(0, message.packed_fixed64_size());
+ EXPECT_EQ(0, message.packed_sfixed32_size());
+ EXPECT_EQ(0, message.packed_sfixed64_size());
+ EXPECT_EQ(0, message.packed_float_size());
+ EXPECT_EQ(0, message.packed_double_size());
+ EXPECT_EQ(0, message.packed_bool_size());
+ EXPECT_EQ(0, message.packed_enum_size());
+}
+
+// -------------------------------------------------------------------
+
+void TestUtilLite::ExpectPackedFieldsModified(
+ const unittest::TestPackedTypesLite& message) {
+ // Do the same for packed repeated fields.
+ ASSERT_EQ(2, message.packed_int32_size());
+ ASSERT_EQ(2, message.packed_int64_size());
+ ASSERT_EQ(2, message.packed_uint32_size());
+ ASSERT_EQ(2, message.packed_uint64_size());
+ ASSERT_EQ(2, message.packed_sint32_size());
+ ASSERT_EQ(2, message.packed_sint64_size());
+ ASSERT_EQ(2, message.packed_fixed32_size());
+ ASSERT_EQ(2, message.packed_fixed64_size());
+ ASSERT_EQ(2, message.packed_sfixed32_size());
+ ASSERT_EQ(2, message.packed_sfixed64_size());
+ ASSERT_EQ(2, message.packed_float_size());
+ ASSERT_EQ(2, message.packed_double_size());
+ ASSERT_EQ(2, message.packed_bool_size());
+ ASSERT_EQ(2, message.packed_enum_size());
+
+ EXPECT_EQ(601, message.packed_int32(0));
+ EXPECT_EQ(602, message.packed_int64(0));
+ EXPECT_EQ(603, message.packed_uint32(0));
+ EXPECT_EQ(604, message.packed_uint64(0));
+ EXPECT_EQ(605, message.packed_sint32(0));
+ EXPECT_EQ(606, message.packed_sint64(0));
+ EXPECT_EQ(607, message.packed_fixed32(0));
+ EXPECT_EQ(608, message.packed_fixed64(0));
+ EXPECT_EQ(609, message.packed_sfixed32(0));
+ EXPECT_EQ(610, message.packed_sfixed64(0));
+ EXPECT_EQ(611, message.packed_float(0));
+ EXPECT_EQ(612, message.packed_double(0));
+ EXPECT_EQ(true, message.packed_bool(0));
+ EXPECT_EQ(unittest::FOREIGN_LITE_BAR, message.packed_enum(0));
+ // Actually verify the second (modified) elements now.
+ EXPECT_EQ(801, message.packed_int32(1));
+ EXPECT_EQ(802, message.packed_int64(1));
+ EXPECT_EQ(803, message.packed_uint32(1));
+ EXPECT_EQ(804, message.packed_uint64(1));
+ EXPECT_EQ(805, message.packed_sint32(1));
+ EXPECT_EQ(806, message.packed_sint64(1));
+ EXPECT_EQ(807, message.packed_fixed32(1));
+ EXPECT_EQ(808, message.packed_fixed64(1));
+ EXPECT_EQ(809, message.packed_sfixed32(1));
+ EXPECT_EQ(810, message.packed_sfixed64(1));
+ EXPECT_EQ(811, message.packed_float(1));
+ EXPECT_EQ(812, message.packed_double(1));
+ EXPECT_EQ(true, message.packed_bool(1));
+ EXPECT_EQ(unittest::FOREIGN_LITE_FOO, message.packed_enum(1));
+}
+
+// ===================================================================
+// Extensions
+//
+// All this code is exactly equivalent to the above code except that it's
+// manipulating extension fields instead of normal ones.
+//
+// I gave up on the 80-char limit here. Sorry.
+
+void TestUtilLite::SetAllExtensions(unittest::TestAllExtensionsLite* message) {
+ message->SetExtension(unittest::optional_int32_extension_lite, 101);
+ message->SetExtension(unittest::optional_int64_extension_lite, 102);
+ message->SetExtension(unittest::optional_uint32_extension_lite, 103);
+ message->SetExtension(unittest::optional_uint64_extension_lite, 104);
+ message->SetExtension(unittest::optional_sint32_extension_lite, 105);
+ message->SetExtension(unittest::optional_sint64_extension_lite, 106);
+ message->SetExtension(unittest::optional_fixed32_extension_lite, 107);
+ message->SetExtension(unittest::optional_fixed64_extension_lite, 108);
+ message->SetExtension(unittest::optional_sfixed32_extension_lite, 109);
+ message->SetExtension(unittest::optional_sfixed64_extension_lite, 110);
+ message->SetExtension(unittest::optional_float_extension_lite, 111);
+ message->SetExtension(unittest::optional_double_extension_lite, 112);
+ message->SetExtension(unittest::optional_bool_extension_lite, true);
+ message->SetExtension(unittest::optional_string_extension_lite, "115");
+ message->SetExtension(unittest::optional_bytes_extension_lite, "116");
+
+ message->MutableExtension(unittest::optionalgroup_extension_lite)->set_a(117);
+ message->MutableExtension(unittest::optional_nested_message_extension_lite)
+ ->set_bb(118);
+ message->MutableExtension(unittest::optional_foreign_message_extension_lite)
+ ->set_c(119);
+ message->MutableExtension(unittest::optional_import_message_extension_lite)
+ ->set_d(120);
+ message
+ ->MutableExtension(
+ unittest::optional_public_import_message_extension_lite)
+ ->set_e(126);
+ message->MutableExtension(unittest::optional_lazy_message_extension_lite)
+ ->set_bb(127);
+
+ message->SetExtension(unittest::optional_nested_enum_extension_lite,
+ unittest::TestAllTypesLite::BAZ);
+ message->SetExtension(unittest::optional_foreign_enum_extension_lite,
+ unittest::FOREIGN_LITE_BAZ);
+ message->SetExtension(unittest::optional_import_enum_extension_lite,
+ unittest_import::IMPORT_LITE_BAZ);
+
+
+ // -----------------------------------------------------------------
+
+ message->AddExtension(unittest::repeated_int32_extension_lite, 201);
+ message->AddExtension(unittest::repeated_int64_extension_lite, 202);
+ message->AddExtension(unittest::repeated_uint32_extension_lite, 203);
+ message->AddExtension(unittest::repeated_uint64_extension_lite, 204);
+ message->AddExtension(unittest::repeated_sint32_extension_lite, 205);
+ message->AddExtension(unittest::repeated_sint64_extension_lite, 206);
+ message->AddExtension(unittest::repeated_fixed32_extension_lite, 207);
+ message->AddExtension(unittest::repeated_fixed64_extension_lite, 208);
+ message->AddExtension(unittest::repeated_sfixed32_extension_lite, 209);
+ message->AddExtension(unittest::repeated_sfixed64_extension_lite, 210);
+ message->AddExtension(unittest::repeated_float_extension_lite, 211);
+ message->AddExtension(unittest::repeated_double_extension_lite, 212);
+ message->AddExtension(unittest::repeated_bool_extension_lite, true);
+ message->AddExtension(unittest::repeated_string_extension_lite, "215");
+ message->AddExtension(unittest::repeated_bytes_extension_lite, "216");
+
+ message->AddExtension(unittest::repeatedgroup_extension_lite)->set_a(217);
+ message->AddExtension(unittest::repeated_nested_message_extension_lite)
+ ->set_bb(218);
+ message->AddExtension(unittest::repeated_foreign_message_extension_lite)
+ ->set_c(219);
+ message->AddExtension(unittest::repeated_import_message_extension_lite)
+ ->set_d(220);
+ message->AddExtension(unittest::repeated_lazy_message_extension_lite)
+ ->set_bb(227);
+
+ message->AddExtension(unittest::repeated_nested_enum_extension_lite,
+ unittest::TestAllTypesLite::BAR);
+ message->AddExtension(unittest::repeated_foreign_enum_extension_lite,
+ unittest::FOREIGN_LITE_BAR);
+ message->AddExtension(unittest::repeated_import_enum_extension_lite,
+ unittest_import::IMPORT_LITE_BAR);
+
+
+ // Add a second one of each field.
+ message->AddExtension(unittest::repeated_int32_extension_lite, 301);
+ message->AddExtension(unittest::repeated_int64_extension_lite, 302);
+ message->AddExtension(unittest::repeated_uint32_extension_lite, 303);
+ message->AddExtension(unittest::repeated_uint64_extension_lite, 304);
+ message->AddExtension(unittest::repeated_sint32_extension_lite, 305);
+ message->AddExtension(unittest::repeated_sint64_extension_lite, 306);
+ message->AddExtension(unittest::repeated_fixed32_extension_lite, 307);
+ message->AddExtension(unittest::repeated_fixed64_extension_lite, 308);
+ message->AddExtension(unittest::repeated_sfixed32_extension_lite, 309);
+ message->AddExtension(unittest::repeated_sfixed64_extension_lite, 310);
+ message->AddExtension(unittest::repeated_float_extension_lite, 311);
+ message->AddExtension(unittest::repeated_double_extension_lite, 312);
+ message->AddExtension(unittest::repeated_bool_extension_lite, false);
+ message->AddExtension(unittest::repeated_string_extension_lite, "315");
+ message->AddExtension(unittest::repeated_bytes_extension_lite, "316");
+
+ message->AddExtension(unittest::repeatedgroup_extension_lite)->set_a(317);
+ message->AddExtension(unittest::repeated_nested_message_extension_lite)
+ ->set_bb(318);
+ message->AddExtension(unittest::repeated_foreign_message_extension_lite)
+ ->set_c(319);
+ message->AddExtension(unittest::repeated_import_message_extension_lite)
+ ->set_d(320);
+ message->AddExtension(unittest::repeated_lazy_message_extension_lite)
+ ->set_bb(327);
+
+ message->AddExtension(unittest::repeated_nested_enum_extension_lite,
+ unittest::TestAllTypesLite::BAZ);
+ message->AddExtension(unittest::repeated_foreign_enum_extension_lite,
+ unittest::FOREIGN_LITE_BAZ);
+ message->AddExtension(unittest::repeated_import_enum_extension_lite,
+ unittest_import::IMPORT_LITE_BAZ);
+
+
+ // -----------------------------------------------------------------
+
+ message->SetExtension(unittest::default_int32_extension_lite, 401);
+ message->SetExtension(unittest::default_int64_extension_lite, 402);
+ message->SetExtension(unittest::default_uint32_extension_lite, 403);
+ message->SetExtension(unittest::default_uint64_extension_lite, 404);
+ message->SetExtension(unittest::default_sint32_extension_lite, 405);
+ message->SetExtension(unittest::default_sint64_extension_lite, 406);
+ message->SetExtension(unittest::default_fixed32_extension_lite, 407);
+ message->SetExtension(unittest::default_fixed64_extension_lite, 408);
+ message->SetExtension(unittest::default_sfixed32_extension_lite, 409);
+ message->SetExtension(unittest::default_sfixed64_extension_lite, 410);
+ message->SetExtension(unittest::default_float_extension_lite, 411);
+ message->SetExtension(unittest::default_double_extension_lite, 412);
+ message->SetExtension(unittest::default_bool_extension_lite, false);
+ message->SetExtension(unittest::default_string_extension_lite, "415");
+ message->SetExtension(unittest::default_bytes_extension_lite, "416");
+
+ message->SetExtension(unittest::default_nested_enum_extension_lite,
+ unittest::TestAllTypesLite::FOO);
+ message->SetExtension(unittest::default_foreign_enum_extension_lite,
+ unittest::FOREIGN_LITE_FOO);
+ message->SetExtension(unittest::default_import_enum_extension_lite,
+ unittest_import::IMPORT_LITE_FOO);
+
+
+ message->SetExtension(unittest::oneof_uint32_extension_lite, 601);
+ message->MutableExtension(unittest::oneof_nested_message_extension_lite)
+ ->set_bb(602);
+ ;
+ message->SetExtension(unittest::oneof_string_extension_lite, "603");
+ message->SetExtension(unittest::oneof_bytes_extension_lite, "604");
+}
+
+// -------------------------------------------------------------------
+
+void TestUtilLite::ModifyRepeatedExtensions(
+ unittest::TestAllExtensionsLite* message) {
+ message->SetExtension(unittest::repeated_int32_extension_lite, 1, 501);
+ message->SetExtension(unittest::repeated_int64_extension_lite, 1, 502);
+ message->SetExtension(unittest::repeated_uint32_extension_lite, 1, 503);
+ message->SetExtension(unittest::repeated_uint64_extension_lite, 1, 504);
+ message->SetExtension(unittest::repeated_sint32_extension_lite, 1, 505);
+ message->SetExtension(unittest::repeated_sint64_extension_lite, 1, 506);
+ message->SetExtension(unittest::repeated_fixed32_extension_lite, 1, 507);
+ message->SetExtension(unittest::repeated_fixed64_extension_lite, 1, 508);
+ message->SetExtension(unittest::repeated_sfixed32_extension_lite, 1, 509);
+ message->SetExtension(unittest::repeated_sfixed64_extension_lite, 1, 510);
+ message->SetExtension(unittest::repeated_float_extension_lite, 1, 511);
+ message->SetExtension(unittest::repeated_double_extension_lite, 1, 512);
+ message->SetExtension(unittest::repeated_bool_extension_lite, 1, true);
+ message->SetExtension(unittest::repeated_string_extension_lite, 1, "515");
+ message->SetExtension(unittest::repeated_bytes_extension_lite, 1, "516");
+
+ message->MutableExtension(unittest::repeatedgroup_extension_lite, 1)
+ ->set_a(517);
+ message->MutableExtension(unittest::repeated_nested_message_extension_lite, 1)
+ ->set_bb(518);
+ message
+ ->MutableExtension(unittest::repeated_foreign_message_extension_lite, 1)
+ ->set_c(519);
+ message->MutableExtension(unittest::repeated_import_message_extension_lite, 1)
+ ->set_d(520);
+ message->MutableExtension(unittest::repeated_lazy_message_extension_lite, 1)
+ ->set_bb(527);
+
+ message->SetExtension(unittest::repeated_nested_enum_extension_lite, 1,
+ unittest::TestAllTypesLite::FOO);
+ message->SetExtension(unittest::repeated_foreign_enum_extension_lite, 1,
+ unittest::FOREIGN_LITE_FOO);
+ message->SetExtension(unittest::repeated_import_enum_extension_lite, 1,
+ unittest_import::IMPORT_LITE_FOO);
+
+}
+
+// -------------------------------------------------------------------
+
+void TestUtilLite::ExpectAllExtensionsSet(
+ const unittest::TestAllExtensionsLite& message) {
+ EXPECT_TRUE(message.HasExtension(unittest::optional_int32_extension_lite));
+ EXPECT_TRUE(message.HasExtension(unittest::optional_int64_extension_lite));
+ EXPECT_TRUE(message.HasExtension(unittest::optional_uint32_extension_lite));
+ EXPECT_TRUE(message.HasExtension(unittest::optional_uint64_extension_lite));
+ EXPECT_TRUE(message.HasExtension(unittest::optional_sint32_extension_lite));
+ EXPECT_TRUE(message.HasExtension(unittest::optional_sint64_extension_lite));
+ EXPECT_TRUE(message.HasExtension(unittest::optional_fixed32_extension_lite));
+ EXPECT_TRUE(message.HasExtension(unittest::optional_fixed64_extension_lite));
+ EXPECT_TRUE(message.HasExtension(unittest::optional_sfixed32_extension_lite));
+ EXPECT_TRUE(message.HasExtension(unittest::optional_sfixed64_extension_lite));
+ EXPECT_TRUE(message.HasExtension(unittest::optional_float_extension_lite));
+ EXPECT_TRUE(message.HasExtension(unittest::optional_double_extension_lite));
+ EXPECT_TRUE(message.HasExtension(unittest::optional_bool_extension_lite));
+ EXPECT_TRUE(message.HasExtension(unittest::optional_string_extension_lite));
+ EXPECT_TRUE(message.HasExtension(unittest::optional_bytes_extension_lite));
+
+ EXPECT_TRUE(message.HasExtension(unittest::optionalgroup_extension_lite));
+ EXPECT_TRUE(
+ message.HasExtension(unittest::optional_nested_message_extension_lite));
+ EXPECT_TRUE(
+ message.HasExtension(unittest::optional_foreign_message_extension_lite));
+ EXPECT_TRUE(
+ message.HasExtension(unittest::optional_import_message_extension_lite));
+ EXPECT_TRUE(message.HasExtension(
+ unittest::optional_public_import_message_extension_lite));
+ EXPECT_TRUE(
+ message.HasExtension(unittest::optional_lazy_message_extension_lite));
+
+ EXPECT_TRUE(
+ message.GetExtension(unittest::optionalgroup_extension_lite).has_a());
+ EXPECT_TRUE(
+ message.GetExtension(unittest::optional_nested_message_extension_lite)
+ .has_bb());
+ EXPECT_TRUE(
+ message.GetExtension(unittest::optional_foreign_message_extension_lite)
+ .has_c());
+ EXPECT_TRUE(
+ message.GetExtension(unittest::optional_import_message_extension_lite)
+ .has_d());
+ EXPECT_TRUE(
+ message
+ .GetExtension(unittest::optional_public_import_message_extension_lite)
+ .has_e());
+ EXPECT_TRUE(
+ message.GetExtension(unittest::optional_lazy_message_extension_lite)
+ .has_bb());
+
+ EXPECT_TRUE(
+ message.HasExtension(unittest::optional_nested_enum_extension_lite));
+ EXPECT_TRUE(
+ message.HasExtension(unittest::optional_foreign_enum_extension_lite));
+ EXPECT_TRUE(
+ message.HasExtension(unittest::optional_import_enum_extension_lite));
+
+
+ EXPECT_EQ(101, message.GetExtension(unittest::optional_int32_extension_lite));
+ EXPECT_EQ(102, message.GetExtension(unittest::optional_int64_extension_lite));
+ EXPECT_EQ(103,
+ message.GetExtension(unittest::optional_uint32_extension_lite));
+ EXPECT_EQ(104,
+ message.GetExtension(unittest::optional_uint64_extension_lite));
+ EXPECT_EQ(105,
+ message.GetExtension(unittest::optional_sint32_extension_lite));
+ EXPECT_EQ(106,
+ message.GetExtension(unittest::optional_sint64_extension_lite));
+ EXPECT_EQ(107,
+ message.GetExtension(unittest::optional_fixed32_extension_lite));
+ EXPECT_EQ(108,
+ message.GetExtension(unittest::optional_fixed64_extension_lite));
+ EXPECT_EQ(109,
+ message.GetExtension(unittest::optional_sfixed32_extension_lite));
+ EXPECT_EQ(110,
+ message.GetExtension(unittest::optional_sfixed64_extension_lite));
+ EXPECT_EQ(111, message.GetExtension(unittest::optional_float_extension_lite));
+ EXPECT_EQ(112,
+ message.GetExtension(unittest::optional_double_extension_lite));
+ EXPECT_EQ(true, message.GetExtension(unittest::optional_bool_extension_lite));
+ EXPECT_EQ("115",
+ message.GetExtension(unittest::optional_string_extension_lite));
+ EXPECT_EQ("116",
+ message.GetExtension(unittest::optional_bytes_extension_lite));
+
+ EXPECT_EQ(117,
+ message.GetExtension(unittest::optionalgroup_extension_lite).a());
+ EXPECT_EQ(
+ 118,
+ message.GetExtension(unittest::optional_nested_message_extension_lite)
+ .bb());
+ EXPECT_EQ(
+ 119,
+ message.GetExtension(unittest::optional_foreign_message_extension_lite)
+ .c());
+ EXPECT_EQ(
+ 120,
+ message.GetExtension(unittest::optional_import_message_extension_lite)
+ .d());
+ EXPECT_EQ(
+ 126,
+ message
+ .GetExtension(unittest::optional_public_import_message_extension_lite)
+ .e());
+ EXPECT_EQ(127,
+ message.GetExtension(unittest::optional_lazy_message_extension_lite)
+ .bb());
+
+ EXPECT_EQ(
+ unittest::TestAllTypesLite::BAZ,
+ message.GetExtension(unittest::optional_nested_enum_extension_lite));
+ EXPECT_EQ(
+ unittest::FOREIGN_LITE_BAZ,
+ message.GetExtension(unittest::optional_foreign_enum_extension_lite));
+ EXPECT_EQ(
+ unittest_import::IMPORT_LITE_BAZ,
+ message.GetExtension(unittest::optional_import_enum_extension_lite));
+
+
+ // -----------------------------------------------------------------
+
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_int32_extension_lite));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_int64_extension_lite));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_uint32_extension_lite));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_uint64_extension_lite));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_sint32_extension_lite));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_sint64_extension_lite));
+ ASSERT_EQ(2,
+ message.ExtensionSize(unittest::repeated_fixed32_extension_lite));
+ ASSERT_EQ(2,
+ message.ExtensionSize(unittest::repeated_fixed64_extension_lite));
+ ASSERT_EQ(2,
+ message.ExtensionSize(unittest::repeated_sfixed32_extension_lite));
+ ASSERT_EQ(2,
+ message.ExtensionSize(unittest::repeated_sfixed64_extension_lite));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_float_extension_lite));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_double_extension_lite));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_bool_extension_lite));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_string_extension_lite));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_bytes_extension_lite));
+
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeatedgroup_extension_lite));
+ ASSERT_EQ(2, message.ExtensionSize(
+ unittest::repeated_nested_message_extension_lite));
+ ASSERT_EQ(2, message.ExtensionSize(
+ unittest::repeated_foreign_message_extension_lite));
+ ASSERT_EQ(2, message.ExtensionSize(
+ unittest::repeated_import_message_extension_lite));
+ ASSERT_EQ(
+ 2, message.ExtensionSize(unittest::repeated_lazy_message_extension_lite));
+ ASSERT_EQ(
+ 2, message.ExtensionSize(unittest::repeated_nested_enum_extension_lite));
+ ASSERT_EQ(
+ 2, message.ExtensionSize(unittest::repeated_foreign_enum_extension_lite));
+ ASSERT_EQ(
+ 2, message.ExtensionSize(unittest::repeated_import_enum_extension_lite));
+
+
+ EXPECT_EQ(201,
+ message.GetExtension(unittest::repeated_int32_extension_lite, 0));
+ EXPECT_EQ(202,
+ message.GetExtension(unittest::repeated_int64_extension_lite, 0));
+ EXPECT_EQ(203,
+ message.GetExtension(unittest::repeated_uint32_extension_lite, 0));
+ EXPECT_EQ(204,
+ message.GetExtension(unittest::repeated_uint64_extension_lite, 0));
+ EXPECT_EQ(205,
+ message.GetExtension(unittest::repeated_sint32_extension_lite, 0));
+ EXPECT_EQ(206,
+ message.GetExtension(unittest::repeated_sint64_extension_lite, 0));
+ EXPECT_EQ(207,
+ message.GetExtension(unittest::repeated_fixed32_extension_lite, 0));
+ EXPECT_EQ(208,
+ message.GetExtension(unittest::repeated_fixed64_extension_lite, 0));
+ EXPECT_EQ(
+ 209, message.GetExtension(unittest::repeated_sfixed32_extension_lite, 0));
+ EXPECT_EQ(
+ 210, message.GetExtension(unittest::repeated_sfixed64_extension_lite, 0));
+ EXPECT_EQ(211,
+ message.GetExtension(unittest::repeated_float_extension_lite, 0));
+ EXPECT_EQ(212,
+ message.GetExtension(unittest::repeated_double_extension_lite, 0));
+ EXPECT_EQ(true,
+ message.GetExtension(unittest::repeated_bool_extension_lite, 0));
+ EXPECT_EQ("215",
+ message.GetExtension(unittest::repeated_string_extension_lite, 0));
+ EXPECT_EQ("216",
+ message.GetExtension(unittest::repeated_bytes_extension_lite, 0));
+
+ EXPECT_EQ(
+ 217, message.GetExtension(unittest::repeatedgroup_extension_lite, 0).a());
+ EXPECT_EQ(
+ 218,
+ message.GetExtension(unittest::repeated_nested_message_extension_lite, 0)
+ .bb());
+ EXPECT_EQ(
+ 219,
+ message.GetExtension(unittest::repeated_foreign_message_extension_lite, 0)
+ .c());
+ EXPECT_EQ(
+ 220,
+ message.GetExtension(unittest::repeated_import_message_extension_lite, 0)
+ .d());
+ EXPECT_EQ(
+ 227,
+ message.GetExtension(unittest::repeated_lazy_message_extension_lite, 0)
+ .bb());
+
+ EXPECT_EQ(
+ unittest::TestAllTypesLite::BAR,
+ message.GetExtension(unittest::repeated_nested_enum_extension_lite, 0));
+ EXPECT_EQ(
+ unittest::FOREIGN_LITE_BAR,
+ message.GetExtension(unittest::repeated_foreign_enum_extension_lite, 0));
+ EXPECT_EQ(
+ unittest_import::IMPORT_LITE_BAR,
+ message.GetExtension(unittest::repeated_import_enum_extension_lite, 0));
+
+
+ EXPECT_EQ(301,
+ message.GetExtension(unittest::repeated_int32_extension_lite, 1));
+ EXPECT_EQ(302,
+ message.GetExtension(unittest::repeated_int64_extension_lite, 1));
+ EXPECT_EQ(303,
+ message.GetExtension(unittest::repeated_uint32_extension_lite, 1));
+ EXPECT_EQ(304,
+ message.GetExtension(unittest::repeated_uint64_extension_lite, 1));
+ EXPECT_EQ(305,
+ message.GetExtension(unittest::repeated_sint32_extension_lite, 1));
+ EXPECT_EQ(306,
+ message.GetExtension(unittest::repeated_sint64_extension_lite, 1));
+ EXPECT_EQ(307,
+ message.GetExtension(unittest::repeated_fixed32_extension_lite, 1));
+ EXPECT_EQ(308,
+ message.GetExtension(unittest::repeated_fixed64_extension_lite, 1));
+ EXPECT_EQ(
+ 309, message.GetExtension(unittest::repeated_sfixed32_extension_lite, 1));
+ EXPECT_EQ(
+ 310, message.GetExtension(unittest::repeated_sfixed64_extension_lite, 1));
+ EXPECT_EQ(311,
+ message.GetExtension(unittest::repeated_float_extension_lite, 1));
+ EXPECT_EQ(312,
+ message.GetExtension(unittest::repeated_double_extension_lite, 1));
+ EXPECT_EQ(false,
+ message.GetExtension(unittest::repeated_bool_extension_lite, 1));
+ EXPECT_EQ("315",
+ message.GetExtension(unittest::repeated_string_extension_lite, 1));
+ EXPECT_EQ("316",
+ message.GetExtension(unittest::repeated_bytes_extension_lite, 1));
+
+ EXPECT_EQ(
+ 317, message.GetExtension(unittest::repeatedgroup_extension_lite, 1).a());
+ EXPECT_EQ(
+ 318,
+ message.GetExtension(unittest::repeated_nested_message_extension_lite, 1)
+ .bb());
+ EXPECT_EQ(
+ 319,
+ message.GetExtension(unittest::repeated_foreign_message_extension_lite, 1)
+ .c());
+ EXPECT_EQ(
+ 320,
+ message.GetExtension(unittest::repeated_import_message_extension_lite, 1)
+ .d());
+ EXPECT_EQ(
+ 327,
+ message.GetExtension(unittest::repeated_lazy_message_extension_lite, 1)
+ .bb());
+
+ EXPECT_EQ(
+ unittest::TestAllTypesLite::BAZ,
+ message.GetExtension(unittest::repeated_nested_enum_extension_lite, 1));
+ EXPECT_EQ(
+ unittest::FOREIGN_LITE_BAZ,
+ message.GetExtension(unittest::repeated_foreign_enum_extension_lite, 1));
+ EXPECT_EQ(
+ unittest_import::IMPORT_LITE_BAZ,
+ message.GetExtension(unittest::repeated_import_enum_extension_lite, 1));
+
+
+ // -----------------------------------------------------------------
+
+ EXPECT_TRUE(message.HasExtension(unittest::default_int32_extension_lite));
+ EXPECT_TRUE(message.HasExtension(unittest::default_int64_extension_lite));
+ EXPECT_TRUE(message.HasExtension(unittest::default_uint32_extension_lite));
+ EXPECT_TRUE(message.HasExtension(unittest::default_uint64_extension_lite));
+ EXPECT_TRUE(message.HasExtension(unittest::default_sint32_extension_lite));
+ EXPECT_TRUE(message.HasExtension(unittest::default_sint64_extension_lite));
+ EXPECT_TRUE(message.HasExtension(unittest::default_fixed32_extension_lite));
+ EXPECT_TRUE(message.HasExtension(unittest::default_fixed64_extension_lite));
+ EXPECT_TRUE(message.HasExtension(unittest::default_sfixed32_extension_lite));
+ EXPECT_TRUE(message.HasExtension(unittest::default_sfixed64_extension_lite));
+ EXPECT_TRUE(message.HasExtension(unittest::default_float_extension_lite));
+ EXPECT_TRUE(message.HasExtension(unittest::default_double_extension_lite));
+ EXPECT_TRUE(message.HasExtension(unittest::default_bool_extension_lite));
+ EXPECT_TRUE(message.HasExtension(unittest::default_string_extension_lite));
+ EXPECT_TRUE(message.HasExtension(unittest::default_bytes_extension_lite));
+
+ EXPECT_TRUE(
+ message.HasExtension(unittest::default_nested_enum_extension_lite));
+ EXPECT_TRUE(
+ message.HasExtension(unittest::default_foreign_enum_extension_lite));
+ EXPECT_TRUE(
+ message.HasExtension(unittest::default_import_enum_extension_lite));
+
+
+ EXPECT_EQ(401, message.GetExtension(unittest::default_int32_extension_lite));
+ EXPECT_EQ(402, message.GetExtension(unittest::default_int64_extension_lite));
+ EXPECT_EQ(403, message.GetExtension(unittest::default_uint32_extension_lite));
+ EXPECT_EQ(404, message.GetExtension(unittest::default_uint64_extension_lite));
+ EXPECT_EQ(405, message.GetExtension(unittest::default_sint32_extension_lite));
+ EXPECT_EQ(406, message.GetExtension(unittest::default_sint64_extension_lite));
+ EXPECT_EQ(407,
+ message.GetExtension(unittest::default_fixed32_extension_lite));
+ EXPECT_EQ(408,
+ message.GetExtension(unittest::default_fixed64_extension_lite));
+ EXPECT_EQ(409,
+ message.GetExtension(unittest::default_sfixed32_extension_lite));
+ EXPECT_EQ(410,
+ message.GetExtension(unittest::default_sfixed64_extension_lite));
+ EXPECT_EQ(411, message.GetExtension(unittest::default_float_extension_lite));
+ EXPECT_EQ(412, message.GetExtension(unittest::default_double_extension_lite));
+ EXPECT_EQ(false, message.GetExtension(unittest::default_bool_extension_lite));
+ EXPECT_EQ("415",
+ message.GetExtension(unittest::default_string_extension_lite));
+ EXPECT_EQ("416",
+ message.GetExtension(unittest::default_bytes_extension_lite));
+
+ EXPECT_EQ(unittest::TestAllTypesLite::FOO,
+ message.GetExtension(unittest::default_nested_enum_extension_lite));
+ EXPECT_EQ(
+ unittest::FOREIGN_LITE_FOO,
+ message.GetExtension(unittest::default_foreign_enum_extension_lite));
+ EXPECT_EQ(unittest_import::IMPORT_LITE_FOO,
+ message.GetExtension(unittest::default_import_enum_extension_lite));
+
+
+ EXPECT_TRUE(message.HasExtension(unittest::oneof_uint32_extension_lite));
+ EXPECT_TRUE(
+ message.GetExtension(unittest::oneof_nested_message_extension_lite)
+ .has_bb());
+ EXPECT_TRUE(message.HasExtension(unittest::oneof_string_extension_lite));
+ EXPECT_TRUE(message.HasExtension(unittest::oneof_bytes_extension_lite));
+
+ EXPECT_EQ(601, message.GetExtension(unittest::oneof_uint32_extension_lite));
+ EXPECT_EQ(
+ 602,
+ message.GetExtension(unittest::oneof_nested_message_extension_lite).bb());
+ EXPECT_EQ("603", message.GetExtension(unittest::oneof_string_extension_lite));
+ EXPECT_EQ("604", message.GetExtension(unittest::oneof_bytes_extension_lite));
+}
+
+// -------------------------------------------------------------------
+
+void TestUtilLite::ExpectExtensionsClear(
+ const unittest::TestAllExtensionsLite& message) {
+ std::string serialized;
+ ASSERT_TRUE(message.SerializeToString(&serialized));
+ EXPECT_EQ("", serialized);
+ EXPECT_EQ(0, message.ByteSizeLong());
+
+ // has_blah() should initially be false for all optional fields.
+ EXPECT_FALSE(message.HasExtension(unittest::optional_int32_extension_lite));
+ EXPECT_FALSE(message.HasExtension(unittest::optional_int64_extension_lite));
+ EXPECT_FALSE(message.HasExtension(unittest::optional_uint32_extension_lite));
+ EXPECT_FALSE(message.HasExtension(unittest::optional_uint64_extension_lite));
+ EXPECT_FALSE(message.HasExtension(unittest::optional_sint32_extension_lite));
+ EXPECT_FALSE(message.HasExtension(unittest::optional_sint64_extension_lite));
+ EXPECT_FALSE(message.HasExtension(unittest::optional_fixed32_extension_lite));
+ EXPECT_FALSE(message.HasExtension(unittest::optional_fixed64_extension_lite));
+ EXPECT_FALSE(
+ message.HasExtension(unittest::optional_sfixed32_extension_lite));
+ EXPECT_FALSE(
+ message.HasExtension(unittest::optional_sfixed64_extension_lite));
+ EXPECT_FALSE(message.HasExtension(unittest::optional_float_extension_lite));
+ EXPECT_FALSE(message.HasExtension(unittest::optional_double_extension_lite));
+ EXPECT_FALSE(message.HasExtension(unittest::optional_bool_extension_lite));
+ EXPECT_FALSE(message.HasExtension(unittest::optional_string_extension_lite));
+ EXPECT_FALSE(message.HasExtension(unittest::optional_bytes_extension_lite));
+
+ EXPECT_FALSE(message.HasExtension(unittest::optionalgroup_extension_lite));
+ EXPECT_FALSE(
+ message.HasExtension(unittest::optional_nested_message_extension_lite));
+ EXPECT_FALSE(
+ message.HasExtension(unittest::optional_foreign_message_extension_lite));
+ EXPECT_FALSE(
+ message.HasExtension(unittest::optional_import_message_extension_lite));
+ EXPECT_FALSE(message.HasExtension(
+ unittest::optional_public_import_message_extension_lite));
+ EXPECT_FALSE(
+ message.HasExtension(unittest::optional_lazy_message_extension_lite));
+
+ EXPECT_FALSE(
+ message.HasExtension(unittest::optional_nested_enum_extension_lite));
+ EXPECT_FALSE(
+ message.HasExtension(unittest::optional_foreign_enum_extension_lite));
+ EXPECT_FALSE(
+ message.HasExtension(unittest::optional_import_enum_extension_lite));
+
+
+ // Optional fields without defaults are set to zero or something like it.
+ EXPECT_EQ(0, message.GetExtension(unittest::optional_int32_extension_lite));
+ EXPECT_EQ(0, message.GetExtension(unittest::optional_int64_extension_lite));
+ EXPECT_EQ(0, message.GetExtension(unittest::optional_uint32_extension_lite));
+ EXPECT_EQ(0, message.GetExtension(unittest::optional_uint64_extension_lite));
+ EXPECT_EQ(0, message.GetExtension(unittest::optional_sint32_extension_lite));
+ EXPECT_EQ(0, message.GetExtension(unittest::optional_sint64_extension_lite));
+ EXPECT_EQ(0, message.GetExtension(unittest::optional_fixed32_extension_lite));
+ EXPECT_EQ(0, message.GetExtension(unittest::optional_fixed64_extension_lite));
+ EXPECT_EQ(0,
+ message.GetExtension(unittest::optional_sfixed32_extension_lite));
+ EXPECT_EQ(0,
+ message.GetExtension(unittest::optional_sfixed64_extension_lite));
+ EXPECT_EQ(0, message.GetExtension(unittest::optional_float_extension_lite));
+ EXPECT_EQ(0, message.GetExtension(unittest::optional_double_extension_lite));
+ EXPECT_EQ(false,
+ message.GetExtension(unittest::optional_bool_extension_lite));
+ EXPECT_EQ("", message.GetExtension(unittest::optional_string_extension_lite));
+ EXPECT_EQ("", message.GetExtension(unittest::optional_bytes_extension_lite));
+
+ // Embedded messages should also be clear.
+ EXPECT_FALSE(
+ message.GetExtension(unittest::optionalgroup_extension_lite).has_a());
+ EXPECT_FALSE(
+ message.GetExtension(unittest::optional_nested_message_extension_lite)
+ .has_bb());
+ EXPECT_FALSE(
+ message.GetExtension(unittest::optional_foreign_message_extension_lite)
+ .has_c());
+ EXPECT_FALSE(
+ message.GetExtension(unittest::optional_import_message_extension_lite)
+ .has_d());
+ EXPECT_FALSE(
+ message
+ .GetExtension(unittest::optional_public_import_message_extension_lite)
+ .has_e());
+ EXPECT_FALSE(
+ message.GetExtension(unittest::optional_lazy_message_extension_lite)
+ .has_bb());
+
+ EXPECT_EQ(0,
+ message.GetExtension(unittest::optionalgroup_extension_lite).a());
+ EXPECT_EQ(
+ 0, message.GetExtension(unittest::optional_nested_message_extension_lite)
+ .bb());
+ EXPECT_EQ(
+ 0, message.GetExtension(unittest::optional_foreign_message_extension_lite)
+ .c());
+ EXPECT_EQ(
+ 0, message.GetExtension(unittest::optional_import_message_extension_lite)
+ .d());
+ EXPECT_EQ(0, message
+ .GetExtension(
+ unittest::optional_public_import_message_extension_lite)
+ .e());
+ EXPECT_EQ(0,
+ message.GetExtension(unittest::optional_lazy_message_extension_lite)
+ .bb());
+
+ // Enums without defaults are set to the first value in the enum.
+ EXPECT_EQ(
+ unittest::TestAllTypesLite::FOO,
+ message.GetExtension(unittest::optional_nested_enum_extension_lite));
+ EXPECT_EQ(
+ unittest::FOREIGN_LITE_FOO,
+ message.GetExtension(unittest::optional_foreign_enum_extension_lite));
+ EXPECT_EQ(
+ unittest_import::IMPORT_LITE_FOO,
+ message.GetExtension(unittest::optional_import_enum_extension_lite));
+
+
+ // Repeated fields are empty.
+ EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_int32_extension_lite));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_int64_extension_lite));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_uint32_extension_lite));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_uint64_extension_lite));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_sint32_extension_lite));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_sint64_extension_lite));
+ EXPECT_EQ(0,
+ message.ExtensionSize(unittest::repeated_fixed32_extension_lite));
+ EXPECT_EQ(0,
+ message.ExtensionSize(unittest::repeated_fixed64_extension_lite));
+ EXPECT_EQ(0,
+ message.ExtensionSize(unittest::repeated_sfixed32_extension_lite));
+ EXPECT_EQ(0,
+ message.ExtensionSize(unittest::repeated_sfixed64_extension_lite));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_float_extension_lite));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_double_extension_lite));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_bool_extension_lite));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_string_extension_lite));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_bytes_extension_lite));
+
+ EXPECT_EQ(0, message.ExtensionSize(unittest::repeatedgroup_extension_lite));
+ EXPECT_EQ(0, message.ExtensionSize(
+ unittest::repeated_nested_message_extension_lite));
+ EXPECT_EQ(0, message.ExtensionSize(
+ unittest::repeated_foreign_message_extension_lite));
+ EXPECT_EQ(0, message.ExtensionSize(
+ unittest::repeated_import_message_extension_lite));
+ EXPECT_EQ(
+ 0, message.ExtensionSize(unittest::repeated_lazy_message_extension_lite));
+ EXPECT_EQ(
+ 0, message.ExtensionSize(unittest::repeated_nested_enum_extension_lite));
+ EXPECT_EQ(
+ 0, message.ExtensionSize(unittest::repeated_foreign_enum_extension_lite));
+ EXPECT_EQ(
+ 0, message.ExtensionSize(unittest::repeated_import_enum_extension_lite));
+
+
+ // has_blah() should also be false for all default fields.
+ EXPECT_FALSE(message.HasExtension(unittest::default_int32_extension_lite));
+ EXPECT_FALSE(message.HasExtension(unittest::default_int64_extension_lite));
+ EXPECT_FALSE(message.HasExtension(unittest::default_uint32_extension_lite));
+ EXPECT_FALSE(message.HasExtension(unittest::default_uint64_extension_lite));
+ EXPECT_FALSE(message.HasExtension(unittest::default_sint32_extension_lite));
+ EXPECT_FALSE(message.HasExtension(unittest::default_sint64_extension_lite));
+ EXPECT_FALSE(message.HasExtension(unittest::default_fixed32_extension_lite));
+ EXPECT_FALSE(message.HasExtension(unittest::default_fixed64_extension_lite));
+ EXPECT_FALSE(message.HasExtension(unittest::default_sfixed32_extension_lite));
+ EXPECT_FALSE(message.HasExtension(unittest::default_sfixed64_extension_lite));
+ EXPECT_FALSE(message.HasExtension(unittest::default_float_extension_lite));
+ EXPECT_FALSE(message.HasExtension(unittest::default_double_extension_lite));
+ EXPECT_FALSE(message.HasExtension(unittest::default_bool_extension_lite));
+ EXPECT_FALSE(message.HasExtension(unittest::default_string_extension_lite));
+ EXPECT_FALSE(message.HasExtension(unittest::default_bytes_extension_lite));
+
+ EXPECT_FALSE(
+ message.HasExtension(unittest::default_nested_enum_extension_lite));
+ EXPECT_FALSE(
+ message.HasExtension(unittest::default_foreign_enum_extension_lite));
+ EXPECT_FALSE(
+ message.HasExtension(unittest::default_import_enum_extension_lite));
+
+
+ // Fields with defaults have their default values (duh).
+ EXPECT_EQ(41, message.GetExtension(unittest::default_int32_extension_lite));
+ EXPECT_EQ(42, message.GetExtension(unittest::default_int64_extension_lite));
+ EXPECT_EQ(43, message.GetExtension(unittest::default_uint32_extension_lite));
+ EXPECT_EQ(44, message.GetExtension(unittest::default_uint64_extension_lite));
+ EXPECT_EQ(-45, message.GetExtension(unittest::default_sint32_extension_lite));
+ EXPECT_EQ(46, message.GetExtension(unittest::default_sint64_extension_lite));
+ EXPECT_EQ(47, message.GetExtension(unittest::default_fixed32_extension_lite));
+ EXPECT_EQ(48, message.GetExtension(unittest::default_fixed64_extension_lite));
+ EXPECT_EQ(49,
+ message.GetExtension(unittest::default_sfixed32_extension_lite));
+ EXPECT_EQ(-50,
+ message.GetExtension(unittest::default_sfixed64_extension_lite));
+ EXPECT_EQ(51.5, message.GetExtension(unittest::default_float_extension_lite));
+ EXPECT_EQ(52e3,
+ message.GetExtension(unittest::default_double_extension_lite));
+ EXPECT_EQ(true, message.GetExtension(unittest::default_bool_extension_lite));
+ EXPECT_EQ("hello",
+ message.GetExtension(unittest::default_string_extension_lite));
+ EXPECT_EQ("world",
+ message.GetExtension(unittest::default_bytes_extension_lite));
+
+ EXPECT_EQ(unittest::TestAllTypesLite::BAR,
+ message.GetExtension(unittest::default_nested_enum_extension_lite));
+ EXPECT_EQ(
+ unittest::FOREIGN_LITE_BAR,
+ message.GetExtension(unittest::default_foreign_enum_extension_lite));
+ EXPECT_EQ(unittest_import::IMPORT_LITE_BAR,
+ message.GetExtension(unittest::default_import_enum_extension_lite));
+
+
+ EXPECT_FALSE(message.HasExtension(unittest::oneof_uint32_extension_lite));
+ EXPECT_FALSE(
+ message.GetExtension(unittest::oneof_nested_message_extension_lite)
+ .has_bb());
+ EXPECT_FALSE(message.HasExtension(unittest::oneof_string_extension_lite));
+ EXPECT_FALSE(message.HasExtension(unittest::oneof_bytes_extension_lite));
+}
+
+// -------------------------------------------------------------------
+
+void TestUtilLite::ExpectRepeatedExtensionsModified(
+ const unittest::TestAllExtensionsLite& message) {
+ // ModifyRepeatedFields only sets the second repeated element of each
+ // field. In addition to verifying this, we also verify that the first
+ // element and size were *not* modified.
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_int32_extension_lite));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_int64_extension_lite));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_uint32_extension_lite));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_uint64_extension_lite));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_sint32_extension_lite));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_sint64_extension_lite));
+ ASSERT_EQ(2,
+ message.ExtensionSize(unittest::repeated_fixed32_extension_lite));
+ ASSERT_EQ(2,
+ message.ExtensionSize(unittest::repeated_fixed64_extension_lite));
+ ASSERT_EQ(2,
+ message.ExtensionSize(unittest::repeated_sfixed32_extension_lite));
+ ASSERT_EQ(2,
+ message.ExtensionSize(unittest::repeated_sfixed64_extension_lite));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_float_extension_lite));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_double_extension_lite));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_bool_extension_lite));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_string_extension_lite));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_bytes_extension_lite));
+
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeatedgroup_extension_lite));
+ ASSERT_EQ(2, message.ExtensionSize(
+ unittest::repeated_nested_message_extension_lite));
+ ASSERT_EQ(2, message.ExtensionSize(
+ unittest::repeated_foreign_message_extension_lite));
+ ASSERT_EQ(2, message.ExtensionSize(
+ unittest::repeated_import_message_extension_lite));
+ ASSERT_EQ(
+ 2, message.ExtensionSize(unittest::repeated_lazy_message_extension_lite));
+ ASSERT_EQ(
+ 2, message.ExtensionSize(unittest::repeated_nested_enum_extension_lite));
+ ASSERT_EQ(
+ 2, message.ExtensionSize(unittest::repeated_foreign_enum_extension_lite));
+ ASSERT_EQ(
+ 2, message.ExtensionSize(unittest::repeated_import_enum_extension_lite));
+
+
+ EXPECT_EQ(201,
+ message.GetExtension(unittest::repeated_int32_extension_lite, 0));
+ EXPECT_EQ(202,
+ message.GetExtension(unittest::repeated_int64_extension_lite, 0));
+ EXPECT_EQ(203,
+ message.GetExtension(unittest::repeated_uint32_extension_lite, 0));
+ EXPECT_EQ(204,
+ message.GetExtension(unittest::repeated_uint64_extension_lite, 0));
+ EXPECT_EQ(205,
+ message.GetExtension(unittest::repeated_sint32_extension_lite, 0));
+ EXPECT_EQ(206,
+ message.GetExtension(unittest::repeated_sint64_extension_lite, 0));
+ EXPECT_EQ(207,
+ message.GetExtension(unittest::repeated_fixed32_extension_lite, 0));
+ EXPECT_EQ(208,
+ message.GetExtension(unittest::repeated_fixed64_extension_lite, 0));
+ EXPECT_EQ(
+ 209, message.GetExtension(unittest::repeated_sfixed32_extension_lite, 0));
+ EXPECT_EQ(
+ 210, message.GetExtension(unittest::repeated_sfixed64_extension_lite, 0));
+ EXPECT_EQ(211,
+ message.GetExtension(unittest::repeated_float_extension_lite, 0));
+ EXPECT_EQ(212,
+ message.GetExtension(unittest::repeated_double_extension_lite, 0));
+ EXPECT_EQ(true,
+ message.GetExtension(unittest::repeated_bool_extension_lite, 0));
+ EXPECT_EQ("215",
+ message.GetExtension(unittest::repeated_string_extension_lite, 0));
+ EXPECT_EQ("216",
+ message.GetExtension(unittest::repeated_bytes_extension_lite, 0));
+
+ EXPECT_EQ(
+ 217, message.GetExtension(unittest::repeatedgroup_extension_lite, 0).a());
+ EXPECT_EQ(
+ 218,
+ message.GetExtension(unittest::repeated_nested_message_extension_lite, 0)
+ .bb());
+ EXPECT_EQ(
+ 219,
+ message.GetExtension(unittest::repeated_foreign_message_extension_lite, 0)
+ .c());
+ EXPECT_EQ(
+ 220,
+ message.GetExtension(unittest::repeated_import_message_extension_lite, 0)
+ .d());
+ EXPECT_EQ(
+ 227,
+ message.GetExtension(unittest::repeated_lazy_message_extension_lite, 0)
+ .bb());
+
+ EXPECT_EQ(
+ unittest::TestAllTypesLite::BAR,
+ message.GetExtension(unittest::repeated_nested_enum_extension_lite, 0));
+ EXPECT_EQ(
+ unittest::FOREIGN_LITE_BAR,
+ message.GetExtension(unittest::repeated_foreign_enum_extension_lite, 0));
+ EXPECT_EQ(
+ unittest_import::IMPORT_LITE_BAR,
+ message.GetExtension(unittest::repeated_import_enum_extension_lite, 0));
+
+
+ // Actually verify the second (modified) elements now.
+ EXPECT_EQ(501,
+ message.GetExtension(unittest::repeated_int32_extension_lite, 1));
+ EXPECT_EQ(502,
+ message.GetExtension(unittest::repeated_int64_extension_lite, 1));
+ EXPECT_EQ(503,
+ message.GetExtension(unittest::repeated_uint32_extension_lite, 1));
+ EXPECT_EQ(504,
+ message.GetExtension(unittest::repeated_uint64_extension_lite, 1));
+ EXPECT_EQ(505,
+ message.GetExtension(unittest::repeated_sint32_extension_lite, 1));
+ EXPECT_EQ(506,
+ message.GetExtension(unittest::repeated_sint64_extension_lite, 1));
+ EXPECT_EQ(507,
+ message.GetExtension(unittest::repeated_fixed32_extension_lite, 1));
+ EXPECT_EQ(508,
+ message.GetExtension(unittest::repeated_fixed64_extension_lite, 1));
+ EXPECT_EQ(
+ 509, message.GetExtension(unittest::repeated_sfixed32_extension_lite, 1));
+ EXPECT_EQ(
+ 510, message.GetExtension(unittest::repeated_sfixed64_extension_lite, 1));
+ EXPECT_EQ(511,
+ message.GetExtension(unittest::repeated_float_extension_lite, 1));
+ EXPECT_EQ(512,
+ message.GetExtension(unittest::repeated_double_extension_lite, 1));
+ EXPECT_EQ(true,
+ message.GetExtension(unittest::repeated_bool_extension_lite, 1));
+ EXPECT_EQ("515",
+ message.GetExtension(unittest::repeated_string_extension_lite, 1));
+ EXPECT_EQ("516",
+ message.GetExtension(unittest::repeated_bytes_extension_lite, 1));
+
+ EXPECT_EQ(
+ 517, message.GetExtension(unittest::repeatedgroup_extension_lite, 1).a());
+ EXPECT_EQ(
+ 518,
+ message.GetExtension(unittest::repeated_nested_message_extension_lite, 1)
+ .bb());
+ EXPECT_EQ(
+ 519,
+ message.GetExtension(unittest::repeated_foreign_message_extension_lite, 1)
+ .c());
+ EXPECT_EQ(
+ 520,
+ message.GetExtension(unittest::repeated_import_message_extension_lite, 1)
+ .d());
+ EXPECT_EQ(
+ 527,
+ message.GetExtension(unittest::repeated_lazy_message_extension_lite, 1)
+ .bb());
+
+ EXPECT_EQ(
+ unittest::TestAllTypesLite::FOO,
+ message.GetExtension(unittest::repeated_nested_enum_extension_lite, 1));
+ EXPECT_EQ(
+ unittest::FOREIGN_LITE_FOO,
+ message.GetExtension(unittest::repeated_foreign_enum_extension_lite, 1));
+ EXPECT_EQ(
+ unittest_import::IMPORT_LITE_FOO,
+ message.GetExtension(unittest::repeated_import_enum_extension_lite, 1));
+
+}
+
+// -------------------------------------------------------------------
+
+void TestUtilLite::SetPackedExtensions(
+ unittest::TestPackedExtensionsLite* message) {
+ message->AddExtension(unittest::packed_int32_extension_lite, 601);
+ message->AddExtension(unittest::packed_int64_extension_lite, 602);
+ message->AddExtension(unittest::packed_uint32_extension_lite, 603);
+ message->AddExtension(unittest::packed_uint64_extension_lite, 604);
+ message->AddExtension(unittest::packed_sint32_extension_lite, 605);
+ message->AddExtension(unittest::packed_sint64_extension_lite, 606);
+ message->AddExtension(unittest::packed_fixed32_extension_lite, 607);
+ message->AddExtension(unittest::packed_fixed64_extension_lite, 608);
+ message->AddExtension(unittest::packed_sfixed32_extension_lite, 609);
+ message->AddExtension(unittest::packed_sfixed64_extension_lite, 610);
+ message->AddExtension(unittest::packed_float_extension_lite, 611);
+ message->AddExtension(unittest::packed_double_extension_lite, 612);
+ message->AddExtension(unittest::packed_bool_extension_lite, true);
+ message->AddExtension(unittest::packed_enum_extension_lite,
+ unittest::FOREIGN_LITE_BAR);
+ // add a second one of each field
+ message->AddExtension(unittest::packed_int32_extension_lite, 701);
+ message->AddExtension(unittest::packed_int64_extension_lite, 702);
+ message->AddExtension(unittest::packed_uint32_extension_lite, 703);
+ message->AddExtension(unittest::packed_uint64_extension_lite, 704);
+ message->AddExtension(unittest::packed_sint32_extension_lite, 705);
+ message->AddExtension(unittest::packed_sint64_extension_lite, 706);
+ message->AddExtension(unittest::packed_fixed32_extension_lite, 707);
+ message->AddExtension(unittest::packed_fixed64_extension_lite, 708);
+ message->AddExtension(unittest::packed_sfixed32_extension_lite, 709);
+ message->AddExtension(unittest::packed_sfixed64_extension_lite, 710);
+ message->AddExtension(unittest::packed_float_extension_lite, 711);
+ message->AddExtension(unittest::packed_double_extension_lite, 712);
+ message->AddExtension(unittest::packed_bool_extension_lite, false);
+ message->AddExtension(unittest::packed_enum_extension_lite,
+ unittest::FOREIGN_LITE_BAZ);
+}
+
+// -------------------------------------------------------------------
+
+void TestUtilLite::ModifyPackedExtensions(
+ unittest::TestPackedExtensionsLite* message) {
+ message->SetExtension(unittest::packed_int32_extension_lite, 1, 801);
+ message->SetExtension(unittest::packed_int64_extension_lite, 1, 802);
+ message->SetExtension(unittest::packed_uint32_extension_lite, 1, 803);
+ message->SetExtension(unittest::packed_uint64_extension_lite, 1, 804);
+ message->SetExtension(unittest::packed_sint32_extension_lite, 1, 805);
+ message->SetExtension(unittest::packed_sint64_extension_lite, 1, 806);
+ message->SetExtension(unittest::packed_fixed32_extension_lite, 1, 807);
+ message->SetExtension(unittest::packed_fixed64_extension_lite, 1, 808);
+ message->SetExtension(unittest::packed_sfixed32_extension_lite, 1, 809);
+ message->SetExtension(unittest::packed_sfixed64_extension_lite, 1, 810);
+ message->SetExtension(unittest::packed_float_extension_lite, 1, 811);
+ message->SetExtension(unittest::packed_double_extension_lite, 1, 812);
+ message->SetExtension(unittest::packed_bool_extension_lite, 1, true);
+ message->SetExtension(unittest::packed_enum_extension_lite, 1,
+ unittest::FOREIGN_LITE_FOO);
+}
+
+// -------------------------------------------------------------------
+
+void TestUtilLite::ExpectPackedExtensionsSet(
+ const unittest::TestPackedExtensionsLite& message) {
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_int32_extension_lite));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_int64_extension_lite));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_uint32_extension_lite));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_uint64_extension_lite));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_sint32_extension_lite));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_sint64_extension_lite));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_fixed32_extension_lite));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_fixed64_extension_lite));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_sfixed32_extension_lite));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_sfixed64_extension_lite));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_float_extension_lite));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_double_extension_lite));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_bool_extension_lite));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_enum_extension_lite));
+
+ EXPECT_EQ(601,
+ message.GetExtension(unittest::packed_int32_extension_lite, 0));
+ EXPECT_EQ(602,
+ message.GetExtension(unittest::packed_int64_extension_lite, 0));
+ EXPECT_EQ(603,
+ message.GetExtension(unittest::packed_uint32_extension_lite, 0));
+ EXPECT_EQ(604,
+ message.GetExtension(unittest::packed_uint64_extension_lite, 0));
+ EXPECT_EQ(605,
+ message.GetExtension(unittest::packed_sint32_extension_lite, 0));
+ EXPECT_EQ(606,
+ message.GetExtension(unittest::packed_sint64_extension_lite, 0));
+ EXPECT_EQ(607,
+ message.GetExtension(unittest::packed_fixed32_extension_lite, 0));
+ EXPECT_EQ(608,
+ message.GetExtension(unittest::packed_fixed64_extension_lite, 0));
+ EXPECT_EQ(609,
+ message.GetExtension(unittest::packed_sfixed32_extension_lite, 0));
+ EXPECT_EQ(610,
+ message.GetExtension(unittest::packed_sfixed64_extension_lite, 0));
+ EXPECT_EQ(611,
+ message.GetExtension(unittest::packed_float_extension_lite, 0));
+ EXPECT_EQ(612,
+ message.GetExtension(unittest::packed_double_extension_lite, 0));
+ EXPECT_EQ(true,
+ message.GetExtension(unittest::packed_bool_extension_lite, 0));
+ EXPECT_EQ(unittest::FOREIGN_LITE_BAR,
+ message.GetExtension(unittest::packed_enum_extension_lite, 0));
+ EXPECT_EQ(701,
+ message.GetExtension(unittest::packed_int32_extension_lite, 1));
+ EXPECT_EQ(702,
+ message.GetExtension(unittest::packed_int64_extension_lite, 1));
+ EXPECT_EQ(703,
+ message.GetExtension(unittest::packed_uint32_extension_lite, 1));
+ EXPECT_EQ(704,
+ message.GetExtension(unittest::packed_uint64_extension_lite, 1));
+ EXPECT_EQ(705,
+ message.GetExtension(unittest::packed_sint32_extension_lite, 1));
+ EXPECT_EQ(706,
+ message.GetExtension(unittest::packed_sint64_extension_lite, 1));
+ EXPECT_EQ(707,
+ message.GetExtension(unittest::packed_fixed32_extension_lite, 1));
+ EXPECT_EQ(708,
+ message.GetExtension(unittest::packed_fixed64_extension_lite, 1));
+ EXPECT_EQ(709,
+ message.GetExtension(unittest::packed_sfixed32_extension_lite, 1));
+ EXPECT_EQ(710,
+ message.GetExtension(unittest::packed_sfixed64_extension_lite, 1));
+ EXPECT_EQ(711,
+ message.GetExtension(unittest::packed_float_extension_lite, 1));
+ EXPECT_EQ(712,
+ message.GetExtension(unittest::packed_double_extension_lite, 1));
+ EXPECT_EQ(false,
+ message.GetExtension(unittest::packed_bool_extension_lite, 1));
+ EXPECT_EQ(unittest::FOREIGN_LITE_BAZ,
+ message.GetExtension(unittest::packed_enum_extension_lite, 1));
+}
+
+// -------------------------------------------------------------------
+
+void TestUtilLite::ExpectPackedExtensionsClear(
+ const unittest::TestPackedExtensionsLite& message) {
+ EXPECT_EQ(0, message.ExtensionSize(unittest::packed_int32_extension_lite));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::packed_int64_extension_lite));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::packed_uint32_extension_lite));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::packed_uint64_extension_lite));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::packed_sint32_extension_lite));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::packed_sint64_extension_lite));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::packed_fixed32_extension_lite));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::packed_fixed64_extension_lite));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::packed_sfixed32_extension_lite));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::packed_sfixed64_extension_lite));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::packed_float_extension_lite));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::packed_double_extension_lite));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::packed_bool_extension_lite));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::packed_enum_extension_lite));
+}
+
+// -------------------------------------------------------------------
+
+void TestUtilLite::ExpectPackedExtensionsModified(
+ const unittest::TestPackedExtensionsLite& message) {
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_int32_extension_lite));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_int64_extension_lite));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_uint32_extension_lite));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_uint64_extension_lite));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_sint32_extension_lite));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_sint64_extension_lite));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_fixed32_extension_lite));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_fixed64_extension_lite));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_sfixed32_extension_lite));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_sfixed64_extension_lite));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_float_extension_lite));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_double_extension_lite));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_bool_extension_lite));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_enum_extension_lite));
+ EXPECT_EQ(601,
+ message.GetExtension(unittest::packed_int32_extension_lite, 0));
+ EXPECT_EQ(602,
+ message.GetExtension(unittest::packed_int64_extension_lite, 0));
+ EXPECT_EQ(603,
+ message.GetExtension(unittest::packed_uint32_extension_lite, 0));
+ EXPECT_EQ(604,
+ message.GetExtension(unittest::packed_uint64_extension_lite, 0));
+ EXPECT_EQ(605,
+ message.GetExtension(unittest::packed_sint32_extension_lite, 0));
+ EXPECT_EQ(606,
+ message.GetExtension(unittest::packed_sint64_extension_lite, 0));
+ EXPECT_EQ(607,
+ message.GetExtension(unittest::packed_fixed32_extension_lite, 0));
+ EXPECT_EQ(608,
+ message.GetExtension(unittest::packed_fixed64_extension_lite, 0));
+ EXPECT_EQ(609,
+ message.GetExtension(unittest::packed_sfixed32_extension_lite, 0));
+ EXPECT_EQ(610,
+ message.GetExtension(unittest::packed_sfixed64_extension_lite, 0));
+ EXPECT_EQ(611,
+ message.GetExtension(unittest::packed_float_extension_lite, 0));
+ EXPECT_EQ(612,
+ message.GetExtension(unittest::packed_double_extension_lite, 0));
+ EXPECT_EQ(true,
+ message.GetExtension(unittest::packed_bool_extension_lite, 0));
+ EXPECT_EQ(unittest::FOREIGN_LITE_BAR,
+ message.GetExtension(unittest::packed_enum_extension_lite, 0));
+
+ // Actually verify the second (modified) elements now.
+ EXPECT_EQ(801,
+ message.GetExtension(unittest::packed_int32_extension_lite, 1));
+ EXPECT_EQ(802,
+ message.GetExtension(unittest::packed_int64_extension_lite, 1));
+ EXPECT_EQ(803,
+ message.GetExtension(unittest::packed_uint32_extension_lite, 1));
+ EXPECT_EQ(804,
+ message.GetExtension(unittest::packed_uint64_extension_lite, 1));
+ EXPECT_EQ(805,
+ message.GetExtension(unittest::packed_sint32_extension_lite, 1));
+ EXPECT_EQ(806,
+ message.GetExtension(unittest::packed_sint64_extension_lite, 1));
+ EXPECT_EQ(807,
+ message.GetExtension(unittest::packed_fixed32_extension_lite, 1));
+ EXPECT_EQ(808,
+ message.GetExtension(unittest::packed_fixed64_extension_lite, 1));
+ EXPECT_EQ(809,
+ message.GetExtension(unittest::packed_sfixed32_extension_lite, 1));
+ EXPECT_EQ(810,
+ message.GetExtension(unittest::packed_sfixed64_extension_lite, 1));
+ EXPECT_EQ(811,
+ message.GetExtension(unittest::packed_float_extension_lite, 1));
+ EXPECT_EQ(812,
+ message.GetExtension(unittest::packed_double_extension_lite, 1));
+ EXPECT_EQ(true,
+ message.GetExtension(unittest::packed_bool_extension_lite, 1));
+ EXPECT_EQ(unittest::FOREIGN_LITE_FOO,
+ message.GetExtension(unittest::packed_enum_extension_lite, 1));
+}
+
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/test_util_lite.h b/NorthstarDedicatedTest/include/protobuf/test_util_lite.h
new file mode 100644
index 00000000..79d42beb
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/test_util_lite.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.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#ifndef GOOGLE_PROTOBUF_TEST_UTIL_LITE_H__
+#define GOOGLE_PROTOBUF_TEST_UTIL_LITE_H__
+
+#include <unittest_lite.pb.h>
+
+namespace google {
+namespace protobuf {
+
+namespace unittest = protobuf_unittest;
+namespace unittest_import = protobuf_unittest_import;
+
+class TestUtilLite {
+ public:
+ // Set every field in the message to a unique value.
+ static void SetAllFields(unittest::TestAllTypesLite* message);
+ static void SetAllExtensions(unittest::TestAllExtensionsLite* message);
+ static void SetPackedFields(unittest::TestPackedTypesLite* message);
+ static void SetPackedExtensions(unittest::TestPackedExtensionsLite* message);
+
+ // Use the repeated versions of the set_*() accessors to modify all the
+ // repeated fields of the message (which should already have been
+ // initialized with Set*Fields()). Set*Fields() itself only tests
+ // the add_*() accessors.
+ static void ModifyRepeatedFields(unittest::TestAllTypesLite* message);
+ static void ModifyRepeatedExtensions(
+ unittest::TestAllExtensionsLite* message);
+ static void ModifyPackedFields(unittest::TestPackedTypesLite* message);
+ static void ModifyPackedExtensions(
+ unittest::TestPackedExtensionsLite* message);
+
+ // Check that all fields have the values that they should have after
+ // Set*Fields() is called.
+ static void ExpectAllFieldsSet(const unittest::TestAllTypesLite& message);
+ static void ExpectAllExtensionsSet(
+ const unittest::TestAllExtensionsLite& message);
+ static void ExpectPackedFieldsSet(
+ const unittest::TestPackedTypesLite& message);
+ static void ExpectPackedExtensionsSet(
+ const unittest::TestPackedExtensionsLite& message);
+
+ // Expect that the message is modified as would be expected from
+ // Modify*Fields().
+ static void ExpectRepeatedFieldsModified(
+ const unittest::TestAllTypesLite& message);
+ static void ExpectRepeatedExtensionsModified(
+ const unittest::TestAllExtensionsLite& message);
+ static void ExpectPackedFieldsModified(
+ const unittest::TestPackedTypesLite& message);
+ static void ExpectPackedExtensionsModified(
+ const unittest::TestPackedExtensionsLite& message);
+
+ // Check that all fields have their default values.
+ static void ExpectClear(const unittest::TestAllTypesLite& message);
+ static void ExpectExtensionsClear(
+ const unittest::TestAllExtensionsLite& message);
+ static void ExpectPackedClear(const unittest::TestPackedTypesLite& message);
+ static void ExpectPackedExtensionsClear(
+ const unittest::TestPackedExtensionsLite& message);
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(TestUtilLite);
+};
+
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_TEST_UTIL_LITE_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/testdata/bad_utf8_string b/NorthstarDedicatedTest/include/protobuf/testdata/bad_utf8_string
new file mode 100644
index 00000000..a1337ec6
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/testdata/bad_utf8_string
@@ -0,0 +1 @@
+rÿ \ No newline at end of file
diff --git a/NorthstarDedicatedTest/include/protobuf/testdata/golden_message b/NorthstarDedicatedTest/include/protobuf/testdata/golden_message
new file mode 100644
index 00000000..0b7e6552
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/testdata/golden_message
Binary files differ
diff --git a/NorthstarDedicatedTest/include/protobuf/testdata/golden_message_maps b/NorthstarDedicatedTest/include/protobuf/testdata/golden_message_maps
new file mode 100644
index 00000000..c70a4d7c
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/testdata/golden_message_maps
Binary files differ
diff --git a/NorthstarDedicatedTest/include/protobuf/testdata/golden_message_oneof_implemented b/NorthstarDedicatedTest/include/protobuf/testdata/golden_message_oneof_implemented
new file mode 100644
index 00000000..b48c8985
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/testdata/golden_message_oneof_implemented
Binary files differ
diff --git a/NorthstarDedicatedTest/include/protobuf/testdata/golden_message_proto3 b/NorthstarDedicatedTest/include/protobuf/testdata/golden_message_proto3
new file mode 100644
index 00000000..bd646a0d
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/testdata/golden_message_proto3
Binary files differ
diff --git a/NorthstarDedicatedTest/include/protobuf/testdata/golden_packed_fields_message b/NorthstarDedicatedTest/include/protobuf/testdata/golden_packed_fields_message
new file mode 100644
index 00000000..ee28d388
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/testdata/golden_packed_fields_message
Binary files differ
diff --git a/NorthstarDedicatedTest/include/protobuf/testdata/map_test_data.txt b/NorthstarDedicatedTest/include/protobuf/testdata/map_test_data.txt
new file mode 100644
index 00000000..bc272321
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/testdata/map_test_data.txt
@@ -0,0 +1,140 @@
+map_int32_int32 {
+ key: 0
+ value: 0
+}
+map_int32_int32 {
+ key: 1
+ value: 1
+}
+map_int64_int64 {
+ key: 0
+ value: 0
+}
+map_int64_int64 {
+ key: 1
+ value: 1
+}
+map_uint32_uint32 {
+ key: 0
+ value: 0
+}
+map_uint32_uint32 {
+ key: 1
+ value: 1
+}
+map_uint64_uint64 {
+ key: 0
+ value: 0
+}
+map_uint64_uint64 {
+ key: 1
+ value: 1
+}
+map_sint32_sint32 {
+ key: 0
+ value: 0
+}
+map_sint32_sint32 {
+ key: 1
+ value: 1
+}
+map_sint64_sint64 {
+ key: 0
+ value: 0
+}
+map_sint64_sint64 {
+ key: 1
+ value: 1
+}
+map_fixed32_fixed32 {
+ key: 0
+ value: 0
+}
+map_fixed32_fixed32 {
+ key: 1
+ value: 1
+}
+map_fixed64_fixed64 {
+ key: 0
+ value: 0
+}
+map_fixed64_fixed64 {
+ key: 1
+ value: 1
+}
+map_sfixed32_sfixed32 {
+ key: 0
+ value: 0
+}
+map_sfixed32_sfixed32 {
+ key: 1
+ value: 1
+}
+map_sfixed64_sfixed64 {
+ key: 0
+ value: 0
+}
+map_sfixed64_sfixed64 {
+ key: 1
+ value: 1
+}
+map_int32_float {
+ key: 0
+ value: 0
+}
+map_int32_float {
+ key: 1
+ value: 1
+}
+map_int32_double {
+ key: 0
+ value: 0
+}
+map_int32_double {
+ key: 1
+ value: 1
+}
+map_bool_bool {
+ key: false
+ value: false
+}
+map_bool_bool {
+ key: true
+ value: true
+}
+map_string_string {
+ key: "0"
+ value: "0"
+}
+map_string_string {
+ key: "1"
+ value: "1"
+}
+map_int32_bytes {
+ key: 0
+ value: "0"
+}
+map_int32_bytes {
+ key: 1
+ value: "1"
+}
+map_int32_enum {
+ key: 0
+ value: MAP_ENUM_BAR
+}
+map_int32_enum {
+ key: 1
+ value: MAP_ENUM_BAZ
+}
+map_int32_foreign_message {
+ key: 0
+ value {
+ c: 0
+ }
+}
+map_int32_foreign_message {
+ key: 1
+ value {
+ c: 1
+ }
+}
diff --git a/NorthstarDedicatedTest/include/protobuf/testdata/text_format_unittest_data.txt b/NorthstarDedicatedTest/include/protobuf/testdata/text_format_unittest_data.txt
new file mode 100644
index 00000000..7a874b54
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/testdata/text_format_unittest_data.txt
@@ -0,0 +1,134 @@
+optional_int32: 101
+optional_int64: 102
+optional_uint32: 103
+optional_uint64: 104
+optional_sint32: 105
+optional_sint64: 106
+optional_fixed32: 107
+optional_fixed64: 108
+optional_sfixed32: 109
+optional_sfixed64: 110
+optional_float: 111
+optional_double: 112
+optional_bool: true
+optional_string: "115"
+optional_bytes: "116"
+OptionalGroup {
+ a: 117
+}
+optional_nested_message {
+ bb: 118
+}
+optional_foreign_message {
+ c: 119
+}
+optional_import_message {
+ d: 120
+}
+optional_nested_enum: BAZ
+optional_foreign_enum: FOREIGN_BAZ
+optional_import_enum: IMPORT_BAZ
+optional_string_piece: "124"
+optional_cord: "125"
+optional_public_import_message {
+ e: 126
+}
+optional_lazy_message {
+ bb: 127
+}
+repeated_int32: 201
+repeated_int32: 301
+repeated_int64: 202
+repeated_int64: 302
+repeated_uint32: 203
+repeated_uint32: 303
+repeated_uint64: 204
+repeated_uint64: 304
+repeated_sint32: 205
+repeated_sint32: 305
+repeated_sint64: 206
+repeated_sint64: 306
+repeated_fixed32: 207
+repeated_fixed32: 307
+repeated_fixed64: 208
+repeated_fixed64: 308
+repeated_sfixed32: 209
+repeated_sfixed32: 309
+repeated_sfixed64: 210
+repeated_sfixed64: 310
+repeated_float: 211
+repeated_float: 311
+repeated_double: 212
+repeated_double: 312
+repeated_bool: true
+repeated_bool: false
+repeated_string: "215"
+repeated_string: "315"
+repeated_bytes: "216"
+repeated_bytes: "316"
+RepeatedGroup {
+ a: 217
+}
+RepeatedGroup {
+ a: 317
+}
+repeated_nested_message {
+ bb: 218
+}
+repeated_nested_message {
+ bb: 318
+}
+repeated_foreign_message {
+ c: 219
+}
+repeated_foreign_message {
+ c: 319
+}
+repeated_import_message {
+ d: 220
+}
+repeated_import_message {
+ d: 320
+}
+repeated_nested_enum: BAR
+repeated_nested_enum: BAZ
+repeated_foreign_enum: FOREIGN_BAR
+repeated_foreign_enum: FOREIGN_BAZ
+repeated_import_enum: IMPORT_BAR
+repeated_import_enum: IMPORT_BAZ
+repeated_string_piece: "224"
+repeated_string_piece: "324"
+repeated_cord: "225"
+repeated_cord: "325"
+repeated_lazy_message {
+ bb: 227
+}
+repeated_lazy_message {
+ bb: 327
+}
+default_int32: 401
+default_int64: 402
+default_uint32: 403
+default_uint64: 404
+default_sint32: 405
+default_sint64: 406
+default_fixed32: 407
+default_fixed64: 408
+default_sfixed32: 409
+default_sfixed64: 410
+default_float: 411
+default_double: 412
+default_bool: false
+default_string: "415"
+default_bytes: "416"
+default_nested_enum: FOO
+default_foreign_enum: FOREIGN_FOO
+default_import_enum: IMPORT_FOO
+default_string_piece: "424"
+default_cord: "425"
+oneof_uint32: 601
+oneof_nested_message {
+ bb: 602
+}
+oneof_string: "603"
+oneof_bytes: "604"
diff --git a/NorthstarDedicatedTest/include/protobuf/testdata/text_format_unittest_data_oneof_implemented.txt b/NorthstarDedicatedTest/include/protobuf/testdata/text_format_unittest_data_oneof_implemented.txt
new file mode 100644
index 00000000..ec95e1e8
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/testdata/text_format_unittest_data_oneof_implemented.txt
@@ -0,0 +1,129 @@
+optional_int32: 101
+optional_int64: 102
+optional_uint32: 103
+optional_uint64: 104
+optional_sint32: 105
+optional_sint64: 106
+optional_fixed32: 107
+optional_fixed64: 108
+optional_sfixed32: 109
+optional_sfixed64: 110
+optional_float: 111
+optional_double: 112
+optional_bool: true
+optional_string: "115"
+optional_bytes: "116"
+OptionalGroup {
+ a: 117
+}
+optional_nested_message {
+ bb: 118
+}
+optional_foreign_message {
+ c: 119
+}
+optional_import_message {
+ d: 120
+}
+optional_nested_enum: BAZ
+optional_foreign_enum: FOREIGN_BAZ
+optional_import_enum: IMPORT_BAZ
+optional_string_piece: "124"
+optional_cord: "125"
+optional_public_import_message {
+ e: 126
+}
+optional_lazy_message {
+ bb: 127
+}
+repeated_int32: 201
+repeated_int32: 301
+repeated_int64: 202
+repeated_int64: 302
+repeated_uint32: 203
+repeated_uint32: 303
+repeated_uint64: 204
+repeated_uint64: 304
+repeated_sint32: 205
+repeated_sint32: 305
+repeated_sint64: 206
+repeated_sint64: 306
+repeated_fixed32: 207
+repeated_fixed32: 307
+repeated_fixed64: 208
+repeated_fixed64: 308
+repeated_sfixed32: 209
+repeated_sfixed32: 309
+repeated_sfixed64: 210
+repeated_sfixed64: 310
+repeated_float: 211
+repeated_float: 311
+repeated_double: 212
+repeated_double: 312
+repeated_bool: true
+repeated_bool: false
+repeated_string: "215"
+repeated_string: "315"
+repeated_bytes: "216"
+repeated_bytes: "316"
+RepeatedGroup {
+ a: 217
+}
+RepeatedGroup {
+ a: 317
+}
+repeated_nested_message {
+ bb: 218
+}
+repeated_nested_message {
+ bb: 318
+}
+repeated_foreign_message {
+ c: 219
+}
+repeated_foreign_message {
+ c: 319
+}
+repeated_import_message {
+ d: 220
+}
+repeated_import_message {
+ d: 320
+}
+repeated_nested_enum: BAR
+repeated_nested_enum: BAZ
+repeated_foreign_enum: FOREIGN_BAR
+repeated_foreign_enum: FOREIGN_BAZ
+repeated_import_enum: IMPORT_BAR
+repeated_import_enum: IMPORT_BAZ
+repeated_string_piece: "224"
+repeated_string_piece: "324"
+repeated_cord: "225"
+repeated_cord: "325"
+repeated_lazy_message {
+ bb: 227
+}
+repeated_lazy_message {
+ bb: 327
+}
+default_int32: 401
+default_int64: 402
+default_uint32: 403
+default_uint64: 404
+default_sint32: 405
+default_sint64: 406
+default_fixed32: 407
+default_fixed64: 408
+default_sfixed32: 409
+default_sfixed64: 410
+default_float: 411
+default_double: 412
+default_bool: false
+default_string: "415"
+default_bytes: "416"
+default_nested_enum: FOO
+default_foreign_enum: FOREIGN_FOO
+default_import_enum: IMPORT_FOO
+default_string_piece: "424"
+default_cord: "425"
+oneof_bytes: "604"
diff --git a/NorthstarDedicatedTest/include/protobuf/testdata/text_format_unittest_data_pointy.txt b/NorthstarDedicatedTest/include/protobuf/testdata/text_format_unittest_data_pointy.txt
new file mode 100644
index 00000000..e1011ebf
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/testdata/text_format_unittest_data_pointy.txt
@@ -0,0 +1,134 @@
+optional_int32: 101
+optional_int64: 102
+optional_uint32: 103
+optional_uint64: 104
+optional_sint32: 105
+optional_sint64: 106
+optional_fixed32: 107
+optional_fixed64: 108
+optional_sfixed32: 109
+optional_sfixed64: 110
+optional_float: 111
+optional_double: 112
+optional_bool: true
+optional_string: "115"
+optional_bytes: "116"
+OptionalGroup <
+ a: 117
+>
+optional_nested_message <
+ bb: 118
+>
+optional_foreign_message <
+ c: 119
+>
+optional_import_message <
+ d: 120
+>
+optional_nested_enum: BAZ
+optional_foreign_enum: FOREIGN_BAZ
+optional_import_enum: IMPORT_BAZ
+optional_string_piece: "124"
+optional_cord: "125"
+optional_public_import_message <
+ e: 126
+>
+optional_lazy_message <
+ bb: 127
+>
+repeated_int32: 201
+repeated_int32: 301
+repeated_int64: 202
+repeated_int64: 302
+repeated_uint32: 203
+repeated_uint32: 303
+repeated_uint64: 204
+repeated_uint64: 304
+repeated_sint32: 205
+repeated_sint32: 305
+repeated_sint64: 206
+repeated_sint64: 306
+repeated_fixed32: 207
+repeated_fixed32: 307
+repeated_fixed64: 208
+repeated_fixed64: 308
+repeated_sfixed32: 209
+repeated_sfixed32: 309
+repeated_sfixed64: 210
+repeated_sfixed64: 310
+repeated_float: 211
+repeated_float: 311
+repeated_double: 212
+repeated_double: 312
+repeated_bool: true
+repeated_bool: false
+repeated_string: "215"
+repeated_string: "315"
+repeated_bytes: "216"
+repeated_bytes: "316"
+RepeatedGroup <
+ a: 217
+>
+RepeatedGroup <
+ a: 317
+>
+repeated_nested_message <
+ bb: 218
+>
+repeated_nested_message <
+ bb: 318
+>
+repeated_foreign_message <
+ c: 219
+>
+repeated_foreign_message <
+ c: 319
+>
+repeated_import_message <
+ d: 220
+>
+repeated_import_message <
+ d: 320
+>
+repeated_nested_enum: BAR
+repeated_nested_enum: BAZ
+repeated_foreign_enum: FOREIGN_BAR
+repeated_foreign_enum: FOREIGN_BAZ
+repeated_import_enum: IMPORT_BAR
+repeated_import_enum: IMPORT_BAZ
+repeated_string_piece: "224"
+repeated_string_piece: "324"
+repeated_cord: "225"
+repeated_cord: "325"
+repeated_lazy_message <
+ bb: 227
+>
+repeated_lazy_message <
+ bb: 327
+>
+default_int32: 401
+default_int64: 402
+default_uint32: 403
+default_uint64: 404
+default_sint32: 405
+default_sint64: 406
+default_fixed32: 407
+default_fixed64: 408
+default_sfixed32: 409
+default_sfixed64: 410
+default_float: 411
+default_double: 412
+default_bool: false
+default_string: "415"
+default_bytes: "416"
+default_nested_enum: FOO
+default_foreign_enum: FOREIGN_FOO
+default_import_enum: IMPORT_FOO
+default_string_piece: "424"
+default_cord: "425"
+oneof_uint32: 601
+oneof_nested_message <
+ bb: 602
+>
+oneof_string: "603"
+oneof_bytes: "604"
diff --git a/NorthstarDedicatedTest/include/protobuf/testdata/text_format_unittest_data_pointy_oneof.txt b/NorthstarDedicatedTest/include/protobuf/testdata/text_format_unittest_data_pointy_oneof.txt
new file mode 100644
index 00000000..95109f62
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/testdata/text_format_unittest_data_pointy_oneof.txt
@@ -0,0 +1,129 @@
+optional_int32: 101
+optional_int64: 102
+optional_uint32: 103
+optional_uint64: 104
+optional_sint32: 105
+optional_sint64: 106
+optional_fixed32: 107
+optional_fixed64: 108
+optional_sfixed32: 109
+optional_sfixed64: 110
+optional_float: 111
+optional_double: 112
+optional_bool: true
+optional_string: "115"
+optional_bytes: "116"
+OptionalGroup <
+ a: 117
+>
+optional_nested_message <
+ bb: 118
+>
+optional_foreign_message <
+ c: 119
+>
+optional_import_message <
+ d: 120
+>
+optional_nested_enum: BAZ
+optional_foreign_enum: FOREIGN_BAZ
+optional_import_enum: IMPORT_BAZ
+optional_string_piece: "124"
+optional_cord: "125"
+optional_public_import_message <
+ e: 126
+>
+optional_lazy_message <
+ bb: 127
+>
+repeated_int32: 201
+repeated_int32: 301
+repeated_int64: 202
+repeated_int64: 302
+repeated_uint32: 203
+repeated_uint32: 303
+repeated_uint64: 204
+repeated_uint64: 304
+repeated_sint32: 205
+repeated_sint32: 305
+repeated_sint64: 206
+repeated_sint64: 306
+repeated_fixed32: 207
+repeated_fixed32: 307
+repeated_fixed64: 208
+repeated_fixed64: 308
+repeated_sfixed32: 209
+repeated_sfixed32: 309
+repeated_sfixed64: 210
+repeated_sfixed64: 310
+repeated_float: 211
+repeated_float: 311
+repeated_double: 212
+repeated_double: 312
+repeated_bool: true
+repeated_bool: false
+repeated_string: "215"
+repeated_string: "315"
+repeated_bytes: "216"
+repeated_bytes: "316"
+RepeatedGroup <
+ a: 217
+>
+RepeatedGroup <
+ a: 317
+>
+repeated_nested_message <
+ bb: 218
+>
+repeated_nested_message <
+ bb: 318
+>
+repeated_foreign_message <
+ c: 219
+>
+repeated_foreign_message <
+ c: 319
+>
+repeated_import_message <
+ d: 220
+>
+repeated_import_message <
+ d: 320
+>
+repeated_nested_enum: BAR
+repeated_nested_enum: BAZ
+repeated_foreign_enum: FOREIGN_BAR
+repeated_foreign_enum: FOREIGN_BAZ
+repeated_import_enum: IMPORT_BAR
+repeated_import_enum: IMPORT_BAZ
+repeated_string_piece: "224"
+repeated_string_piece: "324"
+repeated_cord: "225"
+repeated_cord: "325"
+repeated_lazy_message <
+ bb: 227
+>
+repeated_lazy_message <
+ bb: 327
+>
+default_int32: 401
+default_int64: 402
+default_uint32: 403
+default_uint64: 404
+default_sint32: 405
+default_sint64: 406
+default_fixed32: 407
+default_fixed64: 408
+default_sfixed32: 409
+default_sfixed64: 410
+default_float: 411
+default_double: 412
+default_bool: false
+default_string: "415"
+default_bytes: "416"
+default_nested_enum: FOO
+default_foreign_enum: FOREIGN_FOO
+default_import_enum: IMPORT_FOO
+default_string_piece: "424"
+default_cord: "425"
+oneof_bytes: "604"
diff --git a/NorthstarDedicatedTest/include/protobuf/testdata/text_format_unittest_extensions_data.txt b/NorthstarDedicatedTest/include/protobuf/testdata/text_format_unittest_extensions_data.txt
new file mode 100644
index 00000000..8c8b1eb4
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/testdata/text_format_unittest_extensions_data.txt
@@ -0,0 +1,134 @@
+[protobuf_unittest.optional_int32_extension]: 101
+[protobuf_unittest.optional_int64_extension]: 102
+[protobuf_unittest.optional_uint32_extension]: 103
+[protobuf_unittest.optional_uint64_extension]: 104
+[protobuf_unittest.optional_sint32_extension]: 105
+[protobuf_unittest.optional_sint64_extension]: 106
+[protobuf_unittest.optional_fixed32_extension]: 107
+[protobuf_unittest.optional_fixed64_extension]: 108
+[protobuf_unittest.optional_sfixed32_extension]: 109
+[protobuf_unittest.optional_sfixed64_extension]: 110
+[protobuf_unittest.optional_float_extension]: 111
+[protobuf_unittest.optional_double_extension]: 112
+[protobuf_unittest.optional_bool_extension]: true
+[protobuf_unittest.optional_string_extension]: "115"
+[protobuf_unittest.optional_bytes_extension]: "116"
+[protobuf_unittest.optionalgroup_extension] {
+ a: 117
+}
+[protobuf_unittest.optional_nested_message_extension] {
+ bb: 118
+}
+[protobuf_unittest.optional_foreign_message_extension] {
+ c: 119
+}
+[protobuf_unittest.optional_import_message_extension] {
+ d: 120
+}
+[protobuf_unittest.optional_nested_enum_extension]: BAZ
+[protobuf_unittest.optional_foreign_enum_extension]: FOREIGN_BAZ
+[protobuf_unittest.optional_import_enum_extension]: IMPORT_BAZ
+[protobuf_unittest.optional_string_piece_extension]: "124"
+[protobuf_unittest.optional_cord_extension]: "125"
+[protobuf_unittest.optional_public_import_message_extension] {
+ e: 126
+}
+[protobuf_unittest.optional_lazy_message_extension] {
+ bb: 127
+}
+[protobuf_unittest.repeated_int32_extension]: 201
+[protobuf_unittest.repeated_int32_extension]: 301
+[protobuf_unittest.repeated_int64_extension]: 202
+[protobuf_unittest.repeated_int64_extension]: 302
+[protobuf_unittest.repeated_uint32_extension]: 203
+[protobuf_unittest.repeated_uint32_extension]: 303
+[protobuf_unittest.repeated_uint64_extension]: 204
+[protobuf_unittest.repeated_uint64_extension]: 304
+[protobuf_unittest.repeated_sint32_extension]: 205
+[protobuf_unittest.repeated_sint32_extension]: 305
+[protobuf_unittest.repeated_sint64_extension]: 206
+[protobuf_unittest.repeated_sint64_extension]: 306
+[protobuf_unittest.repeated_fixed32_extension]: 207
+[protobuf_unittest.repeated_fixed32_extension]: 307
+[protobuf_unittest.repeated_fixed64_extension]: 208
+[protobuf_unittest.repeated_fixed64_extension]: 308
+[protobuf_unittest.repeated_sfixed32_extension]: 209
+[protobuf_unittest.repeated_sfixed32_extension]: 309
+[protobuf_unittest.repeated_sfixed64_extension]: 210
+[protobuf_unittest.repeated_sfixed64_extension]: 310
+[protobuf_unittest.repeated_float_extension]: 211
+[protobuf_unittest.repeated_float_extension]: 311
+[protobuf_unittest.repeated_double_extension]: 212
+[protobuf_unittest.repeated_double_extension]: 312
+[protobuf_unittest.repeated_bool_extension]: true
+[protobuf_unittest.repeated_bool_extension]: false
+[protobuf_unittest.repeated_string_extension]: "215"
+[protobuf_unittest.repeated_string_extension]: "315"
+[protobuf_unittest.repeated_bytes_extension]: "216"
+[protobuf_unittest.repeated_bytes_extension]: "316"
+[protobuf_unittest.repeatedgroup_extension] {
+ a: 217
+}
+[protobuf_unittest.repeatedgroup_extension] {
+ a: 317
+}
+[protobuf_unittest.repeated_nested_message_extension] {
+ bb: 218
+}
+[protobuf_unittest.repeated_nested_message_extension] {
+ bb: 318
+}
+[protobuf_unittest.repeated_foreign_message_extension] {
+ c: 219
+}
+[protobuf_unittest.repeated_foreign_message_extension] {
+ c: 319
+}
+[protobuf_unittest.repeated_import_message_extension] {
+ d: 220
+}
+[protobuf_unittest.repeated_import_message_extension] {
+ d: 320
+}
+[protobuf_unittest.repeated_nested_enum_extension]: BAR
+[protobuf_unittest.repeated_nested_enum_extension]: BAZ
+[protobuf_unittest.repeated_foreign_enum_extension]: FOREIGN_BAR
+[protobuf_unittest.repeated_foreign_enum_extension]: FOREIGN_BAZ
+[protobuf_unittest.repeated_import_enum_extension]: IMPORT_BAR
+[protobuf_unittest.repeated_import_enum_extension]: IMPORT_BAZ
+[protobuf_unittest.repeated_string_piece_extension]: "224"
+[protobuf_unittest.repeated_string_piece_extension]: "324"
+[protobuf_unittest.repeated_cord_extension]: "225"
+[protobuf_unittest.repeated_cord_extension]: "325"
+[protobuf_unittest.repeated_lazy_message_extension] {
+ bb: 227
+}
+[protobuf_unittest.repeated_lazy_message_extension] {
+ bb: 327
+}
+[protobuf_unittest.default_int32_extension]: 401
+[protobuf_unittest.default_int64_extension]: 402
+[protobuf_unittest.default_uint32_extension]: 403
+[protobuf_unittest.default_uint64_extension]: 404
+[protobuf_unittest.default_sint32_extension]: 405
+[protobuf_unittest.default_sint64_extension]: 406
+[protobuf_unittest.default_fixed32_extension]: 407
+[protobuf_unittest.default_fixed64_extension]: 408
+[protobuf_unittest.default_sfixed32_extension]: 409
+[protobuf_unittest.default_sfixed64_extension]: 410
+[protobuf_unittest.default_float_extension]: 411
+[protobuf_unittest.default_double_extension]: 412
+[protobuf_unittest.default_bool_extension]: false
+[protobuf_unittest.default_string_extension]: "415"
+[protobuf_unittest.default_bytes_extension]: "416"
+[protobuf_unittest.default_nested_enum_extension]: FOO
+[protobuf_unittest.default_foreign_enum_extension]: FOREIGN_FOO
+[protobuf_unittest.default_import_enum_extension]: IMPORT_FOO
+[protobuf_unittest.default_string_piece_extension]: "424"
+[protobuf_unittest.default_cord_extension]: "425"
+[protobuf_unittest.oneof_uint32_extension]: 601
+[protobuf_unittest.oneof_nested_message_extension] {
+ bb: 602
+}
+[protobuf_unittest.oneof_string_extension]: "603"
+[protobuf_unittest.oneof_bytes_extension]: "604"
diff --git a/NorthstarDedicatedTest/include/protobuf/testdata/text_format_unittest_extensions_data_pointy.txt b/NorthstarDedicatedTest/include/protobuf/testdata/text_format_unittest_extensions_data_pointy.txt
new file mode 100644
index 00000000..132f7445
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/testdata/text_format_unittest_extensions_data_pointy.txt
@@ -0,0 +1,134 @@
+[protobuf_unittest.optional_int32_extension]: 101
+[protobuf_unittest.optional_int64_extension]: 102
+[protobuf_unittest.optional_uint32_extension]: 103
+[protobuf_unittest.optional_uint64_extension]: 104
+[protobuf_unittest.optional_sint32_extension]: 105
+[protobuf_unittest.optional_sint64_extension]: 106
+[protobuf_unittest.optional_fixed32_extension]: 107
+[protobuf_unittest.optional_fixed64_extension]: 108
+[protobuf_unittest.optional_sfixed32_extension]: 109
+[protobuf_unittest.optional_sfixed64_extension]: 110
+[protobuf_unittest.optional_float_extension]: 111
+[protobuf_unittest.optional_double_extension]: 112
+[protobuf_unittest.optional_bool_extension]: true
+[protobuf_unittest.optional_string_extension]: "115"
+[protobuf_unittest.optional_bytes_extension]: "116"
+[protobuf_unittest.optionalgroup_extension] <
+ a: 117
+>
+[protobuf_unittest.optional_nested_message_extension] <
+ bb: 118
+>
+[protobuf_unittest.optional_foreign_message_extension] <
+ c: 119
+>
+[protobuf_unittest.optional_import_message_extension] <
+ d: 120
+>
+[protobuf_unittest.optional_nested_enum_extension]: BAZ
+[protobuf_unittest.optional_foreign_enum_extension]: FOREIGN_BAZ
+[protobuf_unittest.optional_import_enum_extension]: IMPORT_BAZ
+[protobuf_unittest.optional_string_piece_extension]: "124"
+[protobuf_unittest.optional_cord_extension]: "125"
+[protobuf_unittest.optional_public_import_message_extension] <
+ e: 126
+>
+[protobuf_unittest.optional_lazy_message_extension] <
+ bb: 127
+>
+[protobuf_unittest.repeated_int32_extension]: 201
+[protobuf_unittest.repeated_int32_extension]: 301
+[protobuf_unittest.repeated_int64_extension]: 202
+[protobuf_unittest.repeated_int64_extension]: 302
+[protobuf_unittest.repeated_uint32_extension]: 203
+[protobuf_unittest.repeated_uint32_extension]: 303
+[protobuf_unittest.repeated_uint64_extension]: 204
+[protobuf_unittest.repeated_uint64_extension]: 304
+[protobuf_unittest.repeated_sint32_extension]: 205
+[protobuf_unittest.repeated_sint32_extension]: 305
+[protobuf_unittest.repeated_sint64_extension]: 206
+[protobuf_unittest.repeated_sint64_extension]: 306
+[protobuf_unittest.repeated_fixed32_extension]: 207
+[protobuf_unittest.repeated_fixed32_extension]: 307
+[protobuf_unittest.repeated_fixed64_extension]: 208
+[protobuf_unittest.repeated_fixed64_extension]: 308
+[protobuf_unittest.repeated_sfixed32_extension]: 209
+[protobuf_unittest.repeated_sfixed32_extension]: 309
+[protobuf_unittest.repeated_sfixed64_extension]: 210
+[protobuf_unittest.repeated_sfixed64_extension]: 310
+[protobuf_unittest.repeated_float_extension]: 211
+[protobuf_unittest.repeated_float_extension]: 311
+[protobuf_unittest.repeated_double_extension]: 212
+[protobuf_unittest.repeated_double_extension]: 312
+[protobuf_unittest.repeated_bool_extension]: true
+[protobuf_unittest.repeated_bool_extension]: false
+[protobuf_unittest.repeated_string_extension]: "215"
+[protobuf_unittest.repeated_string_extension]: "315"
+[protobuf_unittest.repeated_bytes_extension]: "216"
+[protobuf_unittest.repeated_bytes_extension]: "316"
+[protobuf_unittest.repeatedgroup_extension] <
+ a: 217
+>
+[protobuf_unittest.repeatedgroup_extension] <
+ a: 317
+>
+[protobuf_unittest.repeated_nested_message_extension] <
+ bb: 218
+>
+[protobuf_unittest.repeated_nested_message_extension] <
+ bb: 318
+>
+[protobuf_unittest.repeated_foreign_message_extension] <
+ c: 219
+>
+[protobuf_unittest.repeated_foreign_message_extension] <
+ c: 319
+>
+[protobuf_unittest.repeated_import_message_extension] <
+ d: 220
+>
+[protobuf_unittest.repeated_import_message_extension] <
+ d: 320
+>
+[protobuf_unittest.repeated_nested_enum_extension]: BAR
+[protobuf_unittest.repeated_nested_enum_extension]: BAZ
+[protobuf_unittest.repeated_foreign_enum_extension]: FOREIGN_BAR
+[protobuf_unittest.repeated_foreign_enum_extension]: FOREIGN_BAZ
+[protobuf_unittest.repeated_import_enum_extension]: IMPORT_BAR
+[protobuf_unittest.repeated_import_enum_extension]: IMPORT_BAZ
+[protobuf_unittest.repeated_string_piece_extension]: "224"
+[protobuf_unittest.repeated_string_piece_extension]: "324"
+[protobuf_unittest.repeated_cord_extension]: "225"
+[protobuf_unittest.repeated_cord_extension]: "325"
+[protobuf_unittest.repeated_lazy_message_extension] <
+ bb: 227
+>
+[protobuf_unittest.repeated_lazy_message_extension] <
+ bb: 327
+>
+[protobuf_unittest.default_int32_extension]: 401
+[protobuf_unittest.default_int64_extension]: 402
+[protobuf_unittest.default_uint32_extension]: 403
+[protobuf_unittest.default_uint64_extension]: 404
+[protobuf_unittest.default_sint32_extension]: 405
+[protobuf_unittest.default_sint64_extension]: 406
+[protobuf_unittest.default_fixed32_extension]: 407
+[protobuf_unittest.default_fixed64_extension]: 408
+[protobuf_unittest.default_sfixed32_extension]: 409
+[protobuf_unittest.default_sfixed64_extension]: 410
+[protobuf_unittest.default_float_extension]: 411
+[protobuf_unittest.default_double_extension]: 412
+[protobuf_unittest.default_bool_extension]: false
+[protobuf_unittest.default_string_extension]: "415"
+[protobuf_unittest.default_bytes_extension]: "416"
+[protobuf_unittest.default_nested_enum_extension]: FOO
+[protobuf_unittest.default_foreign_enum_extension]: FOREIGN_FOO
+[protobuf_unittest.default_import_enum_extension]: IMPORT_FOO
+[protobuf_unittest.default_string_piece_extension]: "424"
+[protobuf_unittest.default_cord_extension]: "425"
+[protobuf_unittest.oneof_uint32_extension]: 601
+[protobuf_unittest.oneof_nested_message_extension] <
+ bb: 602
+>
+[protobuf_unittest.oneof_string_extension]: "603"
+[protobuf_unittest.oneof_bytes_extension]: "604"
diff --git a/NorthstarDedicatedTest/include/protobuf/testing/file.cc b/NorthstarDedicatedTest/include/protobuf/testing/file.cc
new file mode 100644
index 00000000..f904028f
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/testing/file.cc
@@ -0,0 +1,215 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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)
+// emulates google3/file/base/file.cc
+
+#include <testing/file.h>
+#include <stdio.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#ifdef _MSC_VER
+#define WIN32_LEAN_AND_MEAN // yeah, right
+#include <windows.h> // Find*File(). :(
+// #include <direct.h>
+#else
+#include <dirent.h>
+#include <unistd.h>
+#endif
+#include <errno.h>
+
+#include <io/io_win32.h>
+#include <stubs/logging.h>
+
+namespace google {
+namespace protobuf {
+
+#ifdef _WIN32
+// Windows doesn't have symbolic links.
+#define lstat stat
+// DO NOT include <io.h>, instead create functions in io_win32.{h,cc} and import
+// them like we do below.
+#endif
+
+#ifdef _WIN32
+using google::protobuf::io::win32::access;
+using google::protobuf::io::win32::chdir;
+using google::protobuf::io::win32::fopen;
+using google::protobuf::io::win32::mkdir;
+using google::protobuf::io::win32::stat;
+#endif
+
+bool File::Exists(const std::string& name) {
+ return access(name.c_str(), F_OK) == 0;
+}
+
+bool File::ReadFileToString(const std::string& name, std::string* output,
+ bool text_mode) {
+ char buffer[1024];
+ FILE* file = fopen(name.c_str(), text_mode ? "rt" : "rb");
+ if (file == NULL) return false;
+
+ while (true) {
+ size_t n = fread(buffer, 1, sizeof(buffer), file);
+ if (n <= 0) break;
+ output->append(buffer, n);
+ }
+
+ int error = ferror(file);
+ if (fclose(file) != 0) return false;
+ return error == 0;
+}
+
+void File::ReadFileToStringOrDie(const std::string& name, std::string* output) {
+ GOOGLE_CHECK(ReadFileToString(name, output)) << "Could not read: " << name;
+}
+
+bool File::WriteStringToFile(const std::string& contents,
+ const std::string& name) {
+ FILE* file = fopen(name.c_str(), "wb");
+ if (file == NULL) {
+ GOOGLE_LOG(ERROR) << "fopen(" << name << ", \"wb\"): " << strerror(errno);
+ return false;
+ }
+
+ if (fwrite(contents.data(), 1, contents.size(), file) != contents.size()) {
+ GOOGLE_LOG(ERROR) << "fwrite(" << name << "): " << strerror(errno);
+ fclose(file);
+ return false;
+ }
+
+ if (fclose(file) != 0) {
+ return false;
+ }
+ return true;
+}
+
+void File::WriteStringToFileOrDie(const std::string& contents,
+ const std::string& name) {
+ FILE* file = fopen(name.c_str(), "wb");
+ GOOGLE_CHECK(file != NULL)
+ << "fopen(" << name << ", \"wb\"): " << strerror(errno);
+ GOOGLE_CHECK_EQ(fwrite(contents.data(), 1, contents.size(), file),
+ contents.size())
+ << "fwrite(" << name << "): " << strerror(errno);
+ GOOGLE_CHECK(fclose(file) == 0)
+ << "fclose(" << name << "): " << strerror(errno);
+}
+
+bool File::CreateDir(const std::string& name, int mode) {
+ if (!name.empty()) {
+ GOOGLE_CHECK_OK(name[name.size() - 1] != '.');
+ }
+ return mkdir(name.c_str(), mode) == 0;
+}
+
+bool File::RecursivelyCreateDir(const std::string& path, int mode) {
+ if (CreateDir(path, mode)) return true;
+
+ if (Exists(path)) return false;
+
+ // Try creating the parent.
+ std::string::size_type slashpos = path.find_last_of('/');
+ if (slashpos == std::string::npos) {
+ // No parent given.
+ return false;
+ }
+
+ return RecursivelyCreateDir(path.substr(0, slashpos), mode) &&
+ CreateDir(path, mode);
+}
+
+void File::DeleteRecursively(const std::string& name, void* dummy1,
+ void* dummy2) {
+ if (name.empty()) return;
+
+ // We don't care too much about error checking here since this is only used
+ // in tests to delete temporary directories that are under /tmp anyway.
+
+#ifdef _MSC_VER
+ // This interface is so weird.
+ WIN32_FIND_DATAA find_data;
+ HANDLE find_handle = FindFirstFileA((name + "/*").c_str(), &find_data);
+ if (find_handle == INVALID_HANDLE_VALUE) {
+ // Just delete it, whatever it is.
+ DeleteFileA(name.c_str());
+ RemoveDirectoryA(name.c_str());
+ return;
+ }
+
+ do {
+ std::string entry_name = find_data.cFileName;
+ if (entry_name != "." && entry_name != "..") {
+ std::string path = name + "/" + entry_name;
+ if (find_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
+ DeleteRecursively(path, NULL, NULL);
+ RemoveDirectoryA(path.c_str());
+ } else {
+ DeleteFileA(path.c_str());
+ }
+ }
+ } while(FindNextFileA(find_handle, &find_data));
+ FindClose(find_handle);
+
+ RemoveDirectoryA(name.c_str());
+#else
+ // Use opendir()! Yay!
+ // lstat = Don't follow symbolic links.
+ struct stat stats;
+ if (lstat(name.c_str(), &stats) != 0) return;
+
+ if (S_ISDIR(stats.st_mode)) {
+ DIR* dir = opendir(name.c_str());
+ if (dir != NULL) {
+ while (true) {
+ struct dirent* entry = readdir(dir);
+ if (entry == NULL) break;
+ std::string entry_name = entry->d_name;
+ if (entry_name != "." && entry_name != "..") {
+ DeleteRecursively(name + "/" + entry_name, NULL, NULL);
+ }
+ }
+ }
+
+ closedir(dir);
+ rmdir(name.c_str());
+
+ } else if (S_ISREG(stats.st_mode)) {
+ remove(name.c_str());
+ }
+#endif
+}
+
+bool File::ChangeWorkingDirectory(const std::string& new_working_directory) {
+ return chdir(new_working_directory.c_str()) == 0;
+}
+
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/testing/file.h b/NorthstarDedicatedTest/include/protobuf/testing/file.h
new file mode 100644
index 00000000..45d641fb
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/testing/file.h
@@ -0,0 +1,107 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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)
+// emulates google3/file/base/file.h
+
+#ifndef GOOGLE_PROTOBUF_TESTING_FILE_H__
+#define GOOGLE_PROTOBUF_TESTING_FILE_H__
+
+#include <stubs/common.h>
+
+namespace google {
+namespace protobuf {
+
+const int DEFAULT_FILE_MODE = 0777;
+
+// Protocol buffer code only uses a couple static methods of File, and only
+// in tests.
+class File {
+ public:
+ // Check if the file exists.
+ static bool Exists(const std::string& name);
+
+ // Read an entire file to a string. Return true if successful, false
+ // otherwise.
+ static bool ReadFileToString(const std::string& name, std::string* output,
+ bool text_mode = false);
+
+ // Same as above, but crash on failure.
+ static void ReadFileToStringOrDie(const std::string& name,
+ std::string* output);
+
+ // Create a file and write a string to it.
+ static bool WriteStringToFile(const std::string& contents,
+ const std::string& name);
+
+ // Same as above, but crash on failure.
+ static void WriteStringToFileOrDie(const std::string& contents,
+ const std::string& name);
+
+ // Create a directory.
+ static bool CreateDir(const std::string& name, int mode);
+
+ // Create a directory and all parent directories if necessary.
+ static bool RecursivelyCreateDir(const std::string& path, int mode);
+
+ // If "name" is a file, we delete it. If it is a directory, we
+ // call DeleteRecursively() for each file or directory (other than
+ // dot and double-dot) within it, and then delete the directory itself.
+ // The "dummy" parameters have a meaning in the original version of this
+ // method but they are not used anywhere in protocol buffers.
+ static void DeleteRecursively(const std::string& name, void* dummy1,
+ void* dummy2);
+
+ // Change working directory to given directory.
+ static bool ChangeWorkingDirectory(const std::string& new_working_directory);
+
+ static bool GetContents(const std::string& name, std::string* output,
+ bool /*is_default*/) {
+ return ReadFileToString(name, output);
+ }
+
+ static bool GetContentsAsText(const std::string& name, std::string* output,
+ bool /*is_default*/) {
+ return ReadFileToString(name, output, true);
+ }
+
+ static bool SetContents(const std::string& name, const std::string& contents,
+ bool /*is_default*/) {
+ return WriteStringToFile(contents, name);
+ }
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(File);
+};
+
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_TESTING_FILE_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/testing/googletest.cc b/NorthstarDedicatedTest/include/protobuf/testing/googletest.cc
new file mode 100644
index 00000000..6fe64bc8
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/testing/googletest.cc
@@ -0,0 +1,302 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// emulates google3/testing/base/public/googletest.cc
+
+#include <testing/googletest.h>
+#include <testing/file.h>
+#include <io/io_win32.h>
+#include <stubs/strutil.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <errno.h>
+#include <stdlib.h>
+#ifdef _MSC_VER
+// #include <direct.h>
+#else
+#include <unistd.h>
+#endif
+#include <stdio.h>
+#include <fcntl.h>
+#include <iostream>
+#include <fstream>
+
+namespace google {
+namespace protobuf {
+
+#ifdef _WIN32
+// 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::close;
+using google::protobuf::io::win32::dup2;
+using google::protobuf::io::win32::dup;
+using google::protobuf::io::win32::mkdir;
+using google::protobuf::io::win32::open;
+#endif
+
+#ifndef O_BINARY
+#ifdef _O_BINARY
+#define O_BINARY _O_BINARY
+#else
+#define O_BINARY 0 // If this isn't defined, the platform doesn't need it.
+#endif
+#endif
+
+std::string TestSourceDir() {
+#ifndef GOOGLE_THIRD_PARTY_PROTOBUF
+#ifdef GOOGLE_PROTOBUF_TEST_SOURCE_PATH
+ return GOOGLE_PROTOBUF_TEST_SOURCE_PATH;
+#else
+#ifndef _MSC_VER
+ // automake sets the "srcdir" environment variable.
+ char* result = getenv("srcdir");
+ if (result != NULL) {
+ return result;
+ }
+#endif // _MSC_VER
+
+ // Look for the "src" directory.
+ std::string prefix = ".";
+
+ // Keep looking further up the directory tree until we find
+ // src/.../descriptor.cc. It is important to look for a particular file,
+ // keeping in mind that with Bazel builds the directory structure under
+ // bazel-bin/ looks similar to the main directory tree in the Git repo.
+ while (!File::Exists(prefix + "/src/google/protobuf/descriptor.cc")) {
+ if (!File::Exists(prefix)) {
+ GOOGLE_LOG(FATAL)
+ << "Could not find protobuf source code. Please run tests from "
+ "somewhere within the protobuf source package.";
+ }
+ prefix += "/..";
+ }
+ return prefix + "/src";
+#endif // GOOGLE_PROTOBUF_TEST_SOURCE_PATH
+#else
+ return "third_party/protobuf/src";
+#endif // GOOGLE_THIRD_PARTY_PROTOBUF
+}
+
+namespace {
+
+std::string GetTemporaryDirectoryName() {
+ // Tests run under Bazel "should not" use /tmp. Bazel sets this environment
+ // variable for tests to use instead.
+ char *from_environment = getenv("TEST_TMPDIR");
+ if (from_environment != NULL && from_environment[0] != '\0') {
+ return std::string(from_environment) + "/protobuf_tmpdir";
+ }
+
+ // tmpnam() is generally not considered safe but we're only using it for
+ // testing. We cannot use tmpfile() or mkstemp() since we're creating a
+ // directory.
+ char b[L_tmpnam + 1]; // HPUX multithread return 0 if s is 0
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+ std::string result = tmpnam(b);
+#pragma GCC diagnostic pop
+#ifdef _WIN32
+ // Avoid a trailing dot by changing it to an underscore. On Win32 the names of
+ // files and directories can, but should not, end with dot.
+ //
+ // In MS-DOS and FAT16 filesystem the filenames were 8dot3 style so it didn't
+ // make sense to have a name ending in dot without an extension, so the shell
+ // silently ignored trailing dots. To this day the Win32 API still maintains
+ // this behavior and silently ignores trailing dots in path arguments of
+ // functions such as CreateFile{A,W}. Even POSIX API function implementations
+ // seem to wrap the Win32 API functions (e.g. CreateDirectoryA) and behave
+ // this way.
+ // It's possible to avoid this behavior and create files / directories with
+ // trailing dots (using CreateFileW / CreateDirectoryW and prefixing the path
+ // with "\\?\") but these will be degenerate in the sense that you cannot
+ // chdir into such directories (or navigate into them with Windows Explorer)
+ // nor can you open such files with some programs (e.g. Notepad).
+ if (result[result.size() - 1] == '.') {
+ result[result.size() - 1] = '_';
+ }
+ // On Win32, tmpnam() returns a file prefixed with '\', but which is supposed
+ // to be used in the current working directory. WTF?
+ if (HasPrefixString(result, "\\")) {
+ result.erase(0, 1);
+ }
+ // The Win32 API accepts forward slashes as a path delimiter as long as the
+ // path doesn't use the "\\?\" prefix.
+ // Let's avoid confusion and use only forward slashes.
+ result = StringReplace(result, "\\", "/", true);
+#endif // _WIN32
+ return result;
+}
+
+// Creates a temporary directory on demand and deletes it when the process
+// quits.
+class TempDirDeleter {
+ public:
+ TempDirDeleter() {}
+ ~TempDirDeleter() {
+ if (!name_.empty()) {
+ File::DeleteRecursively(name_, NULL, NULL);
+ }
+ }
+
+ std::string GetTempDir() {
+ if (name_.empty()) {
+ name_ = GetTemporaryDirectoryName();
+ GOOGLE_CHECK(mkdir(name_.c_str(), 0777) == 0) << strerror(errno);
+
+ // Stick a file in the directory that tells people what this is, in case
+ // we abort and don't get a chance to delete it.
+ File::WriteStringToFileOrDie("", name_ + "/TEMP_DIR_FOR_PROTOBUF_TESTS");
+ }
+ return name_;
+ }
+
+ private:
+ std::string name_;
+};
+
+TempDirDeleter temp_dir_deleter_;
+
+} // namespace
+
+std::string TestTempDir() { return temp_dir_deleter_.GetTempDir(); }
+
+// TODO(kenton): Share duplicated code below. Too busy/lazy for now.
+
+static std::string stdout_capture_filename_;
+static std::string stderr_capture_filename_;
+static int original_stdout_ = -1;
+static int original_stderr_ = -1;
+
+void CaptureTestStdout() {
+ GOOGLE_CHECK_EQ(original_stdout_, -1) << "Already capturing.";
+
+ stdout_capture_filename_ = TestTempDir() + "/captured_stdout";
+
+ int fd = open(stdout_capture_filename_.c_str(),
+ O_WRONLY | O_CREAT | O_EXCL | O_BINARY, 0777);
+ GOOGLE_CHECK(fd >= 0) << "open: " << strerror(errno);
+
+ original_stdout_ = dup(1);
+ close(1);
+ dup2(fd, 1);
+ close(fd);
+}
+
+void CaptureTestStderr() {
+ GOOGLE_CHECK_EQ(original_stderr_, -1) << "Already capturing.";
+
+ stderr_capture_filename_ = TestTempDir() + "/captured_stderr";
+
+ int fd = open(stderr_capture_filename_.c_str(),
+ O_WRONLY | O_CREAT | O_EXCL | O_BINARY, 0777);
+ GOOGLE_CHECK(fd >= 0) << "open: " << strerror(errno);
+
+ original_stderr_ = dup(2);
+ close(2);
+ dup2(fd, 2);
+ close(fd);
+}
+
+std::string GetCapturedTestStdout() {
+ GOOGLE_CHECK_NE(original_stdout_, -1) << "Not capturing.";
+
+ close(1);
+ dup2(original_stdout_, 1);
+ original_stdout_ = -1;
+
+ std::string result;
+ File::ReadFileToStringOrDie(stdout_capture_filename_, &result);
+
+ remove(stdout_capture_filename_.c_str());
+
+ return result;
+}
+
+std::string GetCapturedTestStderr() {
+ GOOGLE_CHECK_NE(original_stderr_, -1) << "Not capturing.";
+
+ close(2);
+ dup2(original_stderr_, 2);
+ original_stderr_ = -1;
+
+ std::string result;
+ File::ReadFileToStringOrDie(stderr_capture_filename_, &result);
+
+ remove(stderr_capture_filename_.c_str());
+
+ return result;
+}
+
+ScopedMemoryLog* ScopedMemoryLog::active_log_ = NULL;
+
+ScopedMemoryLog::ScopedMemoryLog() {
+ GOOGLE_CHECK(active_log_ == NULL);
+ active_log_ = this;
+ old_handler_ = SetLogHandler(&HandleLog);
+}
+
+ScopedMemoryLog::~ScopedMemoryLog() {
+ SetLogHandler(old_handler_);
+ active_log_ = NULL;
+}
+
+const std::vector<std::string>& ScopedMemoryLog::GetMessages(LogLevel level) {
+ GOOGLE_CHECK(level == ERROR ||
+ level == WARNING);
+ return messages_[level];
+}
+
+void ScopedMemoryLog::HandleLog(LogLevel level, const char* filename, int line,
+ const std::string& message) {
+ GOOGLE_CHECK(active_log_ != NULL);
+ if (level == ERROR || level == WARNING) {
+ active_log_->messages_[level].push_back(message);
+ }
+}
+
+namespace {
+
+// Force shutdown at process exit so that we can test for memory leaks. To
+// actually check for leaks, I suggest using the heap checker included with
+// google-perftools. Set it to "draconian" mode to ensure that every last
+// call to malloc() has a corresponding free().
+struct ForceShutdown {
+ ~ForceShutdown() {
+ ShutdownProtobufLibrary();
+ // Test to shutdown the library twice, which should succeed.
+ ShutdownProtobufLibrary();
+ }
+} force_shutdown;
+
+} // namespace
+
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/testing/googletest.h b/NorthstarDedicatedTest/include/protobuf/testing/googletest.h
new file mode 100644
index 00000000..727b62be
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/testing/googletest.h
@@ -0,0 +1,104 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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)
+// emulates google3/testing/base/public/googletest.h
+
+#ifndef GOOGLE_PROTOBUF_GOOGLETEST_H__
+#define GOOGLE_PROTOBUF_GOOGLETEST_H__
+
+#include <map>
+#include <vector>
+#include <stubs/common.h>
+#include <stubs/logging.h>
+#include <gmock/gmock.h>
+// Disable death tests if we use exceptions in CHECK().
+#if !PROTOBUF_USE_EXCEPTIONS && defined(GTEST_HAS_DEATH_TEST) && \
+ !GTEST_OS_WINDOWS
+#define PROTOBUF_HAS_DEATH_TEST
+#endif
+
+namespace google {
+namespace protobuf {
+
+// When running unittests, get the directory containing the source code.
+std::string TestSourceDir();
+
+// When running unittests, get a directory where temporary files may be
+// placed.
+std::string TestTempDir();
+
+// Capture all text written to stdout or stderr.
+void CaptureTestStdout();
+void CaptureTestStderr();
+
+// Stop capturing stdout or stderr and return the text captured.
+std::string GetCapturedTestStdout();
+std::string GetCapturedTestStderr();
+
+// For use with ScopedMemoryLog::GetMessages(). Inside Google the LogLevel
+// constants don't have the LOGLEVEL_ prefix, so the code that used
+// ScopedMemoryLog refers to LOGLEVEL_ERROR as just ERROR.
+#undef ERROR // defend against promiscuous windows.h
+static const LogLevel ERROR = LOGLEVEL_ERROR;
+static const LogLevel WARNING = LOGLEVEL_WARNING;
+
+// Receives copies of all LOG(ERROR) messages while in scope. Sample usage:
+// {
+// ScopedMemoryLog log; // constructor registers object as a log sink
+// SomeRoutineThatMayLogMessages();
+// const vector<string>& warnings = log.GetMessages(ERROR);
+// } // destructor unregisters object as a log sink
+// This is a dummy implementation which covers only what is used by protocol
+// buffer unit tests.
+class ScopedMemoryLog {
+ public:
+ ScopedMemoryLog();
+ virtual ~ScopedMemoryLog();
+
+ // Fetches all messages with the given severity level.
+ const std::vector<std::string>& GetMessages(LogLevel error);
+
+ private:
+ std::map<LogLevel, std::vector<std::string> > messages_;
+ LogHandler* old_handler_;
+
+ static void HandleLog(LogLevel level, const char* filename, int line,
+ const std::string& message);
+
+ static ScopedMemoryLog* active_log_;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ScopedMemoryLog);
+};
+
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_GOOGLETEST_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/testing/zcgunzip.cc b/NorthstarDedicatedTest/include/protobuf/testing/zcgunzip.cc
new file mode 100644
index 00000000..e393e4ab
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/testing/zcgunzip.cc
@@ -0,0 +1,84 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2009 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// Test program to verify that GzipInputStream is compatible with command line
+// gunzip or java.util.zip.GzipInputStream
+//
+// Reads gzip stream on standard input and writes decompressed data to standard
+// output.
+
+#include <assert.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#ifdef _WIN32
+#ifndef STDIN_FILENO
+#define STDIN_FILENO 0
+#endif
+#ifndef STDOUT_FILENO
+#define STDOUT_FILENO 1
+#endif
+#endif
+
+#include <io/gzip_stream.h>
+#include <io/zero_copy_stream_impl.h>
+
+using google::protobuf::io::FileInputStream;
+using google::protobuf::io::GzipInputStream;
+
+int main(int argc, const char** argv) {
+ FileInputStream fin(STDIN_FILENO);
+ GzipInputStream in(&fin);
+
+ while (true) {
+ const void* inptr;
+ int inlen;
+ bool ok;
+ ok = in.Next(&inptr, &inlen);
+ if (!ok) {
+ break;
+ }
+ if (inlen > 0) {
+ int err = write(STDOUT_FILENO, inptr, inlen);
+ if (err != inlen) {
+ fprintf(stderr, "write unexpectedly returned %d.\n", err);
+ return 1;
+ }
+ }
+ }
+
+ return 0;
+}
diff --git a/NorthstarDedicatedTest/include/protobuf/testing/zcgzip.cc b/NorthstarDedicatedTest/include/protobuf/testing/zcgzip.cc
new file mode 100644
index 00000000..d2aba57a
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/testing/zcgzip.cc
@@ -0,0 +1,87 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2009 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// Test program to verify that GzipOutputStream is compatible with command line
+// gzip or java.util.zip.GzipOutputStream
+//
+// Reads data on standard input and writes compressed gzip stream to standard
+// output.
+
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#ifdef _WIN32
+#ifndef STDIN_FILENO
+#define STDIN_FILENO 0
+#endif
+#ifndef STDOUT_FILENO
+#define STDOUT_FILENO 1
+#endif
+#endif
+
+#include <io/gzip_stream.h>
+#include <io/zero_copy_stream_impl.h>
+
+using google::protobuf::io::FileOutputStream;
+using google::protobuf::io::GzipOutputStream;
+
+int main(int argc, const char** argv) {
+ FileOutputStream fout(STDOUT_FILENO);
+ GzipOutputStream out(&fout);
+ int readlen;
+
+ while (true) {
+ void* outptr;
+ int outlen;
+ bool ok;
+ do {
+ ok = out.Next(&outptr, &outlen);
+ if (!ok) {
+ break;
+ }
+ } while (outlen <= 0);
+ readlen = read(STDIN_FILENO, outptr, outlen);
+ if (readlen <= 0) {
+ out.BackUp(outlen);
+ break;
+ }
+ if (readlen < outlen) {
+ out.BackUp(outlen - readlen);
+ }
+ }
+
+ return 0;
+}
diff --git a/NorthstarDedicatedTest/include/protobuf/text_format.cc b/NorthstarDedicatedTest/include/protobuf/text_format.cc
new file mode 100644
index 00000000..28239e9a
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/text_format.cc
@@ -0,0 +1,2728 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 <text_format.h>
+
+#include <float.h>
+#include <stdio.h>
+
+#include <algorithm>
+#include <atomic>
+#include <climits>
+#include <cmath>
+#include <limits>
+#include <vector>
+
+#include <stubs/stringprintf.h>
+#include <any.h>
+#include <descriptor.pb.h>
+#include <io/coded_stream.h>
+#include <io/tokenizer.h>
+#include <io/zero_copy_stream.h>
+#include <io/zero_copy_stream_impl.h>
+#include <descriptor.h>
+#include <dynamic_message.h>
+#include <map_field.h>
+#include <message.h>
+#include <repeated_field.h>
+#include <unknown_field_set.h>
+#include <wire_format_lite.h>
+#include <stubs/strutil.h>
+#include <io/strtod.h>
+#include <stubs/map_util.h>
+#include <stubs/stl_util.h>
+
+// Must be included last.
+#include <port_def.inc>
+
+#define DEBUG_STRING_SILENT_MARKER "\t "
+
+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 {
+// Controls insertion of DEBUG_STRING_SILENT_MARKER.
+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 qux: 2"
+ // where "baz" and "qux" are members of the same oneof.
+ enum SingularOverwritePolicy {
+ ALLOW_SINGULAR_OVERWRITES = 0, // the last value is retained
+ FORBID_SINGULAR_OVERWRITES = 1, // an error is issued
+ };
+
+ ParserImpl(const Descriptor* root_message_type,
+ io::ZeroCopyInputStream* input_stream,
+ io::ErrorCollector* error_collector,
+ const TextFormat::Finder* finder, ParseInfoTree* parse_info_tree,
+ SingularOverwritePolicy singular_overwrite_policy,
+ bool allow_case_insensitive_field, bool allow_unknown_field,
+ bool allow_unknown_extension, bool allow_unknown_enum,
+ bool allow_field_number, bool allow_relaxed_whitespace,
+ bool allow_partial, int recursion_limit)
+ : error_collector_(error_collector),
+ finder_(finder),
+ parse_info_tree_(parse_info_tree),
+ tokenizer_error_collector_(this),
+ tokenizer_(input_stream, &tokenizer_error_collector_),
+ root_message_type_(root_message_type),
+ singular_overwrite_policy_(singular_overwrite_policy),
+ allow_case_insensitive_field_(allow_case_insensitive_field),
+ allow_unknown_field_(allow_unknown_field),
+ allow_unknown_extension_(allow_unknown_extension),
+ allow_unknown_enum_(allow_unknown_enum),
+ allow_field_number_(allow_field_number),
+ allow_partial_(allow_partial),
+ initial_recursion_limit_(recursion_limit),
+ recursion_limit_(recursion_limit),
+ had_errors_(false) {
+ // For backwards-compatibility with proto1, we need to allow the 'f' suffix
+ // for floats.
+ tokenizer_.set_allow_f_after_float(true);
+
+ // '#' starts a comment.
+ tokenizer_.set_comment_style(io::Tokenizer::SH_COMMENT_STYLE);
+
+ if (allow_relaxed_whitespace) {
+ tokenizer_.set_require_space_after_number(false);
+ tokenizer_.set_allow_multiline_strings(true);
+ }
+
+ // Consume the starting token.
+ tokenizer_.Next();
+ }
+ ~ParserImpl() {}
+
+ // Parses the ASCII representation specified in input and saves the
+ // information into the output pointer (a Message). Returns
+ // false if an error occurs (an error will also be logged to
+ // GOOGLE_LOG(ERROR)).
+ bool Parse(Message* output) {
+ // Consume fields until we cannot do so anymore.
+ while (true) {
+ if (LookingAtType(io::Tokenizer::TYPE_END)) {
+ // Ensures recursion limit properly unwinded, but only for success
+ // cases. This implicitly avoids the check when `Parse` returns false
+ // via `DO(...)`.
+ GOOGLE_DCHECK(had_errors_ || recursion_limit_ == initial_recursion_limit_)
+ << "Recursion limit at end of parse should be "
+ << initial_recursion_limit_ << ", but was " << recursion_limit_
+ << ". Difference of " << initial_recursion_limit_ - recursion_limit_
+ << " stack frames not accounted for stack unwind.";
+
+ return !had_errors_;
+ }
+
+ DO(ConsumeField(output));
+ }
+ }
+
+ bool ParseField(const FieldDescriptor* field, Message* output) {
+ bool suc;
+ if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+ suc = ConsumeFieldMessage(output, output->GetReflection(), field);
+ } else {
+ suc = ConsumeFieldValue(output, output->GetReflection(), field);
+ }
+ return suc && LookingAtType(io::Tokenizer::TYPE_END);
+ }
+
+ void ReportError(int line, int col, const 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(prefix_and_full_type_name, "Any");
+ // ':' is optional between message labels and values.
+ TryConsumeBeforeWhitespace(":");
+ TryConsumeWhitespace(prefix_and_full_type_name, "Any");
+ 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,
+ prefix_and_full_type_name);
+ reflection->SetString(message, any_value_field, serialized_value);
+ return true;
+ }
+ if (TryConsume("[")) {
+ // Extension.
+ DO(ConsumeFullTypeName(&field_name));
+ DO(ConsumeBeforeWhitespace("]"));
+ TryConsumeWhitespace(message->GetTypeName(), "Extension");
+
+ field = finder_ ? finder_->FindExtension(message, field_name)
+ : DefaultFinderFindExtension(message, field_name);
+
+ if (field == nullptr) {
+ if (!allow_unknown_field_ && !allow_unknown_extension_) {
+ ReportError("Extension \"" + field_name +
+ "\" is not defined or "
+ "is not an extension of \"" +
+ descriptor->full_name() + "\".");
+ return false;
+ } else {
+ ReportWarning("Ignoring extension \"" + field_name +
+ "\" which is not defined or is not an extension of \"" +
+ descriptor->full_name() + "\".");
+ }
+ }
+ } else {
+ DO(ConsumeIdentifierBeforeWhitespace(&field_name));
+ TryConsumeWhitespace(message->GetTypeName(), "Normal");
+
+ 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(message->GetTypeName(), "Unknown/Reserved");
+ 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(":");
+ TryConsumeWhitespace(message->GetTypeName(), "Normal");
+ if (consumed_semicolon && field->options().weak() &&
+ LookingAtType(io::Tokenizer::TYPE_STRING)) {
+ // we are getting a bytes string for a weak field.
+ 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(message->GetTypeName(), "Normal");
+ }
+
+ if (field->is_repeated() && TryConsume("[")) {
+ // Short repeated format, e.g. "foo: [1, 2, 3]".
+ if (!TryConsume("]")) {
+ // "foo: []" is treated as empty.
+ while (true) {
+ if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+ // Perform special handling for embedded message types.
+ DO(ConsumeFieldMessage(message, reflection, field));
+ } else {
+ DO(ConsumeFieldValue(message, reflection, field));
+ }
+ if (TryConsume("]")) {
+ break;
+ }
+ DO(Consume(","));
+ }
+ }
+ } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+ DO(ConsumeFieldMessage(message, reflection, field));
+ } else {
+ DO(ConsumeFieldValue(message, reflection, field));
+ }
+ label_skip_parsing:
+ // For historical reasons, fields may optionally be separated by commas or
+ // semicolons.
+ TryConsume(";") || TryConsume(",");
+
+ if (field->options().deprecated()) {
+ ReportWarning("text format contains deprecated field \"" + field_name +
+ "\"");
+ }
+
+ // If a parse info tree exists, add the location for the parsed
+ // field.
+ if (parse_info_tree_ != nullptr) {
+ int end_line = tokenizer_.previous().line;
+ int end_column = tokenizer_.previous().end_column;
+
+ RecordLocation(parse_info_tree_, field,
+ ParseLocationRange(ParseLocation(start_line, start_column),
+ ParseLocation(end_line, end_column)));
+ }
+
+ return true;
+ }
+
+ // Skips the next field including the field's name and value.
+ bool SkipField() {
+ if (TryConsume("[")) {
+ // Extension name or type URL.
+ DO(ConsumeTypeUrlOrFullTypeName());
+ DO(ConsumeBeforeWhitespace("]"));
+ } else {
+ std::string field_name;
+ DO(ConsumeIdentifierBeforeWhitespace(&field_name));
+ }
+ TryConsumeWhitespace("Unknown/Reserved", "n/a");
+
+ // Try to guess the type of this field.
+ // If this field is not a message, there should be a ":" between the
+ // field name and the field value and also the field value should not
+ // start with "{" or "<" which indicates the beginning of a message body.
+ // If there is no ":" or there is a "{" or "<" after ":", this field has
+ // to be a message or the input is ill-formed.
+ if (TryConsumeBeforeWhitespace(":")) {
+ TryConsumeWhitespace("Unknown/Reserved", "n/a");
+ if (!LookingAt("{") && !LookingAt("<")) {
+ DO(SkipFieldValue());
+ } else {
+ DO(SkipFieldMessage());
+ }
+ } else {
+ DO(SkipFieldMessage());
+ }
+ // For historical reasons, fields may optionally be separated by commas or
+ // semicolons.
+ TryConsume(";") || TryConsume(",");
+ return true;
+ }
+
+ bool ConsumeFieldMessage(Message* message, const Reflection* reflection,
+ const FieldDescriptor* field) {
+ if (--recursion_limit_ < 0) {
+ ReportError(
+ StrCat("Message is too deep, the parser exceeded the "
+ "configured recursion limit of ",
+ initial_recursion_limit_, "."));
+ return false;
+ }
+ // If the parse information tree is not nullptr, create a nested one
+ // for the nested message.
+ ParseInfoTree* parent = parse_info_tree_;
+ if (parent != nullptr) {
+ parse_info_tree_ = CreateNested(parent, field);
+ }
+
+ 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, 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 discarded;
+ DO(ConsumeIdentifier(&discarded));
+ while (TryConsume(".") || TryConsume("/")) {
+ DO(ConsumeIdentifier(&discarded));
+ }
+ return true;
+ }
+
+ // Consumes a string and saves its value in the text parameter.
+ // Returns false if the token is not of type STRING.
+ bool ConsumeString(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(const std::string& message_type,
+ const char* field_type) {
+ if (LookingAtType(io::Tokenizer::TYPE_WHITESPACE)) {
+ tokenizer_.Next();
+ return true;
+ }
+
+ return false;
+ }
+
+ // An internal instance of the Tokenizer's error collector, used to
+ // collect any base-level parse errors and feed them to the ParserImpl.
+ class ParserErrorCollector : public io::ErrorCollector {
+ public:
+ explicit ParserErrorCollector(TextFormat::Parser::ParserImpl* parser)
+ : parser_(parser) {}
+
+ ~ParserErrorCollector() override {}
+
+ void AddError(int line, int column, const 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_errors_;
+};
+
+// ===========================================================================
+// Internal class for writing text to the io::ZeroCopyOutputStream. Adapted
+// from the Printer found in //net/proto2/io/public/printer.h
+class TextFormat::Printer::TextGenerator
+ : public TextFormat::BaseTextGenerator {
+ public:
+ explicit TextGenerator(io::ZeroCopyOutputStream* output,
+ int initial_indent_level)
+ : output_(output),
+ buffer_(nullptr),
+ buffer_size_(0),
+ at_start_of_line_(true),
+ failed_(false),
+ insert_silent_marker_(false),
+ indent_level_(initial_indent_level),
+ initial_indent_level_(initial_indent_level) {}
+
+ explicit TextGenerator(io::ZeroCopyOutputStream* output,
+ bool insert_silent_marker, int initial_indent_level)
+ : output_(output),
+ buffer_(nullptr),
+ buffer_size_(0),
+ at_start_of_line_(true),
+ failed_(false),
+ insert_silent_marker_(insert_silent_marker),
+ indent_level_(initial_indent_level),
+ initial_indent_level_(initial_indent_level) {}
+
+ ~TextGenerator() {
+ // Only BackUp() if we're sure we've successfully called Next() at least
+ // once.
+ if (!failed_ && buffer_size_ > 0) {
+ output_->BackUp(buffer_size_);
+ }
+ }
+
+ // Indent text by two spaces. After calling Indent(), two spaces will be
+ // inserted at the beginning of each line of text. Indent() may be called
+ // multiple times to produce deeper indents.
+ void Indent() override { ++indent_level_; }
+
+ // Reduces the current indent level by two spaces, or crashes if the indent
+ // level is zero.
+ void Outdent() override {
+ if (indent_level_ == 0 || indent_level_ < initial_indent_level_) {
+ GOOGLE_LOG(DFATAL) << " Outdent() without matching Indent().";
+ return;
+ }
+
+ --indent_level_;
+ }
+
+ size_t GetCurrentIndentationSize() const override {
+ return 2 * indent_level_;
+ }
+
+ // Print text to the output stream.
+ void Print(const char* text, size_t size) override {
+ if (indent_level_ > 0) {
+ size_t pos = 0; // The number of bytes we've written so far.
+ for (size_t i = 0; i < size; i++) {
+ if (text[i] == '\n') {
+ // Saw newline. If there is more text, we may need to insert an
+ // indent here. So, write what we have so far, including the '\n'.
+ Write(text + pos, i - pos + 1);
+ pos = i + 1;
+
+ // Setting this true will cause the next Write() to insert an indent
+ // first.
+ at_start_of_line_ = true;
+ }
+ }
+ // Write the rest.
+ Write(text + pos, size - pos);
+ } else {
+ Write(text, size);
+ if (size > 0 && text[size - 1] == '\n') {
+ at_start_of_line_ = true;
+ }
+ }
+ }
+
+ // True if any write to the underlying stream failed. (We don't just
+ // crash in this case because this is an I/O failure, not a programming
+ // error.)
+ bool failed() const { return failed_; }
+
+ void PrintMaybeWithMarker(StringPiece text) {
+ Print(text.data(), text.size());
+ if (ConsumeInsertSilentMarker()) {
+ PrintLiteral(DEBUG_STRING_SILENT_MARKER);
+ }
+ }
+
+ void PrintMaybeWithMarker(StringPiece text_head,
+ StringPiece text_tail) {
+ Print(text_head.data(), text_head.size());
+ if (ConsumeInsertSilentMarker()) {
+ PrintLiteral(DEBUG_STRING_SILENT_MARKER);
+ }
+ Print(text_tail.data(), text_tail.size());
+ }
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(TextGenerator);
+
+ void Write(const char* data, size_t size) {
+ if (failed_) return;
+ if (size == 0) return;
+
+ if (at_start_of_line_) {
+ // Insert an indent.
+ at_start_of_line_ = false;
+ WriteIndent();
+ if (failed_) return;
+ }
+
+ while (static_cast<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 <port_undef.inc>
diff --git a/NorthstarDedicatedTest/include/protobuf/text_format.h b/NorthstarDedicatedTest/include/protobuf/text_format.h
new file mode 100644
index 00000000..5b6f1d57
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/text_format.h
@@ -0,0 +1,687 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: jschorr@google.com (Joseph Schorr)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// Utilities for printing and parsing protocol messages in a human-readable,
+// text-based format.
+
+#ifndef GOOGLE_PROTOBUF_TEXT_FORMAT_H__
+#define GOOGLE_PROTOBUF_TEXT_FORMAT_H__
+
+#include <map>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include <stubs/common.h>
+#include <descriptor.h>
+#include <message.h>
+#include <message_lite.h>
+#include <port.h>
+
+#include <port_def.inc>
+
+#ifdef SWIG
+#error "You cannot SWIG proto headers"
+#endif
+
+namespace google {
+namespace protobuf {
+
+namespace io {
+class ErrorCollector; // tokenizer.h
+}
+
+// This class implements protocol buffer text format, colloquially known as text
+// proto. Printing and parsing protocol messages in text format is useful for
+// debugging and human editing of messages.
+//
+// This class is really a namespace that contains only static methods.
+class PROTOBUF_EXPORT TextFormat {
+ public:
+ // Outputs a textual representation of the given message to the given
+ // output stream. Returns false if printing fails.
+ static bool Print(const Message& message, io::ZeroCopyOutputStream* output);
+
+ // Print the fields in an UnknownFieldSet. They are printed by tag number
+ // only. Embedded messages are heuristically identified by attempting to
+ // parse them. Returns false if printing fails.
+ static bool PrintUnknownFields(const UnknownFieldSet& unknown_fields,
+ io::ZeroCopyOutputStream* output);
+
+ // Like Print(), but outputs directly to a string.
+ // Note: output will be cleared prior to printing, and will be left empty
+ // even if printing fails. Returns false if printing fails.
+ static bool PrintToString(const Message& message, 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 format
+ // written by Print(). Returns true on success. The message is cleared first,
+ // even if the function fails -- See Merge() to avoid this behavior.
+ //
+ // Example input: "user {\n id: 123 extra { gender: MALE language: 'en' }\n}"
+ //
+ // One use for this function is parsing handwritten strings in test code.
+ // Another use is to parse the output from google::protobuf::Message::DebugString()
+ // (or ShortDebugString()), because these functions output using
+ // google::protobuf::TextFormat::Print().
+ //
+ // If you would like to read a protocol buffer serialized in the
+ // (non-human-readable) binary wire format, see
+ // google::protobuf::MessageLite::ParseFromString().
+ static bool Parse(io::ZeroCopyInputStream* input, Message* output);
+ // Like Parse(), but reads directly from a string.
+ static bool ParseFromString(ConstStringParam input, Message* output);
+
+ // Like Parse(), but the data is merged into the given message, as if
+ // using Message::MergeFrom().
+ static bool Merge(io::ZeroCopyInputStream* input, Message* output);
+ // Like Merge(), but reads directly from a string.
+ static bool MergeFromString(ConstStringParam input, Message* output);
+
+ // Parse the given text as a single field value and store it into the
+ // given field of the given message. If the field is a repeated field,
+ // the new value will be added to the end
+ static bool ParseFieldValueFromString(const 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 <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_TEXT_FORMAT_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/text_format_unittest.cc b/NorthstarDedicatedTest/include/protobuf/text_format_unittest.cc
new file mode 100644
index 00000000..3cf10f66
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/text_format_unittest.cc
@@ -0,0 +1,2400 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 <text_format.h>
+
+#include <math.h>
+#include <stdlib.h>
+
+#include <atomic>
+#include <limits>
+#include <memory>
+
+#include <stubs/logging.h>
+#include <stubs/common.h>
+#include <testing/file.h>
+#include <testing/file.h>
+#include <any.pb.h>
+#include <map_unittest.pb.h>
+#include <test_util.h>
+#include <test_util2.h>
+#include <unittest.pb.h>
+#include <unittest_mset.pb.h>
+#include <unittest_mset_wire_format.pb.h>
+#include <unittest_proto3.pb.h>
+#include <io/tokenizer.h>
+#include <io/zero_copy_stream_impl.h>
+#include <stubs/strutil.h>
+#include <gmock/gmock.h>
+#include <testing/googletest.h>
+#include <gtest/gtest.h>
+#include <stubs/logging.h>
+#include <stubs/substitute.h>
+
+
+#include <port_def.inc>
+
+namespace google {
+namespace protobuf {
+
+namespace internal {
+// Controls insertion of DEBUG_STRING_SILENT_MARKER.
+extern PROTOBUF_EXPORT std::atomic<bool> enable_debug_text_format_marker;
+} // namespace internal
+
+// Can't use an anonymous namespace here due to brokenness of Tru64 compiler.
+namespace text_format_unittest {
+
+// A basic string with different escapable characters for testing.
+const std::string kEscapeTestString =
+ "\"A string with ' characters \n and \r newlines and \t tabs and \001 "
+ "slashes \\ and multiple spaces";
+
+// A representation of the above string with all the characters escaped.
+const std::string kEscapeTestStringEscaped =
+ "\"\\\"A string with \\' characters \\n and \\r newlines "
+ "and \\t tabs and \\001 slashes \\\\ and multiple spaces\"";
+
+class TextFormatTest : public testing::Test {
+ public:
+ static void SetUpTestSuite() {
+ GOOGLE_CHECK_OK(File::GetContents(
+ TestUtil::GetTestDataPath(
+ "net/proto2/internal/"
+ "testdata/text_format_unittest_data_oneof_implemented.txt"),
+ &static_proto_debug_string_, true));
+ CleanStringLineEndings(&static_proto_debug_string_, false);
+ }
+
+ TextFormatTest() : proto_debug_string_(static_proto_debug_string_) {}
+
+ protected:
+ // Debug string read from text_format_unittest_data.txt.
+ const std::string proto_debug_string_;
+ unittest::TestAllTypes proto_;
+
+ private:
+ static std::string static_proto_debug_string_;
+};
+std::string TextFormatTest::static_proto_debug_string_;
+
+class TextFormatExtensionsTest : public testing::Test {
+ public:
+ static void SetUpTestSuite() {
+ GOOGLE_CHECK_OK(File::GetContents(
+ TestUtil::GetTestDataPath("net/proto2/internal/testdata/"
+ "text_format_unittest_extensions_data.txt"),
+ &static_proto_debug_string_, true));
+ CleanStringLineEndings(&static_proto_debug_string_, false);
+ }
+
+ TextFormatExtensionsTest()
+ : proto_debug_string_(static_proto_debug_string_) {}
+
+ protected:
+ // Debug string read from text_format_unittest_data.txt.
+ const std::string proto_debug_string_;
+ unittest::TestAllExtensions proto_;
+
+ private:
+ static std::string static_proto_debug_string_;
+};
+std::string TextFormatExtensionsTest::static_proto_debug_string_;
+
+TEST_F(TextFormatTest, Basic) {
+ TestUtil::SetAllFields(&proto_);
+ EXPECT_EQ(proto_debug_string_, proto_.DebugString());
+}
+
+TEST_F(TextFormatExtensionsTest, Extensions) {
+ TestUtil::SetAllExtensions(&proto_);
+ EXPECT_EQ(proto_debug_string_, proto_.DebugString());
+}
+
+TEST_F(TextFormatTest, ShortDebugString) {
+ proto_.set_optional_int32(1);
+ proto_.set_optional_string("hello");
+ proto_.mutable_optional_nested_message()->set_bb(2);
+ proto_.mutable_optional_foreign_message();
+
+ EXPECT_EQ(
+ "optional_int32: 1 optional_string: \"hello\" "
+ "optional_nested_message { bb: 2 } "
+ "optional_foreign_message { }",
+ proto_.ShortDebugString());
+}
+
+TEST_F(TextFormatTest, ShortPrimitiveRepeateds) {
+ proto_.set_optional_int32(123);
+ proto_.add_repeated_int32(456);
+ proto_.add_repeated_int32(789);
+ proto_.add_repeated_string("foo");
+ proto_.add_repeated_string("bar");
+ proto_.add_repeated_nested_message()->set_bb(2);
+ proto_.add_repeated_nested_message()->set_bb(3);
+ proto_.add_repeated_nested_enum(unittest::TestAllTypes::FOO);
+ proto_.add_repeated_nested_enum(unittest::TestAllTypes::BAR);
+
+ TextFormat::Printer printer;
+ printer.SetUseShortRepeatedPrimitives(true);
+ std::string text;
+ EXPECT_TRUE(printer.PrintToString(proto_, &text));
+
+ EXPECT_EQ(
+ "optional_int32: 123\n"
+ "repeated_int32: [456, 789]\n"
+ "repeated_string: \"foo\"\n"
+ "repeated_string: \"bar\"\n"
+ "repeated_nested_message {\n bb: 2\n}\n"
+ "repeated_nested_message {\n bb: 3\n}\n"
+ "repeated_nested_enum: [FOO, BAR]\n",
+ text);
+
+ // Verify that any existing data in the string is cleared when PrintToString()
+ // is called.
+ text = "just some data here...\n\nblah blah";
+ EXPECT_TRUE(printer.PrintToString(proto_, &text));
+
+ EXPECT_EQ(
+ "optional_int32: 123\n"
+ "repeated_int32: [456, 789]\n"
+ "repeated_string: \"foo\"\n"
+ "repeated_string: \"bar\"\n"
+ "repeated_nested_message {\n bb: 2\n}\n"
+ "repeated_nested_message {\n bb: 3\n}\n"
+ "repeated_nested_enum: [FOO, BAR]\n",
+ text);
+
+ // Try in single-line mode.
+ printer.SetSingleLineMode(true);
+ EXPECT_TRUE(printer.PrintToString(proto_, &text));
+
+ EXPECT_EQ(
+ "optional_int32: 123 "
+ "repeated_int32: [456, 789] "
+ "repeated_string: \"foo\" "
+ "repeated_string: \"bar\" "
+ "repeated_nested_message { bb: 2 } "
+ "repeated_nested_message { bb: 3 } "
+ "repeated_nested_enum: [FOO, BAR] ",
+ text);
+}
+
+
+TEST_F(TextFormatTest, StringEscape) {
+ // Set the string value to test.
+ proto_.set_optional_string(kEscapeTestString);
+
+ // Get the DebugString from the proto.
+ std::string debug_string = proto_.DebugString();
+ std::string utf8_debug_string = proto_.Utf8DebugString();
+
+ // Hardcode a correct value to test against.
+ std::string correct_string =
+ "optional_string: " + kEscapeTestStringEscaped + "\n";
+
+ // Compare.
+ EXPECT_EQ(correct_string, debug_string);
+ // UTF-8 string is the same as non-UTF-8 because
+ // the protocol buffer contains no UTF-8 text.
+ EXPECT_EQ(correct_string, utf8_debug_string);
+
+ std::string expected_short_debug_string =
+ "optional_string: " + kEscapeTestStringEscaped;
+ EXPECT_EQ(expected_short_debug_string, proto_.ShortDebugString());
+}
+
+TEST_F(TextFormatTest, Utf8DebugString) {
+ // Set the string value to test.
+ proto_.set_optional_string("\350\260\267\346\255\214");
+ proto_.set_optional_bytes("\350\260\267\346\255\214");
+
+ // Get the DebugString from the proto.
+ std::string debug_string = proto_.DebugString();
+ std::string utf8_debug_string = proto_.Utf8DebugString();
+
+ // Hardcode a correct value to test against.
+ std::string correct_utf8_string =
+ "optional_string: "
+ "\"\350\260\267\346\255\214\""
+ "\n"
+ "optional_bytes: "
+ "\"\\350\\260\\267\\346\\255\\214\""
+ "\n";
+ std::string correct_string =
+ "optional_string: "
+ "\"\\350\\260\\267\\346\\255\\214\""
+ "\n"
+ "optional_bytes: "
+ "\"\\350\\260\\267\\346\\255\\214\""
+ "\n";
+
+ // Compare.
+ EXPECT_EQ(correct_utf8_string, utf8_debug_string);
+ EXPECT_EQ(correct_string, debug_string);
+}
+
+TEST_F(TextFormatTest, PrintUnknownFields) {
+ // Test printing of unknown fields in a message.
+
+ unittest::TestEmptyMessage message;
+ UnknownFieldSet* unknown_fields = message.mutable_unknown_fields();
+
+ unknown_fields->AddVarint(5, 1);
+ unknown_fields->AddFixed32(5, 2);
+ unknown_fields->AddFixed64(5, 3);
+ unknown_fields->AddLengthDelimited(5, "4");
+ unknown_fields->AddGroup(5)->AddVarint(10, 5);
+
+ unknown_fields->AddVarint(8, 1);
+ unknown_fields->AddVarint(8, 2);
+ unknown_fields->AddVarint(8, 3);
+
+ EXPECT_EQ(
+ "5: 1\n"
+ "5: 0x00000002\n"
+ "5: 0x0000000000000003\n"
+ "5: \"4\"\n"
+ "5 {\n"
+ " 10: 5\n"
+ "}\n"
+ "8: 1\n"
+ "8: 2\n"
+ "8: 3\n",
+ message.DebugString());
+}
+
+TEST_F(TextFormatTest, PrintUnknownFieldsHidden) {
+ // Test printing of unknown fields in a message when suppressed.
+
+ unittest::OneString message;
+ message.set_data("data");
+ UnknownFieldSet* unknown_fields = message.mutable_unknown_fields();
+
+ unknown_fields->AddVarint(5, 1);
+ unknown_fields->AddFixed32(5, 2);
+ unknown_fields->AddFixed64(5, 3);
+ unknown_fields->AddLengthDelimited(5, "4");
+ unknown_fields->AddGroup(5)->AddVarint(10, 5);
+
+ unknown_fields->AddVarint(8, 1);
+ unknown_fields->AddVarint(8, 2);
+ unknown_fields->AddVarint(8, 3);
+
+ TextFormat::Printer printer;
+ printer.SetHideUnknownFields(true);
+ std::string output;
+ printer.PrintToString(message, &output);
+
+ EXPECT_EQ("data: \"data\"\n", output);
+}
+
+TEST_F(TextFormatTest, PrintUnknownMessage) {
+ // Test heuristic printing of messages in an UnknownFieldSet.
+
+ protobuf_unittest::TestAllTypes message;
+
+ // Cases which should not be interpreted as sub-messages.
+
+ // 'a' is a valid FIXED64 tag, so for the string to be parseable as a message
+ // it should be followed by 8 bytes. Since this string only has two
+ // subsequent bytes, it should be treated as a string.
+ message.add_repeated_string("abc");
+
+ // 'd' happens to be a valid ENDGROUP tag. So,
+ // UnknownFieldSet::MergeFromCodedStream() will successfully parse "def", but
+ // the ConsumedEntireMessage() check should fail.
+ message.add_repeated_string("def");
+
+ // A zero-length string should never be interpreted as a message even though
+ // it is technically valid as one.
+ message.add_repeated_string("");
+
+ // Case which should be interpreted as a sub-message.
+
+ // An actual nested message with content should always be interpreted as a
+ // nested message.
+ message.add_repeated_nested_message()->set_bb(123);
+
+ std::string data;
+ message.SerializeToString(&data);
+
+ std::string text;
+ UnknownFieldSet unknown_fields;
+ EXPECT_TRUE(unknown_fields.ParseFromString(data));
+ EXPECT_TRUE(TextFormat::PrintUnknownFieldsToString(unknown_fields, &text));
+ // Field 44 and 48 can be printed in any order.
+ EXPECT_THAT(text, testing::HasSubstr("44: \"abc\"\n"
+ "44: \"def\"\n"
+ "44: \"\"\n"));
+ EXPECT_THAT(text, testing::HasSubstr("48 {\n"
+ " 1: 123\n"
+ "}\n"));
+}
+
+TEST_F(TextFormatTest, PrintDeeplyNestedUnknownMessage) {
+ // Create a deeply nested message.
+ static constexpr int kNestingDepth = 25000;
+ static constexpr int kUnknownFieldNumber = 1;
+ std::vector<int> lengths;
+ lengths.reserve(kNestingDepth);
+ lengths.push_back(0);
+ for (int i = 0; i < kNestingDepth - 1; ++i) {
+ lengths.push_back(
+ internal::WireFormatLite::TagSize(
+ kUnknownFieldNumber, internal::WireFormatLite::TYPE_BYTES) +
+ internal::WireFormatLite::LengthDelimitedSize(lengths.back()));
+ }
+ std::string serialized;
+ {
+ io::StringOutputStream zero_copy_stream(&serialized);
+ io::CodedOutputStream coded_stream(&zero_copy_stream);
+ for (int i = kNestingDepth - 1; i >= 0; --i) {
+ internal::WireFormatLite::WriteTag(
+ kUnknownFieldNumber,
+ internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED, &coded_stream);
+ coded_stream.WriteVarint32(lengths[i]);
+ }
+ }
+
+ // Parse the data and verify that we can print it without overflowing the
+ // stack.
+ unittest::TestEmptyMessage message;
+ ASSERT_TRUE(message.ParseFromString(serialized));
+ std::string text;
+ EXPECT_TRUE(TextFormat::PrintToString(message, &text));
+}
+
+TEST_F(TextFormatTest, PrintMessageWithIndent) {
+ // Test adding an initial indent to printing.
+
+ protobuf_unittest::TestAllTypes message;
+
+ message.add_repeated_string("abc");
+ message.add_repeated_string("def");
+ message.add_repeated_nested_message()->set_bb(123);
+
+ std::string text;
+ TextFormat::Printer printer;
+ printer.SetInitialIndentLevel(1);
+ EXPECT_TRUE(printer.PrintToString(message, &text));
+ EXPECT_EQ(
+ " repeated_string: \"abc\"\n"
+ " repeated_string: \"def\"\n"
+ " repeated_nested_message {\n"
+ " bb: 123\n"
+ " }\n",
+ text);
+}
+
+TEST_F(TextFormatTest, PrintMessageSingleLine) {
+ // Test printing a message on a single line.
+
+ protobuf_unittest::TestAllTypes message;
+
+ message.add_repeated_string("abc");
+ message.add_repeated_string("def");
+ message.add_repeated_nested_message()->set_bb(123);
+
+ std::string text;
+ TextFormat::Printer printer;
+ printer.SetInitialIndentLevel(1);
+ printer.SetSingleLineMode(true);
+ EXPECT_TRUE(printer.PrintToString(message, &text));
+ EXPECT_EQ(
+ " repeated_string: \"abc\" repeated_string: \"def\" "
+ "repeated_nested_message { bb: 123 } ",
+ text);
+}
+
+TEST_F(TextFormatTest, PrintBufferTooSmall) {
+ // Test printing a message to a buffer that is too small.
+
+ protobuf_unittest::TestAllTypes message;
+
+ message.add_repeated_string("abc");
+ message.add_repeated_string("def");
+
+ char buffer[1] = "";
+ io::ArrayOutputStream output_stream(buffer, 1);
+ EXPECT_FALSE(TextFormat::Print(message, &output_stream));
+ EXPECT_EQ(buffer[0], 'r');
+ EXPECT_EQ(output_stream.ByteCount(), 1);
+}
+
+// A printer that appends 'u' to all unsigned int32.
+class CustomUInt32FieldValuePrinter : public TextFormat::FieldValuePrinter {
+ public:
+ virtual std::string PrintUInt32(uint32 val) const {
+ return StrCat(FieldValuePrinter::PrintUInt32(val), "u");
+ }
+};
+
+TEST_F(TextFormatTest, DefaultCustomFieldPrinter) {
+ protobuf_unittest::TestAllTypes message;
+
+ message.set_optional_uint32(42);
+ message.add_repeated_uint32(1);
+ message.add_repeated_uint32(2);
+ message.add_repeated_uint32(3);
+
+ TextFormat::Printer printer;
+ printer.SetDefaultFieldValuePrinter(new CustomUInt32FieldValuePrinter());
+ // Let's see if that works well together with the repeated primitives:
+ printer.SetUseShortRepeatedPrimitives(true);
+ std::string text;
+ printer.PrintToString(message, &text);
+ EXPECT_EQ("optional_uint32: 42u\nrepeated_uint32: [1u, 2u, 3u]\n", text);
+}
+
+class CustomInt32FieldValuePrinter : public TextFormat::FieldValuePrinter {
+ public:
+ virtual std::string PrintInt32(int32 val) const {
+ return StrCat("value-is(", FieldValuePrinter::PrintInt32(val), ")");
+ }
+};
+
+TEST_F(TextFormatTest, FieldSpecificCustomPrinter) {
+ protobuf_unittest::TestAllTypes message;
+
+ message.set_optional_int32(42); // This will be handled by our Printer.
+ message.add_repeated_int32(42); // This will be printed as number.
+
+ TextFormat::Printer printer;
+ EXPECT_TRUE(printer.RegisterFieldValuePrinter(
+ message.GetDescriptor()->FindFieldByName("optional_int32"),
+ new CustomInt32FieldValuePrinter()));
+ std::string text;
+ printer.PrintToString(message, &text);
+ EXPECT_EQ("optional_int32: value-is(42)\nrepeated_int32: 42\n", text);
+}
+
+TEST_F(TextFormatTest, FieldSpecificCustomPrinterRegisterSameFieldTwice) {
+ protobuf_unittest::TestAllTypes message;
+ TextFormat::Printer printer;
+ const FieldDescriptor* const field =
+ message.GetDescriptor()->FindFieldByName("optional_int32");
+ ASSERT_TRUE(printer.RegisterFieldValuePrinter(
+ field, new CustomInt32FieldValuePrinter()));
+ const TextFormat::FieldValuePrinter* const rejected =
+ new CustomInt32FieldValuePrinter();
+ ASSERT_FALSE(printer.RegisterFieldValuePrinter(field, rejected));
+ delete rejected;
+}
+
+TEST_F(TextFormatTest, ErrorCasesRegisteringFieldValuePrinterShouldFail) {
+ protobuf_unittest::TestAllTypes message;
+ TextFormat::Printer printer;
+ // nullptr printer.
+ EXPECT_FALSE(printer.RegisterFieldValuePrinter(
+ message.GetDescriptor()->FindFieldByName("optional_int32"),
+ static_cast<const TextFormat::FieldValuePrinter*>(nullptr)));
+ EXPECT_FALSE(printer.RegisterFieldValuePrinter(
+ message.GetDescriptor()->FindFieldByName("optional_int32"),
+ static_cast<const TextFormat::FastFieldValuePrinter*>(nullptr)));
+ // Because registration fails, the ownership of this printer is never taken.
+ TextFormat::FieldValuePrinter my_field_printer;
+ // nullptr field
+ EXPECT_FALSE(printer.RegisterFieldValuePrinter(nullptr, &my_field_printer));
+}
+
+class CustomMessageFieldValuePrinter : public TextFormat::FieldValuePrinter {
+ public:
+ virtual std::string PrintInt32(int32 v) const {
+ return StrCat(FieldValuePrinter::PrintInt32(v), " # x",
+ strings::Hex(v));
+ }
+
+ virtual std::string PrintMessageStart(const Message& message, int field_index,
+ int field_count,
+ bool single_line_mode) const {
+ if (single_line_mode) {
+ return " { ";
+ }
+ return StrCat(" { # ", message.GetDescriptor()->name(), ": ",
+ field_index, "\n");
+ }
+};
+
+TEST_F(TextFormatTest, CustomPrinterForComments) {
+ protobuf_unittest::TestAllTypes message;
+ message.mutable_optional_nested_message();
+ message.mutable_optional_import_message()->set_d(42);
+ message.add_repeated_nested_message();
+ message.add_repeated_nested_message();
+ message.add_repeated_import_message()->set_d(43);
+ message.add_repeated_import_message()->set_d(44);
+ TextFormat::Printer printer;
+ CustomMessageFieldValuePrinter my_field_printer;
+ printer.SetDefaultFieldValuePrinter(new CustomMessageFieldValuePrinter());
+ std::string text;
+ printer.PrintToString(message, &text);
+ EXPECT_EQ(
+ "optional_nested_message { # NestedMessage: -1\n"
+ "}\n"
+ "optional_import_message { # ImportMessage: -1\n"
+ " d: 42 # x2a\n"
+ "}\n"
+ "repeated_nested_message { # NestedMessage: 0\n"
+ "}\n"
+ "repeated_nested_message { # NestedMessage: 1\n"
+ "}\n"
+ "repeated_import_message { # ImportMessage: 0\n"
+ " d: 43 # x2b\n"
+ "}\n"
+ "repeated_import_message { # ImportMessage: 1\n"
+ " d: 44 # x2c\n"
+ "}\n",
+ text);
+}
+
+class CustomMessageContentFieldValuePrinter
+ : public TextFormat::FastFieldValuePrinter {
+ public:
+ bool PrintMessageContent(
+ const Message& message, int field_index, int field_count,
+ bool single_line_mode,
+ TextFormat::BaseTextGenerator* generator) const override {
+ if (message.ByteSizeLong() > 0) {
+ generator->PrintString(
+ strings::Substitute("# REDACTED, $0 bytes\n", message.ByteSizeLong()));
+ }
+ return true;
+ }
+};
+
+TEST_F(TextFormatTest, CustomPrinterForMessageContent) {
+ protobuf_unittest::TestAllTypes message;
+ message.mutable_optional_nested_message();
+ message.mutable_optional_import_message()->set_d(42);
+ message.add_repeated_nested_message();
+ message.add_repeated_nested_message();
+ message.add_repeated_import_message()->set_d(43);
+ message.add_repeated_import_message()->set_d(44);
+ TextFormat::Printer printer;
+ CustomMessageContentFieldValuePrinter my_field_printer;
+ printer.SetDefaultFieldValuePrinter(
+ new CustomMessageContentFieldValuePrinter());
+ std::string text;
+ printer.PrintToString(message, &text);
+ EXPECT_EQ(
+ "optional_nested_message {\n"
+ "}\n"
+ "optional_import_message {\n"
+ " # REDACTED, 2 bytes\n"
+ "}\n"
+ "repeated_nested_message {\n"
+ "}\n"
+ "repeated_nested_message {\n"
+ "}\n"
+ "repeated_import_message {\n"
+ " # REDACTED, 2 bytes\n"
+ "}\n"
+ "repeated_import_message {\n"
+ " # REDACTED, 2 bytes\n"
+ "}\n",
+ text);
+}
+
+class CustomMultilineCommentPrinter : public TextFormat::FieldValuePrinter {
+ public:
+ virtual std::string PrintMessageStart(const Message& message, int field_index,
+ int field_count,
+ bool single_line_comment) const {
+ return StrCat(" { # 1\n", " # 2\n");
+ }
+};
+
+TEST_F(TextFormatTest, CustomPrinterForMultilineComments) {
+ protobuf_unittest::TestAllTypes message;
+ message.mutable_optional_nested_message();
+ message.mutable_optional_import_message()->set_d(42);
+ TextFormat::Printer printer;
+ CustomMessageFieldValuePrinter my_field_printer;
+ printer.SetDefaultFieldValuePrinter(new CustomMultilineCommentPrinter());
+ std::string text;
+ printer.PrintToString(message, &text);
+ EXPECT_EQ(
+ "optional_nested_message { # 1\n"
+ " # 2\n"
+ "}\n"
+ "optional_import_message { # 1\n"
+ " # 2\n"
+ " d: 42\n"
+ "}\n",
+ text);
+}
+
+// Achieve effects similar to SetUseShortRepeatedPrimitives for messages, using
+// RegisterFieldValuePrinter. Use this to test the version of PrintFieldName
+// that accepts repeated field index and count.
+class CompactRepeatedFieldPrinter : public TextFormat::FastFieldValuePrinter {
+ public:
+ void PrintFieldName(const Message& message, int field_index, int field_count,
+ const Reflection* reflection,
+ const FieldDescriptor* field,
+ TextFormat::BaseTextGenerator* generator) const override {
+ if (field_index == 0 || field_index == -1) {
+ generator->PrintString(field->name());
+ }
+ }
+ // To prevent compiler complaining about Woverloaded-virtual
+ void PrintFieldName(const Message& message, const Reflection* reflection,
+ const FieldDescriptor* field,
+ TextFormat::BaseTextGenerator* generator) const override {
+ }
+ void PrintMessageStart(
+ const Message& message, int field_index, int field_count,
+ bool single_line_mode,
+ TextFormat::BaseTextGenerator* generator) const override {
+ if (field_index == 0 || field_index == -1) {
+ if (single_line_mode) {
+ generator->PrintLiteral(" { ");
+ } else {
+ generator->PrintLiteral(" {\n");
+ }
+ }
+ }
+ void PrintMessageEnd(
+ const Message& message, int field_index, int field_count,
+ bool single_line_mode,
+ TextFormat::BaseTextGenerator* generator) const override {
+ if (field_index == field_count - 1 || field_index == -1) {
+ if (single_line_mode) {
+ generator->PrintLiteral("} ");
+ } else {
+ generator->PrintLiteral("}\n");
+ }
+ }
+ }
+};
+
+TEST_F(TextFormatTest, CompactRepeatedFieldPrinter) {
+ TextFormat::Printer printer;
+ ASSERT_TRUE(printer.RegisterFieldValuePrinter(
+ unittest::TestAllTypes::default_instance()
+ .descriptor()
+ ->FindFieldByNumber(
+ unittest::TestAllTypes::kRepeatedNestedMessageFieldNumber),
+ new CompactRepeatedFieldPrinter));
+
+ protobuf_unittest::TestAllTypes message;
+ message.add_repeated_nested_message()->set_bb(1);
+ message.add_repeated_nested_message()->set_bb(2);
+ message.add_repeated_nested_message()->set_bb(3);
+
+ std::string text;
+ ASSERT_TRUE(printer.PrintToString(message, &text));
+ EXPECT_EQ(
+ "repeated_nested_message {\n"
+ " bb: 1\n"
+ " bb: 2\n"
+ " bb: 3\n"
+ "}\n",
+ text);
+}
+
+// Print strings into multiple line, with indentation. Use this to test
+// BaseTextGenerator::Indent and BaseTextGenerator::Outdent.
+class MultilineStringPrinter : public TextFormat::FastFieldValuePrinter {
+ public:
+ void PrintString(const std::string& val,
+ TextFormat::BaseTextGenerator* generator) const override {
+ generator->Indent();
+ int last_pos = 0;
+ int newline_pos = val.find('\n');
+ while (newline_pos != std::string::npos) {
+ generator->PrintLiteral("\n");
+ TextFormat::FastFieldValuePrinter::PrintString(
+ val.substr(last_pos, newline_pos + 1 - last_pos), generator);
+ last_pos = newline_pos + 1;
+ newline_pos = val.find('\n', last_pos);
+ }
+ if (last_pos < val.size()) {
+ generator->PrintLiteral("\n");
+ TextFormat::FastFieldValuePrinter::PrintString(val.substr(last_pos),
+ generator);
+ }
+ generator->Outdent();
+ }
+};
+
+TEST_F(TextFormatTest, MultilineStringPrinter) {
+ TextFormat::Printer printer;
+ ASSERT_TRUE(printer.RegisterFieldValuePrinter(
+ unittest::TestAllTypes::default_instance()
+ .descriptor()
+ ->FindFieldByNumber(
+ unittest::TestAllTypes::kOptionalStringFieldNumber),
+ new MultilineStringPrinter));
+
+ protobuf_unittest::TestAllTypes message;
+ message.set_optional_string("first line\nsecond line\nthird line");
+
+ std::string text;
+ ASSERT_TRUE(printer.PrintToString(message, &text));
+ EXPECT_EQ(
+ "optional_string: \n"
+ " \"first line\\n\"\n"
+ " \"second line\\n\"\n"
+ " \"third line\"\n",
+ text);
+}
+
+class CustomNestedMessagePrinter : public TextFormat::MessagePrinter {
+ public:
+ CustomNestedMessagePrinter() {}
+ ~CustomNestedMessagePrinter() override {}
+ void Print(const Message& message, bool single_line_mode,
+ TextFormat::BaseTextGenerator* generator) const override {
+ generator->PrintLiteral("custom");
+ }
+};
+
+TEST_F(TextFormatTest, CustomMessagePrinter) {
+ TextFormat::Printer printer;
+ printer.RegisterMessagePrinter(
+ unittest::TestAllTypes::NestedMessage::default_instance().descriptor(),
+ new CustomNestedMessagePrinter);
+
+ unittest::TestAllTypes message;
+ std::string text;
+ EXPECT_TRUE(printer.PrintToString(message, &text));
+ EXPECT_EQ("", text);
+
+ message.mutable_optional_nested_message()->set_bb(1);
+ EXPECT_TRUE(printer.PrintToString(message, &text));
+ EXPECT_EQ("optional_nested_message {\n custom}\n", text);
+}
+
+TEST_F(TextFormatTest, ParseBasic) {
+ io::ArrayInputStream input_stream(proto_debug_string_.data(),
+ proto_debug_string_.size());
+ TextFormat::Parse(&input_stream, &proto_);
+ TestUtil::ExpectAllFieldsSet(proto_);
+}
+
+TEST_F(TextFormatExtensionsTest, ParseExtensions) {
+ io::ArrayInputStream input_stream(proto_debug_string_.data(),
+ proto_debug_string_.size());
+ TextFormat::Parse(&input_stream, &proto_);
+ TestUtil::ExpectAllExtensionsSet(proto_);
+}
+
+TEST_F(TextFormatTest, ParseEnumFieldFromNumber) {
+ // Create a parse string with a numerical value for an enum field.
+ std::string parse_string =
+ strings::Substitute("optional_nested_enum: $0", unittest::TestAllTypes::BAZ);
+ EXPECT_TRUE(TextFormat::ParseFromString(parse_string, &proto_));
+ EXPECT_TRUE(proto_.has_optional_nested_enum());
+ EXPECT_EQ(unittest::TestAllTypes::BAZ, proto_.optional_nested_enum());
+}
+
+TEST_F(TextFormatTest, ParseEnumFieldFromNegativeNumber) {
+ ASSERT_LT(unittest::SPARSE_E, 0);
+ std::string parse_string =
+ strings::Substitute("sparse_enum: $0", unittest::SPARSE_E);
+ unittest::SparseEnumMessage proto;
+ EXPECT_TRUE(TextFormat::ParseFromString(parse_string, &proto));
+ EXPECT_TRUE(proto.has_sparse_enum());
+ EXPECT_EQ(unittest::SPARSE_E, proto.sparse_enum());
+}
+
+TEST_F(TextFormatTest, PrintUnknownEnumFieldProto3) {
+ proto3_unittest::TestAllTypes proto;
+
+ proto.add_repeated_nested_enum(
+ static_cast<proto3_unittest::TestAllTypes::NestedEnum>(10));
+ proto.add_repeated_nested_enum(
+ static_cast<proto3_unittest::TestAllTypes::NestedEnum>(-10));
+ proto.add_repeated_nested_enum(
+ static_cast<proto3_unittest::TestAllTypes::NestedEnum>(2147483647));
+ proto.add_repeated_nested_enum(
+ static_cast<proto3_unittest::TestAllTypes::NestedEnum>(-2147483648));
+
+ EXPECT_EQ(
+ "repeated_nested_enum: 10\n"
+ "repeated_nested_enum: -10\n"
+ "repeated_nested_enum: 2147483647\n"
+ "repeated_nested_enum: -2147483648\n",
+ proto.DebugString());
+}
+
+TEST_F(TextFormatTest, ParseUnknownEnumFieldProto3) {
+ proto3_unittest::TestAllTypes proto;
+ std::string parse_string =
+ "repeated_nested_enum: [10, -10, 2147483647, -2147483648]";
+ EXPECT_TRUE(TextFormat::ParseFromString(parse_string, &proto));
+ ASSERT_EQ(4, proto.repeated_nested_enum_size());
+ EXPECT_EQ(10, proto.repeated_nested_enum(0));
+ EXPECT_EQ(-10, proto.repeated_nested_enum(1));
+ EXPECT_EQ(2147483647, proto.repeated_nested_enum(2));
+ EXPECT_EQ(-2147483648, proto.repeated_nested_enum(3));
+}
+
+TEST_F(TextFormatTest, ParseStringEscape) {
+ // Create a parse string with escaped characters in it.
+ std::string parse_string =
+ "optional_string: " + kEscapeTestStringEscaped + "\n";
+
+ io::ArrayInputStream input_stream(parse_string.data(), parse_string.size());
+ TextFormat::Parse(&input_stream, &proto_);
+
+ // Compare.
+ EXPECT_EQ(kEscapeTestString, proto_.optional_string());
+}
+
+TEST_F(TextFormatTest, ParseConcatenatedString) {
+ // Create a parse string with multiple parts on one line.
+ std::string parse_string = "optional_string: \"foo\" \"bar\"\n";
+
+ io::ArrayInputStream input_stream1(parse_string.data(), parse_string.size());
+ TextFormat::Parse(&input_stream1, &proto_);
+
+ // Compare.
+ EXPECT_EQ("foobar", proto_.optional_string());
+
+ // Create a parse string with multiple parts on separate lines.
+ parse_string =
+ "optional_string: \"foo\"\n"
+ "\"bar\"\n";
+
+ io::ArrayInputStream input_stream2(parse_string.data(), parse_string.size());
+ TextFormat::Parse(&input_stream2, &proto_);
+
+ // Compare.
+ EXPECT_EQ("foobar", proto_.optional_string());
+}
+
+TEST_F(TextFormatTest, ParseFloatWithSuffix) {
+ // Test that we can parse a floating-point value with 'f' appended to the
+ // end. This is needed for backwards-compatibility with proto1.
+
+ // Have it parse a float with the 'f' suffix.
+ std::string parse_string = "optional_float: 1.0f\n";
+
+ io::ArrayInputStream input_stream(parse_string.data(), parse_string.size());
+
+ TextFormat::Parse(&input_stream, &proto_);
+
+ // Compare.
+ EXPECT_EQ(1.0, proto_.optional_float());
+}
+
+TEST_F(TextFormatTest, ParseShortRepeatedForm) {
+ std::string parse_string =
+ // Mixed short-form and long-form are simply concatenated.
+ "repeated_int32: 1\n"
+ "repeated_int32: [456, 789]\n"
+ "repeated_nested_enum: [ FOO ,BAR, # comment\n"
+ " 3]\n"
+ // Note that while the printer won't print repeated strings in short-form,
+ // the parser will accept them.
+ "repeated_string: [ \"foo\", 'bar' ]\n"
+ // Repeated message
+ "repeated_nested_message: [ { bb: 1 }, { bb : 2 }]\n"
+ // Repeated group
+ "RepeatedGroup [{ a: 3 },{ a: 4 }]\n";
+
+ ASSERT_TRUE(TextFormat::ParseFromString(parse_string, &proto_));
+
+ ASSERT_EQ(3, proto_.repeated_int32_size());
+ EXPECT_EQ(1, proto_.repeated_int32(0));
+ EXPECT_EQ(456, proto_.repeated_int32(1));
+ EXPECT_EQ(789, proto_.repeated_int32(2));
+
+ ASSERT_EQ(3, proto_.repeated_nested_enum_size());
+ EXPECT_EQ(unittest::TestAllTypes::FOO, proto_.repeated_nested_enum(0));
+ EXPECT_EQ(unittest::TestAllTypes::BAR, proto_.repeated_nested_enum(1));
+ EXPECT_EQ(unittest::TestAllTypes::BAZ, proto_.repeated_nested_enum(2));
+
+ ASSERT_EQ(2, proto_.repeated_string_size());
+ EXPECT_EQ("foo", proto_.repeated_string(0));
+ EXPECT_EQ("bar", proto_.repeated_string(1));
+
+ ASSERT_EQ(2, proto_.repeated_nested_message_size());
+ EXPECT_EQ(1, proto_.repeated_nested_message(0).bb());
+ EXPECT_EQ(2, proto_.repeated_nested_message(1).bb());
+
+ ASSERT_EQ(2, proto_.repeatedgroup_size());
+ EXPECT_EQ(3, proto_.repeatedgroup(0).a());
+ EXPECT_EQ(4, proto_.repeatedgroup(1).a());
+}
+
+TEST_F(TextFormatTest, ParseShortRepeatedWithTrailingComma) {
+ std::string parse_string = "repeated_int32: [456,]\n";
+ ASSERT_FALSE(TextFormat::ParseFromString(parse_string, &proto_));
+ parse_string = "repeated_nested_enum: [ FOO , ]";
+ ASSERT_FALSE(TextFormat::ParseFromString(parse_string, &proto_));
+ parse_string = "repeated_string: [ \"foo\", ]";
+ ASSERT_FALSE(TextFormat::ParseFromString(parse_string, &proto_));
+ parse_string = "repeated_nested_message: [ { bb: 1 }, ]";
+ ASSERT_FALSE(TextFormat::ParseFromString(parse_string, &proto_));
+ parse_string = "RepeatedGroup [{ a: 3 },]\n";
+}
+
+TEST_F(TextFormatTest, ParseShortRepeatedEmpty) {
+ std::string parse_string =
+ "repeated_int32: []\n"
+ "repeated_nested_enum: []\n"
+ "repeated_string: []\n"
+ "repeated_nested_message: []\n"
+ "RepeatedGroup []\n";
+
+ ASSERT_TRUE(TextFormat::ParseFromString(parse_string, &proto_));
+
+ EXPECT_EQ(0, proto_.repeated_int32_size());
+ EXPECT_EQ(0, proto_.repeated_nested_enum_size());
+ EXPECT_EQ(0, proto_.repeated_string_size());
+ EXPECT_EQ(0, proto_.repeated_nested_message_size());
+ EXPECT_EQ(0, proto_.repeatedgroup_size());
+}
+
+TEST_F(TextFormatTest, ParseShortRepeatedConcatenatedWithEmpty) {
+ std::string parse_string =
+ // Starting with empty [] should have no impact.
+ "repeated_int32: []\n"
+ "repeated_nested_enum: []\n"
+ "repeated_string: []\n"
+ "repeated_nested_message: []\n"
+ "RepeatedGroup []\n"
+ // Mixed short-form and long-form are simply concatenated.
+ "repeated_int32: 1\n"
+ "repeated_int32: [456, 789]\n"
+ "repeated_nested_enum: [ FOO ,BAR, # comment\n"
+ " 3]\n"
+ // Note that while the printer won't print repeated strings in short-form,
+ // the parser will accept them.
+ "repeated_string: [ \"foo\", 'bar' ]\n"
+ // Repeated message
+ "repeated_nested_message: [ { bb: 1 }, { bb : 2 }]\n"
+ // Repeated group
+ "RepeatedGroup [{ a: 3 },{ a: 4 }]\n"
+ // Adding empty [] should have no impact.
+ "repeated_int32: []\n"
+ "repeated_nested_enum: []\n"
+ "repeated_string: []\n"
+ "repeated_nested_message: []\n"
+ "RepeatedGroup []\n";
+
+ ASSERT_TRUE(TextFormat::ParseFromString(parse_string, &proto_));
+
+ ASSERT_EQ(3, proto_.repeated_int32_size());
+ EXPECT_EQ(1, proto_.repeated_int32(0));
+ EXPECT_EQ(456, proto_.repeated_int32(1));
+ EXPECT_EQ(789, proto_.repeated_int32(2));
+
+ ASSERT_EQ(3, proto_.repeated_nested_enum_size());
+ EXPECT_EQ(unittest::TestAllTypes::FOO, proto_.repeated_nested_enum(0));
+ EXPECT_EQ(unittest::TestAllTypes::BAR, proto_.repeated_nested_enum(1));
+ EXPECT_EQ(unittest::TestAllTypes::BAZ, proto_.repeated_nested_enum(2));
+
+ ASSERT_EQ(2, proto_.repeated_string_size());
+ EXPECT_EQ("foo", proto_.repeated_string(0));
+ EXPECT_EQ("bar", proto_.repeated_string(1));
+
+ ASSERT_EQ(2, proto_.repeated_nested_message_size());
+ EXPECT_EQ(1, proto_.repeated_nested_message(0).bb());
+ EXPECT_EQ(2, proto_.repeated_nested_message(1).bb());
+
+ ASSERT_EQ(2, proto_.repeatedgroup_size());
+ EXPECT_EQ(3, proto_.repeatedgroup(0).a());
+ EXPECT_EQ(4, proto_.repeatedgroup(1).a());
+}
+
+
+TEST_F(TextFormatTest, Comments) {
+ // Test that comments are ignored.
+
+ std::string parse_string =
+ "optional_int32: 1 # a comment\n"
+ "optional_int64: 2 # another comment";
+
+ io::ArrayInputStream input_stream(parse_string.data(), parse_string.size());
+
+ TextFormat::Parse(&input_stream, &proto_);
+
+ // Compare.
+ EXPECT_EQ(1, proto_.optional_int32());
+ EXPECT_EQ(2, proto_.optional_int64());
+}
+
+TEST_F(TextFormatTest, OptionalColon) {
+ // Test that we can place a ':' after the field name of a nested message,
+ // even though we don't have to.
+
+ std::string parse_string = "optional_nested_message: { bb: 1}\n";
+
+ io::ArrayInputStream input_stream(parse_string.data(), parse_string.size());
+
+ TextFormat::Parse(&input_stream, &proto_);
+
+ // Compare.
+ EXPECT_TRUE(proto_.has_optional_nested_message());
+ EXPECT_EQ(1, proto_.optional_nested_message().bb());
+}
+
+// Some platforms (e.g. Windows) insist on padding the exponent to three
+// digits when one or two would be just fine.
+static std::string RemoveRedundantZeros(std::string text) {
+ text = StringReplace(text, "e+0", "e+", true);
+ text = StringReplace(text, "e-0", "e-", true);
+ return text;
+}
+
+TEST_F(TextFormatTest, PrintExotic) {
+ unittest::TestAllTypes message;
+
+ message.add_repeated_int64(int64_t{-9223372036854775807} - 1);
+ message.add_repeated_uint64(uint64_t{18446744073709551615u});
+ message.add_repeated_double(123.456);
+ message.add_repeated_double(1.23e21);
+ message.add_repeated_double(1.23e-18);
+ message.add_repeated_double(std::numeric_limits<double>::infinity());
+ message.add_repeated_double(-std::numeric_limits<double>::infinity());
+ message.add_repeated_double(std::numeric_limits<double>::quiet_NaN());
+ message.add_repeated_double(-std::numeric_limits<double>::quiet_NaN());
+ message.add_repeated_double(std::numeric_limits<double>::signaling_NaN());
+ message.add_repeated_double(-std::numeric_limits<double>::signaling_NaN());
+ message.add_repeated_string(std::string("\000\001\a\b\f\n\r\t\v\\\'\"", 12));
+
+ // Fun story: We used to use 1.23e22 instead of 1.23e21 above, but this
+ // seemed to trigger an odd case on MinGW/GCC 3.4.5 where GCC's parsing of
+ // the value differed from strtod()'s parsing. That is to say, the
+ // following assertion fails on MinGW:
+ // assert(1.23e22 == strtod("1.23e22", nullptr));
+ // As a result, SimpleDtoa() would print the value as
+ // "1.2300000000000001e+22" to make sure strtod() produce the exact same
+ // result. Our goal is to test runtime parsing, not compile-time parsing,
+ // so this wasn't our problem. It was found that using 1.23e21 did not
+ // have this problem, so we switched to that instead.
+
+ EXPECT_EQ(
+ "repeated_int64: -9223372036854775808\n"
+ "repeated_uint64: 18446744073709551615\n"
+ "repeated_double: 123.456\n"
+ "repeated_double: 1.23e+21\n"
+ "repeated_double: 1.23e-18\n"
+ "repeated_double: inf\n"
+ "repeated_double: -inf\n"
+ "repeated_double: nan\n"
+ "repeated_double: nan\n"
+ "repeated_double: nan\n"
+ "repeated_double: nan\n"
+ "repeated_string: "
+ "\"\\000\\001\\007\\010\\014\\n\\r\\t\\013\\\\\\'\\\"\"\n",
+ RemoveRedundantZeros(message.DebugString()));
+}
+
+TEST_F(TextFormatTest, PrintFloatPrecision) {
+ unittest::TestAllTypes message;
+
+ message.add_repeated_float(1.0);
+ message.add_repeated_float(1.2);
+ message.add_repeated_float(1.23);
+ message.add_repeated_float(1.234);
+ message.add_repeated_float(1.2345);
+ message.add_repeated_float(1.23456);
+ message.add_repeated_float(1.2e10);
+ message.add_repeated_float(1.23e10);
+ message.add_repeated_float(1.234e10);
+ message.add_repeated_float(1.2345e10);
+ message.add_repeated_float(1.23456e10);
+ message.add_repeated_double(1.2);
+ message.add_repeated_double(1.23);
+ message.add_repeated_double(1.234);
+ message.add_repeated_double(1.2345);
+ message.add_repeated_double(1.23456);
+ message.add_repeated_double(1.234567);
+ message.add_repeated_double(1.2345678);
+ message.add_repeated_double(1.23456789);
+ message.add_repeated_double(1.234567898);
+ message.add_repeated_double(1.2345678987);
+ message.add_repeated_double(1.23456789876);
+ message.add_repeated_double(1.234567898765);
+ message.add_repeated_double(1.2345678987654);
+ message.add_repeated_double(1.23456789876543);
+ message.add_repeated_double(1.2e100);
+ message.add_repeated_double(1.23e100);
+ message.add_repeated_double(1.234e100);
+ message.add_repeated_double(1.2345e100);
+ message.add_repeated_double(1.23456e100);
+ message.add_repeated_double(1.234567e100);
+ message.add_repeated_double(1.2345678e100);
+ message.add_repeated_double(1.23456789e100);
+ message.add_repeated_double(1.234567898e100);
+ message.add_repeated_double(1.2345678987e100);
+ message.add_repeated_double(1.23456789876e100);
+ message.add_repeated_double(1.234567898765e100);
+ message.add_repeated_double(1.2345678987654e100);
+ message.add_repeated_double(1.23456789876543e100);
+
+ EXPECT_EQ(
+ "repeated_float: 1\n"
+ "repeated_float: 1.2\n"
+ "repeated_float: 1.23\n"
+ "repeated_float: 1.234\n"
+ "repeated_float: 1.2345\n"
+ "repeated_float: 1.23456\n"
+ "repeated_float: 1.2e+10\n"
+ "repeated_float: 1.23e+10\n"
+ "repeated_float: 1.234e+10\n"
+ "repeated_float: 1.2345e+10\n"
+ "repeated_float: 1.23456e+10\n"
+ "repeated_double: 1.2\n"
+ "repeated_double: 1.23\n"
+ "repeated_double: 1.234\n"
+ "repeated_double: 1.2345\n"
+ "repeated_double: 1.23456\n"
+ "repeated_double: 1.234567\n"
+ "repeated_double: 1.2345678\n"
+ "repeated_double: 1.23456789\n"
+ "repeated_double: 1.234567898\n"
+ "repeated_double: 1.2345678987\n"
+ "repeated_double: 1.23456789876\n"
+ "repeated_double: 1.234567898765\n"
+ "repeated_double: 1.2345678987654\n"
+ "repeated_double: 1.23456789876543\n"
+ "repeated_double: 1.2e+100\n"
+ "repeated_double: 1.23e+100\n"
+ "repeated_double: 1.234e+100\n"
+ "repeated_double: 1.2345e+100\n"
+ "repeated_double: 1.23456e+100\n"
+ "repeated_double: 1.234567e+100\n"
+ "repeated_double: 1.2345678e+100\n"
+ "repeated_double: 1.23456789e+100\n"
+ "repeated_double: 1.234567898e+100\n"
+ "repeated_double: 1.2345678987e+100\n"
+ "repeated_double: 1.23456789876e+100\n"
+ "repeated_double: 1.234567898765e+100\n"
+ "repeated_double: 1.2345678987654e+100\n"
+ "repeated_double: 1.23456789876543e+100\n",
+ RemoveRedundantZeros(message.DebugString()));
+}
+
+TEST_F(TextFormatTest, AllowPartial) {
+ unittest::TestRequired message;
+ TextFormat::Parser parser;
+ parser.AllowPartialMessage(true);
+ EXPECT_TRUE(parser.ParseFromString("a: 1", &message));
+ EXPECT_EQ(1, message.a());
+ EXPECT_FALSE(message.has_b());
+ EXPECT_FALSE(message.has_c());
+}
+
+TEST_F(TextFormatTest, ParseExotic) {
+ unittest::TestAllTypes message;
+ ASSERT_TRUE(TextFormat::ParseFromString(
+ "repeated_int32: -1\n"
+ "repeated_int32: -2147483648\n"
+ "repeated_int64: -1\n"
+ "repeated_int64: -9223372036854775808\n"
+ "repeated_uint32: 4294967295\n"
+ "repeated_uint32: 2147483648\n"
+ "repeated_uint64: 18446744073709551615\n"
+ "repeated_uint64: 9223372036854775808\n"
+ "repeated_double: 123.0\n"
+ "repeated_double: 123.5\n"
+ "repeated_double: 0.125\n"
+ "repeated_double: 1.23E17\n"
+ "repeated_double: 1.235E+22\n"
+ "repeated_double: 1.235e-18\n"
+ "repeated_double: 123.456789\n"
+ "repeated_double: inf\n"
+ "repeated_double: Infinity\n"
+ "repeated_double: -inf\n"
+ "repeated_double: -Infinity\n"
+ "repeated_double: nan\n"
+ "repeated_double: NaN\n"
+ "repeated_string: \"\\000\\001\\a\\b\\f\\n\\r\\t\\v\\\\\\'\\\"\"\n",
+ &message));
+
+ ASSERT_EQ(2, message.repeated_int32_size());
+ EXPECT_EQ(-1, message.repeated_int32(0));
+ EXPECT_EQ(-2147483648, message.repeated_int32(1));
+
+ ASSERT_EQ(2, message.repeated_int64_size());
+ EXPECT_EQ(-1, message.repeated_int64(0));
+ EXPECT_EQ(int64_t{-9223372036854775807} - 1, message.repeated_int64(1));
+
+ ASSERT_EQ(2, message.repeated_uint32_size());
+ EXPECT_EQ(4294967295u, message.repeated_uint32(0));
+ EXPECT_EQ(2147483648u, message.repeated_uint32(1));
+
+ ASSERT_EQ(2, message.repeated_uint64_size());
+ EXPECT_EQ(uint64_t{18446744073709551615u}, message.repeated_uint64(0));
+ EXPECT_EQ(uint64_t{9223372036854775808u}, message.repeated_uint64(1));
+
+ ASSERT_EQ(13, message.repeated_double_size());
+ EXPECT_EQ(123.0, message.repeated_double(0));
+ EXPECT_EQ(123.5, message.repeated_double(1));
+ EXPECT_EQ(0.125, message.repeated_double(2));
+ EXPECT_EQ(1.23E17, message.repeated_double(3));
+ EXPECT_EQ(1.235E22, message.repeated_double(4));
+ EXPECT_EQ(1.235E-18, message.repeated_double(5));
+ EXPECT_EQ(123.456789, message.repeated_double(6));
+ EXPECT_EQ(message.repeated_double(7),
+ std::numeric_limits<double>::infinity());
+ EXPECT_EQ(message.repeated_double(8),
+ std::numeric_limits<double>::infinity());
+ EXPECT_EQ(message.repeated_double(9),
+ -std::numeric_limits<double>::infinity());
+ EXPECT_EQ(message.repeated_double(10),
+ -std::numeric_limits<double>::infinity());
+ EXPECT_TRUE(std::isnan(message.repeated_double(11)));
+ EXPECT_TRUE(std::isnan(message.repeated_double(12)));
+
+ // Note: Since these string literals have \0's in them, we must explicitly
+ // pass their sizes to string's constructor.
+ ASSERT_EQ(1, message.repeated_string_size());
+ EXPECT_EQ(std::string("\000\001\a\b\f\n\r\t\v\\\'\"", 12),
+ message.repeated_string(0));
+
+ ASSERT_TRUE(
+ TextFormat::ParseFromString("repeated_float: 3.4028235e+38\n"
+ "repeated_float: -3.4028235e+38\n"
+ "repeated_float: 3.402823567797337e+38\n"
+ "repeated_float: -3.402823567797337e+38\n",
+ &message));
+ EXPECT_EQ(message.repeated_float(0), std::numeric_limits<float>::max());
+ EXPECT_EQ(message.repeated_float(1), -std::numeric_limits<float>::max());
+ EXPECT_EQ(message.repeated_float(2), std::numeric_limits<float>::infinity());
+ EXPECT_EQ(message.repeated_float(3), -std::numeric_limits<float>::infinity());
+
+}
+
+TEST_F(TextFormatTest, PrintFieldsInIndexOrder) {
+ protobuf_unittest::TestFieldOrderings message;
+ // Fields are listed in index order instead of field number.
+ message.set_my_string("str"); // Field number 11
+ message.set_my_int(12345); // Field number 1
+ message.set_my_float(0.999); // Field number 101
+ // Extensions are listed based on the order of extension number.
+ // Extension number 12.
+ message
+ .MutableExtension(
+ protobuf_unittest::TestExtensionOrderings2::test_ext_orderings2)
+ ->set_my_string("ext_str2");
+ // Extension number 13.
+ message
+ .MutableExtension(
+ protobuf_unittest::TestExtensionOrderings1::test_ext_orderings1)
+ ->set_my_string("ext_str1");
+ // Extension number 14.
+ message
+ .MutableExtension(protobuf_unittest::TestExtensionOrderings2::
+ TestExtensionOrderings3::test_ext_orderings3)
+ ->set_my_string("ext_str3");
+ // Extension number 50.
+ *message.MutableExtension(protobuf_unittest::my_extension_string) = "ext_str0";
+
+ TextFormat::Printer printer;
+ std::string text;
+
+ // By default, print in field number order.
+ // my_int: 12345
+ // my_string: "str"
+ // [protobuf_unittest.TestExtensionOrderings2.test_ext_orderings2] {
+ // my_string: "ext_str2"
+ // }
+ // [protobuf_unittest.TestExtensionOrderings1.test_ext_orderings1] {
+ // my_string: "ext_str1"
+ // }
+ // [protobuf_unittest.TestExtensionOrderings2.TestExtensionOrderings3.test_ext_orderings3]
+ // {
+ // my_string: "ext_str3"
+ // }
+ // [protobuf_unittest.my_extension_string]: "ext_str0"
+ // my_float: 0.999
+ printer.PrintToString(message, &text);
+ EXPECT_EQ(
+ "my_int: 12345\nmy_string: "
+ "\"str\"\n[protobuf_unittest.TestExtensionOrderings2.test_ext_orderings2] "
+ "{\n my_string: "
+ "\"ext_str2\"\n}\n[protobuf_unittest.TestExtensionOrderings1.test_ext_"
+ "orderings1] {\n my_string: "
+ "\"ext_str1\"\n}\n[protobuf_unittest.TestExtensionOrderings2."
+ "TestExtensionOrderings3.test_ext_orderings3] {\n my_string: "
+ "\"ext_str3\"\n}\n[protobuf_unittest.my_extension_string]: "
+ "\"ext_str0\"\nmy_float: 0.999\n",
+ text);
+
+ // Print in index order.
+ // my_string: "str"
+ // my_int: 12345
+ // my_float: 0.999
+ // [protobuf_unittest.TestExtensionOrderings2.test_ext_orderings2] {
+ // my_string: "ext_str2"
+ // }
+ // [protobuf_unittest.TestExtensionOrderings1.test_ext_orderings1] {
+ // my_string: "ext_str1"
+ // }
+ // [protobuf_unittest.TestExtensionOrderings2.TestExtensionOrderings3.test_ext_orderings3]
+ // {
+ // my_string: "ext_str3"
+ // }
+ // [protobuf_unittest.my_extension_string]: "ext_str0"
+ printer.SetPrintMessageFieldsInIndexOrder(true);
+ printer.PrintToString(message, &text);
+ EXPECT_EQ(
+ "my_string: \"str\"\nmy_int: 12345\nmy_float: "
+ "0.999\n[protobuf_unittest.TestExtensionOrderings2.test_ext_orderings2] "
+ "{\n my_string: "
+ "\"ext_str2\"\n}\n[protobuf_unittest.TestExtensionOrderings1.test_ext_"
+ "orderings1] {\n my_string: "
+ "\"ext_str1\"\n}\n[protobuf_unittest.TestExtensionOrderings2."
+ "TestExtensionOrderings3.test_ext_orderings3] {\n my_string: "
+ "\"ext_str3\"\n}\n[protobuf_unittest.my_extension_string]: \"ext_str0\"\n",
+ text);
+}
+
+class TextFormatParserTest : public testing::Test {
+ protected:
+ void ExpectFailure(const std::string& input, const std::string& message,
+ int line, int col) {
+ std::unique_ptr<unittest::TestAllTypes> proto(new unittest::TestAllTypes);
+ ExpectFailure(input, message, line, col, proto.get());
+ }
+
+ void ExpectFailure(const std::string& input, const std::string& message,
+ int line, int col, Message* proto) {
+ ExpectMessage(input, message, line, col, proto, false);
+ }
+
+ void ExpectMessage(const std::string& input, const std::string& message,
+ int line, int col, Message* proto, bool expected_result) {
+ MockErrorCollector error_collector;
+ parser_.RecordErrorsTo(&error_collector);
+ EXPECT_EQ(expected_result, parser_.ParseFromString(input, proto))
+ << input << " -> " << proto->DebugString();
+ EXPECT_EQ(StrCat(line, ":", col, ": ", message, "\n"),
+ error_collector.text_);
+ parser_.RecordErrorsTo(nullptr);
+ }
+
+ void ExpectSuccessAndTree(const std::string& input, Message* proto,
+ TextFormat::ParseInfoTree* info_tree) {
+ MockErrorCollector error_collector;
+ parser_.RecordErrorsTo(&error_collector);
+ parser_.WriteLocationsTo(info_tree);
+ EXPECT_TRUE(parser_.ParseFromString(input, proto));
+ parser_.WriteLocationsTo(nullptr);
+ parser_.RecordErrorsTo(nullptr);
+ }
+
+ void ExpectLocation(TextFormat::ParseInfoTree* tree, const Descriptor* d,
+ const std::string& field_name, int index, int start_line,
+ int start_column, int end_line, int end_column) {
+ TextFormat::ParseLocationRange range =
+ tree->GetLocationRange(d->FindFieldByName(field_name), index);
+ EXPECT_EQ(start_line, range.start.line);
+ EXPECT_EQ(start_column, range.start.column);
+ EXPECT_EQ(end_line, range.end.line);
+ EXPECT_EQ(end_column, range.end.column);
+ TextFormat::ParseLocation start_location =
+ tree->GetLocation(d->FindFieldByName(field_name), index);
+ EXPECT_EQ(start_line, start_location.line);
+ EXPECT_EQ(start_column, start_location.column);
+ }
+
+ // An error collector which simply concatenates all its errors into a big
+ // block of text which can be checked.
+ class MockErrorCollector : public io::ErrorCollector {
+ public:
+ MockErrorCollector() {}
+ ~MockErrorCollector() {}
+
+ std::string text_;
+
+ // implements ErrorCollector -------------------------------------
+ void AddError(int line, int column, const std::string& message) {
+ strings::SubstituteAndAppend(&text_, "$0:$1: $2\n", line + 1, column + 1,
+ message);
+ }
+
+ void AddWarning(int line, int column, const std::string& message) {
+ AddError(line, column, "WARNING:" + message);
+ }
+ };
+
+ TextFormat::Parser parser_;
+};
+
+TEST_F(TextFormatParserTest, ParseInfoTreeBuilding) {
+ std::unique_ptr<unittest::TestAllTypes> message(new unittest::TestAllTypes);
+ const Descriptor* d = message->GetDescriptor();
+
+ std::string stringData =
+ "optional_int32: 1\n"
+ "optional_int64: 2\n"
+ " optional_double: 2.4\n"
+ "repeated_int32: 5\n"
+ "repeated_int32: 10\n"
+ "optional_nested_message <\n"
+ " bb: 78\n"
+ ">\n"
+ "repeated_nested_message <\n"
+ " bb: 79\n"
+ ">\n"
+ "repeated_nested_message <\n"
+ " bb: 80\n"
+ ">";
+
+ TextFormat::ParseInfoTree tree;
+ ExpectSuccessAndTree(stringData, message.get(), &tree);
+
+ // Verify that the tree has the correct positions.
+ ExpectLocation(&tree, d, "optional_int32", -1, 0, 0, 0, 17);
+ ExpectLocation(&tree, d, "optional_int64", -1, 1, 0, 1, 17);
+ ExpectLocation(&tree, d, "optional_double", -1, 2, 2, 2, 22);
+
+ ExpectLocation(&tree, d, "repeated_int32", 0, 3, 0, 3, 17);
+ ExpectLocation(&tree, d, "repeated_int32", 1, 4, 0, 4, 18);
+
+ ExpectLocation(&tree, d, "optional_nested_message", -1, 5, 0, 7, 1);
+ ExpectLocation(&tree, d, "repeated_nested_message", 0, 8, 0, 10, 1);
+ ExpectLocation(&tree, d, "repeated_nested_message", 1, 11, 0, 13, 1);
+
+ // Check for fields not set. For an invalid field, the start and end locations
+ // returned should be -1, -1.
+ ExpectLocation(&tree, d, "repeated_int64", 0, -1, -1, -1, -1);
+ ExpectLocation(&tree, d, "repeated_int32", 6, -1, -1, -1, -1);
+ ExpectLocation(&tree, d, "some_unknown_field", -1, -1, -1, -1, -1);
+
+ // Verify inside the nested message.
+ const FieldDescriptor* nested_field =
+ d->FindFieldByName("optional_nested_message");
+
+ TextFormat::ParseInfoTree* nested_tree =
+ tree.GetTreeForNested(nested_field, -1);
+ ExpectLocation(nested_tree, nested_field->message_type(), "bb", -1, 6, 2, 6,
+ 8);
+
+ // Verify inside another nested message.
+ nested_field = d->FindFieldByName("repeated_nested_message");
+ nested_tree = tree.GetTreeForNested(nested_field, 0);
+ ExpectLocation(nested_tree, nested_field->message_type(), "bb", -1, 9, 2, 9,
+ 8);
+
+ nested_tree = tree.GetTreeForNested(nested_field, 1);
+ ExpectLocation(nested_tree, nested_field->message_type(), "bb", -1, 12, 2, 12,
+ 8);
+
+ // Verify a nullptr tree for an unknown nested field.
+ TextFormat::ParseInfoTree* unknown_nested_tree =
+ tree.GetTreeForNested(nested_field, 2);
+
+ EXPECT_EQ(nullptr, unknown_nested_tree);
+}
+
+TEST_F(TextFormatParserTest, ParseFieldValueFromString) {
+ std::unique_ptr<unittest::TestAllTypes> message(new unittest::TestAllTypes);
+ const Descriptor* d = message->GetDescriptor();
+
+#define EXPECT_FIELD(name, value, valuestring) \
+ EXPECT_TRUE(TextFormat::ParseFieldValueFromString( \
+ valuestring, d->FindFieldByName("optional_" #name), message.get())); \
+ EXPECT_EQ(value, message->optional_##name()); \
+ EXPECT_TRUE(message->has_optional_##name());
+
+#define EXPECT_BOOL_FIELD(name, value, valuestring) \
+ EXPECT_TRUE(TextFormat::ParseFieldValueFromString( \
+ valuestring, d->FindFieldByName("optional_" #name), message.get())); \
+ EXPECT_TRUE(message->optional_##name() == value); \
+ EXPECT_TRUE(message->has_optional_##name());
+
+#define EXPECT_FLOAT_FIELD(name, value, valuestring) \
+ EXPECT_TRUE(TextFormat::ParseFieldValueFromString( \
+ valuestring, d->FindFieldByName("optional_" #name), message.get())); \
+ EXPECT_FLOAT_EQ(value, message->optional_##name()); \
+ EXPECT_TRUE(message->has_optional_##name());
+
+#define EXPECT_DOUBLE_FIELD(name, value, valuestring) \
+ EXPECT_TRUE(TextFormat::ParseFieldValueFromString( \
+ valuestring, d->FindFieldByName("optional_" #name), message.get())); \
+ EXPECT_DOUBLE_EQ(value, message->optional_##name()); \
+ EXPECT_TRUE(message->has_optional_##name());
+
+#define EXPECT_INVALID(name, valuestring) \
+ EXPECT_FALSE(TextFormat::ParseFieldValueFromString( \
+ valuestring, d->FindFieldByName("optional_" #name), message.get()));
+
+ // int32
+ EXPECT_FIELD(int32, 1, "1");
+ EXPECT_FIELD(int32, -1, "-1");
+ EXPECT_FIELD(int32, 0x1234, "0x1234");
+ EXPECT_INVALID(int32, "a");
+ EXPECT_INVALID(int32, "999999999999999999999999999999999999");
+ EXPECT_INVALID(int32, "1,2");
+
+ // int64
+ EXPECT_FIELD(int64, 1, "1");
+ EXPECT_FIELD(int64, -1, "-1");
+ EXPECT_FIELD(int64, 0x1234567812345678LL, "0x1234567812345678");
+ EXPECT_INVALID(int64, "a");
+ EXPECT_INVALID(int64, "999999999999999999999999999999999999");
+ EXPECT_INVALID(int64, "1,2");
+
+ // uint64
+ EXPECT_FIELD(uint64, 1, "1");
+ EXPECT_FIELD(uint64, 0xf234567812345678ULL, "0xf234567812345678");
+ EXPECT_INVALID(uint64, "-1");
+ EXPECT_INVALID(uint64, "a");
+ EXPECT_INVALID(uint64, "999999999999999999999999999999999999");
+ EXPECT_INVALID(uint64, "1,2");
+
+ // fixed32
+ EXPECT_FIELD(fixed32, 1, "1");
+ EXPECT_FIELD(fixed32, 0x12345678, "0x12345678");
+ EXPECT_INVALID(fixed32, "-1");
+ EXPECT_INVALID(fixed32, "a");
+ EXPECT_INVALID(fixed32, "999999999999999999999999999999999999");
+ EXPECT_INVALID(fixed32, "1,2");
+
+ // fixed64
+ EXPECT_FIELD(fixed64, 1, "1");
+ EXPECT_FIELD(fixed64, 0x1234567812345678ULL, "0x1234567812345678");
+ EXPECT_INVALID(fixed64, "-1");
+ EXPECT_INVALID(fixed64, "a");
+ EXPECT_INVALID(fixed64, "999999999999999999999999999999999999");
+ EXPECT_INVALID(fixed64, "1,2");
+
+ // bool
+ EXPECT_BOOL_FIELD(bool, true, "true");
+ EXPECT_BOOL_FIELD(bool, false, "false");
+ EXPECT_BOOL_FIELD(bool, true, "1");
+ EXPECT_BOOL_FIELD(bool, true, "t");
+ EXPECT_BOOL_FIELD(bool, false, "0");
+ EXPECT_BOOL_FIELD(bool, false, "f");
+ EXPECT_FIELD(bool, true, "True");
+ EXPECT_FIELD(bool, false, "False");
+ EXPECT_INVALID(bool, "tRue");
+ EXPECT_INVALID(bool, "faLse");
+ EXPECT_INVALID(bool, "2");
+ EXPECT_INVALID(bool, "-0");
+ EXPECT_INVALID(bool, "on");
+ EXPECT_INVALID(bool, "a");
+
+ // float
+ EXPECT_FIELD(float, 1, "1");
+ EXPECT_FLOAT_FIELD(float, 1.5, "1.5");
+ EXPECT_FLOAT_FIELD(float, 1.5e3, "1.5e3");
+ EXPECT_FLOAT_FIELD(float, -4.55, "-4.55");
+ EXPECT_INVALID(float, "a");
+ EXPECT_INVALID(float, "1,2");
+
+ // double
+ EXPECT_FIELD(double, 1, "1");
+ EXPECT_FIELD(double, -1, "-1");
+ EXPECT_DOUBLE_FIELD(double, 2.3, "2.3");
+ EXPECT_DOUBLE_FIELD(double, 3e5, "3e5");
+ EXPECT_INVALID(double, "a");
+ EXPECT_INVALID(double, "1,2");
+ // Rejects hex and oct numbers for a double field.
+ EXPECT_INVALID(double, "0xf");
+ EXPECT_INVALID(double, "012");
+
+ // string
+ EXPECT_FIELD(string, "hello", "\"hello\"");
+ EXPECT_FIELD(string, "-1.87", "'-1.87'");
+ EXPECT_INVALID(string, "hello"); // without quote for value
+
+ // enum
+ EXPECT_FIELD(nested_enum, unittest::TestAllTypes::BAR, "BAR");
+ EXPECT_FIELD(nested_enum, unittest::TestAllTypes::BAZ,
+ StrCat(unittest::TestAllTypes::BAZ));
+ EXPECT_INVALID(nested_enum, "FOOBAR");
+
+ // message
+ EXPECT_TRUE(TextFormat::ParseFieldValueFromString(
+ "<bb:12>", d->FindFieldByName("optional_nested_message"), message.get()));
+ EXPECT_EQ(12, message->optional_nested_message().bb());
+ EXPECT_TRUE(message->has_optional_nested_message());
+ EXPECT_INVALID(nested_message, "any");
+
+#undef EXPECT_FIELD
+#undef EXPECT_BOOL_FIELD
+#undef EXPECT_FLOAT_FIELD
+#undef EXPECT_DOUBLE_FIELD
+#undef EXPECT_INVALID
+}
+
+TEST_F(TextFormatParserTest, InvalidToken) {
+ ExpectFailure("optional_bool: true\n-5\n", "Expected identifier, got: -", 2,
+ 1);
+
+ ExpectFailure("optional_bool: true!\n", "Expected identifier, got: !", 1, 20);
+ ExpectFailure("\"some string\"", "Expected identifier, got: \"some string\"",
+ 1, 1);
+}
+
+TEST_F(TextFormatParserTest, InvalidFieldName) {
+ ExpectFailure(
+ "invalid_field: somevalue\n",
+ "Message type \"protobuf_unittest.TestAllTypes\" has no field named "
+ "\"invalid_field\".",
+ 1, 14);
+}
+
+TEST_F(TextFormatParserTest, InvalidCapitalization) {
+ // We require that group names be exactly as they appear in the .proto.
+ ExpectFailure(
+ "optionalgroup {\na: 15\n}\n",
+ "Message type \"protobuf_unittest.TestAllTypes\" has no field named "
+ "\"optionalgroup\".",
+ 1, 15);
+ ExpectFailure(
+ "OPTIONALgroup {\na: 15\n}\n",
+ "Message type \"protobuf_unittest.TestAllTypes\" has no field named "
+ "\"OPTIONALgroup\".",
+ 1, 15);
+ ExpectFailure(
+ "Optional_Double: 10.0\n",
+ "Message type \"protobuf_unittest.TestAllTypes\" has no field named "
+ "\"Optional_Double\".",
+ 1, 16);
+}
+
+TEST_F(TextFormatParserTest, AllowIgnoreCapitalizationError) {
+ TextFormat::Parser parser;
+ protobuf_unittest::TestAllTypes proto;
+
+ // These fields have a mismatching case.
+ EXPECT_FALSE(parser.ParseFromString("Optional_Double: 10.0", &proto));
+ EXPECT_FALSE(parser.ParseFromString("oPtIoNaLgRoUp { a: 15 }", &proto));
+
+ // ... but are parsed correctly if we match case insensitive.
+ parser.AllowCaseInsensitiveField(true);
+ EXPECT_TRUE(parser.ParseFromString("Optional_Double: 10.0", &proto));
+ EXPECT_EQ(10.0, proto.optional_double());
+ EXPECT_TRUE(parser.ParseFromString("oPtIoNaLgRoUp { a: 15 }", &proto));
+ EXPECT_EQ(15, proto.optionalgroup().a());
+}
+
+TEST_F(TextFormatParserTest, InvalidFieldValues) {
+ // Invalid values for a double/float field.
+ ExpectFailure("optional_double: \"hello\"\n",
+ "Expected double, got: \"hello\"", 1, 18);
+ ExpectFailure("optional_double: true\n", "Expected double, got: true", 1, 18);
+ ExpectFailure("optional_double: !\n", "Expected double, got: !", 1, 18);
+ ExpectFailure("optional_double {\n \n}\n", "Expected \":\", found \"{\".", 1,
+ 17);
+
+ // Invalid values for a signed integer field.
+ ExpectFailure("optional_int32: \"hello\"\n",
+ "Expected integer, got: \"hello\"", 1, 17);
+ ExpectFailure("optional_int32: true\n", "Expected integer, got: true", 1, 17);
+ ExpectFailure("optional_int32: 4.5\n", "Expected integer, got: 4.5", 1, 17);
+ ExpectFailure("optional_int32: !\n", "Expected integer, got: !", 1, 17);
+ ExpectFailure("optional_int32 {\n \n}\n", "Expected \":\", found \"{\".", 1,
+ 16);
+ ExpectFailure("optional_int32: 0x80000000\n",
+ "Integer out of range (0x80000000)", 1, 17);
+ ExpectFailure("optional_int64: 0x8000000000000000\n",
+ "Integer out of range (0x8000000000000000)", 1, 17);
+ ExpectFailure("optional_int32: -0x80000001\n",
+ "Integer out of range (0x80000001)", 1, 18);
+ ExpectFailure("optional_int64: -0x8000000000000001\n",
+ "Integer out of range (0x8000000000000001)", 1, 18);
+
+ // Invalid values for an unsigned integer field.
+ ExpectFailure("optional_uint64: \"hello\"\n",
+ "Expected integer, got: \"hello\"", 1, 18);
+ ExpectFailure("optional_uint64: true\n", "Expected integer, got: true", 1,
+ 18);
+ ExpectFailure("optional_uint64: 4.5\n", "Expected integer, got: 4.5", 1, 18);
+ ExpectFailure("optional_uint64: -5\n", "Expected integer, got: -", 1, 18);
+ ExpectFailure("optional_uint64: !\n", "Expected integer, got: !", 1, 18);
+ ExpectFailure("optional_uint64 {\n \n}\n", "Expected \":\", found \"{\".", 1,
+ 17);
+ ExpectFailure("optional_uint32: 0x100000000\n",
+ "Integer out of range (0x100000000)", 1, 18);
+ ExpectFailure("optional_uint64: 0x10000000000000000\n",
+ "Integer out of range (0x10000000000000000)", 1, 18);
+
+ // Invalid values for a boolean field.
+ ExpectFailure("optional_bool: \"hello\"\n",
+ "Expected identifier, got: \"hello\"", 1, 16);
+ ExpectFailure("optional_bool: 5\n", "Integer out of range (5)", 1, 16);
+ ExpectFailure("optional_bool: -7.5\n", "Expected identifier, got: -", 1, 16);
+ ExpectFailure("optional_bool: !\n", "Expected identifier, got: !", 1, 16);
+
+ ExpectFailure(
+ "optional_bool: meh\n",
+ "Invalid value for boolean field \"optional_bool\". Value: \"meh\".", 2,
+ 1);
+
+ ExpectFailure("optional_bool {\n \n}\n", "Expected \":\", found \"{\".", 1,
+ 15);
+
+ // Invalid values for a string field.
+ ExpectFailure("optional_string: true\n", "Expected string, got: true", 1, 18);
+ ExpectFailure("optional_string: 5\n", "Expected string, got: 5", 1, 18);
+ ExpectFailure("optional_string: -7.5\n", "Expected string, got: -", 1, 18);
+ ExpectFailure("optional_string: !\n", "Expected string, got: !", 1, 18);
+ ExpectFailure("optional_string {\n \n}\n", "Expected \":\", found \"{\".", 1,
+ 17);
+
+ // Invalid values for an enumeration field.
+ ExpectFailure("optional_nested_enum: \"hello\"\n",
+ "Expected integer or identifier, got: \"hello\"", 1, 23);
+
+ // Valid token, but enum value is not defined.
+ ExpectFailure("optional_nested_enum: 5\n",
+ "Unknown enumeration value of \"5\" for field "
+ "\"optional_nested_enum\".",
+ 2, 1);
+ // We consume the negative sign, so the error position starts one character
+ // later.
+ ExpectFailure("optional_nested_enum: -7.5\n", "Expected integer, got: 7.5", 1,
+ 24);
+ ExpectFailure("optional_nested_enum: !\n",
+ "Expected integer or identifier, got: !", 1, 23);
+
+ ExpectFailure("optional_nested_enum: grah\n",
+ "Unknown enumeration value of \"grah\" for field "
+ "\"optional_nested_enum\".",
+ 2, 1);
+
+ ExpectFailure("optional_nested_enum {\n \n}\n",
+ "Expected \":\", found \"{\".", 1, 22);
+}
+
+TEST_F(TextFormatParserTest, MessageDelimiters) {
+ // Non-matching delimiters.
+ ExpectFailure("OptionalGroup <\n \n}\n", "Expected \">\", found \"}\".", 3,
+ 1);
+
+ // Invalid delimiters.
+ ExpectFailure("OptionalGroup [\n \n]\n", "Expected \"{\", found \"[\".", 1,
+ 15);
+
+ // Unending message.
+ ExpectFailure("optional_nested_message {\n \nbb: 118\n",
+ "Expected identifier, got: ", 4, 1);
+}
+
+TEST_F(TextFormatParserTest, UnknownExtension) {
+ // Non-matching delimiters.
+ ExpectFailure("[blahblah]: 123",
+ "Extension \"blahblah\" is not defined or is not an "
+ "extension of \"protobuf_unittest.TestAllTypes\".",
+ 1, 11);
+}
+
+TEST_F(TextFormatParserTest, MissingRequired) {
+ unittest::TestRequired message;
+ ExpectFailure("a: 1", "Message missing required fields: b, c", 0, 1,
+ &message);
+}
+
+TEST_F(TextFormatParserTest, ParseDuplicateRequired) {
+ unittest::TestRequired message;
+ ExpectFailure("a: 1 b: 2 c: 3 a: 1",
+ "Non-repeated field \"a\" is specified multiple times.", 1, 17,
+ &message);
+}
+
+TEST_F(TextFormatParserTest, ParseDuplicateOptional) {
+ unittest::ForeignMessage message;
+ ExpectFailure("c: 1 c: 2",
+ "Non-repeated field \"c\" is specified multiple times.", 1, 7,
+ &message);
+}
+
+TEST_F(TextFormatParserTest, MergeDuplicateRequired) {
+ unittest::TestRequired message;
+ TextFormat::Parser parser;
+ EXPECT_TRUE(parser.MergeFromString("a: 1 b: 2 c: 3 a: 4", &message));
+ EXPECT_EQ(4, message.a());
+}
+
+TEST_F(TextFormatParserTest, MergeDuplicateOptional) {
+ unittest::ForeignMessage message;
+ TextFormat::Parser parser;
+ EXPECT_TRUE(parser.MergeFromString("c: 1 c: 2", &message));
+ EXPECT_EQ(2, message.c());
+}
+
+TEST_F(TextFormatParserTest, ExplicitDelimiters) {
+ unittest::TestRequired message;
+ EXPECT_TRUE(TextFormat::ParseFromString("a:1,b:2;c:3", &message));
+ EXPECT_EQ(1, message.a());
+ EXPECT_EQ(2, message.b());
+ EXPECT_EQ(3, message.c());
+}
+
+TEST_F(TextFormatParserTest, PrintErrorsToStderr) {
+ std::vector<std::string> errors;
+
+ {
+ ScopedMemoryLog log;
+ unittest::TestAllTypes proto;
+ EXPECT_FALSE(TextFormat::ParseFromString("no_such_field: 1", &proto));
+ errors = log.GetMessages(ERROR);
+ }
+
+ ASSERT_EQ(1, errors.size());
+ EXPECT_EQ(
+ "Error parsing text-format protobuf_unittest.TestAllTypes: "
+ "1:14: Message type \"protobuf_unittest.TestAllTypes\" has no field "
+ "named \"no_such_field\".",
+ errors[0]);
+}
+
+TEST_F(TextFormatParserTest, FailsOnTokenizationError) {
+ std::vector<std::string> errors;
+
+ {
+ ScopedMemoryLog log;
+ unittest::TestAllTypes proto;
+ EXPECT_FALSE(TextFormat::ParseFromString("\020", &proto));
+ errors = log.GetMessages(ERROR);
+ }
+
+ ASSERT_EQ(1, errors.size());
+ EXPECT_EQ(
+ "Error parsing text-format protobuf_unittest.TestAllTypes: "
+ "1:1: Invalid control characters encountered in text.",
+ errors[0]);
+}
+
+TEST_F(TextFormatParserTest, ParseDeprecatedField) {
+ unittest::TestDeprecatedFields message;
+ ExpectMessage("deprecated_int32: 42",
+ "WARNING:text format contains deprecated field "
+ "\"deprecated_int32\"",
+ 1, 21, &message, true);
+}
+
+TEST_F(TextFormatParserTest, SetRecursionLimit) {
+ const char* format = "child: { $0 }";
+ std::string input;
+ for (int i = 0; i < 100; ++i) input = strings::Substitute(format, input);
+
+ unittest::NestedTestAllTypes message;
+ ExpectSuccessAndTree(input, &message, nullptr);
+
+ input = strings::Substitute(format, input);
+ parser_.SetRecursionLimit(100);
+ ExpectMessage(input,
+ "Message is too deep, the parser exceeded the configured "
+ "recursion limit of 100.",
+ 1, 908, &message, false);
+
+ parser_.SetRecursionLimit(101);
+ ExpectSuccessAndTree(input, &message, nullptr);
+}
+
+TEST_F(TextFormatParserTest, SetRecursionLimitUnknownFieldValue) {
+ const char* format = "[$0]";
+ std::string input = "\"test_value\"";
+ for (int i = 0; i < 99; ++i) input = strings::Substitute(format, input);
+ std::string not_deep_input = StrCat("unknown_nested_array: ", input);
+
+ parser_.AllowUnknownField(true);
+ parser_.SetRecursionLimit(100);
+
+ unittest::NestedTestAllTypes message;
+ ExpectSuccessAndTree(not_deep_input, &message, nullptr);
+
+ input = strings::Substitute(format, input);
+ std::string deep_input = StrCat("unknown_nested_array: ", input);
+ ExpectMessage(
+ deep_input,
+ "WARNING:Message type \"protobuf_unittest.NestedTestAllTypes\" has no "
+ "field named \"unknown_nested_array\".\n1:123: Message is too deep, the "
+ "parser exceeded the configured recursion limit of 100.",
+ 1, 21, &message, false);
+
+ parser_.SetRecursionLimit(101);
+ ExpectSuccessAndTree(deep_input, &message, nullptr);
+}
+
+TEST_F(TextFormatParserTest, SetRecursionLimitUnknownFieldMessage) {
+ const char* format = "unknown_child: { $0 }";
+ std::string input;
+ for (int i = 0; i < 100; ++i) input = strings::Substitute(format, input);
+
+ parser_.AllowUnknownField(true);
+ parser_.SetRecursionLimit(100);
+
+ unittest::NestedTestAllTypes message;
+ ExpectSuccessAndTree(input, &message, nullptr);
+
+ input = strings::Substitute(format, input);
+ ExpectMessage(
+ input,
+ "WARNING:Message type \"protobuf_unittest.NestedTestAllTypes\" has no "
+ "field named \"unknown_child\".\n1:1716: Message is too deep, the parser "
+ "exceeded the configured recursion limit of 100.",
+ 1, 14, &message, false);
+
+ parser_.SetRecursionLimit(101);
+ ExpectSuccessAndTree(input, &message, nullptr);
+}
+
+TEST_F(TextFormatParserTest, ParseAnyFieldWithAdditionalWhiteSpaces) {
+ Any any;
+ std::string parse_string =
+ "[type.googleapis.com/protobuf_unittest.TestAllTypes] \t : \t {\n"
+ " optional_int32: 321\n"
+ " optional_string: \"teststr0\"\n"
+ "}\n";
+
+ ASSERT_TRUE(TextFormat::ParseFromString(parse_string, &any));
+
+ TextFormat::Printer printer;
+ printer.SetExpandAny(true);
+ std::string text;
+ ASSERT_TRUE(printer.PrintToString(any, &text));
+ EXPECT_EQ(text,
+ "[type.googleapis.com/protobuf_unittest.TestAllTypes] {\n"
+ " optional_int32: 321\n"
+ " optional_string: \"teststr0\"\n"
+ "}\n");
+}
+
+TEST_F(TextFormatParserTest, ParseExtensionFieldWithAdditionalWhiteSpaces) {
+ unittest::TestAllExtensions proto;
+ std::string parse_string =
+ "[protobuf_unittest.optional_int32_extension] : \t 101\n"
+ "[protobuf_unittest.optional_int64_extension] \t : 102\n";
+
+ ASSERT_TRUE(TextFormat::ParseFromString(parse_string, &proto));
+
+ TextFormat::Printer printer;
+ std::string text;
+ ASSERT_TRUE(printer.PrintToString(proto, &text));
+ EXPECT_EQ(text,
+ "[protobuf_unittest.optional_int32_extension]: 101\n"
+ "[protobuf_unittest.optional_int64_extension]: 102\n");
+}
+
+TEST_F(TextFormatParserTest, ParseNormalFieldWithAdditionalWhiteSpaces) {
+ unittest::TestAllTypes proto;
+ std::string parse_string =
+ "repeated_int32 : \t 1\n"
+ "repeated_int32: 2\n"
+ "repeated_nested_message: {\n"
+ " bb: 3\n"
+ "}\n"
+ "repeated_nested_message : \t {\n"
+ " bb: 4\n"
+ "}\n"
+ "repeated_nested_message {\n"
+ " bb: 5\n"
+ "}\n";
+
+ ASSERT_TRUE(TextFormat::ParseFromString(parse_string, &proto));
+
+ TextFormat::Printer printer;
+ std::string text;
+ ASSERT_TRUE(printer.PrintToString(proto, &text));
+ EXPECT_EQ(text,
+ "repeated_int32: 1\n"
+ "repeated_int32: 2\n"
+ "repeated_nested_message {\n"
+ " bb: 3\n"
+ "}\n"
+ "repeated_nested_message {\n"
+ " bb: 4\n"
+ "}\n"
+ "repeated_nested_message {\n"
+ " bb: 5\n"
+ "}\n");
+}
+
+TEST_F(TextFormatParserTest, ParseSkippedFieldWithAdditionalWhiteSpaces) {
+ protobuf_unittest::TestAllTypes proto;
+ TextFormat::Parser parser;
+ parser.AllowUnknownField(true);
+ EXPECT_TRUE(
+ parser.ParseFromString("optional_int32: 321\n"
+ "unknown_field1 : \t 12345\n"
+ "[somewhere.unknown_extension1] {\n"
+ " unknown_field2 \t : 12345\n"
+ "}\n"
+ "[somewhere.unknown_extension2] : \t {\n"
+ " unknown_field3 \t : 12345\n"
+ " [somewhere.unknown_extension3] \t : {\n"
+ " unknown_field4: 10\n"
+ " }\n"
+ " [somewhere.unknown_extension4] \t {\n"
+ " }\n"
+ "}\n",
+ &proto));
+ std::string text;
+ TextFormat::Printer printer;
+ ASSERT_TRUE(printer.PrintToString(proto, &text));
+ EXPECT_EQ(text, "optional_int32: 321\n");
+}
+
+class TextFormatMessageSetTest : public testing::Test {
+ protected:
+ static const char proto_debug_string_[];
+};
+const char TextFormatMessageSetTest::proto_debug_string_[] =
+ "message_set {\n"
+ " [protobuf_unittest.TestMessageSetExtension1] {\n"
+ " i: 23\n"
+ " }\n"
+ " [protobuf_unittest.TestMessageSetExtension2] {\n"
+ " str: \"foo\"\n"
+ " }\n"
+ "}\n";
+
+TEST_F(TextFormatMessageSetTest, Serialize) {
+ protobuf_unittest::TestMessageSetContainer proto;
+ protobuf_unittest::TestMessageSetExtension1* item_a =
+ proto.mutable_message_set()->MutableExtension(
+ protobuf_unittest::TestMessageSetExtension1::message_set_extension);
+ item_a->set_i(23);
+ protobuf_unittest::TestMessageSetExtension2* item_b =
+ proto.mutable_message_set()->MutableExtension(
+ protobuf_unittest::TestMessageSetExtension2::message_set_extension);
+ item_b->set_str("foo");
+ EXPECT_EQ(proto_debug_string_, proto.DebugString());
+}
+
+TEST_F(TextFormatMessageSetTest, Deserialize) {
+ protobuf_unittest::TestMessageSetContainer proto;
+ ASSERT_TRUE(TextFormat::ParseFromString(proto_debug_string_, &proto));
+ EXPECT_EQ(
+ 23,
+ proto.message_set()
+ .GetExtension(
+ protobuf_unittest::TestMessageSetExtension1::message_set_extension)
+ .i());
+ EXPECT_EQ(
+ "foo",
+ proto.message_set()
+ .GetExtension(
+ protobuf_unittest::TestMessageSetExtension2::message_set_extension)
+ .str());
+
+ // Ensure that these are the only entries present.
+ std::vector<const FieldDescriptor*> descriptors;
+ proto.message_set().GetReflection()->ListFields(proto.message_set(),
+ &descriptors);
+ EXPECT_EQ(2, descriptors.size());
+}
+
+TEST(TextFormatUnknownFieldTest, TestUnknownField) {
+ protobuf_unittest::TestAllTypes proto;
+ TextFormat::Parser parser;
+ // Unknown field is not permitted by default.
+ EXPECT_FALSE(parser.ParseFromString("unknown_field: 12345", &proto));
+ EXPECT_FALSE(parser.ParseFromString("12345678: 12345", &proto));
+
+ parser.AllowUnknownField(true);
+ EXPECT_TRUE(parser.ParseFromString("unknown_field: 12345", &proto));
+ EXPECT_TRUE(parser.ParseFromString("unknown_field: -12345", &proto));
+ EXPECT_TRUE(parser.ParseFromString("unknown_field: 1.2345", &proto));
+ EXPECT_TRUE(parser.ParseFromString("unknown_field: -1.2345", &proto));
+ EXPECT_TRUE(parser.ParseFromString("unknown_field: 1.2345f", &proto));
+ EXPECT_TRUE(parser.ParseFromString("unknown_field: -1.2345f", &proto));
+ EXPECT_TRUE(parser.ParseFromString("unknown_field: inf", &proto));
+ EXPECT_TRUE(parser.ParseFromString("unknown_field: -inf", &proto));
+ EXPECT_TRUE(parser.ParseFromString("unknown_field: TYPE_STRING", &proto));
+ EXPECT_TRUE(
+ parser.ParseFromString("unknown_field: \"string value\"", &proto));
+ // Invalid field value
+ EXPECT_FALSE(parser.ParseFromString("unknown_field: -TYPE_STRING", &proto));
+ // Two or more unknown fields
+ EXPECT_TRUE(
+ parser.ParseFromString("unknown_field1: TYPE_STRING\n"
+ "unknown_field2: 12345",
+ &proto));
+ // Unknown nested message
+ EXPECT_TRUE(
+ parser.ParseFromString("unknown_message1: {}\n"
+ "unknown_message2 {\n"
+ " unknown_field: 12345\n"
+ "}\n"
+ "unknown_message3 <\n"
+ " unknown_nested_message {\n"
+ " unknown_field: 12345\n"
+ " }\n"
+ ">",
+ &proto));
+ // Unmatched delimiters for message body
+ EXPECT_FALSE(parser.ParseFromString("unknown_message: {>", &proto));
+ // Unknown extension
+ EXPECT_TRUE(
+ parser.ParseFromString("[somewhere.unknown_extension1]: 12345\n"
+ "[somewhere.unknown_extension2] {\n"
+ " unknown_field: 12345\n"
+ "}",
+ &proto));
+ // Unknown fields between known fields
+ ASSERT_TRUE(
+ parser.ParseFromString("optional_int32: 1\n"
+ "unknown_field: 12345\n"
+ "optional_string: \"string\"\n"
+ "unknown_message { unknown: 0 }\n"
+ "optional_nested_message { bb: 2 }",
+ &proto));
+ EXPECT_EQ(1, proto.optional_int32());
+ EXPECT_EQ("string", proto.optional_string());
+ EXPECT_EQ(2, proto.optional_nested_message().bb());
+
+ // Unknown field with numeric tag number instead of identifier.
+ EXPECT_TRUE(parser.ParseFromString("12345678: 12345", &proto));
+
+ // Nested unknown extensions.
+ EXPECT_TRUE(
+ parser.ParseFromString("[test.extension1] <\n"
+ " unknown_nested_message <\n"
+ " [test.extension2] <\n"
+ " unknown_field: 12345\n"
+ " >\n"
+ " >\n"
+ ">",
+ &proto));
+ EXPECT_TRUE(
+ parser.ParseFromString("[test.extension1] {\n"
+ " unknown_nested_message {\n"
+ " [test.extension2] {\n"
+ " unknown_field: 12345\n"
+ " }\n"
+ " }\n"
+ "}",
+ &proto));
+ EXPECT_TRUE(
+ parser.ParseFromString("[test.extension1] <\n"
+ " some_unknown_fields: <\n"
+ " unknown_field: 12345\n"
+ " >\n"
+ ">",
+ &proto));
+ EXPECT_TRUE(
+ parser.ParseFromString("[test.extension1] {\n"
+ " some_unknown_fields: {\n"
+ " unknown_field: 12345\n"
+ " }\n"
+ "}",
+ &proto));
+
+ // Unknown field with compact repetition.
+ EXPECT_TRUE(parser.ParseFromString("unknown_field: [1, 2]", &proto));
+ // Unknown field with compact repetition of some unknown enum.
+ EXPECT_TRUE(parser.ParseFromString("unknown_field: [VAL1, VAL2]", &proto));
+ // Unknown field with compact repetition with sub-message.
+ EXPECT_TRUE(parser.ParseFromString("unknown_field: [{a:1}, <b:2>]", &proto));
+}
+
+TEST(TextFormatUnknownFieldTest, TestAnyInUnknownField) {
+ protobuf_unittest::TestAllTypes proto;
+ TextFormat::Parser parser;
+ parser.AllowUnknownField(true);
+ EXPECT_TRUE(
+ parser.ParseFromString("unknown {\n"
+ " [type.googleapis.com/foo.bar] {\n"
+ " }\n"
+ "}",
+ &proto));
+}
+
+TEST(TextFormatUnknownFieldTest, TestUnknownExtension) {
+ protobuf_unittest::TestAllTypes proto;
+ TextFormat::Parser parser;
+ std::string message_with_ext =
+ "[test.extension1] {\n"
+ " some_unknown_fields: {\n"
+ " unknown_field: 12345\n"
+ " }\n"
+ "}";
+ // Unknown extensions are not permitted by default.
+ EXPECT_FALSE(parser.ParseFromString(message_with_ext, &proto));
+ // AllowUnknownField implies AllowUnknownExtension.
+ parser.AllowUnknownField(true);
+ EXPECT_TRUE(parser.ParseFromString(message_with_ext, &proto));
+
+ parser.AllowUnknownField(false);
+ EXPECT_FALSE(parser.ParseFromString(message_with_ext, &proto));
+ parser.AllowUnknownExtension(true);
+ EXPECT_TRUE(parser.ParseFromString(message_with_ext, &proto));
+ // Unknown fields are still not accepted.
+ EXPECT_FALSE(parser.ParseFromString("unknown_field: 1", &proto));
+}
+
+class TextFormatSilentMarkerTest : public testing::Test {
+ public:
+ void SetUp() override {
+ google::protobuf::internal::enable_debug_text_format_marker = true;
+ }
+ void TearDown() override {
+ google::protobuf::internal::enable_debug_text_format_marker = false;
+ }
+};
+
+TEST_F(TextFormatSilentMarkerTest, NonMessageFieldAsFirstField) {
+ protobuf_unittest::TestAllTypes proto;
+ proto.set_optional_int32(1);
+ proto.mutable_optional_nested_message()->set_bb(2);
+
+ EXPECT_EQ(
+ "optional_int32: \t 1\n"
+ "optional_nested_message {\n"
+ " bb: 2\n"
+ "}\n",
+ proto.DebugString());
+
+ EXPECT_EQ(
+ "optional_int32: \t 1 "
+ "optional_nested_message { bb: 2 }",
+ proto.ShortDebugString());
+}
+
+TEST_F(TextFormatSilentMarkerTest, MessageFieldAsFirstField) {
+ protobuf_unittest::TestAllTypes proto;
+ proto.mutable_optional_nested_message()->set_bb(2);
+ proto.add_repeated_int32(3);
+
+ EXPECT_EQ(
+ "optional_nested_message \t {\n"
+ " bb: 2\n"
+ "}\n"
+ "repeated_int32: 3\n",
+ proto.DebugString());
+
+ EXPECT_EQ(
+ "optional_nested_message \t { bb: 2 } "
+ "repeated_int32: 3",
+ proto.ShortDebugString());
+}
+
+TEST_F(TextFormatSilentMarkerTest, UnknownFieldAsFirstField) {
+ unittest::TestEmptyMessage message;
+ UnknownFieldSet* unknown_fields = message.mutable_unknown_fields();
+
+ unknown_fields->AddVarint(5, 1);
+ unknown_fields->AddGroup(5)->AddVarint(10, 5);
+
+ EXPECT_EQ(
+ "5: \t 1\n"
+ "5 {\n"
+ " 10: 5\n"
+ "}\n",
+ message.DebugString());
+
+ EXPECT_EQ(
+ "5: \t 1 "
+ "5 { 10: 5 }",
+ message.ShortDebugString());
+
+ unknown_fields->Clear();
+ unknown_fields->AddGroup(5)->AddVarint(10, 5);
+ unknown_fields->AddVarint(5, 1);
+
+ EXPECT_EQ(
+ "5 \t {\n"
+ " 10: 5\n"
+ "}\n"
+ "5: 1\n",
+ message.DebugString());
+
+ EXPECT_EQ(
+ "5 \t { 10: 5 } "
+ "5: 1",
+ message.ShortDebugString());
+}
+
+TEST_F(TextFormatSilentMarkerTest, AnyFieldAsFirstField) {
+ protobuf_unittest::TestAllTypes proto;
+ proto.set_optional_string("teststr");
+ proto.set_optional_int32(432);
+ Any any;
+ any.PackFrom(proto);
+
+ EXPECT_EQ(
+ "[type.googleapis.com/protobuf_unittest.TestAllTypes] \t {\n"
+ " optional_int32: 432\n"
+ " optional_string: \"teststr\"\n"
+ "}\n",
+ any.DebugString());
+
+ EXPECT_EQ(
+ "[type.googleapis.com/protobuf_unittest.TestAllTypes]"
+ " \t { optional_int32: 432 optional_string: \"teststr\" }",
+ any.ShortDebugString());
+}
+
+TEST_F(TextFormatSilentMarkerTest, ExtensionFieldAsFirstField) {
+ unittest::TestAllExtensions proto;
+ proto.SetExtension(protobuf_unittest::optional_int32_extension, 101);
+ proto.SetExtension(protobuf_unittest::optional_int64_extension, 102);
+
+ EXPECT_EQ(
+ "[protobuf_unittest.optional_int32_extension]: \t 101\n"
+ "[protobuf_unittest.optional_int64_extension]: 102\n",
+ proto.DebugString());
+}
+
+TEST_F(TextFormatSilentMarkerTest, MapFieldAsFirstField) {
+ unittest::TestMap proto;
+ (*proto.mutable_map_int32_int32())[0] = 1;
+ (*proto.mutable_map_int64_int64())[2] = 3;
+
+ EXPECT_EQ(
+ "map_int32_int32 \t {\n key: 0\n value: 1\n}\n"
+ "map_int64_int64 {\n key: 2\n value: 3\n}\n",
+ proto.DebugString());
+}
+
+
+TEST(TextFormatFloatingPointTest, PreservesNegative0) {
+ proto3_unittest::TestAllTypes in_message;
+ in_message.set_optional_float(-0.0f);
+ in_message.set_optional_double(-0.0);
+ TextFormat::Printer printer;
+ std::string serialized;
+ EXPECT_TRUE(printer.PrintToString(in_message, &serialized));
+ proto3_unittest::TestAllTypes out_message;
+ TextFormat::Parser parser;
+ EXPECT_TRUE(parser.ParseFromString(serialized, &out_message));
+ EXPECT_EQ(in_message.optional_float(), out_message.optional_float());
+ EXPECT_EQ(std::signbit(in_message.optional_float()),
+ std::signbit(out_message.optional_float()));
+ EXPECT_EQ(in_message.optional_double(), out_message.optional_double());
+ EXPECT_EQ(std::signbit(in_message.optional_double()),
+ std::signbit(out_message.optional_double()));
+}
+
+} // namespace text_format_unittest
+} // namespace protobuf
+} // namespace google
+
+#include <port_undef.inc>
diff --git a/NorthstarDedicatedTest/include/protobuf/timestamp.pb.cc b/NorthstarDedicatedTest/include/protobuf/timestamp.pb.cc
new file mode 100644
index 00000000..f6b69083
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/timestamp.pb.cc
@@ -0,0 +1,300 @@
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+// source: google/protobuf/timestamp.proto
+
+#include <timestamp.pb.h>
+
+#include <algorithm>
+
+#include <io/coded_stream.h>
+#include <extension_set.h>
+#include <wire_format_lite.h>
+#include <descriptor.h>
+#include <generated_message_reflection.h>
+#include <reflection_ops.h>
+#include <wire_format.h>
+// @@protoc_insertion_point(includes)
+#include <port_def.inc>
+
+PROTOBUF_PRAGMA_INIT_SEG
+PROTOBUF_NAMESPACE_OPEN
+constexpr Timestamp::Timestamp(
+ ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized)
+ : seconds_(int64_t{0})
+ , nanos_(0){}
+struct TimestampDefaultTypeInternal {
+ constexpr TimestampDefaultTypeInternal()
+ : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {}
+ ~TimestampDefaultTypeInternal() {}
+ union {
+ Timestamp _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT TimestampDefaultTypeInternal _Timestamp_default_instance_;
+PROTOBUF_NAMESPACE_CLOSE
+static ::PROTOBUF_NAMESPACE_ID::Metadata file_level_metadata_google_2fprotobuf_2ftimestamp_2eproto[1];
+static constexpr ::PROTOBUF_NAMESPACE_ID::EnumDescriptor const** file_level_enum_descriptors_google_2fprotobuf_2ftimestamp_2eproto = nullptr;
+static constexpr ::PROTOBUF_NAMESPACE_ID::ServiceDescriptor const** file_level_service_descriptors_google_2fprotobuf_2ftimestamp_2eproto = nullptr;
+
+const 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, seconds_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Timestamp, nanos_),
+};
+static const ::PROTOBUF_NAMESPACE_ID::internal::MigrationSchema schemas[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = {
+ { 0, -1, -1, sizeof(::PROTOBUF_NAMESPACE_ID::Timestamp)},
+};
+
+static ::PROTOBUF_NAMESPACE_ID::Message const * const file_default_instances[] = {
+ reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_Timestamp_default_instance_),
+};
+
+const char descriptor_table_protodef_google_2fprotobuf_2ftimestamp_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) =
+ "\n\037google/protobuf/timestamp.proto\022\017googl"
+ "e.protobuf\"+\n\tTimestamp\022\017\n\007seconds\030\001 \001(\003"
+ "\022\r\n\005nanos\030\002 \001(\005B\205\001\n\023com.google.protobufB"
+ "\016TimestampProtoP\001Z2google.golang.org/pro"
+ "tobuf/types/known/timestamppb\370\001\001\242\002\003GPB\252\002"
+ "\036Google.Protobuf.WellKnownTypesb\006proto3"
+ ;
+static ::PROTOBUF_NAMESPACE_ID::internal::once_flag descriptor_table_google_2fprotobuf_2ftimestamp_2eproto_once;
+const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2ftimestamp_2eproto = {
+ false, false, 239, descriptor_table_protodef_google_2fprotobuf_2ftimestamp_2eproto, "google/protobuf/timestamp.proto",
+ &descriptor_table_google_2fprotobuf_2ftimestamp_2eproto_once, nullptr, 0, 1,
+ schemas, file_default_instances, TableStruct_google_2fprotobuf_2ftimestamp_2eproto::offsets,
+ file_level_metadata_google_2fprotobuf_2ftimestamp_2eproto, file_level_enum_descriptors_google_2fprotobuf_2ftimestamp_2eproto, file_level_service_descriptors_google_2fprotobuf_2ftimestamp_2eproto,
+};
+PROTOBUF_ATTRIBUTE_WEAK const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable* descriptor_table_google_2fprotobuf_2ftimestamp_2eproto_getter() {
+ return &descriptor_table_google_2fprotobuf_2ftimestamp_2eproto;
+}
+
+// Force running AddDescriptors() at dynamic initialization time.
+PROTOBUF_ATTRIBUTE_INIT_PRIORITY static ::PROTOBUF_NAMESPACE_ID::internal::AddDescriptorsRunner dynamic_init_dummy_google_2fprotobuf_2ftimestamp_2eproto(&descriptor_table_google_2fprotobuf_2ftimestamp_2eproto);
+PROTOBUF_NAMESPACE_OPEN
+
+// ===================================================================
+
+class Timestamp::_Internal {
+ public:
+};
+
+Timestamp::Timestamp(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned)
+ : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) {
+ SharedCtor();
+ if (!is_message_owned) {
+ RegisterArenaDtor(arena);
+ }
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.Timestamp)
+}
+Timestamp::Timestamp(const Timestamp& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message() {
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ ::memcpy(&seconds_, &from.seconds_,
+ static_cast<size_t>(reinterpret_cast<char*>(&nanos_) -
+ reinterpret_cast<char*>(&seconds_)) + sizeof(nanos_));
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.Timestamp)
+}
+
+inline void Timestamp::SharedCtor() {
+::memset(reinterpret_cast<char*>(this) + static_cast<size_t>(
+ reinterpret_cast<char*>(&seconds_) - reinterpret_cast<char*>(this)),
+ 0, static_cast<size_t>(reinterpret_cast<char*>(&nanos_) -
+ reinterpret_cast<char*>(&seconds_)) + sizeof(nanos_));
+}
+
+Timestamp::~Timestamp() {
+ // @@protoc_insertion_point(destructor:google.protobuf.Timestamp)
+ if (GetArenaForAllocation() != nullptr) return;
+ SharedDtor();
+ _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+inline void Timestamp::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+}
+
+void Timestamp::ArenaDtor(void* object) {
+ Timestamp* _this = reinterpret_cast< Timestamp* >(object);
+ (void)_this;
+}
+void Timestamp::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) {
+}
+void Timestamp::SetCachedSize(int size) const {
+ _cached_size_.Set(size);
+}
+
+void Timestamp::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.Timestamp)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ ::memset(&seconds_, 0, static_cast<size_t>(
+ reinterpret_cast<char*>(&nanos_) -
+ reinterpret_cast<char*>(&seconds_)) + sizeof(nanos_));
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* Timestamp::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag);
+ switch (tag >> 3) {
+ // int64 seconds = 1;
+ case 1:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 8)) {
+ seconds_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr);
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // int32 nanos = 2;
+ case 2:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 16)) {
+ nanos_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint32(&ptr);
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ default:
+ goto handle_unusual;
+ } // switch
+ handle_unusual:
+ if ((tag == 0) || ((tag & 7) == 4)) {
+ CHK_(ptr);
+ ctx->SetLastTag(tag);
+ goto message_done;
+ }
+ ptr = UnknownFieldParse(
+ tag,
+ _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(),
+ ptr, ctx);
+ CHK_(ptr != nullptr);
+ } // while
+message_done:
+ return ptr;
+failure:
+ ptr = nullptr;
+ goto message_done;
+#undef CHK_
+}
+
+uint8_t* Timestamp::_InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const {
+ // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Timestamp)
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ // int64 seconds = 1;
+ if (this->_internal_seconds() != 0) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt64ToArray(1, this->_internal_seconds(), target);
+ }
+
+ // int32 nanos = 2;
+ if (this->_internal_nanos() != 0) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32ToArray(2, this->_internal_nanos(), target);
+ }
+
+ if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray(
+ _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Timestamp)
+ return target;
+}
+
+size_t Timestamp::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.Timestamp)
+ size_t total_size = 0;
+
+ 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 += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int64SizePlusOne(this->_internal_seconds());
+ }
+
+ // int32 nanos = 2;
+ if (this->_internal_nanos() != 0) {
+ total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32SizePlusOne(this->_internal_nanos());
+ }
+
+ return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData Timestamp::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck,
+ Timestamp::MergeImpl
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*Timestamp::GetClassData() const { return &_class_data_; }
+
+void Timestamp::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to,
+ const ::PROTOBUF_NAMESPACE_ID::Message& from) {
+ static_cast<Timestamp *>(to)->MergeFrom(
+ static_cast<const Timestamp &>(from));
+}
+
+
+void Timestamp::MergeFrom(const Timestamp& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Timestamp)
+ GOOGLE_DCHECK_NE(&from, this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ if (from._internal_seconds() != 0) {
+ _internal_set_seconds(from._internal_seconds());
+ }
+ if (from._internal_nanos() != 0) {
+ _internal_set_nanos(from._internal_nanos());
+ }
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+}
+
+void Timestamp::CopyFrom(const Timestamp& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.Timestamp)
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+bool Timestamp::IsInitialized() const {
+ return true;
+}
+
+void Timestamp::InternalSwap(Timestamp* other) {
+ using std::swap;
+ _internal_metadata_.InternalSwap(&other->_internal_metadata_);
+ ::PROTOBUF_NAMESPACE_ID::internal::memswap<
+ PROTOBUF_FIELD_OFFSET(Timestamp, nanos_)
+ + sizeof(Timestamp::nanos_)
+ - PROTOBUF_FIELD_OFFSET(Timestamp, seconds_)>(
+ reinterpret_cast<char*>(&seconds_),
+ reinterpret_cast<char*>(&other->seconds_));
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata Timestamp::GetMetadata() const {
+ return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(
+ &descriptor_table_google_2fprotobuf_2ftimestamp_2eproto_getter, &descriptor_table_google_2fprotobuf_2ftimestamp_2eproto_once,
+ file_level_metadata_google_2fprotobuf_2ftimestamp_2eproto[0]);
+}
+
+// @@protoc_insertion_point(namespace_scope)
+PROTOBUF_NAMESPACE_CLOSE
+PROTOBUF_NAMESPACE_OPEN
+template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::Timestamp* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::Timestamp >(Arena* arena) {
+ return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::Timestamp >(arena);
+}
+PROTOBUF_NAMESPACE_CLOSE
+
+// @@protoc_insertion_point(global_scope)
+#include <port_undef.inc>
diff --git a/NorthstarDedicatedTest/include/protobuf/timestamp.pb.h b/NorthstarDedicatedTest/include/protobuf/timestamp.pb.h
new file mode 100644
index 00000000..47eb8c65
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/timestamp.pb.h
@@ -0,0 +1,285 @@
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+// source: google/protobuf/timestamp.proto
+
+#ifndef GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2ftimestamp_2eproto
+#define GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2ftimestamp_2eproto
+
+#include <limits>
+#include <string>
+
+#include <port_def.inc>
+#if PROTOBUF_VERSION < 3019000
+#error This file was generated by a newer version of protoc which is
+#error incompatible with your Protocol Buffer headers. Please update
+#error your headers.
+#endif
+#if 3019004 < 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 <port_undef.inc>
+#include <io/coded_stream.h>
+#include <arena.h>
+#include <arenastring.h>
+#include <generated_message_table_driven.h>
+#include <generated_message_util.h>
+#include <metadata_lite.h>
+#include <generated_message_reflection.h>
+#include <message.h>
+#include <repeated_field.h> // IWYU pragma: export
+#include <extension_set.h> // IWYU pragma: export
+#include <unknown_field_set.h>
+// @@protoc_insertion_point(includes)
+#include <port_def.inc>
+#define PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2ftimestamp_2eproto PROTOBUF_EXPORT
+PROTOBUF_NAMESPACE_OPEN
+namespace internal {
+class AnyMetadata;
+} // namespace internal
+PROTOBUF_NAMESPACE_CLOSE
+
+// Internal implementation detail -- do not use these members.
+struct PROTOBUF_EXPORT TableStruct_google_2fprotobuf_2ftimestamp_2eproto {
+ static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTableField entries[]
+ PROTOBUF_SECTION_VARIABLE(protodesc_cold);
+ static const ::PROTOBUF_NAMESPACE_ID::internal::AuxiliaryParseTableField aux[]
+ PROTOBUF_SECTION_VARIABLE(protodesc_cold);
+ static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTable schema[1]
+ PROTOBUF_SECTION_VARIABLE(protodesc_cold);
+ static const ::PROTOBUF_NAMESPACE_ID::internal::FieldMetadata field_metadata[];
+ static const ::PROTOBUF_NAMESPACE_ID::internal::SerializationTable serialization_table[];
+ static const 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 constexpr Timestamp(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
+
+ Timestamp(const Timestamp& from);
+ Timestamp(Timestamp&& from) noexcept
+ : Timestamp() {
+ *this = ::std::move(from);
+ }
+
+ inline Timestamp& operator=(const Timestamp& from) {
+ CopyFrom(from);
+ return *this;
+ }
+ inline Timestamp& operator=(Timestamp&& from) noexcept {
+ if (this == &from) return *this;
+ if (GetOwningArena() == from.GetOwningArena()
+ #ifdef PROTOBUF_FORCE_COPY_IN_MOVE
+ && GetOwningArena() != nullptr
+ #endif // !PROTOBUF_FORCE_COPY_IN_MOVE
+ ) {
+ InternalSwap(&from);
+ } else {
+ CopyFrom(from);
+ }
+ return *this;
+ }
+
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
+ return GetDescriptor();
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
+ return default_instance().GetMetadata().descriptor;
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
+ return default_instance().GetMetadata().reflection;
+ }
+ static const Timestamp& default_instance() {
+ return *internal_default_instance();
+ }
+ static inline const Timestamp* internal_default_instance() {
+ return reinterpret_cast<const Timestamp*>(
+ &_Timestamp_default_instance_);
+ }
+ static constexpr int kIndexInFileMessages =
+ 0;
+
+ friend void swap(Timestamp& a, Timestamp& b) {
+ a.Swap(&b);
+ }
+ inline void Swap(Timestamp* other) {
+ if (other == this) return;
+ #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() != nullptr &&
+ GetOwningArena() == other->GetOwningArena()) {
+ #else // PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() == other->GetOwningArena()) {
+ #endif // !PROTOBUF_FORCE_COPY_IN_SWAP
+ InternalSwap(other);
+ } else {
+ ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
+ }
+ }
+ void UnsafeArenaSwap(Timestamp* other) {
+ if (other == this) return;
+ GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena());
+ InternalSwap(other);
+ }
+
+ // implements Message ----------------------------------------------
+
+ Timestamp* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
+ return CreateMaybeMessage<Timestamp>(arena);
+ }
+ using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
+ void CopyFrom(const Timestamp& from);
+ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
+ void MergeFrom(const Timestamp& from);
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from);
+ public:
+ PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+ bool IsInitialized() const final;
+
+ size_t ByteSizeLong() const final;
+ const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
+ uint8_t* _InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
+ int GetCachedSize() const final { return _cached_size_.Get(); }
+
+ private:
+ void SharedCtor();
+ void SharedDtor();
+ void SetCachedSize(int size) const final;
+ void InternalSwap(Timestamp* other);
+
+ private:
+ friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
+ static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
+ return "google.protobuf.Timestamp";
+ }
+ protected:
+ explicit Timestamp(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned = false);
+ private:
+ static void ArenaDtor(void* object);
+ inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
+ public:
+
+ static const ClassData _class_data_;
+ const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;
+
+ ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;
+
+ // nested types ----------------------------------------------------
+
+ // accessors -------------------------------------------------------
+
+ enum : int {
+ kSecondsFieldNumber = 1,
+ kNanosFieldNumber = 2,
+ };
+ // int64 seconds = 1;
+ void clear_seconds();
+ 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_;
+ int64_t seconds_;
+ int32_t nanos_;
+ mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
+ friend struct ::TableStruct_google_2fprotobuf_2ftimestamp_2eproto;
+};
+// ===================================================================
+
+
+// ===================================================================
+
+#ifdef __GNUC__
+ #pragma GCC diagnostic push
+ #pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#endif // __GNUC__
+// Timestamp
+
+// int64 seconds = 1;
+inline void Timestamp::clear_seconds() {
+ seconds_ = int64_t{0};
+}
+inline int64_t Timestamp::_internal_seconds() const {
+ return 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) {
+
+ 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() {
+ nanos_ = 0;
+}
+inline int32_t Timestamp::_internal_nanos() const {
+ return 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) {
+
+ 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 <port_undef.inc>
+#endif // GOOGLE_PROTOBUF_INCLUDED_GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2ftimestamp_2eproto
diff --git a/NorthstarDedicatedTest/include/protobuf/timestamp.proto b/NorthstarDedicatedTest/include/protobuf/timestamp.proto
new file mode 100644
index 00000000..3b2df6d9
--- /dev/null
+++ b/NorthstarDedicatedTest/include/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/NorthstarDedicatedTest/include/protobuf/type.pb.cc b/NorthstarDedicatedTest/include/protobuf/type.pb.cc
new file mode 100644
index 00000000..18ac908a
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/type.pb.cc
@@ -0,0 +1,2133 @@
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+// source: google/protobuf/type.proto
+
+#include <type.pb.h>
+
+#include <algorithm>
+
+#include <io/coded_stream.h>
+#include <extension_set.h>
+#include <wire_format_lite.h>
+#include <descriptor.h>
+#include <generated_message_reflection.h>
+#include <reflection_ops.h>
+#include <wire_format.h>
+// @@protoc_insertion_point(includes)
+#include <port_def.inc>
+
+PROTOBUF_PRAGMA_INIT_SEG
+PROTOBUF_NAMESPACE_OPEN
+constexpr Type::Type(
+ ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized)
+ : fields_()
+ , oneofs_()
+ , options_()
+ , name_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string)
+ , source_context_(nullptr)
+ , syntax_(0)
+{}
+struct TypeDefaultTypeInternal {
+ constexpr TypeDefaultTypeInternal()
+ : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {}
+ ~TypeDefaultTypeInternal() {}
+ union {
+ Type _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT TypeDefaultTypeInternal _Type_default_instance_;
+constexpr Field::Field(
+ ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized)
+ : options_()
+ , name_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string)
+ , type_url_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string)
+ , json_name_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string)
+ , default_value_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string)
+ , kind_(0)
+
+ , cardinality_(0)
+
+ , number_(0)
+ , oneof_index_(0)
+ , packed_(false){}
+struct FieldDefaultTypeInternal {
+ constexpr FieldDefaultTypeInternal()
+ : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {}
+ ~FieldDefaultTypeInternal() {}
+ union {
+ Field _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT FieldDefaultTypeInternal _Field_default_instance_;
+constexpr Enum::Enum(
+ ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized)
+ : enumvalue_()
+ , options_()
+ , name_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string)
+ , source_context_(nullptr)
+ , syntax_(0)
+{}
+struct EnumDefaultTypeInternal {
+ constexpr EnumDefaultTypeInternal()
+ : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {}
+ ~EnumDefaultTypeInternal() {}
+ union {
+ Enum _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT EnumDefaultTypeInternal _Enum_default_instance_;
+constexpr EnumValue::EnumValue(
+ ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized)
+ : options_()
+ , name_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string)
+ , number_(0){}
+struct EnumValueDefaultTypeInternal {
+ constexpr EnumValueDefaultTypeInternal()
+ : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {}
+ ~EnumValueDefaultTypeInternal() {}
+ union {
+ EnumValue _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT EnumValueDefaultTypeInternal _EnumValue_default_instance_;
+constexpr Option::Option(
+ ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized)
+ : name_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string)
+ , value_(nullptr){}
+struct OptionDefaultTypeInternal {
+ constexpr OptionDefaultTypeInternal()
+ : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {}
+ ~OptionDefaultTypeInternal() {}
+ union {
+ Option _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT OptionDefaultTypeInternal _Option_default_instance_;
+PROTOBUF_NAMESPACE_CLOSE
+static ::PROTOBUF_NAMESPACE_ID::Metadata file_level_metadata_google_2fprotobuf_2ftype_2eproto[5];
+static const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* file_level_enum_descriptors_google_2fprotobuf_2ftype_2eproto[3];
+static constexpr ::PROTOBUF_NAMESPACE_ID::ServiceDescriptor const** file_level_service_descriptors_google_2fprotobuf_2ftype_2eproto = nullptr;
+
+const 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, name_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Type, fields_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Type, oneofs_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Type, options_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Type, source_context_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Type, syntax_),
+ ~0u, // no _has_bits_
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Field, _internal_metadata_),
+ ~0u, // no _extensions_
+ ~0u, // no _oneof_case_
+ ~0u, // no _weak_field_map_
+ ~0u, // no _inlined_string_donated_
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Field, kind_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Field, cardinality_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Field, number_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Field, name_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Field, type_url_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Field, oneof_index_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Field, packed_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Field, options_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Field, json_name_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Field, default_value_),
+ ~0u, // no _has_bits_
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Enum, _internal_metadata_),
+ ~0u, // no _extensions_
+ ~0u, // no _oneof_case_
+ ~0u, // no _weak_field_map_
+ ~0u, // no _inlined_string_donated_
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Enum, name_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Enum, enumvalue_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Enum, options_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Enum, source_context_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Enum, syntax_),
+ ~0u, // no _has_bits_
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumValue, _internal_metadata_),
+ ~0u, // no _extensions_
+ ~0u, // no _oneof_case_
+ ~0u, // no _weak_field_map_
+ ~0u, // no _inlined_string_donated_
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumValue, name_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumValue, number_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumValue, options_),
+ ~0u, // no _has_bits_
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Option, _internal_metadata_),
+ ~0u, // no _extensions_
+ ~0u, // no _oneof_case_
+ ~0u, // no _weak_field_map_
+ ~0u, // no _inlined_string_donated_
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Option, name_),
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Option, value_),
+};
+static const ::PROTOBUF_NAMESPACE_ID::internal::MigrationSchema schemas[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = {
+ { 0, -1, -1, sizeof(::PROTOBUF_NAMESPACE_ID::Type)},
+ { 12, -1, -1, sizeof(::PROTOBUF_NAMESPACE_ID::Field)},
+ { 28, -1, -1, sizeof(::PROTOBUF_NAMESPACE_ID::Enum)},
+ { 39, -1, -1, sizeof(::PROTOBUF_NAMESPACE_ID::EnumValue)},
+ { 48, -1, -1, sizeof(::PROTOBUF_NAMESPACE_ID::Option)},
+};
+
+static ::PROTOBUF_NAMESPACE_ID::Message const * const file_default_instances[] = {
+ reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_Type_default_instance_),
+ reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_Field_default_instance_),
+ reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_Enum_default_instance_),
+ reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_EnumValue_default_instance_),
+ reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_Option_default_instance_),
+};
+
+const char descriptor_table_protodef_google_2fprotobuf_2ftype_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) =
+ "\n\032google/protobuf/type.proto\022\017google.pro"
+ "tobuf\032\031google/protobuf/any.proto\032$google"
+ "/protobuf/source_context.proto\"\327\001\n\004Type\022"
+ "\014\n\004name\030\001 \001(\t\022&\n\006fields\030\002 \003(\0132\026.google.p"
+ "rotobuf.Field\022\016\n\006oneofs\030\003 \003(\t\022(\n\007options"
+ "\030\004 \003(\0132\027.google.protobuf.Option\0226\n\016sourc"
+ "e_context\030\005 \001(\0132\036.google.protobuf.Source"
+ "Context\022\'\n\006syntax\030\006 \001(\0162\027.google.protobu"
+ "f.Syntax\"\325\005\n\005Field\022)\n\004kind\030\001 \001(\0162\033.googl"
+ "e.protobuf.Field.Kind\0227\n\013cardinality\030\002 \001"
+ "(\0162\".google.protobuf.Field.Cardinality\022\016"
+ "\n\006number\030\003 \001(\005\022\014\n\004name\030\004 \001(\t\022\020\n\010type_url"
+ "\030\006 \001(\t\022\023\n\013oneof_index\030\007 \001(\005\022\016\n\006packed\030\010 "
+ "\001(\010\022(\n\007options\030\t \003(\0132\027.google.protobuf.O"
+ "ption\022\021\n\tjson_name\030\n \001(\t\022\025\n\rdefault_valu"
+ "e\030\013 \001(\t\"\310\002\n\004Kind\022\020\n\014TYPE_UNKNOWN\020\000\022\017\n\013TY"
+ "PE_DOUBLE\020\001\022\016\n\nTYPE_FLOAT\020\002\022\016\n\nTYPE_INT6"
+ "4\020\003\022\017\n\013TYPE_UINT64\020\004\022\016\n\nTYPE_INT32\020\005\022\020\n\014"
+ "TYPE_FIXED64\020\006\022\020\n\014TYPE_FIXED32\020\007\022\r\n\tTYPE"
+ "_BOOL\020\010\022\017\n\013TYPE_STRING\020\t\022\016\n\nTYPE_GROUP\020\n"
+ "\022\020\n\014TYPE_MESSAGE\020\013\022\016\n\nTYPE_BYTES\020\014\022\017\n\013TY"
+ "PE_UINT32\020\r\022\r\n\tTYPE_ENUM\020\016\022\021\n\rTYPE_SFIXE"
+ "D32\020\017\022\021\n\rTYPE_SFIXED64\020\020\022\017\n\013TYPE_SINT32\020"
+ "\021\022\017\n\013TYPE_SINT64\020\022\"t\n\013Cardinality\022\027\n\023CAR"
+ "DINALITY_UNKNOWN\020\000\022\030\n\024CARDINALITY_OPTION"
+ "AL\020\001\022\030\n\024CARDINALITY_REQUIRED\020\002\022\030\n\024CARDIN"
+ "ALITY_REPEATED\020\003\"\316\001\n\004Enum\022\014\n\004name\030\001 \001(\t\022"
+ "-\n\tenumvalue\030\002 \003(\0132\032.google.protobuf.Enu"
+ "mValue\022(\n\007options\030\003 \003(\0132\027.google.protobu"
+ "f.Option\0226\n\016source_context\030\004 \001(\0132\036.googl"
+ "e.protobuf.SourceContext\022\'\n\006syntax\030\005 \001(\016"
+ "2\027.google.protobuf.Syntax\"S\n\tEnumValue\022\014"
+ "\n\004name\030\001 \001(\t\022\016\n\006number\030\002 \001(\005\022(\n\007options\030"
+ "\003 \003(\0132\027.google.protobuf.Option\";\n\006Option"
+ "\022\014\n\004name\030\001 \001(\t\022#\n\005value\030\002 \001(\0132\024.google.p"
+ "rotobuf.Any*.\n\006Syntax\022\021\n\rSYNTAX_PROTO2\020\000"
+ "\022\021\n\rSYNTAX_PROTO3\020\001B{\n\023com.google.protob"
+ "ufB\tTypeProtoP\001Z-google.golang.org/proto"
+ "buf/types/known/typepb\370\001\001\242\002\003GPB\252\002\036Google"
+ ".Protobuf.WellKnownTypesb\006proto3"
+ ;
+static const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable*const descriptor_table_google_2fprotobuf_2ftype_2eproto_deps[2] = {
+ &::descriptor_table_google_2fprotobuf_2fany_2eproto,
+ &::descriptor_table_google_2fprotobuf_2fsource_5fcontext_2eproto,
+};
+static ::PROTOBUF_NAMESPACE_ID::internal::once_flag descriptor_table_google_2fprotobuf_2ftype_2eproto_once;
+const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2ftype_2eproto = {
+ false, false, 1592, descriptor_table_protodef_google_2fprotobuf_2ftype_2eproto, "google/protobuf/type.proto",
+ &descriptor_table_google_2fprotobuf_2ftype_2eproto_once, descriptor_table_google_2fprotobuf_2ftype_2eproto_deps, 2, 5,
+ schemas, file_default_instances, TableStruct_google_2fprotobuf_2ftype_2eproto::offsets,
+ file_level_metadata_google_2fprotobuf_2ftype_2eproto, file_level_enum_descriptors_google_2fprotobuf_2ftype_2eproto, file_level_service_descriptors_google_2fprotobuf_2ftype_2eproto,
+};
+PROTOBUF_ATTRIBUTE_WEAK const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable* descriptor_table_google_2fprotobuf_2ftype_2eproto_getter() {
+ return &descriptor_table_google_2fprotobuf_2ftype_2eproto;
+}
+
+// Force running AddDescriptors() at dynamic initialization time.
+PROTOBUF_ATTRIBUTE_INIT_PRIORITY static ::PROTOBUF_NAMESPACE_ID::internal::AddDescriptorsRunner dynamic_init_dummy_google_2fprotobuf_2ftype_2eproto(&descriptor_table_google_2fprotobuf_2ftype_2eproto);
+PROTOBUF_NAMESPACE_OPEN
+const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* Field_Kind_descriptor() {
+ ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(&descriptor_table_google_2fprotobuf_2ftype_2eproto);
+ return file_level_enum_descriptors_google_2fprotobuf_2ftype_2eproto[0];
+}
+bool Field_Kind_IsValid(int value) {
+ switch (value) {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ case 8:
+ case 9:
+ case 10:
+ case 11:
+ case 12:
+ case 13:
+ case 14:
+ case 15:
+ case 16:
+ case 17:
+ case 18:
+ return true;
+ default:
+ return false;
+ }
+}
+
+#if (__cplusplus < 201703) && (!defined(_MSC_VER) || (_MSC_VER >= 1900 && _MSC_VER < 1912))
+constexpr Field_Kind Field::TYPE_UNKNOWN;
+constexpr Field_Kind Field::TYPE_DOUBLE;
+constexpr Field_Kind Field::TYPE_FLOAT;
+constexpr Field_Kind Field::TYPE_INT64;
+constexpr Field_Kind Field::TYPE_UINT64;
+constexpr Field_Kind Field::TYPE_INT32;
+constexpr Field_Kind Field::TYPE_FIXED64;
+constexpr Field_Kind Field::TYPE_FIXED32;
+constexpr Field_Kind Field::TYPE_BOOL;
+constexpr Field_Kind Field::TYPE_STRING;
+constexpr Field_Kind Field::TYPE_GROUP;
+constexpr Field_Kind Field::TYPE_MESSAGE;
+constexpr Field_Kind Field::TYPE_BYTES;
+constexpr Field_Kind Field::TYPE_UINT32;
+constexpr Field_Kind Field::TYPE_ENUM;
+constexpr Field_Kind Field::TYPE_SFIXED32;
+constexpr Field_Kind Field::TYPE_SFIXED64;
+constexpr Field_Kind Field::TYPE_SINT32;
+constexpr Field_Kind Field::TYPE_SINT64;
+constexpr Field_Kind Field::Kind_MIN;
+constexpr Field_Kind Field::Kind_MAX;
+constexpr int Field::Kind_ARRAYSIZE;
+#endif // (__cplusplus < 201703) && (!defined(_MSC_VER) || (_MSC_VER >= 1900 && _MSC_VER < 1912))
+const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* Field_Cardinality_descriptor() {
+ ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(&descriptor_table_google_2fprotobuf_2ftype_2eproto);
+ return file_level_enum_descriptors_google_2fprotobuf_2ftype_2eproto[1];
+}
+bool Field_Cardinality_IsValid(int value) {
+ switch (value) {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ return true;
+ default:
+ return false;
+ }
+}
+
+#if (__cplusplus < 201703) && (!defined(_MSC_VER) || (_MSC_VER >= 1900 && _MSC_VER < 1912))
+constexpr Field_Cardinality Field::CARDINALITY_UNKNOWN;
+constexpr Field_Cardinality Field::CARDINALITY_OPTIONAL;
+constexpr Field_Cardinality Field::CARDINALITY_REQUIRED;
+constexpr Field_Cardinality Field::CARDINALITY_REPEATED;
+constexpr Field_Cardinality Field::Cardinality_MIN;
+constexpr Field_Cardinality Field::Cardinality_MAX;
+constexpr int Field::Cardinality_ARRAYSIZE;
+#endif // (__cplusplus < 201703) && (!defined(_MSC_VER) || (_MSC_VER >= 1900 && _MSC_VER < 1912))
+const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* Syntax_descriptor() {
+ ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(&descriptor_table_google_2fprotobuf_2ftype_2eproto);
+ return file_level_enum_descriptors_google_2fprotobuf_2ftype_2eproto[2];
+}
+bool Syntax_IsValid(int value) {
+ switch (value) {
+ case 0:
+ case 1:
+ return true;
+ default:
+ return false;
+ }
+}
+
+
+// ===================================================================
+
+class Type::_Internal {
+ public:
+ static const ::PROTOBUF_NAMESPACE_ID::SourceContext& source_context(const Type* msg);
+};
+
+const ::PROTOBUF_NAMESPACE_ID::SourceContext&
+Type::_Internal::source_context(const Type* msg) {
+ return *msg->source_context_;
+}
+void Type::clear_source_context() {
+ if (GetArenaForAllocation() == nullptr && source_context_ != nullptr) {
+ delete source_context_;
+ }
+ source_context_ = nullptr;
+}
+Type::Type(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned)
+ : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned),
+ fields_(arena),
+ oneofs_(arena),
+ options_(arena) {
+ SharedCtor();
+ if (!is_message_owned) {
+ RegisterArenaDtor(arena);
+ }
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.Type)
+}
+Type::Type(const Type& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message(),
+ fields_(from.fields_),
+ oneofs_(from.oneofs_),
+ options_(from.options_) {
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (!from._internal_name().empty()) {
+ name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_name(),
+ GetArenaForAllocation());
+ }
+ if (from._internal_has_source_context()) {
+ source_context_ = new ::PROTOBUF_NAMESPACE_ID::SourceContext(*from.source_context_);
+ } else {
+ source_context_ = nullptr;
+ }
+ syntax_ = from.syntax_;
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.Type)
+}
+
+inline void Type::SharedCtor() {
+name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+::memset(reinterpret_cast<char*>(this) + static_cast<size_t>(
+ reinterpret_cast<char*>(&source_context_) - reinterpret_cast<char*>(this)),
+ 0, static_cast<size_t>(reinterpret_cast<char*>(&syntax_) -
+ reinterpret_cast<char*>(&source_context_)) + sizeof(syntax_));
+}
+
+Type::~Type() {
+ // @@protoc_insertion_point(destructor:google.protobuf.Type)
+ if (GetArenaForAllocation() != nullptr) return;
+ SharedDtor();
+ _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+inline void Type::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+ name_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ if (this != internal_default_instance()) delete source_context_;
+}
+
+void Type::ArenaDtor(void* object) {
+ Type* _this = reinterpret_cast< Type* >(object);
+ (void)_this;
+}
+void Type::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) {
+}
+void Type::SetCachedSize(int size) const {
+ _cached_size_.Set(size);
+}
+
+void Type::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.Type)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ fields_.Clear();
+ oneofs_.Clear();
+ options_.Clear();
+ name_.ClearToEmpty();
+ if (GetArenaForAllocation() == nullptr && source_context_ != nullptr) {
+ delete source_context_;
+ }
+ source_context_ = nullptr;
+ syntax_ = 0;
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* Type::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag);
+ switch (tag >> 3) {
+ // string name = 1;
+ case 1:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 10)) {
+ auto str = _internal_mutable_name();
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx);
+ CHK_(::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.Type.name"));
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // repeated .google.protobuf.Field fields = 2;
+ case 2:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 18)) {
+ ptr -= 1;
+ do {
+ ptr += 1;
+ ptr = ctx->ParseMessage(_internal_add_fields(), ptr);
+ CHK_(ptr);
+ if (!ctx->DataAvailable(ptr)) break;
+ } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<18>(ptr));
+ } else
+ goto handle_unusual;
+ continue;
+ // repeated string oneofs = 3;
+ case 3:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 26)) {
+ ptr -= 1;
+ do {
+ ptr += 1;
+ auto str = _internal_add_oneofs();
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx);
+ CHK_(::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.Type.oneofs"));
+ CHK_(ptr);
+ if (!ctx->DataAvailable(ptr)) break;
+ } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<26>(ptr));
+ } else
+ goto handle_unusual;
+ continue;
+ // repeated .google.protobuf.Option options = 4;
+ case 4:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 34)) {
+ ptr -= 1;
+ do {
+ ptr += 1;
+ ptr = ctx->ParseMessage(_internal_add_options(), ptr);
+ CHK_(ptr);
+ if (!ctx->DataAvailable(ptr)) break;
+ } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<34>(ptr));
+ } else
+ goto handle_unusual;
+ continue;
+ // .google.protobuf.SourceContext source_context = 5;
+ case 5:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 42)) {
+ ptr = ctx->ParseMessage(_internal_mutable_source_context(), ptr);
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // .google.protobuf.Syntax syntax = 6;
+ case 6:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 48)) {
+ 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 int i = 0,
+ n = static_cast<unsigned int>(this->_internal_fields_size()); i < n; i++) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(2, this->_internal_fields(i), target, stream);
+ }
+
+ // repeated string oneofs = 3;
+ for (int i = 0, n = this->_internal_oneofs_size(); i < n; i++) {
+ const auto& s = this->_internal_oneofs(i);
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::VerifyUtf8String(
+ s.data(), static_cast<int>(s.length()),
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SERIALIZE,
+ "google.protobuf.Type.oneofs");
+ target = stream->WriteString(3, s, target);
+ }
+
+ // repeated .google.protobuf.Option options = 4;
+ for (unsigned int i = 0,
+ n = static_cast<unsigned int>(this->_internal_options_size()); i < n; i++) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(4, this->_internal_options(i), target, stream);
+ }
+
+ // .google.protobuf.SourceContext source_context = 5;
+ if (this->_internal_has_source_context()) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(
+ 5, _Internal::source_context(this), target, stream);
+ }
+
+ // .google.protobuf.Syntax syntax = 6;
+ if (this->_internal_syntax() != 0) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteEnumToArray(
+ 6, this->_internal_syntax(), target);
+ }
+
+ if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray(
+ _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Type)
+ return target;
+}
+
+size_t Type::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.Type)
+ size_t total_size = 0;
+
+ 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->fields_) {
+ total_size +=
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg);
+ }
+
+ // repeated string oneofs = 3;
+ total_size += 1 *
+ ::PROTOBUF_NAMESPACE_ID::internal::FromIntSize(oneofs_.size());
+ for (int i = 0, n = oneofs_.size(); i < n; i++) {
+ total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
+ oneofs_.Get(i));
+ }
+
+ // repeated .google.protobuf.Option options = 4;
+ total_size += 1UL * this->_internal_options_size();
+ for (const auto& msg : this->options_) {
+ total_size +=
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg);
+ }
+
+ // string name = 1;
+ if (!this->_internal_name().empty()) {
+ total_size += 1 +
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
+ this->_internal_name());
+ }
+
+ // .google.protobuf.SourceContext source_context = 5;
+ if (this->_internal_has_source_context()) {
+ total_size += 1 +
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(
+ *source_context_);
+ }
+
+ // .google.protobuf.Syntax syntax = 6;
+ if (this->_internal_syntax() != 0) {
+ total_size += 1 +
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::EnumSize(this->_internal_syntax());
+ }
+
+ return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData Type::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck,
+ Type::MergeImpl
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*Type::GetClassData() const { return &_class_data_; }
+
+void Type::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to,
+ const ::PROTOBUF_NAMESPACE_ID::Message& from) {
+ static_cast<Type *>(to)->MergeFrom(
+ static_cast<const Type &>(from));
+}
+
+
+void Type::MergeFrom(const Type& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Type)
+ GOOGLE_DCHECK_NE(&from, this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ fields_.MergeFrom(from.fields_);
+ oneofs_.MergeFrom(from.oneofs_);
+ options_.MergeFrom(from.options_);
+ if (!from._internal_name().empty()) {
+ _internal_set_name(from._internal_name());
+ }
+ if (from._internal_has_source_context()) {
+ _internal_mutable_source_context()->::PROTOBUF_NAMESPACE_ID::SourceContext::MergeFrom(from._internal_source_context());
+ }
+ if (from._internal_syntax() != 0) {
+ _internal_set_syntax(from._internal_syntax());
+ }
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+}
+
+void Type::CopyFrom(const Type& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.Type)
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+bool Type::IsInitialized() const {
+ return true;
+}
+
+void Type::InternalSwap(Type* other) {
+ using std::swap;
+ auto* lhs_arena = GetArenaForAllocation();
+ auto* rhs_arena = other->GetArenaForAllocation();
+ _internal_metadata_.InternalSwap(&other->_internal_metadata_);
+ fields_.InternalSwap(&other->fields_);
+ oneofs_.InternalSwap(&other->oneofs_);
+ options_.InternalSwap(&other->options_);
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(),
+ &name_, lhs_arena,
+ &other->name_, rhs_arena
+ );
+ ::PROTOBUF_NAMESPACE_ID::internal::memswap<
+ PROTOBUF_FIELD_OFFSET(Type, syntax_)
+ + sizeof(Type::syntax_)
+ - PROTOBUF_FIELD_OFFSET(Type, source_context_)>(
+ reinterpret_cast<char*>(&source_context_),
+ reinterpret_cast<char*>(&other->source_context_));
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata Type::GetMetadata() const {
+ return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(
+ &descriptor_table_google_2fprotobuf_2ftype_2eproto_getter, &descriptor_table_google_2fprotobuf_2ftype_2eproto_once,
+ file_level_metadata_google_2fprotobuf_2ftype_2eproto[0]);
+}
+
+// ===================================================================
+
+class Field::_Internal {
+ public:
+};
+
+Field::Field(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned)
+ : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned),
+ options_(arena) {
+ SharedCtor();
+ if (!is_message_owned) {
+ RegisterArenaDtor(arena);
+ }
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.Field)
+}
+Field::Field(const Field& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message(),
+ options_(from.options_) {
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (!from._internal_name().empty()) {
+ name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_name(),
+ GetArenaForAllocation());
+ }
+ type_url_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ type_url_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (!from._internal_type_url().empty()) {
+ type_url_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_type_url(),
+ GetArenaForAllocation());
+ }
+ json_name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ json_name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (!from._internal_json_name().empty()) {
+ json_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_json_name(),
+ GetArenaForAllocation());
+ }
+ default_value_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ default_value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (!from._internal_default_value().empty()) {
+ default_value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_default_value(),
+ GetArenaForAllocation());
+ }
+ ::memcpy(&kind_, &from.kind_,
+ static_cast<size_t>(reinterpret_cast<char*>(&packed_) -
+ reinterpret_cast<char*>(&kind_)) + sizeof(packed_));
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.Field)
+}
+
+inline void Field::SharedCtor() {
+name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+type_url_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ type_url_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+json_name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ json_name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+default_value_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ default_value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+::memset(reinterpret_cast<char*>(this) + static_cast<size_t>(
+ reinterpret_cast<char*>(&kind_) - reinterpret_cast<char*>(this)),
+ 0, static_cast<size_t>(reinterpret_cast<char*>(&packed_) -
+ reinterpret_cast<char*>(&kind_)) + sizeof(packed_));
+}
+
+Field::~Field() {
+ // @@protoc_insertion_point(destructor:google.protobuf.Field)
+ if (GetArenaForAllocation() != nullptr) return;
+ SharedDtor();
+ _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+inline void Field::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+ name_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ type_url_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ json_name_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ default_value_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+}
+
+void Field::ArenaDtor(void* object) {
+ Field* _this = reinterpret_cast< Field* >(object);
+ (void)_this;
+}
+void Field::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) {
+}
+void Field::SetCachedSize(int size) const {
+ _cached_size_.Set(size);
+}
+
+void Field::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.Field)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ options_.Clear();
+ name_.ClearToEmpty();
+ type_url_.ClearToEmpty();
+ json_name_.ClearToEmpty();
+ default_value_.ClearToEmpty();
+ ::memset(&kind_, 0, static_cast<size_t>(
+ reinterpret_cast<char*>(&packed_) -
+ reinterpret_cast<char*>(&kind_)) + sizeof(packed_));
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* Field::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag);
+ switch (tag >> 3) {
+ // .google.protobuf.Field.Kind kind = 1;
+ case 1:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 8)) {
+ 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)) {
+ number_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint32(&ptr);
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // string name = 4;
+ case 4:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 34)) {
+ auto str = _internal_mutable_name();
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx);
+ CHK_(::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.Field.name"));
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // string type_url = 6;
+ case 6:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 50)) {
+ auto str = _internal_mutable_type_url();
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx);
+ CHK_(::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.Field.type_url"));
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // int32 oneof_index = 7;
+ case 7:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 56)) {
+ oneof_index_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint32(&ptr);
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // bool packed = 8;
+ case 8:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 64)) {
+ packed_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr);
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // repeated .google.protobuf.Option options = 9;
+ case 9:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 74)) {
+ ptr -= 1;
+ do {
+ ptr += 1;
+ ptr = ctx->ParseMessage(_internal_add_options(), ptr);
+ CHK_(ptr);
+ if (!ctx->DataAvailable(ptr)) break;
+ } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<74>(ptr));
+ } else
+ goto handle_unusual;
+ continue;
+ // string json_name = 10;
+ case 10:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 82)) {
+ auto str = _internal_mutable_json_name();
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx);
+ CHK_(::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.Field.json_name"));
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // string default_value = 11;
+ case 11:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 90)) {
+ auto str = _internal_mutable_default_value();
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx);
+ CHK_(::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.Field.default_value"));
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ default:
+ goto handle_unusual;
+ } // switch
+ handle_unusual:
+ if ((tag == 0) || ((tag & 7) == 4)) {
+ CHK_(ptr);
+ ctx->SetLastTag(tag);
+ goto message_done;
+ }
+ ptr = UnknownFieldParse(
+ tag,
+ _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(),
+ ptr, ctx);
+ CHK_(ptr != nullptr);
+ } // while
+message_done:
+ return ptr;
+failure:
+ ptr = nullptr;
+ goto message_done;
+#undef CHK_
+}
+
+uint8_t* Field::_InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const {
+ // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Field)
+ 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 = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteEnumToArray(
+ 1, this->_internal_kind(), target);
+ }
+
+ // .google.protobuf.Field.Cardinality cardinality = 2;
+ if (this->_internal_cardinality() != 0) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteEnumToArray(
+ 2, this->_internal_cardinality(), target);
+ }
+
+ // int32 number = 3;
+ if (this->_internal_number() != 0) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32ToArray(3, this->_internal_number(), target);
+ }
+
+ // string name = 4;
+ if (!this->_internal_name().empty()) {
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::VerifyUtf8String(
+ this->_internal_name().data(), static_cast<int>(this->_internal_name().length()),
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SERIALIZE,
+ "google.protobuf.Field.name");
+ target = stream->WriteStringMaybeAliased(
+ 4, this->_internal_name(), target);
+ }
+
+ // string type_url = 6;
+ if (!this->_internal_type_url().empty()) {
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::VerifyUtf8String(
+ this->_internal_type_url().data(), static_cast<int>(this->_internal_type_url().length()),
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SERIALIZE,
+ "google.protobuf.Field.type_url");
+ target = stream->WriteStringMaybeAliased(
+ 6, this->_internal_type_url(), target);
+ }
+
+ // int32 oneof_index = 7;
+ if (this->_internal_oneof_index() != 0) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32ToArray(7, this->_internal_oneof_index(), target);
+ }
+
+ // bool packed = 8;
+ if (this->_internal_packed() != 0) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBoolToArray(8, this->_internal_packed(), target);
+ }
+
+ // repeated .google.protobuf.Option options = 9;
+ for (unsigned int i = 0,
+ n = static_cast<unsigned int>(this->_internal_options_size()); i < n; i++) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(9, this->_internal_options(i), target, stream);
+ }
+
+ // string json_name = 10;
+ if (!this->_internal_json_name().empty()) {
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::VerifyUtf8String(
+ this->_internal_json_name().data(), static_cast<int>(this->_internal_json_name().length()),
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SERIALIZE,
+ "google.protobuf.Field.json_name");
+ target = stream->WriteStringMaybeAliased(
+ 10, this->_internal_json_name(), target);
+ }
+
+ // string default_value = 11;
+ if (!this->_internal_default_value().empty()) {
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::VerifyUtf8String(
+ this->_internal_default_value().data(), static_cast<int>(this->_internal_default_value().length()),
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SERIALIZE,
+ "google.protobuf.Field.default_value");
+ target = stream->WriteStringMaybeAliased(
+ 11, this->_internal_default_value(), target);
+ }
+
+ if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray(
+ _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Field)
+ return target;
+}
+
+size_t Field::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.Field)
+ size_t total_size = 0;
+
+ 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->options_) {
+ total_size +=
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg);
+ }
+
+ // string name = 4;
+ if (!this->_internal_name().empty()) {
+ total_size += 1 +
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
+ this->_internal_name());
+ }
+
+ // string type_url = 6;
+ if (!this->_internal_type_url().empty()) {
+ total_size += 1 +
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
+ this->_internal_type_url());
+ }
+
+ // string json_name = 10;
+ if (!this->_internal_json_name().empty()) {
+ total_size += 1 +
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
+ this->_internal_json_name());
+ }
+
+ // string default_value = 11;
+ if (!this->_internal_default_value().empty()) {
+ total_size += 1 +
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
+ this->_internal_default_value());
+ }
+
+ // .google.protobuf.Field.Kind kind = 1;
+ if (this->_internal_kind() != 0) {
+ total_size += 1 +
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::EnumSize(this->_internal_kind());
+ }
+
+ // .google.protobuf.Field.Cardinality cardinality = 2;
+ if (this->_internal_cardinality() != 0) {
+ total_size += 1 +
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::EnumSize(this->_internal_cardinality());
+ }
+
+ // int32 number = 3;
+ if (this->_internal_number() != 0) {
+ total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32SizePlusOne(this->_internal_number());
+ }
+
+ // int32 oneof_index = 7;
+ if (this->_internal_oneof_index() != 0) {
+ total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32SizePlusOne(this->_internal_oneof_index());
+ }
+
+ // bool packed = 8;
+ if (this->_internal_packed() != 0) {
+ total_size += 1 + 1;
+ }
+
+ return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData Field::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck,
+ Field::MergeImpl
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*Field::GetClassData() const { return &_class_data_; }
+
+void Field::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to,
+ const ::PROTOBUF_NAMESPACE_ID::Message& from) {
+ static_cast<Field *>(to)->MergeFrom(
+ static_cast<const Field &>(from));
+}
+
+
+void Field::MergeFrom(const Field& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Field)
+ GOOGLE_DCHECK_NE(&from, this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ options_.MergeFrom(from.options_);
+ if (!from._internal_name().empty()) {
+ _internal_set_name(from._internal_name());
+ }
+ if (!from._internal_type_url().empty()) {
+ _internal_set_type_url(from._internal_type_url());
+ }
+ if (!from._internal_json_name().empty()) {
+ _internal_set_json_name(from._internal_json_name());
+ }
+ if (!from._internal_default_value().empty()) {
+ _internal_set_default_value(from._internal_default_value());
+ }
+ if (from._internal_kind() != 0) {
+ _internal_set_kind(from._internal_kind());
+ }
+ if (from._internal_cardinality() != 0) {
+ _internal_set_cardinality(from._internal_cardinality());
+ }
+ if (from._internal_number() != 0) {
+ _internal_set_number(from._internal_number());
+ }
+ if (from._internal_oneof_index() != 0) {
+ _internal_set_oneof_index(from._internal_oneof_index());
+ }
+ if (from._internal_packed() != 0) {
+ _internal_set_packed(from._internal_packed());
+ }
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+}
+
+void Field::CopyFrom(const Field& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.Field)
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+bool Field::IsInitialized() const {
+ return true;
+}
+
+void Field::InternalSwap(Field* other) {
+ using std::swap;
+ auto* lhs_arena = GetArenaForAllocation();
+ auto* rhs_arena = other->GetArenaForAllocation();
+ _internal_metadata_.InternalSwap(&other->_internal_metadata_);
+ options_.InternalSwap(&other->options_);
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(),
+ &name_, lhs_arena,
+ &other->name_, rhs_arena
+ );
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(),
+ &type_url_, lhs_arena,
+ &other->type_url_, rhs_arena
+ );
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(),
+ &json_name_, lhs_arena,
+ &other->json_name_, rhs_arena
+ );
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(),
+ &default_value_, lhs_arena,
+ &other->default_value_, rhs_arena
+ );
+ ::PROTOBUF_NAMESPACE_ID::internal::memswap<
+ PROTOBUF_FIELD_OFFSET(Field, packed_)
+ + sizeof(Field::packed_)
+ - PROTOBUF_FIELD_OFFSET(Field, kind_)>(
+ reinterpret_cast<char*>(&kind_),
+ reinterpret_cast<char*>(&other->kind_));
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata Field::GetMetadata() const {
+ return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(
+ &descriptor_table_google_2fprotobuf_2ftype_2eproto_getter, &descriptor_table_google_2fprotobuf_2ftype_2eproto_once,
+ file_level_metadata_google_2fprotobuf_2ftype_2eproto[1]);
+}
+
+// ===================================================================
+
+class Enum::_Internal {
+ public:
+ static const ::PROTOBUF_NAMESPACE_ID::SourceContext& source_context(const Enum* msg);
+};
+
+const ::PROTOBUF_NAMESPACE_ID::SourceContext&
+Enum::_Internal::source_context(const Enum* msg) {
+ return *msg->source_context_;
+}
+void Enum::clear_source_context() {
+ if (GetArenaForAllocation() == nullptr && source_context_ != nullptr) {
+ delete source_context_;
+ }
+ source_context_ = nullptr;
+}
+Enum::Enum(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned)
+ : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned),
+ enumvalue_(arena),
+ options_(arena) {
+ SharedCtor();
+ if (!is_message_owned) {
+ RegisterArenaDtor(arena);
+ }
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.Enum)
+}
+Enum::Enum(const Enum& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message(),
+ enumvalue_(from.enumvalue_),
+ options_(from.options_) {
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (!from._internal_name().empty()) {
+ name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_name(),
+ GetArenaForAllocation());
+ }
+ if (from._internal_has_source_context()) {
+ source_context_ = new ::PROTOBUF_NAMESPACE_ID::SourceContext(*from.source_context_);
+ } else {
+ source_context_ = nullptr;
+ }
+ syntax_ = from.syntax_;
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.Enum)
+}
+
+inline void Enum::SharedCtor() {
+name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+::memset(reinterpret_cast<char*>(this) + static_cast<size_t>(
+ reinterpret_cast<char*>(&source_context_) - reinterpret_cast<char*>(this)),
+ 0, static_cast<size_t>(reinterpret_cast<char*>(&syntax_) -
+ reinterpret_cast<char*>(&source_context_)) + sizeof(syntax_));
+}
+
+Enum::~Enum() {
+ // @@protoc_insertion_point(destructor:google.protobuf.Enum)
+ if (GetArenaForAllocation() != nullptr) return;
+ SharedDtor();
+ _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+inline void Enum::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+ name_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ if (this != internal_default_instance()) delete source_context_;
+}
+
+void Enum::ArenaDtor(void* object) {
+ Enum* _this = reinterpret_cast< Enum* >(object);
+ (void)_this;
+}
+void Enum::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) {
+}
+void Enum::SetCachedSize(int size) const {
+ _cached_size_.Set(size);
+}
+
+void Enum::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.Enum)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ enumvalue_.Clear();
+ options_.Clear();
+ name_.ClearToEmpty();
+ if (GetArenaForAllocation() == nullptr && source_context_ != nullptr) {
+ delete source_context_;
+ }
+ source_context_ = nullptr;
+ syntax_ = 0;
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* Enum::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag);
+ switch (tag >> 3) {
+ // string name = 1;
+ case 1:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 10)) {
+ auto str = _internal_mutable_name();
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx);
+ CHK_(::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.Enum.name"));
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // repeated .google.protobuf.EnumValue enumvalue = 2;
+ case 2:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 18)) {
+ ptr -= 1;
+ do {
+ ptr += 1;
+ ptr = ctx->ParseMessage(_internal_add_enumvalue(), ptr);
+ CHK_(ptr);
+ if (!ctx->DataAvailable(ptr)) break;
+ } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<18>(ptr));
+ } else
+ goto handle_unusual;
+ continue;
+ // repeated .google.protobuf.Option options = 3;
+ case 3:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 26)) {
+ ptr -= 1;
+ do {
+ ptr += 1;
+ ptr = ctx->ParseMessage(_internal_add_options(), ptr);
+ CHK_(ptr);
+ if (!ctx->DataAvailable(ptr)) break;
+ } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<26>(ptr));
+ } else
+ goto handle_unusual;
+ continue;
+ // .google.protobuf.SourceContext source_context = 4;
+ case 4:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 34)) {
+ ptr = ctx->ParseMessage(_internal_mutable_source_context(), ptr);
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // .google.protobuf.Syntax syntax = 5;
+ case 5:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 40)) {
+ 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 int i = 0,
+ n = static_cast<unsigned int>(this->_internal_enumvalue_size()); i < n; i++) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(2, this->_internal_enumvalue(i), target, stream);
+ }
+
+ // repeated .google.protobuf.Option options = 3;
+ for (unsigned int i = 0,
+ n = static_cast<unsigned int>(this->_internal_options_size()); i < n; i++) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(3, this->_internal_options(i), target, stream);
+ }
+
+ // .google.protobuf.SourceContext source_context = 4;
+ if (this->_internal_has_source_context()) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(
+ 4, _Internal::source_context(this), target, stream);
+ }
+
+ // .google.protobuf.Syntax syntax = 5;
+ if (this->_internal_syntax() != 0) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteEnumToArray(
+ 5, this->_internal_syntax(), target);
+ }
+
+ if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray(
+ _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Enum)
+ return target;
+}
+
+size_t Enum::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.Enum)
+ size_t total_size = 0;
+
+ 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->enumvalue_) {
+ total_size +=
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg);
+ }
+
+ // repeated .google.protobuf.Option options = 3;
+ total_size += 1UL * this->_internal_options_size();
+ for (const auto& msg : this->options_) {
+ total_size +=
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg);
+ }
+
+ // string name = 1;
+ if (!this->_internal_name().empty()) {
+ total_size += 1 +
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
+ this->_internal_name());
+ }
+
+ // .google.protobuf.SourceContext source_context = 4;
+ if (this->_internal_has_source_context()) {
+ total_size += 1 +
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(
+ *source_context_);
+ }
+
+ // .google.protobuf.Syntax syntax = 5;
+ if (this->_internal_syntax() != 0) {
+ total_size += 1 +
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::EnumSize(this->_internal_syntax());
+ }
+
+ return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData Enum::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck,
+ Enum::MergeImpl
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*Enum::GetClassData() const { return &_class_data_; }
+
+void Enum::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to,
+ const ::PROTOBUF_NAMESPACE_ID::Message& from) {
+ static_cast<Enum *>(to)->MergeFrom(
+ static_cast<const Enum &>(from));
+}
+
+
+void Enum::MergeFrom(const Enum& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Enum)
+ GOOGLE_DCHECK_NE(&from, this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ enumvalue_.MergeFrom(from.enumvalue_);
+ options_.MergeFrom(from.options_);
+ if (!from._internal_name().empty()) {
+ _internal_set_name(from._internal_name());
+ }
+ if (from._internal_has_source_context()) {
+ _internal_mutable_source_context()->::PROTOBUF_NAMESPACE_ID::SourceContext::MergeFrom(from._internal_source_context());
+ }
+ if (from._internal_syntax() != 0) {
+ _internal_set_syntax(from._internal_syntax());
+ }
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+}
+
+void Enum::CopyFrom(const Enum& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.Enum)
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+bool Enum::IsInitialized() const {
+ return true;
+}
+
+void Enum::InternalSwap(Enum* other) {
+ using std::swap;
+ auto* lhs_arena = GetArenaForAllocation();
+ auto* rhs_arena = other->GetArenaForAllocation();
+ _internal_metadata_.InternalSwap(&other->_internal_metadata_);
+ enumvalue_.InternalSwap(&other->enumvalue_);
+ options_.InternalSwap(&other->options_);
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(),
+ &name_, lhs_arena,
+ &other->name_, rhs_arena
+ );
+ ::PROTOBUF_NAMESPACE_ID::internal::memswap<
+ PROTOBUF_FIELD_OFFSET(Enum, syntax_)
+ + sizeof(Enum::syntax_)
+ - PROTOBUF_FIELD_OFFSET(Enum, source_context_)>(
+ reinterpret_cast<char*>(&source_context_),
+ reinterpret_cast<char*>(&other->source_context_));
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata Enum::GetMetadata() const {
+ return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(
+ &descriptor_table_google_2fprotobuf_2ftype_2eproto_getter, &descriptor_table_google_2fprotobuf_2ftype_2eproto_once,
+ file_level_metadata_google_2fprotobuf_2ftype_2eproto[2]);
+}
+
+// ===================================================================
+
+class EnumValue::_Internal {
+ public:
+};
+
+EnumValue::EnumValue(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned)
+ : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned),
+ options_(arena) {
+ SharedCtor();
+ if (!is_message_owned) {
+ RegisterArenaDtor(arena);
+ }
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.EnumValue)
+}
+EnumValue::EnumValue(const EnumValue& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message(),
+ options_(from.options_) {
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (!from._internal_name().empty()) {
+ name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_name(),
+ GetArenaForAllocation());
+ }
+ number_ = from.number_;
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.EnumValue)
+}
+
+inline void EnumValue::SharedCtor() {
+name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+number_ = 0;
+}
+
+EnumValue::~EnumValue() {
+ // @@protoc_insertion_point(destructor:google.protobuf.EnumValue)
+ if (GetArenaForAllocation() != nullptr) return;
+ SharedDtor();
+ _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+inline void EnumValue::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+ name_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+}
+
+void EnumValue::ArenaDtor(void* object) {
+ EnumValue* _this = reinterpret_cast< EnumValue* >(object);
+ (void)_this;
+}
+void EnumValue::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) {
+}
+void EnumValue::SetCachedSize(int size) const {
+ _cached_size_.Set(size);
+}
+
+void EnumValue::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.EnumValue)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ options_.Clear();
+ name_.ClearToEmpty();
+ number_ = 0;
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* EnumValue::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag);
+ switch (tag >> 3) {
+ // string name = 1;
+ case 1:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 10)) {
+ auto str = _internal_mutable_name();
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx);
+ CHK_(::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.EnumValue.name"));
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // int32 number = 2;
+ case 2:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 16)) {
+ number_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint32(&ptr);
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // repeated .google.protobuf.Option options = 3;
+ case 3:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 26)) {
+ ptr -= 1;
+ do {
+ ptr += 1;
+ ptr = ctx->ParseMessage(_internal_add_options(), ptr);
+ CHK_(ptr);
+ if (!ctx->DataAvailable(ptr)) break;
+ } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<26>(ptr));
+ } else
+ goto handle_unusual;
+ continue;
+ default:
+ goto handle_unusual;
+ } // switch
+ handle_unusual:
+ if ((tag == 0) || ((tag & 7) == 4)) {
+ CHK_(ptr);
+ ctx->SetLastTag(tag);
+ goto message_done;
+ }
+ ptr = UnknownFieldParse(
+ tag,
+ _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(),
+ ptr, ctx);
+ CHK_(ptr != nullptr);
+ } // while
+message_done:
+ return ptr;
+failure:
+ ptr = nullptr;
+ goto message_done;
+#undef CHK_
+}
+
+uint8_t* EnumValue::_InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const {
+ // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.EnumValue)
+ 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 = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32ToArray(2, this->_internal_number(), target);
+ }
+
+ // repeated .google.protobuf.Option options = 3;
+ for (unsigned int i = 0,
+ n = static_cast<unsigned int>(this->_internal_options_size()); i < n; i++) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(3, this->_internal_options(i), target, stream);
+ }
+
+ if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray(
+ _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.EnumValue)
+ return target;
+}
+
+size_t EnumValue::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.EnumValue)
+ size_t total_size = 0;
+
+ 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->options_) {
+ total_size +=
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg);
+ }
+
+ // string name = 1;
+ if (!this->_internal_name().empty()) {
+ total_size += 1 +
+ ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
+ this->_internal_name());
+ }
+
+ // int32 number = 2;
+ if (this->_internal_number() != 0) {
+ total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32SizePlusOne(this->_internal_number());
+ }
+
+ return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData EnumValue::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck,
+ EnumValue::MergeImpl
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*EnumValue::GetClassData() const { return &_class_data_; }
+
+void EnumValue::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to,
+ const ::PROTOBUF_NAMESPACE_ID::Message& from) {
+ static_cast<EnumValue *>(to)->MergeFrom(
+ static_cast<const EnumValue &>(from));
+}
+
+
+void EnumValue::MergeFrom(const EnumValue& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.EnumValue)
+ GOOGLE_DCHECK_NE(&from, this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ options_.MergeFrom(from.options_);
+ if (!from._internal_name().empty()) {
+ _internal_set_name(from._internal_name());
+ }
+ if (from._internal_number() != 0) {
+ _internal_set_number(from._internal_number());
+ }
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+}
+
+void EnumValue::CopyFrom(const EnumValue& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.EnumValue)
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+bool EnumValue::IsInitialized() const {
+ return true;
+}
+
+void EnumValue::InternalSwap(EnumValue* other) {
+ using std::swap;
+ auto* lhs_arena = GetArenaForAllocation();
+ auto* rhs_arena = other->GetArenaForAllocation();
+ _internal_metadata_.InternalSwap(&other->_internal_metadata_);
+ options_.InternalSwap(&other->options_);
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(),
+ &name_, lhs_arena,
+ &other->name_, rhs_arena
+ );
+ swap(number_, other->number_);
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata EnumValue::GetMetadata() const {
+ return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(
+ &descriptor_table_google_2fprotobuf_2ftype_2eproto_getter, &descriptor_table_google_2fprotobuf_2ftype_2eproto_once,
+ file_level_metadata_google_2fprotobuf_2ftype_2eproto[3]);
+}
+
+// ===================================================================
+
+class Option::_Internal {
+ public:
+ static const ::PROTOBUF_NAMESPACE_ID::Any& value(const Option* msg);
+};
+
+const ::PROTOBUF_NAMESPACE_ID::Any&
+Option::_Internal::value(const Option* msg) {
+ return *msg->value_;
+}
+void Option::clear_value() {
+ if (GetArenaForAllocation() == nullptr && value_ != nullptr) {
+ delete value_;
+ }
+ value_ = nullptr;
+}
+Option::Option(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned)
+ : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) {
+ SharedCtor();
+ if (!is_message_owned) {
+ RegisterArenaDtor(arena);
+ }
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.Option)
+}
+Option::Option(const Option& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message() {
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (!from._internal_name().empty()) {
+ name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_name(),
+ GetArenaForAllocation());
+ }
+ if (from._internal_has_value()) {
+ value_ = new ::PROTOBUF_NAMESPACE_ID::Any(*from.value_);
+ } else {
+ value_ = nullptr;
+ }
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.Option)
+}
+
+inline void Option::SharedCtor() {
+name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+value_ = nullptr;
+}
+
+Option::~Option() {
+ // @@protoc_insertion_point(destructor:google.protobuf.Option)
+ if (GetArenaForAllocation() != nullptr) return;
+ SharedDtor();
+ _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+inline void Option::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+ name_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ if (this != internal_default_instance()) delete value_;
+}
+
+void Option::ArenaDtor(void* object) {
+ Option* _this = reinterpret_cast< Option* >(object);
+ (void)_this;
+}
+void Option::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) {
+}
+void Option::SetCachedSize(int size) const {
+ _cached_size_.Set(size);
+}
+
+void Option::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.Option)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ name_.ClearToEmpty();
+ if (GetArenaForAllocation() == nullptr && value_ != nullptr) {
+ delete value_;
+ }
+ value_ = nullptr;
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* Option::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag);
+ switch (tag >> 3) {
+ // string name = 1;
+ case 1:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 10)) {
+ auto str = _internal_mutable_name();
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx);
+ CHK_(::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.Option.name"));
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ // .google.protobuf.Any value = 2;
+ case 2:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 18)) {
+ ptr = ctx->ParseMessage(_internal_mutable_value(), ptr);
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ default:
+ goto handle_unusual;
+ } // switch
+ handle_unusual:
+ if ((tag == 0) || ((tag & 7) == 4)) {
+ CHK_(ptr);
+ ctx->SetLastTag(tag);
+ goto message_done;
+ }
+ ptr = UnknownFieldParse(
+ tag,
+ _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(),
+ ptr, ctx);
+ CHK_(ptr != nullptr);
+ } // while
+message_done:
+ return ptr;
+failure:
+ ptr = nullptr;
+ goto message_done;
+#undef CHK_
+}
+
+uint8_t* Option::_InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const {
+ // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Option)
+ 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 = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+ InternalWriteMessage(
+ 2, _Internal::value(this), target, stream);
+ }
+
+ if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray(
+ _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Option)
+ return target;
+}
+
+size_t Option::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.Option)
+ size_t total_size = 0;
+
+ 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(
+ *value_);
+ }
+
+ return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData Option::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck,
+ Option::MergeImpl
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*Option::GetClassData() const { return &_class_data_; }
+
+void Option::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to,
+ const ::PROTOBUF_NAMESPACE_ID::Message& from) {
+ static_cast<Option *>(to)->MergeFrom(
+ static_cast<const Option &>(from));
+}
+
+
+void Option::MergeFrom(const Option& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Option)
+ GOOGLE_DCHECK_NE(&from, this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ if (!from._internal_name().empty()) {
+ _internal_set_name(from._internal_name());
+ }
+ if (from._internal_has_value()) {
+ _internal_mutable_value()->::PROTOBUF_NAMESPACE_ID::Any::MergeFrom(from._internal_value());
+ }
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+}
+
+void Option::CopyFrom(const Option& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.Option)
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+bool Option::IsInitialized() const {
+ return true;
+}
+
+void Option::InternalSwap(Option* other) {
+ using std::swap;
+ auto* lhs_arena = GetArenaForAllocation();
+ auto* rhs_arena = other->GetArenaForAllocation();
+ _internal_metadata_.InternalSwap(&other->_internal_metadata_);
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(),
+ &name_, lhs_arena,
+ &other->name_, rhs_arena
+ );
+ swap(value_, other->value_);
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata Option::GetMetadata() const {
+ return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(
+ &descriptor_table_google_2fprotobuf_2ftype_2eproto_getter, &descriptor_table_google_2fprotobuf_2ftype_2eproto_once,
+ file_level_metadata_google_2fprotobuf_2ftype_2eproto[4]);
+}
+
+// @@protoc_insertion_point(namespace_scope)
+PROTOBUF_NAMESPACE_CLOSE
+PROTOBUF_NAMESPACE_OPEN
+template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::Type* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::Type >(Arena* arena) {
+ return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::Type >(arena);
+}
+template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::Field* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::Field >(Arena* arena) {
+ return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::Field >(arena);
+}
+template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::Enum* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::Enum >(Arena* arena) {
+ return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::Enum >(arena);
+}
+template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::EnumValue* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::EnumValue >(Arena* arena) {
+ return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::EnumValue >(arena);
+}
+template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::Option* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::Option >(Arena* arena) {
+ return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::Option >(arena);
+}
+PROTOBUF_NAMESPACE_CLOSE
+
+// @@protoc_insertion_point(global_scope)
+#include <port_undef.inc>
diff --git a/NorthstarDedicatedTest/include/protobuf/type.pb.h b/NorthstarDedicatedTest/include/protobuf/type.pb.h
new file mode 100644
index 00000000..a3dc7d7e
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/type.pb.h
@@ -0,0 +1,2581 @@
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+// source: google/protobuf/type.proto
+
+#ifndef GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2ftype_2eproto
+#define GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2ftype_2eproto
+
+#include <limits>
+#include <string>
+
+#include <port_def.inc>
+#if PROTOBUF_VERSION < 3019000
+#error This file was generated by a newer version of protoc which is
+#error incompatible with your Protocol Buffer headers. Please update
+#error your headers.
+#endif
+#if 3019004 < 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 <port_undef.inc>
+#include <io/coded_stream.h>
+#include <arena.h>
+#include <arenastring.h>
+#include <generated_message_table_driven.h>
+#include <generated_message_util.h>
+#include <metadata_lite.h>
+#include <generated_message_reflection.h>
+#include <message.h>
+#include <repeated_field.h> // IWYU pragma: export
+#include <extension_set.h> // IWYU pragma: export
+#include <generated_enum_reflection.h>
+#include <unknown_field_set.h>
+#include <any.pb.h>
+#include <source_context.pb.h>
+// @@protoc_insertion_point(includes)
+#include <port_def.inc>
+#define PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2ftype_2eproto PROTOBUF_EXPORT
+PROTOBUF_NAMESPACE_OPEN
+namespace internal {
+class AnyMetadata;
+} // namespace internal
+PROTOBUF_NAMESPACE_CLOSE
+
+// Internal implementation detail -- do not use these members.
+struct PROTOBUF_EXPORT TableStruct_google_2fprotobuf_2ftype_2eproto {
+ static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTableField entries[]
+ PROTOBUF_SECTION_VARIABLE(protodesc_cold);
+ static const ::PROTOBUF_NAMESPACE_ID::internal::AuxiliaryParseTableField aux[]
+ PROTOBUF_SECTION_VARIABLE(protodesc_cold);
+ static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTable schema[5]
+ PROTOBUF_SECTION_VARIABLE(protodesc_cold);
+ static const ::PROTOBUF_NAMESPACE_ID::internal::FieldMetadata field_metadata[];
+ static const ::PROTOBUF_NAMESPACE_ID::internal::SerializationTable serialization_table[];
+ static const 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 constexpr Type(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
+
+ Type(const Type& from);
+ Type(Type&& from) noexcept
+ : Type() {
+ *this = ::std::move(from);
+ }
+
+ inline Type& operator=(const Type& from) {
+ CopyFrom(from);
+ return *this;
+ }
+ inline Type& operator=(Type&& from) noexcept {
+ if (this == &from) return *this;
+ if (GetOwningArena() == from.GetOwningArena()
+ #ifdef PROTOBUF_FORCE_COPY_IN_MOVE
+ && GetOwningArena() != nullptr
+ #endif // !PROTOBUF_FORCE_COPY_IN_MOVE
+ ) {
+ InternalSwap(&from);
+ } else {
+ CopyFrom(from);
+ }
+ return *this;
+ }
+
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
+ return GetDescriptor();
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
+ return default_instance().GetMetadata().descriptor;
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
+ return default_instance().GetMetadata().reflection;
+ }
+ static const Type& default_instance() {
+ return *internal_default_instance();
+ }
+ static inline const Type* internal_default_instance() {
+ return reinterpret_cast<const Type*>(
+ &_Type_default_instance_);
+ }
+ static constexpr int kIndexInFileMessages =
+ 0;
+
+ friend void swap(Type& a, Type& b) {
+ a.Swap(&b);
+ }
+ inline void Swap(Type* other) {
+ if (other == this) return;
+ #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() != nullptr &&
+ GetOwningArena() == other->GetOwningArena()) {
+ #else // PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() == other->GetOwningArena()) {
+ #endif // !PROTOBUF_FORCE_COPY_IN_SWAP
+ InternalSwap(other);
+ } else {
+ ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
+ }
+ }
+ void UnsafeArenaSwap(Type* other) {
+ if (other == this) return;
+ GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena());
+ InternalSwap(other);
+ }
+
+ // implements Message ----------------------------------------------
+
+ Type* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
+ return CreateMaybeMessage<Type>(arena);
+ }
+ using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
+ void CopyFrom(const Type& from);
+ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
+ void MergeFrom(const Type& from);
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from);
+ public:
+ PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+ bool IsInitialized() const final;
+
+ size_t ByteSizeLong() const final;
+ const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
+ uint8_t* _InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
+ int GetCachedSize() const final { return _cached_size_.Get(); }
+
+ private:
+ void SharedCtor();
+ void SharedDtor();
+ void SetCachedSize(int size) const final;
+ void InternalSwap(Type* other);
+
+ private:
+ friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
+ static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
+ return "google.protobuf.Type";
+ }
+ protected:
+ explicit Type(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned = false);
+ private:
+ static void ArenaDtor(void* object);
+ inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
+ public:
+
+ static const ClassData _class_data_;
+ const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;
+
+ ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;
+
+ // nested types ----------------------------------------------------
+
+ // accessors -------------------------------------------------------
+
+ enum : int {
+ kFieldsFieldNumber = 2,
+ kOneofsFieldNumber = 3,
+ kOptionsFieldNumber = 4,
+ kNameFieldNumber = 1,
+ kSourceContextFieldNumber = 5,
+ kSyntaxFieldNumber = 6,
+ };
+ // repeated .google.protobuf.Field fields = 2;
+ int fields_size() const;
+ private:
+ int _internal_fields_size() const;
+ public:
+ void clear_fields();
+ ::PROTOBUF_NAMESPACE_ID::Field* mutable_fields(int index);
+ ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Field >*
+ mutable_fields();
+ private:
+ const ::PROTOBUF_NAMESPACE_ID::Field& _internal_fields(int index) const;
+ ::PROTOBUF_NAMESPACE_ID::Field* _internal_add_fields();
+ public:
+ const ::PROTOBUF_NAMESPACE_ID::Field& fields(int index) const;
+ ::PROTOBUF_NAMESPACE_ID::Field* add_fields();
+ const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Field >&
+ fields() const;
+
+ // repeated string oneofs = 3;
+ int oneofs_size() const;
+ private:
+ int _internal_oneofs_size() const;
+ public:
+ void clear_oneofs();
+ const 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_;
+ ::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_;
+ friend struct ::TableStruct_google_2fprotobuf_2ftype_2eproto;
+};
+// -------------------------------------------------------------------
+
+class PROTOBUF_EXPORT Field final :
+ public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Field) */ {
+ public:
+ inline Field() : Field(nullptr) {}
+ ~Field() override;
+ explicit constexpr Field(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
+
+ Field(const Field& from);
+ Field(Field&& from) noexcept
+ : Field() {
+ *this = ::std::move(from);
+ }
+
+ inline Field& operator=(const Field& from) {
+ CopyFrom(from);
+ return *this;
+ }
+ inline Field& operator=(Field&& from) noexcept {
+ if (this == &from) return *this;
+ if (GetOwningArena() == from.GetOwningArena()
+ #ifdef PROTOBUF_FORCE_COPY_IN_MOVE
+ && GetOwningArena() != nullptr
+ #endif // !PROTOBUF_FORCE_COPY_IN_MOVE
+ ) {
+ InternalSwap(&from);
+ } else {
+ CopyFrom(from);
+ }
+ return *this;
+ }
+
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
+ return GetDescriptor();
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
+ return default_instance().GetMetadata().descriptor;
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
+ return default_instance().GetMetadata().reflection;
+ }
+ static const Field& default_instance() {
+ return *internal_default_instance();
+ }
+ static inline const Field* internal_default_instance() {
+ return reinterpret_cast<const Field*>(
+ &_Field_default_instance_);
+ }
+ static constexpr int kIndexInFileMessages =
+ 1;
+
+ friend void swap(Field& a, Field& b) {
+ a.Swap(&b);
+ }
+ inline void Swap(Field* other) {
+ if (other == this) return;
+ #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() != nullptr &&
+ GetOwningArena() == other->GetOwningArena()) {
+ #else // PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() == other->GetOwningArena()) {
+ #endif // !PROTOBUF_FORCE_COPY_IN_SWAP
+ InternalSwap(other);
+ } else {
+ ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
+ }
+ }
+ void UnsafeArenaSwap(Field* other) {
+ if (other == this) return;
+ GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena());
+ InternalSwap(other);
+ }
+
+ // implements Message ----------------------------------------------
+
+ Field* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
+ return CreateMaybeMessage<Field>(arena);
+ }
+ using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
+ void CopyFrom(const Field& from);
+ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
+ void MergeFrom(const Field& from);
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from);
+ public:
+ PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+ bool IsInitialized() const final;
+
+ size_t ByteSizeLong() const final;
+ const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
+ uint8_t* _InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
+ int GetCachedSize() const final { return _cached_size_.Get(); }
+
+ private:
+ void SharedCtor();
+ void SharedDtor();
+ void SetCachedSize(int size) const final;
+ void InternalSwap(Field* other);
+
+ private:
+ friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
+ static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
+ return "google.protobuf.Field";
+ }
+ protected:
+ explicit Field(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned = false);
+ private:
+ static void ArenaDtor(void* object);
+ inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
+ public:
+
+ static const ClassData _class_data_;
+ const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;
+
+ ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;
+
+ // nested types ----------------------------------------------------
+
+ typedef Field_Kind Kind;
+ static constexpr Kind TYPE_UNKNOWN =
+ Field_Kind_TYPE_UNKNOWN;
+ static constexpr Kind TYPE_DOUBLE =
+ Field_Kind_TYPE_DOUBLE;
+ static constexpr Kind TYPE_FLOAT =
+ Field_Kind_TYPE_FLOAT;
+ static constexpr Kind TYPE_INT64 =
+ Field_Kind_TYPE_INT64;
+ static constexpr Kind TYPE_UINT64 =
+ Field_Kind_TYPE_UINT64;
+ static constexpr Kind TYPE_INT32 =
+ Field_Kind_TYPE_INT32;
+ static constexpr Kind TYPE_FIXED64 =
+ Field_Kind_TYPE_FIXED64;
+ static constexpr Kind TYPE_FIXED32 =
+ Field_Kind_TYPE_FIXED32;
+ static constexpr Kind TYPE_BOOL =
+ Field_Kind_TYPE_BOOL;
+ static constexpr Kind TYPE_STRING =
+ Field_Kind_TYPE_STRING;
+ static constexpr Kind TYPE_GROUP =
+ Field_Kind_TYPE_GROUP;
+ static constexpr Kind TYPE_MESSAGE =
+ Field_Kind_TYPE_MESSAGE;
+ static constexpr Kind TYPE_BYTES =
+ Field_Kind_TYPE_BYTES;
+ static constexpr Kind TYPE_UINT32 =
+ Field_Kind_TYPE_UINT32;
+ static constexpr Kind TYPE_ENUM =
+ Field_Kind_TYPE_ENUM;
+ static constexpr Kind TYPE_SFIXED32 =
+ Field_Kind_TYPE_SFIXED32;
+ static constexpr Kind TYPE_SFIXED64 =
+ Field_Kind_TYPE_SFIXED64;
+ static constexpr Kind TYPE_SINT32 =
+ Field_Kind_TYPE_SINT32;
+ static constexpr Kind TYPE_SINT64 =
+ Field_Kind_TYPE_SINT64;
+ static inline bool Kind_IsValid(int value) {
+ return Field_Kind_IsValid(value);
+ }
+ static constexpr Kind Kind_MIN =
+ Field_Kind_Kind_MIN;
+ static constexpr Kind Kind_MAX =
+ Field_Kind_Kind_MAX;
+ static constexpr int Kind_ARRAYSIZE =
+ Field_Kind_Kind_ARRAYSIZE;
+ static inline const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor*
+ Kind_descriptor() {
+ return Field_Kind_descriptor();
+ }
+ template<typename T>
+ static inline const 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_;
+ ::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_;
+ friend struct ::TableStruct_google_2fprotobuf_2ftype_2eproto;
+};
+// -------------------------------------------------------------------
+
+class PROTOBUF_EXPORT Enum final :
+ public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Enum) */ {
+ public:
+ inline Enum() : Enum(nullptr) {}
+ ~Enum() override;
+ explicit constexpr Enum(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
+
+ Enum(const Enum& from);
+ Enum(Enum&& from) noexcept
+ : Enum() {
+ *this = ::std::move(from);
+ }
+
+ inline Enum& operator=(const Enum& from) {
+ CopyFrom(from);
+ return *this;
+ }
+ inline Enum& operator=(Enum&& from) noexcept {
+ if (this == &from) return *this;
+ if (GetOwningArena() == from.GetOwningArena()
+ #ifdef PROTOBUF_FORCE_COPY_IN_MOVE
+ && GetOwningArena() != nullptr
+ #endif // !PROTOBUF_FORCE_COPY_IN_MOVE
+ ) {
+ InternalSwap(&from);
+ } else {
+ CopyFrom(from);
+ }
+ return *this;
+ }
+
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
+ return GetDescriptor();
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
+ return default_instance().GetMetadata().descriptor;
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
+ return default_instance().GetMetadata().reflection;
+ }
+ static const Enum& default_instance() {
+ return *internal_default_instance();
+ }
+ static inline const Enum* internal_default_instance() {
+ return reinterpret_cast<const Enum*>(
+ &_Enum_default_instance_);
+ }
+ static constexpr int kIndexInFileMessages =
+ 2;
+
+ friend void swap(Enum& a, Enum& b) {
+ a.Swap(&b);
+ }
+ inline void Swap(Enum* other) {
+ if (other == this) return;
+ #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() != nullptr &&
+ GetOwningArena() == other->GetOwningArena()) {
+ #else // PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() == other->GetOwningArena()) {
+ #endif // !PROTOBUF_FORCE_COPY_IN_SWAP
+ InternalSwap(other);
+ } else {
+ ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
+ }
+ }
+ void UnsafeArenaSwap(Enum* other) {
+ if (other == this) return;
+ GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena());
+ InternalSwap(other);
+ }
+
+ // implements Message ----------------------------------------------
+
+ Enum* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
+ return CreateMaybeMessage<Enum>(arena);
+ }
+ using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
+ void CopyFrom(const Enum& from);
+ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
+ void MergeFrom(const Enum& from);
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from);
+ public:
+ PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+ bool IsInitialized() const final;
+
+ size_t ByteSizeLong() const final;
+ const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
+ uint8_t* _InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
+ int GetCachedSize() const final { return _cached_size_.Get(); }
+
+ private:
+ void SharedCtor();
+ void SharedDtor();
+ void SetCachedSize(int size) const final;
+ void InternalSwap(Enum* other);
+
+ private:
+ friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
+ static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
+ return "google.protobuf.Enum";
+ }
+ protected:
+ explicit Enum(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned = false);
+ private:
+ static void ArenaDtor(void* object);
+ inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
+ public:
+
+ static const ClassData _class_data_;
+ const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;
+
+ ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;
+
+ // nested types ----------------------------------------------------
+
+ // accessors -------------------------------------------------------
+
+ enum : int {
+ kEnumvalueFieldNumber = 2,
+ kOptionsFieldNumber = 3,
+ kNameFieldNumber = 1,
+ kSourceContextFieldNumber = 4,
+ kSyntaxFieldNumber = 5,
+ };
+ // repeated .google.protobuf.EnumValue enumvalue = 2;
+ int enumvalue_size() const;
+ private:
+ int _internal_enumvalue_size() const;
+ public:
+ void clear_enumvalue();
+ ::PROTOBUF_NAMESPACE_ID::EnumValue* mutable_enumvalue(int index);
+ ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::EnumValue >*
+ mutable_enumvalue();
+ private:
+ const ::PROTOBUF_NAMESPACE_ID::EnumValue& _internal_enumvalue(int index) const;
+ ::PROTOBUF_NAMESPACE_ID::EnumValue* _internal_add_enumvalue();
+ public:
+ const ::PROTOBUF_NAMESPACE_ID::EnumValue& enumvalue(int index) const;
+ ::PROTOBUF_NAMESPACE_ID::EnumValue* add_enumvalue();
+ const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::EnumValue >&
+ enumvalue() const;
+
+ // repeated .google.protobuf.Option options = 3;
+ int options_size() const;
+ private:
+ int _internal_options_size() const;
+ public:
+ void clear_options();
+ ::PROTOBUF_NAMESPACE_ID::Option* mutable_options(int index);
+ ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Option >*
+ mutable_options();
+ private:
+ const ::PROTOBUF_NAMESPACE_ID::Option& _internal_options(int index) const;
+ ::PROTOBUF_NAMESPACE_ID::Option* _internal_add_options();
+ public:
+ const ::PROTOBUF_NAMESPACE_ID::Option& options(int index) const;
+ ::PROTOBUF_NAMESPACE_ID::Option* add_options();
+ const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Option >&
+ options() const;
+
+ // string name = 1;
+ void clear_name();
+ const 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_;
+ ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::EnumValue > enumvalue_;
+ ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Option > options_;
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr name_;
+ ::PROTOBUF_NAMESPACE_ID::SourceContext* source_context_;
+ int syntax_;
+ mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
+ friend struct ::TableStruct_google_2fprotobuf_2ftype_2eproto;
+};
+// -------------------------------------------------------------------
+
+class PROTOBUF_EXPORT EnumValue final :
+ public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.EnumValue) */ {
+ public:
+ inline EnumValue() : EnumValue(nullptr) {}
+ ~EnumValue() override;
+ explicit constexpr EnumValue(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
+
+ EnumValue(const EnumValue& from);
+ EnumValue(EnumValue&& from) noexcept
+ : EnumValue() {
+ *this = ::std::move(from);
+ }
+
+ inline EnumValue& operator=(const EnumValue& from) {
+ CopyFrom(from);
+ return *this;
+ }
+ inline EnumValue& operator=(EnumValue&& from) noexcept {
+ if (this == &from) return *this;
+ if (GetOwningArena() == from.GetOwningArena()
+ #ifdef PROTOBUF_FORCE_COPY_IN_MOVE
+ && GetOwningArena() != nullptr
+ #endif // !PROTOBUF_FORCE_COPY_IN_MOVE
+ ) {
+ InternalSwap(&from);
+ } else {
+ CopyFrom(from);
+ }
+ return *this;
+ }
+
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
+ return GetDescriptor();
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
+ return default_instance().GetMetadata().descriptor;
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
+ return default_instance().GetMetadata().reflection;
+ }
+ static const EnumValue& default_instance() {
+ return *internal_default_instance();
+ }
+ static inline const EnumValue* internal_default_instance() {
+ return reinterpret_cast<const EnumValue*>(
+ &_EnumValue_default_instance_);
+ }
+ static constexpr int kIndexInFileMessages =
+ 3;
+
+ friend void swap(EnumValue& a, EnumValue& b) {
+ a.Swap(&b);
+ }
+ inline void Swap(EnumValue* other) {
+ if (other == this) return;
+ #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() != nullptr &&
+ GetOwningArena() == other->GetOwningArena()) {
+ #else // PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() == other->GetOwningArena()) {
+ #endif // !PROTOBUF_FORCE_COPY_IN_SWAP
+ InternalSwap(other);
+ } else {
+ ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
+ }
+ }
+ void UnsafeArenaSwap(EnumValue* other) {
+ if (other == this) return;
+ GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena());
+ InternalSwap(other);
+ }
+
+ // implements Message ----------------------------------------------
+
+ EnumValue* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
+ return CreateMaybeMessage<EnumValue>(arena);
+ }
+ using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
+ void CopyFrom(const EnumValue& from);
+ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
+ void MergeFrom(const EnumValue& from);
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from);
+ public:
+ PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+ bool IsInitialized() const final;
+
+ size_t ByteSizeLong() const final;
+ const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
+ uint8_t* _InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
+ int GetCachedSize() const final { return _cached_size_.Get(); }
+
+ private:
+ void SharedCtor();
+ void SharedDtor();
+ void SetCachedSize(int size) const final;
+ void InternalSwap(EnumValue* other);
+
+ private:
+ friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
+ static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
+ return "google.protobuf.EnumValue";
+ }
+ protected:
+ explicit EnumValue(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned = false);
+ private:
+ static void ArenaDtor(void* object);
+ inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
+ public:
+
+ static const ClassData _class_data_;
+ const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;
+
+ ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;
+
+ // nested types ----------------------------------------------------
+
+ // accessors -------------------------------------------------------
+
+ enum : int {
+ kOptionsFieldNumber = 3,
+ kNameFieldNumber = 1,
+ kNumberFieldNumber = 2,
+ };
+ // repeated .google.protobuf.Option options = 3;
+ int options_size() const;
+ private:
+ int _internal_options_size() const;
+ public:
+ void clear_options();
+ ::PROTOBUF_NAMESPACE_ID::Option* mutable_options(int index);
+ ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Option >*
+ mutable_options();
+ private:
+ const ::PROTOBUF_NAMESPACE_ID::Option& _internal_options(int index) const;
+ ::PROTOBUF_NAMESPACE_ID::Option* _internal_add_options();
+ public:
+ const ::PROTOBUF_NAMESPACE_ID::Option& options(int index) const;
+ ::PROTOBUF_NAMESPACE_ID::Option* add_options();
+ const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Option >&
+ options() const;
+
+ // string name = 1;
+ void clear_name();
+ const 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_;
+ ::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_;
+ friend struct ::TableStruct_google_2fprotobuf_2ftype_2eproto;
+};
+// -------------------------------------------------------------------
+
+class PROTOBUF_EXPORT Option final :
+ public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Option) */ {
+ public:
+ inline Option() : Option(nullptr) {}
+ ~Option() override;
+ explicit constexpr Option(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
+
+ Option(const Option& from);
+ Option(Option&& from) noexcept
+ : Option() {
+ *this = ::std::move(from);
+ }
+
+ inline Option& operator=(const Option& from) {
+ CopyFrom(from);
+ return *this;
+ }
+ inline Option& operator=(Option&& from) noexcept {
+ if (this == &from) return *this;
+ if (GetOwningArena() == from.GetOwningArena()
+ #ifdef PROTOBUF_FORCE_COPY_IN_MOVE
+ && GetOwningArena() != nullptr
+ #endif // !PROTOBUF_FORCE_COPY_IN_MOVE
+ ) {
+ InternalSwap(&from);
+ } else {
+ CopyFrom(from);
+ }
+ return *this;
+ }
+
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
+ return GetDescriptor();
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
+ return default_instance().GetMetadata().descriptor;
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
+ return default_instance().GetMetadata().reflection;
+ }
+ static const Option& default_instance() {
+ return *internal_default_instance();
+ }
+ static inline const Option* internal_default_instance() {
+ return reinterpret_cast<const Option*>(
+ &_Option_default_instance_);
+ }
+ static constexpr int kIndexInFileMessages =
+ 4;
+
+ friend void swap(Option& a, Option& b) {
+ a.Swap(&b);
+ }
+ inline void Swap(Option* other) {
+ if (other == this) return;
+ #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() != nullptr &&
+ GetOwningArena() == other->GetOwningArena()) {
+ #else // PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() == other->GetOwningArena()) {
+ #endif // !PROTOBUF_FORCE_COPY_IN_SWAP
+ InternalSwap(other);
+ } else {
+ ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
+ }
+ }
+ void UnsafeArenaSwap(Option* other) {
+ if (other == this) return;
+ GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena());
+ InternalSwap(other);
+ }
+
+ // implements Message ----------------------------------------------
+
+ Option* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
+ return CreateMaybeMessage<Option>(arena);
+ }
+ using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
+ void CopyFrom(const Option& from);
+ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
+ void MergeFrom(const Option& from);
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from);
+ public:
+ PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+ bool IsInitialized() const final;
+
+ size_t ByteSizeLong() const final;
+ const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
+ uint8_t* _InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
+ int GetCachedSize() const final { return _cached_size_.Get(); }
+
+ private:
+ void SharedCtor();
+ void SharedDtor();
+ void SetCachedSize(int size) const final;
+ void InternalSwap(Option* other);
+
+ private:
+ friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
+ static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
+ return "google.protobuf.Option";
+ }
+ protected:
+ explicit Option(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned = false);
+ private:
+ static void ArenaDtor(void* object);
+ inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
+ public:
+
+ static const ClassData _class_data_;
+ const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;
+
+ ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;
+
+ // nested types ----------------------------------------------------
+
+ // accessors -------------------------------------------------------
+
+ enum : int {
+ kNameFieldNumber = 1,
+ kValueFieldNumber = 2,
+ };
+ // string name = 1;
+ void clear_name();
+ const 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_;
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr name_;
+ ::PROTOBUF_NAMESPACE_ID::Any* value_;
+ mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
+ friend struct ::TableStruct_google_2fprotobuf_2ftype_2eproto;
+};
+// ===================================================================
+
+
+// ===================================================================
+
+#ifdef __GNUC__
+ #pragma GCC diagnostic push
+ #pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#endif // __GNUC__
+// Type
+
+// string name = 1;
+inline void Type::clear_name() {
+ name_.ClearToEmpty();
+}
+inline const 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) {
+
+ name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, 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 name_.Get();
+}
+inline void Type::_internal_set_name(const std::string& value) {
+
+ name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation());
+}
+inline std::string* Type::_internal_mutable_name() {
+
+ return name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation());
+}
+inline std::string* Type::release_name() {
+ // @@protoc_insertion_point(field_release:google.protobuf.Type.name)
+ return name_.Release(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
+}
+inline void Type::set_allocated_name(std::string* name) {
+ if (name != nullptr) {
+
+ } else {
+
+ }
+ name_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), name,
+ GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (name_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
+ name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.Type.name)
+}
+
+// repeated .google.protobuf.Field fields = 2;
+inline int Type::_internal_fields_size() const {
+ return fields_.size();
+}
+inline int Type::fields_size() const {
+ return _internal_fields_size();
+}
+inline void Type::clear_fields() {
+ fields_.Clear();
+}
+inline ::PROTOBUF_NAMESPACE_ID::Field* Type::mutable_fields(int index) {
+ // @@protoc_insertion_point(field_mutable:google.protobuf.Type.fields)
+ return fields_.Mutable(index);
+}
+inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Field >*
+Type::mutable_fields() {
+ // @@protoc_insertion_point(field_mutable_list:google.protobuf.Type.fields)
+ return &fields_;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::Field& Type::_internal_fields(int index) const {
+ return fields_.Get(index);
+}
+inline const ::PROTOBUF_NAMESPACE_ID::Field& Type::fields(int index) const {
+ // @@protoc_insertion_point(field_get:google.protobuf.Type.fields)
+ return _internal_fields(index);
+}
+inline ::PROTOBUF_NAMESPACE_ID::Field* Type::_internal_add_fields() {
+ return fields_.Add();
+}
+inline ::PROTOBUF_NAMESPACE_ID::Field* Type::add_fields() {
+ ::PROTOBUF_NAMESPACE_ID::Field* _add = _internal_add_fields();
+ // @@protoc_insertion_point(field_add:google.protobuf.Type.fields)
+ return _add;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Field >&
+Type::fields() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.Type.fields)
+ return fields_;
+}
+
+// repeated string oneofs = 3;
+inline int Type::_internal_oneofs_size() const {
+ return oneofs_.size();
+}
+inline int Type::oneofs_size() const {
+ return _internal_oneofs_size();
+}
+inline void Type::clear_oneofs() {
+ oneofs_.Clear();
+}
+inline 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 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 oneofs_.Mutable(index);
+}
+inline void Type::set_oneofs(int index, const std::string& value) {
+ oneofs_.Mutable(index)->assign(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.Type.oneofs)
+}
+inline void Type::set_oneofs(int index, std::string&& value) {
+ oneofs_.Mutable(index)->assign(std::move(value));
+ // @@protoc_insertion_point(field_set:google.protobuf.Type.oneofs)
+}
+inline void Type::set_oneofs(int index, const char* value) {
+ GOOGLE_DCHECK(value != nullptr);
+ oneofs_.Mutable(index)->assign(value);
+ // @@protoc_insertion_point(field_set_char:google.protobuf.Type.oneofs)
+}
+inline void Type::set_oneofs(int index, const char* value, size_t size) {
+ oneofs_.Mutable(index)->assign(
+ reinterpret_cast<const char*>(value), size);
+ // @@protoc_insertion_point(field_set_pointer:google.protobuf.Type.oneofs)
+}
+inline std::string* Type::_internal_add_oneofs() {
+ return oneofs_.Add();
+}
+inline void Type::add_oneofs(const std::string& value) {
+ oneofs_.Add()->assign(value);
+ // @@protoc_insertion_point(field_add:google.protobuf.Type.oneofs)
+}
+inline void Type::add_oneofs(std::string&& value) {
+ oneofs_.Add(std::move(value));
+ // @@protoc_insertion_point(field_add:google.protobuf.Type.oneofs)
+}
+inline void Type::add_oneofs(const char* value) {
+ GOOGLE_DCHECK(value != nullptr);
+ oneofs_.Add()->assign(value);
+ // @@protoc_insertion_point(field_add_char:google.protobuf.Type.oneofs)
+}
+inline void Type::add_oneofs(const char* value, size_t size) {
+ oneofs_.Add()->assign(reinterpret_cast<const char*>(value), size);
+ // @@protoc_insertion_point(field_add_pointer:google.protobuf.Type.oneofs)
+}
+inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string>&
+Type::oneofs() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.Type.oneofs)
+ return oneofs_;
+}
+inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string>*
+Type::mutable_oneofs() {
+ // @@protoc_insertion_point(field_mutable_list:google.protobuf.Type.oneofs)
+ return &oneofs_;
+}
+
+// repeated .google.protobuf.Option options = 4;
+inline int Type::_internal_options_size() const {
+ return options_.size();
+}
+inline int Type::options_size() const {
+ return _internal_options_size();
+}
+inline void Type::clear_options() {
+ options_.Clear();
+}
+inline ::PROTOBUF_NAMESPACE_ID::Option* Type::mutable_options(int index) {
+ // @@protoc_insertion_point(field_mutable:google.protobuf.Type.options)
+ return options_.Mutable(index);
+}
+inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Option >*
+Type::mutable_options() {
+ // @@protoc_insertion_point(field_mutable_list:google.protobuf.Type.options)
+ return &options_;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::Option& Type::_internal_options(int index) const {
+ return options_.Get(index);
+}
+inline const ::PROTOBUF_NAMESPACE_ID::Option& Type::options(int index) const {
+ // @@protoc_insertion_point(field_get:google.protobuf.Type.options)
+ return _internal_options(index);
+}
+inline ::PROTOBUF_NAMESPACE_ID::Option* Type::_internal_add_options() {
+ return options_.Add();
+}
+inline ::PROTOBUF_NAMESPACE_ID::Option* Type::add_options() {
+ ::PROTOBUF_NAMESPACE_ID::Option* _add = _internal_add_options();
+ // @@protoc_insertion_point(field_add:google.protobuf.Type.options)
+ return _add;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Option >&
+Type::options() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.Type.options)
+ return options_;
+}
+
+// .google.protobuf.SourceContext source_context = 5;
+inline bool Type::_internal_has_source_context() const {
+ return this != internal_default_instance() && source_context_ != nullptr;
+}
+inline bool Type::has_source_context() const {
+ return _internal_has_source_context();
+}
+inline const ::PROTOBUF_NAMESPACE_ID::SourceContext& Type::_internal_source_context() const {
+ const ::PROTOBUF_NAMESPACE_ID::SourceContext* p = source_context_;
+ return p != nullptr ? *p : reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::SourceContext&>(
+ ::PROTOBUF_NAMESPACE_ID::_SourceContext_default_instance_);
+}
+inline const ::PROTOBUF_NAMESPACE_ID::SourceContext& Type::source_context() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.Type.source_context)
+ return _internal_source_context();
+}
+inline void Type::unsafe_arena_set_allocated_source_context(
+ ::PROTOBUF_NAMESPACE_ID::SourceContext* source_context) {
+ if (GetArenaForAllocation() == nullptr) {
+ delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(source_context_);
+ }
+ source_context_ = source_context;
+ if (source_context) {
+
+ } else {
+
+ }
+ // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.Type.source_context)
+}
+inline ::PROTOBUF_NAMESPACE_ID::SourceContext* Type::release_source_context() {
+
+ ::PROTOBUF_NAMESPACE_ID::SourceContext* temp = source_context_;
+ source_context_ = nullptr;
+#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE
+ auto* old = reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(temp);
+ temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
+ if (GetArenaForAllocation() == nullptr) { delete old; }
+#else // PROTOBUF_FORCE_COPY_IN_RELEASE
+ if (GetArenaForAllocation() != nullptr) {
+ temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
+ }
+#endif // !PROTOBUF_FORCE_COPY_IN_RELEASE
+ return temp;
+}
+inline ::PROTOBUF_NAMESPACE_ID::SourceContext* Type::unsafe_arena_release_source_context() {
+ // @@protoc_insertion_point(field_release:google.protobuf.Type.source_context)
+
+ ::PROTOBUF_NAMESPACE_ID::SourceContext* temp = source_context_;
+ source_context_ = nullptr;
+ return temp;
+}
+inline ::PROTOBUF_NAMESPACE_ID::SourceContext* Type::_internal_mutable_source_context() {
+
+ if (source_context_ == nullptr) {
+ auto* p = CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::SourceContext>(GetArenaForAllocation());
+ source_context_ = p;
+ }
+ return source_context_;
+}
+inline ::PROTOBUF_NAMESPACE_ID::SourceContext* Type::mutable_source_context() {
+ ::PROTOBUF_NAMESPACE_ID::SourceContext* _msg = _internal_mutable_source_context();
+ // @@protoc_insertion_point(field_mutable:google.protobuf.Type.source_context)
+ return _msg;
+}
+inline void Type::set_allocated_source_context(::PROTOBUF_NAMESPACE_ID::SourceContext* source_context) {
+ ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaForAllocation();
+ if (message_arena == nullptr) {
+ delete reinterpret_cast< ::PROTOBUF_NAMESPACE_ID::MessageLite*>(source_context_);
+ }
+ if (source_context) {
+ ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
+ ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper<
+ ::PROTOBUF_NAMESPACE_ID::MessageLite>::GetOwningArena(
+ reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(source_context));
+ if (message_arena != submessage_arena) {
+ source_context = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
+ message_arena, source_context, submessage_arena);
+ }
+
+ } else {
+
+ }
+ source_context_ = source_context;
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.Type.source_context)
+}
+
+// .google.protobuf.Syntax syntax = 6;
+inline void Type::clear_syntax() {
+ syntax_ = 0;
+}
+inline ::PROTOBUF_NAMESPACE_ID::Syntax Type::_internal_syntax() const {
+ return static_cast< ::PROTOBUF_NAMESPACE_ID::Syntax >(syntax_);
+}
+inline ::PROTOBUF_NAMESPACE_ID::Syntax Type::syntax() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.Type.syntax)
+ return _internal_syntax();
+}
+inline void Type::_internal_set_syntax(::PROTOBUF_NAMESPACE_ID::Syntax value) {
+
+ syntax_ = value;
+}
+inline void Type::set_syntax(::PROTOBUF_NAMESPACE_ID::Syntax value) {
+ _internal_set_syntax(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.Type.syntax)
+}
+
+// -------------------------------------------------------------------
+
+// Field
+
+// .google.protobuf.Field.Kind kind = 1;
+inline void Field::clear_kind() {
+ kind_ = 0;
+}
+inline ::PROTOBUF_NAMESPACE_ID::Field_Kind Field::_internal_kind() const {
+ return static_cast< ::PROTOBUF_NAMESPACE_ID::Field_Kind >(kind_);
+}
+inline ::PROTOBUF_NAMESPACE_ID::Field_Kind Field::kind() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.Field.kind)
+ return _internal_kind();
+}
+inline void Field::_internal_set_kind(::PROTOBUF_NAMESPACE_ID::Field_Kind value) {
+
+ kind_ = value;
+}
+inline void Field::set_kind(::PROTOBUF_NAMESPACE_ID::Field_Kind value) {
+ _internal_set_kind(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.Field.kind)
+}
+
+// .google.protobuf.Field.Cardinality cardinality = 2;
+inline void Field::clear_cardinality() {
+ cardinality_ = 0;
+}
+inline ::PROTOBUF_NAMESPACE_ID::Field_Cardinality Field::_internal_cardinality() const {
+ return static_cast< ::PROTOBUF_NAMESPACE_ID::Field_Cardinality >(cardinality_);
+}
+inline ::PROTOBUF_NAMESPACE_ID::Field_Cardinality Field::cardinality() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.Field.cardinality)
+ return _internal_cardinality();
+}
+inline void Field::_internal_set_cardinality(::PROTOBUF_NAMESPACE_ID::Field_Cardinality value) {
+
+ cardinality_ = value;
+}
+inline void Field::set_cardinality(::PROTOBUF_NAMESPACE_ID::Field_Cardinality value) {
+ _internal_set_cardinality(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.Field.cardinality)
+}
+
+// int32 number = 3;
+inline void Field::clear_number() {
+ number_ = 0;
+}
+inline int32_t Field::_internal_number() const {
+ return 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) {
+
+ 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() {
+ 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) {
+
+ name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, 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 name_.Get();
+}
+inline void Field::_internal_set_name(const std::string& value) {
+
+ name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation());
+}
+inline std::string* Field::_internal_mutable_name() {
+
+ return name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation());
+}
+inline std::string* Field::release_name() {
+ // @@protoc_insertion_point(field_release:google.protobuf.Field.name)
+ return name_.Release(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
+}
+inline void Field::set_allocated_name(std::string* name) {
+ if (name != nullptr) {
+
+ } else {
+
+ }
+ name_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), name,
+ GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (name_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
+ name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.Field.name)
+}
+
+// string type_url = 6;
+inline void Field::clear_type_url() {
+ type_url_.ClearToEmpty();
+}
+inline const 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) {
+
+ type_url_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
+ // @@protoc_insertion_point(field_set:google.protobuf.Field.type_url)
+}
+inline 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 type_url_.Get();
+}
+inline void Field::_internal_set_type_url(const std::string& value) {
+
+ type_url_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation());
+}
+inline std::string* Field::_internal_mutable_type_url() {
+
+ return type_url_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation());
+}
+inline std::string* Field::release_type_url() {
+ // @@protoc_insertion_point(field_release:google.protobuf.Field.type_url)
+ return type_url_.Release(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
+}
+inline void Field::set_allocated_type_url(std::string* type_url) {
+ if (type_url != nullptr) {
+
+ } else {
+
+ }
+ type_url_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), type_url,
+ GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (type_url_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
+ type_url_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.Field.type_url)
+}
+
+// int32 oneof_index = 7;
+inline void Field::clear_oneof_index() {
+ oneof_index_ = 0;
+}
+inline int32_t Field::_internal_oneof_index() const {
+ return 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) {
+
+ 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() {
+ packed_ = false;
+}
+inline bool Field::_internal_packed() const {
+ return packed_;
+}
+inline bool Field::packed() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.Field.packed)
+ return _internal_packed();
+}
+inline void Field::_internal_set_packed(bool value) {
+
+ packed_ = value;
+}
+inline void Field::set_packed(bool value) {
+ _internal_set_packed(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.Field.packed)
+}
+
+// repeated .google.protobuf.Option options = 9;
+inline int Field::_internal_options_size() const {
+ return options_.size();
+}
+inline int Field::options_size() const {
+ return _internal_options_size();
+}
+inline void Field::clear_options() {
+ options_.Clear();
+}
+inline ::PROTOBUF_NAMESPACE_ID::Option* Field::mutable_options(int index) {
+ // @@protoc_insertion_point(field_mutable:google.protobuf.Field.options)
+ return options_.Mutable(index);
+}
+inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Option >*
+Field::mutable_options() {
+ // @@protoc_insertion_point(field_mutable_list:google.protobuf.Field.options)
+ return &options_;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::Option& Field::_internal_options(int index) const {
+ return options_.Get(index);
+}
+inline const ::PROTOBUF_NAMESPACE_ID::Option& Field::options(int index) const {
+ // @@protoc_insertion_point(field_get:google.protobuf.Field.options)
+ return _internal_options(index);
+}
+inline ::PROTOBUF_NAMESPACE_ID::Option* Field::_internal_add_options() {
+ return options_.Add();
+}
+inline ::PROTOBUF_NAMESPACE_ID::Option* Field::add_options() {
+ ::PROTOBUF_NAMESPACE_ID::Option* _add = _internal_add_options();
+ // @@protoc_insertion_point(field_add:google.protobuf.Field.options)
+ return _add;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Option >&
+Field::options() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.Field.options)
+ return options_;
+}
+
+// string json_name = 10;
+inline void Field::clear_json_name() {
+ json_name_.ClearToEmpty();
+}
+inline const 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) {
+
+ json_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
+ // @@protoc_insertion_point(field_set:google.protobuf.Field.json_name)
+}
+inline 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 json_name_.Get();
+}
+inline void Field::_internal_set_json_name(const std::string& value) {
+
+ json_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation());
+}
+inline std::string* Field::_internal_mutable_json_name() {
+
+ return json_name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation());
+}
+inline std::string* Field::release_json_name() {
+ // @@protoc_insertion_point(field_release:google.protobuf.Field.json_name)
+ return json_name_.Release(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
+}
+inline void Field::set_allocated_json_name(std::string* json_name) {
+ if (json_name != nullptr) {
+
+ } else {
+
+ }
+ json_name_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), json_name,
+ GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (json_name_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
+ json_name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.Field.json_name)
+}
+
+// string default_value = 11;
+inline void Field::clear_default_value() {
+ default_value_.ClearToEmpty();
+}
+inline const 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) {
+
+ default_value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
+ // @@protoc_insertion_point(field_set:google.protobuf.Field.default_value)
+}
+inline 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 default_value_.Get();
+}
+inline void Field::_internal_set_default_value(const std::string& value) {
+
+ default_value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation());
+}
+inline std::string* Field::_internal_mutable_default_value() {
+
+ return default_value_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation());
+}
+inline std::string* Field::release_default_value() {
+ // @@protoc_insertion_point(field_release:google.protobuf.Field.default_value)
+ return default_value_.Release(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
+}
+inline void Field::set_allocated_default_value(std::string* default_value) {
+ if (default_value != nullptr) {
+
+ } else {
+
+ }
+ default_value_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), default_value,
+ GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (default_value_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
+ default_value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.Field.default_value)
+}
+
+// -------------------------------------------------------------------
+
+// Enum
+
+// string name = 1;
+inline void Enum::clear_name() {
+ name_.ClearToEmpty();
+}
+inline const 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) {
+
+ name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, 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 name_.Get();
+}
+inline void Enum::_internal_set_name(const std::string& value) {
+
+ name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation());
+}
+inline std::string* Enum::_internal_mutable_name() {
+
+ return name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation());
+}
+inline std::string* Enum::release_name() {
+ // @@protoc_insertion_point(field_release:google.protobuf.Enum.name)
+ return name_.Release(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
+}
+inline void Enum::set_allocated_name(std::string* name) {
+ if (name != nullptr) {
+
+ } else {
+
+ }
+ name_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), name,
+ GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (name_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
+ name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.Enum.name)
+}
+
+// repeated .google.protobuf.EnumValue enumvalue = 2;
+inline int Enum::_internal_enumvalue_size() const {
+ return enumvalue_.size();
+}
+inline int Enum::enumvalue_size() const {
+ return _internal_enumvalue_size();
+}
+inline void Enum::clear_enumvalue() {
+ enumvalue_.Clear();
+}
+inline ::PROTOBUF_NAMESPACE_ID::EnumValue* Enum::mutable_enumvalue(int index) {
+ // @@protoc_insertion_point(field_mutable:google.protobuf.Enum.enumvalue)
+ return enumvalue_.Mutable(index);
+}
+inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::EnumValue >*
+Enum::mutable_enumvalue() {
+ // @@protoc_insertion_point(field_mutable_list:google.protobuf.Enum.enumvalue)
+ return &enumvalue_;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::EnumValue& Enum::_internal_enumvalue(int index) const {
+ return enumvalue_.Get(index);
+}
+inline const ::PROTOBUF_NAMESPACE_ID::EnumValue& Enum::enumvalue(int index) const {
+ // @@protoc_insertion_point(field_get:google.protobuf.Enum.enumvalue)
+ return _internal_enumvalue(index);
+}
+inline ::PROTOBUF_NAMESPACE_ID::EnumValue* Enum::_internal_add_enumvalue() {
+ return enumvalue_.Add();
+}
+inline ::PROTOBUF_NAMESPACE_ID::EnumValue* Enum::add_enumvalue() {
+ ::PROTOBUF_NAMESPACE_ID::EnumValue* _add = _internal_add_enumvalue();
+ // @@protoc_insertion_point(field_add:google.protobuf.Enum.enumvalue)
+ return _add;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::EnumValue >&
+Enum::enumvalue() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.Enum.enumvalue)
+ return enumvalue_;
+}
+
+// repeated .google.protobuf.Option options = 3;
+inline int Enum::_internal_options_size() const {
+ return options_.size();
+}
+inline int Enum::options_size() const {
+ return _internal_options_size();
+}
+inline void Enum::clear_options() {
+ options_.Clear();
+}
+inline ::PROTOBUF_NAMESPACE_ID::Option* Enum::mutable_options(int index) {
+ // @@protoc_insertion_point(field_mutable:google.protobuf.Enum.options)
+ return options_.Mutable(index);
+}
+inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Option >*
+Enum::mutable_options() {
+ // @@protoc_insertion_point(field_mutable_list:google.protobuf.Enum.options)
+ return &options_;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::Option& Enum::_internal_options(int index) const {
+ return options_.Get(index);
+}
+inline const ::PROTOBUF_NAMESPACE_ID::Option& Enum::options(int index) const {
+ // @@protoc_insertion_point(field_get:google.protobuf.Enum.options)
+ return _internal_options(index);
+}
+inline ::PROTOBUF_NAMESPACE_ID::Option* Enum::_internal_add_options() {
+ return options_.Add();
+}
+inline ::PROTOBUF_NAMESPACE_ID::Option* Enum::add_options() {
+ ::PROTOBUF_NAMESPACE_ID::Option* _add = _internal_add_options();
+ // @@protoc_insertion_point(field_add:google.protobuf.Enum.options)
+ return _add;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Option >&
+Enum::options() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.Enum.options)
+ return options_;
+}
+
+// .google.protobuf.SourceContext source_context = 4;
+inline bool Enum::_internal_has_source_context() const {
+ return this != internal_default_instance() && source_context_ != nullptr;
+}
+inline bool Enum::has_source_context() const {
+ return _internal_has_source_context();
+}
+inline const ::PROTOBUF_NAMESPACE_ID::SourceContext& Enum::_internal_source_context() const {
+ const ::PROTOBUF_NAMESPACE_ID::SourceContext* p = source_context_;
+ return p != nullptr ? *p : reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::SourceContext&>(
+ ::PROTOBUF_NAMESPACE_ID::_SourceContext_default_instance_);
+}
+inline const ::PROTOBUF_NAMESPACE_ID::SourceContext& Enum::source_context() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.Enum.source_context)
+ return _internal_source_context();
+}
+inline void Enum::unsafe_arena_set_allocated_source_context(
+ ::PROTOBUF_NAMESPACE_ID::SourceContext* source_context) {
+ if (GetArenaForAllocation() == nullptr) {
+ delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(source_context_);
+ }
+ source_context_ = source_context;
+ if (source_context) {
+
+ } else {
+
+ }
+ // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.Enum.source_context)
+}
+inline ::PROTOBUF_NAMESPACE_ID::SourceContext* Enum::release_source_context() {
+
+ ::PROTOBUF_NAMESPACE_ID::SourceContext* temp = source_context_;
+ source_context_ = nullptr;
+#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE
+ auto* old = reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(temp);
+ temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
+ if (GetArenaForAllocation() == nullptr) { delete old; }
+#else // PROTOBUF_FORCE_COPY_IN_RELEASE
+ if (GetArenaForAllocation() != nullptr) {
+ temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
+ }
+#endif // !PROTOBUF_FORCE_COPY_IN_RELEASE
+ return temp;
+}
+inline ::PROTOBUF_NAMESPACE_ID::SourceContext* Enum::unsafe_arena_release_source_context() {
+ // @@protoc_insertion_point(field_release:google.protobuf.Enum.source_context)
+
+ ::PROTOBUF_NAMESPACE_ID::SourceContext* temp = source_context_;
+ source_context_ = nullptr;
+ return temp;
+}
+inline ::PROTOBUF_NAMESPACE_ID::SourceContext* Enum::_internal_mutable_source_context() {
+
+ if (source_context_ == nullptr) {
+ auto* p = CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::SourceContext>(GetArenaForAllocation());
+ source_context_ = p;
+ }
+ return source_context_;
+}
+inline ::PROTOBUF_NAMESPACE_ID::SourceContext* Enum::mutable_source_context() {
+ ::PROTOBUF_NAMESPACE_ID::SourceContext* _msg = _internal_mutable_source_context();
+ // @@protoc_insertion_point(field_mutable:google.protobuf.Enum.source_context)
+ return _msg;
+}
+inline void Enum::set_allocated_source_context(::PROTOBUF_NAMESPACE_ID::SourceContext* source_context) {
+ ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaForAllocation();
+ if (message_arena == nullptr) {
+ delete reinterpret_cast< ::PROTOBUF_NAMESPACE_ID::MessageLite*>(source_context_);
+ }
+ if (source_context) {
+ ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
+ ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper<
+ ::PROTOBUF_NAMESPACE_ID::MessageLite>::GetOwningArena(
+ reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(source_context));
+ if (message_arena != submessage_arena) {
+ source_context = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
+ message_arena, source_context, submessage_arena);
+ }
+
+ } else {
+
+ }
+ source_context_ = source_context;
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.Enum.source_context)
+}
+
+// .google.protobuf.Syntax syntax = 5;
+inline void Enum::clear_syntax() {
+ syntax_ = 0;
+}
+inline ::PROTOBUF_NAMESPACE_ID::Syntax Enum::_internal_syntax() const {
+ return static_cast< ::PROTOBUF_NAMESPACE_ID::Syntax >(syntax_);
+}
+inline ::PROTOBUF_NAMESPACE_ID::Syntax Enum::syntax() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.Enum.syntax)
+ return _internal_syntax();
+}
+inline void Enum::_internal_set_syntax(::PROTOBUF_NAMESPACE_ID::Syntax value) {
+
+ syntax_ = value;
+}
+inline void Enum::set_syntax(::PROTOBUF_NAMESPACE_ID::Syntax value) {
+ _internal_set_syntax(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.Enum.syntax)
+}
+
+// -------------------------------------------------------------------
+
+// EnumValue
+
+// string name = 1;
+inline void EnumValue::clear_name() {
+ name_.ClearToEmpty();
+}
+inline const 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) {
+
+ name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, 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 name_.Get();
+}
+inline void EnumValue::_internal_set_name(const std::string& value) {
+
+ name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation());
+}
+inline std::string* EnumValue::_internal_mutable_name() {
+
+ return name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation());
+}
+inline std::string* EnumValue::release_name() {
+ // @@protoc_insertion_point(field_release:google.protobuf.EnumValue.name)
+ return name_.Release(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
+}
+inline void EnumValue::set_allocated_name(std::string* name) {
+ if (name != nullptr) {
+
+ } else {
+
+ }
+ name_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), name,
+ GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (name_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
+ name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.EnumValue.name)
+}
+
+// int32 number = 2;
+inline void EnumValue::clear_number() {
+ number_ = 0;
+}
+inline int32_t EnumValue::_internal_number() const {
+ return 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) {
+
+ 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 options_.size();
+}
+inline int EnumValue::options_size() const {
+ return _internal_options_size();
+}
+inline void EnumValue::clear_options() {
+ options_.Clear();
+}
+inline ::PROTOBUF_NAMESPACE_ID::Option* EnumValue::mutable_options(int index) {
+ // @@protoc_insertion_point(field_mutable:google.protobuf.EnumValue.options)
+ return options_.Mutable(index);
+}
+inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Option >*
+EnumValue::mutable_options() {
+ // @@protoc_insertion_point(field_mutable_list:google.protobuf.EnumValue.options)
+ return &options_;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::Option& EnumValue::_internal_options(int index) const {
+ return options_.Get(index);
+}
+inline const ::PROTOBUF_NAMESPACE_ID::Option& EnumValue::options(int index) const {
+ // @@protoc_insertion_point(field_get:google.protobuf.EnumValue.options)
+ return _internal_options(index);
+}
+inline ::PROTOBUF_NAMESPACE_ID::Option* EnumValue::_internal_add_options() {
+ return options_.Add();
+}
+inline ::PROTOBUF_NAMESPACE_ID::Option* EnumValue::add_options() {
+ ::PROTOBUF_NAMESPACE_ID::Option* _add = _internal_add_options();
+ // @@protoc_insertion_point(field_add:google.protobuf.EnumValue.options)
+ return _add;
+}
+inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Option >&
+EnumValue::options() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.EnumValue.options)
+ return options_;
+}
+
+// -------------------------------------------------------------------
+
+// Option
+
+// string name = 1;
+inline void Option::clear_name() {
+ name_.ClearToEmpty();
+}
+inline const 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) {
+
+ name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, 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 name_.Get();
+}
+inline void Option::_internal_set_name(const std::string& value) {
+
+ name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation());
+}
+inline std::string* Option::_internal_mutable_name() {
+
+ return name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation());
+}
+inline std::string* Option::release_name() {
+ // @@protoc_insertion_point(field_release:google.protobuf.Option.name)
+ return name_.Release(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
+}
+inline void Option::set_allocated_name(std::string* name) {
+ if (name != nullptr) {
+
+ } else {
+
+ }
+ name_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), name,
+ GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (name_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
+ name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.Option.name)
+}
+
+// .google.protobuf.Any value = 2;
+inline bool Option::_internal_has_value() const {
+ return this != internal_default_instance() && value_ != nullptr;
+}
+inline bool Option::has_value() const {
+ return _internal_has_value();
+}
+inline const ::PROTOBUF_NAMESPACE_ID::Any& Option::_internal_value() const {
+ const ::PROTOBUF_NAMESPACE_ID::Any* p = value_;
+ return p != nullptr ? *p : reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Any&>(
+ ::PROTOBUF_NAMESPACE_ID::_Any_default_instance_);
+}
+inline const ::PROTOBUF_NAMESPACE_ID::Any& Option::value() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.Option.value)
+ return _internal_value();
+}
+inline void Option::unsafe_arena_set_allocated_value(
+ ::PROTOBUF_NAMESPACE_ID::Any* value) {
+ if (GetArenaForAllocation() == nullptr) {
+ delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(value_);
+ }
+ value_ = value;
+ if (value) {
+
+ } else {
+
+ }
+ // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.Option.value)
+}
+inline ::PROTOBUF_NAMESPACE_ID::Any* Option::release_value() {
+
+ ::PROTOBUF_NAMESPACE_ID::Any* temp = value_;
+ value_ = nullptr;
+#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE
+ auto* old = reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(temp);
+ temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
+ if (GetArenaForAllocation() == nullptr) { delete old; }
+#else // PROTOBUF_FORCE_COPY_IN_RELEASE
+ if (GetArenaForAllocation() != nullptr) {
+ temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
+ }
+#endif // !PROTOBUF_FORCE_COPY_IN_RELEASE
+ return temp;
+}
+inline ::PROTOBUF_NAMESPACE_ID::Any* Option::unsafe_arena_release_value() {
+ // @@protoc_insertion_point(field_release:google.protobuf.Option.value)
+
+ ::PROTOBUF_NAMESPACE_ID::Any* temp = value_;
+ value_ = nullptr;
+ return temp;
+}
+inline ::PROTOBUF_NAMESPACE_ID::Any* Option::_internal_mutable_value() {
+
+ if (value_ == nullptr) {
+ auto* p = CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::Any>(GetArenaForAllocation());
+ value_ = p;
+ }
+ return value_;
+}
+inline ::PROTOBUF_NAMESPACE_ID::Any* Option::mutable_value() {
+ ::PROTOBUF_NAMESPACE_ID::Any* _msg = _internal_mutable_value();
+ // @@protoc_insertion_point(field_mutable:google.protobuf.Option.value)
+ return _msg;
+}
+inline void Option::set_allocated_value(::PROTOBUF_NAMESPACE_ID::Any* value) {
+ ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaForAllocation();
+ if (message_arena == nullptr) {
+ delete reinterpret_cast< ::PROTOBUF_NAMESPACE_ID::MessageLite*>(value_);
+ }
+ if (value) {
+ ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
+ ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper<
+ ::PROTOBUF_NAMESPACE_ID::MessageLite>::GetOwningArena(
+ reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(value));
+ if (message_arena != submessage_arena) {
+ value = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
+ message_arena, value, submessage_arena);
+ }
+
+ } else {
+
+ }
+ value_ = value;
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.Option.value)
+}
+
+#ifdef __GNUC__
+ #pragma GCC diagnostic pop
+#endif // __GNUC__
+// -------------------------------------------------------------------
+
+// -------------------------------------------------------------------
+
+// -------------------------------------------------------------------
+
+// -------------------------------------------------------------------
+
+
+// @@protoc_insertion_point(namespace_scope)
+
+PROTOBUF_NAMESPACE_CLOSE
+
+PROTOBUF_NAMESPACE_OPEN
+
+template <> struct is_proto_enum< ::PROTOBUF_NAMESPACE_ID::Field_Kind> : ::std::true_type {};
+template <>
+inline const EnumDescriptor* GetEnumDescriptor< ::PROTOBUF_NAMESPACE_ID::Field_Kind>() {
+ return ::PROTOBUF_NAMESPACE_ID::Field_Kind_descriptor();
+}
+template <> struct is_proto_enum< ::PROTOBUF_NAMESPACE_ID::Field_Cardinality> : ::std::true_type {};
+template <>
+inline const EnumDescriptor* GetEnumDescriptor< ::PROTOBUF_NAMESPACE_ID::Field_Cardinality>() {
+ return ::PROTOBUF_NAMESPACE_ID::Field_Cardinality_descriptor();
+}
+template <> struct is_proto_enum< ::PROTOBUF_NAMESPACE_ID::Syntax> : ::std::true_type {};
+template <>
+inline const EnumDescriptor* GetEnumDescriptor< ::PROTOBUF_NAMESPACE_ID::Syntax>() {
+ return ::PROTOBUF_NAMESPACE_ID::Syntax_descriptor();
+}
+
+PROTOBUF_NAMESPACE_CLOSE
+
+// @@protoc_insertion_point(global_scope)
+
+#include <port_undef.inc>
+#endif // GOOGLE_PROTOBUF_INCLUDED_GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2ftype_2eproto
diff --git a/NorthstarDedicatedTest/include/protobuf/type.proto b/NorthstarDedicatedTest/include/protobuf/type.proto
new file mode 100644
index 00000000..d3f6a68b
--- /dev/null
+++ b/NorthstarDedicatedTest/include/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/NorthstarDedicatedTest/include/protobuf/unittest.proto b/NorthstarDedicatedTest/include/protobuf/unittest.proto
new file mode 100644
index 00000000..7dda9246
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/unittest.proto
@@ -0,0 +1,1158 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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.
+//
+// LINT: ALLOW_GROUPS, LEGACY_NAMES
+
+syntax = "proto2";
+
+// Some generic_services option(s) added automatically.
+// See: http://go/proto2-generic-services-default
+option cc_generic_services = true; // auto-added
+option java_generic_services = true; // auto-added
+option py_generic_services = true; // auto-added
+option cc_enable_arenas = true;
+
+import "google/protobuf/unittest_import.proto";
+
+// We don't put this in a package within proto2 because we need to make sure
+// that the generated code doesn't depend on being in the proto2 namespace.
+// In test_util.h we do "using namespace unittest = protobuf_unittest".
+package protobuf_unittest;
+
+// Protos optimized for SPEED use a strict superset of the generated code
+// of equivalent ones optimized for CODE_SIZE, so we should optimize all our
+// tests for speed unless explicitly testing code size optimization.
+option optimize_for = SPEED;
+
+option java_outer_classname = "UnittestProto";
+
+// This proto includes every type of field in both singular and repeated
+// forms.
+message TestAllTypes {
+ message NestedMessage {
+ // The field name "b" fails to compile in proto1 because it conflicts with
+ // a local variable named "b" in one of the generated methods. Doh.
+ // This file needs to compile in proto1 to test backwards-compatibility.
+ optional int32 bb = 1;
+ }
+
+ enum NestedEnum {
+ FOO = 1;
+ BAR = 2;
+ BAZ = 3;
+ NEG = -1; // Intentionally negative.
+ }
+
+ // Singular
+ optional int32 optional_int32 = 1;
+ optional int64 optional_int64 = 2;
+ optional uint32 optional_uint32 = 3;
+ optional uint64 optional_uint64 = 4;
+ optional sint32 optional_sint32 = 5;
+ optional sint64 optional_sint64 = 6;
+ optional fixed32 optional_fixed32 = 7;
+ optional fixed64 optional_fixed64 = 8;
+ optional sfixed32 optional_sfixed32 = 9;
+ optional sfixed64 optional_sfixed64 = 10;
+ optional float optional_float = 11;
+ optional double optional_double = 12;
+ optional bool optional_bool = 13;
+ optional string optional_string = 14;
+ optional bytes optional_bytes = 15;
+
+ optional group OptionalGroup = 16 {
+ optional int32 a = 17;
+ }
+
+ optional NestedMessage optional_nested_message = 18;
+ optional ForeignMessage optional_foreign_message = 19;
+ optional protobuf_unittest_import.ImportMessage optional_import_message = 20;
+
+ optional NestedEnum optional_nested_enum = 21;
+ optional ForeignEnum optional_foreign_enum = 22;
+ optional protobuf_unittest_import.ImportEnum optional_import_enum = 23;
+
+ optional string optional_string_piece = 24 [ctype=STRING_PIECE];
+ optional string optional_cord = 25 [ctype=CORD];
+
+ // Defined in unittest_import_public.proto
+ optional protobuf_unittest_import.PublicImportMessage
+ optional_public_import_message = 26;
+
+ optional NestedMessage optional_lazy_message = 27 [lazy=true];
+
+ // Repeated
+ repeated int32 repeated_int32 = 31;
+ repeated int64 repeated_int64 = 32;
+ repeated uint32 repeated_uint32 = 33;
+ repeated uint64 repeated_uint64 = 34;
+ repeated sint32 repeated_sint32 = 35;
+ repeated sint64 repeated_sint64 = 36;
+ repeated fixed32 repeated_fixed32 = 37;
+ repeated fixed64 repeated_fixed64 = 38;
+ repeated sfixed32 repeated_sfixed32 = 39;
+ repeated sfixed64 repeated_sfixed64 = 40;
+ repeated float repeated_float = 41;
+ repeated double repeated_double = 42;
+ repeated bool repeated_bool = 43;
+ repeated string repeated_string = 44;
+ repeated bytes repeated_bytes = 45;
+
+ repeated group RepeatedGroup = 46 {
+ optional int32 a = 47;
+ }
+
+ repeated NestedMessage repeated_nested_message = 48;
+ repeated ForeignMessage repeated_foreign_message = 49;
+ repeated protobuf_unittest_import.ImportMessage repeated_import_message = 50;
+
+ repeated NestedEnum repeated_nested_enum = 51;
+ repeated ForeignEnum repeated_foreign_enum = 52;
+ repeated protobuf_unittest_import.ImportEnum repeated_import_enum = 53;
+
+ repeated string repeated_string_piece = 54 [ctype=STRING_PIECE];
+ repeated string repeated_cord = 55 [ctype=CORD];
+
+ repeated NestedMessage repeated_lazy_message = 57 [lazy=true];
+
+ // Singular with defaults
+ optional int32 default_int32 = 61 [default = 41 ];
+ optional int64 default_int64 = 62 [default = 42 ];
+ optional uint32 default_uint32 = 63 [default = 43 ];
+ optional uint64 default_uint64 = 64 [default = 44 ];
+ optional sint32 default_sint32 = 65 [default = -45 ];
+ optional sint64 default_sint64 = 66 [default = 46 ];
+ optional fixed32 default_fixed32 = 67 [default = 47 ];
+ optional fixed64 default_fixed64 = 68 [default = 48 ];
+ optional sfixed32 default_sfixed32 = 69 [default = 49 ];
+ optional sfixed64 default_sfixed64 = 70 [default = -50 ];
+ optional float default_float = 71 [default = 51.5 ];
+ optional double default_double = 72 [default = 52e3 ];
+ optional bool default_bool = 73 [default = true ];
+ optional string default_string = 74 [default = "hello"];
+ optional bytes default_bytes = 75 [default = "world"];
+
+ optional NestedEnum default_nested_enum = 81 [default = BAR ];
+ optional ForeignEnum default_foreign_enum = 82 [default = FOREIGN_BAR];
+ optional protobuf_unittest_import.ImportEnum
+ default_import_enum = 83 [default = IMPORT_BAR];
+
+ optional string default_string_piece = 84 [ctype=STRING_PIECE,default="abc"];
+ optional string default_cord = 85 [ctype=CORD,default="123"];
+
+ // For oneof test
+ oneof oneof_field {
+ uint32 oneof_uint32 = 111;
+ NestedMessage oneof_nested_message = 112;
+ string oneof_string = 113;
+ bytes oneof_bytes = 114;
+ }
+}
+
+// This proto includes a recursively nested message.
+message NestedTestAllTypes {
+ optional NestedTestAllTypes child = 1;
+ optional TestAllTypes payload = 2;
+ repeated NestedTestAllTypes repeated_child = 3;
+}
+
+message TestDeprecatedFields {
+ optional int32 deprecated_int32 = 1 [deprecated=true];
+ oneof oneof_fields {
+ int32 deprecated_int32_in_oneof = 2 [deprecated=true];
+ }
+}
+
+message TestDeprecatedMessage {
+ option deprecated = true;
+}
+
+// Define these after TestAllTypes to make sure the compiler can handle
+// that.
+message ForeignMessage {
+ optional int32 c = 1;
+ optional int32 d = 2;
+}
+
+enum ForeignEnum {
+ FOREIGN_FOO = 4;
+ FOREIGN_BAR = 5;
+ FOREIGN_BAZ = 6;
+}
+
+message TestReservedFields {
+ reserved 2, 15, 9 to 11;
+ reserved "bar", "baz";
+}
+
+message TestAllExtensions {
+ extensions 1 to max;
+}
+
+extend TestAllExtensions {
+ // Singular
+ optional int32 optional_int32_extension = 1;
+ optional int64 optional_int64_extension = 2;
+ optional uint32 optional_uint32_extension = 3;
+ optional uint64 optional_uint64_extension = 4;
+ optional sint32 optional_sint32_extension = 5;
+ optional sint64 optional_sint64_extension = 6;
+ optional fixed32 optional_fixed32_extension = 7;
+ optional fixed64 optional_fixed64_extension = 8;
+ optional sfixed32 optional_sfixed32_extension = 9;
+ optional sfixed64 optional_sfixed64_extension = 10;
+ optional float optional_float_extension = 11;
+ optional double optional_double_extension = 12;
+ optional bool optional_bool_extension = 13;
+ optional string optional_string_extension = 14;
+ optional bytes optional_bytes_extension = 15;
+
+ optional group OptionalGroup_extension = 16 {
+ optional int32 a = 17;
+ }
+
+ optional TestAllTypes.NestedMessage optional_nested_message_extension = 18;
+ optional ForeignMessage optional_foreign_message_extension = 19;
+ optional protobuf_unittest_import.ImportMessage
+ optional_import_message_extension = 20;
+
+ optional TestAllTypes.NestedEnum optional_nested_enum_extension = 21;
+ optional ForeignEnum optional_foreign_enum_extension = 22;
+ optional protobuf_unittest_import.ImportEnum
+ optional_import_enum_extension = 23;
+
+ optional string optional_string_piece_extension = 24 [ctype=STRING_PIECE];
+ optional string optional_cord_extension = 25 [ctype=CORD];
+
+ optional protobuf_unittest_import.PublicImportMessage
+ optional_public_import_message_extension = 26;
+
+ optional TestAllTypes.NestedMessage
+ optional_lazy_message_extension = 27 [lazy=true];
+
+ // Repeated
+ repeated int32 repeated_int32_extension = 31;
+ repeated int64 repeated_int64_extension = 32;
+ repeated uint32 repeated_uint32_extension = 33;
+ repeated uint64 repeated_uint64_extension = 34;
+ repeated sint32 repeated_sint32_extension = 35;
+ repeated sint64 repeated_sint64_extension = 36;
+ repeated fixed32 repeated_fixed32_extension = 37;
+ repeated fixed64 repeated_fixed64_extension = 38;
+ repeated sfixed32 repeated_sfixed32_extension = 39;
+ repeated sfixed64 repeated_sfixed64_extension = 40;
+ repeated float repeated_float_extension = 41;
+ repeated double repeated_double_extension = 42;
+ repeated bool repeated_bool_extension = 43;
+ repeated string repeated_string_extension = 44;
+ repeated bytes repeated_bytes_extension = 45;
+
+ repeated group RepeatedGroup_extension = 46 {
+ optional int32 a = 47;
+ }
+
+ repeated TestAllTypes.NestedMessage repeated_nested_message_extension = 48;
+ repeated ForeignMessage repeated_foreign_message_extension = 49;
+ repeated protobuf_unittest_import.ImportMessage
+ repeated_import_message_extension = 50;
+
+ repeated TestAllTypes.NestedEnum repeated_nested_enum_extension = 51;
+ repeated ForeignEnum repeated_foreign_enum_extension = 52;
+ repeated protobuf_unittest_import.ImportEnum
+ repeated_import_enum_extension = 53;
+
+ repeated string repeated_string_piece_extension = 54 [ctype=STRING_PIECE];
+ repeated string repeated_cord_extension = 55 [ctype=CORD];
+
+ repeated TestAllTypes.NestedMessage
+ repeated_lazy_message_extension = 57 [lazy=true];
+
+ // Singular with defaults
+ optional int32 default_int32_extension = 61 [default = 41 ];
+ optional int64 default_int64_extension = 62 [default = 42 ];
+ optional uint32 default_uint32_extension = 63 [default = 43 ];
+ optional uint64 default_uint64_extension = 64 [default = 44 ];
+ optional sint32 default_sint32_extension = 65 [default = -45 ];
+ optional sint64 default_sint64_extension = 66 [default = 46 ];
+ optional fixed32 default_fixed32_extension = 67 [default = 47 ];
+ optional fixed64 default_fixed64_extension = 68 [default = 48 ];
+ optional sfixed32 default_sfixed32_extension = 69 [default = 49 ];
+ optional sfixed64 default_sfixed64_extension = 70 [default = -50 ];
+ optional float default_float_extension = 71 [default = 51.5 ];
+ optional double default_double_extension = 72 [default = 52e3 ];
+ optional bool default_bool_extension = 73 [default = true ];
+ optional string default_string_extension = 74 [default = "hello"];
+ optional bytes default_bytes_extension = 75 [default = "world"];
+
+ optional TestAllTypes.NestedEnum
+ default_nested_enum_extension = 81 [default = BAR];
+ optional ForeignEnum
+ default_foreign_enum_extension = 82 [default = FOREIGN_BAR];
+ optional protobuf_unittest_import.ImportEnum
+ default_import_enum_extension = 83 [default = IMPORT_BAR];
+
+ optional string default_string_piece_extension = 84 [ctype=STRING_PIECE,
+ default="abc"];
+ optional string default_cord_extension = 85 [ctype=CORD, default="123"];
+
+ // For oneof test
+ optional uint32 oneof_uint32_extension = 111;
+ optional TestAllTypes.NestedMessage oneof_nested_message_extension = 112;
+ optional string oneof_string_extension = 113;
+ optional bytes oneof_bytes_extension = 114;
+}
+
+message TestGroup {
+ optional group OptionalGroup = 16 {
+ optional int32 a = 17;
+ }
+ optional ForeignEnum optional_foreign_enum = 22;
+}
+
+message TestGroupExtension {
+ extensions 1 to max;
+}
+
+message TestNestedExtension {
+ extend TestAllExtensions {
+ // Check for bug where string extensions declared in tested scope did not
+ // compile.
+ optional string test = 1002 [default="test"];
+ // Used to test if generated extension name is correct when there are
+ // underscores.
+ optional string nested_string_extension = 1003;
+ }
+
+ extend TestGroupExtension {
+ optional group OptionalGroup_extension = 16 {
+ optional int32 a = 17;
+ }
+ optional ForeignEnum optional_foreign_enum_extension = 22;
+ }
+}
+
+message TestChildExtension {
+ optional string a = 1;
+ optional string b = 2;
+ optional TestAllExtensions optional_extension = 3;
+}
+
+// We have separate messages for testing required fields because it's
+// annoying to have to fill in required fields in TestProto in order to
+// do anything with it. Note that we don't need to test every type of
+// required filed because the code output is basically identical to
+// optional fields for all types.
+message TestRequired {
+ required int32 a = 1;
+ optional int32 dummy2 = 2;
+ required int32 b = 3;
+
+ extend TestAllExtensions {
+ optional TestRequired single = 1000;
+ repeated TestRequired multi = 1001;
+ }
+
+ // Pad the field count to 32 so that we can test that IsInitialized()
+ // properly checks multiple elements of has_bits_.
+ optional int32 dummy4 = 4;
+ optional int32 dummy5 = 5;
+ optional int32 dummy6 = 6;
+ optional int32 dummy7 = 7;
+ optional int32 dummy8 = 8;
+ optional int32 dummy9 = 9;
+ optional int32 dummy10 = 10;
+ optional int32 dummy11 = 11;
+ optional int32 dummy12 = 12;
+ optional int32 dummy13 = 13;
+ optional int32 dummy14 = 14;
+ optional int32 dummy15 = 15;
+ optional int32 dummy16 = 16;
+ optional int32 dummy17 = 17;
+ optional int32 dummy18 = 18;
+ optional int32 dummy19 = 19;
+ optional int32 dummy20 = 20;
+ optional int32 dummy21 = 21;
+ optional int32 dummy22 = 22;
+ optional int32 dummy23 = 23;
+ optional int32 dummy24 = 24;
+ optional int32 dummy25 = 25;
+ optional int32 dummy26 = 26;
+ optional int32 dummy27 = 27;
+ optional int32 dummy28 = 28;
+ optional int32 dummy29 = 29;
+ optional int32 dummy30 = 30;
+ optional int32 dummy31 = 31;
+ optional int32 dummy32 = 32;
+
+ required int32 c = 33;
+}
+
+message TestRequiredForeign {
+ optional TestRequired optional_message = 1;
+ repeated TestRequired repeated_message = 2;
+ optional int32 dummy = 3;
+}
+
+message TestRequiredMessage {
+ optional TestRequired optional_message = 1;
+ repeated TestRequired repeated_message = 2;
+ required TestRequired required_message = 3;
+}
+
+// Test that we can use NestedMessage from outside TestAllTypes.
+message TestForeignNested {
+ optional TestAllTypes.NestedMessage foreign_nested = 1;
+}
+
+// TestEmptyMessage is used to test unknown field support.
+message TestEmptyMessage {
+}
+
+// Like above, but declare all field numbers as potential extensions. No
+// actual extensions should ever be defined for this type.
+message TestEmptyMessageWithExtensions {
+ extensions 1 to max;
+}
+
+// Needed for a Python test.
+message TestPickleNestedMessage {
+ message NestedMessage {
+ optional int32 bb = 1;
+ message NestedNestedMessage {
+ optional int32 cc = 1;
+ }
+ }
+}
+
+message TestMultipleExtensionRanges {
+ extensions 42;
+ extensions 4143 to 4243;
+ extensions 65536 to max;
+}
+
+// Test that really large tag numbers don't break anything.
+message TestReallyLargeTagNumber {
+ // The largest possible tag number is 2^28 - 1, since the wire format uses
+ // three bits to communicate wire type.
+ optional int32 a = 1;
+ optional int32 bb = 268435455;
+}
+
+message TestRecursiveMessage {
+ optional TestRecursiveMessage a = 1;
+ optional int32 i = 2;
+}
+
+// Test that mutual recursion works.
+message TestMutualRecursionA {
+ message SubMessage {
+ optional TestMutualRecursionB b = 1;
+ }
+ optional TestMutualRecursionB bb = 1;
+ optional group SubGroup = 2 {
+ optional SubMessage sub_message = 3; // Needed because of bug in javatest
+ optional TestAllTypes not_in_this_scc = 4;
+ }
+}
+
+message TestMutualRecursionB {
+ optional TestMutualRecursionA a = 1;
+ optional int32 optional_int32 = 2;
+}
+
+message TestIsInitialized {
+ message SubMessage {
+ optional group SubGroup = 1 {
+ required int32 i = 2;
+ }
+ }
+ optional SubMessage sub_message = 1;
+}
+
+// Test that groups have disjoint field numbers from their siblings and
+// parents. This is NOT possible in proto1; only google.protobuf. When attempting
+// to compile with proto1, this will emit an error; so we only include it
+// in protobuf_unittest_proto.
+message TestDupFieldNumber { // NO_PROTO1
+ optional int32 a = 1; // NO_PROTO1
+ optional group Foo = 2 { optional int32 a = 1; } // NO_PROTO1
+ optional group Bar = 3 { optional int32 a = 1; } // NO_PROTO1
+} // NO_PROTO1
+
+// Additional messages for testing lazy fields.
+message TestEagerMessage {
+ optional TestAllTypes sub_message = 1 [lazy=false];
+}
+message TestLazyMessage {
+ optional TestAllTypes sub_message = 1 [lazy=true];
+}
+
+// Needed for a Python test.
+message TestNestedMessageHasBits {
+ message NestedMessage {
+ repeated int32 nestedmessage_repeated_int32 = 1;
+ repeated ForeignMessage nestedmessage_repeated_foreignmessage = 2;
+ }
+ optional NestedMessage optional_nested_message = 1;
+}
+
+
+// Test an enum that has multiple values with the same number.
+enum TestEnumWithDupValue {
+ option allow_alias = true;
+
+ FOO1 = 1;
+ BAR1 = 2;
+ BAZ = 3;
+ FOO2 = 1;
+ BAR2 = 2;
+}
+
+// Test an enum with large, unordered values.
+enum TestSparseEnum {
+ SPARSE_A = 123;
+ SPARSE_B = 62374;
+ SPARSE_C = 12589234;
+ SPARSE_D = -15;
+ SPARSE_E = -53452;
+ SPARSE_F = 0;
+ SPARSE_G = 2;
+}
+
+// Test message with CamelCase field names. This violates Protocol Buffer
+// standard style.
+message TestCamelCaseFieldNames {
+ optional int32 PrimitiveField = 1;
+ optional string StringField = 2;
+ optional ForeignEnum EnumField = 3;
+ optional ForeignMessage MessageField = 4;
+ optional string StringPieceField = 5 [ctype=STRING_PIECE];
+ optional string CordField = 6 [ctype=CORD];
+
+ repeated int32 RepeatedPrimitiveField = 7;
+ repeated string RepeatedStringField = 8;
+ repeated ForeignEnum RepeatedEnumField = 9;
+ repeated ForeignMessage RepeatedMessageField = 10;
+ repeated string RepeatedStringPieceField = 11 [ctype=STRING_PIECE];
+ repeated string RepeatedCordField = 12 [ctype=CORD];
+}
+
+
+// We list fields out of order, to ensure that we're using field number and not
+// field index to determine serialization order.
+message TestFieldOrderings {
+ optional string my_string = 11;
+ extensions 2 to 10;
+ optional int64 my_int = 1;
+ extensions 12 to 100;
+ optional float my_float = 101;
+ message NestedMessage {
+ optional int64 oo = 2;
+ // The field name "b" fails to compile in proto1 because it conflicts with
+ // a local variable named "b" in one of the generated methods. Doh.
+ // This file needs to compile in proto1 to test backwards-compatibility.
+ optional int32 bb = 1;
+ }
+
+ optional NestedMessage optional_nested_message = 200;
+}
+
+extend TestFieldOrderings {
+ optional string my_extension_string = 50;
+ optional int32 my_extension_int = 5;
+}
+
+message TestExtensionOrderings1 {
+ extend TestFieldOrderings {
+ optional TestExtensionOrderings1 test_ext_orderings1 = 13;
+ }
+ optional string my_string = 1;
+}
+
+message TestExtensionOrderings2 {
+ extend TestFieldOrderings {
+ optional TestExtensionOrderings2 test_ext_orderings2 = 12;
+ }
+ message TestExtensionOrderings3 {
+ extend TestFieldOrderings {
+ optional TestExtensionOrderings3 test_ext_orderings3 = 14;
+ }
+ optional string my_string = 1;
+ }
+ optional string my_string = 1;
+}
+
+message TestExtremeDefaultValues {
+ optional bytes escaped_bytes = 1 [default = "\0\001\a\b\f\n\r\t\v\\\'\"\xfe"];
+ optional uint32 large_uint32 = 2 [default = 0xFFFFFFFF];
+ optional uint64 large_uint64 = 3 [default = 0xFFFFFFFFFFFFFFFF];
+ optional int32 small_int32 = 4 [default = -0x7FFFFFFF];
+ optional int64 small_int64 = 5 [default = -0x7FFFFFFFFFFFFFFF];
+ optional int32 really_small_int32 = 21 [default = -0x80000000];
+ optional int64 really_small_int64 = 22 [default = -0x8000000000000000];
+
+ // The default value here is UTF-8 for "\u1234". (We could also just type
+ // the UTF-8 text directly into this text file rather than escape it, but
+ // lots of people use editors that would be confused by this.)
+ optional string utf8_string = 6 [default = "\341\210\264"];
+
+ // Tests for single-precision floating-point values.
+ optional float zero_float = 7 [default = 0];
+ optional float one_float = 8 [default = 1];
+ optional float small_float = 9 [default = 1.5];
+ optional float negative_one_float = 10 [default = -1];
+ optional float negative_float = 11 [default = -1.5];
+ // Using exponents
+ optional float large_float = 12 [default = 2E8];
+ optional float small_negative_float = 13 [default = -8e-28];
+
+ // Text for nonfinite floating-point values.
+ optional double inf_double = 14 [default = inf];
+ optional double neg_inf_double = 15 [default = -inf];
+ optional double nan_double = 16 [default = nan];
+ optional float inf_float = 17 [default = inf];
+ optional float neg_inf_float = 18 [default = -inf];
+ optional float nan_float = 19 [default = nan];
+
+ // Tests for C++ trigraphs.
+ // Trigraphs should be escaped in C++ generated files, but they should not be
+ // escaped for other languages.
+ // Note that in .proto file, "\?" is a valid way to escape ? in string
+ // literals.
+ optional string cpp_trigraph = 20 [default = "? \? ?? \?? \??? ??/ ?\?-"];
+
+ // String defaults containing the character '\000'
+ optional string string_with_zero = 23 [default = "hel\000lo"];
+ optional bytes bytes_with_zero = 24 [default = "wor\000ld"];
+ optional string string_piece_with_zero = 25 [ctype=STRING_PIECE,
+ default="ab\000c"];
+ optional string cord_with_zero = 26 [ctype=CORD,
+ default="12\0003"];
+ optional string replacement_string = 27 [default="${unknown}"];
+}
+
+message SparseEnumMessage {
+ optional TestSparseEnum sparse_enum = 1;
+}
+
+// Test String and Bytes: string is for valid UTF-8 strings
+message OneString {
+ optional string data = 1;
+}
+
+message MoreString {
+ repeated string data = 1;
+}
+
+message OneBytes {
+ optional bytes data = 1;
+}
+
+message MoreBytes {
+ repeated bytes data = 1;
+}
+
+// Test int32, uint32, int64, uint64, and bool are all compatible
+message Int32Message {
+ optional int32 data = 1;
+}
+
+message Uint32Message {
+ optional uint32 data = 1;
+}
+
+message Int64Message {
+ optional int64 data = 1;
+}
+
+message Uint64Message {
+ optional uint64 data = 1;
+}
+
+message BoolMessage {
+ optional bool data = 1;
+}
+
+// Test oneofs.
+message TestOneof {
+ oneof foo {
+ int32 foo_int = 1;
+ string foo_string = 2;
+ TestAllTypes foo_message = 3;
+ group FooGroup = 4 {
+ optional int32 a = 5;
+ optional string b = 6;
+ }
+ }
+}
+
+message TestOneofBackwardsCompatible {
+ optional int32 foo_int = 1;
+ optional string foo_string = 2;
+ optional TestAllTypes foo_message = 3;
+ optional group FooGroup = 4 {
+ optional int32 a = 5;
+ optional string b = 6;
+ }
+}
+
+message TestOneof2 {
+ oneof foo {
+ int32 foo_int = 1;
+ string foo_string = 2;
+ string foo_cord = 3 [ctype=CORD];
+ string foo_string_piece = 4 [ctype=STRING_PIECE];
+ bytes foo_bytes = 5;
+ NestedEnum foo_enum = 6;
+ NestedMessage foo_message = 7;
+ group FooGroup = 8 {
+ optional int32 a = 9;
+ optional string b = 10;
+ }
+ NestedMessage foo_lazy_message = 11 [lazy=true];
+ }
+
+ oneof bar {
+ int32 bar_int = 12 [default = 5];
+ string bar_string = 13 [default = "STRING"];
+ string bar_cord = 14 [ctype=CORD, default = "CORD"];
+ string bar_string_piece = 15 [ctype=STRING_PIECE, default = "SPIECE"];
+ bytes bar_bytes = 16 [default = "BYTES"];
+ NestedEnum bar_enum = 17 [default = BAR];
+ string bar_string_with_empty_default = 20 [default = ""];
+ string bar_cord_with_empty_default = 21 [ctype=CORD, default = ""];
+ string bar_string_piece_with_empty_default = 22 [ctype=STRING_PIECE, default = ""];
+ bytes bar_bytes_with_empty_default = 23 [default = ""];
+ }
+
+ optional int32 baz_int = 18;
+ optional string baz_string = 19 [default = "BAZ"];
+
+ message NestedMessage {
+ optional int64 qux_int = 1;
+ repeated int32 corge_int = 2;
+ }
+
+ enum NestedEnum {
+ FOO = 1;
+ BAR = 2;
+ BAZ = 3;
+ }
+}
+
+message TestRequiredOneof {
+ oneof foo {
+ int32 foo_int = 1;
+ string foo_string = 2;
+ NestedMessage foo_message = 3;
+ }
+ message NestedMessage {
+ required double required_double = 1;
+ }
+}
+
+
+// Test messages for packed fields
+
+message TestPackedTypes {
+ repeated int32 packed_int32 = 90 [packed = true];
+ repeated int64 packed_int64 = 91 [packed = true];
+ repeated uint32 packed_uint32 = 92 [packed = true];
+ repeated uint64 packed_uint64 = 93 [packed = true];
+ repeated sint32 packed_sint32 = 94 [packed = true];
+ repeated sint64 packed_sint64 = 95 [packed = true];
+ repeated fixed32 packed_fixed32 = 96 [packed = true];
+ repeated fixed64 packed_fixed64 = 97 [packed = true];
+ repeated sfixed32 packed_sfixed32 = 98 [packed = true];
+ repeated sfixed64 packed_sfixed64 = 99 [packed = true];
+ repeated float packed_float = 100 [packed = true];
+ repeated double packed_double = 101 [packed = true];
+ repeated bool packed_bool = 102 [packed = true];
+ repeated ForeignEnum packed_enum = 103 [packed = true];
+}
+
+// A message with the same fields as TestPackedTypes, but without packing. Used
+// to test packed <-> unpacked wire compatibility.
+message TestUnpackedTypes {
+ repeated int32 unpacked_int32 = 90 [packed = false];
+ repeated int64 unpacked_int64 = 91 [packed = false];
+ repeated uint32 unpacked_uint32 = 92 [packed = false];
+ repeated uint64 unpacked_uint64 = 93 [packed = false];
+ repeated sint32 unpacked_sint32 = 94 [packed = false];
+ repeated sint64 unpacked_sint64 = 95 [packed = false];
+ repeated fixed32 unpacked_fixed32 = 96 [packed = false];
+ repeated fixed64 unpacked_fixed64 = 97 [packed = false];
+ repeated sfixed32 unpacked_sfixed32 = 98 [packed = false];
+ repeated sfixed64 unpacked_sfixed64 = 99 [packed = false];
+ repeated float unpacked_float = 100 [packed = false];
+ repeated double unpacked_double = 101 [packed = false];
+ repeated bool unpacked_bool = 102 [packed = false];
+ repeated ForeignEnum unpacked_enum = 103 [packed = false];
+}
+
+message TestPackedExtensions {
+ extensions 1 to max;
+}
+
+extend TestPackedExtensions {
+ repeated int32 packed_int32_extension = 90 [packed = true];
+ repeated int64 packed_int64_extension = 91 [packed = true];
+ repeated uint32 packed_uint32_extension = 92 [packed = true];
+ repeated uint64 packed_uint64_extension = 93 [packed = true];
+ repeated sint32 packed_sint32_extension = 94 [packed = true];
+ repeated sint64 packed_sint64_extension = 95 [packed = true];
+ repeated fixed32 packed_fixed32_extension = 96 [packed = true];
+ repeated fixed64 packed_fixed64_extension = 97 [packed = true];
+ repeated sfixed32 packed_sfixed32_extension = 98 [packed = true];
+ repeated sfixed64 packed_sfixed64_extension = 99 [packed = true];
+ repeated float packed_float_extension = 100 [packed = true];
+ repeated double packed_double_extension = 101 [packed = true];
+ repeated bool packed_bool_extension = 102 [packed = true];
+ repeated ForeignEnum packed_enum_extension = 103 [packed = true];
+}
+
+message TestUnpackedExtensions {
+ extensions 1 to max;
+}
+
+extend TestUnpackedExtensions {
+ repeated int32 unpacked_int32_extension = 90 [packed = false];
+ repeated int64 unpacked_int64_extension = 91 [packed = false];
+ repeated uint32 unpacked_uint32_extension = 92 [packed = false];
+ repeated uint64 unpacked_uint64_extension = 93 [packed = false];
+ repeated sint32 unpacked_sint32_extension = 94 [packed = false];
+ repeated sint64 unpacked_sint64_extension = 95 [packed = false];
+ repeated fixed32 unpacked_fixed32_extension = 96 [packed = false];
+ repeated fixed64 unpacked_fixed64_extension = 97 [packed = false];
+ repeated sfixed32 unpacked_sfixed32_extension = 98 [packed = false];
+ repeated sfixed64 unpacked_sfixed64_extension = 99 [packed = false];
+ repeated float unpacked_float_extension = 100 [packed = false];
+ repeated double unpacked_double_extension = 101 [packed = false];
+ repeated bool unpacked_bool_extension = 102 [packed = false];
+ repeated ForeignEnum unpacked_enum_extension = 103 [packed = false];
+}
+
+// Used by ExtensionSetTest/DynamicExtensions. The test actually builds
+// a set of extensions to TestAllExtensions dynamically, based on the fields
+// of this message type.
+message TestDynamicExtensions {
+ enum DynamicEnumType {
+ DYNAMIC_FOO = 2200;
+ DYNAMIC_BAR = 2201;
+ DYNAMIC_BAZ = 2202;
+ }
+ message DynamicMessageType {
+ optional int32 dynamic_field = 2100;
+ }
+
+ optional fixed32 scalar_extension = 2000;
+ optional ForeignEnum enum_extension = 2001;
+ optional DynamicEnumType dynamic_enum_extension = 2002;
+
+ optional ForeignMessage message_extension = 2003;
+ optional DynamicMessageType dynamic_message_extension = 2004;
+
+ repeated string repeated_extension = 2005;
+ repeated sint32 packed_extension = 2006 [packed = true];
+}
+
+message TestRepeatedScalarDifferentTagSizes {
+ // Parsing repeated fixed size values used to fail. This message needs to be
+ // used in order to get a tag of the right size; all of the repeated fields
+ // in TestAllTypes didn't trigger the check.
+ repeated fixed32 repeated_fixed32 = 12;
+ // Check for a varint type, just for good measure.
+ repeated int32 repeated_int32 = 13;
+
+ // These have two-byte tags.
+ repeated fixed64 repeated_fixed64 = 2046;
+ repeated int64 repeated_int64 = 2047;
+
+ // Three byte tags.
+ repeated float repeated_float = 262142;
+ repeated uint64 repeated_uint64 = 262143;
+}
+
+// Test that if an optional or required message/group field appears multiple
+// times in the input, they need to be merged.
+message TestParsingMerge {
+ // RepeatedFieldsGenerator defines matching field types as TestParsingMerge,
+ // except that all fields are repeated. In the tests, we will serialize the
+ // RepeatedFieldsGenerator to bytes, and parse the bytes to TestParsingMerge.
+ // Repeated fields in RepeatedFieldsGenerator are expected to be merged into
+ // the corresponding required/optional fields in TestParsingMerge.
+ message RepeatedFieldsGenerator {
+ repeated TestAllTypes field1 = 1;
+ repeated TestAllTypes field2 = 2;
+ repeated TestAllTypes field3 = 3;
+ repeated group Group1 = 10 {
+ optional TestAllTypes field1 = 11;
+ }
+ repeated group Group2 = 20 {
+ optional TestAllTypes field1 = 21;
+ }
+ repeated TestAllTypes ext1 = 1000;
+ repeated TestAllTypes ext2 = 1001;
+ }
+ required TestAllTypes required_all_types = 1;
+ optional TestAllTypes optional_all_types = 2;
+ repeated TestAllTypes repeated_all_types = 3;
+ optional group OptionalGroup = 10 {
+ optional TestAllTypes optional_group_all_types = 11;
+ }
+ repeated group RepeatedGroup = 20 {
+ optional TestAllTypes repeated_group_all_types = 21;
+ }
+ extensions 1000 to max;
+ extend TestParsingMerge {
+ optional TestAllTypes optional_ext = 1000;
+ repeated TestAllTypes repeated_ext = 1001;
+ }
+}
+
+message TestCommentInjectionMessage {
+ // */ <- This should not close the generated doc comment
+ optional string a = 1 [default="*/ <- Neither should this."];
+}
+
+
+// Test that RPC services work.
+message FooRequest {}
+message FooResponse {}
+
+message FooClientMessage {}
+message FooServerMessage{}
+
+service TestService {
+ rpc Foo(FooRequest) returns (FooResponse);
+ rpc Bar(BarRequest) returns (BarResponse);
+}
+
+
+message BarRequest {}
+message BarResponse {}
+
+message TestJsonName {
+ optional int32 field_name1 = 1;
+ optional int32 fieldName2 = 2;
+ optional int32 FieldName3 = 3;
+ optional int32 _field_name4 = 4;
+ optional int32 FIELD_NAME5 = 5;
+ optional int32 field_name6 = 6 [json_name = "@type"];
+ optional int32 fieldname7 = 7;
+}
+
+message TestHugeFieldNumbers {
+ optional int32 optional_int32 = 536870000;
+ optional int32 fixed_32 = 536870001;
+ repeated int32 repeated_int32 = 536870002 [packed = false];
+ repeated int32 packed_int32 = 536870003 [packed = true];
+
+ optional ForeignEnum optional_enum = 536870004;
+ optional string optional_string = 536870005;
+ optional bytes optional_bytes = 536870006;
+ optional ForeignMessage optional_message = 536870007;
+
+ optional group OptionalGroup = 536870008 {
+ optional int32 group_a = 536870009;
+ }
+
+ map<string, string> string_string_map = 536870010;
+
+ oneof oneof_field {
+ uint32 oneof_uint32 = 536870011;
+ TestAllTypes oneof_test_all_types = 536870012;
+ string oneof_string = 536870013;
+ bytes oneof_bytes = 536870014;
+ }
+
+ extensions 536860000 to 536869999;
+}
+
+extend TestHugeFieldNumbers {
+ optional TestAllTypes test_all_types = 536860000;
+}
+
+message TestExtensionInsideTable {
+ optional int32 field1 = 1;
+ optional int32 field2 = 2;
+ optional int32 field3 = 3;
+ optional int32 field4 = 4;
+ extensions 5 to 5;
+ optional int32 field6 = 6;
+ optional int32 field7 = 7;
+ optional int32 field8 = 8;
+ optional int32 field9 = 9;
+ optional int32 field10 = 10;
+}
+
+extend TestExtensionInsideTable {
+ optional int32 test_extension_inside_table_extension = 5;
+}
+
+enum VeryLargeEnum {
+ ENUM_LABEL_DEFAULT = 0;
+ ENUM_LABEL_1 = 1;
+ ENUM_LABEL_2 = 2;
+ ENUM_LABEL_3 = 3;
+ ENUM_LABEL_4 = 4;
+ ENUM_LABEL_5 = 5;
+ ENUM_LABEL_6 = 6;
+ ENUM_LABEL_7 = 7;
+ ENUM_LABEL_8 = 8;
+ ENUM_LABEL_9 = 9;
+ ENUM_LABEL_10 = 10;
+ ENUM_LABEL_11 = 11;
+ ENUM_LABEL_12 = 12;
+ ENUM_LABEL_13 = 13;
+ ENUM_LABEL_14 = 14;
+ ENUM_LABEL_15 = 15;
+ ENUM_LABEL_16 = 16;
+ ENUM_LABEL_17 = 17;
+ ENUM_LABEL_18 = 18;
+ ENUM_LABEL_19 = 19;
+ ENUM_LABEL_20 = 20;
+ ENUM_LABEL_21 = 21;
+ ENUM_LABEL_22 = 22;
+ ENUM_LABEL_23 = 23;
+ ENUM_LABEL_24 = 24;
+ ENUM_LABEL_25 = 25;
+ ENUM_LABEL_26 = 26;
+ ENUM_LABEL_27 = 27;
+ ENUM_LABEL_28 = 28;
+ ENUM_LABEL_29 = 29;
+ ENUM_LABEL_30 = 30;
+ ENUM_LABEL_31 = 31;
+ ENUM_LABEL_32 = 32;
+ ENUM_LABEL_33 = 33;
+ ENUM_LABEL_34 = 34;
+ ENUM_LABEL_35 = 35;
+ ENUM_LABEL_36 = 36;
+ ENUM_LABEL_37 = 37;
+ ENUM_LABEL_38 = 38;
+ ENUM_LABEL_39 = 39;
+ ENUM_LABEL_40 = 40;
+ ENUM_LABEL_41 = 41;
+ ENUM_LABEL_42 = 42;
+ ENUM_LABEL_43 = 43;
+ ENUM_LABEL_44 = 44;
+ ENUM_LABEL_45 = 45;
+ ENUM_LABEL_46 = 46;
+ ENUM_LABEL_47 = 47;
+ ENUM_LABEL_48 = 48;
+ ENUM_LABEL_49 = 49;
+ ENUM_LABEL_50 = 50;
+ ENUM_LABEL_51 = 51;
+ ENUM_LABEL_52 = 52;
+ ENUM_LABEL_53 = 53;
+ ENUM_LABEL_54 = 54;
+ ENUM_LABEL_55 = 55;
+ ENUM_LABEL_56 = 56;
+ ENUM_LABEL_57 = 57;
+ ENUM_LABEL_58 = 58;
+ ENUM_LABEL_59 = 59;
+ ENUM_LABEL_60 = 60;
+ ENUM_LABEL_61 = 61;
+ ENUM_LABEL_62 = 62;
+ ENUM_LABEL_63 = 63;
+ ENUM_LABEL_64 = 64;
+ ENUM_LABEL_65 = 65;
+ ENUM_LABEL_66 = 66;
+ ENUM_LABEL_67 = 67;
+ ENUM_LABEL_68 = 68;
+ ENUM_LABEL_69 = 69;
+ ENUM_LABEL_70 = 70;
+ ENUM_LABEL_71 = 71;
+ ENUM_LABEL_72 = 72;
+ ENUM_LABEL_73 = 73;
+ ENUM_LABEL_74 = 74;
+ ENUM_LABEL_75 = 75;
+ ENUM_LABEL_76 = 76;
+ ENUM_LABEL_77 = 77;
+ ENUM_LABEL_78 = 78;
+ ENUM_LABEL_79 = 79;
+ ENUM_LABEL_80 = 80;
+ ENUM_LABEL_81 = 81;
+ ENUM_LABEL_82 = 82;
+ ENUM_LABEL_83 = 83;
+ ENUM_LABEL_84 = 84;
+ ENUM_LABEL_85 = 85;
+ ENUM_LABEL_86 = 86;
+ ENUM_LABEL_87 = 87;
+ ENUM_LABEL_88 = 88;
+ ENUM_LABEL_89 = 89;
+ ENUM_LABEL_90 = 90;
+ ENUM_LABEL_91 = 91;
+ ENUM_LABEL_92 = 92;
+ ENUM_LABEL_93 = 93;
+ ENUM_LABEL_94 = 94;
+ ENUM_LABEL_95 = 95;
+ ENUM_LABEL_96 = 96;
+ ENUM_LABEL_97 = 97;
+ ENUM_LABEL_98 = 98;
+ ENUM_LABEL_99 = 99;
+ ENUM_LABEL_100 = 100;
+};
+
+message TestExtensionRangeSerialize {
+ optional int32 foo_one = 1;
+
+ extensions 2 to 2;
+ extensions 3 to 4;
+
+ optional int32 foo_two = 6;
+ optional int32 foo_three = 7;
+
+ extensions 9 to 10;
+
+ optional int32 foo_four = 13;
+
+ extensions 15 to 15;
+ extensions 17 to 17;
+ extensions 19 to 19;
+
+ extend TestExtensionRangeSerialize {
+ optional int32 bar_one = 2;
+ optional int32 bar_two = 4;
+
+ optional int32 bar_three = 10;
+
+ optional int32 bar_four = 15;
+ optional int32 bar_five = 19;
+ }
+}
+
+
diff --git a/NorthstarDedicatedTest/include/protobuf/unittest_arena.proto b/NorthstarDedicatedTest/include/protobuf/unittest_arena.proto
new file mode 100644
index 00000000..7b317399
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/unittest_arena.proto
@@ -0,0 +1,43 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+syntax = "proto2";
+
+package proto2_arena_unittest;
+
+option cc_enable_arenas = true;
+
+message NestedMessage {
+ optional int32 d = 1;
+}
+
+message ArenaMessage {
+ repeated NestedMessage repeated_nested_message = 1;
+}
diff --git a/NorthstarDedicatedTest/include/protobuf/unittest_custom_options.proto b/NorthstarDedicatedTest/include/protobuf/unittest_custom_options.proto
new file mode 100644
index 00000000..1812d71e
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/unittest_custom_options.proto
@@ -0,0 +1,464 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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: benjy@google.com (Benjy Weinberger)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// A proto file used to test the "custom options" feature of google.protobuf.
+
+syntax = "proto2";
+
+// Some generic_services option(s) added automatically.
+// See: http://go/proto2-generic-services-default
+option cc_generic_services = true; // auto-added
+option java_generic_services = true; // auto-added
+option py_generic_services = true;
+
+// A custom file option (defined below).
+option (file_opt1) = 9876543210;
+
+import "google/protobuf/any.proto";
+import "google/protobuf/descriptor.proto";
+
+// We don't put this in a package within proto2 because we need to make sure
+// that the generated code doesn't depend on being in the proto2 namespace.
+package protobuf_unittest;
+
+// Some simple test custom options of various types.
+
+extend google.protobuf.FileOptions {
+ optional uint64 file_opt1 = 7736974;
+}
+
+extend google.protobuf.MessageOptions {
+ optional int32 message_opt1 = 7739036;
+}
+
+extend google.protobuf.FieldOptions {
+ optional fixed64 field_opt1 = 7740936;
+ // This is useful for testing that we correctly register default values for
+ // extension options.
+ optional int32 field_opt2 = 7753913 [default = 42];
+}
+
+extend google.protobuf.OneofOptions {
+ optional int32 oneof_opt1 = 7740111;
+}
+
+extend google.protobuf.EnumOptions {
+ optional sfixed32 enum_opt1 = 7753576;
+}
+
+extend google.protobuf.EnumValueOptions {
+ optional int32 enum_value_opt1 = 1560678;
+}
+
+extend google.protobuf.ServiceOptions {
+ optional sint64 service_opt1 = 7887650;
+}
+
+enum MethodOpt1 {
+ METHODOPT1_VAL1 = 1;
+ METHODOPT1_VAL2 = 2;
+}
+
+extend google.protobuf.MethodOptions {
+ optional MethodOpt1 method_opt1 = 7890860;
+}
+
+// A test message with custom options at all possible locations (and also some
+// regular options, to make sure they interact nicely).
+message TestMessageWithCustomOptions {
+ option message_set_wire_format = false;
+ option (message_opt1) = -56;
+
+ optional string field1 = 1 [ctype = CORD, (field_opt1) = 8765432109];
+
+ oneof AnOneof {
+ option (oneof_opt1) = -99;
+
+ int32 oneof_field = 2;
+ }
+
+ map<string, string> map_field = 3 [(field_opt1) = 12345];
+
+ enum AnEnum {
+ option (enum_opt1) = -789;
+
+ ANENUM_VAL1 = 1;
+ ANENUM_VAL2 = 2 [(enum_value_opt1) = 123];
+ }
+}
+
+// A test RPC service with custom options at all possible locations (and also
+// some regular options, to make sure they interact nicely).
+message CustomOptionFooRequest {}
+
+message CustomOptionFooResponse {}
+
+message CustomOptionFooClientMessage {}
+
+message CustomOptionFooServerMessage {}
+
+service TestServiceWithCustomOptions {
+ option (service_opt1) = -9876543210;
+
+ rpc Foo(CustomOptionFooRequest) returns (CustomOptionFooResponse) {
+ option (method_opt1) = METHODOPT1_VAL2;
+ }
+}
+
+// Options of every possible field type, so we can test them all exhaustively.
+
+message DummyMessageContainingEnum {
+ enum TestEnumType {
+ TEST_OPTION_ENUM_TYPE1 = 22;
+ TEST_OPTION_ENUM_TYPE2 = -23;
+ }
+}
+
+message DummyMessageInvalidAsOptionType {}
+
+extend google.protobuf.MessageOptions {
+ optional bool bool_opt = 7706090;
+ optional int32 int32_opt = 7705709;
+ optional int64 int64_opt = 7705542;
+ optional uint32 uint32_opt = 7704880;
+ optional uint64 uint64_opt = 7702367;
+ optional sint32 sint32_opt = 7701568;
+ optional sint64 sint64_opt = 7700863;
+ optional fixed32 fixed32_opt = 7700307;
+ optional fixed64 fixed64_opt = 7700194;
+ optional sfixed32 sfixed32_opt = 7698645;
+ optional sfixed64 sfixed64_opt = 7685475;
+ optional float float_opt = 7675390;
+ optional double double_opt = 7673293;
+ optional string string_opt = 7673285;
+ optional bytes bytes_opt = 7673238;
+ optional DummyMessageContainingEnum.TestEnumType enum_opt = 7673233;
+ optional DummyMessageInvalidAsOptionType message_type_opt = 7665967;
+}
+
+message CustomOptionMinIntegerValues {
+ option (bool_opt) = false;
+ option (int32_opt) = -0x80000000;
+ option (int64_opt) = -0x8000000000000000;
+ option (uint32_opt) = 0;
+ option (uint64_opt) = 0;
+ option (sint32_opt) = -0x80000000;
+ option (sint64_opt) = -0x8000000000000000;
+ option (fixed32_opt) = 0;
+ option (fixed64_opt) = 0;
+ option (sfixed32_opt) = -0x80000000;
+ option (sfixed64_opt) = -0x8000000000000000;
+}
+
+message CustomOptionMaxIntegerValues {
+ option (bool_opt) = true;
+ option (int32_opt) = 0x7FFFFFFF;
+ option (int64_opt) = 0x7FFFFFFFFFFFFFFF;
+ option (uint32_opt) = 0xFFFFFFFF;
+ option (uint64_opt) = 0xFFFFFFFFFFFFFFFF;
+ option (sint32_opt) = 0x7FFFFFFF;
+ option (sint64_opt) = 0x7FFFFFFFFFFFFFFF;
+ option (fixed32_opt) = 0xFFFFFFFF;
+ option (fixed64_opt) = 0xFFFFFFFFFFFFFFFF;
+ option (sfixed32_opt) = 0x7FFFFFFF;
+ option (sfixed64_opt) = 0x7FFFFFFFFFFFFFFF;
+}
+
+message CustomOptionOtherValues {
+ option (int32_opt) = -100; // To test sign-extension.
+ option (float_opt) = 12.3456789;
+ option (double_opt) = 1.234567890123456789;
+ option (string_opt) = "Hello, \"World\"";
+ option (bytes_opt) = "Hello\0World";
+ option (enum_opt) = TEST_OPTION_ENUM_TYPE2;
+}
+
+message SettingRealsFromPositiveInts {
+ option (float_opt) = 12;
+ option (double_opt) = 154;
+}
+
+message SettingRealsFromNegativeInts {
+ option (float_opt) = -12;
+ option (double_opt) = -154;
+}
+
+// Options of complex message types, themselves combined and extended in
+// various ways.
+
+message ComplexOptionType1 {
+ optional int32 foo = 1;
+ optional int32 foo2 = 2;
+ optional int32 foo3 = 3;
+ repeated int32 foo4 = 4;
+
+ extensions 100 to max;
+}
+
+message ComplexOptionType2 {
+ optional ComplexOptionType1 bar = 1;
+ optional int32 baz = 2;
+
+ message ComplexOptionType4 {
+ optional int32 waldo = 1;
+
+ extend google.protobuf.MessageOptions {
+ optional ComplexOptionType4 complex_opt4 = 7633546;
+ }
+ }
+
+ optional ComplexOptionType4 fred = 3;
+ repeated ComplexOptionType4 barney = 4;
+
+ extensions 100 to max;
+}
+
+message ComplexOptionType3 {
+ optional int32 qux = 1;
+
+ optional group ComplexOptionType5 = 2 {
+ optional int32 plugh = 3;
+ }
+}
+
+extend ComplexOptionType1 {
+ optional int32 quux = 7663707;
+ optional ComplexOptionType3 corge = 7663442;
+}
+
+extend ComplexOptionType2 {
+ optional int32 grault = 7650927;
+ optional ComplexOptionType1 garply = 7649992;
+}
+
+extend google.protobuf.MessageOptions {
+ optional protobuf_unittest.ComplexOptionType1 complex_opt1 = 7646756;
+ optional ComplexOptionType2 complex_opt2 = 7636949;
+ optional ComplexOptionType3 complex_opt3 = 7636463;
+ optional group ComplexOpt6 = 7595468 {
+ optional int32 xyzzy = 7593951;
+ }
+}
+
+// Note that we try various different ways of naming the same extension.
+message VariousComplexOptions {
+ option (.protobuf_unittest.complex_opt1).foo = 42;
+ option (protobuf_unittest.complex_opt1).(.protobuf_unittest.quux) = 324;
+ option (.protobuf_unittest.complex_opt1).(protobuf_unittest.corge).qux = 876;
+ option (protobuf_unittest.complex_opt1).foo4 = 99;
+ option (protobuf_unittest.complex_opt1).foo4 = 88;
+ option (complex_opt2).baz = 987;
+ option (complex_opt2).(grault) = 654;
+ option (complex_opt2).bar.foo = 743;
+ option (complex_opt2).bar.(quux) = 1999;
+ option (complex_opt2).bar.(protobuf_unittest.corge).qux = 2008;
+ option (complex_opt2).(garply).foo = 741;
+ option (complex_opt2).(garply).(.protobuf_unittest.quux) = 1998;
+ option (complex_opt2).(protobuf_unittest.garply).(corge).qux = 2121;
+ option (ComplexOptionType2.ComplexOptionType4.complex_opt4).waldo = 1971;
+ option (complex_opt2).fred.waldo = 321;
+ option (complex_opt2).barney = {
+ waldo: 101
+ };
+ option (complex_opt2).barney = {
+ waldo: 212
+ };
+ option (protobuf_unittest.complex_opt3).qux = 9;
+ option (complex_opt3).complexoptiontype5.plugh = 22;
+ option (complexopt6).xyzzy = 24;
+}
+
+// ------------------------------------------------------
+// Definitions for testing aggregate option parsing.
+// See descriptor_unittest.cc.
+
+message AggregateMessageSet {
+ option message_set_wire_format = true;
+
+ extensions 4 to max;
+}
+
+message AggregateMessageSetElement {
+ extend AggregateMessageSet {
+ optional AggregateMessageSetElement message_set_extension = 15447542;
+ }
+ optional string s = 1;
+}
+
+// A helper type used to test aggregate option parsing
+message Aggregate {
+ optional int32 i = 1;
+ optional string s = 2;
+
+ // A nested object
+ optional Aggregate sub = 3;
+
+ // To test the parsing of extensions inside aggregate values
+ optional google.protobuf.FileOptions file = 4;
+ extend google.protobuf.FileOptions {
+ optional Aggregate nested = 15476903;
+ }
+
+ // An embedded message set
+ optional AggregateMessageSet mset = 5;
+
+ // An any
+ optional google.protobuf.Any any = 6;
+}
+
+// Allow Aggregate to be used as an option at all possible locations
+// in the .proto grammar.
+extend google.protobuf.FileOptions {
+ optional Aggregate fileopt = 15478479;
+}
+extend google.protobuf.MessageOptions {
+ optional Aggregate msgopt = 15480088;
+}
+extend google.protobuf.FieldOptions {
+ optional Aggregate fieldopt = 15481374;
+}
+extend google.protobuf.EnumOptions {
+ optional Aggregate enumopt = 15483218;
+}
+extend google.protobuf.EnumValueOptions {
+ optional Aggregate enumvalopt = 15486921;
+}
+extend google.protobuf.ServiceOptions {
+ optional Aggregate serviceopt = 15497145;
+}
+extend google.protobuf.MethodOptions {
+ optional Aggregate methodopt = 15512713;
+}
+
+// Try using AggregateOption at different points in the proto grammar
+option (fileopt) = {
+ s: 'FileAnnotation'
+ // Also test the handling of comments
+ /* of both types */
+ i: 100
+
+ sub { s: 'NestedFileAnnotation' }
+
+ // Include a google.protobuf.FileOptions and recursively extend it with
+ // another fileopt.
+ file {
+ [protobuf_unittest.fileopt] { s: 'FileExtensionAnnotation' }
+ }
+
+ // A message set inside an option value
+ mset {
+ [protobuf_unittest.AggregateMessageSetElement.message_set_extension] {
+ s: 'EmbeddedMessageSetElement'
+ }
+ }
+
+ any {
+ [type.googleapis.com/protobuf_unittest.AggregateMessageSetElement] {
+ s: 'EmbeddedMessageSetElement'
+ }
+ }
+};
+
+message AggregateMessage {
+ option (msgopt) = {
+ i: 101
+ s: 'MessageAnnotation'
+ };
+
+ optional int32 fieldname = 1 [(fieldopt) = { s: 'FieldAnnotation' }];
+}
+
+service AggregateService {
+ option (serviceopt) = {
+ s: 'ServiceAnnotation'
+ };
+
+ rpc Method(AggregateMessage) returns (AggregateMessage) {
+ option (methodopt) = {
+ s: 'MethodAnnotation'
+ };
+ }
+}
+
+enum AggregateEnum {
+ option (enumopt) = {
+ s: 'EnumAnnotation'
+ };
+
+ VALUE = 1 [(enumvalopt) = { s: 'EnumValueAnnotation' }];
+}
+
+// Test custom options for nested type.
+message NestedOptionType {
+ message NestedMessage {
+ option (message_opt1) = 1001;
+
+ optional int32 nested_field = 1 [(field_opt1) = 1002];
+ }
+ enum NestedEnum {
+ option (enum_opt1) = 1003;
+
+ NESTED_ENUM_VALUE = 1 [(enum_value_opt1) = 1004];
+ }
+ extend google.protobuf.FileOptions {
+ optional int32 nested_extension = 7912573 [(field_opt2) = 1005];
+ }
+}
+
+// Custom message option that has a required enum field.
+// WARNING: this is strongly discouraged!
+message OldOptionType {
+ enum TestEnum { OLD_VALUE = 0; }
+ required TestEnum value = 1;
+}
+
+// Updated version of the custom option above.
+message NewOptionType {
+ enum TestEnum {
+ OLD_VALUE = 0;
+ NEW_VALUE = 1;
+ }
+ required TestEnum value = 1;
+}
+
+extend google.protobuf.MessageOptions {
+ optional OldOptionType required_enum_opt = 106161807;
+}
+
+// Test message using the "required_enum_opt" option defined above.
+message TestMessageWithRequiredEnumOption {
+ option (required_enum_opt) = {
+ value: OLD_VALUE
+ };
+}
diff --git a/NorthstarDedicatedTest/include/protobuf/unittest_drop_unknown_fields.proto b/NorthstarDedicatedTest/include/protobuf/unittest_drop_unknown_fields.proto
new file mode 100644
index 00000000..8aa3a37b
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/unittest_drop_unknown_fields.proto
@@ -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.
+
+syntax = "proto3";
+
+package unittest_drop_unknown_fields;
+option objc_class_prefix = "DropUnknowns";
+
+option csharp_namespace = "Google.Protobuf.TestProtos";
+
+message Foo {
+ enum NestedEnum {
+ FOO = 0;
+ BAR = 1;
+ BAZ = 2;
+ }
+ int32 int32_value = 1;
+ NestedEnum enum_value = 2;
+}
+
+message FooWithExtraFields {
+ enum NestedEnum {
+ FOO = 0;
+ BAR = 1;
+ BAZ = 2;
+ QUX = 3;
+ }
+ int32 int32_value = 1;
+ NestedEnum enum_value = 2;
+ int32 extra_int32_value = 3;
+}
diff --git a/NorthstarDedicatedTest/include/protobuf/unittest_embed_optimize_for.proto b/NorthstarDedicatedTest/include/protobuf/unittest_embed_optimize_for.proto
new file mode 100644
index 00000000..d8b0f9b9
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/unittest_embed_optimize_for.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.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// A proto file which imports a proto file that uses optimize_for = CODE_SIZE.
+
+syntax = "proto2";
+import "google/protobuf/unittest_optimize_for.proto";
+
+package protobuf_unittest;
+
+// We optimize for speed here, but we are importing a proto that is optimized
+// for code size.
+option optimize_for = SPEED;
+
+message TestEmbedOptimizedForSize {
+ // Test that embedding a message which has optimize_for = CODE_SIZE into
+ // one optimized for speed works.
+ optional TestOptimizedForSize optional_message = 1;
+ repeated TestOptimizedForSize repeated_message = 2;
+}
diff --git a/NorthstarDedicatedTest/include/protobuf/unittest_empty.proto b/NorthstarDedicatedTest/include/protobuf/unittest_empty.proto
new file mode 100644
index 00000000..36443e7e
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/unittest_empty.proto
@@ -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.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// This file intentionally left blank. (At one point this wouldn't compile
+// correctly.)
+
+syntax = "proto2";
diff --git a/NorthstarDedicatedTest/include/protobuf/unittest_enormous_descriptor.proto b/NorthstarDedicatedTest/include/protobuf/unittest_enormous_descriptor.proto
new file mode 100644
index 00000000..c700a273
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/unittest_enormous_descriptor.proto
@@ -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.
+//
+// A proto file that has an extremely large descriptor. Used to test that
+// descriptors over 64k don't break language-specific limits in generated code,
+// such as the string literal length limit in Java.
+
+syntax = "proto2";
+
+package protobuf_unittest;
+option java_package = "com.google.protobuf";
+
+// Avoid generating insanely long methods.
+option optimize_for = CODE_SIZE;
+
+message TestEnormousDescriptor {
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_1 = 1 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_2 = 2 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_3 = 3 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_4 = 4 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_5 = 5 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_6 = 6 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_7 = 7 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_8 = 8 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_9 = 9 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_10 = 10 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_11 = 11 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_12 = 12 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_13 = 13 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_14 = 14 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_15 = 15 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_16 = 16 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_17 = 17 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_18 = 18 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_19 = 19 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_20 = 20 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_21 = 21 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_22 = 22 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_23 = 23 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_24 = 24 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_25 = 25 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_26 = 26 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_27 = 27 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_28 = 28 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_29 = 29 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_30 = 30 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_31 = 31 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_32 = 32 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_33 = 33 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_34 = 34 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_35 = 35 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_36 = 36 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_37 = 37 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_38 = 38 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_39 = 39 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_40 = 40 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_41 = 41 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_42 = 42 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_43 = 43 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_44 = 44 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_45 = 45 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_46 = 46 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_47 = 47 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_48 = 48 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_49 = 49 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_50 = 50 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_51 = 51 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_52 = 52 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_53 = 53 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_54 = 54 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_55 = 55 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_56 = 56 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_57 = 57 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_58 = 58 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_59 = 59 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_60 = 60 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_61 = 61 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_62 = 62 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_63 = 63 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_64 = 64 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_65 = 65 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_66 = 66 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_67 = 67 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_68 = 68 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_69 = 69 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_70 = 70 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_71 = 71 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_72 = 72 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_73 = 73 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_74 = 74 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_75 = 75 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_76 = 76 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_77 = 77 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_78 = 78 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_79 = 79 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_80 = 80 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_81 = 81 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_82 = 82 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_83 = 83 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_84 = 84 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_85 = 85 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_86 = 86 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_87 = 87 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_88 = 88 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_89 = 89 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_90 = 90 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_91 = 91 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_92 = 92 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_93 = 93 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_94 = 94 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_95 = 95 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_96 = 96 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_97 = 97 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_98 = 98 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_99 = 99 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_100 = 100 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_101 = 101 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_102 = 102 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_103 = 103 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_104 = 104 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_105 = 105 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_106 = 106 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_107 = 107 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_108 = 108 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_109 = 109 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_110 = 110 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_111 = 111 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_112 = 112 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_113 = 113 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_114 = 114 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_115 = 115 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_116 = 116 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_117 = 117 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_118 = 118 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_119 = 119 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_120 = 120 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_121 = 121 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_122 = 122 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_123 = 123 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_124 = 124 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_125 = 125 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_126 = 126 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_127 = 127 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_128 = 128 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_129 = 129 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_130 = 130 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_131 = 131 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_132 = 132 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_133 = 133 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_134 = 134 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_135 = 135 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_136 = 136 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_137 = 137 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_138 = 138 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_139 = 139 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_140 = 140 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_141 = 141 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_142 = 142 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_143 = 143 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_144 = 144 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_145 = 145 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_146 = 146 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_147 = 147 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_148 = 148 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_149 = 149 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_150 = 150 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_151 = 151 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_152 = 152 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_153 = 153 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_154 = 154 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_155 = 155 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_156 = 156 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_157 = 157 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_158 = 158 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_159 = 159 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_160 = 160 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_161 = 161 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_162 = 162 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_163 = 163 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_164 = 164 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_165 = 165 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_166 = 166 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_167 = 167 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_168 = 168 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_169 = 169 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_170 = 170 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_171 = 171 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_172 = 172 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_173 = 173 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_174 = 174 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_175 = 175 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_176 = 176 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_177 = 177 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_178 = 178 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_179 = 179 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_180 = 180 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_181 = 181 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_182 = 182 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_183 = 183 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_184 = 184 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_185 = 185 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_186 = 186 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_187 = 187 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_188 = 188 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_189 = 189 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_190 = 190 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_191 = 191 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_192 = 192 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_193 = 193 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_194 = 194 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_195 = 195 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_196 = 196 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_197 = 197 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_198 = 198 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_199 = 199 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_200 = 200 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_201 = 201 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_202 = 202 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_203 = 203 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_204 = 204 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_205 = 205 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_206 = 206 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_207 = 207 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_208 = 208 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_209 = 209 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_210 = 210 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_211 = 211 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_212 = 212 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_213 = 213 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_214 = 214 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_215 = 215 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_216 = 216 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_217 = 217 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_218 = 218 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_219 = 219 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_220 = 220 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_221 = 221 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_222 = 222 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_223 = 223 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_224 = 224 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_225 = 225 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_226 = 226 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_227 = 227 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_228 = 228 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_229 = 229 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_230 = 230 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_231 = 231 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_232 = 232 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_233 = 233 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_234 = 234 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_235 = 235 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_236 = 236 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_237 = 237 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_238 = 238 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_239 = 239 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_240 = 240 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_241 = 241 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_242 = 242 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_243 = 243 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_244 = 244 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_245 = 245 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_246 = 246 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_247 = 247 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_248 = 248 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_249 = 249 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_250 = 250 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_251 = 251 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_252 = 252 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_253 = 253 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_254 = 254 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_255 = 255 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_256 = 256 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_257 = 257 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_258 = 258 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_259 = 259 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_260 = 260 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_261 = 261 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_262 = 262 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_263 = 263 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_264 = 264 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_265 = 265 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_266 = 266 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_267 = 267 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_268 = 268 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_269 = 269 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_270 = 270 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_271 = 271 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_272 = 272 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_273 = 273 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_274 = 274 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_275 = 275 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_276 = 276 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_277 = 277 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_278 = 278 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_279 = 279 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_280 = 280 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_281 = 281 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_282 = 282 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_283 = 283 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_284 = 284 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_285 = 285 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_286 = 286 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_287 = 287 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_288 = 288 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_289 = 289 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_290 = 290 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_291 = 291 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_292 = 292 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_293 = 293 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_294 = 294 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_295 = 295 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_296 = 296 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_297 = 297 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_298 = 298 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_299 = 299 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_300 = 300 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_301 = 301 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_302 = 302 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_303 = 303 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_304 = 304 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_305 = 305 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_306 = 306 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_307 = 307 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_308 = 308 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_309 = 309 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_310 = 310 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_311 = 311 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_312 = 312 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_313 = 313 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_314 = 314 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_315 = 315 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_316 = 316 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_317 = 317 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_318 = 318 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_319 = 319 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_320 = 320 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_321 = 321 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_322 = 322 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_323 = 323 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_324 = 324 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_325 = 325 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_326 = 326 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_327 = 327 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_328 = 328 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_329 = 329 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_330 = 330 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_331 = 331 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_332 = 332 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_333 = 333 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_334 = 334 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_335 = 335 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_336 = 336 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_337 = 337 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_338 = 338 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_339 = 339 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_340 = 340 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_341 = 341 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_342 = 342 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_343 = 343 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_344 = 344 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_345 = 345 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_346 = 346 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_347 = 347 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_348 = 348 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_349 = 349 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_350 = 350 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_351 = 351 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_352 = 352 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_353 = 353 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_354 = 354 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_355 = 355 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_356 = 356 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_357 = 357 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_358 = 358 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_359 = 359 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_360 = 360 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_361 = 361 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_362 = 362 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_363 = 363 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_364 = 364 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_365 = 365 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_366 = 366 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_367 = 367 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_368 = 368 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_369 = 369 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_370 = 370 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_371 = 371 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_372 = 372 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_373 = 373 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_374 = 374 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_375 = 375 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_376 = 376 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_377 = 377 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_378 = 378 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_379 = 379 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_380 = 380 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_381 = 381 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_382 = 382 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_383 = 383 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_384 = 384 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_385 = 385 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_386 = 386 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_387 = 387 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_388 = 388 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_389 = 389 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_390 = 390 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_391 = 391 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_392 = 392 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_393 = 393 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_394 = 394 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_395 = 395 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_396 = 396 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_397 = 397 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_398 = 398 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_399 = 399 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_400 = 400 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_401 = 401 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_402 = 402 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_403 = 403 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_404 = 404 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_405 = 405 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_406 = 406 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_407 = 407 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_408 = 408 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_409 = 409 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_410 = 410 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_411 = 411 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_412 = 412 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_413 = 413 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_414 = 414 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_415 = 415 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_416 = 416 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_417 = 417 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_418 = 418 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_419 = 419 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_420 = 420 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_421 = 421 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_422 = 422 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_423 = 423 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_424 = 424 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_425 = 425 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_426 = 426 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_427 = 427 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_428 = 428 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_429 = 429 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_430 = 430 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_431 = 431 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_432 = 432 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_433 = 433 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_434 = 434 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_435 = 435 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_436 = 436 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_437 = 437 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_438 = 438 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_439 = 439 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_440 = 440 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_441 = 441 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_442 = 442 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_443 = 443 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_444 = 444 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_445 = 445 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_446 = 446 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_447 = 447 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_448 = 448 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_449 = 449 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_450 = 450 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_451 = 451 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_452 = 452 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_453 = 453 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_454 = 454 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_455 = 455 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_456 = 456 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_457 = 457 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_458 = 458 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_459 = 459 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_460 = 460 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_461 = 461 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_462 = 462 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_463 = 463 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_464 = 464 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_465 = 465 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_466 = 466 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_467 = 467 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_468 = 468 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_469 = 469 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_470 = 470 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_471 = 471 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_472 = 472 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_473 = 473 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_474 = 474 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_475 = 475 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_476 = 476 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_477 = 477 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_478 = 478 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_479 = 479 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_480 = 480 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_481 = 481 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_482 = 482 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_483 = 483 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_484 = 484 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_485 = 485 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_486 = 486 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_487 = 487 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_488 = 488 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_489 = 489 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_490 = 490 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_491 = 491 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_492 = 492 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_493 = 493 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_494 = 494 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_495 = 495 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_496 = 496 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_497 = 497 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_498 = 498 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_499 = 499 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_500 = 500 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_501 = 501 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_502 = 502 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_503 = 503 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_504 = 504 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_505 = 505 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_506 = 506 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_507 = 507 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_508 = 508 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_509 = 509 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_510 = 510 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_511 = 511 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_512 = 512 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_513 = 513 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_514 = 514 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_515 = 515 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_516 = 516 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_517 = 517 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_518 = 518 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_519 = 519 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_520 = 520 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_521 = 521 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_522 = 522 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_523 = 523 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_524 = 524 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_525 = 525 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_526 = 526 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_527 = 527 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_528 = 528 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_529 = 529 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_530 = 530 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_531 = 531 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_532 = 532 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_533 = 533 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_534 = 534 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_535 = 535 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_536 = 536 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_537 = 537 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_538 = 538 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_539 = 539 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_540 = 540 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_541 = 541 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_542 = 542 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_543 = 543 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_544 = 544 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_545 = 545 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_546 = 546 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_547 = 547 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_548 = 548 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_549 = 549 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_550 = 550 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_551 = 551 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_552 = 552 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_553 = 553 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_554 = 554 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_555 = 555 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_556 = 556 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_557 = 557 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_558 = 558 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_559 = 559 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_560 = 560 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_561 = 561 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_562 = 562 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_563 = 563 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_564 = 564 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_565 = 565 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_566 = 566 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_567 = 567 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_568 = 568 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_569 = 569 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_570 = 570 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_571 = 571 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_572 = 572 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_573 = 573 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_574 = 574 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_575 = 575 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_576 = 576 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_577 = 577 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_578 = 578 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_579 = 579 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_580 = 580 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_581 = 581 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_582 = 582 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_583 = 583 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_584 = 584 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_585 = 585 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_586 = 586 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_587 = 587 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_588 = 588 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_589 = 589 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_590 = 590 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_591 = 591 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_592 = 592 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_593 = 593 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_594 = 594 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_595 = 595 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_596 = 596 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_597 = 597 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_598 = 598 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_599 = 599 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_600 = 600 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_601 = 601 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_602 = 602 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_603 = 603 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_604 = 604 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_605 = 605 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_606 = 606 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_607 = 607 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_608 = 608 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_609 = 609 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_610 = 610 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_611 = 611 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_612 = 612 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_613 = 613 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_614 = 614 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_615 = 615 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_616 = 616 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_617 = 617 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_618 = 618 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_619 = 619 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_620 = 620 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_621 = 621 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_622 = 622 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_623 = 623 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_624 = 624 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_625 = 625 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_626 = 626 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_627 = 627 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_628 = 628 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_629 = 629 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_630 = 630 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_631 = 631 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_632 = 632 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_633 = 633 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_634 = 634 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_635 = 635 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_636 = 636 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_637 = 637 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_638 = 638 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_639 = 639 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_640 = 640 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_641 = 641 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_642 = 642 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_643 = 643 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_644 = 644 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_645 = 645 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_646 = 646 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_647 = 647 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_648 = 648 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_649 = 649 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_650 = 650 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_651 = 651 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_652 = 652 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_653 = 653 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_654 = 654 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_655 = 655 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_656 = 656 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_657 = 657 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_658 = 658 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_659 = 659 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_660 = 660 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_661 = 661 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_662 = 662 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_663 = 663 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_664 = 664 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_665 = 665 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_666 = 666 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_667 = 667 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_668 = 668 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_669 = 669 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_670 = 670 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_671 = 671 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_672 = 672 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_673 = 673 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_674 = 674 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_675 = 675 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_676 = 676 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_677 = 677 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_678 = 678 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_679 = 679 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_680 = 680 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_681 = 681 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_682 = 682 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_683 = 683 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_684 = 684 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_685 = 685 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_686 = 686 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_687 = 687 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_688 = 688 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_689 = 689 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_690 = 690 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_691 = 691 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_692 = 692 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_693 = 693 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_694 = 694 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_695 = 695 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_696 = 696 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_697 = 697 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_698 = 698 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_699 = 699 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_700 = 700 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_701 = 701 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_702 = 702 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_703 = 703 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_704 = 704 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_705 = 705 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_706 = 706 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_707 = 707 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_708 = 708 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_709 = 709 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_710 = 710 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_711 = 711 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_712 = 712 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_713 = 713 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_714 = 714 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_715 = 715 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_716 = 716 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_717 = 717 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_718 = 718 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_719 = 719 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_720 = 720 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_721 = 721 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_722 = 722 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_723 = 723 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_724 = 724 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_725 = 725 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_726 = 726 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_727 = 727 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_728 = 728 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_729 = 729 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_730 = 730 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_731 = 731 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_732 = 732 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_733 = 733 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_734 = 734 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_735 = 735 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_736 = 736 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_737 = 737 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_738 = 738 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_739 = 739 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_740 = 740 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_741 = 741 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_742 = 742 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_743 = 743 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_744 = 744 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_745 = 745 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_746 = 746 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_747 = 747 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_748 = 748 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_749 = 749 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_750 = 750 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_751 = 751 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_752 = 752 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_753 = 753 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_754 = 754 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_755 = 755 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_756 = 756 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_757 = 757 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_758 = 758 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_759 = 759 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_760 = 760 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_761 = 761 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_762 = 762 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_763 = 763 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_764 = 764 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_765 = 765 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_766 = 766 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_767 = 767 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_768 = 768 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_769 = 769 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_770 = 770 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_771 = 771 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_772 = 772 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_773 = 773 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_774 = 774 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_775 = 775 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_776 = 776 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_777 = 777 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_778 = 778 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_779 = 779 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_780 = 780 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_781 = 781 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_782 = 782 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_783 = 783 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_784 = 784 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_785 = 785 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_786 = 786 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_787 = 787 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_788 = 788 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_789 = 789 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_790 = 790 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_791 = 791 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_792 = 792 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_793 = 793 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_794 = 794 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_795 = 795 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_796 = 796 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_797 = 797 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_798 = 798 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_799 = 799 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_800 = 800 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_801 = 801 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_802 = 802 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_803 = 803 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_804 = 804 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_805 = 805 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_806 = 806 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_807 = 807 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_808 = 808 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_809 = 809 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_810 = 810 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_811 = 811 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_812 = 812 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_813 = 813 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_814 = 814 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_815 = 815 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_816 = 816 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_817 = 817 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_818 = 818 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_819 = 819 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_820 = 820 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_821 = 821 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_822 = 822 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_823 = 823 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_824 = 824 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_825 = 825 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_826 = 826 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_827 = 827 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_828 = 828 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_829 = 829 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_830 = 830 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_831 = 831 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_832 = 832 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_833 = 833 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_834 = 834 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_835 = 835 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_836 = 836 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_837 = 837 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_838 = 838 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_839 = 839 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_840 = 840 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_841 = 841 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_842 = 842 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_843 = 843 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_844 = 844 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_845 = 845 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_846 = 846 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_847 = 847 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_848 = 848 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_849 = 849 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_850 = 850 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_851 = 851 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_852 = 852 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_853 = 853 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_854 = 854 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_855 = 855 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_856 = 856 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_857 = 857 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_858 = 858 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_859 = 859 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_860 = 860 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_861 = 861 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_862 = 862 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_863 = 863 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_864 = 864 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_865 = 865 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_866 = 866 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_867 = 867 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_868 = 868 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_869 = 869 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_870 = 870 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_871 = 871 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_872 = 872 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_873 = 873 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_874 = 874 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_875 = 875 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_876 = 876 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_877 = 877 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_878 = 878 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_879 = 879 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_880 = 880 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_881 = 881 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_882 = 882 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_883 = 883 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_884 = 884 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_885 = 885 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_886 = 886 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_887 = 887 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_888 = 888 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_889 = 889 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_890 = 890 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_891 = 891 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_892 = 892 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_893 = 893 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_894 = 894 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_895 = 895 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_896 = 896 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_897 = 897 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_898 = 898 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_899 = 899 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_900 = 900 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_901 = 901 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_902 = 902 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_903 = 903 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_904 = 904 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_905 = 905 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_906 = 906 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_907 = 907 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_908 = 908 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_909 = 909 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_910 = 910 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_911 = 911 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_912 = 912 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_913 = 913 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_914 = 914 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_915 = 915 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_916 = 916 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_917 = 917 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_918 = 918 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_919 = 919 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_920 = 920 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_921 = 921 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_922 = 922 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_923 = 923 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_924 = 924 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_925 = 925 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_926 = 926 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_927 = 927 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_928 = 928 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_929 = 929 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_930 = 930 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_931 = 931 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_932 = 932 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_933 = 933 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_934 = 934 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_935 = 935 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_936 = 936 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_937 = 937 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_938 = 938 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_939 = 939 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_940 = 940 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_941 = 941 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_942 = 942 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_943 = 943 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_944 = 944 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_945 = 945 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_946 = 946 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_947 = 947 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_948 = 948 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_949 = 949 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_950 = 950 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_951 = 951 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_952 = 952 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_953 = 953 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_954 = 954 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_955 = 955 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_956 = 956 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_957 = 957 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_958 = 958 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_959 = 959 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_960 = 960 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_961 = 961 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_962 = 962 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_963 = 963 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_964 = 964 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_965 = 965 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_966 = 966 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_967 = 967 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_968 = 968 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_969 = 969 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_970 = 970 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_971 = 971 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_972 = 972 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_973 = 973 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_974 = 974 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_975 = 975 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_976 = 976 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_977 = 977 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_978 = 978 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_979 = 979 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_980 = 980 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_981 = 981 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_982 = 982 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_983 = 983 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_984 = 984 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_985 = 985 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_986 = 986 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_987 = 987 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_988 = 988 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_989 = 989 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_990 = 990 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_991 = 991 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_992 = 992 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_993 = 993 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_994 = 994 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_995 = 995 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_996 = 996 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_997 = 997 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_998 = 998 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_999 = 999 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_1000 = 1000 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+}
diff --git a/NorthstarDedicatedTest/include/protobuf/unittest_import.proto b/NorthstarDedicatedTest/include/protobuf/unittest_import.proto
new file mode 100644
index 00000000..8d03e388
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/unittest_import.proto
@@ -0,0 +1,73 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 which is imported by unittest.proto to test importing.
+
+syntax = "proto2";
+
+// We don't put this in a package within proto2 because we need to make sure
+// that the generated code doesn't depend on being in the proto2 namespace.
+// In test_util.h we do
+// "using namespace unittest_import = protobuf_unittest_import".
+package protobuf_unittest_import;
+
+option optimize_for = SPEED;
+option cc_enable_arenas = true;
+
+// Exercise the java_package option.
+option java_package = "com.google.protobuf.test";
+
+// Do not set a java_outer_classname here to verify that Proto2 works without
+// one.
+
+// Test public import
+import public "google/protobuf/unittest_import_public.proto";
+
+message ImportMessage {
+ optional int32 d = 1;
+}
+
+enum ImportEnum {
+ IMPORT_FOO = 7;
+ IMPORT_BAR = 8;
+ IMPORT_BAZ = 9;
+}
+
+
+// To use an enum in a map, it must has the first value as 0.
+enum ImportEnumForMap {
+ UNKNOWN = 0;
+ FOO = 1;
+ BAR = 2;
+}
diff --git a/NorthstarDedicatedTest/include/protobuf/unittest_import_lite.proto b/NorthstarDedicatedTest/include/protobuf/unittest_import_lite.proto
new file mode 100644
index 00000000..a7afa452
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/unittest_import_lite.proto
@@ -0,0 +1,52 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+//
+// This is like unittest_import.proto but with optimize_for = LITE_RUNTIME.
+
+syntax = "proto2";
+package protobuf_unittest_import;
+
+option optimize_for = LITE_RUNTIME;
+
+option java_package = "com.google.protobuf";
+
+import public "google/protobuf/unittest_import_public_lite.proto";
+
+message ImportMessageLite {
+ optional int32 d = 1;
+}
+
+enum ImportEnumLite {
+ IMPORT_LITE_FOO = 7;
+ IMPORT_LITE_BAR = 8;
+ IMPORT_LITE_BAZ = 9;
+}
diff --git a/NorthstarDedicatedTest/include/protobuf/unittest_import_public.proto b/NorthstarDedicatedTest/include/protobuf/unittest_import_public.proto
new file mode 100644
index 00000000..ffaf7736
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/unittest_import_public.proto
@@ -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.
+
+// Author: liujisi@google.com (Pherl Liu)
+
+syntax = "proto2";
+
+package protobuf_unittest_import;
+
+option java_package = "com.google.protobuf.test";
+
+message PublicImportMessage {
+ optional int32 e = 1;
+}
diff --git a/NorthstarDedicatedTest/include/protobuf/unittest_import_public_lite.proto b/NorthstarDedicatedTest/include/protobuf/unittest_import_public_lite.proto
new file mode 100644
index 00000000..33549c22
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/unittest_import_public_lite.proto
@@ -0,0 +1,43 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: liujisi@google.com (Pherl Liu)
+
+syntax = "proto2";
+
+package protobuf_unittest_import;
+
+option optimize_for = LITE_RUNTIME;
+
+option java_package = "com.google.protobuf";
+
+message PublicImportMessageLite {
+ optional int32 e = 1;
+}
diff --git a/NorthstarDedicatedTest/include/protobuf/unittest_lazy_dependencies.proto b/NorthstarDedicatedTest/include/protobuf/unittest_lazy_dependencies.proto
new file mode 100644
index 00000000..2f5efd2a
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/unittest_lazy_dependencies.proto
@@ -0,0 +1,75 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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: trafacz@google.com (Todd Rafacz)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// A proto file we will use for unit testing.
+
+syntax = "proto2";
+
+import "google/protobuf/unittest_lazy_dependencies_custom_option.proto";
+
+// Some generic_services option(s) added automatically.
+// See: http://go/proto2-generic-services-default
+option cc_generic_services = true; // auto-added
+option java_generic_services = true; // auto-added
+option py_generic_services = true; // auto-added
+option cc_enable_arenas = true;
+
+// We don't put this in a package within proto2 because we need to make sure
+// that the generated code doesn't depend on being in the proto2 namespace.
+// In test_util.h we do "using namespace unittest = protobuf_unittest".
+package protobuf_unittest.lazy_imports;
+
+// Protos optimized for SPEED use a strict superset of the generated code
+// of equivalent ones optimized for CODE_SIZE, so we should optimize all our
+// tests for speed unless explicitly testing code size optimization.
+option optimize_for = SPEED;
+
+option java_outer_classname = "UnittestLazyImportsProto";
+
+// The following are used to test that the proto file
+// with the definition of the following field types is
+// not built when this proto file is built. Then test
+// that calling message_type() etc will build the correct
+// descriptor lazily and return it.
+
+message ImportedMessage {
+ optional LazyMessage lazy_message = 1;
+}
+
+message MessageCustomOption {
+}
+
+message MessageCustomOption2 {
+ option (lazy_enum_option) = LAZY_ENUM_0;
+}
diff --git a/NorthstarDedicatedTest/include/protobuf/unittest_lazy_dependencies_custom_option.proto b/NorthstarDedicatedTest/include/protobuf/unittest_lazy_dependencies_custom_option.proto
new file mode 100644
index 00000000..22438257
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/unittest_lazy_dependencies_custom_option.proto
@@ -0,0 +1,67 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: trafacz@google.com (Todd Rafacz)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// A proto file we will use for unit testing.
+
+syntax = "proto2";
+
+import "google/protobuf/unittest_lazy_dependencies_enum.proto";
+import "google/protobuf/descriptor.proto";
+
+// Some generic_services option(s) added automatically.
+// See: http://go/proto2-generic-services-default
+option cc_generic_services = true; // auto-added
+option java_generic_services = true; // auto-added
+option py_generic_services = true; // auto-added
+option cc_enable_arenas = true;
+
+// We don't put this in a package within proto2 because we need to make sure
+// that the generated code doesn't depend on being in the proto2 namespace.
+// In test_util.h we do "using namespace unittest = protobuf_unittest".
+package protobuf_unittest.lazy_imports;
+
+// Protos optimized for SPEED use a strict superset of the generated code
+// of equivalent ones optimized for CODE_SIZE, so we should optimize all our
+// tests for speed unless explicitly testing code size optimization.
+option optimize_for = SPEED;
+
+option java_outer_classname = "UnittestLazyImportsCustomOptionProto";
+
+message LazyMessage {
+ optional int32 a = 1;
+}
+
+extend google.protobuf.MessageOptions {
+ optional LazyEnum lazy_enum_option = 138596335 [default = LAZY_ENUM_1];
+}
diff --git a/NorthstarDedicatedTest/include/protobuf/unittest_lazy_dependencies_enum.proto b/NorthstarDedicatedTest/include/protobuf/unittest_lazy_dependencies_enum.proto
new file mode 100644
index 00000000..9be64d85
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/unittest_lazy_dependencies_enum.proto
@@ -0,0 +1,61 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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: trafacz@google.com (Todd Rafacz)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// A proto file we will use for unit testing.
+
+syntax = "proto2";
+
+// Some generic_services option(s) added automatically.
+// See: http://go/proto2-generic-services-default
+option cc_generic_services = true; // auto-added
+option java_generic_services = true; // auto-added
+option py_generic_services = true; // auto-added
+option cc_enable_arenas = true;
+
+// We don't put this in a package within proto2 because we need to make sure
+// that the generated code doesn't depend on being in the proto2 namespace.
+// In test_util.h we do "using namespace unittest = protobuf_unittest".
+package protobuf_unittest.lazy_imports;
+
+// Protos optimized for SPEED use a strict superset of the generated code
+// of equivalent ones optimized for CODE_SIZE, so we should optimize all our
+// tests for speed unless explicitly testing code size optimization.
+option optimize_for = SPEED;
+
+option java_outer_classname = "UnittestLazyImportsEnumProto";
+
+enum LazyEnum {
+ LAZY_ENUM_0 = 0;
+ LAZY_ENUM_1 = 1;
+}
diff --git a/NorthstarDedicatedTest/include/protobuf/unittest_lite.proto b/NorthstarDedicatedTest/include/protobuf/unittest_lite.proto
new file mode 100644
index 00000000..92282a6f
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/unittest_lite.proto
@@ -0,0 +1,501 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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)
+//
+// This is like unittest.proto but with optimize_for = LITE_RUNTIME.
+
+syntax = "proto2";
+
+package protobuf_unittest;
+
+import "google/protobuf/unittest_import_lite.proto";
+
+option cc_enable_arenas = true;
+option optimize_for = LITE_RUNTIME;
+option java_package = "com.google.protobuf";
+
+// Same as TestAllTypes but with the lite runtime.
+message TestAllTypesLite {
+ message NestedMessage {
+ optional int32 bb = 1;
+ optional int64 cc = 2;
+ }
+
+ message NestedMessage2 {
+ optional int32 dd = 1;
+ }
+
+ enum NestedEnum {
+ FOO = 1;
+ BAR = 2;
+ BAZ = 3;
+ }
+
+ // Singular
+ optional int32 optional_int32 = 1;
+ optional int64 optional_int64 = 2;
+ optional uint32 optional_uint32 = 3;
+ optional uint64 optional_uint64 = 4;
+ optional sint32 optional_sint32 = 5;
+ optional sint64 optional_sint64 = 6;
+ optional fixed32 optional_fixed32 = 7;
+ optional fixed64 optional_fixed64 = 8;
+ optional sfixed32 optional_sfixed32 = 9;
+ optional sfixed64 optional_sfixed64 = 10;
+ optional float optional_float = 11;
+ optional double optional_double = 12;
+ optional bool optional_bool = 13;
+ optional string optional_string = 14;
+ optional bytes optional_bytes = 15;
+
+ optional group OptionalGroup = 16 {
+ optional int32 a = 17;
+ }
+
+ optional NestedMessage optional_nested_message = 18;
+ optional ForeignMessageLite optional_foreign_message = 19;
+ optional protobuf_unittest_import.ImportMessageLite optional_import_message =
+ 20;
+
+ optional NestedEnum optional_nested_enum = 21;
+ optional ForeignEnumLite optional_foreign_enum = 22;
+ optional protobuf_unittest_import.ImportEnumLite optional_import_enum = 23;
+
+ optional string optional_string_piece = 24 [ctype = STRING_PIECE];
+ optional string optional_cord = 25 [ctype = CORD];
+
+ // Defined in unittest_import_public.proto
+ optional protobuf_unittest_import.PublicImportMessageLite
+ optional_public_import_message = 26;
+
+ optional NestedMessage optional_lazy_message = 27 [lazy = true];
+
+ // Repeated
+ repeated int32 repeated_int32 = 31;
+ repeated int64 repeated_int64 = 32;
+ repeated uint32 repeated_uint32 = 33;
+ repeated uint64 repeated_uint64 = 34;
+ repeated sint32 repeated_sint32 = 35;
+ repeated sint64 repeated_sint64 = 36;
+ repeated fixed32 repeated_fixed32 = 37;
+ repeated fixed64 repeated_fixed64 = 38;
+ repeated sfixed32 repeated_sfixed32 = 39;
+ repeated sfixed64 repeated_sfixed64 = 40;
+ repeated float repeated_float = 41;
+ repeated double repeated_double = 42;
+ repeated bool repeated_bool = 43;
+ repeated string repeated_string = 44;
+ repeated bytes repeated_bytes = 45;
+
+ repeated group RepeatedGroup = 46 {
+ optional int32 a = 47;
+ }
+
+ repeated NestedMessage repeated_nested_message = 48;
+ repeated ForeignMessageLite repeated_foreign_message = 49;
+ repeated protobuf_unittest_import.ImportMessageLite repeated_import_message =
+ 50;
+
+ repeated NestedEnum repeated_nested_enum = 51;
+ repeated ForeignEnumLite repeated_foreign_enum = 52;
+ repeated protobuf_unittest_import.ImportEnumLite repeated_import_enum = 53;
+
+ repeated string repeated_string_piece = 54 [ctype = STRING_PIECE];
+ repeated string repeated_cord = 55 [ctype = CORD];
+
+ repeated NestedMessage repeated_lazy_message = 57 [lazy = true];
+
+ // Singular with defaults
+ optional int32 default_int32 = 61 [default = 41];
+ optional int64 default_int64 = 62 [default = 42];
+ optional uint32 default_uint32 = 63 [default = 43];
+ optional uint64 default_uint64 = 64 [default = 44];
+ optional sint32 default_sint32 = 65 [default = -45];
+ optional sint64 default_sint64 = 66 [default = 46];
+ optional fixed32 default_fixed32 = 67 [default = 47];
+ optional fixed64 default_fixed64 = 68 [default = 48];
+ optional sfixed32 default_sfixed32 = 69 [default = 49];
+ optional sfixed64 default_sfixed64 = 70 [default = -50];
+ optional float default_float = 71 [default = 51.5];
+ optional double default_double = 72 [default = 52e3];
+ optional bool default_bool = 73 [default = true];
+ optional string default_string = 74 [default = "hello"];
+ optional bytes default_bytes = 75 [default = "world"];
+
+ optional NestedEnum default_nested_enum = 81 [default = BAR];
+ optional ForeignEnumLite default_foreign_enum = 82
+ [default = FOREIGN_LITE_BAR];
+ optional protobuf_unittest_import.ImportEnumLite default_import_enum = 83
+ [default = IMPORT_LITE_BAR];
+
+ optional string default_string_piece = 84
+ [ctype = STRING_PIECE, default = "abc"];
+ optional string default_cord = 85 [ctype = CORD, default = "123"];
+
+ // For oneof test
+ oneof oneof_field {
+ uint32 oneof_uint32 = 111;
+ NestedMessage oneof_nested_message = 112;
+ string oneof_string = 113;
+ bytes oneof_bytes = 114;
+ NestedMessage oneof_lazy_nested_message = 115 [lazy = true];
+ NestedMessage2 oneof_nested_message2 = 117;
+ }
+
+ // Tests toString for non-repeated fields with a list suffix
+ optional int32 deceptively_named_list = 116;
+}
+
+message ForeignMessageLite {
+ optional int32 c = 1;
+}
+
+enum ForeignEnumLite {
+ FOREIGN_LITE_FOO = 4;
+ FOREIGN_LITE_BAZ = 6;
+ FOREIGN_LITE_BAR = 5;
+}
+
+message TestPackedTypesLite {
+ repeated int32 packed_int32 = 90 [packed = true];
+ repeated int64 packed_int64 = 91 [packed = true];
+ repeated uint32 packed_uint32 = 92 [packed = true];
+ repeated uint64 packed_uint64 = 93 [packed = true];
+ repeated sint32 packed_sint32 = 94 [packed = true];
+ repeated sint64 packed_sint64 = 95 [packed = true];
+ repeated fixed32 packed_fixed32 = 96 [packed = true];
+ repeated fixed64 packed_fixed64 = 97 [packed = true];
+ repeated sfixed32 packed_sfixed32 = 98 [packed = true];
+ repeated sfixed64 packed_sfixed64 = 99 [packed = true];
+ repeated float packed_float = 100 [packed = true];
+ repeated double packed_double = 101 [packed = true];
+ repeated bool packed_bool = 102 [packed = true];
+ repeated ForeignEnumLite packed_enum = 103 [packed = true];
+}
+
+message TestAllExtensionsLite {
+ extensions 1 to max;
+}
+
+extend TestAllExtensionsLite {
+ // Singular
+ optional int32 optional_int32_extension_lite = 1;
+ optional int64 optional_int64_extension_lite = 2;
+ optional uint32 optional_uint32_extension_lite = 3;
+ optional uint64 optional_uint64_extension_lite = 4;
+ optional sint32 optional_sint32_extension_lite = 5;
+ optional sint64 optional_sint64_extension_lite = 6;
+ optional fixed32 optional_fixed32_extension_lite = 7;
+ optional fixed64 optional_fixed64_extension_lite = 8;
+ optional sfixed32 optional_sfixed32_extension_lite = 9;
+ optional sfixed64 optional_sfixed64_extension_lite = 10;
+ optional float optional_float_extension_lite = 11;
+ optional double optional_double_extension_lite = 12;
+ optional bool optional_bool_extension_lite = 13;
+ optional string optional_string_extension_lite = 14;
+ optional bytes optional_bytes_extension_lite = 15;
+
+ optional group OptionalGroup_extension_lite = 16 {
+ optional int32 a = 17;
+ }
+
+ optional TestAllTypesLite.NestedMessage
+ optional_nested_message_extension_lite = 18;
+ optional ForeignMessageLite optional_foreign_message_extension_lite = 19;
+ optional protobuf_unittest_import.ImportMessageLite
+ optional_import_message_extension_lite = 20;
+
+ optional TestAllTypesLite.NestedEnum optional_nested_enum_extension_lite = 21;
+ optional ForeignEnumLite optional_foreign_enum_extension_lite = 22;
+ optional protobuf_unittest_import.ImportEnumLite
+ optional_import_enum_extension_lite = 23;
+
+ optional string optional_string_piece_extension_lite = 24
+ [ctype = STRING_PIECE];
+ optional string optional_cord_extension_lite = 25 [ctype = CORD];
+
+ optional protobuf_unittest_import.PublicImportMessageLite
+ optional_public_import_message_extension_lite = 26;
+
+ optional TestAllTypesLite.NestedMessage optional_lazy_message_extension_lite =
+ 27 [lazy = true];
+
+ // Repeated
+ repeated int32 repeated_int32_extension_lite = 31;
+ repeated int64 repeated_int64_extension_lite = 32;
+ repeated uint32 repeated_uint32_extension_lite = 33;
+ repeated uint64 repeated_uint64_extension_lite = 34;
+ repeated sint32 repeated_sint32_extension_lite = 35;
+ repeated sint64 repeated_sint64_extension_lite = 36;
+ repeated fixed32 repeated_fixed32_extension_lite = 37;
+ repeated fixed64 repeated_fixed64_extension_lite = 38;
+ repeated sfixed32 repeated_sfixed32_extension_lite = 39;
+ repeated sfixed64 repeated_sfixed64_extension_lite = 40;
+ repeated float repeated_float_extension_lite = 41;
+ repeated double repeated_double_extension_lite = 42;
+ repeated bool repeated_bool_extension_lite = 43;
+ repeated string repeated_string_extension_lite = 44;
+ repeated bytes repeated_bytes_extension_lite = 45;
+
+ repeated group RepeatedGroup_extension_lite = 46 {
+ optional int32 a = 47;
+ }
+
+ repeated TestAllTypesLite.NestedMessage
+ repeated_nested_message_extension_lite = 48;
+ repeated ForeignMessageLite repeated_foreign_message_extension_lite = 49;
+ repeated protobuf_unittest_import.ImportMessageLite
+ repeated_import_message_extension_lite = 50;
+
+ repeated TestAllTypesLite.NestedEnum repeated_nested_enum_extension_lite = 51;
+ repeated ForeignEnumLite repeated_foreign_enum_extension_lite = 52;
+ repeated protobuf_unittest_import.ImportEnumLite
+ repeated_import_enum_extension_lite = 53;
+
+ repeated string repeated_string_piece_extension_lite = 54
+ [ctype = STRING_PIECE];
+ repeated string repeated_cord_extension_lite = 55 [ctype = CORD];
+
+ repeated TestAllTypesLite.NestedMessage repeated_lazy_message_extension_lite =
+ 57 [lazy = true];
+
+ // Singular with defaults
+ optional int32 default_int32_extension_lite = 61 [default = 41];
+ optional int64 default_int64_extension_lite = 62 [default = 42];
+ optional uint32 default_uint32_extension_lite = 63 [default = 43];
+ optional uint64 default_uint64_extension_lite = 64 [default = 44];
+ optional sint32 default_sint32_extension_lite = 65 [default = -45];
+ optional sint64 default_sint64_extension_lite = 66 [default = 46];
+ optional fixed32 default_fixed32_extension_lite = 67 [default = 47];
+ optional fixed64 default_fixed64_extension_lite = 68 [default = 48];
+ optional sfixed32 default_sfixed32_extension_lite = 69 [default = 49];
+ optional sfixed64 default_sfixed64_extension_lite = 70 [default = -50];
+ optional float default_float_extension_lite = 71 [default = 51.5];
+ optional double default_double_extension_lite = 72 [default = 52e3];
+ optional bool default_bool_extension_lite = 73 [default = true];
+ optional string default_string_extension_lite = 74 [default = "hello"];
+ optional bytes default_bytes_extension_lite = 75 [default = "world"];
+
+ optional TestAllTypesLite.NestedEnum default_nested_enum_extension_lite = 81
+ [default = BAR];
+ optional ForeignEnumLite default_foreign_enum_extension_lite = 82
+ [default = FOREIGN_LITE_BAR];
+ optional protobuf_unittest_import.ImportEnumLite
+ default_import_enum_extension_lite = 83 [default = IMPORT_LITE_BAR];
+
+ optional string default_string_piece_extension_lite = 84
+ [ctype = STRING_PIECE, default = "abc"];
+ optional string default_cord_extension_lite = 85
+ [ctype = CORD, default = "123"];
+
+ // For oneof test
+ optional uint32 oneof_uint32_extension_lite = 111;
+ optional TestAllTypesLite.NestedMessage oneof_nested_message_extension_lite =
+ 112;
+ optional string oneof_string_extension_lite = 113;
+ optional bytes oneof_bytes_extension_lite = 114;
+}
+
+message TestPackedExtensionsLite {
+ extensions 1 to max;
+}
+
+extend TestPackedExtensionsLite {
+ repeated int32 packed_int32_extension_lite = 90 [packed = true];
+ repeated int64 packed_int64_extension_lite = 91 [packed = true];
+ repeated uint32 packed_uint32_extension_lite = 92 [packed = true];
+ repeated uint64 packed_uint64_extension_lite = 93 [packed = true];
+ repeated sint32 packed_sint32_extension_lite = 94 [packed = true];
+ repeated sint64 packed_sint64_extension_lite = 95 [packed = true];
+ repeated fixed32 packed_fixed32_extension_lite = 96 [packed = true];
+ repeated fixed64 packed_fixed64_extension_lite = 97 [packed = true];
+ repeated sfixed32 packed_sfixed32_extension_lite = 98 [packed = true];
+ repeated sfixed64 packed_sfixed64_extension_lite = 99 [packed = true];
+ repeated float packed_float_extension_lite = 100 [packed = true];
+ repeated double packed_double_extension_lite = 101 [packed = true];
+ repeated bool packed_bool_extension_lite = 102 [packed = true];
+ repeated ForeignEnumLite packed_enum_extension_lite = 103 [packed = true];
+}
+
+message TestNestedExtensionLite {
+ extend TestAllExtensionsLite {
+ optional int32 nested_extension = 12345;
+ }
+}
+
+// Test that deprecated fields work. We only verify that they compile (at one
+// point this failed).
+message TestDeprecatedLite {
+ optional int32 deprecated_field = 1 [deprecated = true];
+ required int32 deprecated_field2 = 2 [deprecated = true];
+ optional string deprecated_field3 = 3 [deprecated = true];
+ optional TestDeprecatedLite deprecated_field4 = 4 [deprecated = true];
+}
+
+// See the comments of the same type in unittest.proto.
+message TestParsingMergeLite {
+ message RepeatedFieldsGenerator {
+ repeated TestAllTypesLite field1 = 1;
+ repeated TestAllTypesLite field2 = 2;
+ repeated TestAllTypesLite field3 = 3;
+ repeated group Group1 = 10 {
+ optional TestAllTypesLite field1 = 11;
+ }
+ repeated group Group2 = 20 {
+ optional TestAllTypesLite field1 = 21;
+ }
+ repeated TestAllTypesLite ext1 = 1000;
+ repeated TestAllTypesLite ext2 = 1001;
+ }
+ required TestAllTypesLite required_all_types = 1;
+ optional TestAllTypesLite optional_all_types = 2;
+ repeated TestAllTypesLite repeated_all_types = 3;
+ optional group OptionalGroup = 10 {
+ optional TestAllTypesLite optional_group_all_types = 11;
+ }
+ repeated group RepeatedGroup = 20 {
+ optional TestAllTypesLite repeated_group_all_types = 21;
+ }
+ extensions 1000 to max;
+ extend TestParsingMergeLite {
+ optional TestAllTypesLite optional_ext = 1000;
+ repeated TestAllTypesLite repeated_ext = 1001;
+ }
+}
+
+// TestEmptyMessageLite is used to test unknown fields support in lite mode.
+message TestEmptyMessageLite {}
+
+// Like above, but declare all field numbers as potential extensions. No
+// actual extensions should ever be defined for this type.
+message TestEmptyMessageWithExtensionsLite {
+ extensions 1 to max;
+}
+
+enum V1EnumLite { V1_FIRST = 1; }
+
+enum V2EnumLite {
+ V2_FIRST = 1;
+ V2_SECOND = 2;
+}
+
+message V1MessageLite {
+ required int32 int_field = 1;
+ optional V1EnumLite enum_field = 2 [default = V1_FIRST];
+}
+
+message V2MessageLite {
+ required int32 int_field = 1;
+ optional V2EnumLite enum_field = 2 [default = V2_FIRST];
+}
+
+message TestHugeFieldNumbersLite {
+ optional int32 optional_int32 = 536870000;
+ optional int32 fixed_32 = 536870001;
+ repeated int32 repeated_int32 = 536870002 [packed = false];
+ repeated int32 packed_int32 = 536870003 [packed = true];
+
+ optional ForeignEnumLite optional_enum = 536870004;
+ optional string optional_string = 536870005;
+ optional bytes optional_bytes = 536870006;
+ optional ForeignMessageLite optional_message = 536870007;
+
+ optional group OptionalGroup = 536870008 {
+ optional int32 group_a = 536870009;
+ }
+
+ map<string, string> string_string_map = 536870010;
+
+ oneof oneof_field {
+ uint32 oneof_uint32 = 536870011;
+ TestAllTypesLite oneof_test_all_types = 536870012;
+ string oneof_string = 536870013;
+ bytes oneof_bytes = 536870014;
+ }
+
+ extensions 536860000 to 536869999;
+}
+
+extend TestHugeFieldNumbersLite {
+ optional TestAllTypesLite test_all_types_lite = 536860000;
+}
+
+message TestOneofParsingLite {
+ oneof oneof_field {
+ int32 oneof_int32 = 1;
+ TestAllTypesLite oneof_submessage = 2;
+ string oneof_string = 3;
+ bytes oneof_bytes = 4 [default = "default bytes"];
+ string oneof_string_cord = 5 [ctype = CORD, default = "default Cord"];
+ bytes oneof_bytes_cord = 6 [ctype = CORD];
+ string oneof_string_string_piece = 7 [ctype = STRING_PIECE];
+ bytes oneof_bytes_string_piece = 8
+ [ctype = STRING_PIECE, default = "default StringPiece"];
+ V2EnumLite oneof_enum = 9;
+ }
+}
+
+// The following four messages are set up to test for wire compatibility between
+// packed and non-packed repeated fields. We use the field number 2048, because
+// that is large enough to require a 3-byte varint for the tag.
+message PackedInt32 {
+ repeated int32 repeated_int32 = 2048 [packed = true];
+}
+
+message NonPackedInt32 {
+ repeated int32 repeated_int32 = 2048;
+}
+
+message PackedFixed32 {
+ repeated fixed32 repeated_fixed32 = 2048 [packed = true];
+}
+
+message NonPackedFixed32 {
+ repeated fixed32 repeated_fixed32 = 2048;
+}
+
+// Test an enum that has multiple values with the same number.
+message DupEnum {
+ enum TestEnumWithDupValueLite {
+ option allow_alias = true;
+
+ FOO1 = 1;
+ BAR1 = 2;
+ BAZ = 3;
+ FOO2 = 1;
+ BAR2 = 2;
+ }
+}
+
+message RecursiveMessage {
+ optional RecursiveMessage recurse = 1;
+ optional bytes payload = 2;
+}
diff --git a/NorthstarDedicatedTest/include/protobuf/unittest_lite_imports_nonlite.proto b/NorthstarDedicatedTest/include/protobuf/unittest_lite_imports_nonlite.proto
new file mode 100644
index 00000000..8a470160
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/unittest_lite_imports_nonlite.proto
@@ -0,0 +1,47 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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)
+//
+// Tests that a "lite" message can import a regular message.
+
+syntax = "proto2";
+package protobuf_unittest;
+
+import "google/protobuf/unittest.proto";
+
+option optimize_for = LITE_RUNTIME;
+
+message TestLiteImportsNonlite {
+ optional TestAllTypes message = 1;
+
+ // Verifies that transitive required fields generates valid code.
+ optional TestRequired message_with_required = 2;
+}
diff --git a/NorthstarDedicatedTest/include/protobuf/unittest_mset.proto b/NorthstarDedicatedTest/include/protobuf/unittest_mset.proto
new file mode 100644
index 00000000..4e7a8c51
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/unittest_mset.proto
@@ -0,0 +1,84 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 is similar to unittest_mset_wire_format.proto, but does not
+// have a TestMessageSet, so it can be downgraded to proto1.
+
+syntax = "proto2";
+
+import "google/protobuf/unittest_mset_wire_format.proto";
+
+package protobuf_unittest;
+
+option cc_enable_arenas = true;
+option optimize_for = SPEED;
+
+message TestMessageSetContainer {
+ optional proto2_wireformat_unittest.TestMessageSet message_set = 1;
+}
+
+message TestMessageSetExtension1 {
+ extend proto2_wireformat_unittest.TestMessageSet {
+ optional TestMessageSetExtension1 message_set_extension = 1545008;
+ }
+ optional int32 i = 15;
+ optional proto2_wireformat_unittest.TestMessageSet recursive = 16;
+ optional string test_aliasing = 17 [ctype = STRING_PIECE];
+}
+
+message TestMessageSetExtension2 {
+ extend proto2_wireformat_unittest.TestMessageSet {
+ optional TestMessageSetExtension2 message_set_extension = 1547769;
+ }
+ optional string str = 25;
+}
+
+// This message was used to generate
+// //net/proto2/python/internal/testdata/message_set_message, but is commented
+// out since it must not actually exist in code, to simulate an "unknown"
+// extension.
+// message TestMessageSetUnknownExtension {
+// extend TestMessageSet {
+// optional TestMessageSetUnknownExtension message_set_extension = 56141421;
+// }
+// optional int64 a = 1;
+// }
+
+// MessageSet wire format is equivalent to this.
+message RawMessageSet {
+ repeated group Item = 1 {
+ required int32 type_id = 2;
+ required bytes message = 3;
+ }
+}
diff --git a/NorthstarDedicatedTest/include/protobuf/unittest_mset_wire_format.proto b/NorthstarDedicatedTest/include/protobuf/unittest_mset_wire_format.proto
new file mode 100644
index 00000000..04e4352e
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/unittest_mset_wire_format.proto
@@ -0,0 +1,52 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// This file contains messages for testing message_set_wire_format.
+
+syntax = "proto2";
+package proto2_wireformat_unittest;
+
+option cc_enable_arenas = true;
+option optimize_for = SPEED;
+option csharp_namespace = "Google.ProtocolBuffers.TestProtos";
+
+// A message with message_set_wire_format.
+message TestMessageSet {
+ option message_set_wire_format = true;
+ extensions 4 to max;
+}
+
+message TestMessageSetWireFormatContainer {
+ optional TestMessageSet message_set = 1;
+}
diff --git a/NorthstarDedicatedTest/include/protobuf/unittest_no_field_presence.proto b/NorthstarDedicatedTest/include/protobuf/unittest_no_field_presence.proto
new file mode 100644
index 00000000..994afff4
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/unittest_no_field_presence.proto
@@ -0,0 +1,138 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 proto file used to test a message type with no explicit field presence.
+
+syntax = "proto3";
+
+// We want to test embedded proto2 messages, so include some proto2 types.
+import "google/protobuf/unittest.proto";
+
+package proto2_nofieldpresence_unittest;
+
+// This proto includes every type of field in both singular and repeated
+// forms.
+message TestAllTypes {
+ message NestedMessage {
+ int32 bb = 1;
+ }
+
+ enum NestedEnum {
+ FOO = 0;
+ BAR = 1;
+ BAZ = 2;
+ }
+
+ // Singular
+ // TODO: remove 'optional' labels as soon as CL 69188077 is LGTM'd to make
+ // 'optional' optional.
+ int32 optional_int32 = 1;
+ int64 optional_int64 = 2;
+ uint32 optional_uint32 = 3;
+ uint64 optional_uint64 = 4;
+ sint32 optional_sint32 = 5;
+ sint64 optional_sint64 = 6;
+ fixed32 optional_fixed32 = 7;
+ fixed64 optional_fixed64 = 8;
+ sfixed32 optional_sfixed32 = 9;
+ sfixed64 optional_sfixed64 = 10;
+ float optional_float = 11;
+ double optional_double = 12;
+ bool optional_bool = 13;
+ string optional_string = 14;
+ bytes optional_bytes = 15;
+
+ NestedMessage optional_nested_message = 18;
+ ForeignMessage optional_foreign_message = 19;
+ protobuf_unittest.TestAllTypes optional_proto2_message = 20;
+
+ NestedEnum optional_nested_enum = 21;
+ ForeignEnum optional_foreign_enum = 22;
+ // N.B.: proto2-enum-type fields not allowed, because their default values
+ // might not be zero.
+ //optional protobuf_unittest.ForeignEnum optional_proto2_enum = 23;
+
+ string optional_string_piece = 24 [ctype=STRING_PIECE];
+ string optional_cord = 25 [ctype=CORD];
+
+ NestedMessage optional_lazy_message = 30 [lazy=true];
+
+ // Repeated
+ repeated int32 repeated_int32 = 31;
+ repeated int64 repeated_int64 = 32;
+ repeated uint32 repeated_uint32 = 33;
+ repeated uint64 repeated_uint64 = 34;
+ repeated sint32 repeated_sint32 = 35;
+ repeated sint64 repeated_sint64 = 36;
+ repeated fixed32 repeated_fixed32 = 37;
+ repeated fixed64 repeated_fixed64 = 38;
+ repeated sfixed32 repeated_sfixed32 = 39;
+ repeated sfixed64 repeated_sfixed64 = 40;
+ repeated float repeated_float = 41;
+ repeated double repeated_double = 42;
+ repeated bool repeated_bool = 43;
+ repeated string repeated_string = 44;
+ repeated bytes repeated_bytes = 45;
+
+ repeated NestedMessage repeated_nested_message = 48;
+ repeated ForeignMessage repeated_foreign_message = 49;
+ repeated protobuf_unittest.TestAllTypes repeated_proto2_message = 50;
+
+ repeated NestedEnum repeated_nested_enum = 51;
+ repeated ForeignEnum repeated_foreign_enum = 52;
+
+ repeated string repeated_string_piece = 54 [ctype=STRING_PIECE];
+ repeated string repeated_cord = 55 [ctype=CORD];
+
+ repeated NestedMessage repeated_lazy_message = 57 [lazy=true];
+
+ oneof oneof_field {
+ uint32 oneof_uint32 = 111;
+ NestedMessage oneof_nested_message = 112;
+ string oneof_string = 113;
+ NestedEnum oneof_enum = 114;
+ }
+}
+
+message TestProto2Required {
+ protobuf_unittest.TestRequired proto2 = 1;
+}
+
+// Define these after TestAllTypes to make sure the compiler can handle
+// that.
+message ForeignMessage {
+ int32 c = 1;
+}
+
+enum ForeignEnum {
+ FOREIGN_FOO = 0;
+ FOREIGN_BAR = 1;
+ FOREIGN_BAZ = 2;
+}
diff --git a/NorthstarDedicatedTest/include/protobuf/unittest_no_generic_services.proto b/NorthstarDedicatedTest/include/protobuf/unittest_no_generic_services.proto
new file mode 100644
index 00000000..c2f042ba
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/unittest_no_generic_services.proto
@@ -0,0 +1,54 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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)
+
+syntax = "proto2";
+package protobuf_unittest.no_generic_services_test;
+
+
+// *_generic_services are false by default.
+
+message TestMessage {
+ optional int32 a = 1;
+ extensions 1000 to max;
+}
+
+enum TestEnum {
+ FOO = 1;
+}
+
+extend TestMessage {
+ optional int32 test_extension = 1000;
+}
+
+service TestService {
+ rpc Foo(TestMessage) returns(TestMessage);
+}
diff --git a/NorthstarDedicatedTest/include/protobuf/unittest_optimize_for.proto b/NorthstarDedicatedTest/include/protobuf/unittest_optimize_for.proto
new file mode 100644
index 00000000..ee9cc7bd
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/unittest_optimize_for.proto
@@ -0,0 +1,67 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// A proto file which uses optimize_for = CODE_SIZE.
+
+syntax = "proto2";
+import "google/protobuf/unittest.proto";
+
+package protobuf_unittest;
+
+option optimize_for = CODE_SIZE;
+
+message TestOptimizedForSize {
+ optional int32 i = 1;
+ optional ForeignMessage msg = 19;
+
+ extensions 1000 to max;
+
+ extend TestOptimizedForSize {
+ optional int32 test_extension = 1234;
+ optional TestRequiredOptimizedForSize test_extension2 = 1235;
+ }
+
+ oneof foo {
+ int32 integer_field = 2;
+ string string_field = 3;
+ }
+}
+
+message TestRequiredOptimizedForSize {
+ required int32 x = 1;
+}
+
+message TestOptionalOptimizedForSize {
+ optional TestRequiredOptimizedForSize o = 1;
+}
diff --git a/NorthstarDedicatedTest/include/protobuf/unittest_preserve_unknown_enum.proto b/NorthstarDedicatedTest/include/protobuf/unittest_preserve_unknown_enum.proto
new file mode 100644
index 00000000..2f91332c
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/unittest_preserve_unknown_enum.proto
@@ -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.
+
+syntax = "proto3";
+
+package proto3_preserve_unknown_enum_unittest;
+option objc_class_prefix = "UnknownEnums";
+
+option csharp_namespace = "Google.Protobuf.TestProtos";
+
+enum MyEnum {
+ FOO = 0;
+ BAR = 1;
+ BAZ = 2;
+}
+
+enum MyEnumPlusExtra {
+ E_FOO = 0;
+ E_BAR = 1;
+ E_BAZ = 2;
+ E_EXTRA = 3;
+}
+
+message MyMessage {
+ MyEnum e = 1;
+ repeated MyEnum repeated_e = 2;
+ repeated MyEnum repeated_packed_e = 3 [packed=true];
+ repeated MyEnumPlusExtra repeated_packed_unexpected_e = 4; // not packed
+ oneof o {
+ MyEnum oneof_e_1 = 5;
+ MyEnum oneof_e_2 = 6;
+ }
+}
+
+message MyMessagePlusExtra {
+ MyEnumPlusExtra e = 1;
+ repeated MyEnumPlusExtra repeated_e = 2;
+ repeated MyEnumPlusExtra repeated_packed_e = 3 [packed=true];
+ repeated MyEnumPlusExtra repeated_packed_unexpected_e = 4 [packed=true];
+ oneof o {
+ MyEnumPlusExtra oneof_e_1 = 5;
+ MyEnumPlusExtra oneof_e_2 = 6;
+ }
+}
diff --git a/NorthstarDedicatedTest/include/protobuf/unittest_preserve_unknown_enum2.proto b/NorthstarDedicatedTest/include/protobuf/unittest_preserve_unknown_enum2.proto
new file mode 100644
index 00000000..adf42968
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/unittest_preserve_unknown_enum2.proto
@@ -0,0 +1,50 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+syntax = "proto2";
+
+package proto2_preserve_unknown_enum_unittest;
+
+enum MyEnum {
+ FOO = 0;
+ BAR = 1;
+ BAZ = 2;
+}
+
+message MyMessage {
+ optional MyEnum e = 1;
+ repeated MyEnum repeated_e = 2;
+ repeated MyEnum repeated_packed_e = 3 [packed=true];
+ repeated MyEnum repeated_packed_unexpected_e = 4; // not packed
+ oneof o {
+ MyEnum oneof_e_1 = 5;
+ MyEnum oneof_e_2 = 6;
+ }
+}
diff --git a/NorthstarDedicatedTest/include/protobuf/unittest_proto3.proto b/NorthstarDedicatedTest/include/protobuf/unittest_proto3.proto
new file mode 100644
index 00000000..89c8799a
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/unittest_proto3.proto
@@ -0,0 +1,228 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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_unittest;
+
+import "google/protobuf/unittest_import.proto";
+
+option optimize_for = SPEED;
+
+// This proto includes every type of field in both singular and repeated
+// forms.
+message TestAllTypes {
+ message NestedMessage {
+ // The field name "b" fails to compile in proto1 because it conflicts with
+ // a local variable named "b" in one of the generated methods. Doh.
+ // This file needs to compile in proto1 to test backwards-compatibility.
+ int32 bb = 1;
+ }
+
+ enum NestedEnum {
+ ZERO = 0;
+ FOO = 1;
+ BAR = 2;
+ BAZ = 3;
+ NEG = -1; // Intentionally negative.
+ }
+
+ // Singular
+ int32 optional_int32 = 1;
+ int64 optional_int64 = 2;
+ uint32 optional_uint32 = 3;
+ uint64 optional_uint64 = 4;
+ sint32 optional_sint32 = 5;
+ sint64 optional_sint64 = 6;
+ fixed32 optional_fixed32 = 7;
+ fixed64 optional_fixed64 = 8;
+ sfixed32 optional_sfixed32 = 9;
+ sfixed64 optional_sfixed64 = 10;
+ float optional_float = 11;
+ double optional_double = 12;
+ bool optional_bool = 13;
+ string optional_string = 14;
+ bytes optional_bytes = 15;
+
+ // Groups are not allowed in proto3.
+ // optional group OptionalGroup = 16 {
+ // optional int32 a = 17;
+ // }
+
+ NestedMessage optional_nested_message = 18;
+ ForeignMessage optional_foreign_message = 19;
+ protobuf_unittest_import.ImportMessage optional_import_message = 20;
+
+ NestedEnum optional_nested_enum = 21;
+ ForeignEnum optional_foreign_enum = 22;
+
+ // Omitted (compared to unittest.proto) because proto2 enums are not allowed
+ // inside proto2 messages.
+ //
+ // optional protobuf_unittest_import.ImportEnum optional_import_enum = 23;
+
+ string optional_string_piece = 24 [ctype = STRING_PIECE];
+ string optional_cord = 25 [ctype = CORD];
+
+ // Defined in unittest_import_public.proto
+ protobuf_unittest_import.PublicImportMessage optional_public_import_message =
+ 26;
+
+ NestedMessage optional_lazy_message = 27 [lazy = true];
+ protobuf_unittest_import.ImportMessage optional_lazy_import_message = 115
+ [lazy = true];
+
+ // Repeated
+ repeated int32 repeated_int32 = 31;
+ repeated int64 repeated_int64 = 32;
+ repeated uint32 repeated_uint32 = 33;
+ repeated uint64 repeated_uint64 = 34;
+ repeated sint32 repeated_sint32 = 35;
+ repeated sint64 repeated_sint64 = 36;
+ repeated fixed32 repeated_fixed32 = 37;
+ repeated fixed64 repeated_fixed64 = 38;
+ repeated sfixed32 repeated_sfixed32 = 39;
+ repeated sfixed64 repeated_sfixed64 = 40;
+ repeated float repeated_float = 41;
+ repeated double repeated_double = 42;
+ repeated bool repeated_bool = 43;
+ repeated string repeated_string = 44;
+ repeated bytes repeated_bytes = 45;
+
+ // Groups are not allowed in proto3.
+ // repeated group RepeatedGroup = 46 {
+ // optional int32 a = 47;
+ // }
+
+ repeated NestedMessage repeated_nested_message = 48;
+ repeated ForeignMessage repeated_foreign_message = 49;
+ repeated protobuf_unittest_import.ImportMessage repeated_import_message = 50;
+
+ repeated NestedEnum repeated_nested_enum = 51;
+ repeated ForeignEnum repeated_foreign_enum = 52;
+
+ // Omitted (compared to unittest.proto) because proto2 enums are not allowed
+ // inside proto2 messages.
+ //
+ // repeated protobuf_unittest_import.ImportEnum repeated_import_enum = 53;
+
+ repeated string repeated_string_piece = 54 [ctype = STRING_PIECE];
+ repeated string repeated_cord = 55 [ctype = CORD];
+
+ repeated NestedMessage repeated_lazy_message = 57 [lazy = true];
+
+ oneof oneof_field {
+ uint32 oneof_uint32 = 111;
+ NestedMessage oneof_nested_message = 112;
+ string oneof_string = 113;
+ bytes oneof_bytes = 114;
+ }
+}
+
+// Test messages for packed fields
+
+message TestPackedTypes {
+ repeated int32 packed_int32 = 90 [packed = true];
+ repeated int64 packed_int64 = 91 [packed = true];
+ repeated uint32 packed_uint32 = 92 [packed = true];
+ repeated uint64 packed_uint64 = 93 [packed = true];
+ repeated sint32 packed_sint32 = 94 [packed = true];
+ repeated sint64 packed_sint64 = 95 [packed = true];
+ repeated fixed32 packed_fixed32 = 96 [packed = true];
+ repeated fixed64 packed_fixed64 = 97 [packed = true];
+ repeated sfixed32 packed_sfixed32 = 98 [packed = true];
+ repeated sfixed64 packed_sfixed64 = 99 [packed = true];
+ repeated float packed_float = 100 [packed = true];
+ repeated double packed_double = 101 [packed = true];
+ repeated bool packed_bool = 102 [packed = true];
+ repeated ForeignEnum packed_enum = 103 [packed = true];
+}
+
+// Explicitly set packed to false
+message TestUnpackedTypes {
+ repeated int32 repeated_int32 = 1 [packed = false];
+ repeated int64 repeated_int64 = 2 [packed = false];
+ repeated uint32 repeated_uint32 = 3 [packed = false];
+ repeated uint64 repeated_uint64 = 4 [packed = false];
+ repeated sint32 repeated_sint32 = 5 [packed = false];
+ repeated sint64 repeated_sint64 = 6 [packed = false];
+ repeated fixed32 repeated_fixed32 = 7 [packed = false];
+ repeated fixed64 repeated_fixed64 = 8 [packed = false];
+ repeated sfixed32 repeated_sfixed32 = 9 [packed = false];
+ repeated sfixed64 repeated_sfixed64 = 10 [packed = false];
+ repeated float repeated_float = 11 [packed = false];
+ repeated double repeated_double = 12 [packed = false];
+ repeated bool repeated_bool = 13 [packed = false];
+ repeated TestAllTypes.NestedEnum repeated_nested_enum = 14 [packed = false];
+}
+
+// This proto includes a recursively nested message.
+message NestedTestAllTypes {
+ NestedTestAllTypes child = 1;
+ TestAllTypes payload = 2;
+}
+
+// Define these after TestAllTypes to make sure the compiler can handle
+// that.
+message ForeignMessage {
+ int32 c = 1;
+}
+
+enum ForeignEnum {
+ FOREIGN_ZERO = 0;
+ FOREIGN_FOO = 4;
+ FOREIGN_BAR = 5;
+ FOREIGN_BAZ = 6;
+}
+
+// TestEmptyMessage is used to test behavior of unknown fields.
+message TestEmptyMessage {}
+
+// TestMessageWithDummy is also used to test behavior of unknown fields.
+message TestMessageWithDummy {
+ // This field is only here for triggering copy-on-write; it's not intended to
+ // be serialized.
+ bool dummy = 536870911;
+}
+
+// Same layout as TestOneof2 in unittest.proto to test unknown enum value
+// parsing behavior in oneof.
+message TestOneof2 {
+ oneof foo {
+ NestedEnum foo_enum = 6;
+ }
+
+ enum NestedEnum {
+ UNKNOWN = 0;
+ FOO = 1;
+ BAR = 2;
+ BAZ = 3;
+ }
+}
diff --git a/NorthstarDedicatedTest/include/protobuf/unittest_proto3_arena.proto b/NorthstarDedicatedTest/include/protobuf/unittest_proto3_arena.proto
new file mode 100644
index 00000000..17529397
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/unittest_proto3_arena.proto
@@ -0,0 +1,235 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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";
+
+option cc_enable_arenas = true;
+
+import "google/protobuf/unittest_import.proto";
+
+package proto3_arena_unittest;
+
+// This proto includes every type of field in both singular and repeated
+// forms.
+message TestAllTypes {
+ message NestedMessage {
+ // The field name "b" fails to compile in proto1 because it conflicts with
+ // a local variable named "b" in one of the generated methods. Doh.
+ // This file needs to compile in proto1 to test backwards-compatibility.
+ int32 bb = 1;
+ }
+
+ enum NestedEnum {
+ ZERO = 0;
+ FOO = 1;
+ BAR = 2;
+ BAZ = 3;
+ NEG = -1; // Intentionally negative.
+ }
+
+ // Singular
+ int32 optional_int32 = 1;
+ int64 optional_int64 = 2;
+ uint32 optional_uint32 = 3;
+ uint64 optional_uint64 = 4;
+ sint32 optional_sint32 = 5;
+ sint64 optional_sint64 = 6;
+ fixed32 optional_fixed32 = 7;
+ fixed64 optional_fixed64 = 8;
+ sfixed32 optional_sfixed32 = 9;
+ sfixed64 optional_sfixed64 = 10;
+ float optional_float = 11;
+ double optional_double = 12;
+ bool optional_bool = 13;
+ string optional_string = 14;
+ bytes optional_bytes = 15;
+
+ // Groups are not allowed in proto3.
+ // optional group OptionalGroup = 16 {
+ // optional int32 a = 17;
+ // }
+
+ NestedMessage optional_nested_message = 18;
+ ForeignMessage optional_foreign_message = 19;
+ protobuf_unittest_import.ImportMessage optional_import_message = 20;
+
+ NestedEnum optional_nested_enum = 21;
+ ForeignEnum optional_foreign_enum = 22;
+
+ // Omitted (compared to unittest.proto) because proto2 enums are not allowed
+ // inside proto2 messages.
+ //
+ // optional protobuf_unittest_import.ImportEnum optional_import_enum = 23;
+
+ string optional_string_piece = 24 [ctype=STRING_PIECE];
+ string optional_cord = 25 [ctype=CORD];
+
+ // Defined in unittest_import_public.proto
+ protobuf_unittest_import.PublicImportMessage
+ optional_public_import_message = 26;
+
+ NestedMessage optional_lazy_message = 27 [lazy=true];
+ protobuf_unittest_import.ImportMessage optional_lazy_import_message = 115
+ [lazy = true];
+
+ // Repeated
+ repeated int32 repeated_int32 = 31;
+ repeated int64 repeated_int64 = 32;
+ repeated uint32 repeated_uint32 = 33;
+ repeated uint64 repeated_uint64 = 34;
+ repeated sint32 repeated_sint32 = 35;
+ repeated sint64 repeated_sint64 = 36;
+ repeated fixed32 repeated_fixed32 = 37;
+ repeated fixed64 repeated_fixed64 = 38;
+ repeated sfixed32 repeated_sfixed32 = 39;
+ repeated sfixed64 repeated_sfixed64 = 40;
+ repeated float repeated_float = 41;
+ repeated double repeated_double = 42;
+ repeated bool repeated_bool = 43;
+ repeated string repeated_string = 44;
+ repeated bytes repeated_bytes = 45;
+
+ // Optional
+ optional int32 proto3_optional_int32 = 116;
+ optional int64 proto3_optional_int64 = 117;
+ optional uint32 proto3_optional_uint32 = 118;
+ optional uint64 proto3_optional_uint64 = 119;
+ optional sint32 proto3_optional_sint32 = 120;
+ optional sint64 proto3_optional_sint64 = 121;
+ optional fixed32 proto3_optional_fixed32 = 122;
+ optional fixed64 proto3_optional_fixed64 = 123;
+ optional sfixed32 proto3_optional_sfixed32 = 124;
+ optional sfixed64 proto3_optional_sfixed64 = 125;
+ optional float proto3_optional_float = 126;
+ optional double proto3_optional_double = 127;
+ optional bool proto3_optional_bool = 128;
+ optional string proto3_optional_string = 129;
+ optional bytes proto3_optional_bytes = 130;
+
+ // Groups are not allowed in proto3.
+ // repeated group RepeatedGroup = 46 {
+ // optional int32 a = 47;
+ // }
+
+ repeated NestedMessage repeated_nested_message = 48;
+ repeated ForeignMessage repeated_foreign_message = 49;
+ repeated protobuf_unittest_import.ImportMessage repeated_import_message = 50;
+
+ repeated NestedEnum repeated_nested_enum = 51;
+ repeated ForeignEnum repeated_foreign_enum = 52;
+
+ // Omitted (compared to unittest.proto) because proto2 enums are not allowed
+ // inside proto2 messages.
+ //
+ // repeated protobuf_unittest_import.ImportEnum repeated_import_enum = 53;
+
+ repeated string repeated_string_piece = 54 [ctype=STRING_PIECE];
+ repeated string repeated_cord = 55 [ctype=CORD];
+
+ repeated NestedMessage repeated_lazy_message = 57 [lazy=true];
+
+ oneof oneof_field {
+ uint32 oneof_uint32 = 111;
+ NestedMessage oneof_nested_message = 112;
+ string oneof_string = 113;
+ bytes oneof_bytes = 114;
+ }
+}
+
+// Test messages for packed fields
+
+message TestPackedTypes {
+ repeated int32 packed_int32 = 90 [packed = true];
+ repeated int64 packed_int64 = 91 [packed = true];
+ repeated uint32 packed_uint32 = 92 [packed = true];
+ repeated uint64 packed_uint64 = 93 [packed = true];
+ repeated sint32 packed_sint32 = 94 [packed = true];
+ repeated sint64 packed_sint64 = 95 [packed = true];
+ repeated fixed32 packed_fixed32 = 96 [packed = true];
+ repeated fixed64 packed_fixed64 = 97 [packed = true];
+ repeated sfixed32 packed_sfixed32 = 98 [packed = true];
+ repeated sfixed64 packed_sfixed64 = 99 [packed = true];
+ repeated float packed_float = 100 [packed = true];
+ repeated double packed_double = 101 [packed = true];
+ repeated bool packed_bool = 102 [packed = true];
+ repeated ForeignEnum packed_enum = 103 [packed = true];
+}
+
+// Explicitly set packed to false
+message TestUnpackedTypes {
+ repeated int32 repeated_int32 = 1 [packed = false];
+ repeated int64 repeated_int64 = 2 [packed = false];
+ repeated uint32 repeated_uint32 = 3 [packed = false];
+ repeated uint64 repeated_uint64 = 4 [packed = false];
+ repeated sint32 repeated_sint32 = 5 [packed = false];
+ repeated sint64 repeated_sint64 = 6 [packed = false];
+ repeated fixed32 repeated_fixed32 = 7 [packed = false];
+ repeated fixed64 repeated_fixed64 = 8 [packed = false];
+ repeated sfixed32 repeated_sfixed32 = 9 [packed = false];
+ repeated sfixed64 repeated_sfixed64 = 10 [packed = false];
+ repeated float repeated_float = 11 [packed = false];
+ repeated double repeated_double = 12 [packed = false];
+ repeated bool repeated_bool = 13 [packed = false];
+ repeated TestAllTypes.NestedEnum repeated_nested_enum = 14 [packed = false];
+}
+
+// This proto includes a recursively nested message.
+message NestedTestAllTypes {
+ NestedTestAllTypes child = 1;
+ TestAllTypes payload = 2;
+ repeated NestedTestAllTypes repeated_child = 3;
+}
+
+// Define these after TestAllTypes to make sure the compiler can handle
+// that.
+message ForeignMessage {
+ int32 c = 1;
+}
+
+enum ForeignEnum {
+ FOREIGN_ZERO = 0;
+ FOREIGN_FOO = 4;
+ FOREIGN_BAR = 5;
+ FOREIGN_BAZ = 6;
+}
+
+// TestEmptyMessage is used to test behavior of unknown fields.
+message TestEmptyMessage {
+}
+
+// Needed for a Python test.
+message TestPickleNestedMessage {
+ message NestedMessage {
+ int32 bb = 1;
+ message NestedNestedMessage {
+ int32 cc = 1;
+ }
+ }
+}
diff --git a/NorthstarDedicatedTest/include/protobuf/unittest_proto3_arena_lite.proto b/NorthstarDedicatedTest/include/protobuf/unittest_proto3_arena_lite.proto
new file mode 100644
index 00000000..0d4218b9
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/unittest_proto3_arena_lite.proto
@@ -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.
+
+syntax = "proto3";
+
+package proto3_arena_lite_unittest;
+
+import "google/protobuf/unittest_import.proto";
+
+option cc_enable_arenas = true;
+option optimize_for = LITE_RUNTIME;
+
+// This proto includes every type of field in both singular and repeated
+// forms.
+message TestAllTypes {
+ message NestedMessage {
+ // The field name "b" fails to compile in proto1 because it conflicts with
+ // a local variable named "b" in one of the generated methods. Doh.
+ // This file needs to compile in proto1 to test backwards-compatibility.
+ int32 bb = 1;
+ }
+
+ enum NestedEnum {
+ ZERO = 0;
+ FOO = 1;
+ BAR = 2;
+ BAZ = 3;
+ NEG = -1; // Intentionally negative.
+ }
+
+ // Singular
+ int32 optional_int32 = 1;
+ int64 optional_int64 = 2;
+ uint32 optional_uint32 = 3;
+ uint64 optional_uint64 = 4;
+ sint32 optional_sint32 = 5;
+ sint64 optional_sint64 = 6;
+ fixed32 optional_fixed32 = 7;
+ fixed64 optional_fixed64 = 8;
+ sfixed32 optional_sfixed32 = 9;
+ sfixed64 optional_sfixed64 = 10;
+ float optional_float = 11;
+ double optional_double = 12;
+ bool optional_bool = 13;
+ string optional_string = 14;
+ bytes optional_bytes = 15;
+
+ // Groups are not allowed in proto3.
+ // optional group OptionalGroup = 16 {
+ // optional int32 a = 17;
+ // }
+
+ NestedMessage optional_nested_message = 18;
+ ForeignMessage optional_foreign_message = 19;
+ protobuf_unittest_import.ImportMessage optional_import_message = 20;
+
+ NestedEnum optional_nested_enum = 21;
+ ForeignEnum optional_foreign_enum = 22;
+
+ // Omitted (compared to unittest.proto) because proto2 enums are not allowed
+ // inside proto2 messages.
+ //
+ // optional protobuf_unittest_import.ImportEnum optional_import_enum = 23;
+
+ string optional_string_piece = 24 [ctype = STRING_PIECE];
+ string optional_cord = 25 [ctype = CORD];
+
+ // Defined in unittest_import_public.proto
+ protobuf_unittest_import.PublicImportMessage optional_public_import_message =
+ 26;
+
+ NestedMessage optional_lazy_message = 27 [lazy = true];
+
+ // Repeated
+ repeated int32 repeated_int32 = 31;
+ repeated int64 repeated_int64 = 32;
+ repeated uint32 repeated_uint32 = 33;
+ repeated uint64 repeated_uint64 = 34;
+ repeated sint32 repeated_sint32 = 35;
+ repeated sint64 repeated_sint64 = 36;
+ repeated fixed32 repeated_fixed32 = 37;
+ repeated fixed64 repeated_fixed64 = 38;
+ repeated sfixed32 repeated_sfixed32 = 39;
+ repeated sfixed64 repeated_sfixed64 = 40;
+ repeated float repeated_float = 41;
+ repeated double repeated_double = 42;
+ repeated bool repeated_bool = 43;
+ repeated string repeated_string = 44;
+ repeated bytes repeated_bytes = 45;
+
+ // Groups are not allowed in proto3.
+ // repeated group RepeatedGroup = 46 {
+ // optional int32 a = 47;
+ // }
+
+ repeated NestedMessage repeated_nested_message = 48;
+ repeated ForeignMessage repeated_foreign_message = 49;
+ repeated protobuf_unittest_import.ImportMessage repeated_import_message = 50;
+
+ repeated NestedEnum repeated_nested_enum = 51;
+ repeated ForeignEnum repeated_foreign_enum = 52;
+
+ // Omitted (compared to unittest.proto) because proto2 enums are not allowed
+ // inside proto2 messages.
+ //
+ // repeated protobuf_unittest_import.ImportEnum repeated_import_enum = 53;
+
+ repeated string repeated_string_piece = 54 [ctype = STRING_PIECE];
+ repeated string repeated_cord = 55 [ctype = CORD];
+
+ repeated NestedMessage repeated_lazy_message = 57 [lazy = true];
+
+ oneof oneof_field {
+ uint32 oneof_uint32 = 111;
+ NestedMessage oneof_nested_message = 112;
+ string oneof_string = 113;
+ bytes oneof_bytes = 114;
+ }
+}
+
+// Test messages for packed fields
+
+message TestPackedTypes {
+ repeated int32 packed_int32 = 90 [packed = true];
+ repeated int64 packed_int64 = 91 [packed = true];
+ repeated uint32 packed_uint32 = 92 [packed = true];
+ repeated uint64 packed_uint64 = 93 [packed = true];
+ repeated sint32 packed_sint32 = 94 [packed = true];
+ repeated sint64 packed_sint64 = 95 [packed = true];
+ repeated fixed32 packed_fixed32 = 96 [packed = true];
+ repeated fixed64 packed_fixed64 = 97 [packed = true];
+ repeated sfixed32 packed_sfixed32 = 98 [packed = true];
+ repeated sfixed64 packed_sfixed64 = 99 [packed = true];
+ repeated float packed_float = 100 [packed = true];
+ repeated double packed_double = 101 [packed = true];
+ repeated bool packed_bool = 102 [packed = true];
+ repeated ForeignEnum packed_enum = 103 [packed = true];
+}
+
+// Explicitly set packed to false
+message TestUnpackedTypes {
+ repeated int32 repeated_int32 = 1 [packed = false];
+ repeated int64 repeated_int64 = 2 [packed = false];
+ repeated uint32 repeated_uint32 = 3 [packed = false];
+ repeated uint64 repeated_uint64 = 4 [packed = false];
+ repeated sint32 repeated_sint32 = 5 [packed = false];
+ repeated sint64 repeated_sint64 = 6 [packed = false];
+ repeated fixed32 repeated_fixed32 = 7 [packed = false];
+ repeated fixed64 repeated_fixed64 = 8 [packed = false];
+ repeated sfixed32 repeated_sfixed32 = 9 [packed = false];
+ repeated sfixed64 repeated_sfixed64 = 10 [packed = false];
+ repeated float repeated_float = 11 [packed = false];
+ repeated double repeated_double = 12 [packed = false];
+ repeated bool repeated_bool = 13 [packed = false];
+ repeated TestAllTypes.NestedEnum repeated_nested_enum = 14 [packed = false];
+}
+
+// This proto includes a recursively nested message.
+message NestedTestAllTypes {
+ NestedTestAllTypes child = 1;
+ TestAllTypes payload = 2;
+}
+
+// Define these after TestAllTypes to make sure the compiler can handle
+// that.
+message ForeignMessage {
+ int32 c = 1;
+}
+
+enum ForeignEnum {
+ FOREIGN_ZERO = 0;
+ FOREIGN_FOO = 4;
+ FOREIGN_BAR = 5;
+ FOREIGN_BAZ = 6;
+}
+
+// TestEmptyMessage is used to test behavior of unknown fields.
+message TestEmptyMessage {}
diff --git a/NorthstarDedicatedTest/include/protobuf/unittest_proto3_lite.proto b/NorthstarDedicatedTest/include/protobuf/unittest_proto3_lite.proto
new file mode 100644
index 00000000..837bb03c
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/unittest_proto3_lite.proto
@@ -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.
+
+syntax = "proto3";
+
+package proto3_lite_unittest;
+
+import "google/protobuf/unittest_import.proto";
+
+option optimize_for = LITE_RUNTIME;
+
+// This proto includes every type of field in both singular and repeated
+// forms.
+message TestAllTypes {
+ message NestedMessage {
+ // The field name "b" fails to compile in proto1 because it conflicts with
+ // a local variable named "b" in one of the generated methods. Doh.
+ // This file needs to compile in proto1 to test backwards-compatibility.
+ int32 bb = 1;
+ }
+
+ enum NestedEnum {
+ ZERO = 0;
+ FOO = 1;
+ BAR = 2;
+ BAZ = 3;
+ NEG = -1; // Intentionally negative.
+ }
+
+ // Singular
+ int32 optional_int32 = 1;
+ int64 optional_int64 = 2;
+ uint32 optional_uint32 = 3;
+ uint64 optional_uint64 = 4;
+ sint32 optional_sint32 = 5;
+ sint64 optional_sint64 = 6;
+ fixed32 optional_fixed32 = 7;
+ fixed64 optional_fixed64 = 8;
+ sfixed32 optional_sfixed32 = 9;
+ sfixed64 optional_sfixed64 = 10;
+ float optional_float = 11;
+ double optional_double = 12;
+ bool optional_bool = 13;
+ string optional_string = 14;
+ bytes optional_bytes = 15;
+
+ // Groups are not allowed in proto3.
+ // optional group OptionalGroup = 16 {
+ // optional int32 a = 17;
+ // }
+
+ NestedMessage optional_nested_message = 18;
+ ForeignMessage optional_foreign_message = 19;
+ protobuf_unittest_import.ImportMessage optional_import_message = 20;
+
+ NestedEnum optional_nested_enum = 21;
+ ForeignEnum optional_foreign_enum = 22;
+
+ // Omitted (compared to unittest.proto) because proto2 enums are not allowed
+ // inside proto2 messages.
+ //
+ // optional protobuf_unittest_import.ImportEnum optional_import_enum = 23;
+
+ string optional_string_piece = 24 [ctype = STRING_PIECE];
+ string optional_cord = 25 [ctype = CORD];
+
+ // Defined in unittest_import_public.proto
+ protobuf_unittest_import.PublicImportMessage optional_public_import_message =
+ 26;
+
+ NestedMessage optional_lazy_message = 27 [lazy = true];
+
+ // Repeated
+ repeated int32 repeated_int32 = 31;
+ repeated int64 repeated_int64 = 32;
+ repeated uint32 repeated_uint32 = 33;
+ repeated uint64 repeated_uint64 = 34;
+ repeated sint32 repeated_sint32 = 35;
+ repeated sint64 repeated_sint64 = 36;
+ repeated fixed32 repeated_fixed32 = 37;
+ repeated fixed64 repeated_fixed64 = 38;
+ repeated sfixed32 repeated_sfixed32 = 39;
+ repeated sfixed64 repeated_sfixed64 = 40;
+ repeated float repeated_float = 41;
+ repeated double repeated_double = 42;
+ repeated bool repeated_bool = 43;
+ repeated string repeated_string = 44;
+ repeated bytes repeated_bytes = 45;
+
+ // Groups are not allowed in proto3.
+ // repeated group RepeatedGroup = 46 {
+ // optional int32 a = 47;
+ // }
+
+ repeated NestedMessage repeated_nested_message = 48;
+ repeated ForeignMessage repeated_foreign_message = 49;
+ repeated protobuf_unittest_import.ImportMessage repeated_import_message = 50;
+
+ repeated NestedEnum repeated_nested_enum = 51;
+ repeated ForeignEnum repeated_foreign_enum = 52;
+
+ // Omitted (compared to unittest.proto) because proto2 enums are not allowed
+ // inside proto2 messages.
+ //
+ // repeated protobuf_unittest_import.ImportEnum repeated_import_enum = 53;
+
+ repeated string repeated_string_piece = 54 [ctype = STRING_PIECE];
+ repeated string repeated_cord = 55 [ctype = CORD];
+
+ repeated NestedMessage repeated_lazy_message = 57 [lazy = true];
+
+ oneof oneof_field {
+ uint32 oneof_uint32 = 111;
+ NestedMessage oneof_nested_message = 112;
+ string oneof_string = 113;
+ bytes oneof_bytes = 114;
+ }
+}
+
+// Test messages for packed fields
+
+message TestPackedTypes {
+ repeated int32 packed_int32 = 90 [packed = true];
+ repeated int64 packed_int64 = 91 [packed = true];
+ repeated uint32 packed_uint32 = 92 [packed = true];
+ repeated uint64 packed_uint64 = 93 [packed = true];
+ repeated sint32 packed_sint32 = 94 [packed = true];
+ repeated sint64 packed_sint64 = 95 [packed = true];
+ repeated fixed32 packed_fixed32 = 96 [packed = true];
+ repeated fixed64 packed_fixed64 = 97 [packed = true];
+ repeated sfixed32 packed_sfixed32 = 98 [packed = true];
+ repeated sfixed64 packed_sfixed64 = 99 [packed = true];
+ repeated float packed_float = 100 [packed = true];
+ repeated double packed_double = 101 [packed = true];
+ repeated bool packed_bool = 102 [packed = true];
+ repeated ForeignEnum packed_enum = 103 [packed = true];
+}
+
+// Explicitly set packed to false
+message TestUnpackedTypes {
+ repeated int32 repeated_int32 = 1 [packed = false];
+ repeated int64 repeated_int64 = 2 [packed = false];
+ repeated uint32 repeated_uint32 = 3 [packed = false];
+ repeated uint64 repeated_uint64 = 4 [packed = false];
+ repeated sint32 repeated_sint32 = 5 [packed = false];
+ repeated sint64 repeated_sint64 = 6 [packed = false];
+ repeated fixed32 repeated_fixed32 = 7 [packed = false];
+ repeated fixed64 repeated_fixed64 = 8 [packed = false];
+ repeated sfixed32 repeated_sfixed32 = 9 [packed = false];
+ repeated sfixed64 repeated_sfixed64 = 10 [packed = false];
+ repeated float repeated_float = 11 [packed = false];
+ repeated double repeated_double = 12 [packed = false];
+ repeated bool repeated_bool = 13 [packed = false];
+ repeated TestAllTypes.NestedEnum repeated_nested_enum = 14 [packed = false];
+}
+
+// This proto includes a recursively nested message.
+message NestedTestAllTypes {
+ NestedTestAllTypes child = 1;
+ TestAllTypes payload = 2;
+}
+
+// Define these after TestAllTypes to make sure the compiler can handle
+// that.
+message ForeignMessage {
+ int32 c = 1;
+}
+
+enum ForeignEnum {
+ FOREIGN_ZERO = 0;
+ FOREIGN_FOO = 4;
+ FOREIGN_BAR = 5;
+ FOREIGN_BAZ = 6;
+}
+
+// TestEmptyMessage is used to test behavior of unknown fields.
+message TestEmptyMessage {}
diff --git a/NorthstarDedicatedTest/include/protobuf/unittest_proto3_optional.proto b/NorthstarDedicatedTest/include/protobuf/unittest_proto3_optional.proto
new file mode 100644
index 00000000..09d17182
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/unittest_proto3_optional.proto
@@ -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.
+
+syntax = "proto3";
+
+package protobuf_unittest;
+
+import "google/protobuf/descriptor.proto";
+
+option java_multiple_files = true;
+option java_package = "com.google.protobuf.testing.proto";
+
+message TestProto3Optional {
+ message NestedMessage {
+ // The field name "b" fails to compile in proto1 because it conflicts with
+ // a local variable named "b" in one of the generated methods. Doh.
+ // This file needs to compile in proto1 to test backwards-compatibility.
+ optional int32 bb = 1;
+ }
+
+ enum NestedEnum {
+ UNSPECIFIED = 0;
+ FOO = 1;
+ BAR = 2;
+ BAZ = 3;
+ NEG = -1; // Intentionally negative.
+ }
+
+ // Singular
+ optional int32 optional_int32 = 1;
+ optional int64 optional_int64 = 2;
+ optional uint32 optional_uint32 = 3;
+ optional uint64 optional_uint64 = 4;
+ optional sint32 optional_sint32 = 5;
+ optional sint64 optional_sint64 = 6;
+ optional fixed32 optional_fixed32 = 7;
+ optional fixed64 optional_fixed64 = 8;
+ optional sfixed32 optional_sfixed32 = 9;
+ optional sfixed64 optional_sfixed64 = 10;
+ optional float optional_float = 11;
+ optional double optional_double = 12;
+ optional bool optional_bool = 13;
+ optional string optional_string = 14;
+ optional bytes optional_bytes = 15;
+ optional string optional_cord = 16 [ctype = CORD];
+
+ optional NestedMessage optional_nested_message = 18;
+ optional NestedMessage lazy_nested_message = 19 [lazy = true];
+ optional NestedEnum optional_nested_enum = 21;
+
+ // Add some non-optional fields to verify we can mix them.
+ int32 singular_int32 = 22;
+ int64 singular_int64 = 23;
+}
+
+message TestProto3OptionalMessage {
+ message NestedMessage {
+ string s = 1;
+ }
+
+ NestedMessage nested_message = 1;
+ optional NestedMessage optional_nested_message = 2;
+}
+
+message Proto3OptionalExtensions {
+ option (protobuf_unittest.Proto3OptionalExtensions.ext_no_optional) = 8;
+ option (protobuf_unittest.Proto3OptionalExtensions.ext_with_optional) = 16;
+
+ extend google.protobuf.MessageOptions {
+ int32 ext_no_optional = 355886728;
+ optional int32 ext_with_optional = 355886729;
+ }
+}
diff --git a/NorthstarDedicatedTest/include/protobuf/unittest_well_known_types.proto b/NorthstarDedicatedTest/include/protobuf/unittest_well_known_types.proto
new file mode 100644
index 00000000..c9075244
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/unittest_well_known_types.proto
@@ -0,0 +1,114 @@
+syntax = "proto3";
+
+package protobuf_unittest;
+
+option csharp_namespace = "Google.Protobuf.TestProtos";
+option java_multiple_files = true;
+option java_package = "com.google.protobuf.test";
+
+import "google/protobuf/any.proto";
+import "google/protobuf/api.proto";
+import "google/protobuf/duration.proto";
+import "google/protobuf/empty.proto";
+import "google/protobuf/field_mask.proto";
+import "google/protobuf/source_context.proto";
+import "google/protobuf/struct.proto";
+import "google/protobuf/timestamp.proto";
+import "google/protobuf/type.proto";
+import "google/protobuf/wrappers.proto";
+
+// Test that we can include all well-known types.
+// Each wrapper type is included separately, as languages
+// map handle different wrappers in different ways.
+message TestWellKnownTypes {
+ google.protobuf.Any any_field = 1;
+ google.protobuf.Api api_field = 2;
+ google.protobuf.Duration duration_field = 3;
+ google.protobuf.Empty empty_field = 4;
+ google.protobuf.FieldMask field_mask_field = 5;
+ google.protobuf.SourceContext source_context_field = 6;
+ google.protobuf.Struct struct_field = 7;
+ google.protobuf.Timestamp timestamp_field = 8;
+ google.protobuf.Type type_field = 9;
+ google.protobuf.DoubleValue double_field = 10;
+ google.protobuf.FloatValue float_field = 11;
+ google.protobuf.Int64Value int64_field = 12;
+ google.protobuf.UInt64Value uint64_field = 13;
+ google.protobuf.Int32Value int32_field = 14;
+ google.protobuf.UInt32Value uint32_field = 15;
+ google.protobuf.BoolValue bool_field = 16;
+ google.protobuf.StringValue string_field = 17;
+ google.protobuf.BytesValue bytes_field = 18;
+ // Part of struct, but useful to be able to test separately
+ google.protobuf.Value value_field = 19;
+}
+
+// A repeated field for each well-known type.
+message RepeatedWellKnownTypes {
+ repeated google.protobuf.Any any_field = 1;
+ repeated google.protobuf.Api api_field = 2;
+ repeated google.protobuf.Duration duration_field = 3;
+ repeated google.protobuf.Empty empty_field = 4;
+ repeated google.protobuf.FieldMask field_mask_field = 5;
+ repeated google.protobuf.SourceContext source_context_field = 6;
+ repeated google.protobuf.Struct struct_field = 7;
+ repeated google.protobuf.Timestamp timestamp_field = 8;
+ repeated google.protobuf.Type type_field = 9;
+ // These don't actually make a lot of sense, but they're not prohibited...
+ repeated google.protobuf.DoubleValue double_field = 10;
+ repeated google.protobuf.FloatValue float_field = 11;
+ repeated google.protobuf.Int64Value int64_field = 12;
+ repeated google.protobuf.UInt64Value uint64_field = 13;
+ repeated google.protobuf.Int32Value int32_field = 14;
+ repeated google.protobuf.UInt32Value uint32_field = 15;
+ repeated google.protobuf.BoolValue bool_field = 16;
+ repeated google.protobuf.StringValue string_field = 17;
+ repeated google.protobuf.BytesValue bytes_field = 18;
+}
+
+message OneofWellKnownTypes {
+ oneof oneof_field {
+ google.protobuf.Any any_field = 1;
+ google.protobuf.Api api_field = 2;
+ google.protobuf.Duration duration_field = 3;
+ google.protobuf.Empty empty_field = 4;
+ google.protobuf.FieldMask field_mask_field = 5;
+ google.protobuf.SourceContext source_context_field = 6;
+ google.protobuf.Struct struct_field = 7;
+ google.protobuf.Timestamp timestamp_field = 8;
+ google.protobuf.Type type_field = 9;
+ google.protobuf.DoubleValue double_field = 10;
+ google.protobuf.FloatValue float_field = 11;
+ google.protobuf.Int64Value int64_field = 12;
+ google.protobuf.UInt64Value uint64_field = 13;
+ google.protobuf.Int32Value int32_field = 14;
+ google.protobuf.UInt32Value uint32_field = 15;
+ google.protobuf.BoolValue bool_field = 16;
+ google.protobuf.StringValue string_field = 17;
+ google.protobuf.BytesValue bytes_field = 18;
+ }
+}
+
+// A map field for each well-known type. We only
+// need to worry about the value part of the map being the
+// well-known types, as messages can't be map keys.
+message MapWellKnownTypes {
+ map<int32,google.protobuf.Any> any_field = 1;
+ map<int32,google.protobuf.Api> api_field = 2;
+ map<int32,google.protobuf.Duration> duration_field = 3;
+ map<int32,google.protobuf.Empty> empty_field = 4;
+ map<int32,google.protobuf.FieldMask> field_mask_field = 5;
+ map<int32,google.protobuf.SourceContext> source_context_field = 6;
+ map<int32,google.protobuf.Struct> struct_field = 7;
+ map<int32,google.protobuf.Timestamp> timestamp_field = 8;
+ map<int32,google.protobuf.Type> type_field = 9;
+ map<int32,google.protobuf.DoubleValue> double_field = 10;
+ map<int32,google.protobuf.FloatValue> float_field = 11;
+ map<int32,google.protobuf.Int64Value> int64_field = 12;
+ map<int32,google.protobuf.UInt64Value> uint64_field = 13;
+ map<int32,google.protobuf.Int32Value> int32_field = 14;
+ map<int32,google.protobuf.UInt32Value> uint32_field = 15;
+ map<int32,google.protobuf.BoolValue> bool_field = 16;
+ map<int32,google.protobuf.StringValue> string_field = 17;
+ map<int32,google.protobuf.BytesValue> bytes_field = 18;
+}
diff --git a/NorthstarDedicatedTest/include/protobuf/unknown_field_set.cc b/NorthstarDedicatedTest/include/protobuf/unknown_field_set.cc
new file mode 100644
index 00000000..9361586b
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/unknown_field_set.cc
@@ -0,0 +1,334 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <unknown_field_set.h>
+
+#include <stubs/logging.h>
+#include <stubs/common.h>
+#include <parse_context.h>
+#include <io/coded_stream.h>
+#include <io/zero_copy_stream.h>
+#include <io/zero_copy_stream_impl.h>
+#include <extension_set.h>
+#include <generated_message_tctable_decl.h>
+#include <generated_message_tctable_impl.h>
+#include <wire_format.h>
+#include <wire_format_lite.h>
+#include <stubs/stl_util.h>
+
+#include <port_def.inc>
+
+namespace google {
+namespace protobuf {
+
+const UnknownFieldSet& UnknownFieldSet::default_instance() {
+ static auto instance = internal::OnShutdownDelete(new UnknownFieldSet());
+ return *instance;
+}
+
+void UnknownFieldSet::ClearFallback() {
+ GOOGLE_DCHECK(!fields_.empty());
+ int n = fields_.size();
+ do {
+ (fields_)[--n].Delete();
+ } while (n > 0);
+ fields_.clear();
+}
+
+void UnknownFieldSet::InternalMergeFrom(const UnknownFieldSet& other) {
+ int other_field_count = other.field_count();
+ if (other_field_count > 0) {
+ fields_.reserve(fields_.size() + other_field_count);
+ for (int i = 0; i < other_field_count; i++) {
+ fields_.push_back((other.fields_)[i]);
+ fields_.back().DeepCopy((other.fields_)[i]);
+ }
+ }
+}
+
+void UnknownFieldSet::MergeFrom(const UnknownFieldSet& other) {
+ int other_field_count = other.field_count();
+ if (other_field_count > 0) {
+ fields_.reserve(fields_.size() + other_field_count);
+ for (int i = 0; i < other_field_count; i++) {
+ fields_.push_back((other.fields_)[i]);
+ fields_.back().DeepCopy((other.fields_)[i]);
+ }
+ }
+}
+
+// A specialized MergeFrom for performance when we are merging from an UFS that
+// is temporary and can be destroyed in the process.
+void UnknownFieldSet::MergeFromAndDestroy(UnknownFieldSet* other) {
+ if (fields_.empty()) {
+ fields_ = std::move(other->fields_);
+ } else {
+ fields_.insert(fields_.end(),
+ std::make_move_iterator(other->fields_.begin()),
+ std::make_move_iterator(other->fields_.end()));
+ }
+ other->fields_.clear();
+}
+
+void UnknownFieldSet::MergeToInternalMetadata(
+ const UnknownFieldSet& other, internal::InternalMetadata* metadata) {
+ metadata->mutable_unknown_fields<UnknownFieldSet>()->MergeFrom(other);
+}
+
+size_t UnknownFieldSet::SpaceUsedExcludingSelfLong() const {
+ if (fields_.empty()) return 0;
+
+ size_t total_size = sizeof(fields_) + sizeof(UnknownField) * fields_.size();
+
+ for (const UnknownField& field : fields_) {
+ switch (field.type()) {
+ case UnknownField::TYPE_LENGTH_DELIMITED:
+ total_size += sizeof(*field.data_.length_delimited_.string_value) +
+ internal::StringSpaceUsedExcludingSelfLong(
+ *field.data_.length_delimited_.string_value);
+ break;
+ case UnknownField::TYPE_GROUP:
+ total_size += field.data_.group_->SpaceUsedLong();
+ break;
+ default:
+ break;
+ }
+ }
+ return total_size;
+}
+
+size_t UnknownFieldSet::SpaceUsedLong() const {
+ return sizeof(*this) + SpaceUsedExcludingSelf();
+}
+
+void UnknownFieldSet::AddVarint(int number, 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);
+}
+
+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 <port_undef.inc>
diff --git a/NorthstarDedicatedTest/include/protobuf/unknown_field_set.h b/NorthstarDedicatedTest/include/protobuf/unknown_field_set.h
new file mode 100644
index 00000000..01586047
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/unknown_field_set.h
@@ -0,0 +1,411 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// Contains classes used to keep track of unrecognized fields seen while
+// parsing a protocol message.
+
+#ifndef GOOGLE_PROTOBUF_UNKNOWN_FIELD_SET_H__
+#define GOOGLE_PROTOBUF_UNKNOWN_FIELD_SET_H__
+
+#include <assert.h>
+
+#include <string>
+#include <vector>
+
+#include <stubs/common.h>
+#include <stubs/logging.h>
+#include <parse_context.h>
+#include <io/coded_stream.h>
+#include <io/zero_copy_stream_impl_lite.h>
+#include <message_lite.h>
+#include <port.h>
+
+#include <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);
+
+ 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();
+
+ // Serialization API.
+ // These methods can take advantage of the underlying implementation and may
+ // archieve a better performance than using getters to retrieve the data and
+ // do the serialization yourself.
+ void SerializeLengthDelimitedNoTag(io::CodedOutputStream* output) const {
+ output->SetCur(InternalSerializeLengthDelimitedNoTag(output->Cur(),
+ output->EpsCopy()));
+ }
+
+ inline size_t GetLengthDelimitedSize() const;
+ uint8_t* InternalSerializeLengthDelimitedNoTag(
+ uint8_t* target, io::EpsCopyOutputStream* stream) const;
+
+
+ // If this UnknownField contains a pointer, delete it.
+ void Delete();
+
+ // Make a deep copy of any pointers in this UnknownField.
+ void DeepCopy(const UnknownField& other);
+
+ // Set the wire type of this UnknownField. Should only be used when this
+ // UnknownField is being created.
+ inline void SetType(Type type);
+
+ union LengthDelimited {
+ 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 <port_undef.inc>
+#endif // GOOGLE_PROTOBUF_UNKNOWN_FIELD_SET_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/unknown_field_set_unittest.cc b/NorthstarDedicatedTest/include/protobuf/unknown_field_set_unittest.cc
new file mode 100644
index 00000000..8f1377c7
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/unknown_field_set_unittest.cc
@@ -0,0 +1,652 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 test is testing a lot more than just the UnknownFieldSet class. It
+// tests handling of unknown fields throughout the system.
+
+#include <unknown_field_set.h>
+
+#include <unordered_set>
+
+#include <stubs/callback.h>
+#include <stubs/common.h>
+#include <stubs/logging.h>
+#include <test_util.h>
+#include <unittest.pb.h>
+#include <unittest_lite.pb.h>
+#include <io/coded_stream.h>
+#include <io/zero_copy_stream_impl.h>
+#include <descriptor.h>
+#include <stubs/mutex.h>
+#include <wire_format.h>
+#include <testing/googletest.h>
+#include <gtest/gtest.h>
+#include <stubs/time.h>
+#include <stubs/stl_util.h>
+
+namespace google {
+namespace protobuf {
+
+using internal::WireFormat;
+
+class UnknownFieldSetTest : public testing::Test {
+ protected:
+ virtual void SetUp() {
+ descriptor_ = unittest::TestAllTypes::descriptor();
+ TestUtil::SetAllFields(&all_fields_);
+ all_fields_.SerializeToString(&all_fields_data_);
+ ASSERT_TRUE(empty_message_.ParseFromString(all_fields_data_));
+ unknown_fields_ = empty_message_.mutable_unknown_fields();
+ }
+
+ const UnknownField* GetField(const std::string& name) {
+ const FieldDescriptor* field = descriptor_->FindFieldByName(name);
+ if (field == nullptr) return nullptr;
+ for (int i = 0; i < unknown_fields_->field_count(); i++) {
+ if (unknown_fields_->field(i).number() == field->number()) {
+ return &unknown_fields_->field(i);
+ }
+ }
+ return nullptr;
+ }
+
+ // Constructs a protocol buffer which contains fields with all the same
+ // numbers as all_fields_data_ except that each field is some other wire
+ // type.
+ std::string GetBizarroData() {
+ unittest::TestEmptyMessage bizarro_message;
+ UnknownFieldSet* bizarro_unknown_fields =
+ bizarro_message.mutable_unknown_fields();
+ for (int i = 0; i < unknown_fields_->field_count(); i++) {
+ const UnknownField& unknown_field = unknown_fields_->field(i);
+ if (unknown_field.type() == UnknownField::TYPE_VARINT) {
+ bizarro_unknown_fields->AddFixed32(unknown_field.number(), 1);
+ } else {
+ bizarro_unknown_fields->AddVarint(unknown_field.number(), 1);
+ }
+ }
+
+ std::string data;
+ EXPECT_TRUE(bizarro_message.SerializeToString(&data));
+ return data;
+ }
+
+ const Descriptor* descriptor_;
+ unittest::TestAllTypes all_fields_;
+ std::string all_fields_data_;
+
+ // An empty message that has been parsed from all_fields_data_. So, it has
+ // unknown fields of every type.
+ unittest::TestEmptyMessage empty_message_;
+ UnknownFieldSet* unknown_fields_;
+};
+
+namespace {
+
+TEST_F(UnknownFieldSetTest, AllFieldsPresent) {
+ // Verifies the following:
+ // --all unknown tags belong to TestAllTypes.
+ // --all fields in TestAllTypes is present in UnknownFieldSet except unset
+ // oneof fields.
+ //
+ // Should handle repeated fields that may appear multiple times in
+ // UnknownFieldSet.
+
+ int non_oneof_count = 0;
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ if (!descriptor_->field(i)->containing_oneof()) {
+ non_oneof_count++;
+ }
+ }
+
+ std::unordered_set<uint32> unknown_tags;
+ for (int i = 0; i < unknown_fields_->field_count(); i++) {
+ unknown_tags.insert(unknown_fields_->field(i).number());
+ }
+
+ for (uint32 t : unknown_tags) {
+ EXPECT_NE(descriptor_->FindFieldByNumber(t), nullptr);
+ }
+
+ EXPECT_EQ(non_oneof_count + descriptor_->oneof_decl_count(),
+ unknown_tags.size());
+}
+
+TEST_F(UnknownFieldSetTest, Varint) {
+ const UnknownField* field = GetField("optional_int32");
+ ASSERT_TRUE(field != nullptr);
+
+ ASSERT_EQ(UnknownField::TYPE_VARINT, field->type());
+ EXPECT_EQ(all_fields_.optional_int32(), field->varint());
+}
+
+TEST_F(UnknownFieldSetTest, Fixed32) {
+ const UnknownField* field = GetField("optional_fixed32");
+ ASSERT_TRUE(field != nullptr);
+
+ ASSERT_EQ(UnknownField::TYPE_FIXED32, field->type());
+ EXPECT_EQ(all_fields_.optional_fixed32(), field->fixed32());
+}
+
+TEST_F(UnknownFieldSetTest, Fixed64) {
+ const UnknownField* field = GetField("optional_fixed64");
+ ASSERT_TRUE(field != nullptr);
+
+ ASSERT_EQ(UnknownField::TYPE_FIXED64, field->type());
+ EXPECT_EQ(all_fields_.optional_fixed64(), field->fixed64());
+}
+
+TEST_F(UnknownFieldSetTest, LengthDelimited) {
+ const UnknownField* field = GetField("optional_string");
+ ASSERT_TRUE(field != nullptr);
+
+ ASSERT_EQ(UnknownField::TYPE_LENGTH_DELIMITED, field->type());
+ EXPECT_EQ(all_fields_.optional_string(), field->length_delimited());
+}
+
+TEST_F(UnknownFieldSetTest, Group) {
+ const UnknownField* field = GetField("optionalgroup");
+ ASSERT_TRUE(field != nullptr);
+
+ ASSERT_EQ(UnknownField::TYPE_GROUP, field->type());
+ ASSERT_EQ(1, field->group().field_count());
+
+ const UnknownField& nested_field = field->group().field(0);
+ const FieldDescriptor* nested_field_descriptor =
+ unittest::TestAllTypes::OptionalGroup::descriptor()->FindFieldByName("a");
+ ASSERT_TRUE(nested_field_descriptor != nullptr);
+
+ EXPECT_EQ(nested_field_descriptor->number(), nested_field.number());
+ ASSERT_EQ(UnknownField::TYPE_VARINT, nested_field.type());
+ EXPECT_EQ(all_fields_.optionalgroup().a(), nested_field.varint());
+}
+
+TEST_F(UnknownFieldSetTest, SerializeFastAndSlowAreEquivalent) {
+ int size =
+ WireFormat::ComputeUnknownFieldsSize(empty_message_.unknown_fields());
+ std::string slow_buffer;
+ std::string fast_buffer;
+ slow_buffer.resize(size);
+ fast_buffer.resize(size);
+
+ uint8* target = reinterpret_cast<uint8*>(::google::protobuf::string_as_array(&fast_buffer));
+ uint8* result = WireFormat::SerializeUnknownFieldsToArray(
+ empty_message_.unknown_fields(), target);
+ EXPECT_EQ(size, result - target);
+
+ {
+ io::ArrayOutputStream raw_stream(::google::protobuf::string_as_array(&slow_buffer), size,
+ 1);
+ io::CodedOutputStream output_stream(&raw_stream);
+ WireFormat::SerializeUnknownFields(empty_message_.unknown_fields(),
+ &output_stream);
+ ASSERT_FALSE(output_stream.HadError());
+ }
+ EXPECT_TRUE(fast_buffer == slow_buffer);
+}
+
+TEST_F(UnknownFieldSetTest, Serialize) {
+ // Check that serializing the UnknownFieldSet produces the original data
+ // again.
+
+ std::string data;
+ empty_message_.SerializeToString(&data);
+
+ // Don't use EXPECT_EQ because we don't want to dump raw binary data to
+ // stdout.
+ EXPECT_TRUE(data == all_fields_data_);
+}
+
+TEST_F(UnknownFieldSetTest, ParseViaReflection) {
+ // Make sure fields are properly parsed to the UnknownFieldSet when parsing
+ // via reflection.
+
+ unittest::TestEmptyMessage message;
+ io::ArrayInputStream raw_input(all_fields_data_.data(),
+ all_fields_data_.size());
+ io::CodedInputStream input(&raw_input);
+ ASSERT_TRUE(WireFormat::ParseAndMergePartial(&input, &message));
+
+ EXPECT_EQ(message.DebugString(), empty_message_.DebugString());
+}
+
+TEST_F(UnknownFieldSetTest, SerializeViaReflection) {
+ // Make sure fields are properly written from the UnknownFieldSet when
+ // serializing via reflection.
+
+ std::string data;
+
+ {
+ io::StringOutputStream raw_output(&data);
+ io::CodedOutputStream output(&raw_output);
+ size_t size = WireFormat::ByteSize(empty_message_);
+ WireFormat::SerializeWithCachedSizes(empty_message_, size, &output);
+ ASSERT_FALSE(output.HadError());
+ }
+
+ // Don't use EXPECT_EQ because we don't want to dump raw binary data to
+ // stdout.
+ EXPECT_TRUE(data == all_fields_data_);
+}
+
+TEST_F(UnknownFieldSetTest, CopyFrom) {
+ unittest::TestEmptyMessage message;
+
+ message.CopyFrom(empty_message_);
+
+ EXPECT_EQ(empty_message_.DebugString(), message.DebugString());
+}
+
+TEST_F(UnknownFieldSetTest, Swap) {
+ unittest::TestEmptyMessage other_message;
+ ASSERT_TRUE(other_message.ParseFromString(GetBizarroData()));
+
+ EXPECT_GT(empty_message_.unknown_fields().field_count(), 0);
+ EXPECT_GT(other_message.unknown_fields().field_count(), 0);
+ const std::string debug_string = empty_message_.DebugString();
+ const std::string other_debug_string = other_message.DebugString();
+ EXPECT_NE(debug_string, other_debug_string);
+
+ empty_message_.Swap(&other_message);
+ EXPECT_EQ(debug_string, other_message.DebugString());
+ EXPECT_EQ(other_debug_string, empty_message_.DebugString());
+}
+
+TEST_F(UnknownFieldSetTest, SwapWithSelf) {
+ const std::string debug_string = empty_message_.DebugString();
+ EXPECT_GT(empty_message_.unknown_fields().field_count(), 0);
+
+ empty_message_.Swap(&empty_message_);
+ EXPECT_GT(empty_message_.unknown_fields().field_count(), 0);
+ EXPECT_EQ(debug_string, empty_message_.DebugString());
+}
+
+TEST_F(UnknownFieldSetTest, MergeFrom) {
+ unittest::TestEmptyMessage source, destination;
+
+ destination.mutable_unknown_fields()->AddVarint(1, 1);
+ destination.mutable_unknown_fields()->AddVarint(3, 2);
+ source.mutable_unknown_fields()->AddVarint(2, 3);
+ source.mutable_unknown_fields()->AddVarint(3, 4);
+
+ destination.MergeFrom(source);
+
+ EXPECT_EQ(
+ // Note: The ordering of fields here depends on the ordering of adds
+ // and merging, above.
+ "1: 1\n"
+ "3: 2\n"
+ "2: 3\n"
+ "3: 4\n",
+ destination.DebugString());
+}
+
+TEST_F(UnknownFieldSetTest, MergeFromMessage) {
+ unittest::TestEmptyMessage source, destination;
+
+ destination.mutable_unknown_fields()->AddVarint(1, 1);
+ destination.mutable_unknown_fields()->AddVarint(3, 2);
+ source.mutable_unknown_fields()->AddVarint(2, 3);
+ source.mutable_unknown_fields()->AddVarint(3, 4);
+
+ destination.mutable_unknown_fields()->MergeFromMessage(source);
+
+ EXPECT_EQ(
+ // Note: The ordering of fields here depends on the ordering of adds
+ // and merging, above.
+ "1: 1\n"
+ "3: 2\n"
+ "2: 3\n"
+ "3: 4\n",
+ destination.DebugString());
+}
+
+TEST_F(UnknownFieldSetTest, MergeFromMessageLite) {
+ unittest::TestAllTypesLite source;
+ unittest::TestEmptyMessageLite destination;
+
+ source.set_optional_fixed32(42);
+ destination.ParseFromString(source.SerializeAsString());
+
+ UnknownFieldSet unknown_field_set;
+ EXPECT_TRUE(unknown_field_set.MergeFromMessage(destination));
+ EXPECT_EQ(unknown_field_set.field_count(), 1);
+
+ const UnknownField& unknown_field = unknown_field_set.field(0);
+ EXPECT_EQ(unknown_field.number(), 7);
+ EXPECT_EQ(unknown_field.fixed32(), 42);
+}
+
+
+TEST_F(UnknownFieldSetTest, Clear) {
+ // Clear the set.
+ empty_message_.Clear();
+ EXPECT_EQ(0, unknown_fields_->field_count());
+}
+
+TEST_F(UnknownFieldSetTest, ClearAndFreeMemory) {
+ EXPECT_GT(unknown_fields_->field_count(), 0);
+ unknown_fields_->ClearAndFreeMemory();
+ EXPECT_EQ(0, unknown_fields_->field_count());
+ unknown_fields_->AddVarint(123456, 654321);
+ EXPECT_EQ(1, unknown_fields_->field_count());
+}
+
+TEST_F(UnknownFieldSetTest, ParseKnownAndUnknown) {
+ // Test mixing known and unknown fields when parsing.
+
+ unittest::TestEmptyMessage source;
+ source.mutable_unknown_fields()->AddVarint(123456, 654321);
+ std::string data;
+ ASSERT_TRUE(source.SerializeToString(&data));
+
+ unittest::TestAllTypes destination;
+ ASSERT_TRUE(destination.ParseFromString(all_fields_data_ + data));
+
+ TestUtil::ExpectAllFieldsSet(destination);
+ ASSERT_EQ(1, destination.unknown_fields().field_count());
+ ASSERT_EQ(UnknownField::TYPE_VARINT,
+ destination.unknown_fields().field(0).type());
+ EXPECT_EQ(654321, destination.unknown_fields().field(0).varint());
+}
+
+TEST_F(UnknownFieldSetTest, WrongTypeTreatedAsUnknown) {
+ // Test that fields of the wrong wire type are treated like unknown fields
+ // when parsing.
+
+ unittest::TestAllTypes all_types_message;
+ unittest::TestEmptyMessage empty_message;
+ std::string bizarro_data = GetBizarroData();
+ ASSERT_TRUE(all_types_message.ParseFromString(bizarro_data));
+ ASSERT_TRUE(empty_message.ParseFromString(bizarro_data));
+
+ // All fields should have been interpreted as unknown, so the debug strings
+ // should be the same.
+ EXPECT_EQ(empty_message.DebugString(), all_types_message.DebugString());
+}
+
+TEST_F(UnknownFieldSetTest, WrongTypeTreatedAsUnknownViaReflection) {
+ // Same as WrongTypeTreatedAsUnknown but via the reflection interface.
+
+ unittest::TestAllTypes all_types_message;
+ unittest::TestEmptyMessage empty_message;
+ std::string bizarro_data = GetBizarroData();
+ io::ArrayInputStream raw_input(bizarro_data.data(), bizarro_data.size());
+ io::CodedInputStream input(&raw_input);
+ ASSERT_TRUE(WireFormat::ParseAndMergePartial(&input, &all_types_message));
+ ASSERT_TRUE(empty_message.ParseFromString(bizarro_data));
+
+ EXPECT_EQ(empty_message.DebugString(), all_types_message.DebugString());
+}
+
+TEST_F(UnknownFieldSetTest, UnknownExtensions) {
+ // Make sure fields are properly parsed to the UnknownFieldSet even when
+ // they are declared as extension numbers.
+
+ unittest::TestEmptyMessageWithExtensions message;
+ ASSERT_TRUE(message.ParseFromString(all_fields_data_));
+
+ EXPECT_EQ(message.DebugString(), empty_message_.DebugString());
+}
+
+TEST_F(UnknownFieldSetTest, UnknownExtensionsReflection) {
+ // Same as UnknownExtensions except parsing via reflection.
+
+ unittest::TestEmptyMessageWithExtensions message;
+ io::ArrayInputStream raw_input(all_fields_data_.data(),
+ all_fields_data_.size());
+ io::CodedInputStream input(&raw_input);
+ ASSERT_TRUE(WireFormat::ParseAndMergePartial(&input, &message));
+
+ EXPECT_EQ(message.DebugString(), empty_message_.DebugString());
+}
+
+TEST_F(UnknownFieldSetTest, WrongExtensionTypeTreatedAsUnknown) {
+ // Test that fields of the wrong wire type are treated like unknown fields
+ // when parsing extensions.
+
+ unittest::TestAllExtensions all_extensions_message;
+ unittest::TestEmptyMessage empty_message;
+ std::string bizarro_data = GetBizarroData();
+ ASSERT_TRUE(all_extensions_message.ParseFromString(bizarro_data));
+ ASSERT_TRUE(empty_message.ParseFromString(bizarro_data));
+
+ // All fields should have been interpreted as unknown, so the debug strings
+ // should be the same.
+ EXPECT_EQ(empty_message.DebugString(), all_extensions_message.DebugString());
+}
+
+TEST_F(UnknownFieldSetTest, UnknownEnumValue) {
+ using unittest::TestAllExtensions;
+ using unittest::TestAllTypes;
+ using unittest::TestEmptyMessage;
+
+ const FieldDescriptor* singular_field =
+ TestAllTypes::descriptor()->FindFieldByName("optional_nested_enum");
+ const FieldDescriptor* repeated_field =
+ TestAllTypes::descriptor()->FindFieldByName("repeated_nested_enum");
+ ASSERT_TRUE(singular_field != nullptr);
+ ASSERT_TRUE(repeated_field != nullptr);
+
+ std::string data;
+
+ {
+ TestEmptyMessage empty_message;
+ UnknownFieldSet* unknown_fields = empty_message.mutable_unknown_fields();
+ unknown_fields->AddVarint(singular_field->number(), TestAllTypes::BAR);
+ unknown_fields->AddVarint(singular_field->number(), 5); // not valid
+ unknown_fields->AddVarint(repeated_field->number(), TestAllTypes::FOO);
+ unknown_fields->AddVarint(repeated_field->number(), 4); // not valid
+ unknown_fields->AddVarint(repeated_field->number(), TestAllTypes::BAZ);
+ unknown_fields->AddVarint(repeated_field->number(), 6); // not valid
+ empty_message.SerializeToString(&data);
+ }
+
+ {
+ TestAllTypes message;
+ ASSERT_TRUE(message.ParseFromString(data));
+ EXPECT_EQ(TestAllTypes::BAR, message.optional_nested_enum());
+ ASSERT_EQ(2, message.repeated_nested_enum_size());
+ EXPECT_EQ(TestAllTypes::FOO, message.repeated_nested_enum(0));
+ EXPECT_EQ(TestAllTypes::BAZ, message.repeated_nested_enum(1));
+
+ const UnknownFieldSet& unknown_fields = message.unknown_fields();
+ ASSERT_EQ(3, unknown_fields.field_count());
+
+ EXPECT_EQ(singular_field->number(), unknown_fields.field(0).number());
+ ASSERT_EQ(UnknownField::TYPE_VARINT, unknown_fields.field(0).type());
+ EXPECT_EQ(5, unknown_fields.field(0).varint());
+
+ EXPECT_EQ(repeated_field->number(), unknown_fields.field(1).number());
+ ASSERT_EQ(UnknownField::TYPE_VARINT, unknown_fields.field(1).type());
+ EXPECT_EQ(4, unknown_fields.field(1).varint());
+
+ EXPECT_EQ(repeated_field->number(), unknown_fields.field(2).number());
+ ASSERT_EQ(UnknownField::TYPE_VARINT, unknown_fields.field(2).type());
+ EXPECT_EQ(6, unknown_fields.field(2).varint());
+ }
+
+ {
+ using unittest::optional_nested_enum_extension;
+ using unittest::repeated_nested_enum_extension;
+
+ TestAllExtensions message;
+ ASSERT_TRUE(message.ParseFromString(data));
+ EXPECT_EQ(TestAllTypes::BAR,
+ message.GetExtension(optional_nested_enum_extension));
+ ASSERT_EQ(2, message.ExtensionSize(repeated_nested_enum_extension));
+ EXPECT_EQ(TestAllTypes::FOO,
+ message.GetExtension(repeated_nested_enum_extension, 0));
+ EXPECT_EQ(TestAllTypes::BAZ,
+ message.GetExtension(repeated_nested_enum_extension, 1));
+
+ const UnknownFieldSet& unknown_fields = message.unknown_fields();
+ ASSERT_EQ(3, unknown_fields.field_count());
+
+ EXPECT_EQ(singular_field->number(), unknown_fields.field(0).number());
+ ASSERT_EQ(UnknownField::TYPE_VARINT, unknown_fields.field(0).type());
+ EXPECT_EQ(5, unknown_fields.field(0).varint());
+
+ EXPECT_EQ(repeated_field->number(), unknown_fields.field(1).number());
+ ASSERT_EQ(UnknownField::TYPE_VARINT, unknown_fields.field(1).type());
+ EXPECT_EQ(4, unknown_fields.field(1).varint());
+
+ EXPECT_EQ(repeated_field->number(), unknown_fields.field(2).number());
+ ASSERT_EQ(UnknownField::TYPE_VARINT, unknown_fields.field(2).type());
+ EXPECT_EQ(6, unknown_fields.field(2).varint());
+ }
+}
+
+TEST_F(UnknownFieldSetTest, SpaceUsedExcludingSelf) {
+ UnknownFieldSet empty;
+ empty.AddVarint(1, 0);
+ EXPECT_EQ(sizeof(std::vector<UnknownField>) + sizeof(UnknownField),
+ empty.SpaceUsedExcludingSelf());
+}
+
+TEST_F(UnknownFieldSetTest, SpaceUsed) {
+ unittest::TestEmptyMessage empty_message;
+
+ // Make sure an unknown field set has zero space used until a field is
+ // actually added.
+ size_t base_size = empty_message.SpaceUsedLong();
+ UnknownFieldSet* unknown_fields = empty_message.mutable_unknown_fields();
+ EXPECT_EQ(base_size, empty_message.SpaceUsedLong());
+
+ // Make sure each thing we add to the set increases the SpaceUsedLong().
+ unknown_fields->AddVarint(1, 0);
+ EXPECT_LT(base_size, empty_message.SpaceUsedLong());
+ base_size = empty_message.SpaceUsedLong();
+
+ std::string* str = unknown_fields->AddLengthDelimited(1);
+ EXPECT_LT(base_size, empty_message.SpaceUsedLong());
+ base_size = empty_message.SpaceUsedLong();
+
+ str->assign(sizeof(std::string) + 1, 'x');
+ EXPECT_LT(base_size, empty_message.SpaceUsedLong());
+ base_size = empty_message.SpaceUsedLong();
+
+ UnknownFieldSet* group = unknown_fields->AddGroup(1);
+ EXPECT_LT(base_size, empty_message.SpaceUsedLong());
+ base_size = empty_message.SpaceUsedLong();
+
+ group->AddVarint(1, 0);
+ EXPECT_LT(base_size, empty_message.SpaceUsedLong());
+}
+
+
+TEST_F(UnknownFieldSetTest, Empty) {
+ UnknownFieldSet unknown_fields;
+ EXPECT_TRUE(unknown_fields.empty());
+ unknown_fields.AddVarint(6, 123);
+ EXPECT_FALSE(unknown_fields.empty());
+ unknown_fields.Clear();
+ EXPECT_TRUE(unknown_fields.empty());
+}
+
+TEST_F(UnknownFieldSetTest, DeleteSubrange) {
+ // Exhaustively test the deletion of every possible subrange in arrays of all
+ // sizes from 0 through 9.
+ for (int size = 0; size < 10; ++size) {
+ for (int num = 0; num <= size; ++num) {
+ for (int start = 0; start < size - num; ++start) {
+ // Create a set with "size" fields.
+ UnknownFieldSet unknown;
+ for (int i = 0; i < size; ++i) {
+ unknown.AddFixed32(i, i);
+ }
+ // Delete the specified subrange.
+ unknown.DeleteSubrange(start, num);
+ // Make sure the resulting field values are still correct.
+ EXPECT_EQ(size - num, unknown.field_count());
+ for (int i = 0; i < unknown.field_count(); ++i) {
+ if (i < start) {
+ EXPECT_EQ(i, unknown.field(i).fixed32());
+ } else {
+ EXPECT_EQ(i + num, unknown.field(i).fixed32());
+ }
+ }
+ }
+ }
+ }
+}
+
+void CheckDeleteByNumber(const std::vector<int>& field_numbers,
+ int deleted_number,
+ const std::vector<int>& expected_field_nubmers) {
+ UnknownFieldSet unknown_fields;
+ for (int i = 0; i < field_numbers.size(); ++i) {
+ unknown_fields.AddFixed32(field_numbers[i], i);
+ }
+ unknown_fields.DeleteByNumber(deleted_number);
+ ASSERT_EQ(expected_field_nubmers.size(), unknown_fields.field_count());
+ for (int i = 0; i < expected_field_nubmers.size(); ++i) {
+ EXPECT_EQ(expected_field_nubmers[i], unknown_fields.field(i).number());
+ }
+}
+
+#define MAKE_VECTOR(x) std::vector<int>(x, x + GOOGLE_ARRAYSIZE(x))
+TEST_F(UnknownFieldSetTest, DeleteByNumber) {
+ CheckDeleteByNumber(std::vector<int>(), 1, std::vector<int>());
+ static const int kTestFieldNumbers1[] = {1, 2, 3};
+ static const int kFieldNumberToDelete1 = 1;
+ static const int kExpectedFieldNumbers1[] = {2, 3};
+ CheckDeleteByNumber(MAKE_VECTOR(kTestFieldNumbers1), kFieldNumberToDelete1,
+ MAKE_VECTOR(kExpectedFieldNumbers1));
+ static const int kTestFieldNumbers2[] = {1, 2, 3};
+ static const int kFieldNumberToDelete2 = 2;
+ static const int kExpectedFieldNumbers2[] = {1, 3};
+ CheckDeleteByNumber(MAKE_VECTOR(kTestFieldNumbers2), kFieldNumberToDelete2,
+ MAKE_VECTOR(kExpectedFieldNumbers2));
+ static const int kTestFieldNumbers3[] = {1, 2, 3};
+ static const int kFieldNumberToDelete3 = 3;
+ static const int kExpectedFieldNumbers3[] = {1, 2};
+ CheckDeleteByNumber(MAKE_VECTOR(kTestFieldNumbers3), kFieldNumberToDelete3,
+ MAKE_VECTOR(kExpectedFieldNumbers3));
+ static const int kTestFieldNumbers4[] = {1, 2, 1, 4, 1};
+ static const int kFieldNumberToDelete4 = 1;
+ static const int kExpectedFieldNumbers4[] = {2, 4};
+ CheckDeleteByNumber(MAKE_VECTOR(kTestFieldNumbers4), kFieldNumberToDelete4,
+ MAKE_VECTOR(kExpectedFieldNumbers4));
+ static const int kTestFieldNumbers5[] = {1, 2, 3, 4, 5};
+ static const int kFieldNumberToDelete5 = 6;
+ static const int kExpectedFieldNumbers5[] = {1, 2, 3, 4, 5};
+ CheckDeleteByNumber(MAKE_VECTOR(kTestFieldNumbers5), kFieldNumberToDelete5,
+ MAKE_VECTOR(kExpectedFieldNumbers5));
+}
+#undef MAKE_VECTOR
+} // namespace
+
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/util/delimited_message_util.cc b/NorthstarDedicatedTest/include/protobuf/util/delimited_message_util.cc
new file mode 100644
index 00000000..1efa52a7
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/util/delimited_message_util.cc
@@ -0,0 +1,127 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Adapted from the patch of kenton@google.com (Kenton Varda)
+// See https://github.com/protocolbuffers/protobuf/pull/710 for details.
+
+#include <util/delimited_message_util.h>
+#include <io/coded_stream.h>
+
+namespace google {
+namespace protobuf {
+namespace util {
+
+bool SerializeDelimitedToFileDescriptor(const MessageLite& message,
+ int file_descriptor) {
+ io::FileOutputStream output(file_descriptor);
+ return SerializeDelimitedToZeroCopyStream(message, &output);
+}
+
+bool SerializeDelimitedToOstream(const MessageLite& message,
+ std::ostream* output) {
+ {
+ io::OstreamOutputStream zero_copy_output(output);
+ if (!SerializeDelimitedToZeroCopyStream(message, &zero_copy_output))
+ return false;
+ }
+ return output->good();
+}
+
+bool ParseDelimitedFromZeroCopyStream(MessageLite* message,
+ io::ZeroCopyInputStream* input,
+ bool* clean_eof) {
+ io::CodedInputStream coded_input(input);
+ return ParseDelimitedFromCodedStream(message, &coded_input, clean_eof);
+}
+
+bool ParseDelimitedFromCodedStream(MessageLite* message,
+ io::CodedInputStream* input,
+ bool* clean_eof) {
+ if (clean_eof != NULL) *clean_eof = false;
+ int start = input->CurrentPosition();
+
+ // Read the size.
+ uint32 size;
+ if (!input->ReadVarint32(&size)) {
+ if (clean_eof != NULL) *clean_eof = input->CurrentPosition() == start;
+ return false;
+ }
+
+ // Get the position after any size bytes have been read (and only the message
+ // itself remains).
+ int position_after_size = input->CurrentPosition();
+
+ // Tell the stream not to read beyond that size.
+ io::CodedInputStream::Limit limit = input->PushLimit(size);
+
+ // Parse the message.
+ if (!message->MergeFromCodedStream(input)) return false;
+ if (!input->ConsumedEntireMessage()) return false;
+ if (input->CurrentPosition() - position_after_size != static_cast<int>(size))
+ return false;
+
+ // Release the limit.
+ input->PopLimit(limit);
+
+ return true;
+}
+
+bool SerializeDelimitedToZeroCopyStream(const MessageLite& message,
+ io::ZeroCopyOutputStream* output) {
+ io::CodedOutputStream coded_output(output);
+ return SerializeDelimitedToCodedStream(message, &coded_output);
+}
+
+bool SerializeDelimitedToCodedStream(const MessageLite& message,
+ io::CodedOutputStream* output) {
+ // Write the size.
+ size_t size = message.ByteSizeLong();
+ if (size > INT_MAX) return false;
+
+ output->WriteVarint32(size);
+
+ // Write the content.
+ uint8* buffer = output->GetDirectBufferForNBytesAndAdvance(size);
+ if (buffer != NULL) {
+ // Optimization: The message fits in one buffer, so use the faster
+ // direct-to-array serialization path.
+ message.SerializeWithCachedSizesToArray(buffer);
+ } else {
+ // Slightly-slower path when the message is multiple buffers.
+ message.SerializeWithCachedSizes(output);
+ if (output->HadError()) return false;
+ }
+
+ return true;
+}
+
+} // namespace util
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/util/delimited_message_util.h b/NorthstarDedicatedTest/include/protobuf/util/delimited_message_util.h
new file mode 100644
index 00000000..2279151d
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/util/delimited_message_util.h
@@ -0,0 +1,108 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Adapted from the patch of kenton@google.com (Kenton Varda)
+// See https://github.com/protocolbuffers/protobuf/pull/710 for details.
+
+#ifndef GOOGLE_PROTOBUF_UTIL_DELIMITED_MESSAGE_UTIL_H__
+#define GOOGLE_PROTOBUF_UTIL_DELIMITED_MESSAGE_UTIL_H__
+
+
+#include <ostream>
+
+#include <message_lite.h>
+#include <io/coded_stream.h>
+#include <io/zero_copy_stream_impl.h>
+
+#include <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 <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_UTIL_DELIMITED_MESSAGE_UTIL_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/util/delimited_message_util_test.cc b/NorthstarDedicatedTest/include/protobuf/util/delimited_message_util_test.cc
new file mode 100644
index 00000000..52cb1091
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/util/delimited_message_util_test.cc
@@ -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.
+
+// Adapted from the patch of kenton@google.com (Kenton Varda)
+// See https://github.com/protocolbuffers/protobuf/pull/710 for details.
+
+#include <util/delimited_message_util.h>
+
+#include <sstream>
+
+#include <test_util.h>
+#include <unittest.pb.h>
+#include <testing/googletest.h>
+#include <gtest/gtest.h>
+
+namespace google {
+namespace protobuf {
+namespace util {
+
+TEST(DelimitedMessageUtilTest, DelimitedMessages) {
+ std::stringstream stream;
+
+ {
+ protobuf_unittest::TestAllTypes message1;
+ TestUtil::SetAllFields(&message1);
+ EXPECT_TRUE(SerializeDelimitedToOstream(message1, &stream));
+
+ protobuf_unittest::TestPackedTypes message2;
+ TestUtil::SetPackedFields(&message2);
+ EXPECT_TRUE(SerializeDelimitedToOstream(message2, &stream));
+ }
+
+ {
+ bool clean_eof;
+ io::IstreamInputStream zstream(&stream);
+
+ protobuf_unittest::TestAllTypes message1;
+ clean_eof = true;
+ EXPECT_TRUE(ParseDelimitedFromZeroCopyStream(&message1,
+ &zstream, &clean_eof));
+ EXPECT_FALSE(clean_eof);
+ TestUtil::ExpectAllFieldsSet(message1);
+
+ protobuf_unittest::TestPackedTypes message2;
+ clean_eof = true;
+ EXPECT_TRUE(ParseDelimitedFromZeroCopyStream(&message2,
+ &zstream, &clean_eof));
+ EXPECT_FALSE(clean_eof);
+ TestUtil::ExpectPackedFieldsSet(message2);
+
+ clean_eof = false;
+ EXPECT_FALSE(ParseDelimitedFromZeroCopyStream(&message2,
+ &zstream, &clean_eof));
+ EXPECT_TRUE(clean_eof);
+ }
+}
+
+TEST(DelimitedMessageUtilTest, FailsAtEndOfStream) {
+ std::stringstream full_stream;
+ std::stringstream partial_stream;
+
+ {
+ protobuf_unittest::ForeignMessage message;
+ message.set_c(42);
+ message.set_d(24);
+ EXPECT_TRUE(SerializeDelimitedToOstream(message, &full_stream));
+
+ std::string full_output = full_stream.str();
+ ASSERT_GT(full_output.size(), size_t{2});
+ ASSERT_EQ(full_output[0], 4);
+
+ partial_stream << full_output[0] << full_output[1] << full_output[2];
+ }
+
+ {
+ bool clean_eof;
+ io::IstreamInputStream zstream(&partial_stream);
+
+ protobuf_unittest::ForeignMessage message;
+ clean_eof = true;
+ EXPECT_FALSE(ParseDelimitedFromZeroCopyStream(&message,
+ &zstream, &clean_eof));
+ EXPECT_FALSE(clean_eof);
+ }
+}
+
+} // namespace util
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/util/field_comparator.cc b/NorthstarDedicatedTest/include/protobuf/util/field_comparator.cc
new file mode 100644
index 00000000..596edd81
--- /dev/null
+++ b/NorthstarDedicatedTest/include/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 <util/field_comparator.h>
+
+#include <limits>
+#include <string>
+
+#include <descriptor.h>
+#include <message.h>
+#include <util/message_differencer.h>
+#include <stubs/map_util.h>
+#include <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/NorthstarDedicatedTest/include/protobuf/util/field_comparator.h b/NorthstarDedicatedTest/include/protobuf/util/field_comparator.h
new file mode 100644
index 00000000..f52e2485
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/util/field_comparator.h
@@ -0,0 +1,285 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Defines classes for field comparison.
+
+#ifndef GOOGLE_PROTOBUF_UTIL_FIELD_COMPARATOR_H__
+#define GOOGLE_PROTOBUF_UTIL_FIELD_COMPARATOR_H__
+
+#include <cstdint>
+#include <map>
+#include <string>
+#include <vector>
+
+#include <stubs/common.h>
+#include <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 <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_UTIL_FIELD_COMPARATOR_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/util/field_comparator_test.cc b/NorthstarDedicatedTest/include/protobuf/util/field_comparator_test.cc
new file mode 100644
index 00000000..611b4940
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/util/field_comparator_test.cc
@@ -0,0 +1,495 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 <util/field_comparator.h>
+
+#include <limits>
+
+#include <unittest.pb.h>
+#include <descriptor.h>
+#include <gtest/gtest.h>
+#include <stubs/mathutil.h>
+
+namespace google {
+namespace protobuf {
+namespace util {
+namespace {
+
+using protobuf_unittest::TestAllTypes;
+
+class DefaultFieldComparatorTest : public ::testing::Test {
+ protected:
+ void SetUp() { descriptor_ = TestAllTypes::descriptor(); }
+
+ const Descriptor* descriptor_;
+ DefaultFieldComparator comparator_;
+ TestAllTypes message_1_;
+ TestAllTypes message_2_;
+};
+
+TEST_F(DefaultFieldComparatorTest, RecursesIntoGroup) {
+ const FieldDescriptor* field = descriptor_->FindFieldByName("optionalgroup");
+ EXPECT_EQ(FieldComparator::RECURSE,
+ comparator_.Compare(message_1_, message_2_, field, -1, -1, NULL));
+}
+
+TEST_F(DefaultFieldComparatorTest, RecursesIntoNestedMessage) {
+ const FieldDescriptor* field =
+ descriptor_->FindFieldByName("optional_nested_message");
+ EXPECT_EQ(FieldComparator::RECURSE,
+ comparator_.Compare(message_1_, message_2_, field, -1, -1, NULL));
+}
+
+TEST_F(DefaultFieldComparatorTest, RecursesIntoForeignMessage) {
+ const FieldDescriptor* field =
+ descriptor_->FindFieldByName("optional_foreign_message");
+ EXPECT_EQ(FieldComparator::RECURSE,
+ comparator_.Compare(message_1_, message_2_, field, -1, -1, NULL));
+}
+
+TEST_F(DefaultFieldComparatorTest, Int32Comparison) {
+ const FieldDescriptor* field = descriptor_->FindFieldByName("optional_int32");
+ message_1_.set_optional_int32(1);
+ message_2_.set_optional_int32(1);
+
+ EXPECT_EQ(FieldComparator::SAME,
+ comparator_.Compare(message_1_, message_2_, field, -1, -1, NULL));
+
+ message_2_.set_optional_int32(-1);
+ EXPECT_EQ(FieldComparator::DIFFERENT,
+ comparator_.Compare(message_1_, message_2_, field, -1, -1, NULL));
+}
+
+TEST_F(DefaultFieldComparatorTest, Int64Comparison) {
+ const FieldDescriptor* field = descriptor_->FindFieldByName("optional_int64");
+ message_1_.set_optional_int64(1L);
+ message_2_.set_optional_int64(1L);
+
+ EXPECT_EQ(FieldComparator::SAME,
+ comparator_.Compare(message_1_, message_2_, field, -1, -1, NULL));
+
+ message_2_.set_optional_int64(-1L);
+ EXPECT_EQ(FieldComparator::DIFFERENT,
+ comparator_.Compare(message_1_, message_2_, field, -1, -1, NULL));
+}
+
+TEST_F(DefaultFieldComparatorTest, UInt32Comparison) {
+ const FieldDescriptor* field =
+ descriptor_->FindFieldByName("optional_uint32");
+ message_1_.set_optional_uint32(1);
+ message_2_.set_optional_uint32(1);
+
+ EXPECT_EQ(FieldComparator::SAME,
+ comparator_.Compare(message_1_, message_2_, field, -1, -1, NULL));
+
+ message_2_.set_optional_uint32(2);
+ EXPECT_EQ(FieldComparator::DIFFERENT,
+ comparator_.Compare(message_1_, message_2_, field, -1, -1, NULL));
+}
+
+TEST_F(DefaultFieldComparatorTest, UInt64Comparison) {
+ const FieldDescriptor* field =
+ descriptor_->FindFieldByName("optional_uint64");
+ message_1_.set_optional_uint64(1L);
+ message_2_.set_optional_uint64(1L);
+
+ EXPECT_EQ(FieldComparator::SAME,
+ comparator_.Compare(message_1_, message_2_, field, -1, -1, NULL));
+
+ message_2_.set_optional_uint64(2L);
+ EXPECT_EQ(FieldComparator::DIFFERENT,
+ comparator_.Compare(message_1_, message_2_, field, -1, -1, NULL));
+}
+
+TEST_F(DefaultFieldComparatorTest, BooleanComparison) {
+ const FieldDescriptor* field = descriptor_->FindFieldByName("optional_bool");
+ message_1_.set_optional_bool(true);
+ message_2_.set_optional_bool(true);
+
+ EXPECT_EQ(FieldComparator::SAME,
+ comparator_.Compare(message_1_, message_2_, field, -1, -1, NULL));
+
+ message_2_.set_optional_bool(false);
+ EXPECT_EQ(FieldComparator::DIFFERENT,
+ comparator_.Compare(message_1_, message_2_, field, -1, -1, NULL));
+}
+
+TEST_F(DefaultFieldComparatorTest, EnumComparison) {
+ const FieldDescriptor* field =
+ descriptor_->FindFieldByName("optional_nested_enum");
+ message_1_.set_optional_nested_enum(TestAllTypes::BAR);
+ message_2_.set_optional_nested_enum(TestAllTypes::BAR);
+
+ EXPECT_EQ(FieldComparator::SAME,
+ comparator_.Compare(message_1_, message_2_, field, -1, -1, NULL));
+
+ message_2_.set_optional_nested_enum(TestAllTypes::BAZ);
+ EXPECT_EQ(FieldComparator::DIFFERENT,
+ comparator_.Compare(message_1_, message_2_, field, -1, -1, NULL));
+}
+
+TEST_F(DefaultFieldComparatorTest, StringComparison) {
+ const FieldDescriptor* field =
+ descriptor_->FindFieldByName("optional_string");
+ message_1_.set_optional_string("foo");
+ message_2_.set_optional_string("foo");
+
+ EXPECT_EQ(FieldComparator::SAME,
+ comparator_.Compare(message_1_, message_2_, field, -1, -1, NULL));
+
+ message_2_.set_optional_string("bar");
+ EXPECT_EQ(FieldComparator::DIFFERENT,
+ comparator_.Compare(message_1_, message_2_, field, -1, -1, NULL));
+}
+
+TEST_F(DefaultFieldComparatorTest, FloatingPointComparisonExact) {
+ const FieldDescriptor* field_float =
+ descriptor_->FindFieldByName("optional_float");
+ const FieldDescriptor* field_double =
+ descriptor_->FindFieldByName("optional_double");
+
+ message_1_.set_optional_float(0.1f);
+ message_2_.set_optional_float(0.1f);
+ message_1_.set_optional_double(0.1);
+ message_2_.set_optional_double(0.1);
+
+ EXPECT_EQ(
+ FieldComparator::SAME,
+ comparator_.Compare(message_1_, message_2_, field_float, -1, -1, NULL));
+ EXPECT_EQ(
+ FieldComparator::SAME,
+ comparator_.Compare(message_1_, message_2_, field_double, -1, -1, NULL));
+
+ message_2_.set_optional_float(0.2f);
+ message_2_.set_optional_double(0.2);
+
+ EXPECT_EQ(
+ FieldComparator::DIFFERENT,
+ comparator_.Compare(message_1_, message_2_, field_float, -1, -1, NULL));
+ EXPECT_EQ(
+ FieldComparator::DIFFERENT,
+ comparator_.Compare(message_1_, message_2_, field_double, -1, -1, NULL));
+}
+
+TEST_F(DefaultFieldComparatorTest, FloatingPointComparisonApproximate) {
+ const FieldDescriptor* field_float =
+ descriptor_->FindFieldByName("optional_float");
+ const FieldDescriptor* field_double =
+ descriptor_->FindFieldByName("optional_double");
+
+ message_1_.set_optional_float(2.300005f);
+ message_2_.set_optional_float(2.300006f);
+ message_1_.set_optional_double(2.3000000000000003);
+ message_2_.set_optional_double(2.3000000000000007);
+
+ // Approximate comparison depends on MathUtil, so we assert on MathUtil
+ // results first to check if that's where the failure was introduced.
+ ASSERT_NE(message_1_.optional_float(), message_2_.optional_float());
+ ASSERT_NE(message_1_.optional_double(), message_2_.optional_double());
+ ASSERT_TRUE(MathUtil::AlmostEquals(message_1_.optional_float(),
+ message_2_.optional_float()));
+ ASSERT_TRUE(MathUtil::AlmostEquals(message_1_.optional_double(),
+ message_2_.optional_double()));
+
+ // DefaultFieldComparator's default float comparison mode is EXACT.
+ ASSERT_EQ(DefaultFieldComparator::EXACT, comparator_.float_comparison());
+ EXPECT_EQ(
+ FieldComparator::DIFFERENT,
+ comparator_.Compare(message_1_, message_2_, field_float, -1, -1, NULL));
+ EXPECT_EQ(
+ FieldComparator::DIFFERENT,
+ comparator_.Compare(message_1_, message_2_, field_double, -1, -1, NULL));
+
+ comparator_.set_float_comparison(DefaultFieldComparator::APPROXIMATE);
+
+ EXPECT_EQ(
+ FieldComparator::SAME,
+ comparator_.Compare(message_1_, message_2_, field_float, -1, -1, NULL));
+ EXPECT_EQ(
+ FieldComparator::SAME,
+ comparator_.Compare(message_1_, message_2_, field_double, -1, -1, NULL));
+}
+
+TEST_F(DefaultFieldComparatorTest, FloatingPointComparisonTreatNaNsAsEqual) {
+ const FieldDescriptor* field_float =
+ descriptor_->FindFieldByName("optional_float");
+ const FieldDescriptor* field_double =
+ descriptor_->FindFieldByName("optional_double");
+
+ message_1_.set_optional_float(std::numeric_limits<float>::quiet_NaN());
+ message_2_.set_optional_float(std::numeric_limits<float>::quiet_NaN());
+ message_1_.set_optional_double(std::numeric_limits<double>::quiet_NaN());
+ message_2_.set_optional_double(std::numeric_limits<double>::quiet_NaN());
+
+ // DefaultFieldComparator's default float comparison mode is EXACT with
+ // treating NaNs as different.
+ ASSERT_EQ(DefaultFieldComparator::EXACT, comparator_.float_comparison());
+ ASSERT_EQ(false, comparator_.treat_nan_as_equal());
+ EXPECT_EQ(
+ FieldComparator::DIFFERENT,
+ comparator_.Compare(message_1_, message_2_, field_float, -1, -1, NULL));
+ EXPECT_EQ(
+ FieldComparator::DIFFERENT,
+ comparator_.Compare(message_1_, message_2_, field_double, -1, -1, NULL));
+ comparator_.set_float_comparison(DefaultFieldComparator::APPROXIMATE);
+ EXPECT_EQ(
+ FieldComparator::DIFFERENT,
+ comparator_.Compare(message_1_, message_2_, field_float, -1, -1, NULL));
+ EXPECT_EQ(
+ FieldComparator::DIFFERENT,
+ comparator_.Compare(message_1_, message_2_, field_double, -1, -1, NULL));
+
+ comparator_.set_treat_nan_as_equal(true);
+ ASSERT_EQ(true, comparator_.treat_nan_as_equal());
+ comparator_.set_float_comparison(DefaultFieldComparator::EXACT);
+ EXPECT_EQ(
+ FieldComparator::SAME,
+ comparator_.Compare(message_1_, message_2_, field_float, -1, -1, NULL));
+ EXPECT_EQ(
+ FieldComparator::SAME,
+ comparator_.Compare(message_1_, message_2_, field_double, -1, -1, NULL));
+ comparator_.set_float_comparison(DefaultFieldComparator::APPROXIMATE);
+ EXPECT_EQ(
+ FieldComparator::SAME,
+ comparator_.Compare(message_1_, message_2_, field_float, -1, -1, NULL));
+ EXPECT_EQ(
+ FieldComparator::SAME,
+ comparator_.Compare(message_1_, message_2_, field_double, -1, -1, NULL));
+}
+
+TEST_F(DefaultFieldComparatorTest,
+ FloatingPointComparisonWithinFractionOrMargin) {
+ const FieldDescriptor* field_float =
+ descriptor_->FindFieldByName("optional_float");
+ const FieldDescriptor* field_double =
+ descriptor_->FindFieldByName("optional_double");
+
+ message_1_.set_optional_float(100.0f);
+ message_2_.set_optional_float(109.9f);
+ message_1_.set_optional_double(100.0);
+ message_2_.set_optional_double(109.9);
+
+ comparator_.set_float_comparison(DefaultFieldComparator::APPROXIMATE);
+ EXPECT_EQ(
+ FieldComparator::DIFFERENT,
+ comparator_.Compare(message_1_, message_2_, field_float, -1, -1, NULL));
+ EXPECT_EQ(
+ FieldComparator::DIFFERENT,
+ comparator_.Compare(message_1_, message_2_, field_double, -1, -1, NULL));
+
+ // Should fail since the fraction is too low.
+ comparator_.SetFractionAndMargin(field_float, 0.01, 0.0);
+ comparator_.SetFractionAndMargin(field_double, 0.01, 0.0);
+
+ EXPECT_EQ(
+ FieldComparator::DIFFERENT,
+ comparator_.Compare(message_1_, message_2_, field_float, -1, -1, NULL));
+ EXPECT_EQ(
+ FieldComparator::DIFFERENT,
+ comparator_.Compare(message_1_, message_2_, field_double, -1, -1, NULL));
+
+ // Should fail since the margin is too low.
+ comparator_.SetFractionAndMargin(field_float, 0.0, 9.0);
+ comparator_.SetFractionAndMargin(field_double, 0.0, 9.0);
+ EXPECT_EQ(
+ FieldComparator::DIFFERENT,
+ comparator_.Compare(message_1_, message_2_, field_float, -1, -1, NULL));
+ EXPECT_EQ(
+ FieldComparator::DIFFERENT,
+ comparator_.Compare(message_1_, message_2_, field_double, -1, -1, NULL));
+
+ // Should succeed since the fraction is high enough.
+ comparator_.SetFractionAndMargin(field_float, 0.2, 0.0);
+ comparator_.SetFractionAndMargin(field_double, 0.2, 0.0);
+ EXPECT_EQ(
+ FieldComparator::SAME,
+ comparator_.Compare(message_1_, message_2_, field_float, -1, -1, NULL));
+ EXPECT_EQ(
+ FieldComparator::SAME,
+ comparator_.Compare(message_1_, message_2_, field_double, -1, -1, NULL));
+
+ // Should succeed since the margin is high enough.
+ comparator_.SetFractionAndMargin(field_float, 0.0, 10.0);
+ comparator_.SetFractionAndMargin(field_double, 0.0, 10.0);
+ EXPECT_EQ(
+ FieldComparator::SAME,
+ comparator_.Compare(message_1_, message_2_, field_float, -1, -1, NULL));
+ EXPECT_EQ(
+ FieldComparator::SAME,
+ comparator_.Compare(message_1_, message_2_, field_double, -1, -1, NULL));
+
+ // Setting values for one of the fields should not affect the other.
+ comparator_.SetFractionAndMargin(field_double, 0.0, 0.0);
+ EXPECT_EQ(
+ FieldComparator::SAME,
+ comparator_.Compare(message_1_, message_2_, field_float, -1, -1, NULL));
+ EXPECT_EQ(
+ FieldComparator::DIFFERENT,
+ comparator_.Compare(message_1_, message_2_, field_double, -1, -1, NULL));
+
+ // +inf should be equal even though they are not technically within margin or
+ // fraction.
+ message_1_.set_optional_float(std::numeric_limits<float>::infinity());
+ message_2_.set_optional_float(std::numeric_limits<float>::infinity());
+ message_1_.set_optional_double(std::numeric_limits<double>::infinity());
+ message_2_.set_optional_double(std::numeric_limits<double>::infinity());
+ comparator_.SetFractionAndMargin(field_float, 0.0, 0.0);
+ comparator_.SetFractionAndMargin(field_double, 0.0, 0.0);
+ EXPECT_EQ(
+ FieldComparator::SAME,
+ comparator_.Compare(message_1_, message_2_, field_float, -1, -1, NULL));
+ EXPECT_EQ(
+ FieldComparator::SAME,
+ comparator_.Compare(message_1_, message_2_, field_double, -1, -1, NULL));
+
+ // -inf should be equal even though they are not technically within margin or
+ // fraction.
+ message_1_.set_optional_float(-std::numeric_limits<float>::infinity());
+ message_2_.set_optional_float(-std::numeric_limits<float>::infinity());
+ message_1_.set_optional_double(-std::numeric_limits<double>::infinity());
+ message_2_.set_optional_double(-std::numeric_limits<double>::infinity());
+ comparator_.SetFractionAndMargin(field_float, 0.0, 0.0);
+ comparator_.SetFractionAndMargin(field_double, 0.0, 0.0);
+ EXPECT_EQ(
+ FieldComparator::SAME,
+ comparator_.Compare(message_1_, message_2_, field_float, -1, -1, NULL));
+ EXPECT_EQ(
+ FieldComparator::SAME,
+ comparator_.Compare(message_1_, message_2_, field_double, -1, -1, NULL));
+
+ // Finite values and inf should not be equal, even for a positive fraction.
+ message_1_.set_optional_float(std::numeric_limits<float>::infinity());
+ message_2_.set_optional_float(0.0f);
+ message_1_.set_optional_double(std::numeric_limits<double>::infinity());
+ message_2_.set_optional_double(0.0);
+ comparator_.SetFractionAndMargin(field_float, 0.1, 0.0);
+ comparator_.SetFractionAndMargin(field_double, 0.1, 0.0);
+ EXPECT_EQ(FieldComparator::DIFFERENT,
+ comparator_.Compare(message_1_, message_2_, field_float, -1, -1,
+ nullptr));
+ EXPECT_EQ(FieldComparator::DIFFERENT,
+ comparator_.Compare(message_1_, message_2_, field_double, -1, -1,
+ nullptr));
+}
+
+TEST_F(DefaultFieldComparatorTest,
+ FloatingPointComparisonWithinDefaultFractionOrMargin) {
+ const FieldDescriptor* field_float =
+ descriptor_->FindFieldByName("optional_float");
+ const FieldDescriptor* field_double =
+ descriptor_->FindFieldByName("optional_double");
+
+ message_1_.set_optional_float(100.0f);
+ message_2_.set_optional_float(109.9f);
+ message_1_.set_optional_double(100.0);
+ message_2_.set_optional_double(109.9);
+
+ comparator_.set_float_comparison(DefaultFieldComparator::APPROXIMATE);
+ EXPECT_EQ(
+ FieldComparator::DIFFERENT,
+ comparator_.Compare(message_1_, message_2_, field_float, -1, -1, NULL));
+ EXPECT_EQ(
+ FieldComparator::DIFFERENT,
+ comparator_.Compare(message_1_, message_2_, field_double, -1, -1, NULL));
+
+ // Set default fraction and margin.
+ comparator_.SetDefaultFractionAndMargin(0.01, 0.0);
+
+ // Float comparisons should fail since the fraction is too low.
+ EXPECT_EQ(
+ FieldComparator::DIFFERENT,
+ comparator_.Compare(message_1_, message_2_, field_float, -1, -1, NULL));
+ EXPECT_EQ(
+ FieldComparator::DIFFERENT,
+ comparator_.Compare(message_1_, message_2_, field_double, -1, -1, NULL));
+
+ // Set field-specific fraction and margin for one field (field_float) but not
+ // the other (field_double)
+ comparator_.SetFractionAndMargin(field_float, 0.2, 0.0);
+
+ // The field with the override should succeed, since its field-specific
+ // fraction is high enough.
+ EXPECT_EQ(
+ FieldComparator::SAME,
+ comparator_.Compare(message_1_, message_2_, field_float, -1, -1, NULL));
+ // The field with no override should fail, since the default fraction is too
+ // low
+ EXPECT_EQ(
+ FieldComparator::DIFFERENT,
+ comparator_.Compare(message_1_, message_2_, field_double, -1, -1, NULL));
+
+ // Set the default fraction and margin high enough so that fields that use
+ // the default should succeed
+ comparator_.SetDefaultFractionAndMargin(0.2, 0.0);
+ EXPECT_EQ(
+ FieldComparator::SAME,
+ comparator_.Compare(message_1_, message_2_, field_double, -1, -1, NULL));
+
+ // The field with an override should still be OK
+ EXPECT_EQ(
+ FieldComparator::SAME,
+ comparator_.Compare(message_1_, message_2_, field_float, -1, -1, NULL));
+
+ // Set fraction and margin for the field with an override to be too low
+ comparator_.SetFractionAndMargin(field_float, 0.01, 0.0);
+
+ // Now our default is high enough but field_float's override is too low.
+ EXPECT_EQ(
+ FieldComparator::DIFFERENT,
+ comparator_.Compare(message_1_, message_2_, field_float, -1, -1, NULL));
+ EXPECT_EQ(
+ FieldComparator::SAME,
+ comparator_.Compare(message_1_, message_2_, field_double, -1, -1, NULL));
+}
+
+// Simple test checking whether we compare values at correct indices.
+TEST_F(DefaultFieldComparatorTest, RepeatedFieldComparison) {
+ const FieldDescriptor* field =
+ descriptor_->FindFieldByName("repeated_string");
+
+ message_1_.add_repeated_string("foo");
+ message_1_.add_repeated_string("bar");
+ message_2_.add_repeated_string("bar");
+ message_2_.add_repeated_string("baz");
+
+ EXPECT_EQ(FieldComparator::DIFFERENT,
+ comparator_.Compare(message_1_, message_2_, field, 0, 0, NULL));
+ EXPECT_EQ(FieldComparator::DIFFERENT,
+ comparator_.Compare(message_1_, message_2_, field, 1, 1, NULL));
+ EXPECT_EQ(FieldComparator::SAME,
+ comparator_.Compare(message_1_, message_2_, field, 1, 0, NULL));
+}
+
+} // namespace
+} // namespace util
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/util/field_mask_util.cc b/NorthstarDedicatedTest/include/protobuf/util/field_mask_util.cc
new file mode 100644
index 00000000..6151adcc
--- /dev/null
+++ b/NorthstarDedicatedTest/include/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 <util/field_mask_util.h>
+
+#include <cstdint>
+
+#include <message.h>
+#include <stubs/strutil.h>
+#include <stubs/map_util.h>
+
+// Must be included last.
+#include <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 == NULL) {
+ 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 == NULL) {
+ // No intersection found.
+ return;
+ }
+ node = result;
+ }
+ // Now we found a matching node with the given path. Add all leaf nodes
+ // to out.
+ MergeLeafNodesToTree(path, node, out);
+}
+
+void FieldMaskTree::MergeLeafNodesToTree(const 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 == NULL) {
+ GOOGLE_LOG(ERROR) << "Cannot find field \"" << field_name << "\" in message "
+ << descriptor->full_name();
+ continue;
+ }
+ if (!child->children.empty()) {
+ // Sub-paths are only allowed for singular message fields.
+ if (field->is_repeated() ||
+ field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) {
+ GOOGLE_LOG(ERROR) << "Field \"" << field_name << "\" in message "
+ << descriptor->full_name()
+ << " is not a singular message field and cannot "
+ << "have sub-fields.";
+ continue;
+ }
+ MergeMessage(child, source_reflection->GetMessage(source, field), options,
+ destination_reflection->MutableMessage(destination, field));
+ continue;
+ }
+ if (!field->is_repeated()) {
+ switch (field->cpp_type()) {
+#define COPY_VALUE(TYPE, Name) \
+ case FieldDescriptor::CPPTYPE_##TYPE: { \
+ if (source_reflection->HasField(source, field)) { \
+ destination_reflection->Set##Name( \
+ destination, field, source_reflection->Get##Name(source, field)); \
+ } else { \
+ destination_reflection->ClearField(destination, field); \
+ } \
+ break; \
+ }
+ COPY_VALUE(BOOL, Bool)
+ COPY_VALUE(INT32, Int32)
+ COPY_VALUE(INT64, Int64)
+ COPY_VALUE(UINT32, UInt32)
+ COPY_VALUE(UINT64, UInt64)
+ COPY_VALUE(FLOAT, Float)
+ COPY_VALUE(DOUBLE, Double)
+ COPY_VALUE(ENUM, Enum)
+ COPY_VALUE(STRING, String)
+#undef COPY_VALUE
+ case FieldDescriptor::CPPTYPE_MESSAGE: {
+ if (options.replace_message_fields()) {
+ destination_reflection->ClearField(destination, field);
+ }
+ if (source_reflection->HasField(source, field)) {
+ destination_reflection->MutableMessage(destination, field)
+ ->MergeFrom(source_reflection->GetMessage(source, field));
+ }
+ break;
+ }
+ }
+ } else {
+ if (options.replace_repeated_fields()) {
+ destination_reflection->ClearField(destination, field);
+ }
+ switch (field->cpp_type()) {
+#define COPY_REPEATED_VALUE(TYPE, Name) \
+ case FieldDescriptor::CPPTYPE_##TYPE: { \
+ int size = source_reflection->FieldSize(source, field); \
+ for (int i = 0; i < size; ++i) { \
+ destination_reflection->Add##Name( \
+ destination, field, \
+ source_reflection->GetRepeated##Name(source, field, i)); \
+ } \
+ break; \
+ }
+ COPY_REPEATED_VALUE(BOOL, Bool)
+ COPY_REPEATED_VALUE(INT32, Int32)
+ COPY_REPEATED_VALUE(INT64, Int64)
+ COPY_REPEATED_VALUE(UINT32, UInt32)
+ COPY_REPEATED_VALUE(UINT64, UInt64)
+ COPY_REPEATED_VALUE(FLOAT, Float)
+ COPY_REPEATED_VALUE(DOUBLE, Double)
+ COPY_REPEATED_VALUE(ENUM, Enum)
+ COPY_REPEATED_VALUE(STRING, String)
+#undef COPY_REPEATED_VALUE
+ case FieldDescriptor::CPPTYPE_MESSAGE: {
+ int size = source_reflection->FieldSize(source, field);
+ for (int i = 0; i < size; ++i) {
+ destination_reflection->AddMessage(destination, field)
+ ->MergeFrom(
+ source_reflection->GetRepeatedMessage(source, field, i));
+ }
+ break;
+ }
+ }
+ }
+ }
+}
+
+void FieldMaskTree::AddRequiredFieldPath(Node* node,
+ const Descriptor* descriptor) {
+ const 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/NorthstarDedicatedTest/include/protobuf/util/field_mask_util.h b/NorthstarDedicatedTest/include/protobuf/util/field_mask_util.h
new file mode 100644
index 00000000..5bc50fb3
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/util/field_mask_util.h
@@ -0,0 +1,262 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Defines utilities for the FieldMask well known type.
+
+#ifndef GOOGLE_PROTOBUF_UTIL_FIELD_MASK_UTIL_H__
+#define GOOGLE_PROTOBUF_UTIL_FIELD_MASK_UTIL_H__
+
+#include <cstdint>
+#include <string>
+
+#include <field_mask.pb.h>
+#include <descriptor.h>
+#include <stubs/strutil.h>
+
+// Must be included last.
+#include <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 <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_UTIL_FIELD_MASK_UTIL_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/util/field_mask_util_test.cc b/NorthstarDedicatedTest/include/protobuf/util/field_mask_util_test.cc
new file mode 100644
index 00000000..b8e13b97
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/util/field_mask_util_test.cc
@@ -0,0 +1,836 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 <util/field_mask_util.h>
+
+#include <algorithm>
+#include <cstdint>
+#include <vector>
+
+#include <field_mask.pb.h>
+#include <test_util.h>
+#include <unittest.pb.h>
+#include <gtest/gtest.h>
+#include <stubs/logging.h>
+#include <stubs/common.h>
+
+namespace google {
+namespace protobuf {
+namespace util {
+
+class SnakeCaseCamelCaseTest : public ::testing::Test {
+ protected:
+ std::string SnakeCaseToCamelCase(const std::string& input) {
+ std::string output;
+ if (FieldMaskUtil::SnakeCaseToCamelCase(input, &output)) {
+ return output;
+ } else {
+ return "#FAIL#";
+ }
+ }
+
+ std::string CamelCaseToSnakeCase(const std::string& input) {
+ std::string output;
+ if (FieldMaskUtil::CamelCaseToSnakeCase(input, &output)) {
+ return output;
+ } else {
+ return "#FAIL#";
+ }
+ }
+};
+
+namespace {
+
+TEST_F(SnakeCaseCamelCaseTest, SnakeToCamel) {
+ EXPECT_EQ("fooBar", SnakeCaseToCamelCase("foo_bar"));
+ EXPECT_EQ("FooBar", SnakeCaseToCamelCase("_foo_bar"));
+ EXPECT_EQ("foo3Bar", SnakeCaseToCamelCase("foo3_bar"));
+ // No uppercase letter is allowed.
+ EXPECT_EQ("#FAIL#", SnakeCaseToCamelCase("Foo"));
+ // Any character after a "_" must be a lowercase letter.
+ // 1. "_" cannot be followed by another "_".
+ // 2. "_" cannot be followed by a digit.
+ // 3. "_" cannot appear as the last character.
+ EXPECT_EQ("#FAIL#", SnakeCaseToCamelCase("foo__bar"));
+ EXPECT_EQ("#FAIL#", SnakeCaseToCamelCase("foo_3bar"));
+ EXPECT_EQ("#FAIL#", SnakeCaseToCamelCase("foo_bar_"));
+}
+
+TEST_F(SnakeCaseCamelCaseTest, CamelToSnake) {
+ EXPECT_EQ("foo_bar", CamelCaseToSnakeCase("fooBar"));
+ EXPECT_EQ("_foo_bar", CamelCaseToSnakeCase("FooBar"));
+ EXPECT_EQ("foo3_bar", CamelCaseToSnakeCase("foo3Bar"));
+ // "_"s are not allowed.
+ EXPECT_EQ("#FAIL#", CamelCaseToSnakeCase("foo_bar"));
+}
+
+TEST_F(SnakeCaseCamelCaseTest, RoundTripTest) {
+ // Enumerates all possible snake_case names and test that converting it to
+ // camelCase and then to snake_case again will yield the original name.
+ std::string name = "___abc123";
+ std::sort(name.begin(), name.end());
+ do {
+ std::string camelName = SnakeCaseToCamelCase(name);
+ if (camelName != "#FAIL#") {
+ EXPECT_EQ(name, CamelCaseToSnakeCase(camelName));
+ }
+ } while (std::next_permutation(name.begin(), name.end()));
+
+ // Enumerates all possible camelCase names and test that converting it to
+ // snake_case and then to camelCase again will yield the original name.
+ name = "abcABC123";
+ std::sort(name.begin(), name.end());
+ do {
+ std::string camelName = CamelCaseToSnakeCase(name);
+ if (camelName != "#FAIL#") {
+ EXPECT_EQ(name, SnakeCaseToCamelCase(camelName));
+ }
+ } while (std::next_permutation(name.begin(), name.end()));
+}
+
+using google::protobuf::FieldMask;
+using protobuf_unittest::NestedTestAllTypes;
+using protobuf_unittest::TestAllTypes;
+using protobuf_unittest::TestRequired;
+using protobuf_unittest::TestRequiredMessage;
+
+TEST(FieldMaskUtilTest, StringFormat) {
+ FieldMask mask;
+ EXPECT_EQ("", FieldMaskUtil::ToString(mask));
+ mask.add_paths("foo_bar");
+ EXPECT_EQ("foo_bar", FieldMaskUtil::ToString(mask));
+ mask.add_paths("baz_quz");
+ EXPECT_EQ("foo_bar,baz_quz", FieldMaskUtil::ToString(mask));
+
+ FieldMaskUtil::FromString("", &mask);
+ EXPECT_EQ(0, mask.paths_size());
+ FieldMaskUtil::FromString("fooBar", &mask);
+ EXPECT_EQ(1, mask.paths_size());
+ EXPECT_EQ("fooBar", mask.paths(0));
+ FieldMaskUtil::FromString("fooBar,bazQuz", &mask);
+ EXPECT_EQ(2, mask.paths_size());
+ EXPECT_EQ("fooBar", mask.paths(0));
+ EXPECT_EQ("bazQuz", mask.paths(1));
+}
+
+TEST(FieldMaskUtilTest, JsonStringFormat) {
+ FieldMask mask;
+ std::string value;
+ EXPECT_TRUE(FieldMaskUtil::ToJsonString(mask, &value));
+ EXPECT_EQ("", value);
+ mask.add_paths("foo_bar");
+ EXPECT_TRUE(FieldMaskUtil::ToJsonString(mask, &value));
+ EXPECT_EQ("fooBar", value);
+ mask.add_paths("bar_quz");
+ EXPECT_TRUE(FieldMaskUtil::ToJsonString(mask, &value));
+ EXPECT_EQ("fooBar,barQuz", value);
+
+ FieldMaskUtil::FromJsonString("", &mask);
+ EXPECT_EQ(0, mask.paths_size());
+ FieldMaskUtil::FromJsonString("fooBar", &mask);
+ EXPECT_EQ(1, mask.paths_size());
+ EXPECT_EQ("foo_bar", mask.paths(0));
+ FieldMaskUtil::FromJsonString("fooBar,bazQuz", &mask);
+ EXPECT_EQ(2, mask.paths_size());
+ EXPECT_EQ("foo_bar", mask.paths(0));
+ EXPECT_EQ("baz_quz", mask.paths(1));
+}
+
+TEST(FieldMaskUtilTest, FromFieldNumbers) {
+ FieldMask mask;
+ std::vector<int64_t> field_numbers = {
+ TestAllTypes::kOptionalInt64FieldNumber,
+ TestAllTypes::kOptionalBoolFieldNumber,
+ TestAllTypes::kRepeatedStringFieldNumber,
+ };
+ FieldMaskUtil::FromFieldNumbers<TestAllTypes>(field_numbers, &mask);
+ ASSERT_EQ(3, mask.paths_size());
+ EXPECT_EQ("optional_int64", mask.paths(0));
+ EXPECT_EQ("optional_bool", mask.paths(1));
+ EXPECT_EQ("repeated_string", mask.paths(2));
+}
+
+TEST(FieldMaskUtilTest, GetFieldDescriptors) {
+ std::vector<const FieldDescriptor*> field_descriptors;
+ EXPECT_TRUE(FieldMaskUtil::GetFieldDescriptors(
+ TestAllTypes::descriptor(), "optional_int32", &field_descriptors));
+ EXPECT_EQ(1, field_descriptors.size());
+ EXPECT_EQ("optional_int32", field_descriptors[0]->name());
+ EXPECT_FALSE(FieldMaskUtil::GetFieldDescriptors(
+ TestAllTypes::descriptor(), "optional_nonexist", nullptr));
+ EXPECT_TRUE(FieldMaskUtil::GetFieldDescriptors(TestAllTypes::descriptor(),
+ "optional_nested_message.bb",
+ &field_descriptors));
+ EXPECT_EQ(2, field_descriptors.size());
+ EXPECT_EQ("optional_nested_message", field_descriptors[0]->name());
+ EXPECT_EQ("bb", field_descriptors[1]->name());
+ EXPECT_FALSE(FieldMaskUtil::GetFieldDescriptors(
+ TestAllTypes::descriptor(), "optional_nested_message.nonexist", nullptr));
+ // FieldMask cannot be used to specify sub-fields of a repeated message.
+ EXPECT_FALSE(FieldMaskUtil::GetFieldDescriptors(
+ TestAllTypes::descriptor(), "repeated_nested_message.bb", nullptr));
+}
+
+TEST(FieldMaskUtilTest, TestIsVaildPath) {
+ EXPECT_TRUE(FieldMaskUtil::IsValidPath<TestAllTypes>("optional_int32"));
+ EXPECT_FALSE(FieldMaskUtil::IsValidPath<TestAllTypes>("optional_nonexist"));
+ EXPECT_TRUE(
+ FieldMaskUtil::IsValidPath<TestAllTypes>("optional_nested_message.bb"));
+ EXPECT_FALSE(FieldMaskUtil::IsValidPath<TestAllTypes>(
+ "optional_nested_message.nonexist"));
+ // FieldMask cannot be used to specify sub-fields of a repeated message.
+ EXPECT_FALSE(
+ FieldMaskUtil::IsValidPath<TestAllTypes>("repeated_nested_message.bb"));
+}
+
+TEST(FieldMaskUtilTest, TestIsValidFieldMask) {
+ FieldMask mask;
+ FieldMaskUtil::FromString("optional_int32,optional_nested_message.bb", &mask);
+ EXPECT_TRUE(FieldMaskUtil::IsValidFieldMask<TestAllTypes>(mask));
+
+ FieldMaskUtil::FromString(
+ "optional_int32,optional_nested_message.bb,optional_nonexist", &mask);
+ EXPECT_FALSE(FieldMaskUtil::IsValidFieldMask<TestAllTypes>(mask));
+}
+
+TEST(FieldMaskUtilTest, TestGetFieldMaskForAllFields) {
+ FieldMask mask;
+ mask = FieldMaskUtil::GetFieldMaskForAllFields<TestAllTypes::NestedMessage>();
+ EXPECT_EQ(1, mask.paths_size());
+ EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("bb", mask));
+
+ mask = FieldMaskUtil::GetFieldMaskForAllFields<TestAllTypes>();
+ EXPECT_EQ(75, mask.paths_size());
+ EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("optional_int32", mask));
+ EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("optional_int64", mask));
+ EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("optional_uint32", mask));
+ EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("optional_uint64", mask));
+ EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("optional_sint32", mask));
+ EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("optional_sint64", mask));
+ EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("optional_fixed32", mask));
+ EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("optional_fixed64", mask));
+ EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("optional_sfixed32", mask));
+ EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("optional_sfixed64", mask));
+ EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("optional_float", mask));
+ EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("optional_double", mask));
+ EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("optional_bool", mask));
+ EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("optional_string", mask));
+ EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("optional_bytes", mask));
+ EXPECT_TRUE(
+ FieldMaskUtil::IsPathInFieldMask("optional_nested_message", mask));
+ EXPECT_TRUE(
+ FieldMaskUtil::IsPathInFieldMask("optional_foreign_message", mask));
+ EXPECT_TRUE(
+ FieldMaskUtil::IsPathInFieldMask("optional_import_message", mask));
+ EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("optional_nested_enum", mask));
+ EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("optional_foreign_enum", mask));
+ EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("optional_import_enum", mask));
+ EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("repeated_int32", mask));
+ EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("repeated_int64", mask));
+ EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("repeated_uint32", mask));
+ EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("repeated_uint64", mask));
+ EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("repeated_sint32", mask));
+ EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("repeated_sint64", mask));
+ EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("repeated_fixed32", mask));
+ EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("repeated_fixed64", mask));
+ EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("repeated_sfixed32", mask));
+ EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("repeated_sfixed64", mask));
+ EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("repeated_float", mask));
+ EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("repeated_double", mask));
+ EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("repeated_bool", mask));
+ EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("repeated_string", mask));
+ EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("repeated_bytes", mask));
+ EXPECT_TRUE(
+ FieldMaskUtil::IsPathInFieldMask("repeated_nested_message", mask));
+ EXPECT_TRUE(
+ FieldMaskUtil::IsPathInFieldMask("repeated_foreign_message", mask));
+ EXPECT_TRUE(
+ FieldMaskUtil::IsPathInFieldMask("repeated_import_message", mask));
+ EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("repeated_nested_enum", mask));
+ EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("repeated_foreign_enum", mask));
+ EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("repeated_import_enum", mask));
+}
+
+TEST(FieldMaskUtilTest, TestToCanonicalForm) {
+ FieldMask in, out;
+ // Paths will be sorted.
+ FieldMaskUtil::FromString("baz.quz,bar,foo", &in);
+ FieldMaskUtil::ToCanonicalForm(in, &out);
+ EXPECT_EQ("bar,baz.quz,foo", FieldMaskUtil::ToString(out));
+ // Duplicated paths will be removed.
+ FieldMaskUtil::FromString("foo,bar,foo", &in);
+ FieldMaskUtil::ToCanonicalForm(in, &out);
+ EXPECT_EQ("bar,foo", FieldMaskUtil::ToString(out));
+ // Sub-paths of other paths will be removed.
+ FieldMaskUtil::FromString("foo.b1,bar.b1,foo.b2,bar", &in);
+ FieldMaskUtil::ToCanonicalForm(in, &out);
+ EXPECT_EQ("bar,foo.b1,foo.b2", FieldMaskUtil::ToString(out));
+
+ // Test more deeply nested cases.
+ FieldMaskUtil::FromString(
+ "foo.bar.baz1,"
+ "foo.bar.baz2.quz,"
+ "foo.bar.baz2",
+ &in);
+ FieldMaskUtil::ToCanonicalForm(in, &out);
+ EXPECT_EQ("foo.bar.baz1,foo.bar.baz2", FieldMaskUtil::ToString(out));
+ FieldMaskUtil::FromString(
+ "foo.bar.baz1,"
+ "foo.bar.baz2,"
+ "foo.bar.baz2.quz",
+ &in);
+ FieldMaskUtil::ToCanonicalForm(in, &out);
+ EXPECT_EQ("foo.bar.baz1,foo.bar.baz2", FieldMaskUtil::ToString(out));
+ FieldMaskUtil::FromString(
+ "foo.bar.baz1,"
+ "foo.bar.baz2,"
+ "foo.bar.baz2.quz,"
+ "foo.bar",
+ &in);
+ FieldMaskUtil::ToCanonicalForm(in, &out);
+ EXPECT_EQ("foo.bar", FieldMaskUtil::ToString(out));
+ FieldMaskUtil::FromString(
+ "foo.bar.baz1,"
+ "foo.bar.baz2,"
+ "foo.bar.baz2.quz,"
+ "foo",
+ &in);
+ FieldMaskUtil::ToCanonicalForm(in, &out);
+ EXPECT_EQ("foo", FieldMaskUtil::ToString(out));
+}
+
+TEST(FieldMaskUtilTest, TestUnion) {
+ FieldMask mask1, mask2, out;
+ // Test cases without overlapping.
+ FieldMaskUtil::FromString("foo,baz", &mask1);
+ FieldMaskUtil::FromString("bar,quz", &mask2);
+ FieldMaskUtil::Union(mask1, mask2, &out);
+ EXPECT_EQ("bar,baz,foo,quz", FieldMaskUtil::ToString(out));
+ // Overlap with duplicated paths.
+ FieldMaskUtil::FromString("foo,baz.bb", &mask1);
+ FieldMaskUtil::FromString("baz.bb,quz", &mask2);
+ FieldMaskUtil::Union(mask1, mask2, &out);
+ EXPECT_EQ("baz.bb,foo,quz", FieldMaskUtil::ToString(out));
+ // Overlap with paths covering some other paths.
+ FieldMaskUtil::FromString("foo.bar.baz,quz", &mask1);
+ FieldMaskUtil::FromString("foo.bar,bar", &mask2);
+ FieldMaskUtil::Union(mask1, mask2, &out);
+ EXPECT_EQ("bar,foo.bar,quz", FieldMaskUtil::ToString(out));
+}
+
+TEST(FieldMaskUtilTest, TestIntersect) {
+ FieldMask mask1, mask2, out;
+ // Test cases without overlapping.
+ FieldMaskUtil::FromString("foo,baz", &mask1);
+ FieldMaskUtil::FromString("bar,quz", &mask2);
+ FieldMaskUtil::Intersect(mask1, mask2, &out);
+ EXPECT_EQ("", FieldMaskUtil::ToString(out));
+ // Overlap with duplicated paths.
+ FieldMaskUtil::FromString("foo,baz.bb", &mask1);
+ FieldMaskUtil::FromString("baz.bb,quz", &mask2);
+ FieldMaskUtil::Intersect(mask1, mask2, &out);
+ EXPECT_EQ("baz.bb", FieldMaskUtil::ToString(out));
+ // Overlap with paths covering some other paths.
+ FieldMaskUtil::FromString("foo.bar.baz,quz", &mask1);
+ FieldMaskUtil::FromString("foo.bar,bar", &mask2);
+ FieldMaskUtil::Intersect(mask1, mask2, &out);
+ EXPECT_EQ("foo.bar.baz", FieldMaskUtil::ToString(out));
+}
+
+TEST(FieldMaskUtilTest, TestSubtract) {
+ FieldMask mask1, mask2, out;
+ // Normal case.
+ FieldMaskUtil::FromString(
+ "optional_int32,optional_uint64,optional_nested_message,optional_foreign_"
+ "message,repeated_int32,repeated_foreign_message,repeated_nested_message."
+ "bb",
+ &mask1);
+
+ FieldMaskUtil::FromString(
+ "optional_int32,optional_nested_message.bb,optional_foreign_message.c,"
+ "repeated_int32,repeated_nested_message.bb,repeated_foreign_message.f,"
+ "repeated_foreign_message.d,repeated_nested_message.bb,repeated_uint32",
+ &mask2);
+
+ FieldMaskUtil::Subtract<TestAllTypes>(mask1, mask2, &out);
+ EXPECT_EQ(
+ "optional_foreign_message.d,optional_uint64,repeated_foreign_message.c",
+ FieldMaskUtil::ToString(out));
+
+ // mask1 is empty.
+ FieldMaskUtil::FromString("", &mask1);
+ FieldMaskUtil::Subtract<TestAllTypes>(mask1, mask2, &out);
+ EXPECT_EQ("", FieldMaskUtil::ToString(out));
+
+ // mask1 is "optional_nested_message" and mask2 is
+ // "optional_nested_message.nonexist_field".
+ FieldMaskUtil::FromString("optional_nested_message", &mask1);
+ FieldMaskUtil::FromString("optional_nested_message.nonexist_field", &mask2);
+ FieldMaskUtil::Subtract<TestAllTypes>(mask1, mask2, &out);
+ EXPECT_EQ("optional_nested_message", FieldMaskUtil::ToString(out));
+
+ // mask1 is "optional_nested_message" and mask2 is
+ // "optional_nested_message".
+ FieldMaskUtil::FromString("optional_nested_message", &mask1);
+ FieldMaskUtil::FromString("optional_nested_message", &mask2);
+ FieldMaskUtil::Subtract<TestAllTypes>(mask1, mask2, &out);
+ EXPECT_EQ("", FieldMaskUtil::ToString(out));
+
+ // Regression test for b/72727550
+ FieldMaskUtil::FromString("optional_foreign_message.c", &mask1);
+ FieldMaskUtil::FromString("optional_foreign_message,optional_nested_message",
+ &mask2);
+ FieldMaskUtil::Subtract<TestAllTypes>(mask1, mask2, &out);
+ EXPECT_EQ("", FieldMaskUtil::ToString(out));
+}
+
+TEST(FieldMaskUtilTest, TestIspathInFieldMask) {
+ FieldMask mask;
+ FieldMaskUtil::FromString("foo.bar", &mask);
+ EXPECT_FALSE(FieldMaskUtil::IsPathInFieldMask("", mask));
+ EXPECT_FALSE(FieldMaskUtil::IsPathInFieldMask("foo", mask));
+ EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("foo.bar", mask));
+ EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("foo.bar.baz", mask));
+ EXPECT_FALSE(FieldMaskUtil::IsPathInFieldMask("foo.bar0.baz", mask));
+}
+
+TEST(FieldMaskUtilTest, MergeMessage) {
+ TestAllTypes src, dst;
+ TestUtil::SetAllFields(&src);
+ FieldMaskUtil::MergeOptions options;
+
+#define TEST_MERGE_ONE_PRIMITIVE_FIELD(field_name) \
+ { \
+ TestAllTypes tmp; \
+ tmp.set_##field_name(src.field_name()); \
+ FieldMask mask; \
+ mask.add_paths(#field_name); \
+ dst.Clear(); \
+ FieldMaskUtil::MergeMessageTo(src, mask, options, &dst); \
+ EXPECT_EQ(tmp.DebugString(), dst.DebugString()); \
+ src.clear_##field_name(); \
+ tmp.clear_##field_name(); \
+ FieldMaskUtil::MergeMessageTo(src, mask, options, &dst); \
+ EXPECT_EQ(tmp.DebugString(), dst.DebugString()); \
+ }
+ TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_int32)
+ TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_int64)
+ TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_uint32)
+ TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_uint64)
+ TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_sint32)
+ TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_sint64)
+ TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_fixed32)
+ TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_fixed64)
+ TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_sfixed32)
+ TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_sfixed64)
+ TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_float)
+ TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_double)
+ TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_bool)
+ TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_string)
+ TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_bytes)
+ TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_nested_enum)
+ TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_foreign_enum)
+ TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_import_enum)
+#undef TEST_MERGE_ONE_PRIMITIVE_FIELD
+
+#define TEST_MERGE_ONE_FIELD(field_name) \
+ { \
+ TestAllTypes tmp; \
+ *tmp.mutable_##field_name() = src.field_name(); \
+ FieldMask mask; \
+ mask.add_paths(#field_name); \
+ dst.Clear(); \
+ FieldMaskUtil::MergeMessageTo(src, mask, options, &dst); \
+ EXPECT_EQ(tmp.DebugString(), dst.DebugString()); \
+ }
+ TEST_MERGE_ONE_FIELD(optional_nested_message)
+ TEST_MERGE_ONE_FIELD(optional_foreign_message)
+ TEST_MERGE_ONE_FIELD(optional_import_message)
+
+ TEST_MERGE_ONE_FIELD(repeated_int32)
+ TEST_MERGE_ONE_FIELD(repeated_int64)
+ TEST_MERGE_ONE_FIELD(repeated_uint32)
+ TEST_MERGE_ONE_FIELD(repeated_uint64)
+ TEST_MERGE_ONE_FIELD(repeated_sint32)
+ TEST_MERGE_ONE_FIELD(repeated_sint64)
+ TEST_MERGE_ONE_FIELD(repeated_fixed32)
+ TEST_MERGE_ONE_FIELD(repeated_fixed64)
+ TEST_MERGE_ONE_FIELD(repeated_sfixed32)
+ TEST_MERGE_ONE_FIELD(repeated_sfixed64)
+ TEST_MERGE_ONE_FIELD(repeated_float)
+ TEST_MERGE_ONE_FIELD(repeated_double)
+ TEST_MERGE_ONE_FIELD(repeated_bool)
+ TEST_MERGE_ONE_FIELD(repeated_string)
+ TEST_MERGE_ONE_FIELD(repeated_bytes)
+ TEST_MERGE_ONE_FIELD(repeated_nested_message)
+ TEST_MERGE_ONE_FIELD(repeated_foreign_message)
+ TEST_MERGE_ONE_FIELD(repeated_import_message)
+ TEST_MERGE_ONE_FIELD(repeated_nested_enum)
+ TEST_MERGE_ONE_FIELD(repeated_foreign_enum)
+ TEST_MERGE_ONE_FIELD(repeated_import_enum)
+#undef TEST_MERGE_ONE_FIELD
+
+ // Test merge nested fields.
+ NestedTestAllTypes nested_src, nested_dst;
+ nested_src.mutable_child()->mutable_payload()->set_optional_int32(1234);
+ nested_src.mutable_child()
+ ->mutable_child()
+ ->mutable_payload()
+ ->set_optional_int32(5678);
+ FieldMask mask;
+ FieldMaskUtil::FromString("child.payload", &mask);
+ FieldMaskUtil::MergeMessageTo(nested_src, mask, options, &nested_dst);
+ EXPECT_EQ(1234, nested_dst.child().payload().optional_int32());
+ EXPECT_EQ(0, nested_dst.child().child().payload().optional_int32());
+
+ FieldMaskUtil::FromString("child.child.payload", &mask);
+ FieldMaskUtil::MergeMessageTo(nested_src, mask, options, &nested_dst);
+ EXPECT_EQ(1234, nested_dst.child().payload().optional_int32());
+ EXPECT_EQ(5678, nested_dst.child().child().payload().optional_int32());
+
+ nested_dst.Clear();
+ FieldMaskUtil::FromString("child.child.payload", &mask);
+ FieldMaskUtil::MergeMessageTo(nested_src, mask, options, &nested_dst);
+ EXPECT_EQ(0, nested_dst.child().payload().optional_int32());
+ EXPECT_EQ(5678, nested_dst.child().child().payload().optional_int32());
+
+ nested_dst.Clear();
+ FieldMaskUtil::FromString("child", &mask);
+ FieldMaskUtil::MergeMessageTo(nested_src, mask, options, &nested_dst);
+ EXPECT_EQ(1234, nested_dst.child().payload().optional_int32());
+ EXPECT_EQ(5678, nested_dst.child().child().payload().optional_int32());
+
+ // Test MergeOptions.
+
+ nested_dst.Clear();
+ nested_dst.mutable_child()->mutable_payload()->set_optional_int64(4321);
+ // Message fields will be merged by default.
+ FieldMaskUtil::FromString("child.payload", &mask);
+ FieldMaskUtil::MergeMessageTo(nested_src, mask, options, &nested_dst);
+ EXPECT_EQ(1234, nested_dst.child().payload().optional_int32());
+ EXPECT_EQ(4321, nested_dst.child().payload().optional_int64());
+ // Change the behavior to replace message fields.
+ options.set_replace_message_fields(true);
+ FieldMaskUtil::FromString("child.payload", &mask);
+ FieldMaskUtil::MergeMessageTo(nested_src, mask, options, &nested_dst);
+ EXPECT_EQ(1234, nested_dst.child().payload().optional_int32());
+ EXPECT_EQ(0, nested_dst.child().payload().optional_int64());
+
+ // By default, fields missing in source are not cleared in destination.
+ options.set_replace_message_fields(false);
+ nested_dst.mutable_payload();
+ EXPECT_TRUE(nested_dst.has_payload());
+ FieldMaskUtil::FromString("payload", &mask);
+ FieldMaskUtil::MergeMessageTo(nested_src, mask, options, &nested_dst);
+ EXPECT_TRUE(nested_dst.has_payload());
+ // But they are cleared when replacing message fields.
+ options.set_replace_message_fields(true);
+ nested_dst.Clear();
+ nested_dst.mutable_payload();
+ FieldMaskUtil::FromString("payload", &mask);
+ FieldMaskUtil::MergeMessageTo(nested_src, mask, options, &nested_dst);
+ EXPECT_FALSE(nested_dst.has_payload());
+
+ nested_src.mutable_payload()->add_repeated_int32(1234);
+ nested_dst.mutable_payload()->add_repeated_int32(5678);
+ // Repeated fields will be appended by default.
+ FieldMaskUtil::FromString("payload.repeated_int32", &mask);
+ FieldMaskUtil::MergeMessageTo(nested_src, mask, options, &nested_dst);
+ ASSERT_EQ(2, nested_dst.payload().repeated_int32_size());
+ EXPECT_EQ(5678, nested_dst.payload().repeated_int32(0));
+ EXPECT_EQ(1234, nested_dst.payload().repeated_int32(1));
+ // Change the behavior to replace repeated fields.
+ options.set_replace_repeated_fields(true);
+ FieldMaskUtil::FromString("payload.repeated_int32", &mask);
+ FieldMaskUtil::MergeMessageTo(nested_src, mask, options, &nested_dst);
+ ASSERT_EQ(1, nested_dst.payload().repeated_int32_size());
+ EXPECT_EQ(1234, nested_dst.payload().repeated_int32(0));
+}
+
+TEST(FieldMaskUtilTest, TrimMessage) {
+#define TEST_TRIM_ONE_PRIMITIVE_FIELD(field_name) \
+ { \
+ TestAllTypes msg; \
+ TestUtil::SetAllFields(&msg); \
+ TestAllTypes tmp; \
+ tmp.set_##field_name(msg.field_name()); \
+ FieldMask mask; \
+ mask.add_paths(#field_name); \
+ FieldMaskUtil::TrimMessage(mask, &msg); \
+ EXPECT_EQ(tmp.DebugString(), msg.DebugString()); \
+ }
+ TEST_TRIM_ONE_PRIMITIVE_FIELD(optional_int32)
+ TEST_TRIM_ONE_PRIMITIVE_FIELD(optional_int64)
+ TEST_TRIM_ONE_PRIMITIVE_FIELD(optional_uint32)
+ TEST_TRIM_ONE_PRIMITIVE_FIELD(optional_uint64)
+ TEST_TRIM_ONE_PRIMITIVE_FIELD(optional_sint32)
+ TEST_TRIM_ONE_PRIMITIVE_FIELD(optional_sint64)
+ TEST_TRIM_ONE_PRIMITIVE_FIELD(optional_fixed32)
+ TEST_TRIM_ONE_PRIMITIVE_FIELD(optional_fixed64)
+ TEST_TRIM_ONE_PRIMITIVE_FIELD(optional_sfixed32)
+ TEST_TRIM_ONE_PRIMITIVE_FIELD(optional_sfixed64)
+ TEST_TRIM_ONE_PRIMITIVE_FIELD(optional_float)
+ TEST_TRIM_ONE_PRIMITIVE_FIELD(optional_double)
+ TEST_TRIM_ONE_PRIMITIVE_FIELD(optional_bool)
+ TEST_TRIM_ONE_PRIMITIVE_FIELD(optional_string)
+ TEST_TRIM_ONE_PRIMITIVE_FIELD(optional_bytes)
+ TEST_TRIM_ONE_PRIMITIVE_FIELD(optional_nested_enum)
+ TEST_TRIM_ONE_PRIMITIVE_FIELD(optional_foreign_enum)
+ TEST_TRIM_ONE_PRIMITIVE_FIELD(optional_import_enum)
+#undef TEST_TRIM_ONE_PRIMITIVE_FIELD
+
+#define TEST_TRIM_ONE_FIELD(field_name) \
+ { \
+ TestAllTypes msg; \
+ TestUtil::SetAllFields(&msg); \
+ TestAllTypes tmp; \
+ *tmp.mutable_##field_name() = msg.field_name(); \
+ FieldMask mask; \
+ mask.add_paths(#field_name); \
+ FieldMaskUtil::TrimMessage(mask, &msg); \
+ EXPECT_EQ(tmp.DebugString(), msg.DebugString()); \
+ }
+ TEST_TRIM_ONE_FIELD(optional_nested_message)
+ TEST_TRIM_ONE_FIELD(optional_foreign_message)
+ TEST_TRIM_ONE_FIELD(optional_import_message)
+
+ TEST_TRIM_ONE_FIELD(repeated_int32)
+ TEST_TRIM_ONE_FIELD(repeated_int64)
+ TEST_TRIM_ONE_FIELD(repeated_uint32)
+ TEST_TRIM_ONE_FIELD(repeated_uint64)
+ TEST_TRIM_ONE_FIELD(repeated_sint32)
+ TEST_TRIM_ONE_FIELD(repeated_sint64)
+ TEST_TRIM_ONE_FIELD(repeated_fixed32)
+ TEST_TRIM_ONE_FIELD(repeated_fixed64)
+ TEST_TRIM_ONE_FIELD(repeated_sfixed32)
+ TEST_TRIM_ONE_FIELD(repeated_sfixed64)
+ TEST_TRIM_ONE_FIELD(repeated_float)
+ TEST_TRIM_ONE_FIELD(repeated_double)
+ TEST_TRIM_ONE_FIELD(repeated_bool)
+ TEST_TRIM_ONE_FIELD(repeated_string)
+ TEST_TRIM_ONE_FIELD(repeated_bytes)
+ TEST_TRIM_ONE_FIELD(repeated_nested_message)
+ TEST_TRIM_ONE_FIELD(repeated_foreign_message)
+ TEST_TRIM_ONE_FIELD(repeated_import_message)
+ TEST_TRIM_ONE_FIELD(repeated_nested_enum)
+ TEST_TRIM_ONE_FIELD(repeated_foreign_enum)
+ TEST_TRIM_ONE_FIELD(repeated_import_enum)
+#undef TEST_TRIM_ONE_FIELD
+
+ // Test trim nested fields.
+ NestedTestAllTypes nested_msg;
+ nested_msg.mutable_child()->mutable_payload()->set_optional_int32(1234);
+ nested_msg.mutable_child()
+ ->mutable_child()
+ ->mutable_payload()
+ ->set_optional_int32(5678);
+ NestedTestAllTypes trimmed_msg(nested_msg);
+ FieldMask mask;
+ FieldMaskUtil::FromString("child.payload", &mask);
+ FieldMaskUtil::TrimMessage(mask, &trimmed_msg);
+ EXPECT_EQ(1234, trimmed_msg.child().payload().optional_int32());
+ EXPECT_EQ(0, trimmed_msg.child().child().payload().optional_int32());
+
+ trimmed_msg = nested_msg;
+ FieldMaskUtil::FromString("child.child.payload", &mask);
+ FieldMaskUtil::TrimMessage(mask, &trimmed_msg);
+ EXPECT_EQ(0, trimmed_msg.child().payload().optional_int32());
+ EXPECT_EQ(5678, trimmed_msg.child().child().payload().optional_int32());
+
+ trimmed_msg = nested_msg;
+ FieldMaskUtil::FromString("child", &mask);
+ FieldMaskUtil::TrimMessage(mask, &trimmed_msg);
+ EXPECT_EQ(1234, trimmed_msg.child().payload().optional_int32());
+ EXPECT_EQ(5678, trimmed_msg.child().child().payload().optional_int32());
+
+ trimmed_msg = nested_msg;
+ FieldMaskUtil::FromString("child.child", &mask);
+ FieldMaskUtil::TrimMessage(mask, &trimmed_msg);
+ EXPECT_EQ(0, trimmed_msg.child().payload().optional_int32());
+ EXPECT_EQ(5678, trimmed_msg.child().child().payload().optional_int32());
+
+ // Verify than an empty FieldMask trims nothing
+ TestAllTypes all_types_msg;
+ TestUtil::SetAllFields(&all_types_msg);
+ TestAllTypes trimmed_all_types(all_types_msg);
+ FieldMask empty_mask;
+ FieldMaskUtil::TrimMessage(empty_mask, &trimmed_all_types);
+ EXPECT_EQ(trimmed_all_types.DebugString(), all_types_msg.DebugString());
+
+ // Test trim required fields with keep_required_fields is set true.
+ FieldMaskUtil::TrimOptions options;
+ TestRequired required_msg_1;
+ required_msg_1.set_a(1234);
+ required_msg_1.set_b(3456);
+ required_msg_1.set_c(5678);
+ TestRequired trimmed_required_msg_1(required_msg_1);
+ FieldMaskUtil::FromString("dummy2", &mask);
+ options.set_keep_required_fields(true);
+ FieldMaskUtil::TrimMessage(mask, &trimmed_required_msg_1, options);
+ EXPECT_EQ(trimmed_required_msg_1.DebugString(), required_msg_1.DebugString());
+
+ // Test trim required fields with keep_required_fields is set false.
+ required_msg_1.clear_a();
+ required_msg_1.clear_b();
+ required_msg_1.clear_c();
+ options.set_keep_required_fields(false);
+ FieldMaskUtil::TrimMessage(mask, &trimmed_required_msg_1, options);
+ EXPECT_EQ(trimmed_required_msg_1.DebugString(), required_msg_1.DebugString());
+
+ // Test trim required message with keep_required_fields is set true.
+ TestRequiredMessage required_msg_2;
+ required_msg_2.mutable_optional_message()->set_a(1234);
+ required_msg_2.mutable_optional_message()->set_b(3456);
+ required_msg_2.mutable_optional_message()->set_c(5678);
+ required_msg_2.mutable_required_message()->set_a(1234);
+ required_msg_2.mutable_required_message()->set_b(3456);
+ required_msg_2.mutable_required_message()->set_c(5678);
+ required_msg_2.mutable_required_message()->set_dummy2(7890);
+ TestRequired* repeated_msg = required_msg_2.add_repeated_message();
+ repeated_msg->set_a(1234);
+ repeated_msg->set_b(3456);
+ repeated_msg->set_c(5678);
+ TestRequiredMessage trimmed_required_msg_2(required_msg_2);
+ FieldMaskUtil::FromString("optional_message.dummy2", &mask);
+ options.set_keep_required_fields(true);
+ required_msg_2.clear_repeated_message();
+ required_msg_2.mutable_required_message()->clear_dummy2();
+ FieldMaskUtil::TrimMessage(mask, &trimmed_required_msg_2, options);
+ EXPECT_EQ(trimmed_required_msg_2.DebugString(), required_msg_2.DebugString());
+
+ FieldMaskUtil::FromString("required_message", &mask);
+ required_msg_2.mutable_required_message()->set_dummy2(7890);
+ trimmed_required_msg_2.mutable_required_message()->set_dummy2(7890);
+ required_msg_2.clear_optional_message();
+ FieldMaskUtil::TrimMessage(mask, &trimmed_required_msg_2, options);
+ EXPECT_EQ(trimmed_required_msg_2.DebugString(), required_msg_2.DebugString());
+
+ // Test trim required message with keep_required_fields is set false.
+ FieldMaskUtil::FromString("required_message.dummy2", &mask);
+ required_msg_2.mutable_required_message()->clear_a();
+ required_msg_2.mutable_required_message()->clear_b();
+ required_msg_2.mutable_required_message()->clear_c();
+ options.set_keep_required_fields(false);
+ FieldMaskUtil::TrimMessage(mask, &trimmed_required_msg_2, options);
+ EXPECT_EQ(trimmed_required_msg_2.DebugString(), required_msg_2.DebugString());
+
+ // Verify that trimming an empty message has no effect. In particular, fields
+ // mentioned in the field mask should not be created or changed.
+ TestAllTypes empty_msg;
+ FieldMaskUtil::FromString(
+ "optional_int32,optional_bytes,optional_nested_message.bb", &mask);
+ FieldMaskUtil::TrimMessage(mask, &empty_msg);
+ EXPECT_FALSE(empty_msg.has_optional_int32());
+ EXPECT_FALSE(empty_msg.has_optional_bytes());
+ EXPECT_FALSE(empty_msg.has_optional_nested_message());
+
+ // Verify trimming of oneof fields. This should work as expected even if
+ // multiple elements of the same oneof are included in the FieldMask.
+ TestAllTypes oneof_msg;
+ oneof_msg.set_oneof_uint32(11);
+ FieldMaskUtil::FromString("oneof_uint32,oneof_nested_message.bb", &mask);
+ FieldMaskUtil::TrimMessage(mask, &oneof_msg);
+ EXPECT_EQ(11, oneof_msg.oneof_uint32());
+}
+
+TEST(FieldMaskUtilTest, TrimMessageReturnValue) {
+ FieldMask mask;
+ TestAllTypes trimed_msg;
+ TestAllTypes default_msg;
+
+ // Field mask on optional field.
+ FieldMaskUtil::FromString("optional_int32", &mask);
+
+ // Verify that if a message is updated by FieldMaskUtil::TrimMessage(), the
+ // function returns true.
+ // Test on primary field.
+ trimed_msg.set_optional_string("abc");
+ EXPECT_TRUE(FieldMaskUtil::TrimMessage(mask, &trimed_msg));
+ EXPECT_EQ(trimed_msg.DebugString(), default_msg.DebugString());
+ trimed_msg.Clear();
+
+ // Test on repeated primary field.
+ trimed_msg.add_repeated_string("abc");
+ trimed_msg.add_repeated_string("def");
+ EXPECT_TRUE(FieldMaskUtil::TrimMessage(mask, &trimed_msg));
+ EXPECT_EQ(trimed_msg.DebugString(), default_msg.DebugString());
+ trimed_msg.Clear();
+
+ // Test on nested message.
+ trimed_msg.mutable_optional_nested_message()->set_bb(123);
+ EXPECT_TRUE(FieldMaskUtil::TrimMessage(mask, &trimed_msg));
+ EXPECT_EQ(trimed_msg.DebugString(), default_msg.DebugString());
+ trimed_msg.Clear();
+
+ // Test on repeated nested message.
+ trimed_msg.add_repeated_nested_message()->set_bb(123);
+ trimed_msg.add_repeated_nested_message()->set_bb(456);
+ EXPECT_TRUE(FieldMaskUtil::TrimMessage(mask, &trimed_msg));
+ EXPECT_EQ(trimed_msg.DebugString(), default_msg.DebugString());
+ trimed_msg.Clear();
+
+ // Test on oneof field.
+ trimed_msg.set_oneof_uint32(123);
+ EXPECT_TRUE(FieldMaskUtil::TrimMessage(mask, &trimed_msg));
+ EXPECT_EQ(trimed_msg.DebugString(), default_msg.DebugString());
+ trimed_msg.Clear();
+
+ // If there is no field set other then those whitelisted,
+ // FieldMaskUtil::TrimMessage() should return false.
+ trimed_msg.set_optional_int32(123);
+ EXPECT_FALSE(FieldMaskUtil::TrimMessage(mask, &trimed_msg));
+ EXPECT_EQ(trimed_msg.optional_int32(), 123);
+ trimed_msg.Clear();
+
+ // Field mask on repeated field.
+ FieldMaskUtil::FromString("repeated_string", &mask);
+ trimed_msg.add_repeated_string("abc");
+ trimed_msg.add_repeated_string("def");
+ EXPECT_FALSE(FieldMaskUtil::TrimMessage(mask, &trimed_msg));
+ EXPECT_EQ(trimed_msg.repeated_string(0), "abc");
+ EXPECT_EQ(trimed_msg.repeated_string(1), "def");
+ trimed_msg.Clear();
+
+ // Field mask on nested message.
+ FieldMaskUtil::FromString("optional_nested_message.bb", &mask);
+ trimed_msg.mutable_optional_nested_message()->set_bb(123);
+ EXPECT_FALSE(FieldMaskUtil::TrimMessage(mask, &trimed_msg));
+ EXPECT_EQ(trimed_msg.optional_nested_message().bb(), 123);
+ trimed_msg.Clear();
+
+ // TODO(b/32443320): field mask on repeated nested message is not yet
+ // supported.
+}
+
+
+} // namespace
+} // namespace util
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/util/internal/constants.h b/NorthstarDedicatedTest/include/protobuf/util/internal/constants.h
new file mode 100644
index 00000000..c43aaa42
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/util/internal/constants.h
@@ -0,0 +1,101 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef GOOGLE_PROTOBUF_UTIL_CONVERTER_CONSTANTS_H__
+#define GOOGLE_PROTOBUF_UTIL_CONVERTER_CONSTANTS_H__
+
+#include <cstdint>
+
+#include <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_CONVERTER_CONSTANTS_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/util/internal/datapiece.cc b/NorthstarDedicatedTest/include/protobuf/util/internal/datapiece.cc
new file mode 100644
index 00000000..b32b37a8
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/util/internal/datapiece.cc
@@ -0,0 +1,423 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <util/internal/datapiece.h>
+
+#include <cmath>
+#include <cstdint>
+#include <limits>
+
+#include <struct.pb.h>
+#include <type.pb.h>
+#include <descriptor.h>
+#include <util/internal/utility.h>
+#include <stubs/status.h>
+#include <stubs/strutil.h>
+#include <stubs/mathutil.h>
+
+namespace google {
+namespace protobuf {
+namespace util {
+namespace converter {
+
+using util::Status;
+
+namespace {
+
+template <typename To, typename From>
+util::StatusOr<To> ValidateNumberConversion(To after, From before) {
+ if (after == before &&
+ MathUtil::Sign<From>(before) == MathUtil::Sign<To>(after)) {
+ return after;
+ } else {
+ return util::InvalidArgumentError(
+ std::is_integral<From>::value ? ValueAsString(before)
+ : std::is_same<From, double>::value ? DoubleAsString(before)
+ : FloatAsString(before));
+ }
+}
+
+// For general conversion between
+// int32, int64, uint32, uint64, double and float
+// except conversion between double and float.
+template <typename To, typename From>
+util::StatusOr<To> NumberConvertAndCheck(From before) {
+ if (std::is_same<From, To>::value) return before;
+
+ To after = static_cast<To>(before);
+ return ValidateNumberConversion(after, before);
+}
+
+// For conversion to integer types (int32, int64, uint32, uint64) from floating
+// point types (double, float) only.
+template <typename To, typename From>
+util::StatusOr<To> FloatingPointToIntConvertAndCheck(From before) {
+ if (std::is_same<From, To>::value) return before;
+
+ To after = static_cast<To>(before);
+ return ValidateNumberConversion(after, before);
+}
+
+// For conversion between double and float only.
+util::StatusOr<double> FloatToDouble(float before) {
+ // Casting float to double should just work as double has more precision
+ // than float.
+ return static_cast<double>(before);
+}
+
+util::StatusOr<float> DoubleToFloat(double before) {
+ if (std::isnan(before)) {
+ return std::numeric_limits<float>::quiet_NaN();
+ } else if (!std::isfinite(before)) {
+ // Converting a double +inf/-inf to float should just work.
+ return static_cast<float>(before);
+ } else if (before > std::numeric_limits<float>::max() ||
+ before < -std::numeric_limits<float>::max()) {
+ // Double value outside of the range of float.
+ return util::InvalidArgumentError(DoubleAsString(before));
+ } else {
+ return static_cast<float>(before);
+ }
+}
+
+} // namespace
+
+util::StatusOr<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/NorthstarDedicatedTest/include/protobuf/util/internal/datapiece.h b/NorthstarDedicatedTest/include/protobuf/util/internal/datapiece.h
new file mode 100644
index 00000000..aa13ae02
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/util/internal/datapiece.h
@@ -0,0 +1,218 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef GOOGLE_PROTOBUF_UTIL_CONVERTER_DATAPIECE_H__
+#define GOOGLE_PROTOBUF_UTIL_CONVERTER_DATAPIECE_H__
+
+#include <cstdint>
+#include <string>
+
+#include <stubs/common.h>
+#include <stubs/logging.h>
+#include <type.pb.h>
+#include <stubs/statusor.h>
+#include <stubs/strutil.h>
+
+#include <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 <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_UTIL_CONVERTER_DATAPIECE_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/util/internal/default_value_objectwriter.cc b/NorthstarDedicatedTest/include/protobuf/util/internal/default_value_objectwriter.cc
new file mode 100644
index 00000000..d3ac429b
--- /dev/null
+++ b/NorthstarDedicatedTest/include/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 <util/internal/default_value_objectwriter.h>
+
+#include <cstdint>
+#include <unordered_map>
+
+#include <util/internal/constants.h>
+#include <util/internal/utility.h>
+#include <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/NorthstarDedicatedTest/include/protobuf/util/internal/default_value_objectwriter.h b/NorthstarDedicatedTest/include/protobuf/util/internal/default_value_objectwriter.h
new file mode 100644
index 00000000..e97d7bf1
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/util/internal/default_value_objectwriter.h
@@ -0,0 +1,332 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef GOOGLE_PROTOBUF_UTIL_CONVERTER_DEFAULT_VALUE_OBJECTWRITER_H__
+#define GOOGLE_PROTOBUF_UTIL_CONVERTER_DEFAULT_VALUE_OBJECTWRITER_H__
+
+#include <cstdint>
+#include <functional>
+#include <memory>
+#include <stack>
+#include <vector>
+
+#include <stubs/common.h>
+#include <util/internal/type_info.h>
+#include <util/internal/datapiece.h>
+#include <util/internal/object_writer.h>
+#include <util/internal/utility.h>
+#include <util/type_resolver.h>
+#include <stubs/strutil.h>
+
+// Must be included last.
+#include <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);
+
+ virtual ~DefaultValueObjectWriter();
+
+ // ObjectWriter methods.
+ DefaultValueObjectWriter* StartObject(StringPiece name) override;
+
+ DefaultValueObjectWriter* EndObject() override;
+
+ DefaultValueObjectWriter* StartList(StringPiece name) override;
+
+ DefaultValueObjectWriter* EndList() override;
+
+ DefaultValueObjectWriter* RenderBool(StringPiece name,
+ bool value) override;
+
+ DefaultValueObjectWriter* RenderInt32(StringPiece name,
+ 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 <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_UTIL_CONVERTER_DEFAULT_VALUE_OBJECTWRITER_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/util/internal/default_value_objectwriter_test.cc b/NorthstarDedicatedTest/include/protobuf/util/internal/default_value_objectwriter_test.cc
new file mode 100644
index 00000000..dad638e4
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/util/internal/default_value_objectwriter_test.cc
@@ -0,0 +1,191 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 <util/internal/default_value_objectwriter.h>
+
+#include <util/internal/expecting_objectwriter.h>
+#include <util/internal/testdata/default_value_test.pb.h>
+#include <util/internal/type_info_test_helper.h>
+#include <util/internal/constants.h>
+#include <gtest/gtest.h>
+
+namespace google {
+namespace protobuf {
+namespace util {
+namespace converter {
+namespace testing {
+
+using proto_util_converter::testing::DefaultValueTest;
+
+// Base class for setting up required state for running default values tests on
+// different descriptors.
+class BaseDefaultValueObjectWriterTest
+ : public ::testing::TestWithParam<testing::TypeInfoSource> {
+ protected:
+ explicit BaseDefaultValueObjectWriterTest(const Descriptor* descriptor)
+ : helper_(GetParam()), mock_(), expects_(&mock_) {
+ helper_.ResetTypeInfo(descriptor);
+ testing_.reset(helper_.NewDefaultValueWriter(
+ std::string(kTypeServiceBaseUrl) + "/" + descriptor->full_name(),
+ &mock_));
+ }
+
+ virtual ~BaseDefaultValueObjectWriterTest() {}
+
+ TypeInfoTestHelper helper_;
+ MockObjectWriter mock_;
+ ExpectingObjectWriter expects_;
+ std::unique_ptr<DefaultValueObjectWriter> testing_;
+};
+
+// Tests to cover some basic DefaultValueObjectWriter use cases. More tests are
+// in the marshalling_test.cc and translator_integration_test.cc.
+class DefaultValueObjectWriterTest : public BaseDefaultValueObjectWriterTest {
+ protected:
+ DefaultValueObjectWriterTest()
+ : BaseDefaultValueObjectWriterTest(DefaultValueTest::descriptor()) {}
+ virtual ~DefaultValueObjectWriterTest() {}
+};
+
+INSTANTIATE_TEST_SUITE_P(DifferentTypeInfoSourceTest,
+ DefaultValueObjectWriterTest,
+ ::testing::Values(
+ testing::USE_TYPE_RESOLVER));
+
+TEST_P(DefaultValueObjectWriterTest, Empty) {
+ // Set expectation
+ expects_.StartObject("")
+ ->RenderDouble("doubleValue", 0.0)
+ ->StartList("repeatedDouble")
+ ->EndList()
+ ->RenderFloat("floatValue", 0.0)
+ ->RenderInt64("int64Value", 0)
+ ->RenderUint64("uint64Value", 0)
+ ->RenderInt32("int32Value", 0)
+ ->RenderUint32("uint32Value", 0)
+ ->RenderBool("boolValue", false)
+ ->RenderString("stringValue", "")
+ ->RenderBytes("bytesValue", "")
+ ->RenderString("enumValue", "ENUM_FIRST")
+ ->EndObject();
+
+ // Actual testing
+ testing_->StartObject("")->EndObject();
+}
+
+TEST_P(DefaultValueObjectWriterTest, NonDefaultDouble) {
+ // Set expectation
+ expects_.StartObject("")
+ ->RenderDouble("doubleValue", 1.0)
+ ->StartList("repeatedDouble")
+ ->EndList()
+ ->RenderFloat("floatValue", 0.0)
+ ->RenderInt64("int64Value", 0)
+ ->RenderUint64("uint64Value", 0)
+ ->RenderInt32("int32Value", 0)
+ ->RenderUint32("uint32Value", 0)
+ ->RenderBool("boolValue", false)
+ ->RenderString("stringValue", "")
+ ->RenderString("enumValue", "ENUM_FIRST")
+ ->EndObject();
+
+ // Actual testing
+ testing_->StartObject("")->RenderDouble("doubleValue", 1.0)->EndObject();
+}
+
+TEST_P(DefaultValueObjectWriterTest, ShouldRetainUnknownField) {
+ // Set expectation
+ expects_.StartObject("")
+ ->RenderDouble("doubleValue", 1.0)
+ ->StartList("repeatedDouble")
+ ->EndList()
+ ->RenderFloat("floatValue", 0.0)
+ ->RenderInt64("int64Value", 0)
+ ->RenderUint64("uint64Value", 0)
+ ->RenderInt32("int32Value", 0)
+ ->RenderUint32("uint32Value", 0)
+ ->RenderBool("boolValue", false)
+ ->RenderString("stringValue", "")
+ ->RenderString("unknown", "abc")
+ ->StartObject("unknownObject")
+ ->RenderString("unknown", "def")
+ ->EndObject()
+ ->RenderString("enumValue", "ENUM_FIRST")
+ ->EndObject();
+
+ // Actual testing
+ testing_->StartObject("")
+ ->RenderDouble("doubleValue", 1.0)
+ ->RenderString("unknown", "abc")
+ ->StartObject("unknownObject")
+ ->RenderString("unknown", "def")
+ ->EndObject()
+ ->EndObject();
+}
+
+
+class DefaultValueObjectWriterSuppressListTest
+ : public BaseDefaultValueObjectWriterTest {
+ protected:
+ DefaultValueObjectWriterSuppressListTest()
+ : BaseDefaultValueObjectWriterTest(DefaultValueTest::descriptor()) {
+ testing_->set_suppress_empty_list(true);
+ }
+ ~DefaultValueObjectWriterSuppressListTest() override {}
+};
+
+INSTANTIATE_TEST_SUITE_P(DifferentTypeInfoSourceTest,
+ DefaultValueObjectWriterSuppressListTest,
+ ::testing::Values(
+ testing::USE_TYPE_RESOLVER));
+
+TEST_P(DefaultValueObjectWriterSuppressListTest, Empty) {
+ // Set expectation. Empty lists should be suppressed.
+ expects_.StartObject("")
+ ->RenderDouble("doubleValue", 0.0)
+ ->RenderFloat("floatValue", 0.0)
+ ->RenderInt64("int64Value", 0)
+ ->RenderUint64("uint64Value", 0)
+ ->RenderInt32("int32Value", 0)
+ ->RenderUint32("uint32Value", 0)
+ ->RenderBool("boolValue", false)
+ ->RenderString("stringValue", "")
+ ->RenderBytes("bytesValue", "")
+ ->RenderString("enumValue", "ENUM_FIRST")
+ ->EndObject();
+
+ // Actual testing
+ testing_->StartObject("")->EndObject();
+}
+} // namespace testing
+} // namespace converter
+} // namespace util
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/util/internal/error_listener.cc b/NorthstarDedicatedTest/include/protobuf/util/internal/error_listener.cc
new file mode 100644
index 00000000..f086a7e1
--- /dev/null
+++ b/NorthstarDedicatedTest/include/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 <util/internal/error_listener.h>
+
+namespace google {
+namespace protobuf {
+namespace util {
+namespace converter {
+
+
+} // namespace converter
+} // namespace util
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/util/internal/error_listener.h b/NorthstarDedicatedTest/include/protobuf/util/internal/error_listener.h
new file mode 100644
index 00000000..df51ff27
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/util/internal/error_listener.h
@@ -0,0 +1,109 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef GOOGLE_PROTOBUF_UTIL_CONVERTER_ERROR_LISTENER_H__
+#define GOOGLE_PROTOBUF_UTIL_CONVERTER_ERROR_LISTENER_H__
+
+#include <algorithm>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include <stubs/callback.h>
+#include <stubs/common.h>
+#include <stubs/logging.h>
+#include <util/internal/location_tracker.h>
+#include <stubs/strutil.h>
+
+// Must be included last.
+#include <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 <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_UTIL_CONVERTER_ERROR_LISTENER_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/util/internal/expecting_objectwriter.h b/NorthstarDedicatedTest/include/protobuf/util/internal/expecting_objectwriter.h
new file mode 100644
index 00000000..414ffd8d
--- /dev/null
+++ b/NorthstarDedicatedTest/include/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_CONVERTER_EXPECTING_OBJECTWRITER_H__
+#define GOOGLE_PROTOBUF_UTIL_CONVERTER_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 <stubs/common.h>
+#include <util/internal/object_writer.h>
+#include <gmock/gmock.h>
+#include <stubs/strutil.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) {}
+
+ virtual ObjectWriter* StartObject(StringPiece name) {
+ (name.empty() ? EXPECT_CALL(*mock_, StartObject(IsEmpty()))
+ : EXPECT_CALL(*mock_, StartObject(Eq(std::string(name)))))
+ .WillOnce(Return(mock_))
+ .RetiresOnSaturation();
+ return this;
+ }
+
+ virtual ObjectWriter* EndObject() {
+ EXPECT_CALL(*mock_, EndObject())
+ .WillOnce(Return(mock_))
+ .RetiresOnSaturation();
+ return this;
+ }
+
+ virtual ObjectWriter* StartList(StringPiece name) {
+ (name.empty() ? EXPECT_CALL(*mock_, StartList(IsEmpty()))
+ : EXPECT_CALL(*mock_, StartList(Eq(std::string(name)))))
+ .WillOnce(Return(mock_))
+ .RetiresOnSaturation();
+ return this;
+ }
+
+ virtual ObjectWriter* EndList() {
+ EXPECT_CALL(*mock_, EndList())
+ .WillOnce(Return(mock_))
+ .RetiresOnSaturation();
+ return this;
+ }
+
+ virtual ObjectWriter* RenderBool(StringPiece name, bool value) {
+ (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;
+ }
+
+ virtual ObjectWriter* RenderInt32(StringPiece name, int32_t value) {
+ (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;
+ }
+
+ virtual ObjectWriter* RenderUint32(StringPiece name, uint32_t value) {
+ (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;
+ }
+
+ virtual ObjectWriter* RenderInt64(StringPiece name, int64_t value) {
+ (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;
+ }
+
+ virtual ObjectWriter* RenderUint64(StringPiece name, uint64_t value) {
+ (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;
+ }
+
+ virtual ObjectWriter* RenderDouble(StringPiece name, double value) {
+ (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;
+ }
+
+ virtual ObjectWriter* RenderFloat(StringPiece name, float value) {
+ (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;
+ }
+
+ virtual ObjectWriter* RenderString(StringPiece name,
+ StringPiece value) {
+ (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;
+ }
+
+ virtual ObjectWriter* RenderNull(StringPiece name) {
+ (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_CONVERTER_EXPECTING_OBJECTWRITER_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/util/internal/field_mask_utility.cc b/NorthstarDedicatedTest/include/protobuf/util/internal/field_mask_utility.cc
new file mode 100644
index 00000000..5b1bfe6c
--- /dev/null
+++ b/NorthstarDedicatedTest/include/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 <util/internal/field_mask_utility.h>
+
+#include <util/internal/utility.h>
+#include <stubs/status.h>
+#include <stubs/strutil.h>
+#include <stubs/status_macros.h>
+
+// Must be included last.
+#include <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/NorthstarDedicatedTest/include/protobuf/util/internal/field_mask_utility.h b/NorthstarDedicatedTest/include/protobuf/util/internal/field_mask_utility.h
new file mode 100644
index 00000000..b238f533
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/util/internal/field_mask_utility.h
@@ -0,0 +1,74 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// FieldMask related utility methods.
+
+#ifndef GOOGLE_PROTOBUF_UTIL_CONVERTER_FIELD_MASK_UTILITY_H__
+#define GOOGLE_PROTOBUF_UTIL_CONVERTER_FIELD_MASK_UTILITY_H__
+
+#include <functional>
+#include <stack>
+
+#include <stubs/callback.h>
+#include <stubs/common.h>
+#include <stubs/status.h>
+#include <stubs/strutil.h>
+#include <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_CONVERTER_FIELD_MASK_UTILITY_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/util/internal/json_escaping.cc b/NorthstarDedicatedTest/include/protobuf/util/internal/json_escaping.cc
new file mode 100644
index 00000000..22d981ab
--- /dev/null
+++ b/NorthstarDedicatedTest/include/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 <util/internal/json_escaping.h>
+
+#include <cstdint>
+
+#include <stubs/logging.h>
+#include <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/NorthstarDedicatedTest/include/protobuf/util/internal/json_escaping.h b/NorthstarDedicatedTest/include/protobuf/util/internal/json_escaping.h
new file mode 100644
index 00000000..61e5b605
--- /dev/null
+++ b/NorthstarDedicatedTest/include/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 <stubs/common.h>
+#include <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/NorthstarDedicatedTest/include/protobuf/util/internal/json_objectwriter.cc b/NorthstarDedicatedTest/include/protobuf/util/internal/json_objectwriter.cc
new file mode 100644
index 00000000..f28af9b0
--- /dev/null
+++ b/NorthstarDedicatedTest/include/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 <util/internal/json_objectwriter.h>
+
+#include <cmath>
+#include <cstdint>
+#include <limits>
+
+#include <stubs/casts.h>
+#include <stubs/logging.h>
+#include <stubs/common.h>
+#include <util/internal/utility.h>
+#include <util/internal/json_escaping.h>
+#include <stubs/strutil.h>
+
+namespace google {
+namespace protobuf {
+namespace util {
+namespace converter {
+
+
+JsonObjectWriter::~JsonObjectWriter() {
+ if (element_ && !element_->is_root()) {
+ GOOGLE_LOG(WARNING) << "JsonObjectWriter was not fully closed.";
+ }
+}
+
+JsonObjectWriter* JsonObjectWriter::StartObject(StringPiece name) {
+ WritePrefix(name);
+ WriteChar('{');
+ PushObject();
+ return this;
+}
+
+JsonObjectWriter* JsonObjectWriter::EndObject() {
+ Pop();
+ WriteChar('}');
+ if (element() && element()->is_root()) NewLine();
+ return this;
+}
+
+JsonObjectWriter* JsonObjectWriter::StartList(StringPiece name) {
+ WritePrefix(name);
+ WriteChar('[');
+ PushArray();
+ return this;
+}
+
+JsonObjectWriter* JsonObjectWriter::EndList() {
+ Pop();
+ WriteChar(']');
+ if (element()->is_root()) NewLine();
+ return this;
+}
+
+JsonObjectWriter* JsonObjectWriter::RenderBool(StringPiece name,
+ bool value) {
+ return RenderSimple(name, value ? "true" : "false");
+}
+
+JsonObjectWriter* JsonObjectWriter::RenderInt32(StringPiece name,
+ 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/NorthstarDedicatedTest/include/protobuf/util/internal/json_objectwriter.h b/NorthstarDedicatedTest/include/protobuf/util/internal/json_objectwriter.h
new file mode 100644
index 00000000..791decdc
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/util/internal/json_objectwriter.h
@@ -0,0 +1,278 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef GOOGLE_PROTOBUF_UTIL_CONVERTER_JSON_OBJECTWRITER_H__
+#define GOOGLE_PROTOBUF_UTIL_CONVERTER_JSON_OBJECTWRITER_H__
+
+#include <cstdint>
+#include <memory>
+#include <string>
+
+#include <io/coded_stream.h>
+#include <util/internal/structured_objectwriter.h>
+#include <stubs/bytestream.h>
+
+// clang-format off
+#include <port_def.inc>
+// clang-format on
+
+namespace google {
+namespace protobuf {
+namespace util {
+namespace converter {
+
+
+// An ObjectWriter implementation that outputs JSON. This ObjectWriter
+// supports writing a compact form or a pretty printed form.
+//
+// Sample usage:
+// string output;
+// StringOutputStream* str_stream = new StringOutputStream(&output);
+// CodedOutputStream* out_stream = new CodedOutputStream(str_stream);
+// JsonObjectWriter* ow = new JsonObjectWriter(" ", out_stream);
+// ow->StartObject("")
+// ->RenderString("name", "value")
+// ->RenderString("emptystring", string())
+// ->StartObject("nested")
+// ->RenderInt64("light", 299792458);
+// ->RenderDouble("pi", 3.141592653589793);
+// ->EndObject()
+// ->StartList("empty")
+// ->EndList()
+// ->EndObject();
+//
+// And then the output string would become:
+// {
+// "name": "value",
+// "emptystring": "",
+// "nested": {
+// "light": "299792458",
+// "pi": 3.141592653589793
+// },
+// "empty": []
+// }
+//
+// JsonObjectWriter does not validate if calls actually result in valid JSON.
+// For example, passing an empty name when one would be required won't result
+// in an error, just an invalid output.
+//
+// Note that all int64 and uint64 are rendered as strings instead of numbers.
+// This is because JavaScript parses numbers as 64-bit float thus int64 and
+// uint64 would lose precision if rendered as numbers.
+//
+// JsonObjectWriter is thread-unsafe.
+class PROTOBUF_EXPORT JsonObjectWriter : public StructuredObjectWriter {
+ public:
+ JsonObjectWriter(StringPiece indent_string, io::CodedOutputStream* out)
+ : element_(new Element(/*parent=*/nullptr, /*is_json_object=*/false)),
+ stream_(out),
+ sink_(out),
+ indent_string_(indent_string),
+ indent_char_('\0'),
+ indent_count_(0),
+ use_websafe_base64_for_bytes_(false) {
+ // See if we have a trivial sequence of indent characters.
+ if (!indent_string.empty()) {
+ indent_char_ = indent_string[0];
+ indent_count_ = indent_string.length();
+ for (int i = 1; i < indent_string.length(); i++) {
+ if (indent_char_ != indent_string_[i]) {
+ indent_char_ = '\0';
+ indent_count_ = 0;
+ break;
+ }
+ }
+ }
+ }
+ virtual ~JsonObjectWriter();
+
+ // ObjectWriter methods.
+ JsonObjectWriter* StartObject(StringPiece name) override;
+ JsonObjectWriter* EndObject() override;
+ JsonObjectWriter* StartList(StringPiece name) override;
+ JsonObjectWriter* EndList() override;
+ JsonObjectWriter* RenderBool(StringPiece name, bool value) override;
+ JsonObjectWriter* RenderInt32(StringPiece name, 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 <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_UTIL_CONVERTER_JSON_OBJECTWRITER_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/util/internal/json_objectwriter_test.cc b/NorthstarDedicatedTest/include/protobuf/util/internal/json_objectwriter_test.cc
new file mode 100644
index 00000000..89b43111
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/util/internal/json_objectwriter_test.cc
@@ -0,0 +1,315 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 <util/internal/json_objectwriter.h>
+
+#include <cstdint>
+
+#include <io/zero_copy_stream_impl_lite.h>
+#include <util/internal/utility.h>
+#include <gtest/gtest.h>
+
+namespace google {
+namespace protobuf {
+namespace util {
+namespace converter {
+
+using io::CodedOutputStream;
+using io::StringOutputStream;
+
+class JsonObjectWriterTest : public ::testing::Test {
+ protected:
+ JsonObjectWriterTest()
+ : str_stream_(new StringOutputStream(&output_)),
+ out_stream_(new CodedOutputStream(str_stream_)),
+ ow_(nullptr) {}
+
+ ~JsonObjectWriterTest() override { delete ow_; }
+
+ std::string CloseStreamAndGetString() {
+ delete out_stream_;
+ delete str_stream_;
+ return output_;
+ }
+
+ std::string output_;
+ StringOutputStream* const str_stream_;
+ CodedOutputStream* const out_stream_;
+ JsonObjectWriter* ow_;
+};
+
+TEST_F(JsonObjectWriterTest, EmptyRootObject) {
+ ow_ = new JsonObjectWriter("", out_stream_);
+ ow_->StartObject("")->EndObject();
+ EXPECT_EQ("{}", CloseStreamAndGetString());
+}
+
+TEST_F(JsonObjectWriterTest, EmptyObject) {
+ ow_ = new JsonObjectWriter("", out_stream_);
+ ow_->StartObject("")
+ ->RenderString("test", "value")
+ ->StartObject("empty")
+ ->EndObject()
+ ->EndObject();
+ EXPECT_EQ("{\"test\":\"value\",\"empty\":{}}", CloseStreamAndGetString());
+}
+
+TEST_F(JsonObjectWriterTest, EmptyRootList) {
+ ow_ = new JsonObjectWriter("", out_stream_);
+ ow_->StartList("")->EndList();
+ EXPECT_EQ("[]", CloseStreamAndGetString());
+}
+
+TEST_F(JsonObjectWriterTest, EmptyList) {
+ ow_ = new JsonObjectWriter("", out_stream_);
+ ow_->StartObject("")
+ ->RenderString("test", "value")
+ ->StartList("empty")
+ ->EndList()
+ ->EndObject();
+ EXPECT_EQ("{\"test\":\"value\",\"empty\":[]}", CloseStreamAndGetString());
+}
+
+TEST_F(JsonObjectWriterTest, EmptyObjectKey) {
+ ow_ = new JsonObjectWriter("", out_stream_);
+ ow_->StartObject("")->RenderString("", "value")->EndObject();
+ EXPECT_EQ("{\"\":\"value\"}", CloseStreamAndGetString());
+}
+
+TEST_F(JsonObjectWriterTest, ObjectInObject) {
+ ow_ = new JsonObjectWriter("", out_stream_);
+ ow_->StartObject("")
+ ->StartObject("nested")
+ ->RenderString("field", "value")
+ ->EndObject()
+ ->EndObject();
+ EXPECT_EQ("{\"nested\":{\"field\":\"value\"}}", CloseStreamAndGetString());
+}
+
+TEST_F(JsonObjectWriterTest, ListInObject) {
+ ow_ = new JsonObjectWriter("", out_stream_);
+ ow_->StartObject("")
+ ->StartList("nested")
+ ->RenderString("", "value")
+ ->EndList()
+ ->EndObject();
+ EXPECT_EQ("{\"nested\":[\"value\"]}", CloseStreamAndGetString());
+}
+
+TEST_F(JsonObjectWriterTest, ObjectInList) {
+ ow_ = new JsonObjectWriter("", out_stream_);
+ ow_->StartList("")
+ ->StartObject("")
+ ->RenderString("field", "value")
+ ->EndObject()
+ ->EndList();
+ EXPECT_EQ("[{\"field\":\"value\"}]", CloseStreamAndGetString());
+}
+
+TEST_F(JsonObjectWriterTest, ListInList) {
+ ow_ = new JsonObjectWriter("", out_stream_);
+ ow_->StartList("")
+ ->StartList("")
+ ->RenderString("", "value")
+ ->EndList()
+ ->EndList();
+ EXPECT_EQ("[[\"value\"]]", CloseStreamAndGetString());
+}
+
+TEST_F(JsonObjectWriterTest, RenderPrimitives) {
+ ow_ = new JsonObjectWriter("", out_stream_);
+ ow_->StartObject("")
+ ->RenderBool("bool", true)
+ ->RenderDouble("double", std::numeric_limits<double>::max())
+ ->RenderFloat("float", std::numeric_limits<float>::max())
+ ->RenderInt32("int", std::numeric_limits<int32_t>::min())
+ ->RenderInt64("long", std::numeric_limits<int64_t>::min())
+ ->RenderBytes("bytes", "abracadabra")
+ ->RenderString("string", "string")
+ ->RenderBytes("emptybytes", "")
+ ->RenderString("emptystring", std::string())
+ ->EndObject();
+ EXPECT_EQ(
+ "{\"bool\":true,"
+ "\"double\":" +
+ ValueAsString<double>(std::numeric_limits<double>::max()) +
+ ","
+ "\"float\":" +
+ ValueAsString<float>(std::numeric_limits<float>::max()) +
+ ","
+ "\"int\":-2147483648,"
+ "\"long\":\"-9223372036854775808\","
+ "\"bytes\":\"YWJyYWNhZGFicmE=\","
+ "\"string\":\"string\","
+ "\"emptybytes\":\"\","
+ "\"emptystring\":\"\"}",
+ CloseStreamAndGetString());
+}
+
+TEST_F(JsonObjectWriterTest, BytesEncodesAsNonWebSafeBase64) {
+ std::string s;
+ s.push_back('\377');
+ s.push_back('\357');
+ ow_ = new JsonObjectWriter("", out_stream_);
+ ow_->StartObject("")->RenderBytes("bytes", s)->EndObject();
+ // Non-web-safe would encode this as "/+8="
+ EXPECT_EQ("{\"bytes\":\"/+8=\"}", CloseStreamAndGetString());
+}
+
+TEST_F(JsonObjectWriterTest, PrettyPrintList) {
+ ow_ = new JsonObjectWriter(" ", out_stream_);
+ ow_->StartObject("")
+ ->StartList("items")
+ ->RenderString("", "item1")
+ ->RenderString("", "item2")
+ ->RenderString("", "item3")
+ ->EndList()
+ ->StartList("empty")
+ ->EndList()
+ ->EndObject();
+ EXPECT_EQ(
+ "{\n"
+ " \"items\": [\n"
+ " \"item1\",\n"
+ " \"item2\",\n"
+ " \"item3\"\n"
+ " ],\n"
+ " \"empty\": []\n"
+ "}\n",
+ CloseStreamAndGetString());
+}
+
+TEST_F(JsonObjectWriterTest, PrettyPrintObject) {
+ ow_ = new JsonObjectWriter(" ", out_stream_);
+ ow_->StartObject("")
+ ->StartObject("items")
+ ->RenderString("key1", "item1")
+ ->RenderString("key2", "item2")
+ ->RenderString("key3", "item3")
+ ->EndObject()
+ ->StartObject("empty")
+ ->EndObject()
+ ->EndObject();
+ EXPECT_EQ(
+ "{\n"
+ " \"items\": {\n"
+ " \"key1\": \"item1\",\n"
+ " \"key2\": \"item2\",\n"
+ " \"key3\": \"item3\"\n"
+ " },\n"
+ " \"empty\": {}\n"
+ "}\n",
+ CloseStreamAndGetString());
+}
+
+TEST_F(JsonObjectWriterTest, PrettyPrintEmptyObjectInEmptyList) {
+ ow_ = new JsonObjectWriter(" ", out_stream_);
+ ow_->StartObject("")
+ ->StartList("list")
+ ->StartObject("")
+ ->EndObject()
+ ->EndList()
+ ->EndObject();
+ EXPECT_EQ(
+ "{\n"
+ " \"list\": [\n"
+ " {}\n"
+ " ]\n"
+ "}\n",
+ CloseStreamAndGetString());
+}
+
+TEST_F(JsonObjectWriterTest, PrettyPrintDoubleIndent) {
+ ow_ = new JsonObjectWriter(" ", out_stream_);
+ ow_->StartObject("")
+ ->RenderBool("bool", true)
+ ->RenderInt32("int", 42)
+ ->EndObject();
+ EXPECT_EQ(
+ "{\n"
+ " \"bool\": true,\n"
+ " \"int\": 42\n"
+ "}\n",
+ CloseStreamAndGetString());
+}
+
+TEST_F(JsonObjectWriterTest, StringsEscapedAndEnclosedInDoubleQuotes) {
+ ow_ = new JsonObjectWriter("", out_stream_);
+ ow_->StartObject("")->RenderString("string", "'<>&amp;\\\"\r\n")->EndObject();
+ EXPECT_EQ("{\"string\":\"'\\u003c\\u003e&amp;\\\\\\\"\\r\\n\"}",
+ CloseStreamAndGetString());
+}
+
+TEST_F(JsonObjectWriterTest, Stringification) {
+ ow_ = new JsonObjectWriter("", out_stream_);
+ ow_->StartObject("")
+ ->RenderDouble("double_nan", std::numeric_limits<double>::quiet_NaN())
+ ->RenderFloat("float_nan", std::numeric_limits<float>::quiet_NaN())
+ ->RenderDouble("double_pos", std::numeric_limits<double>::infinity())
+ ->RenderFloat("float_pos", std::numeric_limits<float>::infinity())
+ ->RenderDouble("double_neg", -std::numeric_limits<double>::infinity())
+ ->RenderFloat("float_neg", -std::numeric_limits<float>::infinity())
+ ->EndObject();
+ EXPECT_EQ(
+ "{\"double_nan\":\"NaN\","
+ "\"float_nan\":\"NaN\","
+ "\"double_pos\":\"Infinity\","
+ "\"float_pos\":\"Infinity\","
+ "\"double_neg\":\"-Infinity\","
+ "\"float_neg\":\"-Infinity\"}",
+ CloseStreamAndGetString());
+}
+
+TEST_F(JsonObjectWriterTest, TestRegularByteEncoding) {
+ ow_ = new JsonObjectWriter("", out_stream_);
+ ow_->StartObject("")
+ ->RenderBytes("bytes", "\x03\xef\xc0")
+ ->EndObject();
+
+ // Test that we get regular (non websafe) base64 encoding on byte fields by
+ // default.
+ EXPECT_EQ("{\"bytes\":\"A+/A\"}", CloseStreamAndGetString());
+}
+
+TEST_F(JsonObjectWriterTest, TestWebsafeByteEncoding) {
+ ow_ = new JsonObjectWriter("", out_stream_);
+ ow_->set_use_websafe_base64_for_bytes(true);
+ ow_->StartObject("")
+ ->RenderBytes("bytes", "\x03\xef\xc0\x10")
+ ->EndObject();
+
+ // Test that we get websafe base64 encoding when explicitly asked.
+ EXPECT_EQ("{\"bytes\":\"A-_AEA==\"}", CloseStreamAndGetString());
+}
+
+} // namespace converter
+} // namespace util
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/util/internal/json_stream_parser.cc b/NorthstarDedicatedTest/include/protobuf/util/internal/json_stream_parser.cc
new file mode 100644
index 00000000..c5a72931
--- /dev/null
+++ b/NorthstarDedicatedTest/include/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 <util/internal/json_stream_parser.h>
+
+#include <algorithm>
+#include <cctype>
+#include <cmath>
+#include <memory>
+#include <stack>
+#include <string>
+
+#include <stubs/common.h>
+#include <stubs/logging.h>
+#include <stubs/strutil.h>
+#include <stubs/status.h>
+#include <util/internal/object_writer.h>
+#include <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 code = 0;
+ for (int i = 2; i < kUnicodeEscapedLength; ++i) {
+ if (!isxdigit(p_.data()[i])) {
+ return ReportFailure("Invalid escape sequence.",
+ ParseErrorType::INVALID_ESCAPE_SEQUENCE);
+ }
+ code = (code << 4) + hex_digit_to_int(p_.data()[i]);
+ }
+ if (code >= JsonEscaping::kMinHighSurrogate &&
+ code <= JsonEscaping::kMaxHighSurrogate) {
+ if (p_.length() < 2 * kUnicodeEscapedLength) {
+ if (!finishing_) {
+ return util::CancelledError("");
+ }
+ if (!coerce_to_utf8_) {
+ return ReportFailure("Missing low surrogate.",
+ ParseErrorType::MISSING_LOW_SURROGATE);
+ }
+ } else if (p_.data()[kUnicodeEscapedLength] == '\\' &&
+ p_.data()[kUnicodeEscapedLength + 1] == 'u') {
+ uint32 low_code = 0;
+ for (int i = kUnicodeEscapedLength + 2; i < 2 * kUnicodeEscapedLength;
+ ++i) {
+ if (!isxdigit(p_.data()[i])) {
+ return ReportFailure("Invalid escape sequence.",
+ ParseErrorType::INVALID_ESCAPE_SEQUENCE);
+ }
+ low_code = (low_code << 4) + hex_digit_to_int(p_.data()[i]);
+ }
+ if (low_code >= JsonEscaping::kMinLowSurrogate &&
+ low_code <= JsonEscaping::kMaxLowSurrogate) {
+ // Convert UTF-16 surrogate pair to 21-bit Unicode codepoint.
+ code = (((code & 0x3FF) << 10) | (low_code & 0x3FF)) +
+ JsonEscaping::kMinSupplementaryCodePoint;
+ // Advance past the first code unit escape.
+ p_.remove_prefix(kUnicodeEscapedLength);
+ } else if (!coerce_to_utf8_) {
+ return ReportFailure("Invalid low surrogate.",
+ ParseErrorType::INVALID_LOW_SURROGATE);
+ }
+ } else if (!coerce_to_utf8_) {
+ return ReportFailure("Missing low surrogate.",
+ ParseErrorType::MISSING_LOW_SURROGATE);
+ }
+ }
+ if (!coerce_to_utf8_ && !IsValidCodePoint(code)) {
+ return ReportFailure("Invalid unicode code point.",
+ ParseErrorType::INVALID_UNICODE);
+ }
+ char buf[UTFmax];
+ int len = EncodeAsUTF8Char(code, buf);
+ // Advance past the [final] code unit escape.
+ p_.remove_prefix(kUnicodeEscapedLength);
+ parsed_storage_.append(buf, len);
+ return util::Status();
+}
+
+util::Status JsonStreamParser::ParseNumber() {
+ NumberResult number;
+ util::Status result = ParseNumberHelper(&number);
+ if (result.ok()) {
+ switch (number.type) {
+ case NumberResult::DOUBLE:
+ ow_->RenderDouble(key_, number.double_val);
+ key_ = StringPiece();
+ break;
+
+ case NumberResult::INT:
+ ow_->RenderInt64(key_, number.int_val);
+ key_ = StringPiece();
+ break;
+
+ case NumberResult::UINT:
+ ow_->RenderUint64(key_, number.uint_val);
+ key_ = StringPiece();
+ break;
+
+ default:
+ return ReportFailure("Unable to parse number.",
+ ParseErrorType::UNABLE_TO_PARSE_NUMBER);
+ }
+ }
+ return result;
+}
+
+util::Status JsonStreamParser::ParseDoubleHelper(const 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.
+ if (!negative) {
+ // Octal/Hex numbers are not valid JSON values.
+ if (number.length() >= 2 && number[0] == '0') {
+ return ReportFailure(
+ "Octal/hex numbers are not valid JSON values.",
+ ParseErrorType::OCTAL_OR_HEX_ARE_NOT_VALID_JSON_VALUES);
+ }
+ if (safe_strtou64(number, &result->uint_val)) {
+ result->type = NumberResult::UINT;
+ p_.remove_prefix(index);
+ return util::Status();
+ } else {
+ // If the value is too large, parse it as double.
+ util::Status status = ParseDoubleHelper(number, result);
+ if (status.ok()) {
+ p_.remove_prefix(index);
+ }
+ return status;
+ }
+ }
+
+ // Octal/Hex numbers are not valid JSON values.
+ if (number.length() >= 3 && number[1] == '0') {
+ return ReportFailure(
+ "Octal/hex numbers are not valid JSON values.",
+ ParseErrorType::OCTAL_OR_HEX_ARE_NOT_VALID_JSON_VALUES);
+ }
+ // Negative non-floating point number, parse as an int64.
+ if (safe_strto64(number, &result->int_val)) {
+ result->type = NumberResult::INT;
+ p_.remove_prefix(index);
+ return util::Status();
+ } else {
+ // If the value is too large, parse it as double.
+ util::Status status = ParseDoubleHelper(number, result);
+ if (status.ok()) {
+ p_.remove_prefix(index);
+ }
+ return status;
+ }
+}
+
+util::Status JsonStreamParser::HandleBeginObject() {
+ GOOGLE_DCHECK_EQ('{', *p_.data());
+ Advance();
+ ow_->StartObject(key_);
+ auto status = IncrementRecursionDepth(key_);
+ if (!status.ok()) {
+ return status;
+ }
+ key_ = StringPiece();
+ stack_.push(ENTRY);
+ return util::Status();
+}
+
+util::Status JsonStreamParser::ParseObjectMid(TokenType type) {
+ if (type == UNKNOWN) {
+ return ReportUnknown("Expected , or } after key:value pair.",
+ ParseErrorType::EXPECTED_COMMA_OR_BRACES);
+ }
+
+ // Object is complete, advance past the comma and render the EndObject.
+ if (type == END_OBJECT) {
+ Advance();
+ ow_->EndObject();
+ --recursion_depth_;
+ return util::Status();
+ }
+ // Found a comma, advance past it and get ready for an entry.
+ if (type == VALUE_SEPARATOR) {
+ Advance();
+ stack_.push(ENTRY);
+ return util::Status();
+ }
+ // Illegal token after key:value pair.
+ return ReportFailure("Expected , or } after key:value pair.",
+ ParseErrorType::EXPECTED_COMMA_OR_BRACES);
+}
+
+util::Status JsonStreamParser::ParseEntry(TokenType type) {
+ if (type == UNKNOWN) {
+ return ReportUnknown("Expected an object key or }.",
+ ParseErrorType::EXPECTED_OBJECT_KEY_OR_BRACES);
+ }
+
+ // Close the object and return. This allows for trailing commas.
+ if (type == END_OBJECT) {
+ ow_->EndObject();
+ Advance();
+ --recursion_depth_;
+ return util::Status();
+ }
+
+ util::Status result;
+ if (type == BEGIN_STRING) {
+ // Key is a string (standard JSON), parse it and store the string.
+ result = ParseStringHelper();
+ if (result.ok()) {
+ key_storage_.clear();
+ if (!parsed_storage_.empty()) {
+ parsed_storage_.swap(key_storage_);
+ key_ = StringPiece(key_storage_);
+ } else {
+ key_ = parsed_;
+ }
+ parsed_ = StringPiece();
+ }
+ } else if (type == BEGIN_KEY) {
+ // Key is a bare key (back compat), create a StringPiece pointing to it.
+ result = ParseKey();
+ } else if (type == BEGIN_NULL || type == BEGIN_TRUE || type == BEGIN_FALSE) {
+ // Key may be a bare key that begins with a reserved word.
+ result = ParseKey();
+ if (result.ok() && (key_ == kKeywordNull || key_ == kKeywordTrue ||
+ key_ == kKeywordFalse)) {
+ result = ReportFailure("Expected an object key or }.",
+ ParseErrorType::EXPECTED_OBJECT_KEY_OR_BRACES);
+ }
+ } else {
+ // Unknown key type, report an error.
+ result = ReportFailure("Expected an object key or }.",
+ ParseErrorType::EXPECTED_OBJECT_KEY_OR_BRACES);
+ }
+ // On success we next expect an entry mid ':' then an object mid ',' or '}'
+ if (result.ok()) {
+ stack_.push(OBJ_MID);
+ stack_.push(ENTRY_MID);
+ }
+ return result;
+}
+
+util::Status JsonStreamParser::ParseEntryMid(TokenType type) {
+ if (type == UNKNOWN) {
+ return ReportUnknown("Expected : between key:value pair.",
+ ParseErrorType::EXPECTED_COLON);
+ }
+ if (type == ENTRY_SEPARATOR) {
+ Advance();
+ stack_.push(VALUE);
+ return util::Status();
+ }
+ return ReportFailure("Expected : between key:value pair.",
+ ParseErrorType::EXPECTED_COLON);
+}
+
+util::Status JsonStreamParser::HandleBeginArray() {
+ GOOGLE_DCHECK_EQ('[', *p_.data());
+ Advance();
+ ow_->StartList(key_);
+ key_ = StringPiece();
+ stack_.push(ARRAY_VALUE);
+ return util::Status();
+}
+
+util::Status JsonStreamParser::ParseArrayValue(TokenType type) {
+ if (type == UNKNOWN) {
+ return ReportUnknown("Expected a value or ] within an array.",
+ ParseErrorType::EXPECTED_VALUE_OR_BRACKET);
+ }
+
+ if (type == END_ARRAY) {
+ ow_->EndList();
+ Advance();
+ return util::Status();
+ }
+
+ // The ParseValue call may push something onto the stack so we need to make
+ // sure an ARRAY_MID is after it, so we push it on now. Also, the parsing of
+ // empty-null array value is relying on this ARRAY_MID token.
+ stack_.push(ARRAY_MID);
+ util::Status result = ParseValue(type);
+ if (util::IsCancelled(result)) {
+ // If we were cancelled, pop back off the ARRAY_MID so we don't try to
+ // push it on again when we try over.
+ stack_.pop();
+ }
+ return result;
+}
+
+util::Status JsonStreamParser::ParseArrayMid(TokenType type) {
+ if (type == UNKNOWN) {
+ return ReportUnknown("Expected , or ] after array value.",
+ ParseErrorType::EXPECTED_COMMA_OR_BRACKET);
+ }
+
+ if (type == END_ARRAY) {
+ ow_->EndList();
+ Advance();
+ return util::Status();
+ }
+
+ // Found a comma, advance past it and expect an array value next.
+ if (type == VALUE_SEPARATOR) {
+ Advance();
+ stack_.push(ARRAY_VALUE);
+ return util::Status();
+ }
+ // Illegal token after array value.
+ return ReportFailure("Expected , or ] after array value.",
+ ParseErrorType::EXPECTED_COMMA_OR_BRACKET);
+}
+
+util::Status JsonStreamParser::ParseTrue() {
+ ow_->RenderBool(key_, true);
+ key_ = StringPiece();
+ p_.remove_prefix(kKeywordTrue.length());
+ return util::Status();
+}
+
+util::Status JsonStreamParser::ParseFalse() {
+ ow_->RenderBool(key_, false);
+ key_ = StringPiece();
+ p_.remove_prefix(kKeywordFalse.length());
+ return util::Status();
+}
+
+util::Status JsonStreamParser::ParseNull() {
+ ow_->RenderNull(key_);
+ key_ = StringPiece();
+ p_.remove_prefix(kKeywordNull.length());
+ return util::Status();
+}
+
+util::Status JsonStreamParser::ParseEmptyNull() {
+ ow_->RenderNull(key_);
+ key_ = StringPiece();
+ return util::Status();
+}
+
+bool JsonStreamParser::IsEmptyNullAllowed(TokenType type) {
+ if (stack_.empty()) return false;
+ return (stack_.top() == ARRAY_MID && type == VALUE_SEPARATOR) ||
+ stack_.top() == OBJ_MID;
+}
+
+util::Status JsonStreamParser::ReportFailure(StringPiece message,
+ ParseErrorType parse_code) {
+ (void)parse_code; // Parameter is used in Google-internal code.
+ static const int kContextLength = 20;
+ const char* p_start = p_.data();
+ const char* json_start = json_.data();
+ const char* begin = std::max(p_start - kContextLength, json_start);
+ const char* end =
+ std::min(p_start + kContextLength, json_start + json_.size());
+ StringPiece segment(begin, end - begin);
+ 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/NorthstarDedicatedTest/include/protobuf/util/internal/json_stream_parser.h b/NorthstarDedicatedTest/include/protobuf/util/internal/json_stream_parser.h
new file mode 100644
index 00000000..ac90e413
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/util/internal/json_stream_parser.h
@@ -0,0 +1,349 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef GOOGLE_PROTOBUF_UTIL_CONVERTER_JSON_STREAM_PARSER_H__
+#define GOOGLE_PROTOBUF_UTIL_CONVERTER_JSON_STREAM_PARSER_H__
+
+#include <cstdint>
+#include <stack>
+#include <string>
+
+#include <stubs/common.h>
+#include <stubs/status.h>
+#include <stubs/strutil.h>
+#include <stubs/status.h>
+
+#include <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 <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_UTIL_CONVERTER_JSON_STREAM_PARSER_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/util/internal/json_stream_parser_test.cc b/NorthstarDedicatedTest/include/protobuf/util/internal/json_stream_parser_test.cc
new file mode 100644
index 00000000..af2ee741
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/util/internal/json_stream_parser_test.cc
@@ -0,0 +1,979 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 <util/internal/json_stream_parser.h>
+
+#include <cstdint>
+
+#include <stubs/logging.h>
+#include <stubs/common.h>
+#include <util/internal/expecting_objectwriter.h>
+#include <util/internal/object_writer.h>
+#include <gtest/gtest.h>
+#include <stubs/time.h>
+#include <stubs/status.h>
+
+
+namespace google {
+namespace protobuf {
+namespace util {
+namespace converter {
+
+using ParseErrorType =
+ ::google::protobuf::util::converter::JsonStreamParser::ParseErrorType;
+
+
+// Tests for the JSON Stream Parser. These tests are intended to be
+// comprehensive and cover the following:
+//
+// Positive tests:
+// - true, false, null
+// - empty object or array.
+// - negative and positive double and int, unsigned int
+// - single and double quoted strings
+// - string key, unquoted key, numeric key
+// - array containing array, object, value
+// - object containing array, object, value
+// - unicode handling in strings
+// - ascii escaping (\b, \f, \n, \r, \t, \v)
+// - trailing commas
+//
+// Negative tests:
+// - illegal literals
+// - mismatched quotes failure on strings
+// - unterminated string failure
+// - unexpected end of string failure
+// - mismatched object and array closing
+// - Failure to close array or object
+// - numbers too large
+// - invalid unicode escapes.
+// - invalid unicode sequences.
+// - numbers as keys
+//
+// For each test we split the input string on every possible character to ensure
+// the parser is able to handle arbitrarily split input for all cases. We also
+// do a final test of the entire test case one character at a time.
+//
+// It is verified that expected calls to the mocked objects are in sequence.
+class JsonStreamParserTest : public ::testing::Test {
+ protected:
+ JsonStreamParserTest() : mock_(), ow_(&mock_) {}
+ virtual ~JsonStreamParserTest() {}
+
+ util::Status RunTest(StringPiece json, int split,
+ std::function<void(JsonStreamParser*)> setup) {
+ JsonStreamParser parser(&mock_);
+ setup(&parser);
+
+ // Special case for split == length, test parsing one character at a time.
+ if (split == json.length()) {
+ GOOGLE_LOG(INFO) << "Testing split every char: " << json;
+ for (int i = 0; i < json.length(); ++i) {
+ StringPiece single = json.substr(i, 1);
+ util::Status result = parser.Parse(single);
+ if (!result.ok()) {
+ return result;
+ }
+ }
+ return parser.FinishParse();
+ }
+
+ // Normal case, split at the split point and parse two substrings.
+ StringPiece first = json.substr(0, split);
+ StringPiece rest = json.substr(split);
+ GOOGLE_LOG(INFO) << "Testing split: " << first << "><" << rest;
+ util::Status result = parser.Parse(first);
+ if (result.ok()) {
+ result = parser.Parse(rest);
+ if (result.ok()) {
+ result = parser.FinishParse();
+ }
+ }
+ if (result.ok()) {
+ EXPECT_EQ(parser.recursion_depth(), 0);
+ }
+ return result;
+ }
+
+ void DoTest(
+ StringPiece json, int split,
+ std::function<void(JsonStreamParser*)> setup = [](JsonStreamParser* p) {
+ }) {
+ util::Status result = RunTest(json, split, setup);
+ if (!result.ok()) {
+ GOOGLE_LOG(WARNING) << result;
+ }
+ EXPECT_TRUE(result.ok());
+ }
+
+ void DoErrorTest(
+ StringPiece json, int split, StringPiece error_prefix,
+ std::function<void(JsonStreamParser*)> setup = [](JsonStreamParser* p) {
+ }) {
+ util::Status result = RunTest(json, split, setup);
+ EXPECT_TRUE(util::IsInvalidArgument(result));
+ StringPiece error_message(result.message());
+ EXPECT_EQ(error_prefix, error_message.substr(0, error_prefix.size()));
+ }
+
+ void DoErrorTest(
+ StringPiece json, int split, StringPiece error_prefix,
+ ParseErrorType expected_parse_error_type,
+ std::function<void(JsonStreamParser*)> setup = [](JsonStreamParser* p) {
+ }) {
+ util::Status result = RunTest(json, split, setup);
+ EXPECT_TRUE(util::IsInvalidArgument(result));
+ StringPiece error_message(result.message());
+ EXPECT_EQ(error_prefix, error_message.substr(0, error_prefix.size()));
+ }
+
+
+#ifndef _MSC_VER
+ // TODO(xiaofeng): We have to disable InSequence check for MSVC because it
+ // causes stack overflow due to its use of a linked list that is destructed
+ // recursively.
+ ::testing::InSequence in_sequence_;
+#endif // !_MSC_VER
+ MockObjectWriter mock_;
+ ExpectingObjectWriter ow_;
+};
+
+
+// Positive tests
+
+// - true, false, null
+TEST_F(JsonStreamParserTest, SimpleTrue) {
+ StringPiece str = "true";
+ for (int i = 0; i <= str.length(); ++i) {
+ ow_.RenderBool("", true);
+ DoTest(str, i);
+ }
+}
+
+TEST_F(JsonStreamParserTest, SimpleFalse) {
+ StringPiece str = "false";
+ for (int i = 0; i <= str.length(); ++i) {
+ ow_.RenderBool("", false);
+ DoTest(str, i);
+ }
+}
+
+TEST_F(JsonStreamParserTest, SimpleNull) {
+ StringPiece str = "null";
+ for (int i = 0; i <= str.length(); ++i) {
+ ow_.RenderNull("");
+ DoTest(str, i);
+ }
+}
+
+// - empty object and array.
+TEST_F(JsonStreamParserTest, EmptyObject) {
+ StringPiece str = "{}";
+ for (int i = 0; i <= str.length(); ++i) {
+ ow_.StartObject("")->EndObject();
+ DoTest(str, i);
+ }
+}
+
+TEST_F(JsonStreamParserTest, EmptyList) {
+ StringPiece str = "[]";
+ for (int i = 0; i <= str.length(); ++i) {
+ ow_.StartList("")->EndList();
+ DoTest(str, i);
+ }
+}
+
+// - negative and positive double and int, unsigned int
+TEST_F(JsonStreamParserTest, SimpleDouble) {
+ StringPiece str = "42.5";
+ for (int i = 0; i <= str.length(); ++i) {
+ ow_.RenderDouble("", 42.5);
+ DoTest(str, i);
+ }
+}
+
+TEST_F(JsonStreamParserTest, ScientificDouble) {
+ StringPiece str = "1.2345e-10";
+ for (int i = 0; i < str.length(); ++i) {
+ ow_.RenderDouble("", 1.2345e-10);
+ DoTest(str, i);
+ }
+}
+
+TEST_F(JsonStreamParserTest, SimpleNegativeDouble) {
+ StringPiece str = "-1045.235";
+ for (int i = 0; i <= str.length(); ++i) {
+ ow_.RenderDouble("", -1045.235);
+ DoTest(str, i);
+ }
+}
+
+TEST_F(JsonStreamParserTest, SimpleInt) {
+ StringPiece str = "123456";
+ for (int i = 0; i <= str.length(); ++i) {
+ ow_.RenderUint64("", 123456);
+ DoTest(str, i);
+ }
+}
+
+TEST_F(JsonStreamParserTest, SimpleNegativeInt) {
+ StringPiece str = "-79497823553162765";
+ for (int i = 0; i <= str.length(); ++i) {
+ ow_.RenderInt64("", int64_t{-79497823553162765});
+ DoTest(str, i);
+ }
+}
+
+TEST_F(JsonStreamParserTest, SimpleUnsignedInt) {
+ StringPiece str = "11779497823553162765";
+ for (int i = 0; i <= str.length(); ++i) {
+ ow_.RenderUint64("", uint64_t{11779497823553162765u});
+ DoTest(str, i);
+ }
+}
+
+TEST_F(JsonStreamParserTest, OctalNumberIsInvalid) {
+ StringPiece str = "01234";
+ for (int i = 0; i <= str.length(); ++i) {
+ DoErrorTest(str, i, "Octal/hex numbers are not valid JSON values.",
+ ParseErrorType::OCTAL_OR_HEX_ARE_NOT_VALID_JSON_VALUES);
+ }
+ str = "-01234";
+ for (int i = 0; i <= str.length(); ++i) {
+ DoErrorTest(str, i, "Octal/hex numbers are not valid JSON values.",
+ ParseErrorType::OCTAL_OR_HEX_ARE_NOT_VALID_JSON_VALUES);
+ }
+}
+
+TEST_F(JsonStreamParserTest, HexNumberIsInvalid) {
+ StringPiece str = "0x1234";
+ for (int i = 0; i <= str.length(); ++i) {
+ DoErrorTest(str, i, "Octal/hex numbers are not valid JSON values.",
+ ParseErrorType::OCTAL_OR_HEX_ARE_NOT_VALID_JSON_VALUES);
+ }
+ str = "-0x1234";
+ for (int i = 0; i <= str.length(); ++i) {
+ DoErrorTest(str, i, "Octal/hex numbers are not valid JSON values.",
+ ParseErrorType::OCTAL_OR_HEX_ARE_NOT_VALID_JSON_VALUES);
+ }
+ str = "12x34";
+ for (int i = 0; i <= str.length(); ++i) {
+ DoErrorTest(str, i, "Unable to parse number.",
+ ParseErrorType::UNABLE_TO_PARSE_NUMBER);
+ }
+}
+
+// - single and double quoted strings
+TEST_F(JsonStreamParserTest, EmptyDoubleQuotedString) {
+ StringPiece str = "\"\"";
+ for (int i = 0; i <= str.length(); ++i) {
+ ow_.RenderString("", "");
+ DoTest(str, i);
+ }
+}
+
+TEST_F(JsonStreamParserTest, EmptySingleQuotedString) {
+ StringPiece str = "''";
+ for (int i = 0; i <= str.length(); ++i) {
+ ow_.RenderString("", "");
+ DoTest(str, i);
+ }
+}
+
+TEST_F(JsonStreamParserTest, SimpleDoubleQuotedString) {
+ StringPiece str = "\"Some String\"";
+ for (int i = 0; i <= str.length(); ++i) {
+ ow_.RenderString("", "Some String");
+ DoTest(str, i);
+ }
+}
+
+TEST_F(JsonStreamParserTest, SimpleSingleQuotedString) {
+ StringPiece str = "'Another String'";
+ for (int i = 0; i <= str.length(); ++i) {
+ ow_.RenderString("", "Another String");
+ DoTest(str, i);
+ }
+}
+
+// - string key, unquoted key, numeric key
+TEST_F(JsonStreamParserTest, ObjectKeyTypes) {
+ StringPiece str =
+ "{'s': true, \"d\": false, key: null, snake_key: [], camelKey: {}}";
+ for (int i = 0; i <= str.length(); ++i) {
+ ow_.StartObject("")
+ ->RenderBool("s", true)
+ ->RenderBool("d", false)
+ ->RenderNull("key")
+ ->StartList("snake_key")
+ ->EndList()
+ ->StartObject("camelKey")
+ ->EndObject()
+ ->EndObject();
+ DoTest(str, i);
+ }
+}
+
+TEST_F(JsonStreamParserTest, UnquotedObjectKeyWithReservedPrefxes) {
+ StringPiece str = "{ nullkey: \"a\", truekey: \"b\", falsekey: \"c\"}";
+ for (int i = 0; i <= str.length(); ++i) {
+ ow_.StartObject("")
+ ->RenderString("nullkey", "a")
+ ->RenderString("truekey", "b")
+ ->RenderString("falsekey", "c")
+ ->EndObject();
+ DoTest(str, i);
+ }
+}
+
+TEST_F(JsonStreamParserTest, UnquotedObjectKeyWithReservedKeyword) {
+ StringPiece str = "{ null: \"a\", true: \"b\", false: \"c\"}";
+ for (int i = 0; i <= str.length(); ++i) {
+ DoErrorTest(str, i, "Expected an object key or }.",
+ ParseErrorType::EXPECTED_OBJECT_KEY_OR_BRACES);
+ }
+}
+
+TEST_F(JsonStreamParserTest, UnquotedObjectKeyWithEmbeddedNonAlphanumeric) {
+ StringPiece str = "{ foo-bar-baz: \"a\"}";
+ for (int i = 0; i <= str.length(); ++i) {
+ DoErrorTest(str, i, "Expected : between key:value pair.",
+ ParseErrorType::EXPECTED_COLON);
+ }
+}
+
+
+// - array containing primitive values (true, false, null, num, string)
+TEST_F(JsonStreamParserTest, ArrayPrimitiveValues) {
+ StringPiece str = "[true, false, null, 'one', \"two\"]";
+ for (int i = 0; i <= str.length(); ++i) {
+ ow_.StartList("")
+ ->RenderBool("", true)
+ ->RenderBool("", false)
+ ->RenderNull("")
+ ->RenderString("", "one")
+ ->RenderString("", "two")
+ ->EndList();
+ DoTest(str, i);
+ }
+}
+
+// - array containing array, object
+TEST_F(JsonStreamParserTest, ArrayComplexValues) {
+ StringPiece str =
+ "[[22, -127, 45.3, -1056.4, 11779497823553162765], {'key': true}]";
+ for (int i = 0; i <= str.length(); ++i) {
+ ow_.StartList("")
+ ->StartList("")
+ ->RenderUint64("", 22)
+ ->RenderInt64("", -127)
+ ->RenderDouble("", 45.3)
+ ->RenderDouble("", -1056.4)
+ ->RenderUint64("", uint64_t{11779497823553162765u})
+ ->EndList()
+ ->StartObject("")
+ ->RenderBool("key", true)
+ ->EndObject()
+ ->EndList();
+ DoTest(str, i);
+ }
+}
+
+
+// - object containing array, object, value (true, false, null, num, string)
+TEST_F(JsonStreamParserTest, ObjectValues) {
+ StringPiece str =
+ "{t: true, f: false, n: null, s: 'a string', d: \"another string\", pi: "
+ "22, ni: -127, pd: 45.3, nd: -1056.4, pl: 11779497823553162765, l: [[]], "
+ "o: {'key': true}}";
+ for (int i = 0; i <= str.length(); ++i) {
+ ow_.StartObject("")
+ ->RenderBool("t", true)
+ ->RenderBool("f", false)
+ ->RenderNull("n")
+ ->RenderString("s", "a string")
+ ->RenderString("d", "another string")
+ ->RenderUint64("pi", 22)
+ ->RenderInt64("ni", -127)
+ ->RenderDouble("pd", 45.3)
+ ->RenderDouble("nd", -1056.4)
+ ->RenderUint64("pl", uint64_t{11779497823553162765u})
+ ->StartList("l")
+ ->StartList("")
+ ->EndList()
+ ->EndList()
+ ->StartObject("o")
+ ->RenderBool("key", true)
+ ->EndObject()
+ ->EndObject();
+ DoTest(str, i);
+ }
+}
+
+
+TEST_F(JsonStreamParserTest, RejectNonUtf8WhenNotCoerced) {
+ StringPiece json = "{\"address\":\xFF\"חרושת 23, רעננה, ישר×ל\"}";
+ for (int i = 0; i <= json.length(); ++i) {
+ DoErrorTest(json, i, "Encountered non UTF-8 code points.",
+ ParseErrorType::NON_UTF_8);
+ }
+ json = "{\"address\": \"חרושת 23,\xFFרעננה, ישר×ל\"}";
+ for (int i = 0; i <= json.length(); ++i) {
+ DoErrorTest(json, i, "Encountered non UTF-8 code points.",
+ ParseErrorType::NON_UTF_8);
+ }
+ DoErrorTest("\xFF{}", 0, "Encountered non UTF-8 code points.",
+ ParseErrorType::NON_UTF_8);
+}
+
+// - unicode handling in strings
+TEST_F(JsonStreamParserTest, UnicodeEscaping) {
+ StringPiece str = "[\"\\u0639\\u0631\\u0628\\u0649\"]";
+ for (int i = 0; i <= str.length(); ++i) {
+ ow_.StartList("")
+ ->RenderString("", "\xD8\xB9\xD8\xB1\xD8\xA8\xD9\x89")
+ ->EndList();
+ DoTest(str, i);
+ }
+}
+
+// - unicode UTF-16 surrogate pair handling in strings
+TEST_F(JsonStreamParserTest, UnicodeSurrogatePairEscaping) {
+ StringPiece str =
+ "[\"\\u0bee\\ud800\\uddf1\\uD80C\\uDDA4\\uD83d\\udC1D\\uD83C\\uDF6F\"]";
+ for (int i = 0; i <= str.length(); ++i) {
+ ow_.StartList("")
+ ->RenderString("",
+ "\xE0\xAF\xAE\xF0\x90\x87\xB1\xF0\x93\x86\xA4\xF0"
+ "\x9F\x90\x9D\xF0\x9F\x8D\xAF")
+ ->EndList();
+ DoTest(str, i);
+ }
+}
+
+
+TEST_F(JsonStreamParserTest, UnicodeEscapingInvalidCodePointWhenNotCoerced) {
+ // A low surrogate alone.
+ StringPiece str = "[\"\\ude36\"]";
+ for (int i = 0; i <= str.length(); ++i) {
+ DoErrorTest(str, i, "Invalid unicode code point.",
+ ParseErrorType::INVALID_UNICODE);
+ }
+}
+
+TEST_F(JsonStreamParserTest, UnicodeEscapingMissingLowSurrogateWhenNotCoerced) {
+ // A high surrogate alone.
+ StringPiece str = "[\"\\ud83d\"]";
+ for (int i = 0; i <= str.length(); ++i) {
+ DoErrorTest(str, i, "Missing low surrogate.",
+ ParseErrorType::MISSING_LOW_SURROGATE);
+ }
+ // A high surrogate with some trailing characters.
+ str = "[\"\\ud83d|ude36\"]";
+ for (int i = 0; i <= str.length(); ++i) {
+ DoErrorTest(str, i, "Missing low surrogate.",
+ ParseErrorType::MISSING_LOW_SURROGATE);
+ }
+ // A high surrogate with half a low surrogate.
+ str = "[\"\\ud83d\\ude--\"]";
+ for (int i = 0; i <= str.length(); ++i) {
+ DoErrorTest(str, i, "Invalid escape sequence.",
+ ParseErrorType::INVALID_ESCAPE_SEQUENCE);
+ }
+ // Two high surrogates.
+ str = "[\"\\ud83d\\ud83d\"]";
+ for (int i = 0; i <= str.length(); ++i) {
+ DoErrorTest(str, i, "Invalid low surrogate.",
+ ParseErrorType::INVALID_LOW_SURROGATE);
+ }
+}
+
+// - ascii escaping (\b, \f, \n, \r, \t, \v)
+TEST_F(JsonStreamParserTest, AsciiEscaping) {
+ StringPiece str =
+ "[\"\\b\", \"\\ning\", \"test\\f\", \"\\r\\t\", \"test\\\\\\ving\"]";
+ for (int i = 0; i <= str.length(); ++i) {
+ ow_.StartList("")
+ ->RenderString("", "\b")
+ ->RenderString("", "\ning")
+ ->RenderString("", "test\f")
+ ->RenderString("", "\r\t")
+ ->RenderString("", "test\\\ving")
+ ->EndList();
+ DoTest(str, i);
+ }
+}
+
+// - trailing commas, we support a single trailing comma but no internal commas.
+TEST_F(JsonStreamParserTest, TrailingCommas) {
+ StringPiece str = "[['a',true,], {b: null,},]";
+ for (int i = 0; i <= str.length(); ++i) {
+ ow_.StartList("")
+ ->StartList("")
+ ->RenderString("", "a")
+ ->RenderBool("", true)
+ ->EndList()
+ ->StartObject("")
+ ->RenderNull("b")
+ ->EndObject()
+ ->EndList();
+ DoTest(str, i);
+ }
+}
+
+// Negative tests
+
+// illegal literals
+TEST_F(JsonStreamParserTest, ExtraTextAfterTrue) {
+ StringPiece str = "truee";
+ for (int i = 0; i <= str.length(); ++i) {
+ ow_.RenderBool("", true);
+ DoErrorTest(str, i, "Parsing terminated before end of input.",
+ ParseErrorType::PARSING_TERMINATED_BEFORE_END_OF_INPUT);
+ }
+}
+
+TEST_F(JsonStreamParserTest, InvalidNumberDashOnly) {
+ StringPiece str = "-";
+ for (int i = 0; i <= str.length(); ++i) {
+ DoErrorTest(str, i, "Unable to parse number.",
+ ParseErrorType::UNABLE_TO_PARSE_NUMBER);
+ }
+}
+
+TEST_F(JsonStreamParserTest, InvalidNumberDashName) {
+ StringPiece str = "-foo";
+ for (int i = 0; i <= str.length(); ++i) {
+ DoErrorTest(str, i, "Unable to parse number.",
+ ParseErrorType::UNABLE_TO_PARSE_NUMBER);
+ }
+}
+
+TEST_F(JsonStreamParserTest, InvalidLiteralInArray) {
+ StringPiece str = "[nule]";
+ for (int i = 0; i <= str.length(); ++i) {
+ ow_.StartList("");
+ DoErrorTest(str, i, "Unexpected token.", ParseErrorType::UNEXPECTED_TOKEN);
+ }
+}
+
+TEST_F(JsonStreamParserTest, InvalidLiteralInObject) {
+ StringPiece str = "{123false}";
+ for (int i = 0; i <= str.length(); ++i) {
+ ow_.StartObject("");
+ DoErrorTest(str, i, "Expected an object key or }.",
+ ParseErrorType::EXPECTED_OBJECT_KEY_OR_BRACES);
+ }
+}
+
+// mismatched quotes failure on strings
+TEST_F(JsonStreamParserTest, MismatchedSingleQuotedLiteral) {
+ StringPiece str = "'Some str\"";
+ for (int i = 0; i <= str.length(); ++i) {
+ DoErrorTest(str, i, "Closing quote expected in string.",
+ ParseErrorType::EXPECTED_CLOSING_QUOTE);
+ }
+}
+
+TEST_F(JsonStreamParserTest, MismatchedDoubleQuotedLiteral) {
+ StringPiece str = "\"Another string that ends poorly!'";
+ for (int i = 0; i <= str.length(); ++i) {
+ DoErrorTest(str, i, "Closing quote expected in string.",
+ ParseErrorType::EXPECTED_CLOSING_QUOTE);
+ }
+}
+
+// unterminated strings
+TEST_F(JsonStreamParserTest, UnterminatedLiteralString) {
+ StringPiece str = "\"Forgot the rest of i";
+ for (int i = 0; i <= str.length(); ++i) {
+ DoErrorTest(str, i, "Closing quote expected in string.",
+ ParseErrorType::EXPECTED_CLOSING_QUOTE);
+ }
+}
+
+TEST_F(JsonStreamParserTest, UnterminatedStringEscape) {
+ StringPiece str = "\"Forgot the rest of \\";
+ for (int i = 0; i <= str.length(); ++i) {
+ DoErrorTest(str, i, "Closing quote expected in string.",
+ ParseErrorType::EXPECTED_CLOSING_QUOTE);
+ }
+}
+
+TEST_F(JsonStreamParserTest, UnterminatedStringInArray) {
+ StringPiece str = "[\"Forgot to close the string]";
+ for (int i = 0; i <= str.length(); ++i) {
+ ow_.StartList("");
+ DoErrorTest(str, i, "Closing quote expected in string.",
+ ParseErrorType::EXPECTED_CLOSING_QUOTE);
+ }
+}
+
+TEST_F(JsonStreamParserTest, UnterminatedStringInObject) {
+ StringPiece str = "{f: \"Forgot to close the string}";
+ for (int i = 0; i <= str.length(); ++i) {
+ ow_.StartObject("");
+ DoErrorTest(str, i, "Closing quote expected in string.",
+ ParseErrorType::EXPECTED_CLOSING_QUOTE);
+ }
+}
+
+TEST_F(JsonStreamParserTest, UnterminatedObject) {
+ StringPiece str = "{";
+ for (int i = 0; i <= str.length(); ++i) {
+ ow_.StartObject("");
+ DoErrorTest(str, i, "Unexpected end of string.",
+ ParseErrorType::EXPECTED_OBJECT_KEY_OR_BRACES);
+ }
+}
+
+
+// mismatched object and array closing
+TEST_F(JsonStreamParserTest, MismatchedCloseObject) {
+ StringPiece str = "{'key': true]";
+ for (int i = 0; i <= str.length(); ++i) {
+ ow_.StartObject("")->RenderBool("key", true);
+ DoErrorTest(str, i, "Expected , or } after key:value pair.",
+ ParseErrorType::EXPECTED_COMMA_OR_BRACES);
+ }
+}
+
+TEST_F(JsonStreamParserTest, MismatchedCloseArray) {
+ StringPiece str = "[true, null}";
+ for (int i = 0; i <= str.length(); ++i) {
+ ow_.StartList("")->RenderBool("", true)->RenderNull("");
+ DoErrorTest(str, i, "Expected , or ] after array value.",
+ ParseErrorType::EXPECTED_COMMA_OR_BRACKET);
+ }
+}
+
+// Invalid object keys.
+TEST_F(JsonStreamParserTest, InvalidNumericObjectKey) {
+ StringPiece str = "{42: true}";
+ for (int i = 0; i <= str.length(); ++i) {
+ ow_.StartObject("");
+ DoErrorTest(str, i, "Expected an object key or }.",
+ ParseErrorType::EXPECTED_OBJECT_KEY_OR_BRACES);
+ }
+}
+
+TEST_F(JsonStreamParserTest, InvalidLiteralObjectInObject) {
+ StringPiece str = "{{bob: true}}";
+ for (int i = 0; i <= str.length(); ++i) {
+ ow_.StartObject("");
+ DoErrorTest(str, i, "Expected an object key or }.",
+ ParseErrorType::EXPECTED_OBJECT_KEY_OR_BRACES);
+ }
+}
+
+TEST_F(JsonStreamParserTest, InvalidLiteralArrayInObject) {
+ StringPiece str = "{[null]}";
+ for (int i = 0; i <= str.length(); ++i) {
+ ow_.StartObject("");
+ DoErrorTest(str, i, "Expected an object key or }.",
+ ParseErrorType::EXPECTED_OBJECT_KEY_OR_BRACES);
+ }
+}
+
+TEST_F(JsonStreamParserTest, InvalidLiteralValueInObject) {
+ StringPiece str = "{false}";
+ for (int i = 0; i <= str.length(); ++i) {
+ ow_.StartObject("");
+ DoErrorTest(str, i, "Expected an object key or }.",
+ ParseErrorType::EXPECTED_OBJECT_KEY_OR_BRACES);
+ }
+}
+
+TEST_F(JsonStreamParserTest, MissingColonAfterStringInObject) {
+ StringPiece str = "{\"key\"}";
+ for (int i = 0; i <= str.length(); ++i) {
+ ow_.StartObject("");
+ DoErrorTest(str, i, "Expected : between key:value pair.",
+ ParseErrorType::EXPECTED_COLON);
+ }
+}
+
+TEST_F(JsonStreamParserTest, MissingColonAfterKeyInObject) {
+ StringPiece str = "{key}";
+ for (int i = 0; i <= str.length(); ++i) {
+ ow_.StartObject("");
+ DoErrorTest(str, i, "Expected : between key:value pair.",
+ ParseErrorType::EXPECTED_COLON);
+ }
+}
+
+TEST_F(JsonStreamParserTest, EndOfTextAfterKeyInObject) {
+ StringPiece str = "{key";
+ for (int i = 0; i <= str.length(); ++i) {
+ ow_.StartObject("");
+ DoErrorTest(str, i, "Unexpected end of string.",
+ ParseErrorType::EXPECTED_COLON);
+ }
+}
+
+TEST_F(JsonStreamParserTest, MissingValueAfterColonInObject) {
+ StringPiece str = "{key:}";
+ for (int i = 0; i <= str.length(); ++i) {
+ ow_.StartObject("");
+ DoErrorTest(str, i, "Unexpected token.", ParseErrorType::UNEXPECTED_TOKEN);
+ }
+}
+
+TEST_F(JsonStreamParserTest, MissingCommaBetweenObjectEntries) {
+ StringPiece str = "{key:20 'hello': true}";
+ for (int i = 0; i <= str.length(); ++i) {
+ ow_.StartObject("")->RenderUint64("key", 20);
+ DoErrorTest(str, i, "Expected , or } after key:value pair.",
+ ParseErrorType::EXPECTED_COMMA_OR_BRACES);
+ }
+}
+
+TEST_F(JsonStreamParserTest, InvalidLiteralAsObjectKey) {
+ StringPiece str = "{false: 20}";
+ for (int i = 0; i <= str.length(); ++i) {
+ ow_.StartObject("");
+ DoErrorTest(str, i, "Expected an object key or }.",
+ ParseErrorType::EXPECTED_OBJECT_KEY_OR_BRACES);
+ }
+}
+
+TEST_F(JsonStreamParserTest, ExtraCharactersAfterObject) {
+ StringPiece str = "{}}";
+ for (int i = 0; i <= str.length(); ++i) {
+ ow_.StartObject("")->EndObject();
+ DoErrorTest(str, i, "Parsing terminated before end of input.",
+ ParseErrorType::PARSING_TERMINATED_BEFORE_END_OF_INPUT);
+ }
+}
+
+TEST_F(JsonStreamParserTest, PositiveNumberTooBigIsDouble) {
+ StringPiece str = "18446744073709551616"; // 2^64
+ for (int i = 0; i <= str.length(); ++i) {
+ ow_.RenderDouble("", 18446744073709552000.0);
+ DoTest(str, i);
+ }
+}
+
+TEST_F(JsonStreamParserTest, NegativeNumberTooBigIsDouble) {
+ StringPiece str = "-18446744073709551616";
+ for (int i = 0; i <= str.length(); ++i) {
+ ow_.RenderDouble("", -18446744073709551616.0);
+ DoTest(str, i);
+ }
+}
+
+TEST_F(JsonStreamParserTest, DoubleTooBig) {
+ StringPiece str = "[1.89769e+308]";
+ for (int i = 0; i <= str.length(); ++i) {
+ ow_.StartList("");
+ DoErrorTest(str, i, "Number exceeds the range of double.",
+ ParseErrorType::NUMBER_EXCEEDS_RANGE_DOUBLE);
+ }
+ str = "[-1.89769e+308]";
+ for (int i = 0; i <= str.length(); ++i) {
+ ow_.StartList("");
+ DoErrorTest(str, i, "Number exceeds the range of double.",
+ ParseErrorType::NUMBER_EXCEEDS_RANGE_DOUBLE);
+ }
+}
+
+
+// invalid bare backslash.
+TEST_F(JsonStreamParserTest, UnfinishedEscape) {
+ StringPiece str = "\"\\";
+ for (int i = 0; i <= str.length(); ++i) {
+ DoErrorTest(str, i, "Closing quote expected in string.",
+ ParseErrorType::EXPECTED_CLOSING_QUOTE);
+ }
+}
+
+// invalid bare backslash u.
+TEST_F(JsonStreamParserTest, UnfinishedUnicodeEscape) {
+ StringPiece str = "\"\\u";
+ for (int i = 0; i <= str.length(); ++i) {
+ DoErrorTest(str, i, "Illegal hex string.",
+ ParseErrorType::ILLEGAL_HEX_STRING);
+ }
+}
+
+// invalid unicode sequence.
+TEST_F(JsonStreamParserTest, UnicodeEscapeCutOff) {
+ StringPiece str = "\"\\u12";
+ for (int i = 0; i <= str.length(); ++i) {
+ DoErrorTest(str, i, "Illegal hex string.",
+ ParseErrorType::ILLEGAL_HEX_STRING);
+ }
+}
+
+// invalid unicode sequence (valid in modern EcmaScript but not in JSON).
+TEST_F(JsonStreamParserTest, BracketedUnicodeEscape) {
+ StringPiece str = "\"\\u{1f36f}\"";
+ for (int i = 0; i <= str.length(); ++i) {
+ DoErrorTest(str, i, "Invalid escape sequence.",
+ ParseErrorType::INVALID_ESCAPE_SEQUENCE);
+ }
+}
+
+
+TEST_F(JsonStreamParserTest, UnicodeEscapeInvalidCharacters) {
+ StringPiece str = "\"\\u12$4hello";
+ for (int i = 0; i <= str.length(); ++i) {
+ DoErrorTest(str, i, "Invalid escape sequence.",
+ ParseErrorType::INVALID_ESCAPE_SEQUENCE);
+ }
+}
+
+// invalid unicode sequence in low half surrogate: g is not a hex digit.
+TEST_F(JsonStreamParserTest, UnicodeEscapeLowHalfSurrogateInvalidCharacters) {
+ StringPiece str = "\"\\ud800\\udcfg\"";
+ for (int i = 0; i <= str.length(); ++i) {
+ DoErrorTest(str, i, "Invalid escape sequence.",
+ ParseErrorType::INVALID_ESCAPE_SEQUENCE);
+ }
+}
+
+// Extra commas with an object or array.
+TEST_F(JsonStreamParserTest, ExtraCommaInObject) {
+ StringPiece str = "{'k1': true,,'k2': false}";
+ for (int i = 0; i <= str.length(); ++i) {
+ ow_.StartObject("")->RenderBool("k1", true);
+ DoErrorTest(str, i, "Expected an object key or }.",
+ ParseErrorType::EXPECTED_OBJECT_KEY_OR_BRACES);
+ }
+}
+
+TEST_F(JsonStreamParserTest, ExtraCommaInArray) {
+ StringPiece str = "[true,,false}";
+ for (int i = 0; i <= str.length(); ++i) {
+ ow_.StartList("")->RenderBool("", true);
+ DoErrorTest(str, i, "Unexpected token.", ParseErrorType::UNEXPECTED_TOKEN);
+ }
+}
+
+// Extra text beyond end of value.
+TEST_F(JsonStreamParserTest, ExtraTextAfterLiteral) {
+ StringPiece str = "'hello', 'world'";
+ for (int i = 0; i <= str.length(); ++i) {
+ ow_.RenderString("", "hello");
+ DoErrorTest(str, i, "Parsing terminated before end of input.",
+ ParseErrorType::PARSING_TERMINATED_BEFORE_END_OF_INPUT);
+ }
+}
+
+TEST_F(JsonStreamParserTest, ExtraTextAfterObject) {
+ StringPiece str = "{'key': true} 'oops'";
+ for (int i = 0; i <= str.length(); ++i) {
+ ow_.StartObject("")->RenderBool("key", true)->EndObject();
+ DoErrorTest(str, i, "Parsing terminated before end of input.",
+ ParseErrorType::PARSING_TERMINATED_BEFORE_END_OF_INPUT);
+ }
+}
+
+TEST_F(JsonStreamParserTest, ExtraTextAfterArray) {
+ StringPiece str = "[null] 'oops'";
+ for (int i = 0; i <= str.length(); ++i) {
+ ow_.StartList("")->RenderNull("")->EndList();
+ DoErrorTest(str, i, "Parsing terminated before end of input.",
+ ParseErrorType::PARSING_TERMINATED_BEFORE_END_OF_INPUT);
+ }
+}
+
+// Random unknown text in the value.
+TEST_F(JsonStreamParserTest, UnknownCharactersAsValue) {
+ StringPiece str = "*&#25";
+ for (int i = 0; i <= str.length(); ++i) {
+ DoErrorTest(str, i, "Expected a value.", ParseErrorType::EXPECTED_VALUE);
+ }
+}
+
+TEST_F(JsonStreamParserTest, UnknownCharactersInArray) {
+ StringPiece str = "[*&#25]";
+ for (int i = 0; i <= str.length(); ++i) {
+ ow_.StartList("");
+ DoErrorTest(str, i, "Expected a value or ] within an array.",
+ ParseErrorType::EXPECTED_VALUE_OR_BRACKET);
+ }
+}
+
+TEST_F(JsonStreamParserTest, UnknownCharactersInObject) {
+ StringPiece str = "{'key': *&#25}";
+ for (int i = 0; i <= str.length(); ++i) {
+ ow_.StartObject("");
+ DoErrorTest(str, i, "Expected a value.", ParseErrorType::EXPECTED_VALUE);
+ }
+}
+
+TEST_F(JsonStreamParserTest, DeepNestJsonNotExceedLimit) {
+ int count = 99;
+ std::string str;
+ for (int i = 0; i < count; ++i) {
+ StrAppend(&str, "{'a':");
+ }
+ StrAppend(&str, "{'nest64':'v1', 'nest64': false, 'nest64': ['v2']}");
+ for (int i = 0; i < count; ++i) {
+ StrAppend(&str, "}");
+ }
+ ow_.StartObject("");
+ for (int i = 0; i < count; ++i) {
+ ow_.StartObject("a");
+ }
+ ow_.RenderString("nest64", "v1")
+ ->RenderBool("nest64", false)
+ ->StartList("nest64")
+ ->RenderString("", "v2")
+ ->EndList();
+ for (int i = 0; i < count; ++i) {
+ ow_.EndObject();
+ }
+ ow_.EndObject();
+ DoTest(str, 0);
+}
+
+TEST_F(JsonStreamParserTest, DeepNestJsonExceedLimit) {
+ int count = 98;
+ std::string str;
+ for (int i = 0; i < count; ++i) {
+ StrAppend(&str, "{'a':");
+ }
+ // Supports trailing commas.
+ StrAppend(&str,
+ "{'nest11' : [{'nest12' : null,},],"
+ "'nest21' : {'nest22' : {'nest23' : false}}}");
+ for (int i = 0; i < count; ++i) {
+ StrAppend(&str, "}");
+ }
+ DoErrorTest(str, 0,
+ "Message too deep. Max recursion depth reached for key 'nest22'");
+}
+
+} // namespace converter
+} // namespace util
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/util/internal/location_tracker.h b/NorthstarDedicatedTest/include/protobuf/util/internal/location_tracker.h
new file mode 100644
index 00000000..ae7875fd
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/util/internal/location_tracker.h
@@ -0,0 +1,69 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef GOOGLE_PROTOBUF_UTIL_CONVERTER_LOCATION_TRACKER_H__
+#define GOOGLE_PROTOBUF_UTIL_CONVERTER_LOCATION_TRACKER_H__
+
+#include <string>
+
+#include <stubs/common.h>
+
+#include <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 <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_UTIL_CONVERTER_LOCATION_TRACKER_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/util/internal/mock_error_listener.h b/NorthstarDedicatedTest/include/protobuf/util/internal/mock_error_listener.h
new file mode 100644
index 00000000..65376eaf
--- /dev/null
+++ b/NorthstarDedicatedTest/include/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_CONVERTER_MOCK_ERROR_LISTENER_H__
+#define GOOGLE_PROTOBUF_UTIL_CONVERTER_MOCK_ERROR_LISTENER_H__
+
+#include <util/internal/error_listener.h>
+#include <util/internal/location_tracker.h>
+#include <gmock/gmock.h>
+#include <stubs/strutil.h>
+
+namespace google {
+namespace protobuf {
+namespace util {
+namespace converter {
+
+class MockErrorListener : public ErrorListener {
+ public:
+ MockErrorListener() {}
+ virtual ~MockErrorListener() {}
+
+ 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_CONVERTER_MOCK_ERROR_LISTENER_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/util/internal/object_location_tracker.h b/NorthstarDedicatedTest/include/protobuf/util/internal/object_location_tracker.h
new file mode 100644
index 00000000..d5eab1a9
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/util/internal/object_location_tracker.h
@@ -0,0 +1,64 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef GOOGLE_PROTOBUF_UTIL_CONVERTER_OBJECT_LOCATION_TRACKER_H__
+#define GOOGLE_PROTOBUF_UTIL_CONVERTER_OBJECT_LOCATION_TRACKER_H__
+
+#include <string>
+
+#include <stubs/common.h>
+#include <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_CONVERTER_OBJECT_LOCATION_TRACKER_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/util/internal/object_source.h b/NorthstarDedicatedTest/include/protobuf/util/internal/object_source.h
new file mode 100644
index 00000000..378e7350
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/util/internal/object_source.h
@@ -0,0 +1,85 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef GOOGLE_PROTOBUF_UTIL_CONVERTER_OBJECT_SOURCE_H__
+#define GOOGLE_PROTOBUF_UTIL_CONVERTER_OBJECT_SOURCE_H__
+
+#include <stubs/common.h>
+#include <stubs/status.h>
+#include <stubs/strutil.h>
+#include <stubs/status.h>
+
+// Must be included last.
+#include <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 <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_UTIL_CONVERTER_OBJECT_SOURCE_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/util/internal/object_writer.cc b/NorthstarDedicatedTest/include/protobuf/util/internal/object_writer.cc
new file mode 100644
index 00000000..3d57f832
--- /dev/null
+++ b/NorthstarDedicatedTest/include/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 <util/internal/object_writer.h>
+
+#include <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/NorthstarDedicatedTest/include/protobuf/util/internal/object_writer.h b/NorthstarDedicatedTest/include/protobuf/util/internal/object_writer.h
new file mode 100644
index 00000000..abbaa520
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/util/internal/object_writer.h
@@ -0,0 +1,151 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef GOOGLE_PROTOBUF_UTIL_CONVERTER_OBJECT_WRITER_H__
+#define GOOGLE_PROTOBUF_UTIL_CONVERTER_OBJECT_WRITER_H__
+
+#include <cstdint>
+
+#include <stubs/common.h>
+#include <stubs/strutil.h>
+
+// Must be included last.
+#include <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 <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_UTIL_CONVERTER_OBJECT_WRITER_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/util/internal/proto_writer.cc b/NorthstarDedicatedTest/include/protobuf/util/internal/proto_writer.cc
new file mode 100644
index 00000000..33b33262
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/util/internal/proto_writer.cc
@@ -0,0 +1,825 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <util/internal/proto_writer.h>
+
+#include <cstdint>
+#include <functional>
+#include <stack>
+
+#include <stubs/once.h>
+#include <wire_format_lite.h>
+#include <util/internal/field_mask_utility.h>
+#include <util/internal/object_location_tracker.h>
+#include <util/internal/constants.h>
+#include <util/internal/utility.h>
+#include <stubs/strutil.h>
+#include <stubs/statusor.h>
+#include <stubs/time.h>
+#include <stubs/map_util.h>
+
+
+#include <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::set<const google::protobuf::Field*> GetRequiredFields(
+ const google::protobuf::Type& type) {
+ std::set<const google::protobuf::Field*> required;
+ for (int i = 0; i < type.fields_size(); i++) {
+ const google::protobuf::Field& field = type.fields(i);
+ if (field.cardinality() == google::protobuf::Field::CARDINALITY_REQUIRED) {
+ required.insert(&field);
+ }
+ }
+ return required;
+}
+
+} // namespace
+
+ProtoWriter::ProtoElement::ProtoElement(const TypeInfo* typeinfo,
+ const google::protobuf::Type& type,
+ ProtoWriter* enclosing)
+ : BaseElement(nullptr),
+ ow_(enclosing),
+ parent_field_(nullptr),
+ typeinfo_(typeinfo),
+ proto3_(type.syntax() == google::protobuf::SYNTAX_PROTO3),
+ type_(type),
+ size_index_(-1),
+ array_index_(-1),
+ // oneof_indices_ values are 1-indexed (0 means not present).
+ oneof_indices_(type.oneofs_size() + 1) {
+ if (!proto3_) {
+ required_fields_ = GetRequiredFields(type_);
+ }
+}
+
+ProtoWriter::ProtoElement::ProtoElement(ProtoWriter::ProtoElement* parent,
+ const google::protobuf::Field* field,
+ const google::protobuf::Type& type,
+ bool is_list)
+ : BaseElement(parent),
+ ow_(this->parent()->ow_),
+ parent_field_(field),
+ typeinfo_(this->parent()->typeinfo_),
+ proto3_(type.syntax() == google::protobuf::SYNTAX_PROTO3),
+ type_(type),
+ size_index_(!is_list &&
+ field->kind() == google::protobuf::Field::TYPE_MESSAGE
+ ? ow_->size_insert_.size()
+ : -1),
+ array_index_(is_list ? 0 : -1),
+ // oneof_indices_ values are 1-indexed (0 means not present).
+ oneof_indices_(type_.oneofs_size() + 1) {
+ if (!is_list) {
+ if (ow_->IsRepeated(*field)) {
+ // Update array_index_ if it is an explicit list.
+ if (this->parent()->array_index_ >= 0) this->parent()->array_index_++;
+ } else if (!proto3_) {
+ // For required fields tracking.
+ this->parent()->RegisterField(field);
+ }
+
+ if (field->kind() == google::protobuf::Field::TYPE_MESSAGE) {
+ if (!proto3_) {
+ required_fields_ = GetRequiredFields(type_);
+ }
+ int start_pos = ow_->stream_->ByteCount();
+ // length of serialized message is the final buffer position minus
+ // starting buffer position, plus length adjustments for size fields
+ // of any nested messages. We start with -start_pos here, so we only
+ // need to add the final buffer position to it at the end.
+ SizeInfo info = {start_pos, -start_pos};
+ ow_->size_insert_.push_back(info);
+ }
+ }
+}
+
+ProtoWriter::ProtoElement* ProtoWriter::ProtoElement::pop() {
+ if (!proto3_) {
+ // Calls the registered error listener for any required field(s) not yet
+ // seen.
+ for (std::set<const google::protobuf::Field*>::iterator it =
+ required_fields_.begin();
+ it != required_fields_.end(); ++it) {
+ ow_->MissingField(ow_->use_json_name_in_missing_fields_
+ ? (*it)->json_name()
+ : (*it)->name());
+ }
+ }
+ // Computes the total number of proto bytes used by a message, also adjusts
+ // the size of all parent messages by the length of this size field.
+ // If size_index_ < 0, this is not a message, so no size field is added.
+ if (size_index_ >= 0) {
+ // Add the final buffer position to compute the total length of this
+ // serialized message. The stored value (before this addition) already
+ // contains the total length of the size fields of all nested messages
+ // minus the initial buffer position.
+ ow_->size_insert_[size_index_].size += ow_->stream_->ByteCount();
+ // Calculate the length required to serialize the size field of the
+ // message, and propagate this additional size information upward to
+ // all enclosing messages.
+ int size = ow_->size_insert_[size_index_].size;
+ int length = CodedOutputStream::VarintSize32(size);
+ for (ProtoElement* e = parent(); e != nullptr; e = e->parent()) {
+ // Only nested messages have size field, lists do not have size field.
+ if (e->size_index_ >= 0) {
+ ow_->size_insert_[e->size_index_].size += length;
+ }
+ }
+ }
+ return BaseElement::pop<ProtoElement>();
+}
+
+void ProtoWriter::ProtoElement::RegisterField(
+ const google::protobuf::Field* field) {
+ if (!required_fields_.empty() &&
+ field->cardinality() == google::protobuf::Field::CARDINALITY_REQUIRED) {
+ required_fields_.erase(field);
+ }
+}
+
+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/NorthstarDedicatedTest/include/protobuf/util/internal/proto_writer.h b/NorthstarDedicatedTest/include/protobuf/util/internal/proto_writer.h
new file mode 100644
index 00000000..562ff8dd
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/util/internal/proto_writer.h
@@ -0,0 +1,388 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef GOOGLE_PROTOBUF_UTIL_CONVERTER_PROTO_WRITER_H__
+#define GOOGLE_PROTOBUF_UTIL_CONVERTER_PROTO_WRITER_H__
+
+#include <cstdint>
+#include <deque>
+#include <string>
+#include <vector>
+
+#include <stubs/common.h>
+#include <type.pb.h>
+#include <io/coded_stream.h>
+#include <io/zero_copy_stream_impl.h>
+#include <descriptor.h>
+#include <util/internal/type_info.h>
+#include <util/internal/datapiece.h>
+#include <util/internal/error_listener.h>
+#include <util/internal/structured_objectwriter.h>
+#include <util/type_resolver.h>
+#include <stubs/bytestream.h>
+#include <stubs/status.h>
+#include <stubs/hash.h>
+#include <stubs/status.h>
+
+// Must be included last.
+#include <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::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 <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_UTIL_CONVERTER_PROTO_WRITER_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/util/internal/protostream_objectsource.cc b/NorthstarDedicatedTest/include/protobuf/util/internal/protostream_objectsource.cc
new file mode 100644
index 00000000..801e90a3
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/util/internal/protostream_objectsource.cc
@@ -0,0 +1,1112 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <util/internal/protostream_objectsource.h>
+
+#include <cstdint>
+#include <unordered_map>
+#include <utility>
+
+#include <stubs/logging.h>
+#include <stubs/common.h>
+#include <stubs/stringprintf.h>
+#include <io/coded_stream.h>
+#include <io/zero_copy_stream_impl.h>
+#include <descriptor.h>
+#include <stubs/once.h>
+#include <unknown_field_set.h>
+#include <wire_format.h>
+#include <wire_format_lite.h>
+#include <util/internal/field_mask_utility.h>
+#include <util/internal/constants.h>
+#include <util/internal/utility.h>
+#include <stubs/strutil.h>
+#include <stubs/casts.h>
+#include <stubs/status.h>
+#include <stubs/time.h>
+#include <stubs/map_util.h>
+#include <stubs/status_macros.h>
+
+
+#include <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>(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>(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>(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>(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 char* format = (nanos % 1000 != 0) ? "%.9f"
+ : (nanos % 1000000 != 0) ? "%.6f"
+ : "%.3f";
+ std::string formatted =
+ StringPrintf(format, static_cast<double>(nanos) / kNanosPerSecond);
+ // remove the leading 0 before decimal.
+ return formatted.substr(1);
+}
+} // namespace
+
+} // namespace converter
+} // namespace util
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/util/internal/protostream_objectsource.h b/NorthstarDedicatedTest/include/protobuf/util/internal/protostream_objectsource.h
new file mode 100644
index 00000000..d3e4d8cb
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/util/internal/protostream_objectsource.h
@@ -0,0 +1,328 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef GOOGLE_PROTOBUF_UTIL_CONVERTER_PROTOSTREAM_OBJECTSOURCE_H__
+#define GOOGLE_PROTOBUF_UTIL_CONVERTER_PROTOSTREAM_OBJECTSOURCE_H__
+
+#include <cstdint>
+#include <functional>
+#include <string>
+#include <unordered_map>
+
+#include <stubs/status.h>
+
+#include <stubs/common.h>
+#include <type.pb.h>
+#include <util/internal/type_info.h>
+#include <util/internal/object_source.h>
+#include <util/internal/object_writer.h>
+#include <util/type_resolver.h>
+#include <stubs/statusor.h>
+#include <stubs/strutil.h>
+#include <stubs/hash.h>
+#include <stubs/status.h>
+
+
+#include <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 <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_UTIL_CONVERTER_PROTOSTREAM_OBJECTSOURCE_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/util/internal/protostream_objectsource_test.cc b/NorthstarDedicatedTest/include/protobuf/util/internal/protostream_objectsource_test.cc
new file mode 100644
index 00000000..ec35789c
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/util/internal/protostream_objectsource_test.cc
@@ -0,0 +1,1165 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 <util/internal/protostream_objectsource.h>
+
+#include <cstdint>
+#include <memory>
+#include <sstream>
+
+#include <any.pb.h>
+#include <io/coded_stream.h>
+#include <io/zero_copy_stream_impl_lite.h>
+#include <descriptor.h>
+#include <util/internal/expecting_objectwriter.h>
+#include <util/internal/testdata/anys.pb.h>
+#include <util/internal/testdata/books.pb.h>
+#include <util/internal/testdata/field_mask.pb.h>
+#include <util/internal/testdata/maps.pb.h>
+#include <util/internal/testdata/proto3.pb.h>
+#include <util/internal/testdata/struct.pb.h>
+#include <util/internal/testdata/timestamp_duration.pb.h>
+#include <util/internal/type_info_test_helper.h>
+#include <util/internal/constants.h>
+#include <gtest/gtest.h>
+#include <stubs/casts.h>
+#include <stubs/status.h>
+
+
+namespace google {
+namespace protobuf {
+namespace util {
+namespace converter {
+
+using ::google::protobuf::Any;
+using io::ArrayInputStream;
+using io::CodedInputStream;
+using proto_util_converter::testing::AnyM;
+using proto_util_converter::testing::AnyOut;
+using proto_util_converter::testing::Author;
+using proto_util_converter::testing::BadAuthor;
+using proto_util_converter::testing::BadNestedBook;
+using proto_util_converter::testing::Book;
+using proto_util_converter::testing::Book_Label;
+using proto_util_converter::testing::Cyclic;
+using proto_util_converter::testing::FieldMaskTest;
+using proto_util_converter::testing::MapOut;
+using proto_util_converter::testing::MapOutWireFormat;
+using proto_util_converter::testing::NestedBook;
+using proto_util_converter::testing::NestedFieldMask;
+using proto_util_converter::testing::PackedPrimitive;
+using proto_util_converter::testing::Primitive;
+using proto_util_converter::testing::Proto3Message;
+using proto_util_converter::testing::StructType;
+using proto_util_converter::testing::TimestampDuration;
+using ::testing::_;
+
+
+namespace {
+std::string GetTypeUrl(const Descriptor* descriptor) {
+ return std::string(kTypeServiceBaseUrl) + "/" + descriptor->full_name();
+}
+} // namespace
+
+class ProtostreamObjectSourceTest
+ : public ::testing::TestWithParam<testing::TypeInfoSource> {
+ protected:
+ ProtostreamObjectSourceTest()
+ : helper_(GetParam()),
+ mock_(),
+ ow_(&mock_),
+ use_lower_camel_for_enums_(false),
+ use_ints_for_enums_(false),
+ use_preserve_proto_field_names_(false),
+ add_trailing_zeros_(false),
+ render_unknown_enum_values_(true) {
+ helper_.ResetTypeInfo(Book::descriptor(), Proto3Message::descriptor());
+ }
+
+ virtual ~ProtostreamObjectSourceTest() {}
+
+ void DoTest(const Message& msg, const Descriptor* descriptor) {
+ util::Status status = ExecuteTest(msg, descriptor);
+ EXPECT_EQ(util::Status(), status);
+ }
+
+ util::Status ExecuteTest(const Message& msg, const Descriptor* descriptor) {
+ std::ostringstream oss;
+ msg.SerializePartialToOstream(&oss);
+ std::string proto = oss.str();
+ ArrayInputStream arr_stream(proto.data(), proto.size());
+ CodedInputStream in_stream(&arr_stream);
+
+ ProtoStreamObjectSource::RenderOptions render_options;
+ render_options.use_lower_camel_for_enums = use_lower_camel_for_enums_;
+ render_options.use_ints_for_enums = use_ints_for_enums_;
+ render_options.preserve_proto_field_names = use_preserve_proto_field_names_;
+ std::unique_ptr<ProtoStreamObjectSource> os(helper_.NewProtoSource(
+ &in_stream, GetTypeUrl(descriptor), render_options));
+ os->set_max_recursion_depth(64);
+ return os->WriteTo(&mock_);
+ }
+
+ void PrepareExpectingObjectWriterForRepeatedPrimitive() {
+ ow_.StartObject("")
+ ->StartList("repFix32")
+ ->RenderUint32("", bit_cast<uint32_t>(3201))
+ ->RenderUint32("", bit_cast<uint32_t>(0))
+ ->RenderUint32("", bit_cast<uint32_t>(3202))
+ ->EndList()
+ ->StartList("repU32")
+ ->RenderUint32("", bit_cast<uint32_t>(3203))
+ ->RenderUint32("", bit_cast<uint32_t>(0))
+ ->EndList()
+ ->StartList("repI32")
+ ->RenderInt32("", 0)
+ ->RenderInt32("", 3204)
+ ->RenderInt32("", 3205)
+ ->EndList()
+ ->StartList("repSf32")
+ ->RenderInt32("", 3206)
+ ->RenderInt32("", 0)
+ ->EndList()
+ ->StartList("repS32")
+ ->RenderInt32("", 0)
+ ->RenderInt32("", 3207)
+ ->RenderInt32("", 3208)
+ ->EndList()
+ ->StartList("repFix64")
+ ->RenderUint64("", bit_cast<uint64_t>(int64_t{6401}))
+ ->RenderUint64("", bit_cast<uint64_t>(int64_t{0}))
+ ->EndList()
+ ->StartList("repU64")
+ ->RenderUint64("", bit_cast<uint64_t>(int64_t{0}))
+ ->RenderUint64("", bit_cast<uint64_t>(int64_t{6402}))
+ ->RenderUint64("", bit_cast<uint64_t>(int64_t{6403}))
+ ->EndList()
+ ->StartList("repI64")
+ ->RenderInt64("", 6404L)
+ ->RenderInt64("", 0L)
+ ->EndList()
+ ->StartList("repSf64")
+ ->RenderInt64("", 0L)
+ ->RenderInt64("", 6405L)
+ ->RenderInt64("", 6406L)
+ ->EndList()
+ ->StartList("repS64")
+ ->RenderInt64("", 6407L)
+ ->RenderInt64("", 0L)
+ ->EndList()
+ ->StartList("repFloat")
+ ->RenderFloat("", 0.0f)
+ ->RenderFloat("", 32.1f)
+ ->RenderFloat("", 32.2f)
+ ->EndList()
+ ->StartList("repDouble")
+ ->RenderDouble("", 64.1L)
+ ->RenderDouble("", 0.0L)
+ ->EndList()
+ ->StartList("repBool")
+ ->RenderBool("", true)
+ ->RenderBool("", false)
+ ->EndList()
+ ->EndObject();
+ }
+
+ Primitive PrepareRepeatedPrimitive() {
+ Primitive primitive;
+ primitive.add_rep_fix32(3201);
+ primitive.add_rep_fix32(0);
+ primitive.add_rep_fix32(3202);
+ primitive.add_rep_u32(3203);
+ primitive.add_rep_u32(0);
+ primitive.add_rep_i32(0);
+ primitive.add_rep_i32(3204);
+ primitive.add_rep_i32(3205);
+ primitive.add_rep_sf32(3206);
+ primitive.add_rep_sf32(0);
+ primitive.add_rep_s32(0);
+ primitive.add_rep_s32(3207);
+ primitive.add_rep_s32(3208);
+ primitive.add_rep_fix64(6401L);
+ primitive.add_rep_fix64(0L);
+ primitive.add_rep_u64(0L);
+ primitive.add_rep_u64(6402L);
+ primitive.add_rep_u64(6403L);
+ primitive.add_rep_i64(6404L);
+ primitive.add_rep_i64(0L);
+ primitive.add_rep_sf64(0L);
+ primitive.add_rep_sf64(6405L);
+ primitive.add_rep_sf64(6406L);
+ primitive.add_rep_s64(6407L);
+ primitive.add_rep_s64(0L);
+ primitive.add_rep_float(0.0f);
+ primitive.add_rep_float(32.1f);
+ primitive.add_rep_float(32.2f);
+ primitive.add_rep_double(64.1L);
+ primitive.add_rep_double(0.0);
+ primitive.add_rep_bool(true);
+ primitive.add_rep_bool(false);
+
+ PrepareExpectingObjectWriterForRepeatedPrimitive();
+ return primitive;
+ }
+
+ PackedPrimitive PreparePackedPrimitive() {
+ PackedPrimitive primitive;
+ primitive.add_rep_fix32(3201);
+ primitive.add_rep_fix32(0);
+ primitive.add_rep_fix32(3202);
+ primitive.add_rep_u32(3203);
+ primitive.add_rep_u32(0);
+ primitive.add_rep_i32(0);
+ primitive.add_rep_i32(3204);
+ primitive.add_rep_i32(3205);
+ primitive.add_rep_sf32(3206);
+ primitive.add_rep_sf32(0);
+ primitive.add_rep_s32(0);
+ primitive.add_rep_s32(3207);
+ primitive.add_rep_s32(3208);
+ primitive.add_rep_fix64(6401L);
+ primitive.add_rep_fix64(0L);
+ primitive.add_rep_u64(0L);
+ primitive.add_rep_u64(6402L);
+ primitive.add_rep_u64(6403L);
+ primitive.add_rep_i64(6404L);
+ primitive.add_rep_i64(0L);
+ primitive.add_rep_sf64(0L);
+ primitive.add_rep_sf64(6405L);
+ primitive.add_rep_sf64(6406L);
+ primitive.add_rep_s64(6407L);
+ primitive.add_rep_s64(0L);
+ primitive.add_rep_float(0.0f);
+ primitive.add_rep_float(32.1f);
+ primitive.add_rep_float(32.2f);
+ primitive.add_rep_double(64.1L);
+ primitive.add_rep_double(0.0);
+ primitive.add_rep_bool(true);
+ primitive.add_rep_bool(false);
+
+ PrepareExpectingObjectWriterForRepeatedPrimitive();
+ return primitive;
+ }
+
+ void UseLowerCamelForEnums() { use_lower_camel_for_enums_ = true; }
+
+ void UseIntsForEnums() { use_ints_for_enums_ = true; }
+
+ void UsePreserveProtoFieldNames() { use_preserve_proto_field_names_ = true; }
+
+ void AddTrailingZeros() { add_trailing_zeros_ = true; }
+
+ void SetRenderUnknownEnumValues(bool value) {
+ render_unknown_enum_values_ = value;
+ }
+
+ testing::TypeInfoTestHelper helper_;
+
+ ::testing::NiceMock<MockObjectWriter> mock_;
+ ExpectingObjectWriter ow_;
+ bool use_lower_camel_for_enums_;
+ bool use_ints_for_enums_;
+ bool use_preserve_proto_field_names_;
+ bool add_trailing_zeros_;
+ bool render_unknown_enum_values_;
+};
+
+INSTANTIATE_TEST_SUITE_P(DifferentTypeInfoSourceTest,
+ ProtostreamObjectSourceTest,
+ ::testing::Values(
+ testing::USE_TYPE_RESOLVER));
+
+TEST_P(ProtostreamObjectSourceTest, EmptyMessage) {
+ Book empty;
+ ow_.StartObject("")->EndObject();
+ DoTest(empty, Book::descriptor());
+}
+
+TEST_P(ProtostreamObjectSourceTest, Primitives) {
+ Primitive primitive;
+ primitive.set_fix32(3201);
+ primitive.set_u32(3202);
+ primitive.set_i32(3203);
+ primitive.set_sf32(3204);
+ primitive.set_s32(3205);
+ primitive.set_fix64(6401L);
+ primitive.set_u64(6402L);
+ primitive.set_i64(6403L);
+ primitive.set_sf64(6404L);
+ primitive.set_s64(6405L);
+ primitive.set_str("String Value");
+ primitive.set_bytes("Some Bytes");
+ primitive.set_float_(32.1f);
+ primitive.set_double_(64.1L);
+ primitive.set_bool_(true);
+
+ ow_.StartObject("")
+ ->RenderUint32("fix32", bit_cast<uint32_t>(3201))
+ ->RenderUint32("u32", bit_cast<uint32_t>(3202))
+ ->RenderInt32("i32", 3203)
+ ->RenderInt32("sf32", 3204)
+ ->RenderInt32("s32", 3205)
+ ->RenderUint64("fix64", bit_cast<uint64_t>(int64_t{6401}))
+ ->RenderUint64("u64", bit_cast<uint64_t>(int64_t{6402}))
+ ->RenderInt64("i64", 6403L)
+ ->RenderInt64("sf64", 6404L)
+ ->RenderInt64("s64", 6405L)
+ ->RenderString("str", "String Value")
+ ->RenderBytes("bytes", "Some Bytes")
+ ->RenderFloat("float", 32.1f)
+ ->RenderDouble("double", 64.1L)
+ ->RenderBool("bool", true)
+ ->EndObject();
+ DoTest(primitive, Primitive::descriptor());
+}
+
+TEST_P(ProtostreamObjectSourceTest, RepeatingPrimitives) {
+ Primitive primitive = PrepareRepeatedPrimitive();
+ primitive.add_rep_str("String One");
+ primitive.add_rep_str("String Two");
+ primitive.add_rep_bytes("Some Bytes");
+
+ ow_.StartList("repStr")
+ ->RenderString("", "String One")
+ ->RenderString("", "String Two")
+ ->EndList()
+ ->StartList("repBytes")
+ ->RenderBytes("", "Some Bytes")
+ ->EndList();
+ DoTest(primitive, Primitive::descriptor());
+}
+
+TEST_P(ProtostreamObjectSourceTest, CustomJsonName) {
+ Author author;
+ author.set_id(12345);
+
+ ow_.StartObject("")->RenderUint64("@id", 12345)->EndObject();
+ DoTest(author, Author::descriptor());
+}
+
+TEST_P(ProtostreamObjectSourceTest, NestedMessage) {
+ Author* author = new Author();
+ author->set_name("Tolstoy");
+ Book book;
+ book.set_title("My Book");
+ book.set_allocated_author(author);
+
+ ow_.StartObject("")
+ ->RenderString("title", "My Book")
+ ->StartObject("author")
+ ->RenderString("name", "Tolstoy")
+ ->EndObject()
+ ->EndObject();
+ DoTest(book, Book::descriptor());
+}
+
+TEST_P(ProtostreamObjectSourceTest, RepeatingField) {
+ Author author;
+ author.set_alive(false);
+ author.set_name("john");
+ author.add_pseudonym("phil");
+ author.add_pseudonym("bob");
+
+ ow_.StartObject("")
+ ->RenderBool("alive", false)
+ ->RenderString("name", "john")
+ ->StartList("pseudonym")
+ ->RenderString("", "phil")
+ ->RenderString("", "bob")
+ ->EndList()
+ ->EndObject();
+ DoTest(author, Author::descriptor());
+}
+
+TEST_P(ProtostreamObjectSourceTest, PackedRepeatingFields) {
+ DoTest(PreparePackedPrimitive(), PackedPrimitive::descriptor());
+}
+
+TEST_P(ProtostreamObjectSourceTest, NonPackedPackableFieldsActuallyPacked) {
+ // Protostream is packed, but parse with non-packed Primitive.
+ DoTest(PreparePackedPrimitive(), Primitive::descriptor());
+}
+
+TEST_P(ProtostreamObjectSourceTest, PackedPackableFieldNotActuallyPacked) {
+ // Protostream is not packed, but parse with PackedPrimitive.
+ DoTest(PrepareRepeatedPrimitive(), PackedPrimitive::descriptor());
+}
+
+TEST_P(ProtostreamObjectSourceTest, BadAuthor) {
+ Author author;
+ author.set_alive(false);
+ author.set_name("john");
+ author.set_id(1234L);
+ author.add_pseudonym("phil");
+ author.add_pseudonym("bob");
+
+ ow_.StartObject("")
+ ->StartList("alive")
+ ->RenderBool("", false)
+ ->EndList()
+ ->StartList("name")
+ ->RenderUint64("", static_cast<uint64_t>('j'))
+ ->RenderUint64("", static_cast<uint64_t>('o'))
+ ->RenderUint64("", static_cast<uint64_t>('h'))
+ ->RenderUint64("", static_cast<uint64_t>('n'))
+ ->EndList()
+ ->RenderString("pseudonym", "phil")
+ ->RenderString("pseudonym", "bob")
+ ->EndObject();
+ // Protostream created with Author, but parsed with BadAuthor.
+ DoTest(author, BadAuthor::descriptor());
+}
+
+TEST_P(ProtostreamObjectSourceTest, NestedBookToBadNestedBook) {
+ Book* book = new Book();
+ book->set_length(250);
+ book->set_published(2014L);
+ NestedBook nested;
+ nested.set_allocated_book(book);
+
+ ow_.StartObject("")
+ ->StartList("book")
+ ->RenderUint32("", 24) // tag for field length (3 << 3)
+ ->RenderUint32("", 250)
+ ->RenderUint32("", 32) // tag for field published (4 << 3)
+ ->RenderUint32("", 2014)
+ ->EndList()
+ ->EndObject();
+ // Protostream created with NestedBook, but parsed with BadNestedBook.
+ DoTest(nested, BadNestedBook::descriptor());
+}
+
+TEST_P(ProtostreamObjectSourceTest, BadNestedBookToNestedBook) {
+ BadNestedBook nested;
+ nested.add_book(1);
+ nested.add_book(2);
+ nested.add_book(3);
+ nested.add_book(4);
+ nested.add_book(5);
+ nested.add_book(6);
+ nested.add_book(7);
+
+ ow_.StartObject("")->StartObject("book")->EndObject()->EndObject();
+ // Protostream created with BadNestedBook, but parsed with NestedBook.
+ DoTest(nested, NestedBook::descriptor());
+}
+
+TEST_P(ProtostreamObjectSourceTest,
+ LongRepeatedListDoesNotBreakIntoMultipleJsonLists) {
+ Book book;
+
+ int repeat = 10000;
+ for (int i = 0; i < repeat; ++i) {
+ Book_Label* label = book.add_labels();
+ label->set_key(StrCat("i", i));
+ label->set_value(StrCat("v", i));
+ }
+
+ // Make sure StartList and EndList are called exactly once (see b/18227499 for
+ // problems when this doesn't happen)
+ EXPECT_CALL(mock_, StartList(_)).Times(1);
+ EXPECT_CALL(mock_, EndList()).Times(1);
+
+ DoTest(book, Book::descriptor());
+}
+
+TEST_P(ProtostreamObjectSourceTest, LowerCamelEnumOutputMacroCase) {
+ Book book;
+ book.set_type(Book::ACTION_AND_ADVENTURE);
+
+ UseLowerCamelForEnums();
+
+ ow_.StartObject("")->RenderString("type", "actionAndAdventure")->EndObject();
+ DoTest(book, Book::descriptor());
+}
+
+TEST_P(ProtostreamObjectSourceTest, LowerCamelEnumOutputSnakeCase) {
+ Book book;
+ book.set_type(Book::arts_and_photography);
+
+ UseLowerCamelForEnums();
+
+ ow_.StartObject("")->RenderString("type", "artsAndPhotography")->EndObject();
+ DoTest(book, Book::descriptor());
+}
+
+TEST_P(ProtostreamObjectSourceTest, LowerCamelEnumOutputWithNumber) {
+ Book book;
+ book.set_type(Book::I18N_Tech);
+
+ UseLowerCamelForEnums();
+
+ ow_.StartObject("")->RenderString("type", "i18nTech")->EndObject();
+ DoTest(book, Book::descriptor());
+}
+
+TEST_P(ProtostreamObjectSourceTest, EnumCaseIsUnchangedByDefault) {
+ Book book;
+ book.set_type(Book::ACTION_AND_ADVENTURE);
+ ow_.StartObject("")
+ ->RenderString("type", "ACTION_AND_ADVENTURE")
+ ->EndObject();
+ DoTest(book, Book::descriptor());
+}
+
+TEST_P(ProtostreamObjectSourceTest, UseIntsForEnumsTest) {
+ Book book;
+ book.set_type(Book::ACTION_AND_ADVENTURE);
+
+ UseIntsForEnums();
+
+ ow_.StartObject("")->RenderInt32("type", 3)->EndObject();
+ DoTest(book, Book::descriptor());
+}
+
+TEST_P(ProtostreamObjectSourceTest, UsePreserveProtoFieldNames) {
+ Book book;
+ book.set_snake_field("foo");
+
+ UsePreserveProtoFieldNames();
+
+ ow_.StartObject("")->RenderString("snake_field", "foo")->EndObject();
+ DoTest(book, Book::descriptor());
+}
+
+TEST_P(ProtostreamObjectSourceTest,
+ UnknownEnumAreDroppedWhenRenderUnknownEnumValuesIsUnset) {
+ Proto3Message message;
+ message.set_enum_value(static_cast<Proto3Message::NestedEnum>(1234));
+
+ SetRenderUnknownEnumValues(false);
+
+ // Unknown enum values are not output.
+ ow_.StartObject("")->EndObject();
+ DoTest(message, Proto3Message::descriptor());
+}
+
+TEST_P(ProtostreamObjectSourceTest,
+ UnknownEnumAreOutputWhenRenderUnknownEnumValuesIsSet) {
+ Proto3Message message;
+ message.set_enum_value(static_cast<Proto3Message::NestedEnum>(1234));
+
+ SetRenderUnknownEnumValues(true);
+
+ // Unknown enum values are output.
+ ow_.StartObject("")->RenderInt32("enumValue", 1234)->EndObject();
+ DoTest(message, Proto3Message::descriptor());
+}
+
+TEST_P(ProtostreamObjectSourceTest, CyclicMessageDepthTest) {
+ Cyclic cyclic;
+ cyclic.set_m_int(123);
+
+ Book* book = cyclic.mutable_m_book();
+ book->set_title("book title");
+ Cyclic* current = cyclic.mutable_m_cyclic();
+ Author* current_author = cyclic.add_m_author();
+ for (int i = 0; i < 63; ++i) {
+ Author* next = current_author->add_friend_();
+ next->set_id(i);
+ next->set_name(StrCat("author_name_", i));
+ next->set_alive(true);
+ current_author = next;
+ }
+
+ // Recursive message with depth (65) > max (max is 64).
+ for (int i = 0; i < 64; ++i) {
+ Cyclic* next = current->mutable_m_cyclic();
+ next->set_m_str(StrCat("count_", i));
+ current = next;
+ }
+
+ util::Status status = ExecuteTest(cyclic, Cyclic::descriptor());
+ EXPECT_TRUE(util::IsInvalidArgument(status));
+}
+
+class ProtostreamObjectSourceMapsTest : public ProtostreamObjectSourceTest {
+ protected:
+ ProtostreamObjectSourceMapsTest() {
+ helper_.ResetTypeInfo(MapOut::descriptor());
+ }
+};
+
+INSTANTIATE_TEST_SUITE_P(DifferentTypeInfoSourceTest,
+ ProtostreamObjectSourceMapsTest,
+ ::testing::Values(
+ testing::USE_TYPE_RESOLVER));
+
+// Tests JSON map.
+//
+// This is the example expected output.
+// {
+// "map1": {
+// "key1": {
+// "foo": "foovalue"
+// },
+// "key2": {
+// "foo": "barvalue"
+// }
+// },
+// "map2": {
+// "nestedself": {
+// "map1": {
+// "nested_key1": {
+// "foo": "nested_foo"
+// }
+// },
+// "bar": "nested_bar_string"
+// }
+// },
+// "map3": {
+// "111": "one one one"
+// },
+// "bar": "top bar"
+// }
+TEST_P(ProtostreamObjectSourceMapsTest, MapsTest) {
+ MapOut out;
+ (*out.mutable_map1())["key1"].set_foo("foovalue");
+ (*out.mutable_map1())["key2"].set_foo("barvalue");
+
+ MapOut* nested_value = &(*out.mutable_map2())["nestedself"];
+ (*nested_value->mutable_map1())["nested_key1"].set_foo("nested_foo");
+ nested_value->set_bar("nested_bar_string");
+
+ (*out.mutable_map3())[111] = "one one one";
+
+ out.set_bar("top bar");
+
+ ow_.StartObject("")
+ ->StartObject("map1")
+ ->StartObject("key1")
+ ->RenderString("foo", "foovalue")
+ ->EndObject()
+ ->StartObject("key2")
+ ->RenderString("foo", "barvalue")
+ ->EndObject()
+ ->StartObject("map2")
+ ->StartObject("nestedself")
+ ->StartObject("map1")
+ ->StartObject("nested_key1")
+ ->RenderString("foo", "nested_foo")
+ ->EndObject()
+ ->EndObject()
+ ->RenderString("bar", "nested_bar_string")
+ ->EndObject()
+ ->EndObject()
+ ->StartObject("map3")
+ ->RenderString("111", "one one one")
+ ->EndObject()
+ ->EndObject()
+ ->RenderString("bar", "top bar")
+ ->EndObject();
+
+ DoTest(out, MapOut::descriptor());
+}
+
+TEST_P(ProtostreamObjectSourceMapsTest, MissingKeysTest) {
+ // MapOutWireFormat has the same wire representation with MapOut but uses
+ // repeated message fields to represent map fields so we can intentionally
+ // leave out the key field or the value field of a map entry.
+ MapOutWireFormat out;
+ // Create some map entries without keys. They will be rendered with the
+ // default values ("" for strings, "0" for integers, etc.).
+ // {
+ // "map1": {
+ // "": {
+ // "foo": "foovalue"
+ // }
+ // },
+ // "map2": {
+ // "": {
+ // "map1": {
+ // "nested_key1": {
+ // "foo": "nested_foo"
+ // }
+ // }
+ // }
+ // },
+ // "map3": {
+ // "0": "one one one"
+ // },
+ // "map4": {
+ // "false": "bool"
+ // }
+ // }
+ out.add_map1()->mutable_value()->set_foo("foovalue");
+ MapOut* nested = out.add_map2()->mutable_value();
+ (*nested->mutable_map1())["nested_key1"].set_foo("nested_foo");
+ out.add_map3()->set_value("one one one");
+ out.add_map4()->set_value("bool");
+
+ ow_.StartObject("")
+ ->StartObject("map1")
+ ->StartObject("")
+ ->RenderString("foo", "foovalue")
+ ->EndObject()
+ ->EndObject()
+ ->StartObject("map2")
+ ->StartObject("")
+ ->StartObject("map1")
+ ->StartObject("nested_key1")
+ ->RenderString("foo", "nested_foo")
+ ->EndObject()
+ ->EndObject()
+ ->EndObject()
+ ->EndObject()
+ ->StartObject("map3")
+ ->RenderString("0", "one one one")
+ ->EndObject()
+ ->StartObject("map4")
+ ->RenderString("false", "bool")
+ ->EndObject()
+ ->EndObject();
+
+ DoTest(out, MapOut::descriptor());
+}
+
+class ProtostreamObjectSourceAnysTest : public ProtostreamObjectSourceTest {
+ protected:
+ ProtostreamObjectSourceAnysTest() {
+ helper_.ResetTypeInfo({AnyOut::descriptor(), Book::descriptor(),
+ google::protobuf::Any::descriptor()});
+ }
+};
+
+INSTANTIATE_TEST_SUITE_P(DifferentTypeInfoSourceTest,
+ ProtostreamObjectSourceAnysTest,
+ ::testing::Values(
+ testing::USE_TYPE_RESOLVER));
+
+// Tests JSON any support.
+//
+// This is the example expected output.
+// {
+// "any": {
+// "@type": "type.googleapis.com/google.protobuf.testing.AnyM"
+// "foo": "foovalue"
+// }
+// }
+TEST_P(ProtostreamObjectSourceAnysTest, BasicAny) {
+ AnyOut out;
+ ::google::protobuf::Any* any = out.mutable_any();
+
+ AnyM m;
+ m.set_foo("foovalue");
+ any->PackFrom(m);
+
+ ow_.StartObject("")
+ ->StartObject("any")
+ ->RenderString("@type",
+ "type.googleapis.com/proto_util_converter.testing.AnyM")
+ ->RenderString("foo", "foovalue")
+ ->EndObject()
+ ->EndObject();
+
+ DoTest(out, AnyOut::descriptor());
+}
+
+TEST_P(ProtostreamObjectSourceAnysTest, LowerCamelEnumOutputSnakeCase) {
+ AnyOut out;
+ ::google::protobuf::Any* any = out.mutable_any();
+
+ Book book;
+ book.set_type(Book::arts_and_photography);
+ any->PackFrom(book);
+
+ UseLowerCamelForEnums();
+
+ ow_.StartObject("")
+ ->StartObject("any")
+ ->RenderString("@type",
+ "type.googleapis.com/proto_util_converter.testing.Book")
+ ->RenderString("type", "artsAndPhotography")
+ ->EndObject()
+ ->EndObject();
+
+ DoTest(out, AnyOut::descriptor());
+}
+
+TEST_P(ProtostreamObjectSourceAnysTest, UseIntsForEnumsTest) {
+ AnyOut out;
+ ::google::protobuf::Any* any = out.mutable_any();
+
+ Book book;
+ book.set_type(Book::ACTION_AND_ADVENTURE);
+ any->PackFrom(book);
+
+ UseIntsForEnums();
+
+ ow_.StartObject("")
+ ->StartObject("any")
+ ->RenderString("@type",
+ "type.googleapis.com/proto_util_converter.testing.Book")
+ ->RenderInt32("type", 3)
+ ->EndObject()
+ ->EndObject();
+
+ DoTest(out, AnyOut::descriptor());
+}
+
+TEST_P(ProtostreamObjectSourceAnysTest, UsePreserveProtoFieldNames) {
+ AnyOut out;
+ ::google::protobuf::Any* any = out.mutable_any();
+
+ Book book;
+ book.set_snake_field("foo");
+ any->PackFrom(book);
+
+ UsePreserveProtoFieldNames();
+
+ ow_.StartObject("")
+ ->StartObject("any")
+ ->RenderString("@type",
+ "type.googleapis.com/proto_util_converter.testing.Book")
+ ->RenderString("snake_field", "foo")
+ ->EndObject()
+ ->EndObject();
+
+ DoTest(out, AnyOut::descriptor());
+}
+
+TEST_P(ProtostreamObjectSourceAnysTest, RecursiveAny) {
+ AnyOut out;
+ ::google::protobuf::Any* any = out.mutable_any();
+ any->set_type_url("type.googleapis.com/google.protobuf.Any");
+
+ ::google::protobuf::Any nested_any;
+ nested_any.set_type_url(
+ "type.googleapis.com/proto_util_converter.testing.AnyM");
+
+ AnyM m;
+ m.set_foo("foovalue");
+ nested_any.set_value(m.SerializeAsString());
+
+ any->set_value(nested_any.SerializeAsString());
+
+ ow_.StartObject("")
+ ->StartObject("any")
+ ->RenderString("@type", "type.googleapis.com/google.protobuf.Any")
+ ->StartObject("value")
+ ->RenderString("@type",
+ "type.googleapis.com/proto_util_converter.testing.AnyM")
+ ->RenderString("foo", "foovalue")
+ ->EndObject()
+ ->EndObject()
+ ->EndObject();
+
+ DoTest(out, AnyOut::descriptor());
+}
+
+TEST_P(ProtostreamObjectSourceAnysTest, DoubleRecursiveAny) {
+ AnyOut out;
+ ::google::protobuf::Any* any = out.mutable_any();
+ any->set_type_url("type.googleapis.com/google.protobuf.Any");
+
+ ::google::protobuf::Any nested_any;
+ nested_any.set_type_url("type.googleapis.com/google.protobuf.Any");
+
+ ::google::protobuf::Any second_nested_any;
+ second_nested_any.set_type_url(
+ "type.googleapis.com/proto_util_converter.testing.AnyM");
+
+ AnyM m;
+ m.set_foo("foovalue");
+ second_nested_any.set_value(m.SerializeAsString());
+ nested_any.set_value(second_nested_any.SerializeAsString());
+ any->set_value(nested_any.SerializeAsString());
+
+ ow_.StartObject("")
+ ->StartObject("any")
+ ->RenderString("@type", "type.googleapis.com/google.protobuf.Any")
+ ->StartObject("value")
+ ->RenderString("@type", "type.googleapis.com/google.protobuf.Any")
+ ->StartObject("value")
+ ->RenderString("@type",
+ "type.googleapis.com/proto_util_converter.testing.AnyM")
+ ->RenderString("foo", "foovalue")
+ ->EndObject()
+ ->EndObject()
+ ->EndObject()
+ ->EndObject();
+
+ DoTest(out, AnyOut::descriptor());
+}
+
+TEST_P(ProtostreamObjectSourceAnysTest, EmptyAnyOutputsEmptyObject) {
+ AnyOut out;
+ out.mutable_any();
+
+ ow_.StartObject("")->StartObject("any")->EndObject()->EndObject();
+
+ DoTest(out, AnyOut::descriptor());
+}
+
+TEST_P(ProtostreamObjectSourceAnysTest, EmptyWithTypeAndNoValueOutputsType) {
+ AnyOut out;
+ out.mutable_any()->set_type_url("foo.googleapis.com/my.Type");
+
+ ow_.StartObject("")
+ ->StartObject("any")
+ ->RenderString("@type", "foo.googleapis.com/my.Type")
+ ->EndObject()
+ ->EndObject();
+
+ DoTest(out, AnyOut::descriptor());
+}
+
+TEST_P(ProtostreamObjectSourceAnysTest, MissingTypeUrlError) {
+ AnyOut out;
+ ::google::protobuf::Any* any = out.mutable_any();
+
+ AnyM m;
+ m.set_foo("foovalue");
+ any->set_value(m.SerializeAsString());
+
+ // We start the "AnyOut" part and then fail when we hit the Any object.
+ ow_.StartObject("");
+
+ util::Status status = ExecuteTest(out, AnyOut::descriptor());
+ EXPECT_TRUE(util::IsInternal(status));
+}
+
+TEST_P(ProtostreamObjectSourceAnysTest, UnknownTypeServiceError) {
+ AnyOut out;
+ ::google::protobuf::Any* any = out.mutable_any();
+ any->set_type_url("foo.googleapis.com/my.own.Type");
+
+ AnyM m;
+ m.set_foo("foovalue");
+ any->set_value(m.SerializeAsString());
+
+ // We start the "AnyOut" part and then fail when we hit the Any object.
+ ow_.StartObject("");
+
+ util::Status status = ExecuteTest(out, AnyOut::descriptor());
+ EXPECT_TRUE(util::IsInternal(status));
+}
+
+TEST_P(ProtostreamObjectSourceAnysTest, UnknownTypeError) {
+ AnyOut out;
+ ::google::protobuf::Any* any = out.mutable_any();
+ any->set_type_url("type.googleapis.com/unknown.Type");
+
+ AnyM m;
+ m.set_foo("foovalue");
+ any->set_value(m.SerializeAsString());
+
+ // We start the "AnyOut" part and then fail when we hit the Any object.
+ ow_.StartObject("");
+
+ util::Status status = ExecuteTest(out, AnyOut::descriptor());
+ EXPECT_TRUE(util::IsInternal(status));
+}
+
+class ProtostreamObjectSourceStructTest : public ProtostreamObjectSourceTest {
+ protected:
+ ProtostreamObjectSourceStructTest() {
+ helper_.ResetTypeInfo(StructType::descriptor(),
+ google::protobuf::Struct::descriptor());
+ }
+};
+
+INSTANTIATE_TEST_SUITE_P(DifferentTypeInfoSourceTest,
+ ProtostreamObjectSourceStructTest,
+ ::testing::Values(
+ testing::USE_TYPE_RESOLVER));
+
+// Tests struct
+//
+// "object": {
+// "k1": 123,
+// "k2": true
+// }
+TEST_P(ProtostreamObjectSourceStructTest, StructRenderSuccess) {
+ StructType out;
+ google::protobuf::Struct* s = out.mutable_object();
+ s->mutable_fields()->operator[]("k1").set_number_value(123);
+ s->mutable_fields()->operator[]("k2").set_bool_value(true);
+
+ ow_.StartObject("")
+ ->StartObject("object")
+ ->RenderDouble("k1", 123)
+ ->RenderBool("k2", true)
+ ->EndObject()
+ ->EndObject();
+
+ DoTest(out, StructType::descriptor());
+}
+
+TEST_P(ProtostreamObjectSourceStructTest, MissingValueSkipsField) {
+ StructType out;
+ google::protobuf::Struct* s = out.mutable_object();
+ s->mutable_fields()->operator[]("k1");
+
+ ow_.StartObject("")->StartObject("object")->EndObject()->EndObject();
+
+ DoTest(out, StructType::descriptor());
+}
+
+class ProtostreamObjectSourceFieldMaskTest
+ : public ProtostreamObjectSourceTest {
+ protected:
+ ProtostreamObjectSourceFieldMaskTest() {
+ helper_.ResetTypeInfo(FieldMaskTest::descriptor(),
+ google::protobuf::FieldMask::descriptor());
+ }
+};
+
+INSTANTIATE_TEST_SUITE_P(DifferentTypeInfoSourceTest,
+ ProtostreamObjectSourceFieldMaskTest,
+ ::testing::Values(
+ testing::USE_TYPE_RESOLVER));
+
+TEST_P(ProtostreamObjectSourceFieldMaskTest, FieldMaskRenderSuccess) {
+ FieldMaskTest out;
+ out.set_id("1");
+ out.mutable_single_mask()->add_paths("path1");
+ out.mutable_single_mask()->add_paths("snake_case_path2");
+ ::google::protobuf::FieldMask* mask = out.add_repeated_mask();
+ mask->add_paths("path3");
+ mask = out.add_repeated_mask();
+ mask->add_paths("snake_case_path4");
+ mask->add_paths("path5");
+ NestedFieldMask* nested = out.add_nested_mask();
+ nested->set_data("data");
+ nested->mutable_single_mask()->add_paths("nested.path1");
+ nested->mutable_single_mask()->add_paths("nested_field.snake_case_path2");
+ mask = nested->add_repeated_mask();
+ mask->add_paths("nested_field.path3");
+ mask->add_paths("nested.snake_case_path4");
+ mask = nested->add_repeated_mask();
+ mask->add_paths("nested.path5");
+ mask = nested->add_repeated_mask();
+ mask->add_paths(
+ "snake_case.map_field[\"map_key_should_be_ignored\"].nested_snake_case."
+ "map_field[\"map_key_sho\\\"uld_be_ignored\"]");
+
+ ow_.StartObject("")
+ ->RenderString("id", "1")
+ ->RenderString("singleMask", "path1,snakeCasePath2")
+ ->StartList("repeatedMask")
+ ->RenderString("", "path3")
+ ->RenderString("", "snakeCasePath4,path5")
+ ->EndList()
+ ->StartList("nestedMask")
+ ->StartObject("")
+ ->RenderString("data", "data")
+ ->RenderString("singleMask", "nested.path1,nestedField.snakeCasePath2")
+ ->StartList("repeatedMask")
+ ->RenderString("", "nestedField.path3,nested.snakeCasePath4")
+ ->RenderString("", "nested.path5")
+ ->RenderString("",
+ "snakeCase.mapField[\"map_key_should_be_ignored\"]."
+ "nestedSnakeCase.mapField[\"map_key_sho\\\"uld_be_"
+ "ignored\"]")
+ ->EndList()
+ ->EndObject()
+ ->EndList()
+ ->EndObject();
+
+ DoTest(out, FieldMaskTest::descriptor());
+}
+
+class ProtostreamObjectSourceTimestampTest
+ : public ProtostreamObjectSourceTest {
+ protected:
+ ProtostreamObjectSourceTimestampTest() {
+ helper_.ResetTypeInfo(TimestampDuration::descriptor());
+ }
+};
+
+INSTANTIATE_TEST_SUITE_P(DifferentTypeInfoSourceTest,
+ ProtostreamObjectSourceTimestampTest,
+ ::testing::Values(
+ testing::USE_TYPE_RESOLVER));
+
+TEST_P(ProtostreamObjectSourceTimestampTest, InvalidTimestampBelowMinTest) {
+ TimestampDuration out;
+ google::protobuf::Timestamp* ts = out.mutable_ts();
+ // Min allowed seconds - 1
+ ts->set_seconds(kTimestampMinSeconds - 1);
+ ow_.StartObject("");
+
+ util::Status status = ExecuteTest(out, TimestampDuration::descriptor());
+ EXPECT_TRUE(util::IsInternal(status));
+}
+
+TEST_P(ProtostreamObjectSourceTimestampTest, InvalidTimestampAboveMaxTest) {
+ TimestampDuration out;
+ google::protobuf::Timestamp* ts = out.mutable_ts();
+ // Max allowed seconds + 1
+ ts->set_seconds(kTimestampMaxSeconds + 1);
+ ow_.StartObject("");
+
+ util::Status status = ExecuteTest(out, TimestampDuration::descriptor());
+ EXPECT_TRUE(util::IsInternal(status));
+}
+
+TEST_P(ProtostreamObjectSourceTimestampTest, InvalidDurationBelowMinTest) {
+ TimestampDuration out;
+ google::protobuf::Duration* dur = out.mutable_dur();
+ // Min allowed seconds - 1
+ dur->set_seconds(kDurationMinSeconds - 1);
+ ow_.StartObject("");
+
+ util::Status status = ExecuteTest(out, TimestampDuration::descriptor());
+ EXPECT_TRUE(util::IsInternal(status));
+}
+
+TEST_P(ProtostreamObjectSourceTimestampTest, InvalidDurationAboveMaxTest) {
+ TimestampDuration out;
+ google::protobuf::Duration* dur = out.mutable_dur();
+ // Min allowed seconds + 1
+ dur->set_seconds(kDurationMaxSeconds + 1);
+ ow_.StartObject("");
+
+ util::Status status = ExecuteTest(out, TimestampDuration::descriptor());
+ EXPECT_TRUE(util::IsInternal(status));
+}
+
+TEST_P(ProtostreamObjectSourceTimestampTest, TimestampDurationDefaultValue) {
+ TimestampDuration out;
+ out.mutable_ts()->set_seconds(0);
+ out.mutable_dur()->set_seconds(0);
+
+ ow_.StartObject("")
+ ->RenderString("ts", "1970-01-01T00:00:00Z")
+ ->RenderString("dur", "0s")
+ ->EndObject();
+
+ DoTest(out, TimestampDuration::descriptor());
+}
+
+
+
+} // namespace converter
+} // namespace util
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/util/internal/protostream_objectwriter.cc b/NorthstarDedicatedTest/include/protobuf/util/internal/protostream_objectwriter.cc
new file mode 100644
index 00000000..5f3a1a68
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/util/internal/protostream_objectwriter.cc
@@ -0,0 +1,1400 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <util/internal/protostream_objectwriter.h>
+
+#include <cstdint>
+#include <functional>
+#include <stack>
+#include <unordered_map>
+#include <unordered_set>
+
+#include <stubs/once.h>
+#include <wire_format_lite.h>
+#include <util/internal/field_mask_utility.h>
+#include <util/internal/object_location_tracker.h>
+#include <util/internal/constants.h>
+#include <util/internal/utility.h>
+#include <stubs/strutil.h>
+#include <stubs/status.h>
+#include <stubs/statusor.h>
+#include <stubs/time.h>
+#include <stubs/map_util.h>
+
+
+#include <port_def.inc>
+
+namespace google {
+namespace protobuf {
+namespace util {
+namespace converter {
+
+using ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite;
+using std::placeholders::_1;
+using util::Status;
+
+
+ProtoStreamObjectWriter::ProtoStreamObjectWriter(
+ TypeResolver* type_resolver, const google::protobuf::Type& type,
+ strings::ByteSink* output, ErrorListener* listener,
+ const ProtoStreamObjectWriter::Options& options)
+ : ProtoWriter(type_resolver, type, output, listener),
+ master_type_(type),
+ current_(nullptr),
+ options_(options) {
+ set_ignore_unknown_fields(options_.ignore_unknown_fields);
+ set_ignore_unknown_enum_values(options_.ignore_unknown_enum_values);
+ set_use_lower_camel_for_enums(options_.use_lower_camel_for_enums);
+ set_case_insensitive_enum_parsing(options_.case_insensitive_enum_parsing);
+ set_use_json_name_in_missing_fields(options.use_json_name_in_missing_fields);
+}
+
+ProtoStreamObjectWriter::ProtoStreamObjectWriter(
+ const TypeInfo* typeinfo, const google::protobuf::Type& type,
+ strings::ByteSink* output, ErrorListener* listener,
+ const ProtoStreamObjectWriter::Options& options)
+ : ProtoWriter(typeinfo, type, output, listener),
+ master_type_(type),
+ current_(nullptr),
+ options_(options) {
+ set_ignore_unknown_fields(options_.ignore_unknown_fields);
+ set_use_lower_camel_for_enums(options.use_lower_camel_for_enums);
+ set_case_insensitive_enum_parsing(options_.case_insensitive_enum_parsing);
+ set_use_json_name_in_missing_fields(options.use_json_name_in_missing_fields);
+}
+
+ProtoStreamObjectWriter::ProtoStreamObjectWriter(
+ const TypeInfo* typeinfo, const google::protobuf::Type& type,
+ strings::ByteSink* output, ErrorListener* listener)
+ : ProtoWriter(typeinfo, type, output, listener),
+ master_type_(type),
+ current_(nullptr),
+ options_(ProtoStreamObjectWriter::Options::Defaults()) {}
+
+ProtoStreamObjectWriter::~ProtoStreamObjectWriter() {
+ if (current_ == nullptr) return;
+ // Cleanup explicitly in order to avoid destructor stack overflow when input
+ // is deeply nested.
+ // Cast to BaseElement to avoid doing additional checks (like missing fields)
+ // during pop().
+ std::unique_ptr<BaseElement> element(
+ static_cast<BaseElement*>(current_.get())->pop<BaseElement>());
+ while (element != nullptr) {
+ element.reset(element->pop<BaseElement>());
+ }
+}
+
+namespace {
+// Utility method to split a string representation of Timestamp or Duration and
+// return the parts.
+void SplitSecondsAndNanos(StringPiece input, StringPiece* seconds,
+ StringPiece* nanos) {
+ size_t idx = input.rfind('.');
+ if (idx != 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 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>(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/master/src/google/protobuf/struct.proto
+ // "fields": [
+ Push("fields", Item::MAP, true, true);
+ return this;
+ }
+
+ if (master_type_.name() == kStructValueType) {
+ // We got a StartObject call with google.protobuf.Value field. The only
+ // object within that type is a struct type. So start a struct.
+ //
+ // The struct field in Value type is named "struct_value"
+ // https://github.com/protocolbuffers/protobuf/blob/master/src/google/protobuf/struct.proto
+ // Also start the map field "fields" within the struct.
+ // "struct_value": {
+ // "fields": [
+ Push("struct_value", Item::MESSAGE, true, false);
+ Push("fields", Item::MAP, true, true);
+ return this;
+ }
+
+ if (master_type_.name() == kStructListValueType) {
+ InvalidValue(kStructListValueType,
+ "Cannot start root message with ListValue.");
+ }
+
+ return this;
+ }
+
+ // Send all ANY events to AnyWriter.
+ if (current_->IsAny()) {
+ current_->any()->StartObject(name);
+ return this;
+ }
+
+ // If we are within a map, we render name as keys and send StartObject to the
+ // value field.
+ if (current_->IsMap()) {
+ if (!ValidMapKey(name)) {
+ IncrementInvalidDepth();
+ return this;
+ }
+
+ // Map is a repeated field of message type with a "key" and a "value" field.
+ // https://developers.google.com/protocol-buffers/docs/proto3?hl=en#maps
+ // message MapFieldEntry {
+ // key_type key = 1;
+ // value_type value = 2;
+ // }
+ //
+ // repeated MapFieldEntry map_field = N;
+ //
+ // That means, we render the following element within a list (hence no
+ // name):
+ // { "key": "<name>", "value": {
+ Push("", Item::MESSAGE, false, false);
+ ProtoWriter::RenderDataPiece("key",
+ DataPiece(name, use_strict_base64_decoding()));
+ Push("value", IsAny(*Lookup("value")) ? Item::ANY : Item::MESSAGE, true,
+ false);
+
+ // Make sure we are valid so far after starting map fields.
+ if (invalid_depth() > 0) return this;
+
+ // If top of stack is g.p.Struct type, start the struct the map field within
+ // it.
+ if (element() != nullptr && IsStruct(*element()->parent_field())) {
+ // Render "fields": [
+ Push("fields", Item::MAP, true, true);
+ return this;
+ }
+
+ // If top of stack is g.p.Value type, start the Struct within it.
+ if (element() != nullptr && IsStructValue(*element()->parent_field())) {
+ // Render
+ // "struct_value": {
+ // "fields": [
+ Push("struct_value", Item::MESSAGE, true, false);
+ Push("fields", Item::MAP, true, true);
+ }
+ return this;
+ }
+
+ const google::protobuf::Field* field = BeginNamed(name, false);
+
+ if (field == nullptr) return this;
+
+ // Legacy JSON map is a list of key value pairs. Starts a map entry object.
+ if (options_.use_legacy_json_map_format && name.empty()) {
+ Push(name, IsAny(*field) ? Item::ANY : Item::MESSAGE, false, false);
+ return this;
+ }
+
+ if (IsMap(*field)) {
+ // Begin a map. A map is triggered by a StartObject() call if the current
+ // field has a map type.
+ // A map type is always repeated, hence set is_list to true.
+ // Render
+ // "<name>": [
+ Push(name, Item::MAP, false, true);
+ return this;
+ }
+
+ if (options_.disable_implicit_message_list) {
+ // If the incoming object is repeated, the top-level object on stack should
+ // be list. Report an error otherwise.
+ if (IsRepeated(*field) && !current_->is_list()) {
+ IncrementInvalidDepth();
+
+ if (!options_.suppress_implicit_message_list_error) {
+ InvalidValue(
+ field->name(),
+ "Starting an object in a repeated field but the parent object "
+ "is not a list");
+ }
+ return this;
+ }
+ }
+
+ if (IsStruct(*field)) {
+ // Start a struct object.
+ // Render
+ // "<name>": {
+ // "fields": {
+ Push(name, Item::MESSAGE, false, false);
+ Push("fields", Item::MAP, true, true);
+ return this;
+ }
+
+ if (IsStructValue(*field)) {
+ // We got a StartObject call with google.protobuf.Value field. The only
+ // object within that type is a struct type. So start a struct.
+ // Render
+ // "<name>": {
+ // "struct_value": {
+ // "fields": {
+ Push(name, Item::MESSAGE, false, false);
+ Push("struct_value", Item::MESSAGE, true, false);
+ Push("fields", Item::MAP, true, true);
+ return this;
+ }
+
+ if (field->kind() != google::protobuf::Field::TYPE_GROUP &&
+ field->kind() != google::protobuf::Field::TYPE_MESSAGE) {
+ IncrementInvalidDepth();
+ if (!options_.suppress_object_to_scalar_error) {
+ InvalidValue(field->name(), "Starting an object on a scalar field");
+ }
+
+ return this;
+ }
+
+ // A regular message type. Pass it directly to ProtoWriter.
+ // Render
+ // "<name>": {
+ Push(name, IsAny(*field) ? Item::ANY : Item::MESSAGE, false, false);
+ return this;
+}
+
+ProtoStreamObjectWriter* ProtoStreamObjectWriter::EndObject() {
+ if (invalid_depth() > 0) {
+ DecrementInvalidDepth();
+ return this;
+ }
+
+ if (current_ == nullptr) return this;
+
+ if (current_->IsAny()) {
+ if (current_->any()->EndObject()) return this;
+ }
+
+ Pop();
+
+ return this;
+}
+
+
+ProtoStreamObjectWriter* ProtoStreamObjectWriter::StartList(
+ StringPiece name) {
+ if (invalid_depth() > 0) {
+ IncrementInvalidDepth();
+ return this;
+ }
+
+ // Since we cannot have a top-level repeated item in protobuf, the only way
+ // this is valid is if we start a special type google.protobuf.ListValue or
+ // google.protobuf.Value.
+ if (current_ == nullptr) {
+ if (!name.empty()) {
+ InvalidName(name, "Root element should not be named.");
+ IncrementInvalidDepth();
+ return this;
+ }
+
+ // If master type is a special type that needs extra values to be written to
+ // stream, we write those values.
+ if (master_type_.name() == kStructValueType) {
+ // We got a StartList with google.protobuf.Value master type. This means
+ // we have to start the "list_value" within google.protobuf.Value.
+ //
+ // See
+ // https://github.com/protocolbuffers/protobuf/blob/master/src/google/protobuf/struct.proto
+ //
+ // Render
+ // "<name>": {
+ // "list_value": {
+ // "values": [ // Start this list.
+ ProtoWriter::StartObject(name);
+ current_.reset(new Item(this, Item::MESSAGE, false, false));
+ Push("list_value", Item::MESSAGE, true, false);
+ Push("values", Item::MESSAGE, true, true);
+ return this;
+ }
+
+ if (master_type_.name() == kStructListValueType) {
+ // We got a StartList with google.protobuf.ListValue master type. This
+ // means we have to start the "values" within google.protobuf.ListValue.
+ //
+ // Render
+ // "<name>": {
+ // "values": [ // Start this list.
+ ProtoWriter::StartObject(name);
+ current_.reset(new Item(this, Item::MESSAGE, false, false));
+ Push("values", Item::MESSAGE, true, true);
+ return this;
+ }
+
+ // Send the event to ProtoWriter so proper errors can be reported.
+ //
+ // Render a regular list:
+ // "<name>": [
+ ProtoWriter::StartList(name);
+ current_.reset(new Item(this, Item::MESSAGE, false, true));
+ return this;
+ }
+
+ if (current_->IsAny()) {
+ current_->any()->StartList(name);
+ return this;
+ }
+
+ // If the top of stack is a map, we are starting a list value within a map.
+ // Since map does not allow repeated values, this can only happen when the map
+ // value is of a special type that renders a list in JSON. These can be one
+ // of 3 cases:
+ // i. We are rendering a list value within google.protobuf.Struct
+ // ii. We are rendering a list value within google.protobuf.Value
+ // iii. We are rendering a list value with type google.protobuf.ListValue.
+ if (current_->IsMap()) {
+ if (!ValidMapKey(name)) {
+ IncrementInvalidDepth();
+ return this;
+ }
+
+ // Start the repeated map entry object.
+ // Render
+ // { "key": "<name>", "value": {
+ Push("", Item::MESSAGE, false, false);
+ ProtoWriter::RenderDataPiece("key",
+ DataPiece(name, use_strict_base64_decoding()));
+ Push("value", Item::MESSAGE, true, false);
+
+ // Make sure we are valid after pushing all above items.
+ if (invalid_depth() > 0) return this;
+
+ // case i and ii above. Start "list_value" field within g.p.Value
+ if (element() != nullptr && element()->parent_field() != nullptr) {
+ // Render
+ // "list_value": {
+ // "values": [ // Start this list
+ if (IsStructValue(*element()->parent_field())) {
+ Push("list_value", Item::MESSAGE, true, false);
+ Push("values", Item::MESSAGE, true, true);
+ return this;
+ }
+
+ // Render
+ // "values": [
+ if (IsStructListValue(*element()->parent_field())) {
+ // case iii above. Bind directly to g.p.ListValue
+ Push("values", Item::MESSAGE, true, true);
+ return this;
+ }
+ }
+
+ // Report an error.
+ InvalidValue("Map", StrCat("Cannot have repeated items ('", name,
+ "') within a map."));
+ return this;
+ }
+
+ // When name is empty and stack is not empty, we are rendering an item within
+ // a list.
+ if (name.empty()) {
+ if (element() != nullptr && element()->parent_field() != nullptr) {
+ if (IsStructValue(*element()->parent_field())) {
+ // Since it is g.p.Value, we bind directly to the list_value.
+ // Render
+ // { // g.p.Value item within the list
+ // "list_value": {
+ // "values": [
+ Push("", Item::MESSAGE, false, false);
+ Push("list_value", Item::MESSAGE, true, false);
+ Push("values", Item::MESSAGE, true, true);
+ return this;
+ }
+
+ if (IsStructListValue(*element()->parent_field())) {
+ // Since it is g.p.ListValue, we bind to it directly.
+ // Render
+ // { // g.p.ListValue item within the list
+ // "values": [
+ Push("", Item::MESSAGE, false, false);
+ Push("values", Item::MESSAGE, true, true);
+ return this;
+ }
+ }
+
+ // Pass the event to underlying ProtoWriter.
+ Push(name, Item::MESSAGE, false, true);
+ return this;
+ }
+
+ // name is not empty
+ const google::protobuf::Field* field = Lookup(name);
+
+ if (field == nullptr) {
+ IncrementInvalidDepth();
+ return this;
+ }
+
+ if (IsStructValue(*field)) {
+ // If g.p.Value is repeated, start that list. Otherwise, start the
+ // "list_value" within it.
+ if (IsRepeated(*field)) {
+ // Render it just like a regular repeated field.
+ // "<name>": [
+ Push(name, Item::MESSAGE, false, true);
+ return this;
+ }
+
+ // Start the "list_value" field.
+ // Render
+ // "<name>": {
+ // "list_value": {
+ // "values": [
+ Push(name, Item::MESSAGE, false, false);
+ Push("list_value", Item::MESSAGE, true, false);
+ Push("values", Item::MESSAGE, true, true);
+ return this;
+ }
+
+ if (IsStructListValue(*field)) {
+ // If g.p.ListValue is repeated, start that list. Otherwise, start the
+ // "values" within it.
+ if (IsRepeated(*field)) {
+ // Render it just like a regular repeated field.
+ // "<name>": [
+ Push(name, Item::MESSAGE, false, true);
+ return this;
+ }
+
+ // Start the "values" field within g.p.ListValue.
+ // Render
+ // "<name>": {
+ // "values": [
+ Push(name, Item::MESSAGE, false, false);
+ Push("values", Item::MESSAGE, true, true);
+ return this;
+ }
+
+ // If we are here, the field should be repeated. Report an error otherwise.
+ if (!IsRepeated(*field)) {
+ IncrementInvalidDepth();
+ InvalidName(name, "Proto field is not repeating, cannot start list.");
+ return this;
+ }
+
+ if (IsMap(*field)) {
+ if (options_.use_legacy_json_map_format) {
+ Push(name, Item::MESSAGE, false, true);
+ return this;
+ }
+ InvalidValue("Map", StrCat("Cannot bind a list to map for field '",
+ name, "'."));
+ IncrementInvalidDepth();
+ return this;
+ }
+
+ // Pass the event to ProtoWriter.
+ // Render
+ // "<name>": [
+ Push(name, Item::MESSAGE, false, true);
+ return this;
+}
+
+ProtoStreamObjectWriter* ProtoStreamObjectWriter::EndList() {
+ if (invalid_depth() > 0) {
+ DecrementInvalidDepth();
+ return this;
+ }
+
+ if (current_ == nullptr) return this;
+
+ if (current_->IsAny()) {
+ current_->any()->EndList();
+ return this;
+ }
+
+ Pop();
+ return this;
+}
+
+Status ProtoStreamObjectWriter::RenderStructValue(ProtoStreamObjectWriter* ow,
+ const DataPiece& data) {
+ 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 seconds;
+ int32 nanos;
+ if (!::google::protobuf::internal::ParseTime(value.ToString(), &seconds,
+ &nanos)) {
+ return util::InvalidArgumentError(StrCat("Invalid time format: ", value));
+ }
+
+
+ ow->ProtoWriter::RenderDataPiece("seconds", DataPiece(seconds));
+ ow->ProtoWriter::RenderDataPiece("nanos", DataPiece(nanos));
+ return Status();
+}
+
+static inline util::Status RenderOneFieldPath(ProtoStreamObjectWriter* ow,
+ StringPiece path) {
+ ow->ProtoWriter::RenderDataPiece(
+ "paths", DataPiece(ConvertFieldMaskPath(path, &ToSnakeCase), true));
+ return Status();
+}
+
+Status ProtoStreamObjectWriter::RenderFieldMask(ProtoStreamObjectWriter* ow,
+ const DataPiece& data) {
+ if (data.type() == DataPiece::TYPE_NULL) return Status();
+ if (data.type() != DataPiece::TYPE_STRING) {
+ return util::InvalidArgumentError(
+ StrCat("Invalid data type for field mask, value is ",
+ data.ValueAsStringOrDefault("")));
+ }
+
+ // TODO(tsun): figure out how to do proto descriptor based snake case
+ // conversions as much as possible. Because ToSnakeCase sometimes returns the
+ // wrong value.
+ return DecodeCompactFieldMaskPaths(data.str(),
+ std::bind(&RenderOneFieldPath, ow, _1));
+}
+
+Status ProtoStreamObjectWriter::RenderDuration(ProtoStreamObjectWriter* ow,
+ const DataPiece& data) {
+ if (data.type() == DataPiece::TYPE_NULL) return Status();
+ if (data.type() != DataPiece::TYPE_STRING) {
+ return util::InvalidArgumentError(
+ StrCat("Invalid data type for duration, value is ",
+ data.ValueAsStringOrDefault("")));
+ }
+
+ StringPiece value(data.str());
+
+ if (!HasSuffixString(value, "s")) {
+ return util::InvalidArgumentError(
+ "Illegal duration format; duration must end with 's'");
+ }
+ value = value.substr(0, value.size() - 1);
+ int sign = 1;
+ if (HasPrefixString(value, "-")) {
+ sign = -1;
+ value = value.substr(1);
+ }
+
+ StringPiece s_secs, s_nanos;
+ SplitSecondsAndNanos(value, &s_secs, &s_nanos);
+ 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/NorthstarDedicatedTest/include/protobuf/util/internal/protostream_objectwriter.h b/NorthstarDedicatedTest/include/protobuf/util/internal/protostream_objectwriter.h
new file mode 100644
index 00000000..ac5f8a0c
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/util/internal/protostream_objectwriter.h
@@ -0,0 +1,452 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef GOOGLE_PROTOBUF_UTIL_CONVERTER_PROTOSTREAM_OBJECTWRITER_H__
+#define GOOGLE_PROTOBUF_UTIL_CONVERTER_PROTOSTREAM_OBJECTWRITER_H__
+
+#include <deque>
+#include <string>
+#include <unordered_map>
+#include <unordered_set>
+
+#include <stubs/common.h>
+#include <type.pb.h>
+#include <io/coded_stream.h>
+#include <io/zero_copy_stream_impl.h>
+#include <descriptor.h>
+#include <util/internal/type_info.h>
+#include <util/internal/datapiece.h>
+#include <util/internal/error_listener.h>
+#include <util/internal/proto_writer.h>
+#include <util/internal/structured_objectwriter.h>
+#include <util/type_resolver.h>
+#include <stubs/bytestream.h>
+#include <stubs/status.h>
+#include <stubs/hash.h>
+
+#include <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 <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_UTIL_CONVERTER_PROTOSTREAM_OBJECTWRITER_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/util/internal/protostream_objectwriter_test.cc b/NorthstarDedicatedTest/include/protobuf/util/internal/protostream_objectwriter_test.cc
new file mode 100644
index 00000000..60501752
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/util/internal/protostream_objectwriter_test.cc
@@ -0,0 +1,3032 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 <util/internal/protostream_objectwriter.h>
+
+#include <stddef.h> // For size_t
+
+#include <field_mask.pb.h>
+#include <timestamp.pb.h>
+#include <type.pb.h>
+#include <wrappers.pb.h>
+#include <io/zero_copy_stream_impl_lite.h>
+#include <descriptor.pb.h>
+#include <descriptor.h>
+#include <dynamic_message.h>
+#include <message.h>
+#include <util/internal/mock_error_listener.h>
+#include <util/internal/testdata/anys.pb.h>
+#include <util/internal/testdata/books.pb.h>
+#include <util/internal/testdata/field_mask.pb.h>
+#include <util/internal/testdata/maps.pb.h>
+#include <util/internal/testdata/oneofs.pb.h>
+#include <util/internal/testdata/proto3.pb.h>
+#include <util/internal/testdata/struct.pb.h>
+#include <util/internal/testdata/timestamp_duration.pb.h>
+#include <util/internal/testdata/wrappers.pb.h>
+#include <util/internal/type_info_test_helper.h>
+#include <util/internal/constants.h>
+#include <util/message_differencer.h>
+#include <util/type_resolver_util.h>
+#include <stubs/bytestream.h>
+#include <stubs/strutil.h>
+#include <gtest/gtest.h>
+
+
+namespace google {
+namespace protobuf {
+namespace util {
+namespace converter {
+
+
+using proto_util_converter::testing::AnyM;
+using proto_util_converter::testing::AnyOut;
+using proto_util_converter::testing::Author;
+using proto_util_converter::testing::Book;
+using proto_util_converter::testing::FieldMaskTest;
+using proto_util_converter::testing::Int32Wrapper;
+using proto_util_converter::testing::MapIn;
+using proto_util_converter::testing::Primitive;
+using proto_util_converter::testing::Proto3Message;
+using proto_util_converter::testing::Publisher;
+using proto_util_converter::testing::StructType;
+using proto_util_converter::testing::TestJsonName1;
+using proto_util_converter::testing::TestJsonName2;
+using proto_util_converter::testing::TimestampDuration;
+using proto_util_converter::testing::ValueWrapper;
+using proto_util_converter::testing::oneofs::OneOfsRequest;
+using strings::GrowingArrayByteSink;
+using ::testing::_;
+using ::testing::Args;
+
+
+namespace {
+std::string GetTypeUrl(const Descriptor* descriptor) {
+ return std::string(kTypeServiceBaseUrl) + "/" + descriptor->full_name();
+}
+} // namespace
+
+class BaseProtoStreamObjectWriterTest
+ : public ::testing::TestWithParam<testing::TypeInfoSource> {
+ protected:
+ BaseProtoStreamObjectWriterTest()
+ : helper_(GetParam()),
+ listener_(),
+ output_(new GrowingArrayByteSink(1000)),
+ ow_() {}
+
+ explicit BaseProtoStreamObjectWriterTest(const Descriptor* descriptor)
+ : helper_(GetParam()),
+ listener_(),
+ output_(new GrowingArrayByteSink(1000)),
+ ow_() {
+ std::vector<const Descriptor*> descriptors;
+ descriptors.push_back(descriptor);
+ ResetTypeInfo(descriptors);
+ }
+
+ explicit BaseProtoStreamObjectWriterTest(
+ std::vector<const Descriptor*> descriptors)
+ : helper_(GetParam()),
+ listener_(),
+ output_(new GrowingArrayByteSink(1000)),
+ ow_() {
+ ResetTypeInfo(descriptors);
+ }
+
+ void ResetTypeInfo(std::vector<const Descriptor*> descriptors) {
+ GOOGLE_CHECK(!descriptors.empty()) << "Must have at least one descriptor!";
+ helper_.ResetTypeInfo(descriptors);
+ ow_.reset(helper_.NewProtoWriter(GetTypeUrl(descriptors[0]), output_.get(),
+ &listener_, options_));
+ }
+
+ void ResetTypeInfo(const Descriptor* descriptor) {
+ std::vector<const Descriptor*> descriptors;
+ descriptors.push_back(descriptor);
+ ResetTypeInfo(descriptors);
+ }
+
+ virtual ~BaseProtoStreamObjectWriterTest() {}
+
+ void CheckOutput(const Message& expected, int expected_length) {
+ size_t nbytes;
+ std::unique_ptr<char[]> buffer(output_->GetBuffer(&nbytes));
+ if (expected_length >= 0) {
+ EXPECT_EQ(expected_length, nbytes);
+ }
+ std::string str(buffer.get(), nbytes);
+
+ std::stringbuf str_buf(str, std::ios_base::in);
+ std::istream istream(&str_buf);
+ std::unique_ptr<Message> message(expected.New());
+ message->ParsePartialFromIstream(&istream);
+
+ if (!MessageDifferencer::Equivalent(expected, *message)) {
+ EXPECT_EQ(expected.DebugString(), message->DebugString());
+ }
+ }
+
+ void CheckOutput(const Message& expected) { CheckOutput(expected, -1); }
+
+ testing::TypeInfoTestHelper helper_;
+ MockErrorListener listener_;
+ std::unique_ptr<GrowingArrayByteSink> output_;
+ std::unique_ptr<ProtoStreamObjectWriter> ow_;
+ ProtoStreamObjectWriter::Options options_;
+};
+
+MATCHER_P(HasObjectLocation, expected,
+ "Verifies the expected object location") {
+ std::string actual = std::get<0>(arg).ToString();
+ if (actual == expected) return true;
+ *result_listener << "actual location is: " << actual;
+ return false;
+}
+
+class ProtoStreamObjectWriterTest : public BaseProtoStreamObjectWriterTest {
+ protected:
+ ProtoStreamObjectWriterTest()
+ : BaseProtoStreamObjectWriterTest(Book::descriptor()) {}
+
+ void ResetProtoWriter() { ResetTypeInfo(Book::descriptor()); }
+
+ virtual ~ProtoStreamObjectWriterTest() {}
+};
+
+INSTANTIATE_TEST_SUITE_P(DifferentTypeInfoSourceTest,
+ ProtoStreamObjectWriterTest,
+ ::testing::Values(
+ testing::USE_TYPE_RESOLVER));
+
+TEST_P(ProtoStreamObjectWriterTest, EmptyObject) {
+ Book empty;
+ ow_->StartObject("")->EndObject();
+ CheckOutput(empty, 0);
+}
+
+TEST_P(ProtoStreamObjectWriterTest, SimpleObject) {
+ std::string content("My content");
+
+ Book book;
+ book.set_title("My Title");
+ book.set_length(222);
+ book.set_content(content);
+
+ ow_->StartObject("")
+ ->RenderString("title", "My Title")
+ ->RenderInt32("length", 222)
+ ->RenderBytes("content", content)
+ ->EndObject();
+ CheckOutput(book);
+}
+
+TEST_P(ProtoStreamObjectWriterTest, SimpleMessage) {
+ Book book;
+ book.set_title("Some Book");
+ book.set_length(102);
+ Publisher* publisher = book.mutable_publisher();
+ publisher->set_name("My Publisher");
+ Author* robert = book.mutable_author();
+ robert->set_alive(true);
+ robert->set_name("robert");
+ robert->add_pseudonym("bob");
+ robert->add_pseudonym("bobby");
+ robert->add_friend_()->set_name("john");
+
+ ow_->StartObject("")
+ ->RenderString("title", "Some Book")
+ ->RenderInt32("length", 102)
+ ->StartObject("publisher")
+ ->RenderString("name", "My Publisher")
+ ->EndObject()
+ ->StartObject("author")
+ ->RenderBool("alive", true)
+ ->RenderString("name", "robert")
+ ->StartList("pseudonym")
+ ->RenderString("", "bob")
+ ->RenderString("", "bobby")
+ ->EndList()
+ ->StartList("friend")
+ ->StartObject("")
+ ->RenderString("name", "john")
+ ->EndObject()
+ ->EndList()
+ ->EndObject()
+ ->EndObject();
+ CheckOutput(book);
+}
+
+TEST_P(ProtoStreamObjectWriterTest, CustomJsonName) {
+ Book book;
+ Author* robert = book.mutable_author();
+ robert->set_id(12345);
+ robert->set_name("robert");
+
+ ow_->StartObject("")
+ ->StartObject("author")
+ ->RenderUint64("@id", 12345)
+ ->RenderString("name", "robert")
+ ->EndObject()
+ ->EndObject();
+ CheckOutput(book);
+}
+
+// Test that two messages can have different fields mapped to the same JSON
+// name. See: https://github.com/protocolbuffers/protobuf/issues/1415
+TEST_P(ProtoStreamObjectWriterTest, ConflictingJsonName) {
+ ResetTypeInfo(TestJsonName1::descriptor());
+ TestJsonName1 message1;
+ message1.set_one_value(12345);
+ ow_->StartObject("")->RenderInt32("value", 12345)->EndObject();
+ CheckOutput(message1);
+
+ ResetTypeInfo(TestJsonName2::descriptor());
+ TestJsonName2 message2;
+ message2.set_another_value(12345);
+ ow_->StartObject("")->RenderInt32("value", 12345)->EndObject();
+ CheckOutput(message2);
+}
+
+
+TEST_P(ProtoStreamObjectWriterTest, IntEnumValuesAreAccepted) {
+ Book book;
+ book.set_title("Some Book");
+ book.set_type(proto_util_converter::testing::Book::KIDS);
+ Author* robert = book.mutable_author();
+ robert->set_name("robert");
+
+ ow_->StartObject("")
+ ->RenderString("title", "Some Book")
+ ->RenderString("type", "2")
+ ->StartObject("author")
+ ->RenderString("name", "robert")
+ ->EndObject()
+ ->EndObject();
+ CheckOutput(book);
+}
+
+TEST_P(ProtoStreamObjectWriterTest, EnumValuesWithDifferentCaseIsRejected) {
+ Book book;
+ book.set_title("Some Book");
+ Author* robert = book.mutable_author();
+ robert->set_name("robert");
+
+ options_.case_insensitive_enum_parsing = false;
+ ResetProtoWriter();
+
+ ow_->StartObject("")
+ ->RenderString("title", "Some Book")
+ ->RenderString("type", "action_and_adventure")
+ ->StartObject("author")
+ ->RenderString("name", "robert")
+ ->EndObject()
+ ->EndObject();
+ CheckOutput(book);
+}
+
+TEST_P(ProtoStreamObjectWriterTest, EnumValuesWithSameCaseIsAccepted) {
+ Book book;
+ book.set_title("Some Book");
+ book.set_type(proto_util_converter::testing::Book::ACTION_AND_ADVENTURE);
+ Author* robert = book.mutable_author();
+ robert->set_name("robert");
+
+ options_.case_insensitive_enum_parsing = false;
+ ResetProtoWriter();
+
+ ow_->StartObject("")
+ ->RenderString("title", "Some Book")
+ ->RenderString("type", "ACTION_AND_ADVENTURE")
+ ->StartObject("author")
+ ->RenderString("name", "robert")
+ ->EndObject()
+ ->EndObject();
+ CheckOutput(book);
+}
+
+TEST_P(ProtoStreamObjectWriterTest, EnumValuesWithDifferentCaseIsAccepted) {
+ Book book;
+ book.set_title("Some Book");
+ book.set_type(proto_util_converter::testing::Book::ACTION_AND_ADVENTURE);
+ Author* robert = book.mutable_author();
+ robert->set_name("robert");
+
+ options_.case_insensitive_enum_parsing = true;
+ ResetProtoWriter();
+
+ ow_->StartObject("")
+ ->RenderString("title", "Some Book")
+ ->RenderString("type", "action_AND_adventure")
+ ->StartObject("author")
+ ->RenderString("name", "robert")
+ ->EndObject()
+ ->EndObject();
+ CheckOutput(book);
+}
+
+TEST_P(ProtoStreamObjectWriterTest, EnumValuesWithoutUnderscoreAreAccepted) {
+ Book book;
+ book.set_title("Some Book");
+ book.set_type(proto_util_converter::testing::Book::ACTION_AND_ADVENTURE);
+ Author* robert = book.mutable_author();
+ robert->set_name("robert");
+
+ options_.use_lower_camel_for_enums = true;
+ ResetProtoWriter();
+
+ ow_->StartObject("")
+ ->RenderString("title", "Some Book")
+ ->RenderString("type", "ACTIONANDADVENTURE")
+ ->StartObject("author")
+ ->RenderString("name", "robert")
+ ->EndObject()
+ ->EndObject();
+ CheckOutput(book);
+}
+
+TEST_P(ProtoStreamObjectWriterTest, EnumValuesInCamelCaseAreAccepted) {
+ Book book;
+ book.set_title("Some Book");
+ book.set_type(proto_util_converter::testing::Book::ACTION_AND_ADVENTURE);
+ Author* robert = book.mutable_author();
+ robert->set_name("robert");
+
+ options_.use_lower_camel_for_enums = true;
+ ResetProtoWriter();
+
+ ow_->StartObject("")
+ ->RenderString("title", "Some Book")
+ ->RenderString("type", "actionAndAdventure")
+ ->StartObject("author")
+ ->RenderString("name", "robert")
+ ->EndObject()
+ ->EndObject();
+ CheckOutput(book);
+}
+
+TEST_P(ProtoStreamObjectWriterTest,
+ EnumValuesInCamelCaseRemoveDashAndUnderscoreAreAccepted) {
+ Book book;
+ book.set_title("Some Book");
+ book.set_type(proto_util_converter::testing::Book::ACTION_AND_ADVENTURE);
+ Author* robert = book.mutable_author();
+ robert->set_name("robert");
+
+ options_.use_lower_camel_for_enums = true;
+ options_.case_insensitive_enum_parsing = false;
+ ResetProtoWriter();
+
+ ow_->StartObject("")
+ ->RenderString("title", "Some Book")
+ ->RenderString("type", "action-And_Adventure")
+ ->StartObject("author")
+ ->RenderString("name", "robert")
+ ->EndObject()
+ ->EndObject();
+ CheckOutput(book);
+}
+
+TEST_P(ProtoStreamObjectWriterTest,
+ EnumValuesInCamelCaseWithNameNotUppercaseAreAccepted) {
+ Book book;
+ book.set_title("Some Book");
+ book.set_type(proto_util_converter::testing::Book::arts_and_photography);
+ Author* robert = book.mutable_author();
+ robert->set_name("robert");
+
+ options_.use_lower_camel_for_enums = true;
+ ResetProtoWriter();
+
+ ow_->StartObject("")
+ ->RenderString("title", "Some Book")
+ ->RenderString("type", "artsAndPhotography")
+ ->StartObject("author")
+ ->RenderString("name", "robert")
+ ->EndObject()
+ ->EndObject();
+ CheckOutput(book);
+}
+
+TEST_P(ProtoStreamObjectWriterTest, PrimitiveFromStringConversion) {
+ Primitive full;
+ full.set_fix32(101);
+ full.set_u32(102);
+ full.set_i32(-103);
+ full.set_sf32(-104);
+ full.set_s32(-105);
+ full.set_fix64(40000000001L);
+ full.set_u64(40000000002L);
+ full.set_i64(-40000000003L);
+ full.set_sf64(-40000000004L);
+ full.set_s64(-40000000005L);
+ full.set_str("string1");
+ full.set_bytes("Some Bytes");
+ full.set_float_(3.14f);
+ full.set_double_(-4.05L);
+ full.set_bool_(true);
+ full.add_rep_fix32(201);
+ full.add_rep_u32(202);
+ full.add_rep_i32(-203);
+ full.add_rep_sf32(-204);
+ full.add_rep_s32(-205);
+ full.add_rep_fix64(80000000001L);
+ full.add_rep_u64(80000000002L);
+ full.add_rep_i64(-80000000003L);
+ full.add_rep_sf64(-80000000004L);
+ full.add_rep_s64(-80000000005L);
+ full.add_rep_str("string2");
+ full.add_rep_bytes("More Bytes");
+ full.add_rep_float(6.14f);
+ full.add_rep_double(-8.05L);
+ full.add_rep_bool(false);
+
+ ResetTypeInfo(Primitive::descriptor());
+
+ ow_->StartObject("")
+ ->RenderString("fix32", "101")
+ ->RenderString("u32", "102")
+ ->RenderString("i32", "-103")
+ ->RenderString("sf32", "-104")
+ ->RenderString("s32", "-105")
+ ->RenderString("fix64", "40000000001")
+ ->RenderString("u64", "40000000002")
+ ->RenderString("i64", "-40000000003")
+ ->RenderString("sf64", "-40000000004")
+ ->RenderString("s64", "-40000000005")
+ ->RenderString("str", "string1")
+ ->RenderString("bytes", "U29tZSBCeXRlcw==") // "Some Bytes"
+ ->RenderString("float", "3.14")
+ ->RenderString("double", "-4.05")
+ ->RenderString("bool", "true")
+ ->StartList("rep_fix32")
+ ->RenderString("", "201")
+ ->EndList()
+ ->StartList("rep_u32")
+ ->RenderString("", "202")
+ ->EndList()
+ ->StartList("rep_i32")
+ ->RenderString("", "-203")
+ ->EndList()
+ ->StartList("rep_sf32")
+ ->RenderString("", "-204")
+ ->EndList()
+ ->StartList("rep_s32")
+ ->RenderString("", "-205")
+ ->EndList()
+ ->StartList("rep_fix64")
+ ->RenderString("", "80000000001")
+ ->EndList()
+ ->StartList("rep_u64")
+ ->RenderString("", "80000000002")
+ ->EndList()
+ ->StartList("rep_i64")
+ ->RenderString("", "-80000000003")
+ ->EndList()
+ ->StartList("rep_sf64")
+ ->RenderString("", "-80000000004")
+ ->EndList()
+ ->StartList("rep_s64")
+ ->RenderString("", "-80000000005")
+ ->EndList()
+ ->StartList("rep_str")
+ ->RenderString("", "string2")
+ ->EndList()
+ ->StartList("rep_bytes")
+ ->RenderString("", "TW9yZSBCeXRlcw==") // "More Bytes"
+ ->EndList()
+ ->StartList("rep_float")
+ ->RenderString("", "6.14")
+ ->EndList()
+ ->StartList("rep_double")
+ ->RenderString("", "-8.05")
+ ->EndList()
+ ->StartList("rep_bool")
+ ->RenderString("", "false")
+ ->EndList()
+ ->EndObject();
+ CheckOutput(full);
+}
+
+TEST_P(ProtoStreamObjectWriterTest, InfinityInputTest) {
+ Primitive full;
+ full.set_double_(std::numeric_limits<double>::infinity());
+ full.set_float_(std::numeric_limits<float>::infinity());
+ full.set_str("-Infinity");
+
+ ResetTypeInfo(Primitive::descriptor());
+
+ EXPECT_CALL(listener_, InvalidValue(_, StringPiece("TYPE_INT32"),
+ StringPiece("\"Infinity\"")))
+ .With(Args<0>(HasObjectLocation("i32")));
+ EXPECT_CALL(listener_, InvalidValue(_, StringPiece("TYPE_UINT32"),
+ StringPiece("\"Infinity\"")))
+ .With(Args<0>(HasObjectLocation("u32")));
+ EXPECT_CALL(listener_, InvalidValue(_, StringPiece("TYPE_SFIXED64"),
+ StringPiece("\"-Infinity\"")))
+ .With(Args<0>(HasObjectLocation("sf64")));
+ EXPECT_CALL(listener_, InvalidValue(_, StringPiece("TYPE_BOOL"),
+ StringPiece("\"Infinity\"")))
+ .With(Args<0>(HasObjectLocation("bool")));
+
+ ow_->StartObject("")
+ ->RenderString("double", "Infinity")
+ ->RenderString("float", "Infinity")
+ ->RenderString("i32", "Infinity")
+ ->RenderString("u32", "Infinity")
+ ->RenderString("sf64", "-Infinity")
+ ->RenderString("str", "-Infinity")
+ ->RenderString("bool", "Infinity")
+ ->EndObject();
+ CheckOutput(full);
+}
+
+TEST_P(ProtoStreamObjectWriterTest, NaNInputTest) {
+ Primitive full;
+ full.set_double_(std::numeric_limits<double>::quiet_NaN());
+ full.set_float_(std::numeric_limits<float>::quiet_NaN());
+ full.set_str("NaN");
+
+ ResetTypeInfo(Primitive::descriptor());
+
+ EXPECT_CALL(listener_, InvalidValue(_, StringPiece("TYPE_INT32"),
+ StringPiece("\"NaN\"")))
+ .With(Args<0>(HasObjectLocation("i32")));
+ EXPECT_CALL(listener_, InvalidValue(_, StringPiece("TYPE_UINT32"),
+ StringPiece("\"NaN\"")))
+ .With(Args<0>(HasObjectLocation("u32")));
+ EXPECT_CALL(listener_, InvalidValue(_, StringPiece("TYPE_SFIXED64"),
+ StringPiece("\"NaN\"")))
+ .With(Args<0>(HasObjectLocation("sf64")));
+ EXPECT_CALL(listener_, InvalidValue(_, StringPiece("TYPE_BOOL"),
+ StringPiece("\"NaN\"")))
+ .With(Args<0>(HasObjectLocation("bool")));
+
+ ow_->StartObject("")
+ ->RenderString("double", "NaN")
+ ->RenderString("float", "NaN")
+ ->RenderString("i32", "NaN")
+ ->RenderString("u32", "NaN")
+ ->RenderString("sf64", "NaN")
+ ->RenderString("str", "NaN")
+ ->RenderString("bool", "NaN")
+ ->EndObject();
+
+ CheckOutput(full);
+}
+
+TEST_P(ProtoStreamObjectWriterTest, ImplicitPrimitiveList) {
+ Book expected;
+ Author* author = expected.mutable_author();
+ author->set_name("The Author");
+ author->add_pseudonym("first");
+ author->add_pseudonym("second");
+
+ ow_->StartObject("")
+ ->StartObject("author")
+ ->RenderString("name", "The Author")
+ ->RenderString("pseudonym", "first")
+ ->RenderString("pseudonym", "second")
+ ->EndObject()
+ ->EndObject();
+ CheckOutput(expected);
+}
+
+TEST_P(ProtoStreamObjectWriterTest,
+ LastWriteWinsOnNonRepeatedPrimitiveFieldWithDuplicates) {
+ Book expected;
+ Author* author = expected.mutable_author();
+ author->set_name("second");
+
+ ow_->StartObject("")
+ ->StartObject("author")
+ ->RenderString("name", "first")
+ ->RenderString("name", "second")
+ ->EndObject()
+ ->EndObject();
+ CheckOutput(expected);
+}
+
+TEST_P(ProtoStreamObjectWriterTest, ExplicitPrimitiveList) {
+ Book expected;
+ Author* author = expected.mutable_author();
+ author->set_name("The Author");
+ author->add_pseudonym("first");
+ author->add_pseudonym("second");
+
+ ow_->StartObject("")
+ ->StartObject("author")
+ ->RenderString("name", "The Author")
+ ->StartList("pseudonym")
+ ->RenderString("", "first")
+ ->RenderString("", "second")
+ ->EndList()
+ ->EndObject()
+ ->EndObject();
+ CheckOutput(expected);
+}
+
+TEST_P(ProtoStreamObjectWriterTest, NonRepeatedExplicitPrimitiveList) {
+ Book expected;
+ expected.set_allocated_author(new Author());
+
+ EXPECT_CALL(
+ listener_,
+ InvalidName(_, StringPiece("name"),
+ StringPiece(
+ "Proto field is not repeating, cannot start list.")))
+ .With(Args<0>(HasObjectLocation("author")));
+ ow_->StartObject("")
+ ->StartObject("author")
+ ->StartList("name")
+ ->RenderString("", "first")
+ ->RenderString("", "second")
+ ->EndList()
+ ->EndObject()
+ ->EndObject();
+ CheckOutput(expected);
+}
+
+TEST_P(ProtoStreamObjectWriterTest, ImplicitMessageList) {
+ Book expected;
+ Author* outer = expected.mutable_author();
+ outer->set_name("outer");
+ outer->set_alive(true);
+ Author* first = outer->add_friend_();
+ first->set_name("first");
+ Author* second = outer->add_friend_();
+ second->set_name("second");
+
+ ow_->StartObject("")
+ ->StartObject("author")
+ ->RenderString("name", "outer")
+ ->RenderBool("alive", true)
+ ->StartObject("friend")
+ ->RenderString("name", "first")
+ ->EndObject()
+ ->StartObject("friend")
+ ->RenderString("name", "second")
+ ->EndObject()
+ ->EndObject()
+ ->EndObject();
+ CheckOutput(expected);
+}
+
+TEST_P(ProtoStreamObjectWriterTest, DisableImplicitMessageList) {
+ options_.disable_implicit_message_list = true;
+ options_.suppress_implicit_message_list_error = true;
+ ResetProtoWriter();
+
+ Book expected;
+ // The repeated friend field of the author is empty.
+ expected.mutable_author();
+
+ EXPECT_CALL(listener_, InvalidValue(_, _, _)).Times(0);
+
+ ow_->StartObject("")
+ ->StartObject("author")
+ ->StartObject("friend")
+ ->RenderString("name", "first")
+ ->EndObject()
+ ->StartObject("friend")
+ ->RenderString("name", "second")
+ ->EndObject()
+ ->EndObject()
+ ->EndObject();
+ CheckOutput(expected);
+}
+
+TEST_P(ProtoStreamObjectWriterTest,
+ DisableImplicitMessageListWithoutErrorSuppressed) {
+ options_.disable_implicit_message_list = true;
+ ResetProtoWriter();
+
+ Book expected;
+ // The repeated friend field of the author is empty.
+ expected.mutable_author();
+ EXPECT_CALL(
+ listener_,
+ InvalidValue(
+ _, StringPiece("friend"),
+ StringPiece(
+ "Starting an object in a repeated field but the parent object "
+ "is not a list")))
+ .With(Args<0>(HasObjectLocation("author")))
+ .Times(2);
+
+ ow_->StartObject("")
+ ->StartObject("author")
+ ->StartObject("friend")
+ ->RenderString("name", "first")
+ ->EndObject()
+ ->StartObject("friend")
+ ->RenderString("name", "second")
+ ->EndObject()
+ ->EndObject()
+ ->EndObject();
+ CheckOutput(expected);
+}
+
+TEST_P(ProtoStreamObjectWriterTest,
+ LastWriteWinsOnNonRepeatedMessageFieldWithDuplicates) {
+ Book expected;
+ Author* author = expected.mutable_author();
+ author->set_name("The Author");
+ Publisher* publisher = expected.mutable_publisher();
+ publisher->set_name("second");
+
+ ow_->StartObject("")
+ ->StartObject("author")
+ ->RenderString("name", "The Author")
+ ->EndObject()
+ ->StartObject("publisher")
+ ->RenderString("name", "first")
+ ->EndObject()
+ ->StartObject("publisher")
+ ->RenderString("name", "second")
+ ->EndObject()
+ ->EndObject();
+ CheckOutput(expected);
+}
+
+TEST_P(ProtoStreamObjectWriterTest, ExplicitMessageList) {
+ Book expected;
+ Author* outer = expected.mutable_author();
+ outer->set_name("outer");
+ outer->set_alive(true);
+ Author* first = outer->add_friend_();
+ first->set_name("first");
+ Author* second = outer->add_friend_();
+ second->set_name("second");
+
+ ow_->StartObject("")
+ ->StartObject("author")
+ ->RenderString("name", "outer")
+ ->RenderBool("alive", true)
+ ->StartList("friend")
+ ->StartObject("")
+ ->RenderString("name", "first")
+ ->EndObject()
+ ->StartObject("")
+ ->RenderString("name", "second")
+ ->EndObject()
+ ->EndList()
+ ->EndObject()
+ ->EndObject();
+ CheckOutput(expected);
+}
+
+TEST_P(ProtoStreamObjectWriterTest, NonRepeatedExplicitMessageList) {
+ Book expected;
+ Author* author = expected.mutable_author();
+ author->set_name("The Author");
+
+ EXPECT_CALL(
+ listener_,
+ InvalidName(_, StringPiece("publisher"),
+ StringPiece(
+ "Proto field is not repeating, cannot start list.")))
+ .With(Args<0>(HasObjectLocation("")));
+ ow_->StartObject("")
+ ->StartObject("author")
+ ->RenderString("name", "The Author")
+ ->EndObject()
+ ->StartList("publisher")
+ ->StartObject("")
+ ->RenderString("name", "first")
+ ->EndObject()
+ ->StartObject("")
+ ->RenderString("name", "second")
+ ->EndObject()
+ ->EndList()
+ ->EndObject();
+ CheckOutput(expected);
+}
+
+TEST_P(ProtoStreamObjectWriterTest, UnknownFieldAtRoot) {
+ Book empty;
+
+ EXPECT_CALL(listener_, InvalidName(_, StringPiece("unknown"),
+ StringPiece("Cannot find field.")))
+ .With(Args<0>(HasObjectLocation("")));
+ ow_->StartObject("")->RenderString("unknown", "Nope!")->EndObject();
+ CheckOutput(empty, 0);
+}
+
+TEST_P(ProtoStreamObjectWriterTest, UnknownFieldAtAuthorFriend) {
+ Book expected;
+ Author* paul = expected.mutable_author();
+ paul->set_name("Paul");
+ Author* mark = paul->add_friend_();
+ mark->set_name("Mark");
+ Author* john = paul->add_friend_();
+ john->set_name("John");
+ Author* luke = paul->add_friend_();
+ luke->set_name("Luke");
+
+ EXPECT_CALL(listener_, InvalidName(_, StringPiece("address"),
+ StringPiece("Cannot find field.")))
+ .With(Args<0>(HasObjectLocation("author.friend[1]")));
+ ow_->StartObject("")
+ ->StartObject("author")
+ ->RenderString("name", "Paul")
+ ->StartList("friend")
+ ->StartObject("")
+ ->RenderString("name", "Mark")
+ ->EndObject()
+ ->StartObject("")
+ ->RenderString("name", "John")
+ ->RenderString("address", "Patmos")
+ ->EndObject()
+ ->StartObject("")
+ ->RenderString("name", "Luke")
+ ->EndObject()
+ ->EndList()
+ ->EndObject()
+ ->EndObject();
+ CheckOutput(expected);
+}
+
+TEST_P(ProtoStreamObjectWriterTest, UnknownObjectAtRoot) {
+ Book empty;
+
+ EXPECT_CALL(listener_, InvalidName(_, StringPiece("unknown"),
+ StringPiece("Cannot find field.")))
+ .With(Args<0>(HasObjectLocation("")));
+ ow_->StartObject("")->StartObject("unknown")->EndObject()->EndObject();
+ CheckOutput(empty, 0);
+}
+
+TEST_P(ProtoStreamObjectWriterTest, UnknownObjectAtAuthor) {
+ Book expected;
+ Author* author = expected.mutable_author();
+ author->set_name("William");
+ author->add_pseudonym("Bill");
+
+ EXPECT_CALL(listener_, InvalidName(_, StringPiece("wife"),
+ StringPiece("Cannot find field.")))
+ .With(Args<0>(HasObjectLocation("author")));
+ ow_->StartObject("")
+ ->StartObject("author")
+ ->RenderString("name", "William")
+ ->StartObject("wife")
+ ->RenderString("name", "Hilary")
+ ->EndObject()
+ ->RenderString("pseudonym", "Bill")
+ ->EndObject()
+ ->EndObject();
+ CheckOutput(expected);
+}
+
+TEST_P(ProtoStreamObjectWriterTest, UnknownListAtRoot) {
+ Book empty;
+
+ EXPECT_CALL(listener_, InvalidName(_, StringPiece("unknown"),
+ StringPiece("Cannot find field.")))
+ .With(Args<0>(HasObjectLocation("")));
+ ow_->StartObject("")->StartList("unknown")->EndList()->EndObject();
+ CheckOutput(empty, 0);
+}
+
+TEST_P(ProtoStreamObjectWriterTest, UnknownListAtPublisher) {
+ Book expected;
+ expected.set_title("Brainwashing");
+ Publisher* publisher = expected.mutable_publisher();
+ publisher->set_name("propaganda");
+
+ EXPECT_CALL(listener_, InvalidName(_, StringPiece("alliance"),
+ StringPiece("Cannot find field.")))
+ .With(Args<0>(HasObjectLocation("publisher")));
+ ow_->StartObject("")
+ ->StartObject("publisher")
+ ->RenderString("name", "propaganda")
+ ->StartList("alliance")
+ ->EndList()
+ ->EndObject()
+ ->RenderString("title", "Brainwashing")
+ ->EndObject();
+ CheckOutput(expected);
+}
+
+TEST_P(ProtoStreamObjectWriterTest, IgnoreUnknownFieldAtRoot) {
+ Book empty;
+
+ options_.ignore_unknown_fields = true;
+ ResetProtoWriter();
+
+ EXPECT_CALL(listener_, InvalidName(_, _, _)).Times(0);
+ ow_->StartObject("")->RenderString("unknown", "Nope!")->EndObject();
+ CheckOutput(empty, 0);
+}
+
+TEST_P(ProtoStreamObjectWriterTest, IgnoreUnknownFieldAtAuthorFriend) {
+ Book expected;
+ Author* paul = expected.mutable_author();
+ paul->set_name("Paul");
+ Author* mark = paul->add_friend_();
+ mark->set_name("Mark");
+ Author* john = paul->add_friend_();
+ john->set_name("John");
+ Author* luke = paul->add_friend_();
+ luke->set_name("Luke");
+
+ options_.ignore_unknown_fields = true;
+ ResetProtoWriter();
+
+ EXPECT_CALL(listener_, InvalidName(_, _, _)).Times(0);
+ ow_->StartObject("")
+ ->StartObject("author")
+ ->RenderString("name", "Paul")
+ ->StartList("friend")
+ ->StartObject("")
+ ->RenderString("name", "Mark")
+ ->EndObject()
+ ->StartObject("")
+ ->RenderString("name", "John")
+ ->RenderString("address", "Patmos")
+ ->EndObject()
+ ->StartObject("")
+ ->RenderString("name", "Luke")
+ ->EndObject()
+ ->EndList()
+ ->EndObject()
+ ->EndObject();
+ CheckOutput(expected);
+}
+
+TEST_P(ProtoStreamObjectWriterTest, IgnoreUnknownObjectAtRoot) {
+ Book empty;
+
+ options_.ignore_unknown_fields = true;
+ ResetProtoWriter();
+
+ EXPECT_CALL(listener_, InvalidName(_, StringPiece("unknown"),
+ StringPiece("Cannot find field.")))
+ .Times(0);
+ ow_->StartObject("")->StartObject("unknown")->EndObject()->EndObject();
+ CheckOutput(empty, 0);
+}
+
+TEST_P(ProtoStreamObjectWriterTest, IgnoreUnknownObjectAtAuthor) {
+ Book expected;
+ Author* author = expected.mutable_author();
+ author->set_name("William");
+ author->add_pseudonym("Bill");
+
+ options_.ignore_unknown_fields = true;
+ ResetProtoWriter();
+
+ EXPECT_CALL(listener_, InvalidName(_, _, _)).Times(0);
+ ow_->StartObject("")
+ ->StartObject("author")
+ ->RenderString("name", "William")
+ ->StartObject("wife")
+ ->RenderString("name", "Hilary")
+ ->EndObject()
+ ->RenderString("pseudonym", "Bill")
+ ->EndObject()
+ ->EndObject();
+ CheckOutput(expected);
+}
+
+TEST_P(ProtoStreamObjectWriterTest, IgnoreUnknownListAtRoot) {
+ Book empty;
+
+ options_.ignore_unknown_fields = true;
+ ResetProtoWriter();
+
+ EXPECT_CALL(listener_, InvalidName(_, _, _)).Times(0);
+ ow_->StartObject("")->StartList("unknown")->EndList()->EndObject();
+ CheckOutput(empty, 0);
+}
+
+TEST_P(ProtoStreamObjectWriterTest, IgnoreUnknownListAtPublisher) {
+ Book expected;
+ expected.set_title("Brainwashing");
+ Publisher* publisher = expected.mutable_publisher();
+ publisher->set_name("propaganda");
+
+ options_.ignore_unknown_fields = true;
+ ResetProtoWriter();
+
+ EXPECT_CALL(listener_, InvalidName(_, _, _)).Times(0);
+ ow_->StartObject("")
+ ->StartObject("publisher")
+ ->RenderString("name", "propaganda")
+ ->StartList("alliance")
+ ->EndList()
+ ->EndObject()
+ ->RenderString("title", "Brainwashing")
+ ->EndObject();
+ CheckOutput(expected);
+}
+
+TEST_P(ProtoStreamObjectWriterTest,
+ IgnoreUnknownFieldsDontIgnoreUnknownEnumValues) {
+ ResetTypeInfo(Proto3Message::descriptor());
+
+ Proto3Message expected;
+ EXPECT_CALL(
+ listener_,
+ InvalidValue(_,
+ StringPiece(
+ "type.googleapis.com/"
+ "proto_util_converter.testing.Proto3Message.NestedEnum"),
+ StringPiece("\"someunknownvalueyouwillneverknow\"")))
+ .With(Args<0>(HasObjectLocation("enum_value")));
+ ow_->StartObject("")
+ ->RenderString("enumValue", "someunknownvalueyouwillneverknow")
+ ->EndObject();
+ CheckOutput(expected);
+}
+
+TEST_P(ProtoStreamObjectWriterTest, AcceptUnknownEnumValue) {
+ ResetTypeInfo(Proto3Message::descriptor());
+
+ Proto3Message expected;
+ expected.set_enum_value(static_cast<Proto3Message::NestedEnum>(12345));
+
+ EXPECT_CALL(listener_, InvalidValue(_, _, _)).Times(0);
+ ow_->StartObject("")->RenderInt32("enumValue", 12345)->EndObject();
+ CheckOutput(expected);
+}
+
+TEST_P(ProtoStreamObjectWriterTest, MissingRequiredField) {
+ Book expected;
+ expected.set_title("My Title");
+ expected.set_allocated_publisher(new Publisher());
+
+ EXPECT_CALL(listener_, MissingField(_, StringPiece("name")))
+ .With(Args<0>(HasObjectLocation("publisher")));
+ ow_->StartObject("")
+ ->StartObject("publisher")
+ ->EndObject()
+ ->RenderString("title", "My Title")
+ ->EndObject();
+ CheckOutput(expected);
+}
+
+TEST_P(ProtoStreamObjectWriterTest, InvalidFieldValueAtRoot) {
+ Book empty;
+
+ EXPECT_CALL(listener_, InvalidValue(_, StringPiece("TYPE_UINT32"),
+ StringPiece("\"garbage\"")))
+ .With(Args<0>(HasObjectLocation("length")));
+ ow_->StartObject("")->RenderString("length", "garbage")->EndObject();
+ CheckOutput(empty, 0);
+}
+
+TEST_P(ProtoStreamObjectWriterTest, MultipleInvalidFieldValues) {
+ Book expected;
+ expected.set_title("My Title");
+
+ EXPECT_CALL(listener_, InvalidValue(_, StringPiece("TYPE_UINT32"),
+ StringPiece("\"-400\"")))
+ .With(Args<0>(HasObjectLocation("length")));
+ EXPECT_CALL(listener_, InvalidValue(_, StringPiece("TYPE_INT64"),
+ StringPiece("\"3.14\"")))
+ .With(Args<0>(HasObjectLocation("published")));
+ ow_->StartObject("")
+ ->RenderString("length", "-400")
+ ->RenderString("published", "3.14")
+ ->RenderString("title", "My Title")
+ ->EndObject();
+ CheckOutput(expected);
+}
+
+TEST_P(ProtoStreamObjectWriterTest, UnnamedFieldAtRoot) {
+ Book empty;
+
+ EXPECT_CALL(listener_,
+ InvalidName(_, StringPiece(""),
+ StringPiece("Proto fields must have a name.")))
+ .With(Args<0>(HasObjectLocation("")));
+ ow_->StartObject("")->RenderFloat("", 3.14)->EndObject();
+ CheckOutput(empty, 0);
+}
+
+TEST_P(ProtoStreamObjectWriterTest, UnnamedFieldAtAuthor) {
+ Book expected;
+ expected.set_title("noname");
+ expected.set_allocated_author(new Author());
+
+ EXPECT_CALL(listener_,
+ InvalidName(_, StringPiece(""),
+ StringPiece("Proto fields must have a name.")))
+ .With(Args<0>(HasObjectLocation("author")));
+ ow_->StartObject("")
+ ->StartObject("author")
+ ->RenderInt32("", 123)
+ ->EndObject()
+ ->RenderString("title", "noname")
+ ->EndObject();
+ CheckOutput(expected);
+}
+
+TEST_P(ProtoStreamObjectWriterTest, UnnamedListAtRoot) {
+ Book expected;
+ expected.set_title("noname");
+
+ EXPECT_CALL(listener_,
+ InvalidName(_, StringPiece(""),
+ StringPiece("Proto fields must have a name.")))
+ .With(Args<0>(HasObjectLocation("")));
+ ow_->StartObject("")
+ ->StartList("")
+ ->EndList()
+ ->RenderString("title", "noname")
+ ->EndObject();
+ CheckOutput(expected);
+}
+
+TEST_P(ProtoStreamObjectWriterTest, RootNamedObject) {
+ Book expected;
+ expected.set_title("Annie");
+
+ EXPECT_CALL(
+ listener_,
+ InvalidName(_, StringPiece("oops"),
+ StringPiece("Root element should not be named.")))
+ .With(Args<0>(HasObjectLocation("")));
+ ow_->StartObject("oops")->RenderString("title", "Annie")->EndObject();
+ CheckOutput(expected, 7);
+}
+
+TEST_P(ProtoStreamObjectWriterTest, RootNamedList) {
+ Book empty;
+
+ EXPECT_CALL(
+ listener_,
+ InvalidName(_, StringPiece("oops"),
+ StringPiece("Root element should not be named.")))
+ .With(Args<0>(HasObjectLocation("")));
+ ow_->StartList("oops")->RenderString("", "item")->EndList();
+ CheckOutput(empty, 0);
+}
+
+TEST_P(ProtoStreamObjectWriterTest, RootUnnamedField) {
+ Book empty;
+
+ EXPECT_CALL(listener_,
+ InvalidName(_, StringPiece(""),
+ StringPiece("Root element must be a message.")))
+ .With(Args<0>(HasObjectLocation("")));
+ ow_->RenderBool("", true);
+ CheckOutput(empty, 0);
+}
+
+TEST_P(ProtoStreamObjectWriterTest, RootNamedField) {
+ Book empty;
+
+ EXPECT_CALL(listener_,
+ InvalidName(_, StringPiece("oops"),
+ StringPiece("Root element must be a message.")))
+ .With(Args<0>(HasObjectLocation("")));
+ ow_->RenderBool("oops", true);
+ CheckOutput(empty, 0);
+}
+
+TEST_P(ProtoStreamObjectWriterTest, NullValue) {
+ Book empty;
+
+ ow_->RenderNull("");
+ CheckOutput(empty, 0);
+}
+
+TEST_P(ProtoStreamObjectWriterTest, NullValueForMessageField) {
+ Book empty;
+
+ ow_->RenderNull("author");
+ CheckOutput(empty, 0);
+}
+
+TEST_P(ProtoStreamObjectWriterTest, NullValueForPrimitiveField) {
+ Book empty;
+
+ ow_->RenderNull("length");
+ CheckOutput(empty, 0);
+}
+
+class ProtoStreamObjectWriterTimestampDurationTest
+ : public BaseProtoStreamObjectWriterTest {
+ protected:
+ ProtoStreamObjectWriterTimestampDurationTest() {
+ std::vector<const Descriptor*> descriptors;
+ descriptors.push_back(TimestampDuration::descriptor());
+ descriptors.push_back(google::protobuf::Timestamp::descriptor());
+ descriptors.push_back(google::protobuf::Duration::descriptor());
+ ResetTypeInfo(descriptors);
+ }
+};
+
+INSTANTIATE_TEST_SUITE_P(DifferentTypeInfoSourceTest,
+ ProtoStreamObjectWriterTimestampDurationTest,
+ ::testing::Values(
+ testing::USE_TYPE_RESOLVER));
+
+TEST_P(ProtoStreamObjectWriterTimestampDurationTest, ParseTimestamp) {
+ TimestampDuration timestamp;
+ google::protobuf::Timestamp* ts = timestamp.mutable_ts();
+ ts->set_seconds(1448249855);
+ ts->set_nanos(33155000);
+
+ ow_->StartObject("")
+ ->RenderString("ts", "2015-11-23T03:37:35.033155Z")
+ ->EndObject();
+ CheckOutput(timestamp);
+}
+
+TEST_P(ProtoStreamObjectWriterTimestampDurationTest,
+ ParseTimestampYearNotZeroPadded) {
+ TimestampDuration timestamp;
+ google::protobuf::Timestamp* ts = timestamp.mutable_ts();
+ ts->set_seconds(-61665654145);
+ ts->set_nanos(33155000);
+
+ ow_->StartObject("")
+ ->RenderString("ts", "15-11-23T03:37:35.033155Z")
+ ->EndObject();
+ CheckOutput(timestamp);
+}
+
+TEST_P(ProtoStreamObjectWriterTimestampDurationTest,
+ ParseTimestampYearZeroPadded) {
+ TimestampDuration timestamp;
+ google::protobuf::Timestamp* ts = timestamp.mutable_ts();
+ ts->set_seconds(-61665654145);
+ ts->set_nanos(33155000);
+
+ ow_->StartObject("")
+ ->RenderString("ts", "0015-11-23T03:37:35.033155Z")
+ ->EndObject();
+ CheckOutput(timestamp);
+}
+
+TEST_P(ProtoStreamObjectWriterTimestampDurationTest,
+ ParseTimestampWithPositiveOffset) {
+ TimestampDuration timestamp;
+ google::protobuf::Timestamp* ts = timestamp.mutable_ts();
+ ts->set_seconds(1448249855);
+ ts->set_nanos(33155000);
+
+ ow_->StartObject("")
+ ->RenderString("ts", "2015-11-23T11:47:35.033155+08:10")
+ ->EndObject();
+ CheckOutput(timestamp);
+}
+
+TEST_P(ProtoStreamObjectWriterTimestampDurationTest,
+ ParseTimestampWithNegativeOffset) {
+ TimestampDuration timestamp;
+ google::protobuf::Timestamp* ts = timestamp.mutable_ts();
+ ts->set_seconds(1448249855);
+ ts->set_nanos(33155000);
+
+ ow_->StartObject("")
+ ->RenderString("ts", "2015-11-22T19:47:35.033155-07:50")
+ ->EndObject();
+ CheckOutput(timestamp);
+}
+
+TEST_P(ProtoStreamObjectWriterTimestampDurationTest,
+ TimestampWithInvalidOffset1) {
+ TimestampDuration timestamp;
+
+ EXPECT_CALL(
+ listener_,
+ InvalidValue(
+ _, StringPiece("type.googleapis.com/google.protobuf.Timestamp"),
+ StringPiece("Field 'ts', Invalid time format: "
+ "2016-03-07T15:14:23+")));
+
+ ow_->StartObject("")->RenderString("ts", "2016-03-07T15:14:23+")->EndObject();
+ CheckOutput(timestamp);
+}
+
+TEST_P(ProtoStreamObjectWriterTimestampDurationTest,
+ TimestampWithInvalidOffset2) {
+ TimestampDuration timestamp;
+
+ EXPECT_CALL(
+ listener_,
+ InvalidValue(
+ _, StringPiece("type.googleapis.com/google.protobuf.Timestamp"),
+ StringPiece("Field 'ts', Invalid time format: "
+ "2016-03-07T15:14:23+08-10")));
+
+ ow_->StartObject("")
+ ->RenderString("ts", "2016-03-07T15:14:23+08-10")
+ ->EndObject();
+ CheckOutput(timestamp);
+}
+
+TEST_P(ProtoStreamObjectWriterTimestampDurationTest,
+ TimestampWithInvalidOffset3) {
+ TimestampDuration timestamp;
+
+ EXPECT_CALL(
+ listener_,
+ InvalidValue(
+ _, StringPiece("type.googleapis.com/google.protobuf.Timestamp"),
+ StringPiece("Field 'ts', Invalid time format: "
+ "2016-03-07T15:14:23+24:10")));
+
+ ow_->StartObject("")
+ ->RenderString("ts", "2016-03-07T15:14:23+24:10")
+ ->EndObject();
+ CheckOutput(timestamp);
+}
+
+TEST_P(ProtoStreamObjectWriterTimestampDurationTest,
+ TimestampWithInvalidOffset4) {
+ TimestampDuration timestamp;
+
+ EXPECT_CALL(
+ listener_,
+ InvalidValue(
+ _, StringPiece("type.googleapis.com/google.protobuf.Timestamp"),
+ StringPiece("Field 'ts', Invalid time format: "
+ "2016-03-07T15:14:23+04:60")));
+
+ ow_->StartObject("")
+ ->RenderString("ts", "2016-03-07T15:14:23+04:60")
+ ->EndObject();
+ CheckOutput(timestamp);
+}
+
+TEST_P(ProtoStreamObjectWriterTimestampDurationTest, InvalidTimestampError1) {
+ TimestampDuration timestamp;
+
+ EXPECT_CALL(
+ listener_,
+ InvalidValue(
+ _, StringPiece("type.googleapis.com/google.protobuf.Timestamp"),
+ StringPiece("Field 'ts', Invalid time format: ")));
+
+ ow_->StartObject("")->RenderString("ts", "")->EndObject();
+ CheckOutput(timestamp);
+}
+
+TEST_P(ProtoStreamObjectWriterTimestampDurationTest, InvalidTimestampError2) {
+ TimestampDuration timestamp;
+
+ EXPECT_CALL(
+ listener_,
+ InvalidValue(
+ _, StringPiece("type.googleapis.com/google.protobuf.Timestamp"),
+ StringPiece("Field 'ts', Invalid time format: Z")));
+
+ ow_->StartObject("")->RenderString("ts", "Z")->EndObject();
+ CheckOutput(timestamp);
+}
+
+TEST_P(ProtoStreamObjectWriterTimestampDurationTest, InvalidTimestampError3) {
+ TimestampDuration timestamp;
+
+ EXPECT_CALL(
+ listener_,
+ InvalidValue(
+ _, StringPiece("type.googleapis.com/google.protobuf.Timestamp"),
+ StringPiece("Field 'ts', Invalid time format: "
+ "1970-01-01T00:00:00.ABZ")));
+
+ ow_->StartObject("")
+ ->RenderString("ts", "1970-01-01T00:00:00.ABZ")
+ ->EndObject();
+ CheckOutput(timestamp);
+}
+
+TEST_P(ProtoStreamObjectWriterTimestampDurationTest, InvalidTimestampError4) {
+ TimestampDuration timestamp;
+
+ EXPECT_CALL(
+ listener_,
+ InvalidValue(
+ _, StringPiece("type.googleapis.com/google.protobuf.Timestamp"),
+ StringPiece("Field 'ts', Invalid time format: "
+ "-8031-10-18T00:00:00.000Z")));
+
+ ow_->StartObject("")
+ ->RenderString("ts", "-8031-10-18T00:00:00.000Z")
+ ->EndObject();
+ CheckOutput(timestamp);
+}
+
+TEST_P(ProtoStreamObjectWriterTimestampDurationTest, InvalidTimestampError5) {
+ TimestampDuration timestamp;
+
+ EXPECT_CALL(
+ listener_,
+ InvalidValue(
+ _, StringPiece("type.googleapis.com/google.protobuf.Timestamp"),
+ StringPiece("Field 'ts', Invalid time format: "
+ "2015-11-23T03:37:35.033155 Z")));
+
+ ow_->StartObject("")
+ // Whitespace in the Timestamp nanos is not allowed.
+ ->RenderString("ts", "2015-11-23T03:37:35.033155 Z")
+ ->EndObject();
+ CheckOutput(timestamp);
+}
+
+TEST_P(ProtoStreamObjectWriterTimestampDurationTest, InvalidTimestampError6) {
+ TimestampDuration timestamp;
+
+ EXPECT_CALL(
+ listener_,
+ InvalidValue(
+ _, StringPiece("type.googleapis.com/google.protobuf.Timestamp"),
+ StringPiece("Field 'ts', Invalid time format: "
+ "2015-11-23T03:37:35.033155 1234Z")));
+
+ ow_->StartObject("")
+ // Whitespace in the Timestamp nanos is not allowed.
+ ->RenderString("ts", "2015-11-23T03:37:35.033155 1234Z")
+ ->EndObject();
+ CheckOutput(timestamp);
+}
+
+TEST_P(ProtoStreamObjectWriterTimestampDurationTest, InvalidTimestampError7) {
+ TimestampDuration timestamp;
+
+ EXPECT_CALL(
+ listener_,
+ InvalidValue(
+ _, StringPiece("type.googleapis.com/google.protobuf.Timestamp"),
+ StringPiece("Field 'ts', Invalid time format: "
+ "2015-11-23T03:37:35.033abc155Z")));
+
+ ow_->StartObject("")
+ // Non-numeric characters in the Timestamp nanos is not allowed.
+ ->RenderString("ts", "2015-11-23T03:37:35.033abc155Z")
+ ->EndObject();
+ CheckOutput(timestamp);
+}
+
+TEST_P(ProtoStreamObjectWriterTimestampDurationTest, InvalidTimestampError8) {
+ TimestampDuration timestamp;
+
+ EXPECT_CALL(
+ listener_,
+ InvalidValue(
+ _, StringPiece("type.googleapis.com/google.protobuf.Timestamp"),
+ StringPiece("Field 'ts', Invalid time format: "
+ "0-12-31T23:59:59.000Z")));
+
+ ow_->StartObject("")
+ ->RenderString("ts", "0-12-31T23:59:59.000Z")
+ ->EndObject();
+ CheckOutput(timestamp);
+}
+
+TEST_P(ProtoStreamObjectWriterTimestampDurationTest, ParseDuration) {
+ TimestampDuration duration;
+ google::protobuf::Duration* dur = duration.mutable_dur();
+ dur->set_seconds(1448216930);
+ dur->set_nanos(132262000);
+
+ ow_->StartObject("")->RenderString("dur", "1448216930.132262s")->EndObject();
+ CheckOutput(duration);
+}
+
+TEST_P(ProtoStreamObjectWriterTimestampDurationTest, InvalidDurationError1) {
+ TimestampDuration duration;
+
+ EXPECT_CALL(
+ listener_,
+ InvalidValue(
+ _, StringPiece("type.googleapis.com/google.protobuf.Duration"),
+ StringPiece(
+ "Field 'dur', Illegal duration format; duration must "
+ "end with 's'")));
+
+ ow_->StartObject("")->RenderString("dur", "")->EndObject();
+ CheckOutput(duration);
+}
+
+TEST_P(ProtoStreamObjectWriterTimestampDurationTest, InvalidDurationError2) {
+ TimestampDuration duration;
+
+ EXPECT_CALL(
+ listener_,
+ InvalidValue(
+ _, StringPiece("type.googleapis.com/google.protobuf.Duration"),
+ StringPiece(
+ "Field 'dur', Invalid duration format, failed to parse "
+ "seconds")));
+
+ ow_->StartObject("")->RenderString("dur", "s")->EndObject();
+ CheckOutput(duration);
+}
+
+TEST_P(ProtoStreamObjectWriterTimestampDurationTest, InvalidDurationError3) {
+ TimestampDuration duration;
+
+ EXPECT_CALL(
+ listener_,
+ InvalidValue(
+ _, StringPiece("type.googleapis.com/google.protobuf.Duration"),
+ StringPiece("Field 'dur', Invalid duration format, failed to "
+ "parse nano seconds")));
+
+ ow_->StartObject("")->RenderString("dur", "123.DEFs")->EndObject();
+ CheckOutput(duration);
+}
+
+TEST_P(ProtoStreamObjectWriterTimestampDurationTest, InvalidDurationError4) {
+ TimestampDuration duration;
+
+ EXPECT_CALL(
+ listener_,
+ InvalidValue(
+ _, StringPiece("type.googleapis.com/google.protobuf.Duration"),
+ StringPiece("Field 'dur', Duration value exceeds limits")));
+
+ ow_->StartObject("")->RenderString("dur", "315576000002s")->EndObject();
+ CheckOutput(duration);
+}
+
+TEST_P(ProtoStreamObjectWriterTimestampDurationTest, InvalidDurationError5) {
+ TimestampDuration duration;
+
+ EXPECT_CALL(
+ listener_,
+ InvalidValue(
+ _, StringPiece("type.googleapis.com/google.protobuf.Duration"),
+ StringPiece("Field 'dur', Duration value exceeds limits")));
+
+ ow_->StartObject("")->RenderString("dur", "0.1000000001s")->EndObject();
+ CheckOutput(duration);
+}
+
+TEST_P(ProtoStreamObjectWriterTimestampDurationTest,
+ MismatchedTimestampTypeInput) {
+ TimestampDuration timestamp;
+ EXPECT_CALL(
+ listener_,
+ InvalidValue(
+ _, StringPiece("type.googleapis.com/google.protobuf.Timestamp"),
+ StringPiece(
+ "Field 'ts', Invalid data type for timestamp, value is 1")))
+ .With(Args<0>(HasObjectLocation("ts")));
+ ow_->StartObject("")->RenderInt32("ts", 1)->EndObject();
+ CheckOutput(timestamp);
+}
+
+TEST_P(ProtoStreamObjectWriterTimestampDurationTest,
+ MismatchedDurationTypeInput) {
+ TimestampDuration duration;
+ EXPECT_CALL(
+ listener_,
+ InvalidValue(
+ _, StringPiece("type.googleapis.com/google.protobuf.Duration"),
+ StringPiece(
+ "Field 'dur', Invalid data type for duration, value is 1")))
+ .With(Args<0>(HasObjectLocation("dur")));
+ ow_->StartObject("")->RenderInt32("dur", 1)->EndObject();
+ CheckOutput(duration);
+}
+
+TEST_P(ProtoStreamObjectWriterTimestampDurationTest, TimestampAcceptsNull) {
+ TimestampDuration timestamp;
+ EXPECT_CALL(listener_, InvalidValue(_, _, _)).Times(0);
+ ow_->StartObject("")->RenderNull("ts")->EndObject();
+ CheckOutput(timestamp);
+}
+
+TEST_P(ProtoStreamObjectWriterTimestampDurationTest, DurationAcceptsNull) {
+ TimestampDuration duration;
+ EXPECT_CALL(listener_, InvalidValue(_, _, _)).Times(0);
+ ow_->StartObject("")->RenderNull("dur")->EndObject();
+ CheckOutput(duration);
+}
+
+class ProtoStreamObjectWriterStructTest
+ : public BaseProtoStreamObjectWriterTest {
+ protected:
+ ProtoStreamObjectWriterStructTest() { ResetProtoWriter(); }
+
+ // Resets ProtoWriter with current set of options and other state.
+ void ResetProtoWriter() {
+ std::vector<const Descriptor*> descriptors;
+ descriptors.push_back(StructType::descriptor());
+ descriptors.push_back(google::protobuf::Struct::descriptor());
+ ResetTypeInfo(descriptors);
+ }
+};
+
+INSTANTIATE_TEST_SUITE_P(DifferentTypeInfoSourceTest,
+ ProtoStreamObjectWriterStructTest,
+ ::testing::Values(
+ testing::USE_TYPE_RESOLVER));
+
+// TODO(skarvaje): Write tests for failure cases.
+TEST_P(ProtoStreamObjectWriterStructTest, StructRenderSuccess) {
+ StructType struct_type;
+ google::protobuf::Struct* s = struct_type.mutable_object();
+ s->mutable_fields()->operator[]("k1").set_number_value(123);
+ s->mutable_fields()->operator[]("k2").set_bool_value(true);
+
+ ow_->StartObject("")
+ ->StartObject("object")
+ ->RenderDouble("k1", 123)
+ ->RenderBool("k2", true)
+ ->EndObject()
+ ->EndObject();
+ CheckOutput(struct_type);
+}
+
+TEST_P(ProtoStreamObjectWriterStructTest, StructNullInputSuccess) {
+ StructType struct_type;
+ EXPECT_CALL(listener_,
+ InvalidName(_, StringPiece(""),
+ StringPiece("Proto fields must have a name.")))
+ .With(Args<0>(HasObjectLocation("")));
+ ow_->StartObject("")->RenderNull("")->EndObject();
+ CheckOutput(struct_type);
+}
+
+TEST_P(ProtoStreamObjectWriterStructTest, StructInvalidInputFailure) {
+ StructType struct_type;
+ EXPECT_CALL(
+ listener_,
+ InvalidValue(
+ _, StringPiece("type.googleapis.com/google.protobuf.Struct"),
+ StringPiece("true")))
+ .With(Args<0>(HasObjectLocation("object")));
+
+ ow_->StartObject("")->RenderBool("object", true)->EndObject();
+ CheckOutput(struct_type);
+}
+
+TEST_P(ProtoStreamObjectWriterStructTest, StructAcceptsNull) {
+ StructType struct_type;
+ EXPECT_CALL(listener_, InvalidValue(_, _, _)).Times(0);
+
+ ow_->StartObject("")->RenderNull("object")->EndObject();
+ CheckOutput(struct_type);
+}
+
+TEST_P(ProtoStreamObjectWriterStructTest, StructValuePreservesNull) {
+ StructType struct_type;
+ (*struct_type.mutable_object()->mutable_fields())["key"].set_null_value(
+ google::protobuf::NULL_VALUE);
+ EXPECT_CALL(listener_, InvalidValue(_, _, _)).Times(0);
+
+ ow_->StartObject("")
+ ->StartObject("object")
+ ->RenderNull("key")
+ ->EndObject()
+ ->EndObject();
+ CheckOutput(struct_type);
+}
+
+TEST_P(ProtoStreamObjectWriterStructTest, SimpleRepeatedStructMapKeyTest) {
+ EXPECT_CALL(listener_,
+ InvalidName(_, StringPiece("gBike"),
+ StringPiece(
+ "Repeated map key: 'gBike' is already set.")));
+ ow_->StartObject("")
+ ->StartObject("object")
+ ->RenderString("gBike", "v1")
+ ->RenderString("gBike", "v2")
+ ->EndObject()
+ ->EndObject();
+}
+
+TEST_P(ProtoStreamObjectWriterStructTest, RepeatedStructMapListKeyTest) {
+ EXPECT_CALL(
+ listener_,
+ InvalidName(_, StringPiece("k1"),
+ StringPiece("Repeated map key: 'k1' is already set.")));
+ ow_->StartObject("")
+ ->StartObject("object")
+ ->RenderString("k1", "v1")
+ ->StartList("k1")
+ ->RenderString("", "v2")
+ ->EndList()
+ ->EndObject()
+ ->EndObject();
+}
+
+TEST_P(ProtoStreamObjectWriterStructTest, RepeatedStructMapObjectKeyTest) {
+ EXPECT_CALL(
+ listener_,
+ InvalidName(_, StringPiece("k1"),
+ StringPiece("Repeated map key: 'k1' is already set.")));
+ ow_->StartObject("")
+ ->StartObject("object")
+ ->StartObject("k1")
+ ->RenderString("sub_k1", "v1")
+ ->EndObject()
+ ->StartObject("k1")
+ ->RenderString("sub_k2", "v2")
+ ->EndObject()
+ ->EndObject()
+ ->EndObject();
+}
+
+TEST_P(ProtoStreamObjectWriterStructTest, OptionStructIntAsStringsTest) {
+ StructType struct_type;
+ google::protobuf::Struct* s = struct_type.mutable_object();
+ s->mutable_fields()->operator[]("k1").set_string_value("123");
+ s->mutable_fields()->operator[]("k2").set_bool_value(true);
+ s->mutable_fields()->operator[]("k3").set_string_value("-222222222");
+ s->mutable_fields()->operator[]("k4").set_string_value("33333333");
+
+ options_.struct_integers_as_strings = true;
+ ResetProtoWriter();
+
+ ow_->StartObject("")
+ ->StartObject("object")
+ ->RenderDouble("k1", 123)
+ ->RenderBool("k2", true)
+ ->RenderInt64("k3", -222222222)
+ ->RenderUint64("k4", 33333333)
+ ->EndObject()
+ ->EndObject();
+ CheckOutput(struct_type);
+}
+
+TEST_P(ProtoStreamObjectWriterStructTest, Struct32BitIntsAndFloatsTest) {
+ StructType struct_type;
+ google::protobuf::Struct* s = struct_type.mutable_object();
+ s->mutable_fields()->operator[]("k1").set_number_value(1.5);
+ s->mutable_fields()->operator[]("k2").set_number_value(100);
+ s->mutable_fields()->operator[]("k3").set_number_value(100);
+ ResetProtoWriter();
+
+ ow_->StartObject("")
+ ->StartObject("object")
+ ->RenderFloat("k1", 1.5)
+ ->RenderInt32("k2", 100)
+ ->RenderUint32("k3", 100)
+ ->EndObject()
+ ->EndObject();
+ CheckOutput(struct_type);
+}
+
+TEST_P(ProtoStreamObjectWriterStructTest,
+ Struct32BitIntsAndFloatsAsStringsTest) {
+ StructType struct_type;
+ google::protobuf::Struct* s = struct_type.mutable_object();
+ s->mutable_fields()->operator[]("k1").set_string_value("1.5");
+ s->mutable_fields()->operator[]("k2").set_string_value("100");
+ s->mutable_fields()->operator[]("k3").set_string_value("100");
+
+ options_.struct_integers_as_strings = true;
+ ResetProtoWriter();
+
+ ow_->StartObject("")
+ ->StartObject("object")
+ ->RenderFloat("k1", 1.5)
+ ->RenderInt32("k2", 100)
+ ->RenderUint32("k3", 100)
+ ->EndObject()
+ ->EndObject();
+ CheckOutput(struct_type);
+}
+
+TEST_P(ProtoStreamObjectWriterStructTest, ValuePreservesNull) {
+ ValueWrapper value;
+ value.mutable_value()->set_null_value(google::protobuf::NULL_VALUE);
+
+ EXPECT_CALL(listener_, InvalidValue(_, _, _)).Times(0);
+ ow_->StartObject("")->RenderNull("value")->EndObject();
+ CheckOutput(value);
+}
+
+class ProtoStreamObjectWriterMapTest : public BaseProtoStreamObjectWriterTest {
+ protected:
+ ProtoStreamObjectWriterMapTest() {
+ std::vector<const Descriptor*> descriptors;
+ descriptors.push_back(MapIn::descriptor());
+ descriptors.push_back(google::protobuf::DoubleValue::descriptor());
+ ResetTypeInfo(descriptors);
+ }
+};
+
+INSTANTIATE_TEST_SUITE_P(DifferentTypeInfoSourceTest,
+ ProtoStreamObjectWriterMapTest,
+ ::testing::Values(
+ testing::USE_TYPE_RESOLVER));
+
+TEST_P(ProtoStreamObjectWriterMapTest, MapShouldNotAcceptList) {
+ MapIn mm;
+ EXPECT_CALL(
+ listener_,
+ InvalidValue(_, StringPiece("Map"),
+ StringPiece(
+ "Cannot bind a list to map for field 'map_input'.")));
+ ow_->StartObject("")
+ ->StartList("map_input")
+ ->RenderString("a", "b")
+ ->EndList()
+ ->EndObject();
+ CheckOutput(mm);
+}
+
+TEST_P(ProtoStreamObjectWriterMapTest, MapAcceptsNullValue) {
+ // Null should not be a valid map value.
+ // See http://go/proto3-json-spec#heading=h.r2ddatp7y4vi
+ // This test is added for backward compatibility.
+ MapIn mm;
+ (*mm.mutable_map_input())["a"] = "b";
+ (*mm.mutable_map_input())["x"] = "";
+ ow_->StartObject("")
+ ->StartObject("map_input")
+ ->RenderString("a", "b")
+ ->RenderNull("x")
+ ->EndObject()
+ ->EndObject();
+ CheckOutput(mm);
+}
+
+TEST_P(ProtoStreamObjectWriterMapTest, MapShouldIgnoreNullValueEntry) {
+ options_.ignore_null_value_map_entry = true;
+ ResetTypeInfo(MapIn::descriptor());
+ MapIn mm;
+ (*mm.mutable_map_input())["a"] = "b";
+ ow_->StartObject("")
+ ->StartObject("map_input")
+ ->RenderString("a", "b")
+ ->RenderNull("x")
+ ->EndObject()
+ ->EndObject();
+ CheckOutput(mm);
+}
+
+TEST_P(ProtoStreamObjectWriterMapTest, RepeatedMapKeyTest) {
+ EXPECT_CALL(
+ listener_,
+ InvalidName(_, StringPiece("k1"),
+ StringPiece("Repeated map key: 'k1' is already set.")));
+ ow_->StartObject("")
+ ->RenderString("other", "test")
+ ->StartObject("map_input")
+ ->RenderString("k1", "v1")
+ ->RenderString("k1", "v2")
+ ->EndObject()
+ ->EndObject();
+}
+
+TEST_P(ProtoStreamObjectWriterMapTest, AnyInMap) {
+ MapIn mm;
+ google::protobuf::DoubleValue d;
+ d.set_value(40.2);
+ (*mm.mutable_map_any())["foo"].PackFrom(d);
+ ow_->StartObject("")
+ ->StartObject("map_any")
+ ->StartObject("foo")
+ ->RenderString("@type", "type.googleapis.com/google.protobuf.DoubleValue")
+ ->RenderDouble("value", 40.2)
+ ->EndObject()
+ ->EndObject()
+ ->EndObject();
+ CheckOutput(mm);
+}
+
+class ProtoStreamObjectWriterAnyTest : public BaseProtoStreamObjectWriterTest {
+ protected:
+ ProtoStreamObjectWriterAnyTest() {
+ std::vector<const Descriptor*> descriptors;
+ descriptors.push_back(AnyOut::descriptor());
+ descriptors.push_back(Book::descriptor());
+ descriptors.push_back(google::protobuf::Any::descriptor());
+ descriptors.push_back(google::protobuf::DoubleValue::descriptor());
+ descriptors.push_back(google::protobuf::FieldMask::descriptor());
+ descriptors.push_back(google::protobuf::Int32Value::descriptor());
+ descriptors.push_back(google::protobuf::Struct::descriptor());
+ descriptors.push_back(google::protobuf::Timestamp::descriptor());
+ descriptors.push_back(google::protobuf::Value::descriptor());
+ ResetTypeInfo(descriptors);
+ }
+};
+
+INSTANTIATE_TEST_SUITE_P(DifferentTypeInfoSourceTest,
+ ProtoStreamObjectWriterAnyTest,
+ ::testing::Values(
+ testing::USE_TYPE_RESOLVER));
+
+TEST_P(ProtoStreamObjectWriterAnyTest, AnyRenderSuccess) {
+ AnyOut any;
+ google::protobuf::Any* any_type = any.mutable_any();
+ any_type->set_type_url("type.googleapis.com/google.protobuf.DoubleValue");
+ google::protobuf::DoubleValue d;
+ d.set_value(40.2);
+ any_type->set_value(d.SerializeAsString());
+
+ ow_->StartObject("")
+ ->StartObject("any")
+ ->RenderString("@type", "type.googleapis.com/google.protobuf.DoubleValue")
+ ->RenderDouble("value", 40.2)
+ ->EndObject()
+ ->EndObject();
+ CheckOutput(any);
+}
+
+TEST_P(ProtoStreamObjectWriterAnyTest, RecursiveAny) {
+ AnyOut out;
+ ::google::protobuf::Any* any = out.mutable_any();
+ any->set_type_url("type.googleapis.com/google.protobuf.Any");
+
+ ::google::protobuf::Any nested_any;
+ nested_any.set_type_url(
+ "type.googleapis.com/proto_util_converter.testing.AnyM");
+
+ AnyM m;
+ m.set_foo("foovalue");
+ nested_any.set_value(m.SerializeAsString());
+
+ any->set_value(nested_any.SerializeAsString());
+
+ ow_->StartObject("")
+ ->StartObject("any")
+ ->RenderString("@type", "type.googleapis.com/google.protobuf.Any")
+ ->StartObject("value")
+ ->RenderString("@type",
+ "type.googleapis.com/proto_util_converter.testing.AnyM")
+ ->RenderString("foo", "foovalue")
+ ->EndObject()
+ ->EndObject()
+ ->EndObject();
+ CheckOutput(out, 112);
+}
+
+TEST_P(ProtoStreamObjectWriterAnyTest, DoubleRecursiveAny) {
+ AnyOut out;
+ ::google::protobuf::Any* any = out.mutable_any();
+ any->set_type_url("type.googleapis.com/google.protobuf.Any");
+
+ ::google::protobuf::Any nested_any;
+ nested_any.set_type_url("type.googleapis.com/google.protobuf.Any");
+
+ ::google::protobuf::Any second_nested_any;
+ second_nested_any.set_type_url(
+ "type.googleapis.com/proto_util_converter.testing.AnyM");
+
+ AnyM m;
+ m.set_foo("foovalue");
+ second_nested_any.set_value(m.SerializeAsString());
+
+ nested_any.set_value(second_nested_any.SerializeAsString());
+ any->set_value(nested_any.SerializeAsString());
+
+ ow_->StartObject("")
+ ->StartObject("any")
+ ->RenderString("@type", "type.googleapis.com/google.protobuf.Any")
+ ->StartObject("value")
+ ->RenderString("@type", "type.googleapis.com/google.protobuf.Any")
+ ->StartObject("value")
+ ->RenderString("@type",
+ "type.googleapis.com/proto_util_converter.testing.AnyM")
+ ->RenderString("foo", "foovalue")
+ ->EndObject()
+ ->EndObject()
+ ->EndObject()
+ ->EndObject();
+ CheckOutput(out, 156);
+}
+
+TEST_P(ProtoStreamObjectWriterAnyTest, TypeUrlAtEnd) {
+ Book book;
+ book.set_title("C++");
+ book.set_length(1234);
+ book.set_content("Hello World!");
+
+ ::google::protobuf::Any any;
+ any.PackFrom(book);
+
+ ::google::protobuf::Any outer_any;
+ outer_any.PackFrom(any);
+
+ AnyOut out;
+ out.mutable_any()->PackFrom(outer_any);
+
+ // Put the @type field at the end of each Any message. Parsers should
+ // be able to accept that.
+ ow_->StartObject("")
+ ->StartObject("any")
+ ->StartObject("value")
+ ->StartObject("value")
+ ->RenderString("title", "C++")
+ ->RenderInt32("length", 1234)
+ ->RenderBytes("content", "Hello World!")
+ ->RenderString("@type",
+ "type.googleapis.com/proto_util_converter.testing.Book")
+ ->EndObject()
+ ->RenderString("@type", "type.googleapis.com/google.protobuf.Any")
+ ->EndObject()
+ ->RenderString("@type", "type.googleapis.com/google.protobuf.Any")
+ ->EndObject()
+ ->EndObject();
+ CheckOutput(out);
+}
+
+// Same as TypeUrlAtEnd, but use temporary string values to make sure we don't
+// mistakenly store StringPiece objects pointing to invalid memory.
+TEST_P(ProtoStreamObjectWriterAnyTest, TypeUrlAtEndWithTemporaryStrings) {
+ Book book;
+ book.set_title("C++");
+ book.set_length(1234);
+ book.set_content("Hello World!");
+
+ ::google::protobuf::Any any;
+ any.PackFrom(book);
+
+ ::google::protobuf::Any outer_any;
+ outer_any.PackFrom(any);
+
+ AnyOut out;
+ out.mutable_any()->PackFrom(outer_any);
+
+ std::string name, value;
+ // Put the @type field at the end of each Any message. Parsers should
+ // be able to accept that.
+ ow_->StartObject("")->StartObject("any");
+ {
+ ow_->StartObject("value");
+ {
+ ow_->StartObject("value");
+ {
+ name = "title";
+ value = "C++";
+ ow_->RenderString(name, value);
+ name = "length";
+ ow_->RenderInt32(name, 1234);
+ name = "content";
+ value = "Hello World!";
+ ow_->RenderBytes(name, value);
+ name = "@type";
+ value = "type.googleapis.com/proto_util_converter.testing.Book";
+ ow_->RenderString(name, value);
+ }
+ ow_->EndObject();
+
+ name = "@type";
+ value = "type.googleapis.com/google.protobuf.Any";
+ ow_->RenderString(name, value);
+ }
+ ow_->EndObject();
+
+ name = "@type";
+ value = "type.googleapis.com/google.protobuf.Any";
+ ow_->RenderString(name, value);
+ }
+ ow_->EndObject()->EndObject();
+ CheckOutput(out);
+}
+
+TEST_P(ProtoStreamObjectWriterAnyTest, EmptyAnyFromEmptyObject) {
+ AnyOut out;
+ out.mutable_any();
+
+ EXPECT_CALL(listener_, InvalidValue(_, _, _)).Times(0);
+
+ ow_->StartObject("")->StartObject("any")->EndObject()->EndObject();
+
+ CheckOutput(out, 2);
+}
+
+TEST_P(ProtoStreamObjectWriterAnyTest, AnyWithoutTypeUrlFails1) {
+ AnyOut any;
+
+ EXPECT_CALL(
+ listener_,
+ InvalidValue(_, StringPiece("Any"),
+ StringPiece("Missing @type for any field in "
+ "proto_util_converter.testing.AnyOut")));
+
+ ow_->StartObject("")
+ ->StartObject("any")
+ ->StartObject("another")
+ ->EndObject()
+ ->EndObject()
+ ->EndObject();
+ CheckOutput(any);
+}
+
+TEST_P(ProtoStreamObjectWriterAnyTest, AnyWithoutTypeUrlFails2) {
+ AnyOut any;
+
+ EXPECT_CALL(
+ listener_,
+ InvalidValue(_, StringPiece("Any"),
+ StringPiece("Missing @type for any field in "
+ "proto_util_converter.testing.AnyOut")));
+
+ ow_->StartObject("")
+ ->StartObject("any")
+ ->StartList("another")
+ ->EndObject()
+ ->EndObject()
+ ->EndObject();
+ CheckOutput(any);
+}
+
+TEST_P(ProtoStreamObjectWriterAnyTest, AnyWithoutTypeUrlFails3) {
+ AnyOut any;
+
+ EXPECT_CALL(
+ listener_,
+ InvalidValue(_, StringPiece("Any"),
+ StringPiece("Missing @type for any field in "
+ "proto_util_converter.testing.AnyOut")));
+
+ ow_->StartObject("")
+ ->StartObject("any")
+ ->RenderString("value", "somevalue")
+ ->EndObject()
+ ->EndObject();
+ CheckOutput(any);
+}
+
+TEST_P(ProtoStreamObjectWriterAnyTest, AnyWithInvalidTypeUrlFails) {
+ AnyOut any;
+
+ EXPECT_CALL(
+ listener_,
+ InvalidValue(
+ _, StringPiece("Any"),
+ StringPiece("Invalid type URL, type URLs must be of the form "
+ "'type.googleapis.com/<typename>', got: "
+ "type.other.com/some.Type")));
+
+ ow_->StartObject("")
+ ->StartObject("any")
+ ->RenderString("@type", "type.other.com/some.Type")
+ ->RenderDouble("value", 40.2)
+ ->EndObject()
+ ->EndObject();
+ CheckOutput(any);
+}
+
+TEST_P(ProtoStreamObjectWriterAnyTest, AnyWithUnknownTypeFails) {
+ AnyOut any;
+
+ EXPECT_CALL(listener_,
+ InvalidValue(_, StringPiece("Any"),
+ StringPiece(
+ "Invalid type URL, unknown type: some.Type")));
+ ow_->StartObject("")
+ ->StartObject("any")
+ ->RenderString("@type", "type.googleapis.com/some.Type")
+ ->RenderDouble("value", 40.2)
+ ->EndObject()
+ ->EndObject();
+ CheckOutput(any);
+}
+
+TEST_P(ProtoStreamObjectWriterAnyTest, AnyIncorrectInputTypeFails) {
+ AnyOut any;
+
+ EXPECT_CALL(
+ listener_,
+ InvalidValue(_,
+ StringPiece("type.googleapis.com/google.protobuf.Any"),
+ StringPiece("1")));
+ ow_->StartObject("")->RenderInt32("any", 1)->EndObject();
+ CheckOutput(any);
+}
+
+TEST_P(ProtoStreamObjectWriterAnyTest, AnyAcceptsNull) {
+ AnyOut any;
+
+ EXPECT_CALL(listener_, InvalidValue(_, _, _)).Times(0);
+ ow_->StartObject("")->RenderNull("any")->EndObject();
+ CheckOutput(any);
+}
+
+TEST_P(ProtoStreamObjectWriterAnyTest, AnyWellKnownTypeErrorTest) {
+ EXPECT_CALL(listener_, InvalidValue(_, StringPiece("Any"),
+ StringPiece("Invalid time format: ")));
+
+ AnyOut any;
+ google::protobuf::Any* any_type = any.mutable_any();
+ any_type->set_type_url("type.googleapis.com/google.protobuf.Timestamp");
+
+ ow_->StartObject("")
+ ->StartObject("any")
+ ->RenderString("@type", "type.googleapis.com/google.protobuf.Timestamp")
+ ->RenderString("value", "")
+ ->EndObject()
+ ->EndObject();
+ CheckOutput(any);
+}
+
+// Test the following case:
+//
+// {
+// "any": {
+// "@type": "type.googleapis.com/google.protobuf.Value",
+// "value": "abc"
+// }
+// }
+TEST_P(ProtoStreamObjectWriterAnyTest, AnyWithNestedPrimitiveValue) {
+ AnyOut out;
+ ::google::protobuf::Any* any = out.mutable_any();
+
+ ::google::protobuf::Value value;
+ value.set_string_value("abc");
+ any->PackFrom(value);
+
+ ow_->StartObject("")
+ ->StartObject("any")
+ ->RenderString("@type", "type.googleapis.com/google.protobuf.Value")
+ ->RenderString("value", "abc")
+ ->EndObject()
+ ->EndObject();
+ CheckOutput(out);
+}
+
+// Test the following case:
+//
+// {
+// "any": {
+// "@type": "type.googleapis.com/google.protobuf.Value",
+// "value": {
+// "foo": "abc"
+// }
+// }
+// }
+TEST_P(ProtoStreamObjectWriterAnyTest, AnyWithNestedObjectValue) {
+ AnyOut out;
+ ::google::protobuf::Any* any = out.mutable_any();
+
+ ::google::protobuf::Value value;
+ (*value.mutable_struct_value()->mutable_fields())["foo"].set_string_value(
+ "abc");
+ any->PackFrom(value);
+
+ ow_->StartObject("")
+ ->StartObject("any")
+ ->RenderString("@type", "type.googleapis.com/google.protobuf.Value")
+ ->StartObject("value")
+ ->RenderString("foo", "abc")
+ ->EndObject()
+ ->EndObject()
+ ->EndObject();
+ CheckOutput(out);
+}
+
+// Test the following case:
+//
+// {
+// "any": {
+// "@type": "type.googleapis.com/google.protobuf.Value",
+// "value": ["hello"],
+// }
+// }
+TEST_P(ProtoStreamObjectWriterAnyTest, AnyWithNestedArrayValue) {
+ AnyOut out;
+ ::google::protobuf::Any* any = out.mutable_any();
+
+ ::google::protobuf::Value value;
+ value.mutable_list_value()->add_values()->set_string_value("hello");
+ any->PackFrom(value);
+
+ ow_->StartObject("")
+ ->StartObject("any")
+ ->RenderString("@type", "type.googleapis.com/google.protobuf.Value")
+ ->StartList("value")
+ ->RenderString("", "hello")
+ ->EndList()
+ ->EndObject()
+ ->EndObject()
+ ->EndObject();
+ CheckOutput(out);
+}
+
+// Test the following case:
+//
+// {
+// "any": {
+// "@type": "type.googleapis.com/google.protobuf.Value",
+// "not_value": ""
+// }
+// }
+TEST_P(ProtoStreamObjectWriterAnyTest,
+ AnyWellKnownTypesNoValueFieldForPrimitive) {
+ EXPECT_CALL(
+ listener_,
+ InvalidValue(
+ _, StringPiece("Any"),
+ StringPiece("Expect a \"value\" field for well-known types.")));
+ AnyOut any;
+ google::protobuf::Any* any_type = any.mutable_any();
+ any_type->set_type_url("type.googleapis.com/google.protobuf.Value");
+
+ ow_->StartObject("")
+ ->StartObject("any")
+ ->RenderString("@type", "type.googleapis.com/google.protobuf.Value")
+ ->RenderString("not_value", "")
+ ->EndObject()
+ ->EndObject();
+ CheckOutput(any);
+}
+
+// Test the following case:
+//
+// {
+// "any": {
+// "@type": "type.googleapis.com/google.protobuf.Value",
+// "not_value": {}
+// }
+// }
+TEST_P(ProtoStreamObjectWriterAnyTest, AnyWellKnownTypesNoValueFieldForObject) {
+ EXPECT_CALL(
+ listener_,
+ InvalidValue(
+ _, StringPiece("Any"),
+ StringPiece("Expect a \"value\" field for well-known types.")));
+ AnyOut any;
+ google::protobuf::Any* any_type = any.mutable_any();
+ any_type->set_type_url("type.googleapis.com/google.protobuf.Value");
+
+ ow_->StartObject("")
+ ->StartObject("any")
+ ->RenderString("@type", "type.googleapis.com/google.protobuf.Value")
+ ->StartObject("not_value")
+ ->EndObject()
+ ->EndObject()
+ ->EndObject();
+ CheckOutput(any);
+}
+
+// Test the following case:
+//
+// {
+// "any": {
+// "@type": "type.googleapis.com/google.protobuf.Value",
+// "not_value": [],
+// }
+// }
+TEST_P(ProtoStreamObjectWriterAnyTest, AnyWellKnownTypesNoValueFieldForArray) {
+ EXPECT_CALL(
+ listener_,
+ InvalidValue(
+ _, StringPiece("Any"),
+ StringPiece("Expect a \"value\" field for well-known types.")));
+ AnyOut any;
+ google::protobuf::Any* any_type = any.mutable_any();
+ any_type->set_type_url("type.googleapis.com/google.protobuf.Value");
+
+ ow_->StartObject("")
+ ->StartObject("any")
+ ->RenderString("@type", "type.googleapis.com/google.protobuf.Value")
+ ->StartList("not_value")
+ ->EndList()
+ ->EndObject()
+ ->EndObject()
+ ->EndObject();
+ CheckOutput(any);
+}
+
+// Test the following case:
+//
+// {
+// "any": {
+// "@type": "type.googleapis.com/google.protobuf.Struct",
+// "value": "",
+// }
+// }
+TEST_P(ProtoStreamObjectWriterAnyTest, AnyWellKnownTypesExpectObjectForStruct) {
+ EXPECT_CALL(listener_,
+ InvalidValue(_, StringPiece("Any"),
+ StringPiece("Expect a JSON object.")));
+ AnyOut any;
+ google::protobuf::Any* any_type = any.mutable_any();
+ any_type->set_type_url("type.googleapis.com/google.protobuf.Struct");
+
+ ow_->StartObject("")
+ ->StartObject("any")
+ ->RenderString("@type", "type.googleapis.com/google.protobuf.Struct")
+ ->RenderString("value", "")
+ ->EndObject()
+ ->EndObject();
+ CheckOutput(any);
+}
+
+// Test the following case:
+//
+// {
+// "any": {
+// "@type": "type.googleapis.com/google.protobuf.Any",
+// "value": "",
+// }
+// }
+TEST_P(ProtoStreamObjectWriterAnyTest, AnyWellKnownTypesExpectObjectForAny) {
+ EXPECT_CALL(listener_,
+ InvalidValue(_, StringPiece("Any"),
+ StringPiece("Expect a JSON object.")));
+ AnyOut any;
+ google::protobuf::Any* any_type = any.mutable_any();
+ any_type->set_type_url("type.googleapis.com/google.protobuf.Any");
+
+ ow_->StartObject("")
+ ->StartObject("any")
+ ->RenderString("@type", "type.googleapis.com/google.protobuf.Any")
+ ->RenderString("value", "")
+ ->EndObject()
+ ->EndObject();
+ CheckOutput(any);
+}
+
+// {
+// "any": {
+// "@type": "type.googleapis.com/google.protobuf.Any",
+// "value": null
+// }
+// }
+TEST_P(ProtoStreamObjectWriterAnyTest, AnyInAnyAcceptsNull) {
+ AnyOut out;
+ google::protobuf::Any empty;
+ out.mutable_any()->PackFrom(empty);
+
+ EXPECT_CALL(listener_, InvalidValue(_, _, _)).Times(0);
+ ow_->StartObject("")
+ ->StartObject("any")
+ ->RenderString("@type", "type.googleapis.com/google.protobuf.Any")
+ ->RenderNull("value")
+ ->EndObject()
+ ->EndObject();
+ CheckOutput(out);
+}
+
+// {
+// "any": {
+// "@type": "type.googleapis.com/google.protobuf.Timestamp",
+// "value": null
+// }
+// }
+TEST_P(ProtoStreamObjectWriterAnyTest, TimestampInAnyAcceptsNull) {
+ AnyOut out;
+ google::protobuf::Timestamp empty;
+ out.mutable_any()->PackFrom(empty);
+
+ EXPECT_CALL(listener_, InvalidValue(_, _, _)).Times(0);
+ ow_->StartObject("")
+ ->StartObject("any")
+ ->RenderString("@type", "type.googleapis.com/google.protobuf.Timestamp")
+ ->RenderNull("value")
+ ->EndObject()
+ ->EndObject();
+ CheckOutput(out);
+}
+
+// {
+// "any": {
+// "@type": "type.googleapis.com/google.protobuf.Duration",
+// "value": null
+// }
+// }
+TEST_P(ProtoStreamObjectWriterAnyTest, DurationInAnyAcceptsNull) {
+ AnyOut out;
+ google::protobuf::Duration empty;
+ out.mutable_any()->PackFrom(empty);
+
+ EXPECT_CALL(listener_, InvalidValue(_, _, _)).Times(0);
+ ow_->StartObject("")
+ ->StartObject("any")
+ ->RenderString("@type", "type.googleapis.com/google.protobuf.Duration")
+ ->RenderNull("value")
+ ->EndObject()
+ ->EndObject();
+ CheckOutput(out);
+}
+
+// {
+// "any": {
+// "@type": "type.googleapis.com/google.protobuf.FieldMask",
+// "value": null
+// }
+// }
+TEST_P(ProtoStreamObjectWriterAnyTest, FieldMaskInAnyAcceptsNull) {
+ AnyOut out;
+ google::protobuf::FieldMask empty;
+ out.mutable_any()->PackFrom(empty);
+
+ EXPECT_CALL(listener_, InvalidValue(_, _, _)).Times(0);
+ ow_->StartObject("")
+ ->StartObject("any")
+ ->RenderString("@type", "type.googleapis.com/google.protobuf.FieldMask")
+ ->RenderNull("value")
+ ->EndObject()
+ ->EndObject();
+ CheckOutput(out);
+}
+
+// {
+// "any": {
+// "@type": "type.googleapis.com/google.protobuf.Int32Value",
+// "value": null
+// }
+// }
+TEST_P(ProtoStreamObjectWriterAnyTest, WrapperInAnyAcceptsNull) {
+ AnyOut out;
+ google::protobuf::Int32Value empty;
+ out.mutable_any()->PackFrom(empty);
+
+ EXPECT_CALL(listener_, InvalidValue(_, _, _)).Times(0);
+ ow_->StartObject("")
+ ->StartObject("any")
+ ->RenderString("@type", "type.googleapis.com/google.protobuf.Int32Value")
+ ->RenderNull("value")
+ ->EndObject()
+ ->EndObject();
+ CheckOutput(out);
+}
+
+class ProtoStreamObjectWriterFieldMaskTest
+ : public BaseProtoStreamObjectWriterTest {
+ protected:
+ ProtoStreamObjectWriterFieldMaskTest() {
+ std::vector<const Descriptor*> descriptors;
+ descriptors.push_back(FieldMaskTest::descriptor());
+ descriptors.push_back(google::protobuf::FieldMask::descriptor());
+ ResetTypeInfo(descriptors);
+ }
+};
+
+INSTANTIATE_TEST_SUITE_P(DifferentTypeInfoSourceTest,
+ ProtoStreamObjectWriterFieldMaskTest,
+ ::testing::Values(
+ testing::USE_TYPE_RESOLVER));
+
+TEST_P(ProtoStreamObjectWriterFieldMaskTest, SimpleFieldMaskTest) {
+ FieldMaskTest expected;
+ expected.set_id("1");
+ expected.mutable_single_mask()->add_paths("path1");
+
+ ow_->StartObject("");
+ ow_->RenderString("id", "1");
+ ow_->RenderString("single_mask", "path1");
+ ow_->EndObject();
+
+ CheckOutput(expected);
+}
+
+TEST_P(ProtoStreamObjectWriterFieldMaskTest, MultipleMasksInCompactForm) {
+ FieldMaskTest expected;
+ expected.set_id("1");
+ expected.mutable_single_mask()->add_paths("camel_case1");
+ expected.mutable_single_mask()->add_paths("camel_case2");
+ expected.mutable_single_mask()->add_paths("camel_case3");
+
+ ow_->StartObject("");
+ ow_->RenderString("id", "1");
+ ow_->RenderString("single_mask", "camelCase1,camelCase2,camelCase3");
+ ow_->EndObject();
+
+ CheckOutput(expected);
+}
+
+TEST_P(ProtoStreamObjectWriterFieldMaskTest, RepeatedFieldMaskTest) {
+ FieldMaskTest expected;
+ expected.set_id("1");
+ google::protobuf::FieldMask* mask = expected.add_repeated_mask();
+ mask->add_paths("field1");
+ mask->add_paths("field2");
+ expected.add_repeated_mask()->add_paths("field3");
+
+ ow_->StartObject("");
+ ow_->RenderString("id", "1");
+ ow_->StartList("repeated_mask");
+ ow_->RenderString("", "field1,field2");
+ ow_->RenderString("", "field3");
+ ow_->EndList();
+ ow_->EndObject();
+
+ CheckOutput(expected);
+}
+
+TEST_P(ProtoStreamObjectWriterFieldMaskTest, EmptyFieldMaskTest) {
+ FieldMaskTest expected;
+ expected.set_id("1");
+
+ ow_->StartObject("");
+ ow_->RenderString("id", "1");
+ ow_->RenderString("single_mask", "");
+ ow_->EndObject();
+
+ CheckOutput(expected);
+}
+
+TEST_P(ProtoStreamObjectWriterFieldMaskTest, MaskUsingApiaryStyleShouldWork) {
+ FieldMaskTest expected;
+ expected.set_id("1");
+
+ ow_->StartObject("");
+ ow_->RenderString("id", "1");
+ // Case1
+ ow_->RenderString("single_mask",
+ "outerField(camelCase1,camelCase2,camelCase3)");
+ expected.mutable_single_mask()->add_paths("outer_field.camel_case1");
+ expected.mutable_single_mask()->add_paths("outer_field.camel_case2");
+ expected.mutable_single_mask()->add_paths("outer_field.camel_case3");
+
+ ow_->StartList("repeated_mask");
+
+ ow_->RenderString("", "a(field1,field2)");
+ google::protobuf::FieldMask* mask = expected.add_repeated_mask();
+ mask->add_paths("a.field1");
+ mask->add_paths("a.field2");
+
+ ow_->RenderString("", "a(field3)");
+ mask = expected.add_repeated_mask();
+ mask->add_paths("a.field3");
+
+ ow_->RenderString("", "a()");
+ expected.add_repeated_mask();
+
+ ow_->RenderString("", "a(,)");
+ expected.add_repeated_mask();
+
+ ow_->RenderString("", "a(field1(field2(field3)))");
+ mask = expected.add_repeated_mask();
+ mask->add_paths("a.field1.field2.field3");
+
+ ow_->RenderString("", "a(field1(field2(field3,field4),field5),field6)");
+ mask = expected.add_repeated_mask();
+ mask->add_paths("a.field1.field2.field3");
+ mask->add_paths("a.field1.field2.field4");
+ mask->add_paths("a.field1.field5");
+ mask->add_paths("a.field6");
+
+ ow_->RenderString("", "a(id,field1(id,field2(field3,field4),field5),field6)");
+ mask = expected.add_repeated_mask();
+ mask->add_paths("a.id");
+ mask->add_paths("a.field1.id");
+ mask->add_paths("a.field1.field2.field3");
+ mask->add_paths("a.field1.field2.field4");
+ mask->add_paths("a.field1.field5");
+ mask->add_paths("a.field6");
+
+ ow_->RenderString("", "a(((field3,field4)))");
+ mask = expected.add_repeated_mask();
+ mask->add_paths("a.field3");
+ mask->add_paths("a.field4");
+
+ ow_->EndList();
+ ow_->EndObject();
+
+ CheckOutput(expected);
+}
+
+TEST_P(ProtoStreamObjectWriterFieldMaskTest, MoreCloseThanOpenParentheses) {
+ EXPECT_CALL(
+ listener_,
+ InvalidValue(
+ _, StringPiece("type.googleapis.com/google.protobuf.FieldMask"),
+ StringPiece("Field 'single_mask', Invalid FieldMask 'a(b,c))'. "
+ "Cannot find matching '(' for all ')'.")));
+
+ ow_->StartObject("");
+ ow_->RenderString("id", "1");
+ ow_->RenderString("single_mask", "a(b,c))");
+ ow_->EndObject();
+}
+
+TEST_P(ProtoStreamObjectWriterFieldMaskTest, MoreOpenThanCloseParentheses) {
+ EXPECT_CALL(
+ listener_,
+ InvalidValue(
+ _, StringPiece("type.googleapis.com/google.protobuf.FieldMask"),
+ StringPiece(
+ "Field 'single_mask', Invalid FieldMask 'a(((b,c)'. Cannot "
+ "find matching ')' for all '('.")));
+
+ ow_->StartObject("");
+ ow_->RenderString("id", "1");
+ ow_->RenderString("single_mask", "a(((b,c)");
+ ow_->EndObject();
+}
+
+TEST_P(ProtoStreamObjectWriterFieldMaskTest, PathWithMapKeyShouldWork) {
+ FieldMaskTest expected;
+ expected.mutable_single_mask()->add_paths("path.to.map[\"key1\"]");
+ expected.mutable_single_mask()->add_paths(
+ "path.to.map[\"e\\\"[]][scape\\\"\"]");
+ expected.mutable_single_mask()->add_paths("path.to.map[\"key2\"]");
+
+ ow_->StartObject("");
+ ow_->RenderString("single_mask",
+ "path.to.map[\"key1\"],path.to.map[\"e\\\"[]][scape\\\"\"],"
+ "path.to.map[\"key2\"]");
+ ow_->EndObject();
+
+ CheckOutput(expected);
+}
+
+TEST_P(ProtoStreamObjectWriterFieldMaskTest,
+ MapKeyMustBeAtTheEndOfAPathSegment) {
+ EXPECT_CALL(
+ listener_,
+ InvalidValue(
+ _, StringPiece("type.googleapis.com/google.protobuf.FieldMask"),
+ StringPiece(
+ "Field 'single_mask', Invalid FieldMask "
+ "'path.to.map[\"key1\"]a,path.to.map[\"key2\"]'. "
+ "Map keys should be at the end of a path segment.")));
+
+ ow_->StartObject("");
+ ow_->RenderString("single_mask",
+ "path.to.map[\"key1\"]a,path.to.map[\"key2\"]");
+ ow_->EndObject();
+}
+
+TEST_P(ProtoStreamObjectWriterFieldMaskTest, MapKeyMustEnd) {
+ EXPECT_CALL(
+ listener_,
+ InvalidValue(
+ _, StringPiece("type.googleapis.com/google.protobuf.FieldMask"),
+ StringPiece("Field 'single_mask', Invalid FieldMask "
+ "'path.to.map[\"key1\"'. Map keys should be "
+ "represented as [\"some_key\"].")));
+
+ ow_->StartObject("");
+ ow_->RenderString("single_mask", "path.to.map[\"key1\"");
+ ow_->EndObject();
+}
+
+TEST_P(ProtoStreamObjectWriterFieldMaskTest, MapKeyMustBeEscapedCorrectly) {
+ EXPECT_CALL(
+ listener_,
+ InvalidValue(
+ _, StringPiece("type.googleapis.com/google.protobuf.FieldMask"),
+ StringPiece("Field 'single_mask', Invalid FieldMask "
+ "'path.to.map[\"ke\"y1\"]'. Map keys should be "
+ "represented as [\"some_key\"].")));
+
+ ow_->StartObject("");
+ ow_->RenderString("single_mask", "path.to.map[\"ke\"y1\"]");
+ ow_->EndObject();
+}
+
+TEST_P(ProtoStreamObjectWriterFieldMaskTest, MapKeyCanContainAnyChars) {
+ FieldMaskTest expected;
+ expected.mutable_single_mask()->add_paths(
+ // \xE5\xAD\x99 is the UTF-8 byte sequence for chinese character å­™.
+ // We cannot embed non-ASCII characters in the code directly because
+ // some windows compilers will try to interpret them using the system's
+ // current encoding and end up with invalid UTF-8 byte sequence.
+ "path.to.map[\"(),[],\\\"'!@#$%^&*123_|War\xE5\xAD\x99,./?><\\\\\"]");
+ expected.mutable_single_mask()->add_paths("path.to.map[\"key2\"]");
+
+ ow_->StartObject("");
+ ow_->RenderString(
+ "single_mask",
+ "path.to.map[\"(),[],\\\"'!@#$%^&*123_|War\xE5\xAD\x99,./?><\\\\\"],"
+ "path.to.map[\"key2\"]");
+ ow_->EndObject();
+
+ CheckOutput(expected);
+}
+
+TEST_P(ProtoStreamObjectWriterFieldMaskTest, FieldMaskAcceptsNull) {
+ FieldMaskTest expected;
+ EXPECT_CALL(listener_, InvalidValue(_, _, _)).Times(0);
+ ow_->StartObject("")->RenderNull("single_mask")->EndObject();
+ CheckOutput(expected);
+}
+
+class ProtoStreamObjectWriterWrappersTest
+ : public BaseProtoStreamObjectWriterTest {
+ protected:
+ ProtoStreamObjectWriterWrappersTest() {
+ std::vector<const Descriptor*> descriptors;
+ descriptors.push_back(Int32Wrapper::descriptor());
+ descriptors.push_back(google::protobuf::Int32Value::descriptor());
+ ResetTypeInfo(descriptors);
+ }
+};
+
+INSTANTIATE_TEST_SUITE_P(DifferentTypeInfoSourceTest,
+ ProtoStreamObjectWriterWrappersTest,
+ ::testing::Values(
+ testing::USE_TYPE_RESOLVER));
+
+TEST_P(ProtoStreamObjectWriterWrappersTest, WrapperAcceptsNull) {
+ Int32Wrapper wrapper;
+ EXPECT_CALL(listener_, InvalidName(_, _, _)).Times(0);
+ ow_->StartObject("")->RenderNull("int32")->EndObject();
+ CheckOutput(wrapper);
+}
+
+class ProtoStreamObjectWriterOneOfsTest
+ : public BaseProtoStreamObjectWriterTest {
+ protected:
+ ProtoStreamObjectWriterOneOfsTest() {
+ std::vector<const Descriptor*> descriptors;
+ descriptors.push_back(OneOfsRequest::descriptor());
+ descriptors.push_back(google::protobuf::Struct::descriptor());
+ ResetTypeInfo(descriptors);
+ }
+};
+
+INSTANTIATE_TEST_SUITE_P(DifferentTypeInfoSourceTest,
+ ProtoStreamObjectWriterOneOfsTest,
+ ::testing::Values(
+ testing::USE_TYPE_RESOLVER));
+
+TEST_P(ProtoStreamObjectWriterOneOfsTest,
+ MultipleOneofsFailForPrimitiveTypesTest) {
+ EXPECT_CALL(
+ listener_,
+ InvalidValue(
+ _, StringPiece("oneof"),
+ StringPiece(
+ "oneof field 'data' is already set. Cannot set 'intData'")));
+
+ ow_->StartObject("");
+ ow_->RenderString("strData", "blah");
+ ow_->RenderString("intData", "123");
+ ow_->EndObject();
+}
+
+TEST_P(ProtoStreamObjectWriterOneOfsTest,
+ MultipleOneofsFailForMessageTypesPrimitiveFirstTest) {
+ // Test for setting primitive oneof field first and then message field.
+ EXPECT_CALL(listener_, InvalidValue(_, StringPiece("oneof"),
+ StringPiece(
+ "oneof field 'data' is already set. "
+ "Cannot set 'messageData'")));
+
+ // JSON: { "strData": "blah", "messageData": { "dataValue": 123 } }
+ ow_->StartObject("");
+ ow_->RenderString("strData", "blah");
+ ow_->StartObject("messageData");
+ ow_->RenderInt32("dataValue", 123);
+ ow_->EndObject();
+ ow_->EndObject();
+}
+
+TEST_P(ProtoStreamObjectWriterOneOfsTest,
+ MultipleOneofsFailForMessageTypesMessageFirstTest) {
+ // Test for setting message oneof field first and then primitive field.
+ EXPECT_CALL(listener_, InvalidValue(_, StringPiece("oneof"),
+ StringPiece(
+ "oneof field 'data' is already set. "
+ "Cannot set 'strData'")));
+
+ // JSON: { "messageData": { "dataValue": 123 }, "strData": "blah" }
+ ow_->StartObject("");
+ ow_->StartObject("messageData");
+ ow_->RenderInt32("dataValue", 123);
+ ow_->EndObject();
+ ow_->RenderString("strData", "blah");
+ ow_->EndObject();
+}
+
+TEST_P(ProtoStreamObjectWriterOneOfsTest,
+ MultipleOneofsFailForStructTypesPrimitiveFirstTest) {
+ EXPECT_CALL(listener_, InvalidValue(_, StringPiece("oneof"),
+ StringPiece(
+ "oneof field 'data' is already set. "
+ "Cannot set 'structData'")));
+
+ // JSON: { "strData": "blah", "structData": { "a": "b" } }
+ ow_->StartObject("");
+ ow_->RenderString("strData", "blah");
+ ow_->StartObject("structData");
+ ow_->RenderString("a", "b");
+ ow_->EndObject();
+ ow_->EndObject();
+}
+
+TEST_P(ProtoStreamObjectWriterOneOfsTest,
+ MultipleOneofsFailForStructTypesStructFirstTest) {
+ EXPECT_CALL(listener_, InvalidValue(_, StringPiece("oneof"),
+ StringPiece(
+ "oneof field 'data' is already set. "
+ "Cannot set 'strData'")));
+
+ // JSON: { "structData": { "a": "b" }, "strData": "blah" }
+ ow_->StartObject("");
+ ow_->StartObject("structData");
+ ow_->RenderString("a", "b");
+ ow_->EndObject();
+ ow_->RenderString("strData", "blah");
+ ow_->EndObject();
+}
+
+TEST_P(ProtoStreamObjectWriterOneOfsTest,
+ MultipleOneofsFailForStructValueTypesTest) {
+ EXPECT_CALL(listener_, InvalidValue(_, StringPiece("oneof"),
+ StringPiece(
+ "oneof field 'data' is already set. "
+ "Cannot set 'valueData'")));
+
+ // JSON: { "messageData": { "dataValue": 123 }, "valueData": { "a": "b" } }
+ ow_->StartObject("");
+ ow_->StartObject("messageData");
+ ow_->RenderInt32("dataValue", 123);
+ ow_->EndObject();
+ ow_->StartObject("valueData");
+ ow_->RenderString("a", "b");
+ ow_->EndObject();
+ ow_->EndObject();
+}
+
+TEST_P(ProtoStreamObjectWriterOneOfsTest,
+ MultipleOneofsFailForWellKnownTypesPrimitiveFirstTest) {
+ EXPECT_CALL(listener_, InvalidValue(_, StringPiece("oneof"),
+ StringPiece(
+ "oneof field 'data' is already set. "
+ "Cannot set 'tsData'")));
+
+ // JSON: { "intData": 123, "tsData": "1970-01-02T01:00:00.000Z" }
+ ow_->StartObject("");
+ ow_->RenderInt32("intData", 123);
+ ow_->RenderString("tsData", "1970-01-02T01:00:00.000Z");
+ ow_->EndObject();
+}
+
+TEST_P(ProtoStreamObjectWriterOneOfsTest,
+ MultipleOneofsFailForWellKnownTypesWktFirstTest) {
+ EXPECT_CALL(listener_, InvalidValue(_, StringPiece("oneof"),
+ StringPiece(
+ "oneof field 'data' is already set. "
+ "Cannot set 'intData'")));
+
+ // JSON: { "tsData": "1970-01-02T01:00:00.000Z", "intData": 123 }
+ ow_->StartObject("");
+ ow_->RenderString("tsData", "1970-01-02T01:00:00.000Z");
+ ow_->RenderInt32("intData", 123);
+ ow_->EndObject();
+}
+
+TEST_P(ProtoStreamObjectWriterOneOfsTest,
+ MultipleOneofsFailForWellKnownTypesAndMessageTest) {
+ EXPECT_CALL(listener_, InvalidValue(_, StringPiece("oneof"),
+ StringPiece(
+ "oneof field 'data' is already set. "
+ "Cannot set 'messageData'")));
+
+ // JSON: { "tsData": "1970-01-02T01:00:00.000Z",
+ // "messageData": { "dataValue": 123 } }
+ ow_->StartObject("");
+ ow_->RenderString("tsData", "1970-01-02T01:00:00.000Z");
+ ow_->StartObject("messageData");
+ ow_->RenderInt32("dataValue", 123);
+ ow_->EndObject();
+ ow_->EndObject();
+}
+
+TEST_P(ProtoStreamObjectWriterOneOfsTest,
+ MultipleOneofsFailForOneofWithinAnyTest) {
+ EXPECT_CALL(listener_, InvalidValue(_, StringPiece("oneof"),
+ StringPiece(
+ "oneof field 'data' is already set. "
+ "Cannot set 'intData'")));
+
+ // JSON:
+ // { "anyData":
+ // { "@type":
+ // "type.googleapis.com/proto_util_converter.testing.oneofs.OneOfsRequest",
+ // "strData": "blah",
+ // "intData": 123
+ // }
+ // }
+ ow_->StartObject("");
+ ow_->StartObject("anyData");
+ ow_->RenderString(
+ "@type",
+ "type.googleapis.com/proto_util_converter.testing.oneofs.OneOfsRequest");
+ ow_->RenderString("strData", "blah");
+ ow_->RenderInt32("intData", 123);
+ ow_->EndObject();
+ ow_->EndObject();
+}
+
+} // namespace converter
+} // namespace util
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/util/internal/structured_objectwriter.h b/NorthstarDedicatedTest/include/protobuf/util/internal/structured_objectwriter.h
new file mode 100644
index 00000000..88fa187e
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/util/internal/structured_objectwriter.h
@@ -0,0 +1,120 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef GOOGLE_PROTOBUF_UTIL_CONVERTER_STRUCTURED_OBJECTWRITER_H__
+#define GOOGLE_PROTOBUF_UTIL_CONVERTER_STRUCTURED_OBJECTWRITER_H__
+
+#include <memory>
+
+#include <stubs/casts.h>
+#include <stubs/common.h>
+#include <util/internal/object_writer.h>
+
+#include <port_def.inc>
+
+namespace google {
+namespace protobuf {
+namespace util {
+namespace converter {
+
+// An StructuredObjectWriter is an ObjectWriter for writing
+// tree-structured data in a stream of events representing objects
+// and collections. Implementation of this interface can be used to
+// write an object stream to an in-memory structure, protobufs,
+// JSON, XML, or any other output format desired. The ObjectSource
+// interface is typically used as the source of an object stream.
+//
+// See JsonObjectWriter for a sample implementation of
+// StructuredObjectWriter and its use.
+//
+// Derived classes could be thread-unsafe.
+class PROTOBUF_EXPORT StructuredObjectWriter : public ObjectWriter {
+ public:
+ virtual ~StructuredObjectWriter() {}
+
+ protected:
+ // A base element class for subclasses to extend, makes tracking state easier.
+ //
+ // StructuredObjectWriter behaves as a visitor. BaseElement represents a node
+ // in the input tree. Implementation of StructuredObjectWriter should also
+ // extend BaseElement to keep track of the location in the input tree.
+ class PROTOBUF_EXPORT BaseElement {
+ public:
+ // Takes ownership of the parent Element.
+ explicit BaseElement(BaseElement* parent)
+ : parent_(parent),
+ level_(parent == nullptr ? 0 : parent->level() + 1) {}
+ virtual ~BaseElement() {}
+
+ // Releases ownership of the parent and returns a pointer to it.
+ template <typename ElementType>
+ ElementType* pop() {
+ return down_cast<ElementType*>(parent_.release());
+ }
+
+ // Returns true if this element is the root.
+ bool is_root() const { return parent_ == nullptr; }
+
+ // Returns the number of hops from this element to the root element.
+ int level() const { return level_; }
+
+ protected:
+ // Returns pointer to parent element without releasing ownership.
+ virtual BaseElement* parent() const { return parent_.get(); }
+
+ private:
+ // Pointer to the parent Element.
+ std::unique_ptr<BaseElement> parent_;
+
+ // Number of hops to the root Element.
+ // The root Element has nullptr parent_ and a level_ of 0.
+ const int level_;
+
+ GOOGLE_DISALLOW_IMPLICIT_CONSTRUCTORS(BaseElement);
+ };
+
+ StructuredObjectWriter() {}
+
+ // Returns the current element. Used for indentation and name overrides.
+ virtual BaseElement* element() = 0;
+
+ private:
+ // Do not add any data members to this class.
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(StructuredObjectWriter);
+};
+
+} // namespace converter
+} // namespace util
+} // namespace protobuf
+} // namespace google
+
+#include <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_UTIL_CONVERTER_STRUCTURED_OBJECTWRITER_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/util/internal/testdata/anys.proto b/NorthstarDedicatedTest/include/protobuf/util/internal/testdata/anys.proto
new file mode 100644
index 00000000..b6fc3f6c
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/util/internal/testdata/anys.proto
@@ -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.
+
+syntax = "proto3";
+
+package proto_util_converter.testing;
+
+import "google/protobuf/any.proto";
+import "google/protobuf/duration.proto";
+import "google/protobuf/empty.proto";
+import "google/protobuf/struct.proto";
+import "google/protobuf/timestamp.proto";
+import "google/protobuf/wrappers.proto";
+
+// Top-level test cases proto used by MarshallingTest. See description
+// at the top of the class MarshallingTest for details on how to write
+// test cases.
+message AnyTestCases {
+ AnyWrapper empty_any = 1;
+ AnyWrapper type_only_any = 2;
+ AnyWrapper wrapper_any = 3;
+ AnyWrapper any_with_timestamp_value = 4;
+ AnyWrapper any_with_duration_value = 5;
+ AnyWrapper any_with_struct_value = 6;
+ AnyWrapper recursive_any = 7;
+ AnyWrapper any_with_message_value = 8;
+ AnyWrapper any_with_nested_message = 9;
+ AnyWrapper any_with_message_with_wrapper_type = 10;
+ AnyWrapper any_with_message_with_timestamp = 11;
+ AnyWrapper any_with_message_containing_map = 12;
+ AnyWrapper any_with_message_containing_struct = 13;
+ AnyWrapper any_with_message_containing_repeated_message = 14;
+ AnyWrapper recursive_any_with_type_field_at_end = 15;
+ AnyWrapper repeated_any = 16;
+ AnyWrapper empty_any_with_null_type_url = 17;
+ AnyWrapper any_with_empty = 18;
+ AnyWrapper any_with_default_timestamp = 19;
+
+ google.protobuf.Any top_level_any = 50;
+ google.protobuf.Any top_level_any_with_type_field_at_end = 51;
+ google.protobuf.Any top_level_any_with_pivot_one = 52;
+ google.protobuf.Any top_level_any_with_pivot_two = 53;
+ google.protobuf.Any top_level_any_unordered = 54;
+}
+
+message AnyWrapper {
+ google.protobuf.Any any = 1;
+}
+
+// Hack to make sure the types we put into the any are included in the types.
+// Real solution is to add these types to the service config.
+message Imports {
+ google.protobuf.DoubleValue dbl = 1;
+ google.protobuf.Struct struct = 2;
+ google.protobuf.Timestamp timestamp = 3;
+ google.protobuf.Duration duration = 4;
+ google.protobuf.Int32Value i32 = 5;
+ google.protobuf.Empty empty = 6;
+ Data data = 100;
+}
+
+message Data {
+ int32 attr = 1;
+ string str = 2;
+ repeated string msgs = 3;
+ Data nested_data = 4;
+ google.protobuf.Int32Value int_wrapper = 5;
+ google.protobuf.Timestamp time = 6;
+ map<string, string> map_data = 7;
+ google.protobuf.Struct struct_data = 8;
+ repeated Data repeated_data = 9;
+ repeated google.protobuf.Any repeated_any = 10;
+}
+
+service AnyTestService {
+ rpc Call(AnyTestCases) returns (AnyTestCases);
+ rpc Call1(Imports) returns (Imports);
+}
+
+message AnyIn {
+ string something = 1;
+ google.protobuf.Any any = 2;
+}
+
+message AnyOut {
+ google.protobuf.Any any = 1;
+}
+
+message AnyM {
+ string foo = 1;
+}
diff --git a/NorthstarDedicatedTest/include/protobuf/util/internal/testdata/books.proto b/NorthstarDedicatedTest/include/protobuf/util/internal/testdata/books.proto
new file mode 100644
index 00000000..328c5ce0
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/util/internal/testdata/books.proto
@@ -0,0 +1,251 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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: sven@google.com (Sven Mawson)
+//
+// Sample protos for testing.
+
+// Some of the older enums don't use CAPITALS_WITH_UNDERSCORES for testing.
+// LINT: LEGACY_NAMES
+// LINT: ALLOW_GROUPS
+
+syntax = "proto2";
+
+package proto_util_converter.testing;
+
+import "google/protobuf/util/internal/testdata/anys.proto";
+
+// A book
+message Book {
+ optional string title = 1;
+ optional Author author = 2;
+ optional uint32 length = 3;
+ optional int64 published = 4;
+ optional bytes content = 5;
+
+ optional group Data = 6 {
+ optional uint32 year = 7;
+ optional string copyright = 8;
+ }
+
+ message Label {
+ optional string key = 1;
+ optional string value = 2;
+ }
+
+ optional Publisher publisher = 9;
+ repeated Label labels = 10;
+
+ enum Type {
+ FICTION = 1;
+ KIDS = 2;
+ ACTION_AND_ADVENTURE = 3;
+ arts_and_photography = 4;
+ I18N_Tech = 5;
+ }
+ optional Type type = 11;
+
+ // Useful for testing JSON snake/camel-case conversions.
+ optional string snake_field = 12;
+
+ // Used to test type not found in type info. Messages defined in other files
+ // are not added when adding Book to type info.
+ optional AnyWrapper type_not_found = 13;
+
+ // Used to test invalid value inside of primitive repeated fields.
+ repeated int32 primitive_repeated = 14;
+
+ extensions 200 to 499;
+}
+
+// A publisher of a book, tests required fields.
+message Publisher {
+ required string name = 1;
+}
+
+// An author of a book
+message Author {
+ optional uint64 id = 1 [json_name = "@id"];
+ optional string name = 2;
+ repeated string pseudonym = 3;
+ optional bool alive = 4;
+ repeated Author friend = 5;
+}
+
+// For testing resiliency of our protostream parser.
+// Field numbers of Author are reused for something else.
+message BadAuthor {
+ optional string id = 1; // non-length-delimited to length-delimited.
+ repeated uint64 name = 2; // string to repeated (both length-delimited).
+ optional string pseudonym = 3; // Repeated to optional.
+ repeated bool alive = 4 [packed = true]; // Optional to repeated.
+}
+
+// All primitive types
+message Primitive {
+ // 32 bit numbers:
+ optional fixed32 fix32 = 1;
+ optional uint32 u32 = 2;
+ optional int32 i32 = 3;
+ optional sfixed32 sf32 = 4;
+ optional sint32 s32 = 5;
+
+ // 64 bit numbers:
+ optional fixed64 fix64 = 6;
+ optional uint64 u64 = 7;
+ optional int64 i64 = 8;
+ optional sfixed64 sf64 = 9;
+ optional sint64 s64 = 10;
+
+ // The other stuff.
+ optional string str = 11;
+ optional bytes bytes = 12;
+ optional float float = 13;
+ optional double double = 14;
+ optional bool bool = 15;
+
+ // repeated 32 bit numbers:
+ repeated fixed32 rep_fix32 = 16;
+ repeated uint32 rep_u32 = 17;
+ repeated int32 rep_i32 = 18;
+ repeated sfixed32 rep_sf32 = 19;
+ repeated sint32 rep_s32 = 20;
+
+ // repeated 64 bit numbers:
+ repeated fixed64 rep_fix64 = 21;
+ repeated uint64 rep_u64 = 22;
+ repeated int64 rep_i64 = 23;
+ repeated sfixed64 rep_sf64 = 24;
+ repeated sint64 rep_s64 = 25;
+
+ // repeated other stuff:
+ repeated string rep_str = 26;
+ repeated bytes rep_bytes = 27;
+ repeated float rep_float = 28;
+ repeated double rep_double = 29;
+ repeated bool rep_bool = 30;
+}
+
+// Test packed versions of all repeated primitives.
+// The field numbers should match their non-packed version in Primitive message.
+message PackedPrimitive {
+ // repeated 32 bit numbers:
+ repeated fixed32 rep_fix32 = 16 [packed = true];
+ repeated uint32 rep_u32 = 17 [packed = true];
+ repeated int32 rep_i32 = 18 [packed = true];
+ repeated sfixed32 rep_sf32 = 19 [packed = true];
+ repeated sint32 rep_s32 = 20 [packed = true];
+
+ // repeated 64 bit numbers:
+ repeated fixed64 rep_fix64 = 21 [packed = true];
+ repeated uint64 rep_u64 = 22 [packed = true];
+ repeated int64 rep_i64 = 23 [packed = true];
+ repeated sfixed64 rep_sf64 = 24 [packed = true];
+ repeated sint64 rep_s64 = 25 [packed = true];
+
+ // repeated other stuff:
+ repeated float rep_float = 28 [packed = true];
+ repeated double rep_double = 29 [packed = true];
+ repeated bool rep_bool = 30 [packed = true];
+}
+
+// Test extensions.
+extend Book {
+ repeated Author more_author = 201;
+}
+
+// Test nested extensions.
+message NestedBook {
+ extend Book {
+ optional NestedBook another_book = 301;
+ }
+ // Recurse
+ optional Book book = 1;
+}
+
+// For testing resiliency of our protostream parser.
+// Field number of NestedBook is reused for something else.
+message BadNestedBook {
+ repeated uint32 book = 1 [packed = true]; // Packed to optional message.
+}
+
+// A recursively defined message.
+message Cyclic {
+ optional int32 m_int = 1;
+ optional string m_str = 2;
+ optional Book m_book = 3;
+ repeated Author m_author = 5;
+ optional Cyclic m_cyclic = 4;
+}
+
+// Test that two messages can have different fields mapped to the same JSON
+// name. See: https://github.com/protocolbuffers/protobuf/issues/1415
+message TestJsonName1 {
+ optional int32 one_value = 1 [json_name = "value"];
+}
+message TestJsonName2 {
+ optional int32 another_value = 1 [json_name = "value"];
+}
+
+message TestPrimitiveFieldsWithSameJsonName {
+ optional string val_str1 = 1;
+ optional string val_str_1 = 2;
+
+ optional int32 val_int321 = 3;
+ optional int32 val_int32_1 = 4;
+
+ optional uint32 val_uint321 = 5;
+ optional uint32 val_uint32_1 = 6;
+
+ optional int64 val_int641 = 7;
+ optional int64 val_int64_1 = 8;
+
+ optional uint64 val_uint641 = 9;
+ optional uint64 val_uint64_1 = 10;
+
+ optional bool val_bool1 = 11;
+ optional bool val_bool_1 = 12;
+
+ optional double val_double1 = 13;
+ optional double val_double_1 = 14;
+
+ optional float val_float1 = 15;
+ optional float val_float_1 = 16;
+}
+
+message TestRepeatedFieldsWithSameJsonName {
+ repeated string rep_str1 = 1;
+ repeated string rep_str_1 = 2;
+}
+
+message TestMessageFieldsWithSameJsonName {
+ optional Primitive prim1 = 1;
+ optional Primitive prim_1 = 2;
+}
diff --git a/NorthstarDedicatedTest/include/protobuf/util/internal/testdata/default_value.proto b/NorthstarDedicatedTest/include/protobuf/util/internal/testdata/default_value.proto
new file mode 100644
index 00000000..79ce1443
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/util/internal/testdata/default_value.proto
@@ -0,0 +1,170 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 proto_util_converter.testing;
+
+import "google/protobuf/any.proto";
+import "google/protobuf/struct.proto";
+import "google/protobuf/wrappers.proto";
+
+message DefaultValueTestCases {
+ DoubleMessage empty_double = 1;
+ DoubleMessage double_with_default_value = 2;
+ DoubleMessage double_with_nondefault_value = 3;
+ DoubleMessage repeated_double = 4;
+ DoubleMessage nested_message = 5;
+ DoubleMessage repeated_nested_message = 6;
+ DoubleMessage double_message_with_oneof = 7;
+ StructMessage empty_struct = 201;
+ StructMessage empty_struct2 = 202;
+ StructMessage struct_with_null_value = 203;
+ StructMessage struct_with_values = 204;
+ StructMessage struct_with_nested_struct = 205;
+ StructMessage struct_with_nested_list = 206;
+ StructMessage struct_with_list_of_nulls = 207;
+ StructMessage struct_with_list_of_lists = 208;
+ StructMessage struct_with_list_of_structs = 209;
+ google.protobuf.Struct top_level_struct = 210;
+ ValueMessage value_wrapper_simple = 212;
+ ValueMessage value_wrapper_with_struct = 213;
+ ValueMessage value_wrapper_with_list = 214;
+ ListValueMessage list_value_wrapper = 215;
+ google.protobuf.Value top_level_value_simple = 216;
+ google.protobuf.Value top_level_value_with_struct = 217;
+ google.protobuf.Value top_level_value_with_list = 218;
+ google.protobuf.ListValue top_level_listvalue = 219;
+ AnyMessage empty_any = 301;
+ AnyMessage type_only_any = 302;
+ AnyMessage recursive_any = 303;
+ AnyMessage any_with_message_value = 304;
+ AnyMessage any_with_nested_message = 305;
+ AnyMessage any_with_message_containing_map = 306;
+ AnyMessage any_with_message_containing_struct = 307;
+ google.protobuf.Any top_level_any = 308;
+ StringtoIntMap empty_map = 401;
+ StringtoIntMap string_to_int = 402;
+ IntToStringMap int_to_string = 403;
+ MixedMap mixed1 = 404;
+ MixedMap2 mixed2 = 405;
+ MixedMap2 empty_mixed2 = 406;
+ MessageMap map_of_objects = 407;
+ MixedMap mixed_empty = 408;
+ MessageMap message_map_empty = 409;
+ DoubleValueMessage double_value = 501;
+ DoubleValueMessage double_value_default = 502;
+}
+
+message DoubleMessage {
+ double double_value = 1;
+ repeated double repeated_double = 2;
+ DoubleMessage nested_message = 3;
+ repeated DoubleMessage repeated_nested_message = 4;
+ google.protobuf.DoubleValue double_wrapper = 100;
+ oneof value {
+ string str_value = 112;
+ int64 num_value = 113;
+ }
+}
+
+message StructMessage {
+ google.protobuf.Struct struct = 1;
+}
+
+message ValueMessage {
+ google.protobuf.Value value = 1;
+}
+
+message ListValueMessage {
+ google.protobuf.ListValue shopping_list = 1;
+}
+message RequestMessage {
+ string content = 1;
+}
+
+// A test service.
+service DefaultValueTestService {
+ // A test method.
+ rpc Call(RequestMessage) returns (DefaultValueTestCases);
+}
+
+message AnyMessage {
+ google.protobuf.Any any = 1;
+ AnyData data = 2;
+}
+
+message AnyData {
+ int32 attr = 1;
+ string str = 2;
+ repeated string msgs = 3;
+ AnyData nested_data = 4;
+ map<string, string> map_data = 7;
+ google.protobuf.Struct struct_data = 8;
+ repeated AnyData repeated_data = 9;
+}
+
+message StringtoIntMap {
+ map<string, int32> map = 1;
+}
+
+message IntToStringMap {
+ map<int32, string> map = 1;
+}
+
+message MixedMap {
+ string msg = 1;
+ map<string, float> map = 2;
+ int32 int_value = 3;
+}
+
+message MixedMap2 {
+ enum E {
+ E0 = 0;
+ E1 = 1;
+ E2 = 2;
+ E3 = 3;
+ }
+ map<int32, bool> map = 1;
+ E ee = 2;
+ string msg = 4;
+}
+
+message MessageMap {
+ message M {
+ int32 inner_int = 1;
+ string inner_text = 2;
+ }
+ map<string, M> map = 1;
+}
+
+message DoubleValueMessage {
+ google.protobuf.DoubleValue double = 1;
+}
diff --git a/NorthstarDedicatedTest/include/protobuf/util/internal/testdata/default_value_test.proto b/NorthstarDedicatedTest/include/protobuf/util/internal/testdata/default_value_test.proto
new file mode 100644
index 00000000..af755d3d
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/util/internal/testdata/default_value_test.proto
@@ -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.
+
+syntax = "proto3";
+
+package proto_util_converter.testing;
+
+message DefaultValueTest {
+ double double_value = 1;
+ repeated double repeated_double = 2;
+ float float_value = 3;
+ int64 int64_value = 5;
+ uint64 uint64_value = 7;
+ int32 int32_value = 9;
+ uint32 uint32_value = 11;
+ bool bool_value = 13;
+ string string_value = 15;
+ bytes bytes_value = 17 [ctype = CORD];
+
+ enum EnumDefault {
+ ENUM_FIRST = 0;
+ ENUM_SECOND = 1;
+ ENUM_THIRD = 2;
+ }
+ EnumDefault enum_value = 18;
+}
diff --git a/NorthstarDedicatedTest/include/protobuf/util/internal/testdata/field_mask.proto b/NorthstarDedicatedTest/include/protobuf/util/internal/testdata/field_mask.proto
new file mode 100644
index 00000000..9d2bc400
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/util/internal/testdata/field_mask.proto
@@ -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.
+
+syntax = "proto3";
+
+package proto_util_converter.testing;
+
+import "google/protobuf/field_mask.proto";
+
+message NestedFieldMask {
+ string data = 1;
+ google.protobuf.FieldMask single_mask = 2;
+ repeated google.protobuf.FieldMask repeated_mask = 3;
+}
+
+message FieldMaskTest {
+ string id = 1;
+ google.protobuf.FieldMask single_mask = 2;
+ repeated google.protobuf.FieldMask repeated_mask = 3;
+ repeated NestedFieldMask nested_mask = 4;
+}
+
+message FieldMaskTestCases {
+ FieldMaskWrapper single_mask = 1;
+ FieldMaskWrapper multiple_mask = 2;
+ FieldMaskWrapper snake_camel = 3;
+ FieldMaskWrapper empty_field = 4;
+ FieldMaskWrapper apiary_format1 = 5;
+ FieldMaskWrapper apiary_format2 = 6;
+ FieldMaskWrapper apiary_format3 = 7;
+ FieldMaskWrapper map_key1 = 8;
+ FieldMaskWrapper map_key2 = 9;
+ FieldMaskWrapper map_key3 = 10;
+ FieldMaskWrapper map_key4 = 11;
+ FieldMaskWrapper map_key5 = 12;
+}
+
+message FieldMaskWrapper {
+ google.protobuf.FieldMask mask = 1;
+}
+
+service FieldMaskTestService {
+ rpc Call(FieldMaskTestCases) returns (FieldMaskTestCases);
+}
diff --git a/NorthstarDedicatedTest/include/protobuf/util/internal/testdata/maps.proto b/NorthstarDedicatedTest/include/protobuf/util/internal/testdata/maps.proto
new file mode 100644
index 00000000..a9fdbe63
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/util/internal/testdata/maps.proto
@@ -0,0 +1,148 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+syntax = "proto3";
+
+package proto_util_converter.testing;
+
+import "google/protobuf/any.proto";
+
+// Top-level test cases proto used by MarshallingTest. See description
+// at the top of the class MarshallingTest for details on how to write
+// test cases.
+message MapsTestCases {
+ EmptyMap empty_map = 1;
+ StringtoInt string_to_int = 2;
+ IntToString int_to_string = 3;
+ Mixed1 mixed1 = 4;
+ Mixed2 mixed2 = 5;
+ MapOfObjects map_of_objects = 6;
+
+ // Empty key tests
+ StringtoInt empty_key_string_to_int1 = 7;
+ StringtoInt empty_key_string_to_int2 = 8;
+ StringtoInt empty_key_string_to_int3 = 9;
+ BoolToString empty_key_bool_to_string = 10;
+ IntToString empty_key_int_to_string = 11;
+ Mixed1 empty_key_mixed = 12;
+ MapOfObjects empty_key_map_objects = 13;
+}
+
+message EmptyMap {
+ map<int32, int32> map = 1;
+}
+
+message StringtoInt {
+ map<string, int32> map = 1;
+}
+
+message IntToString {
+ map<int32, string> map = 1;
+}
+
+message BoolToString {
+ map<bool, string> map = 1;
+}
+
+message Mixed1 {
+ string msg = 1;
+ map<string, float> map = 2;
+}
+
+message Mixed2 {
+ enum E {
+ E0 = 0;
+ E1 = 1;
+ E2 = 2;
+ E3 = 3;
+ }
+ map<int32, bool> map = 1;
+ E ee = 2;
+}
+
+message MapOfObjects {
+ message M {
+ string inner_text = 1;
+ }
+ map<string, M> map = 1;
+}
+
+message DummyRequest {}
+
+service MapsTestService {
+ rpc Call(DummyRequest) returns (MapsTestCases);
+}
+
+message MapIn {
+ string other = 1;
+ repeated string things = 2;
+ map<string, string> map_input = 3;
+ map<string, google.protobuf.Any> map_any = 4;
+}
+
+message MapOut {
+ map<string, MapM> map1 = 1;
+ map<string, MapOut> map2 = 2;
+ map<int32, string> map3 = 3;
+ map<bool, string> map4 = 5;
+ string bar = 4;
+}
+
+// A message with exactly the same wire representation as MapOut, but using
+// repeated message fields instead of map fields. We use this message to test
+// the wire-format compatibility of the JSON transcoder (e.g., whether it
+// handles missing keys correctly).
+message MapOutWireFormat {
+ message Map1Entry {
+ string key = 1;
+ MapM value = 2;
+ }
+ repeated Map1Entry map1 = 1;
+ message Map2Entry {
+ string key = 1;
+ MapOut value = 2;
+ }
+ repeated Map2Entry map2 = 2;
+ message Map3Entry {
+ int32 key = 1;
+ string value = 2;
+ }
+ repeated Map3Entry map3 = 3;
+ message Map4Entry {
+ bool key = 1;
+ string value = 2;
+ }
+ repeated Map4Entry map4 = 5;
+ string bar = 4;
+}
+
+message MapM {
+ string foo = 1;
+}
diff --git a/NorthstarDedicatedTest/include/protobuf/util/internal/testdata/oneofs.proto b/NorthstarDedicatedTest/include/protobuf/util/internal/testdata/oneofs.proto
new file mode 100644
index 00000000..7706af0b
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/util/internal/testdata/oneofs.proto
@@ -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.
+
+// Proto to test proto3 oneofs.
+syntax = "proto3";
+
+package proto_util_converter.testing.oneofs;
+
+import "google/protobuf/any.proto";
+import "google/protobuf/struct.proto";
+import "google/protobuf/timestamp.proto";
+
+message OneOfsRequest {
+ string value = 1;
+ oneof data {
+ string str_data = 2;
+ int32 int_data = 3;
+ // Simple message
+ Data message_data = 4;
+ MoreData more_data = 5;
+ // Well known types
+ google.protobuf.Struct struct_data = 6;
+ google.protobuf.Value value_data = 7;
+ google.protobuf.ListValue list_value_data = 8;
+ google.protobuf.Timestamp ts_data = 9;
+ }
+ google.protobuf.Any any_data = 19;
+}
+
+message RequestWithSimpleOneof {
+ string value = 1;
+ oneof data {
+ string str_data = 2;
+ int32 int_data = 3;
+ Data message_data = 4;
+ MoreData more_data = 5;
+ }
+}
+
+message Data {
+ int32 data_value = 1;
+}
+
+message MoreData {
+ string str_value = 1;
+}
+
+message Response {
+ string value = 1;
+}
diff --git a/NorthstarDedicatedTest/include/protobuf/util/internal/testdata/proto3.proto b/NorthstarDedicatedTest/include/protobuf/util/internal/testdata/proto3.proto
new file mode 100644
index 00000000..01434b02
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/util/internal/testdata/proto3.proto
@@ -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.
+
+syntax = "proto3";
+
+package proto_util_converter.testing;
+
+message Proto3Message {
+ enum NestedEnum {
+ FOO = 0;
+ BAR = 1;
+ BAZ = 2;
+ }
+ NestedEnum enum_value = 1;
+}
diff --git a/NorthstarDedicatedTest/include/protobuf/util/internal/testdata/struct.proto b/NorthstarDedicatedTest/include/protobuf/util/internal/testdata/struct.proto
new file mode 100644
index 00000000..a50ea87f
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/util/internal/testdata/struct.proto
@@ -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.
+
+syntax = "proto3";
+
+package proto_util_converter.testing;
+
+import "google/protobuf/struct.proto";
+
+message StructTestCases {
+ StructWrapper empty_value = 1;
+ StructWrapper empty_value2 = 2;
+ StructWrapper null_value = 3;
+ StructWrapper simple_struct = 4;
+ StructWrapper longer_struct = 5;
+ StructWrapper struct_with_nested_struct = 6;
+ StructWrapper struct_with_nested_list = 7;
+ StructWrapper struct_with_list_of_nulls = 8;
+ StructWrapper struct_with_list_of_lists = 9;
+ StructWrapper struct_with_list_of_structs = 10;
+ StructWrapper struct_with_empty_list = 11;
+ StructWrapper struct_with_list_with_empty_struct = 12;
+ google.protobuf.Struct top_level_struct = 13;
+ google.protobuf.Struct top_level_struct_with_empty_list = 14;
+ google.protobuf.Struct top_level_struct_with_list_with_empty_struct = 15;
+ ValueWrapper value_wrapper_simple = 16;
+ ValueWrapper value_wrapper_with_struct = 17;
+ ValueWrapper value_wrapper_with_list = 18;
+ ValueWrapper value_wrapper_with_empty_list = 19;
+ ValueWrapper value_wrapper_with_list_with_empty_struct = 20;
+ ListValueWrapper list_value_wrapper = 21;
+ ListValueWrapper list_value_wrapper_with_empty_list = 22;
+ ListValueWrapper list_value_wrapper_with_list_with_empty_struct = 23;
+ google.protobuf.Value top_level_value_simple = 24;
+ google.protobuf.Value top_level_value_with_struct = 25;
+ google.protobuf.Value top_level_value_with_list = 26;
+ google.protobuf.Value top_level_value_with_empty_list = 27;
+ google.protobuf.Value top_level_value_with_list_with_empty_struct = 28;
+ google.protobuf.ListValue top_level_listvalue = 29;
+ google.protobuf.ListValue top_level_empty_listvalue = 30;
+ google.protobuf.ListValue top_level_listvalue_with_empty_struct = 31;
+ RepeatedValueWrapper repeated_value = 32;
+ RepeatedValueWrapper repeated_value_nested_list = 33;
+ RepeatedValueWrapper repeated_value_nested_list2 = 34;
+ RepeatedValueWrapper repeated_value_nested_list3 = 35;
+ RepeatedListValueWrapper repeated_listvalue = 36;
+ MapOfStruct map_of_struct = 37;
+ MapOfStruct map_of_struct_value = 38;
+ MapOfStruct map_of_listvalue = 39;
+}
+
+message StructWrapper {
+ google.protobuf.Struct struct = 1;
+}
+
+message ValueWrapper {
+ google.protobuf.Value value = 1;
+}
+
+message RepeatedValueWrapper {
+ repeated google.protobuf.Value values = 1;
+}
+
+message ListValueWrapper {
+ google.protobuf.ListValue shopping_list = 1;
+}
+
+message RepeatedListValueWrapper {
+ repeated google.protobuf.ListValue dimensions = 1;
+}
+
+message MapOfStruct {
+ map<string, google.protobuf.Struct> struct_map = 1;
+ map<string, google.protobuf.Value> value_map = 2;
+ map<string, google.protobuf.ListValue> listvalue_map = 3;
+}
+
+// Hack to test return types with Struct as top-level message. Struct typers
+// cannot be directly used in API requests. Hence using Dummy as request type.
+message Dummy {
+ string text = 1;
+}
+
+service StructTestService {
+ rpc Call(Dummy) returns (StructTestCases);
+}
+
+message StructType {
+ google.protobuf.Struct object = 1;
+}
diff --git a/NorthstarDedicatedTest/include/protobuf/util/internal/testdata/timestamp_duration.proto b/NorthstarDedicatedTest/include/protobuf/util/internal/testdata/timestamp_duration.proto
new file mode 100644
index 00000000..8e87bdd2
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/util/internal/testdata/timestamp_duration.proto
@@ -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.
+
+syntax = "proto3";
+
+package proto_util_converter.testing;
+
+import "google/protobuf/duration.proto";
+import "google/protobuf/timestamp.proto";
+
+message TimestampDurationTestCases {
+ // Timestamp tests
+ TimeStampType epoch = 1;
+ TimeStampType epoch2 = 2;
+ TimeStampType mintime = 3;
+ TimeStampType maxtime = 4;
+ TimeStampType timeval1 = 5;
+ TimeStampType timeval2 = 6;
+ TimeStampType timeval3 = 7;
+ TimeStampType timeval4 = 8;
+ TimeStampType timeval5 = 9;
+ TimeStampType timeval6 = 10;
+ TimeStampType timeval7 = 11;
+ google.protobuf.Timestamp timeval8 = 12;
+
+ // Duration tests
+ DurationType zero_duration = 101;
+ DurationType min_duration = 102;
+ DurationType max_duration = 103;
+ DurationType duration1 = 104;
+ DurationType duration2 = 105;
+ DurationType duration3 = 106;
+ DurationType duration4 = 107;
+ google.protobuf.Duration duration5 = 108;
+}
+
+message TimeStampType {
+ google.protobuf.Timestamp timestamp = 1;
+}
+
+message DurationType {
+ google.protobuf.Duration duration = 1;
+}
+
+service TimestampDurationTestService {
+ rpc Call(TimestampDurationTestCases) returns (TimestampDurationTestCases);
+}
+
+message TimestampDuration {
+ google.protobuf.Timestamp ts = 1;
+ google.protobuf.Duration dur = 2;
+ repeated google.protobuf.Timestamp rep_ts = 3;
+}
diff --git a/NorthstarDedicatedTest/include/protobuf/util/internal/testdata/wrappers.proto b/NorthstarDedicatedTest/include/protobuf/util/internal/testdata/wrappers.proto
new file mode 100644
index 00000000..e7a0541d
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/util/internal/testdata/wrappers.proto
@@ -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.
+
+syntax = "proto3";
+
+package proto_util_converter.testing;
+
+import "google/protobuf/wrappers.proto";
+
+// Top-level test cases proto used by MarshallingTest. See description
+// at the top of the class MarshallingTest for details on how to write
+// test cases.
+message WrappersTestCases {
+ DoubleWrapper double_wrapper = 1;
+ FloatWrapper float_wrapper = 2;
+ Int64Wrapper int64_wrapper = 3;
+ UInt64Wrapper uint64_wrapper = 4;
+ Int32Wrapper int32_wrapper = 5;
+ UInt32Wrapper uint32_wrapper = 6;
+ BoolWrapper bool_wrapper = 7;
+ StringWrapper string_wrapper = 8;
+ BytesWrapper bytes_wrapper = 9;
+
+ DoubleWrapper double_wrapper_default = 10;
+ FloatWrapper float_wrapper_default = 11;
+ Int64Wrapper int64_wrapper_default = 12;
+ UInt64Wrapper uint64_wrapper_default = 13;
+ Int32Wrapper int32_wrapper_default = 14;
+ UInt32Wrapper uint32_wrapper_default = 15;
+ BoolWrapper bool_wrapper_default = 16;
+ StringWrapper string_wrapper_default = 17;
+ BytesWrapper bytes_wrapper_default = 18;
+}
+
+message DoubleWrapper {
+ google.protobuf.DoubleValue double = 1;
+}
+
+message FloatWrapper {
+ google.protobuf.FloatValue float = 1;
+}
+
+message Int64Wrapper {
+ google.protobuf.Int64Value int64 = 1;
+}
+
+message UInt64Wrapper {
+ google.protobuf.UInt64Value uint64 = 1;
+}
+
+message Int32Wrapper {
+ google.protobuf.Int32Value int32 = 1;
+}
+
+message UInt32Wrapper {
+ google.protobuf.UInt32Value uint32 = 1;
+}
+
+message BoolWrapper {
+ google.protobuf.BoolValue bool = 1;
+}
+
+message StringWrapper {
+ google.protobuf.StringValue string = 1;
+}
+
+message BytesWrapper {
+ google.protobuf.BytesValue bytes = 1;
+}
+
+service WrappersTestService {
+ rpc Call(WrappersTestCases) returns (WrappersTestCases);
+}
diff --git a/NorthstarDedicatedTest/include/protobuf/util/internal/type_info.cc b/NorthstarDedicatedTest/include/protobuf/util/internal/type_info.cc
new file mode 100644
index 00000000..0cf509ed
--- /dev/null
+++ b/NorthstarDedicatedTest/include/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 <util/internal/type_info.h>
+
+#include <map>
+#include <set>
+
+#include <stubs/common.h>
+#include <type.pb.h>
+#include <util/internal/utility.h>
+#include <stubs/status.h>
+#include <stubs/statusor.h>
+#include <stubs/strutil.h>
+#include <stubs/map_util.h>
+#include <stubs/status.h>
+
+namespace google {
+namespace protobuf {
+namespace util {
+namespace converter {
+
+namespace {
+// A TypeInfo that looks up information provided by a TypeResolver.
+class TypeInfoForTypeResolver : public TypeInfo {
+ public:
+ explicit TypeInfoForTypeResolver(TypeResolver* type_resolver)
+ : type_resolver_(type_resolver) {}
+
+ virtual ~TypeInfoForTypeResolver() {
+ DeleteCachedTypes(&cached_types_);
+ DeleteCachedTypes(&cached_enums_);
+ }
+
+ util::StatusOr<const google::protobuf::Type*> ResolveTypeUrl(
+ StringPiece type_url) const override {
+ std::map<StringPiece, StatusOrType>::iterator it =
+ cached_types_.find(type_url);
+ if (it != cached_types_.end()) {
+ return it->second;
+ }
+ // Stores the string value so it can be referenced using StringPiece in the
+ // cached_types_ map.
+ const 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/NorthstarDedicatedTest/include/protobuf/util/internal/type_info.h b/NorthstarDedicatedTest/include/protobuf/util/internal/type_info.h
new file mode 100644
index 00000000..80c73ea1
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/util/internal/type_info.h
@@ -0,0 +1,97 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef GOOGLE_PROTOBUF_UTIL_CONVERTER_TYPE_INFO_H__
+#define GOOGLE_PROTOBUF_UTIL_CONVERTER_TYPE_INFO_H__
+
+#include <stubs/common.h>
+#include <type.pb.h>
+#include <util/type_resolver.h>
+#include <stubs/statusor.h>
+#include <stubs/strutil.h>
+#include <stubs/status.h>
+
+// Must be included last.
+#include <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 <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_UTIL_CONVERTER_TYPE_INFO_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/util/internal/type_info_test_helper.cc b/NorthstarDedicatedTest/include/protobuf/util/internal/type_info_test_helper.cc
new file mode 100644
index 00000000..69ab08a8
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/util/internal/type_info_test_helper.cc
@@ -0,0 +1,132 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 <util/internal/type_info_test_helper.h>
+
+#include <memory>
+#include <vector>
+
+#include <stubs/logging.h>
+#include <stubs/common.h>
+#include <descriptor.h>
+#include <util/internal/default_value_objectwriter.h>
+#include <util/internal/type_info.h>
+#include <util/internal/constants.h>
+#include <util/internal/protostream_objectsource.h>
+#include <util/internal/protostream_objectwriter.h>
+#include <util/type_resolver.h>
+#include <util/type_resolver_util.h>
+
+namespace google {
+namespace protobuf {
+namespace util {
+namespace converter {
+namespace testing {
+
+
+void TypeInfoTestHelper::ResetTypeInfo(
+ const std::vector<const Descriptor*>& descriptors) {
+ switch (type_) {
+ case USE_TYPE_RESOLVER: {
+ const DescriptorPool* pool = descriptors[0]->file()->pool();
+ for (int i = 1; i < descriptors.size(); ++i) {
+ GOOGLE_CHECK(pool == descriptors[i]->file()->pool())
+ << "Descriptors from different pools are not supported.";
+ }
+ type_resolver_.reset(
+ NewTypeResolverForDescriptorPool(kTypeServiceBaseUrl, pool));
+ typeinfo_.reset(TypeInfo::NewTypeInfo(type_resolver_.get()));
+ return;
+ }
+ }
+ GOOGLE_LOG(FATAL) << "Can not reach here.";
+}
+
+void TypeInfoTestHelper::ResetTypeInfo(const Descriptor* descriptor) {
+ std::vector<const Descriptor*> descriptors;
+ descriptors.push_back(descriptor);
+ ResetTypeInfo(descriptors);
+}
+
+void TypeInfoTestHelper::ResetTypeInfo(const Descriptor* descriptor1,
+ const Descriptor* descriptor2) {
+ std::vector<const Descriptor*> descriptors;
+ descriptors.push_back(descriptor1);
+ descriptors.push_back(descriptor2);
+ ResetTypeInfo(descriptors);
+}
+
+TypeInfo* TypeInfoTestHelper::GetTypeInfo() { return typeinfo_.get(); }
+
+ProtoStreamObjectSource* TypeInfoTestHelper::NewProtoSource(
+ io::CodedInputStream* coded_input, const std::string& type_url,
+ ProtoStreamObjectSource::RenderOptions render_options) {
+ const google::protobuf::Type* type = typeinfo_->GetTypeByTypeUrl(type_url);
+ switch (type_) {
+ case USE_TYPE_RESOLVER: {
+ return new ProtoStreamObjectSource(coded_input, type_resolver_.get(),
+ *type, render_options);
+ }
+ }
+ GOOGLE_LOG(FATAL) << "Can not reach here.";
+ return nullptr;
+}
+
+ProtoStreamObjectWriter* TypeInfoTestHelper::NewProtoWriter(
+ const std::string& type_url, strings::ByteSink* output,
+ ErrorListener* listener, const ProtoStreamObjectWriter::Options& options) {
+ const google::protobuf::Type* type = typeinfo_->GetTypeByTypeUrl(type_url);
+ switch (type_) {
+ case USE_TYPE_RESOLVER: {
+ return new ProtoStreamObjectWriter(type_resolver_.get(), *type, output,
+ listener, options);
+ }
+ }
+ GOOGLE_LOG(FATAL) << "Can not reach here.";
+ return nullptr;
+}
+
+DefaultValueObjectWriter* TypeInfoTestHelper::NewDefaultValueWriter(
+ const std::string& type_url, ObjectWriter* writer) {
+ const google::protobuf::Type* type = typeinfo_->GetTypeByTypeUrl(type_url);
+ switch (type_) {
+ case USE_TYPE_RESOLVER: {
+ return new DefaultValueObjectWriter(type_resolver_.get(), *type, writer);
+ }
+ }
+ GOOGLE_LOG(FATAL) << "Can not reach here.";
+ return nullptr;
+}
+
+} // namespace testing
+} // namespace converter
+} // namespace util
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/util/internal/type_info_test_helper.h b/NorthstarDedicatedTest/include/protobuf/util/internal/type_info_test_helper.h
new file mode 100644
index 00000000..8697bc15
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/util/internal/type_info_test_helper.h
@@ -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.
+
+#ifndef GOOGLE_PROTOBUF_UTIL_CONVERTER_TYPE_INFO_TEST_HELPER_H__
+#define GOOGLE_PROTOBUF_UTIL_CONVERTER_TYPE_INFO_TEST_HELPER_H__
+
+#include <memory>
+#include <vector>
+
+#include <io/coded_stream.h>
+#include <descriptor.h>
+#include <util/internal/default_value_objectwriter.h>
+#include <util/internal/type_info.h>
+#include <util/internal/protostream_objectsource.h>
+#include <util/internal/protostream_objectwriter.h>
+#include <util/type_resolver.h>
+
+namespace google {
+namespace protobuf {
+namespace util {
+namespace converter {
+namespace testing {
+
+enum TypeInfoSource {
+ USE_TYPE_RESOLVER,
+};
+
+// In the unit-tests we want to test two scenarios: one with type info from
+// ServiceTypeInfo, the other with type info from TypeResolver. This class
+// wraps the detail of where the type info is from and provides the same
+// interface so the same unit-test code can test both scenarios.
+class TypeInfoTestHelper {
+ public:
+ explicit TypeInfoTestHelper(TypeInfoSource type) : type_(type) {}
+
+ // Creates a TypeInfo object for the given set of descriptors.
+ void ResetTypeInfo(const std::vector<const Descriptor*>& descriptors);
+
+ // Convenient overloads.
+ void ResetTypeInfo(const Descriptor* descriptor);
+ void ResetTypeInfo(const Descriptor* descriptor1,
+ const Descriptor* descriptor2);
+
+ // Returns the TypeInfo created after ResetTypeInfo.
+ TypeInfo* GetTypeInfo();
+
+ ProtoStreamObjectSource* NewProtoSource(
+ io::CodedInputStream* coded_input, const std::string& type_url,
+ ProtoStreamObjectSource::RenderOptions render_options = {});
+
+ ProtoStreamObjectWriter* NewProtoWriter(
+ const std::string& type_url, strings::ByteSink* output,
+ ErrorListener* listener, const ProtoStreamObjectWriter::Options& options);
+
+ DefaultValueObjectWriter* NewDefaultValueWriter(const std::string& type_url,
+ ObjectWriter* writer);
+
+ private:
+ TypeInfoSource type_;
+ std::unique_ptr<TypeInfo> typeinfo_;
+ std::unique_ptr<TypeResolver> type_resolver_;
+};
+} // namespace testing
+} // namespace converter
+} // namespace util
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_UTIL_CONVERTER_TYPE_INFO_TEST_HELPER_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/util/internal/utility.cc b/NorthstarDedicatedTest/include/protobuf/util/internal/utility.cc
new file mode 100644
index 00000000..b90e7ba5
--- /dev/null
+++ b/NorthstarDedicatedTest/include/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 <util/internal/utility.h>
+
+#include <algorithm>
+#include <cmath>
+#include <cstdint>
+#include <limits>
+
+#include <stubs/callback.h>
+#include <stubs/common.h>
+#include <stubs/logging.h>
+#include <wrappers.pb.h>
+#include <descriptor.pb.h>
+#include <descriptor.h>
+#include <util/internal/constants.h>
+#include <stubs/strutil.h>
+#include <stubs/map_util.h>
+
+// clang-format off
+#include <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/NorthstarDedicatedTest/include/protobuf/util/internal/utility.h b/NorthstarDedicatedTest/include/protobuf/util/internal/utility.h
new file mode 100644
index 00000000..69325dec
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/util/internal/utility.h
@@ -0,0 +1,204 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef GOOGLE_PROTOBUF_UTIL_CONVERTER_UTILITY_H__
+#define GOOGLE_PROTOBUF_UTIL_CONVERTER_UTILITY_H__
+
+#include <cstdint>
+#include <memory>
+#include <string>
+#include <utility>
+
+#include <stubs/common.h>
+#include <stubs/logging.h>
+#include <any.pb.h>
+#include <type.pb.h>
+#include <repeated_field.h>
+#include <stubs/strutil.h>
+#include <stubs/statusor.h>
+#include <stubs/status.h>
+
+// Must be included last.
+#include <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 <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_UTIL_CONVERTER_UTILITY_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/util/json_format.proto b/NorthstarDedicatedTest/include/protobuf/util/json_format.proto
new file mode 100644
index 00000000..7b7100d7
--- /dev/null
+++ b/NorthstarDedicatedTest/include/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/NorthstarDedicatedTest/include/protobuf/util/json_format_proto3.proto b/NorthstarDedicatedTest/include/protobuf/util/json_format_proto3.proto
new file mode 100644
index 00000000..0eec9da3
--- /dev/null
+++ b/NorthstarDedicatedTest/include/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/NorthstarDedicatedTest/include/protobuf/util/json_util.cc b/NorthstarDedicatedTest/include/protobuf/util/json_util.cc
new file mode 100644
index 00000000..6daa2542
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/util/json_util.cc
@@ -0,0 +1,282 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <util/json_util.h>
+
+#include <stubs/common.h>
+#include <io/coded_stream.h>
+#include <io/zero_copy_stream.h>
+#include <stubs/once.h>
+#include <util/internal/default_value_objectwriter.h>
+#include <util/internal/error_listener.h>
+#include <util/internal/json_objectwriter.h>
+#include <util/internal/json_stream_parser.h>
+#include <util/internal/protostream_objectsource.h>
+#include <util/internal/protostream_objectwriter.h>
+#include <util/type_resolver.h>
+#include <util/type_resolver_util.h>
+#include <stubs/bytestream.h>
+#include <stubs/status.h>
+#include <stubs/strutil.h>
+#include <stubs/status_macros.h>
+
+// clang-format off
+#include <port_def.inc>
+// clang-format on
+
+namespace google {
+namespace protobuf {
+namespace util {
+
+namespace internal {
+ZeroCopyStreamByteSink::~ZeroCopyStreamByteSink() {
+ if (buffer_size_ > 0) {
+ stream_->BackUp(buffer_size_);
+ }
+}
+
+void ZeroCopyStreamByteSink::Append(const char* bytes, size_t len) {
+ while (true) {
+ if (len <= buffer_size_) {
+ memcpy(buffer_, bytes, len);
+ buffer_ = static_cast<char*>(buffer_) + len;
+ buffer_size_ -= len;
+ return;
+ }
+ if (buffer_size_ > 0) {
+ memcpy(buffer_, bytes, buffer_size_);
+ bytes += buffer_size_;
+ len -= buffer_size_;
+ }
+ if (!stream_->Next(&buffer_, &buffer_size_)) {
+ // There isn't a way for ByteSink to report errors.
+ buffer_size_ = 0;
+ return;
+ }
+ }
+}
+} // namespace internal
+
+util::Status BinaryToJsonStream(TypeResolver* resolver,
+ const 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_ = NULL;
+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() { 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/NorthstarDedicatedTest/include/protobuf/util/json_util.h b/NorthstarDedicatedTest/include/protobuf/util/json_util.h
new file mode 100644
index 00000000..02903dbf
--- /dev/null
+++ b/NorthstarDedicatedTest/include/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 <message.h>
+#include <util/type_resolver.h>
+#include <stubs/bytestream.h>
+#include <stubs/status.h>
+#include <stubs/strutil.h>
+
+#include <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_(NULL), buffer_size_(0) {}
+ ~ZeroCopyStreamByteSink();
+
+ void Append(const char* bytes, size_t len) override;
+
+ private:
+ io::ZeroCopyOutputStream* stream_;
+ void* buffer_;
+ int buffer_size_;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ZeroCopyStreamByteSink);
+};
+} // namespace internal
+
+} // namespace util
+} // namespace protobuf
+} // namespace google
+
+#include <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_UTIL_JSON_UTIL_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/util/json_util_test.cc b/NorthstarDedicatedTest/include/protobuf/util/json_util_test.cc
new file mode 100644
index 00000000..f29b079c
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/util/json_util_test.cc
@@ -0,0 +1,668 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 <util/json_util.h>
+
+#include <cstdint>
+#include <list>
+#include <string>
+
+#include <io/zero_copy_stream.h>
+#include <io/zero_copy_stream_impl.h>
+#include <descriptor_database.h>
+#include <dynamic_message.h>
+#include <util/internal/testdata/maps.pb.h>
+#include <util/json_format.pb.h>
+#include <util/json_format_proto3.pb.h>
+#include <util/type_resolver.h>
+#include <util/type_resolver_util.h>
+#include <gtest/gtest.h>
+
+namespace google {
+namespace protobuf {
+namespace util {
+namespace {
+
+using proto3::BAR;
+using proto3::FOO;
+using proto3::TestAny;
+using proto3::TestEnumValue;
+using proto3::TestMap;
+using proto3::TestMessage;
+using proto3::TestOneof;
+using proto_util_converter::testing::MapIn;
+
+// As functions defined in json_util.h are just thin wrappers around the
+// JSON conversion code in //net/proto2/util/converter, in this test we
+// only cover some very basic cases to make sure the wrappers have forwarded
+// parameters to the underlying implementation correctly. More detailed
+// tests are contained in the //net/proto2/util/converter directory.
+class JsonUtilTest : public ::testing::Test {
+ protected:
+ JsonUtilTest() {}
+
+ std::string ToJson(const Message& message, const JsonPrintOptions& options) {
+ std::string result;
+ GOOGLE_CHECK_OK(MessageToJsonString(message, &result, options));
+ return result;
+ }
+
+ bool FromJson(const std::string& json, Message* message,
+ const JsonParseOptions& options) {
+ return JsonStringToMessage(json, message, options).ok();
+ }
+
+ bool FromJson(const std::string& json, Message* message) {
+ return FromJson(json, message, JsonParseOptions());
+ }
+
+ std::unique_ptr<TypeResolver> resolver_;
+};
+
+TEST_F(JsonUtilTest, TestWhitespaces) {
+ TestMessage m;
+ m.mutable_message_value();
+
+ JsonPrintOptions options;
+ EXPECT_EQ("{\"messageValue\":{}}", ToJson(m, options));
+ options.add_whitespace = true;
+ EXPECT_EQ(
+ "{\n"
+ " \"messageValue\": {}\n"
+ "}\n",
+ ToJson(m, options));
+}
+
+TEST_F(JsonUtilTest, TestDefaultValues) {
+ TestMessage m;
+ JsonPrintOptions options;
+ EXPECT_EQ("{}", ToJson(m, options));
+ options.always_print_primitive_fields = true;
+ EXPECT_EQ(
+ "{\"boolValue\":false,"
+ "\"int32Value\":0,"
+ "\"int64Value\":\"0\","
+ "\"uint32Value\":0,"
+ "\"uint64Value\":\"0\","
+ "\"floatValue\":0,"
+ "\"doubleValue\":0,"
+ "\"stringValue\":\"\","
+ "\"bytesValue\":\"\","
+ "\"enumValue\":\"FOO\","
+ "\"repeatedBoolValue\":[],"
+ "\"repeatedInt32Value\":[],"
+ "\"repeatedInt64Value\":[],"
+ "\"repeatedUint32Value\":[],"
+ "\"repeatedUint64Value\":[],"
+ "\"repeatedFloatValue\":[],"
+ "\"repeatedDoubleValue\":[],"
+ "\"repeatedStringValue\":[],"
+ "\"repeatedBytesValue\":[],"
+ "\"repeatedEnumValue\":[],"
+ "\"repeatedMessageValue\":[]"
+ "}",
+ ToJson(m, options));
+
+ options.always_print_primitive_fields = true;
+ m.set_string_value("i am a test string value");
+ m.set_bytes_value("i am a test bytes value");
+ EXPECT_EQ(
+ "{\"boolValue\":false,"
+ "\"int32Value\":0,"
+ "\"int64Value\":\"0\","
+ "\"uint32Value\":0,"
+ "\"uint64Value\":\"0\","
+ "\"floatValue\":0,"
+ "\"doubleValue\":0,"
+ "\"stringValue\":\"i am a test string value\","
+ "\"bytesValue\":\"aSBhbSBhIHRlc3QgYnl0ZXMgdmFsdWU=\","
+ "\"enumValue\":\"FOO\","
+ "\"repeatedBoolValue\":[],"
+ "\"repeatedInt32Value\":[],"
+ "\"repeatedInt64Value\":[],"
+ "\"repeatedUint32Value\":[],"
+ "\"repeatedUint64Value\":[],"
+ "\"repeatedFloatValue\":[],"
+ "\"repeatedDoubleValue\":[],"
+ "\"repeatedStringValue\":[],"
+ "\"repeatedBytesValue\":[],"
+ "\"repeatedEnumValue\":[],"
+ "\"repeatedMessageValue\":[]"
+ "}",
+ ToJson(m, options));
+
+ options.preserve_proto_field_names = true;
+ m.set_string_value("i am a test string value");
+ m.set_bytes_value("i am a test bytes value");
+ EXPECT_EQ(
+ "{\"bool_value\":false,"
+ "\"int32_value\":0,"
+ "\"int64_value\":\"0\","
+ "\"uint32_value\":0,"
+ "\"uint64_value\":\"0\","
+ "\"float_value\":0,"
+ "\"double_value\":0,"
+ "\"string_value\":\"i am a test string value\","
+ "\"bytes_value\":\"aSBhbSBhIHRlc3QgYnl0ZXMgdmFsdWU=\","
+ "\"enum_value\":\"FOO\","
+ "\"repeated_bool_value\":[],"
+ "\"repeated_int32_value\":[],"
+ "\"repeated_int64_value\":[],"
+ "\"repeated_uint32_value\":[],"
+ "\"repeated_uint64_value\":[],"
+ "\"repeated_float_value\":[],"
+ "\"repeated_double_value\":[],"
+ "\"repeated_string_value\":[],"
+ "\"repeated_bytes_value\":[],"
+ "\"repeated_enum_value\":[],"
+ "\"repeated_message_value\":[]"
+ "}",
+ ToJson(m, options));
+}
+
+TEST_F(JsonUtilTest, TestPreserveProtoFieldNames) {
+ TestMessage m;
+ m.mutable_message_value();
+
+ JsonPrintOptions options;
+ options.preserve_proto_field_names = true;
+ EXPECT_EQ("{\"message_value\":{}}", ToJson(m, options));
+}
+
+TEST_F(JsonUtilTest, TestAlwaysPrintEnumsAsInts) {
+ TestMessage orig;
+ orig.set_enum_value(proto3::BAR);
+ orig.add_repeated_enum_value(proto3::FOO);
+ orig.add_repeated_enum_value(proto3::BAR);
+
+ JsonPrintOptions print_options;
+ print_options.always_print_enums_as_ints = true;
+
+ std::string expected_json = "{\"enumValue\":1,\"repeatedEnumValue\":[0,1]}";
+ EXPECT_EQ(expected_json, ToJson(orig, print_options));
+
+ TestMessage parsed;
+ JsonParseOptions parse_options;
+ ASSERT_TRUE(FromJson(expected_json, &parsed, parse_options));
+
+ EXPECT_EQ(proto3::BAR, parsed.enum_value());
+ EXPECT_EQ(2, parsed.repeated_enum_value_size());
+ EXPECT_EQ(proto3::FOO, parsed.repeated_enum_value(0));
+ EXPECT_EQ(proto3::BAR, parsed.repeated_enum_value(1));
+}
+
+TEST_F(JsonUtilTest, TestPrintEnumsAsIntsWithDefaultValue) {
+ TestEnumValue orig;
+ // orig.set_enum_value1(proto3::FOO)
+ orig.set_enum_value2(proto3::FOO);
+ orig.set_enum_value3(proto3::BAR);
+
+ JsonPrintOptions print_options;
+ print_options.always_print_enums_as_ints = true;
+ print_options.always_print_primitive_fields = true;
+
+ std::string expected_json =
+ "{\"enumValue1\":0,\"enumValue2\":0,\"enumValue3\":1}";
+ EXPECT_EQ(expected_json, ToJson(orig, print_options));
+
+ TestEnumValue parsed;
+ JsonParseOptions parse_options;
+ ASSERT_TRUE(FromJson(expected_json, &parsed, parse_options));
+
+ EXPECT_EQ(proto3::FOO, parsed.enum_value1());
+ EXPECT_EQ(proto3::FOO, parsed.enum_value2());
+ EXPECT_EQ(proto3::BAR, parsed.enum_value3());
+}
+
+TEST_F(JsonUtilTest, TestPrintProto2EnumAsIntWithDefaultValue) {
+ protobuf_unittest::TestDefaultEnumValue orig;
+
+ JsonPrintOptions print_options;
+ // use enum as int
+ print_options.always_print_enums_as_ints = true;
+ print_options.always_print_primitive_fields = true;
+
+ // result should be int rather than string
+ std::string expected_json = "{\"enumValue\":2}";
+ EXPECT_EQ(expected_json, ToJson(orig, print_options));
+
+ protobuf_unittest::TestDefaultEnumValue parsed;
+ JsonParseOptions parse_options;
+ ASSERT_TRUE(FromJson(expected_json, &parsed, parse_options));
+
+ EXPECT_EQ(protobuf_unittest::DEFAULT, parsed.enum_value());
+}
+
+TEST_F(JsonUtilTest, ParseMessage) {
+ // Some random message but good enough to verify that the parsing wrapper
+ // functions are working properly.
+ std::string input =
+ "{\n"
+ " \"int32Value\": 1024,\n"
+ " \"repeatedInt32Value\": [1, 2],\n"
+ " \"messageValue\": {\n"
+ " \"value\": 2048\n"
+ " },\n"
+ " \"repeatedMessageValue\": [\n"
+ " {\"value\": 40}, {\"value\": 96}\n"
+ " ]\n"
+ "}\n";
+ JsonParseOptions options;
+ TestMessage m;
+ ASSERT_TRUE(FromJson(input, &m, options));
+ EXPECT_EQ(1024, m.int32_value());
+ ASSERT_EQ(2, m.repeated_int32_value_size());
+ EXPECT_EQ(1, m.repeated_int32_value(0));
+ EXPECT_EQ(2, m.repeated_int32_value(1));
+ EXPECT_EQ(2048, m.message_value().value());
+ ASSERT_EQ(2, m.repeated_message_value_size());
+ EXPECT_EQ(40, m.repeated_message_value(0).value());
+ EXPECT_EQ(96, m.repeated_message_value(1).value());
+}
+
+TEST_F(JsonUtilTest, ParseMap) {
+ TestMap message;
+ (*message.mutable_string_map())["hello"] = 1234;
+ JsonPrintOptions print_options;
+ JsonParseOptions parse_options;
+ EXPECT_EQ("{\"stringMap\":{\"hello\":1234}}", ToJson(message, print_options));
+ TestMap other;
+ ASSERT_TRUE(FromJson(ToJson(message, print_options), &other, parse_options));
+ EXPECT_EQ(message.DebugString(), other.DebugString());
+}
+
+TEST_F(JsonUtilTest, ParsePrimitiveMapIn) {
+ MapIn message;
+ JsonPrintOptions print_options;
+ print_options.always_print_primitive_fields = true;
+ JsonParseOptions parse_options;
+ EXPECT_EQ("{\"other\":\"\",\"things\":[],\"mapInput\":{},\"mapAny\":{}}",
+ ToJson(message, print_options));
+ MapIn other;
+ ASSERT_TRUE(FromJson(ToJson(message, print_options), &other, parse_options));
+ EXPECT_EQ(message.DebugString(), other.DebugString());
+}
+
+TEST_F(JsonUtilTest, PrintPrimitiveOneof) {
+ TestOneof message;
+ JsonPrintOptions options;
+ options.always_print_primitive_fields = true;
+ message.mutable_oneof_message_value();
+ EXPECT_EQ("{\"oneofMessageValue\":{\"value\":0}}", ToJson(message, options));
+
+ message.set_oneof_int32_value(1);
+ EXPECT_EQ("{\"oneofInt32Value\":1}", ToJson(message, options));
+}
+
+TEST_F(JsonUtilTest, TestParseIgnoreUnknownFields) {
+ TestMessage m;
+ JsonParseOptions options;
+ options.ignore_unknown_fields = true;
+ EXPECT_TRUE(FromJson("{\"unknownName\":0}", &m, options));
+}
+
+TEST_F(JsonUtilTest, TestParseErrors) {
+ TestMessage m;
+ JsonParseOptions options;
+ // Parsing should fail if the field name can not be recognized.
+ EXPECT_FALSE(FromJson("{\"unknownName\":0}", &m, options));
+ // Parsing should fail if the value is invalid.
+ EXPECT_FALSE(FromJson("{\"int32Value\":2147483648}", &m, options));
+}
+
+TEST_F(JsonUtilTest, TestDynamicMessage) {
+ // Some random message but good enough to test the wrapper functions.
+ std::string input =
+ "{\n"
+ " \"int32Value\": 1024,\n"
+ " \"repeatedInt32Value\": [1, 2],\n"
+ " \"messageValue\": {\n"
+ " \"value\": 2048\n"
+ " },\n"
+ " \"repeatedMessageValue\": [\n"
+ " {\"value\": 40}, {\"value\": 96}\n"
+ " ]\n"
+ "}\n";
+
+ // Create a new DescriptorPool with the same protos as the generated one.
+ DescriptorPoolDatabase database(*DescriptorPool::generated_pool());
+ DescriptorPool pool(&database);
+ // A dynamic version of the test proto.
+ DynamicMessageFactory factory;
+ std::unique_ptr<Message> message(
+ factory.GetPrototype(pool.FindMessageTypeByName("proto3.TestMessage"))
+ ->New());
+ EXPECT_TRUE(FromJson(input, message.get()));
+
+ // Convert to generated message for easy inspection.
+ TestMessage generated;
+ EXPECT_TRUE(generated.ParseFromString(message->SerializeAsString()));
+ EXPECT_EQ(1024, generated.int32_value());
+ ASSERT_EQ(2, generated.repeated_int32_value_size());
+ EXPECT_EQ(1, generated.repeated_int32_value(0));
+ EXPECT_EQ(2, generated.repeated_int32_value(1));
+ EXPECT_EQ(2048, generated.message_value().value());
+ ASSERT_EQ(2, generated.repeated_message_value_size());
+ EXPECT_EQ(40, generated.repeated_message_value(0).value());
+ EXPECT_EQ(96, generated.repeated_message_value(1).value());
+
+ JsonOptions options;
+ EXPECT_EQ(ToJson(generated, options), ToJson(*message, options));
+}
+
+TEST_F(JsonUtilTest, TestParsingUnknownAnyFields) {
+ std::string input =
+ "{\n"
+ " \"value\": {\n"
+ " \"@type\": \"type.googleapis.com/proto3.TestMessage\",\n"
+ " \"unknown_field\": \"UNKNOWN_VALUE\",\n"
+ " \"string_value\": \"expected_value\"\n"
+ " }\n"
+ "}";
+
+ TestAny m;
+ JsonParseOptions options;
+ EXPECT_FALSE(FromJson(input, &m, options));
+
+ options.ignore_unknown_fields = true;
+ EXPECT_TRUE(FromJson(input, &m, options));
+
+ TestMessage t;
+ EXPECT_TRUE(m.value().UnpackTo(&t));
+ EXPECT_EQ("expected_value", t.string_value());
+}
+
+TEST_F(JsonUtilTest, TestParsingUnknownEnumsProto2) {
+ std::string input =
+ "{\n"
+ " \"a\": \"UNKNOWN_VALUE\"\n"
+ "}";
+ protobuf_unittest::TestNumbers m;
+ JsonParseOptions options;
+ EXPECT_FALSE(FromJson(input, &m, options));
+
+ options.ignore_unknown_fields = true;
+ EXPECT_TRUE(FromJson(input, &m, options));
+ EXPECT_FALSE(m.has_a());
+}
+
+TEST_F(JsonUtilTest, TestParsingUnknownEnumsProto3) {
+ TestMessage m;
+ {
+ JsonParseOptions options;
+ ASSERT_FALSE(options.ignore_unknown_fields);
+ std::string input =
+ "{\n"
+ " \"enum_value\":\"UNKNOWN_VALUE\"\n"
+ "}";
+ m.set_enum_value(proto3::BAR);
+ EXPECT_FALSE(FromJson(input, &m, options));
+ ASSERT_EQ(proto3::BAR, m.enum_value()); // Keep previous value
+
+ options.ignore_unknown_fields = true;
+ EXPECT_TRUE(FromJson(input, &m, options));
+ EXPECT_EQ(0, m.enum_value()); // Unknown enum value must be decoded as 0
+ }
+ // Integer values are read as usual
+ {
+ JsonParseOptions options;
+ std::string input =
+ "{\n"
+ " \"enum_value\":12345\n"
+ "}";
+ m.set_enum_value(proto3::BAR);
+ EXPECT_TRUE(FromJson(input, &m, options));
+ ASSERT_EQ(12345, m.enum_value());
+
+ options.ignore_unknown_fields = true;
+ EXPECT_TRUE(FromJson(input, &m, options));
+ EXPECT_EQ(12345, m.enum_value());
+ }
+
+ // Trying to pass an object as an enum field value is always treated as an
+ // error
+ {
+ JsonParseOptions options;
+ std::string input =
+ "{\n"
+ " \"enum_value\":{}\n"
+ "}";
+ options.ignore_unknown_fields = true;
+ EXPECT_FALSE(FromJson(input, &m, options));
+ options.ignore_unknown_fields = false;
+ EXPECT_FALSE(FromJson(input, &m, options));
+ }
+ // Trying to pass an array as an enum field value is always treated as an
+ // error
+ {
+ JsonParseOptions options;
+ std::string input =
+ "{\n"
+ " \"enum_value\":[]\n"
+ "}";
+ EXPECT_FALSE(FromJson(input, &m, options));
+ options.ignore_unknown_fields = true;
+ EXPECT_FALSE(FromJson(input, &m, options));
+ }
+}
+
+TEST_F(JsonUtilTest, TestParsingEnumIgnoreCase) {
+ TestMessage m;
+ {
+ JsonParseOptions options;
+ std::string input =
+ "{\n"
+ " \"enum_value\":\"bar\"\n"
+ "}";
+ m.set_enum_value(proto3::FOO);
+ EXPECT_FALSE(FromJson(input, &m, options));
+ // Default behavior is case-sensitive, so keep previous value.
+ ASSERT_EQ(proto3::FOO, m.enum_value());
+ }
+ {
+ JsonParseOptions options;
+ options.case_insensitive_enum_parsing = false;
+ std::string input =
+ "{\n"
+ " \"enum_value\":\"bar\"\n"
+ "}";
+ m.set_enum_value(proto3::FOO);
+ EXPECT_FALSE(FromJson(input, &m, options));
+ ASSERT_EQ(proto3::FOO, m.enum_value()); // Keep previous value
+ }
+ {
+ JsonParseOptions options;
+ options.case_insensitive_enum_parsing = true;
+ std::string input =
+ "{\n"
+ " \"enum_value\":\"bar\"\n"
+ "}";
+ m.set_enum_value(proto3::FOO);
+ EXPECT_TRUE(FromJson(input, &m, options));
+ ASSERT_EQ(proto3::BAR, m.enum_value());
+ }
+}
+
+typedef std::pair<char*, int> Segment;
+// A ZeroCopyOutputStream that writes to multiple buffers.
+class SegmentedZeroCopyOutputStream : public io::ZeroCopyOutputStream {
+ public:
+ explicit SegmentedZeroCopyOutputStream(std::list<Segment> segments)
+ : segments_(segments),
+ last_segment_(static_cast<char*>(NULL), 0),
+ byte_count_(0) {}
+
+ bool Next(void** buffer, int* length) override {
+ if (segments_.empty()) {
+ return false;
+ }
+ last_segment_ = segments_.front();
+ segments_.pop_front();
+ *buffer = last_segment_.first;
+ *length = last_segment_.second;
+ byte_count_ += *length;
+ return true;
+ }
+
+ void BackUp(int length) override {
+ GOOGLE_CHECK(length <= last_segment_.second);
+ segments_.push_front(
+ Segment(last_segment_.first + last_segment_.second - length, length));
+ last_segment_ = Segment(last_segment_.first, last_segment_.second - length);
+ byte_count_ -= length;
+ }
+
+ int64_t ByteCount() const override { return byte_count_; }
+
+ private:
+ std::list<Segment> segments_;
+ Segment last_segment_;
+ int64_t byte_count_;
+};
+
+// This test splits the output buffer and also the input data into multiple
+// segments and checks that the implementation of ZeroCopyStreamByteSink
+// handles all possible cases correctly.
+TEST(ZeroCopyStreamByteSinkTest, TestAllInputOutputPatterns) {
+ static const int kOutputBufferLength = 10;
+ // An exhaustive test takes too long, skip some combinations to make the test
+ // run faster.
+ static const int kSkippedPatternCount = 7;
+
+ char buffer[kOutputBufferLength];
+ for (int split_pattern = 0; split_pattern < (1 << (kOutputBufferLength - 1));
+ split_pattern += kSkippedPatternCount) {
+ // Split the buffer into small segments according to the split_pattern.
+ std::list<Segment> segments;
+ int segment_start = 0;
+ for (int i = 0; i < kOutputBufferLength - 1; ++i) {
+ if (split_pattern & (1 << i)) {
+ segments.push_back(
+ Segment(buffer + segment_start, i - segment_start + 1));
+ segment_start = i + 1;
+ }
+ }
+ segments.push_back(
+ Segment(buffer + segment_start, kOutputBufferLength - segment_start));
+
+ // Write exactly 10 bytes through the ByteSink.
+ std::string input_data = "0123456789";
+ for (int input_pattern = 0; input_pattern < (1 << (input_data.size() - 1));
+ input_pattern += kSkippedPatternCount) {
+ memset(buffer, 0, sizeof(buffer));
+ {
+ SegmentedZeroCopyOutputStream output_stream(segments);
+ internal::ZeroCopyStreamByteSink byte_sink(&output_stream);
+ int start = 0;
+ for (int j = 0; j < input_data.length() - 1; ++j) {
+ if (input_pattern & (1 << j)) {
+ byte_sink.Append(&input_data[start], j - start + 1);
+ start = j + 1;
+ }
+ }
+ byte_sink.Append(&input_data[start], input_data.length() - start);
+ }
+ EXPECT_EQ(input_data, std::string(buffer, input_data.length()));
+ }
+
+ // Write only 9 bytes through the ByteSink.
+ input_data = "012345678";
+ for (int input_pattern = 0; input_pattern < (1 << (input_data.size() - 1));
+ input_pattern += kSkippedPatternCount) {
+ memset(buffer, 0, sizeof(buffer));
+ {
+ SegmentedZeroCopyOutputStream output_stream(segments);
+ internal::ZeroCopyStreamByteSink byte_sink(&output_stream);
+ int start = 0;
+ for (int j = 0; j < input_data.length() - 1; ++j) {
+ if (input_pattern & (1 << j)) {
+ byte_sink.Append(&input_data[start], j - start + 1);
+ start = j + 1;
+ }
+ }
+ byte_sink.Append(&input_data[start], input_data.length() - start);
+ }
+ EXPECT_EQ(input_data, std::string(buffer, input_data.length()));
+ EXPECT_EQ(0, buffer[input_data.length()]);
+ }
+
+ // Write 11 bytes through the ByteSink. The extra byte will just
+ // be ignored.
+ input_data = "0123456789A";
+ for (int input_pattern = 0; input_pattern < (1 << (input_data.size() - 1));
+ input_pattern += kSkippedPatternCount) {
+ memset(buffer, 0, sizeof(buffer));
+ {
+ SegmentedZeroCopyOutputStream output_stream(segments);
+ internal::ZeroCopyStreamByteSink byte_sink(&output_stream);
+ int start = 0;
+ for (int j = 0; j < input_data.length() - 1; ++j) {
+ if (input_pattern & (1 << j)) {
+ byte_sink.Append(&input_data[start], j - start + 1);
+ start = j + 1;
+ }
+ }
+ byte_sink.Append(&input_data[start], input_data.length() - start);
+ }
+ EXPECT_EQ(input_data.substr(0, kOutputBufferLength),
+ std::string(buffer, kOutputBufferLength));
+ }
+ }
+}
+
+TEST_F(JsonUtilTest, TestWrongJsonInput) {
+ const char json[] = "{\"unknown_field\":\"some_value\"}";
+ io::ArrayInputStream input_stream(json, strlen(json));
+ char proto_buffer[10000];
+ io::ArrayOutputStream output_stream(proto_buffer, sizeof(proto_buffer));
+ std::string message_type = "type.googleapis.com/proto3.TestMessage";
+ TypeResolver* resolver = NewTypeResolverForDescriptorPool(
+ "type.googleapis.com", DescriptorPool::generated_pool());
+
+ auto result_status = util::JsonToBinaryStream(resolver, message_type,
+ &input_stream, &output_stream);
+
+ delete resolver;
+
+ EXPECT_FALSE(result_status.ok());
+ EXPECT_TRUE(util::IsInvalidArgument(result_status));
+}
+
+TEST_F(JsonUtilTest, HtmlEscape) {
+ TestMessage m;
+ m.set_string_value("</script>");
+ JsonPrintOptions options;
+ EXPECT_EQ("{\"stringValue\":\"\\u003c/script\\u003e\"}", ToJson(m, options));
+}
+
+} // namespace
+} // namespace util
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/util/message_differencer.cc b/NorthstarDedicatedTest/include/protobuf/util/message_differencer.cc
new file mode 100644
index 00000000..61019a5e
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/util/message_differencer.cc
@@ -0,0 +1,2222 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: jschorr@google.com (Joseph Schorr)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <util/message_differencer.h>
+
+#include <algorithm>
+#include <cstddef>
+#include <cstdint>
+#include <functional>
+#include <limits>
+#include <memory>
+#include <utility>
+
+#include <stubs/logging.h>
+#include <stubs/common.h>
+#include <stubs/stringprintf.h>
+#include <io/printer.h>
+#include <io/zero_copy_stream.h>
+#include <io/zero_copy_stream_impl.h>
+#include <descriptor.pb.h>
+#include <descriptor.h>
+#include <dynamic_message.h>
+#include <generated_enum_reflection.h>
+#include <map_field.h>
+#include <message.h>
+#include <text_format.h>
+#include <util/field_comparator.h>
+#include <stubs/strutil.h>
+
+// Always include as last one, otherwise it can break compilation
+#include <port_def.inc>
+
+namespace google {
+namespace protobuf {
+
+namespace util {
+
+// A reporter to report the total number of diffs.
+// TODO(ykzhu): we can improve this to take into account the value differencers.
+class NumDiffsReporter : public google::protobuf::util::MessageDifferencer::Reporter {
+ public:
+ NumDiffsReporter() : num_diffs_(0) {}
+
+ // Returns the total number of diffs.
+ 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;
+}
+
+void MessageDifferencer::set_scope(Scope scope) { scope_ = scope; }
+
+MessageDifferencer::Scope MessageDifferencer::scope() { return scope_; }
+
+void MessageDifferencer::set_float_comparison(FloatComparison comparison) {
+ default_field_comparator_.set_float_comparison(
+ comparison == EXACT ? DefaultFieldComparator::EXACT
+ : DefaultFieldComparator::APPROXIMATE);
+}
+
+void MessageDifferencer::set_repeated_field_comparison(
+ RepeatedFieldComparison comparison) {
+ repeated_field_comparison_ = comparison;
+}
+
+MessageDifferencer::RepeatedFieldComparison
+MessageDifferencer::repeated_field_comparison() {
+ return repeated_field_comparison_;
+}
+
+void MessageDifferencer::CheckRepeatedFieldComparisons(
+ const FieldDescriptor* field,
+ const RepeatedFieldComparison& new_comparison) {
+ GOOGLE_CHECK(field->is_repeated())
+ << "Field must be repeated: " << field->full_name();
+ const MapKeyComparator* key_comparator = GetMapKeyComparator(field);
+ GOOGLE_CHECK(key_comparator == NULL)
+ << "Cannot treat this repeated field as both MAP and " << new_comparison
+ << " for comparison. Field name is: " << field->full_name();
+}
+
+void MessageDifferencer::TreatAsSet(const FieldDescriptor* field) {
+ CheckRepeatedFieldComparisons(field, AS_SET);
+ repeated_field_comparisons_[field] = AS_SET;
+}
+
+void MessageDifferencer::TreatAsSmartSet(const FieldDescriptor* field) {
+ CheckRepeatedFieldComparisons(field, AS_SMART_SET);
+ repeated_field_comparisons_[field] = AS_SMART_SET;
+}
+
+void MessageDifferencer::SetMatchIndicesForSmartListCallback(
+ std::function<void(std::vector<int>*, std::vector<int>*)> callback) {
+ match_indices_for_smart_list_callback_ = callback;
+}
+
+void MessageDifferencer::TreatAsList(const FieldDescriptor* field) {
+ CheckRepeatedFieldComparisons(field, AS_LIST);
+ repeated_field_comparisons_[field] = AS_LIST;
+}
+
+void MessageDifferencer::TreatAsSmartList(const FieldDescriptor* field) {
+ CheckRepeatedFieldComparisons(field, AS_SMART_LIST);
+ repeated_field_comparisons_[field] = AS_SMART_LIST;
+}
+
+void MessageDifferencer::TreatAsMap(const FieldDescriptor* field,
+ const FieldDescriptor* key) {
+ GOOGLE_CHECK_EQ(FieldDescriptor::CPPTYPE_MESSAGE, field->cpp_type())
+ << "Field has to be message type. Field name is: " << field->full_name();
+ GOOGLE_CHECK(key->containing_type() == field->message_type())
+ << key->full_name()
+ << " must be a direct subfield within the repeated field "
+ << field->full_name() << ", not " << key->containing_type()->full_name();
+ GOOGLE_CHECK(repeated_field_comparisons_.find(field) ==
+ repeated_field_comparisons_.end())
+ << "Cannot treat the same field as both "
+ << repeated_field_comparisons_[field]
+ << " and MAP. Field name is: " << field->full_name();
+ MapKeyComparator* key_comparator =
+ new MultipleFieldsMapKeyComparator(this, key);
+ owned_key_comparators_.push_back(key_comparator);
+ map_field_key_comparator_[field] = key_comparator;
+}
+
+void MessageDifferencer::TreatAsMapWithMultipleFieldsAsKey(
+ const FieldDescriptor* field,
+ const std::vector<const FieldDescriptor*>& key_fields) {
+ std::vector<std::vector<const FieldDescriptor*> > key_field_paths;
+ for (const FieldDescriptor* key_filed : key_fields) {
+ std::vector<const FieldDescriptor*> key_field_path;
+ key_field_path.push_back(key_filed);
+ key_field_paths.push_back(key_field_path);
+ }
+ TreatAsMapWithMultipleFieldPathsAsKey(field, key_field_paths);
+}
+
+void MessageDifferencer::TreatAsMapWithMultipleFieldPathsAsKey(
+ const FieldDescriptor* field,
+ const std::vector<std::vector<const FieldDescriptor*> >& key_field_paths) {
+ GOOGLE_CHECK(field->is_repeated())
+ << "Field must be repeated: " << field->full_name();
+ GOOGLE_CHECK_EQ(FieldDescriptor::CPPTYPE_MESSAGE, field->cpp_type())
+ << "Field has to be message type. Field name is: " << field->full_name();
+ for (const auto& key_field_path : key_field_paths) {
+ for (size_t j = 0; j < key_field_path.size(); ++j) {
+ const FieldDescriptor* parent_field =
+ j == 0 ? field : key_field_path[j - 1];
+ const FieldDescriptor* child_field = key_field_path[j];
+ GOOGLE_CHECK(child_field->containing_type() == parent_field->message_type())
+ << child_field->full_name()
+ << " must be a direct subfield within the field: "
+ << parent_field->full_name();
+ if (j != 0) {
+ GOOGLE_CHECK_EQ(FieldDescriptor::CPPTYPE_MESSAGE, parent_field->cpp_type())
+ << parent_field->full_name() << " has to be of type message.";
+ GOOGLE_CHECK(!parent_field->is_repeated())
+ << parent_field->full_name() << " cannot be a repeated field.";
+ }
+ }
+ }
+ GOOGLE_CHECK(repeated_field_comparisons_.find(field) ==
+ repeated_field_comparisons_.end())
+ << "Cannot treat the same field as both "
+ << repeated_field_comparisons_[field]
+ << " and MAP. Field name is: " << field->full_name();
+ MapKeyComparator* key_comparator =
+ new MultipleFieldsMapKeyComparator(this, key_field_paths);
+ owned_key_comparators_.push_back(key_comparator);
+ map_field_key_comparator_[field] = key_comparator;
+}
+
+void MessageDifferencer::TreatAsMapUsingKeyComparator(
+ const FieldDescriptor* field, const MapKeyComparator* key_comparator) {
+ GOOGLE_CHECK(field->is_repeated())
+ << "Field must be repeated: " << field->full_name();
+ GOOGLE_CHECK(repeated_field_comparisons_.find(field) ==
+ repeated_field_comparisons_.end())
+ << "Cannot treat the same field as both "
+ << repeated_field_comparisons_[field]
+ << " and MAP. Field name is: " << field->full_name();
+ map_field_key_comparator_[field] = key_comparator;
+}
+
+void MessageDifferencer::AddIgnoreCriteria(IgnoreCriteria* ignore_criteria) {
+ ignore_criteria_.push_back(ignore_criteria);
+}
+
+void MessageDifferencer::IgnoreField(const FieldDescriptor* field) {
+ ignored_fields_.insert(field);
+}
+
+void MessageDifferencer::SetFractionAndMargin(const FieldDescriptor* field,
+ double fraction, double margin) {
+ default_field_comparator_.SetFractionAndMargin(field, fraction, margin);
+}
+
+void MessageDifferencer::ReportDifferencesToString(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 = field_message.GetReflection()
+ ->GetMessage(field_message, fd)
+ .ShortDebugString();
+ } else {
+ TextFormat::PrintFieldValueToString(field_message, fd, -1, &output);
+ }
+ } else {
+ output = field_message.ShortDebugString();
+ }
+ if (output.empty()) {
+ printer_->Print("{ }");
+ } else {
+ if ((fd != nullptr) &&
+ (fd->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE)) {
+ printer_->PrintRaw(output);
+ } else {
+ printer_->Print("{ $name$ }", "name", output);
+ }
+ }
+ } else {
+ TextFormat::PrintFieldValueToString(message, field, index, &output);
+ printer_->PrintRaw(output);
+ }
+ } else {
+ const UnknownFieldSet* unknown_fields =
+ (left_side ? specific_field.unknown_field_set1
+ : specific_field.unknown_field_set2);
+ const UnknownField* unknown_field =
+ &unknown_fields->field(left_side ? specific_field.unknown_field_index1
+ : specific_field.unknown_field_index2);
+ PrintUnknownFieldValue(unknown_field);
+ }
+}
+
+void MessageDifferencer::StreamReporter::PrintUnknownFieldValue(
+ const UnknownField* unknown_field) {
+ GOOGLE_CHECK(unknown_field != NULL) << " Cannot print NULL unknown_field.";
+
+ 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/NorthstarDedicatedTest/include/protobuf/util/message_differencer.h b/NorthstarDedicatedTest/include/protobuf/util/message_differencer.h
new file mode 100644
index 00000000..c2f79051
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/util/message_differencer.h
@@ -0,0 +1,976 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: jschorr@google.com (Joseph Schorr)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// This file defines static methods and classes for comparing Protocol
+// Messages.
+//
+// Aug. 2008: Added Unknown Fields Comparison for messages.
+// Aug. 2009: Added different options to compare repeated fields.
+// Apr. 2010: Moved field comparison to FieldComparator
+// Sep. 2020: Added option to output map keys in path
+
+#ifndef GOOGLE_PROTOBUF_UTIL_MESSAGE_DIFFERENCER_H__
+#define GOOGLE_PROTOBUF_UTIL_MESSAGE_DIFFERENCER_H__
+
+#include <functional>
+#include <map>
+#include <memory>
+#include <set>
+#include <string>
+#include <vector>
+
+#include <descriptor.h> // FieldDescriptor
+#include <message.h> // Message
+#include <unknown_field_set.h>
+#include <util/field_comparator.h>
+
+// Always include as last one, otherwise it can break compilation
+#include <port_def.inc>
+
+namespace google {
+namespace protobuf {
+
+class DynamicMessageFactory;
+class FieldDescriptor;
+
+namespace io {
+class ZeroCopyOutputStream;
+class Printer;
+} // namespace io
+
+namespace util {
+
+class DefaultFieldComparator;
+class FieldContext; // declared below MessageDifferencer
+
+// Defines a collection of field descriptors.
+// In case of internal google codebase we are using absl::FixedArray instead
+// of vector. It significantly speeds up proto comparison (by ~30%) by
+// reducing the number of malloc/free operations
+typedef std::vector<const FieldDescriptor*> FieldDescriptorArray;
+
+// A basic differencer that can be used to determine
+// the differences between two specified Protocol Messages. If any differences
+// are found, the Compare method will return false, and any differencer reporter
+// specified via ReportDifferencesTo will have its reporting methods called (see
+// below for implementation of the report). Based off of the original
+// ProtocolDifferencer implementation in //net/proto/protocol-differencer.h
+// (Thanks Todd!).
+//
+// MessageDifferencer REQUIRES that compared messages be the same type, defined
+// as messages that share the same descriptor. If not, the behavior of this
+// class is undefined.
+//
+// People disagree on what MessageDifferencer should do when asked to compare
+// messages with different descriptors. Some people think it should always
+// return false. Others expect it to try to look for similar fields and
+// compare them anyway -- especially if the descriptors happen to be identical.
+// If we chose either of these behaviors, some set of people would find it
+// surprising, and could end up writing code expecting the other behavior
+// without realizing their error. Therefore, we forbid that usage.
+//
+// This class is implemented based on the proto2 reflection. The performance
+// should be good enough for normal usages. However, for places where the
+// performance is extremely sensitive, there are several alternatives:
+// - Comparing serialized string
+// Downside: false negatives (there are messages that are the same but their
+// serialized strings are different).
+// - Equals code generator by compiler plugin (net/proto2/contrib/equals_plugin)
+// Downside: more generated code; maintenance overhead for the additional rule
+// (must be in sync with the original proto_library).
+//
+// Note on handling of google.protobuf.Any: MessageDifferencer automatically
+// unpacks Any::value into a Message and compares its individual fields.
+// Messages encoded in a repeated Any cannot be compared using TreatAsMap.
+//
+// Note on thread-safety: MessageDifferencer is *not* thread-safe. You need to
+// guard it with a lock to use the same MessageDifferencer instance from
+// multiple threads. Note that it's fine to call static comparison methods
+// (like MessageDifferencer::Equals) concurrently, but it's not recommended for
+// performance critical code as it leads to extra allocations.
+class PROTOBUF_EXPORT MessageDifferencer {
+ public:
+ // Determines whether the supplied messages are equal. Equality is defined as
+ // all fields within the two messages being set to the same value. Primitive
+ // fields and strings are compared by value while embedded messages/groups
+ // are compared as if via a recursive call. Use Compare() with IgnoreField()
+ // if some fields should be ignored in the comparison. Use Compare() with
+ // TreatAsSet() if there are repeated fields where ordering does not matter.
+ //
+ // This method REQUIRES that the two messages have the same
+ // Descriptor (message1.GetDescriptor() == message2.GetDescriptor()).
+ static bool Equals(const Message& message1, const Message& message2);
+
+ // Determines whether the supplied messages are equivalent. Equivalency is
+ // defined as all fields within the two messages having the same value. This
+ // differs from the Equals method above in that fields with default values
+ // are considered set to said value automatically. For details on how default
+ // values are defined for each field type, see:
+ // https://developers.google.com/protocol-buffers/docs/proto?csw=1#optional.
+ // Also, Equivalent() ignores unknown fields. Use IgnoreField() and Compare()
+ // if some fields should be ignored in the comparison.
+ //
+ // This method REQUIRES that the two messages have the same
+ // Descriptor (message1.GetDescriptor() == message2.GetDescriptor()).
+ static bool Equivalent(const Message& message1, const Message& message2);
+
+ // Determines whether the supplied messages are approximately equal.
+ // Approximate equality is defined as all fields within the two messages
+ // being approximately equal. Primitive (non-float) fields and strings are
+ // compared by value, floats are compared using MathUtil::AlmostEquals() and
+ // embedded messages/groups are compared as if via a recursive call. Use
+ // IgnoreField() and Compare() if some fields should be ignored in the
+ // comparison.
+ //
+ // This method REQUIRES that the two messages have the same
+ // Descriptor (message1.GetDescriptor() == message2.GetDescriptor()).
+ static bool ApproximatelyEquals(const Message& message1,
+ const Message& message2);
+
+ // Determines whether the supplied messages are approximately equivalent.
+ // Approximate equivalency is defined as all fields within the two messages
+ // being approximately equivalent. As in
+ // MessageDifferencer::ApproximatelyEquals, primitive (non-float) fields and
+ // strings are compared by value, floats are compared using
+ // MathUtil::AlmostEquals() and embedded messages/groups are compared as if
+ // via a recursive call. However, fields with default values are considered
+ // set to said value, as per MessageDiffencer::Equivalent. Use IgnoreField()
+ // and Compare() if some fields should be ignored in the comparison.
+ //
+ // This method REQUIRES that the two messages have the same
+ // Descriptor (message1.GetDescriptor() == message2.GetDescriptor()).
+ static bool ApproximatelyEquivalent(const Message& message1,
+ const Message& message2);
+
+ // Identifies an individual field in a message instance. Used for field_path,
+ // below.
+ struct SpecificField {
+ // For known fields, "field" is filled in and "unknown_field_number" is -1.
+ // For unknown fields, "field" is NULL, "unknown_field_number" is the field
+ // number, and "unknown_field_type" is its type.
+ const FieldDescriptor* field = nullptr;
+ int unknown_field_number = -1;
+ UnknownField::Type unknown_field_type = UnknownField::Type::TYPE_VARINT;
+
+ // If this a repeated field, "index" is the index within it. For unknown
+ // fields, this is the index of the field among all unknown fields of the
+ // same field number and type.
+ int index = -1;
+
+ // If "field" is a repeated field which is being treated as a map or
+ // a set (see TreatAsMap() and TreatAsSet(), below), new_index indicates
+ // the index the position to which the element has moved. If the element
+ // has not moved, "new_index" will have the same value as "index".
+ int new_index = -1;
+
+ // If "field" is a map field, point to the map entry.
+ const Message* map_entry1 = nullptr;
+ const Message* map_entry2 = nullptr;
+
+ // For unknown fields, these are the pointers to the UnknownFieldSet
+ // containing the unknown fields. In certain cases (e.g. proto1's
+ // MessageSet, or nested groups of unknown fields), these may differ from
+ // the messages' internal UnknownFieldSets.
+ const UnknownFieldSet* unknown_field_set1 = nullptr;
+ const UnknownFieldSet* unknown_field_set2 = nullptr;
+
+ // For unknown fields, these are the index of the field within the
+ // UnknownFieldSets. One or the other will be -1 when
+ // reporting an addition or deletion.
+ int unknown_field_index1 = -1;
+ int unknown_field_index2 = -1;
+ };
+
+ // Abstract base class from which all MessageDifferencer
+ // reporters derive. The five Report* methods below will be called when
+ // a field has been added, deleted, modified, moved, or matched. The third
+ // argument is a vector of FieldDescriptor pointers which describes the chain
+ // of fields that was taken to find the current field. For example, for a
+ // field found in an embedded message, the vector will contain two
+ // FieldDescriptors. The first will be the field of the embedded message
+ // itself and the second will be the actual field in the embedded message
+ // that was added/deleted/modified.
+ // Fields will be reported in PostTraversalOrder.
+ // For example, given following proto, if both baz and quux are changed.
+ // foo {
+ // bar {
+ // baz: 1
+ // quux: 2
+ // }
+ // }
+ // ReportModified will be invoked with following order:
+ // 1. foo.bar.baz or foo.bar.quux
+ // 2. foo.bar.quux or foo.bar.baz
+ // 2. foo.bar
+ // 3. foo
+ class PROTOBUF_EXPORT Reporter {
+ public:
+ Reporter();
+ virtual ~Reporter();
+
+ // Reports that a field has been added into Message2.
+ virtual void ReportAdded(const Message& message1, const Message& message2,
+ const std::vector<SpecificField>& field_path) = 0;
+
+ // Reports that a field has been deleted from Message1.
+ virtual void ReportDeleted(
+ const Message& message1, const Message& message2,
+ const std::vector<SpecificField>& field_path) = 0;
+
+ // Reports that the value of a field has been modified.
+ virtual void ReportModified(
+ const Message& message1, const Message& message2,
+ const std::vector<SpecificField>& field_path) = 0;
+
+ // Reports that a repeated field has been moved to another location. This
+ // only applies when using TreatAsSet or TreatAsMap() -- see below. Also
+ // note that for any given field, ReportModified and ReportMoved are
+ // mutually exclusive. If a field has been both moved and modified, then
+ // only ReportModified will be called.
+ virtual void ReportMoved(
+ const Message& /* message1 */, const Message& /* message2 */,
+ const std::vector<SpecificField>& /* field_path */) {}
+
+ // Reports that two fields match. Useful for doing side-by-side diffs.
+ // This function is mutually exclusive with ReportModified and ReportMoved.
+ // Note that you must call set_report_matches(true) before calling Compare
+ // to make use of this function.
+ virtual void ReportMatched(
+ const Message& /* message1 */, const Message& /* message2 */,
+ const std::vector<SpecificField>& /* field_path */) {}
+
+ // Reports that two fields would have been compared, but the
+ // comparison has been skipped because the field was marked as
+ // 'ignored' using IgnoreField(). This function is mutually
+ // exclusive with all the other Report() functions.
+ //
+ // The contract of ReportIgnored is slightly different than the
+ // other Report() functions, in that |field_path.back().index| is
+ // always equal to -1, even if the last field is repeated. This is
+ // because while the other Report() functions indicate where in a
+ // repeated field the action (Addition, Deletion, etc...)
+ // happened, when a repeated field is 'ignored', the differencer
+ // simply calls ReportIgnored on the repeated field as a whole and
+ // moves on without looking at its individual elements.
+ //
+ // Furthermore, ReportIgnored() does not indicate whether the
+ // fields were in fact equal or not, as Compare() does not inspect
+ // these fields at all. It is up to the Reporter to decide whether
+ // the fields are equal or not (perhaps with a second call to
+ // Compare()), if it cares.
+ virtual void ReportIgnored(
+ const Message& /* message1 */, const Message& /* message2 */,
+ const std::vector<SpecificField>& /* field_path */) {}
+
+ // Report that an unknown field is ignored. (see comment above).
+ // Note this is a different function since the last SpecificField in field
+ // path has a null field. This could break existing Reporter.
+ virtual void ReportUnknownFieldIgnored(
+ const Message& /* message1 */, const Message& /* message2 */,
+ const std::vector<SpecificField>& /* field_path */) {}
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Reporter);
+ };
+
+ // MapKeyComparator is used to determine if two elements have the same key
+ // when comparing elements of a repeated field as a map.
+ class PROTOBUF_EXPORT MapKeyComparator {
+ public:
+ MapKeyComparator();
+ virtual ~MapKeyComparator();
+
+ virtual bool IsMatch(
+ const Message& /* message1 */, const Message& /* message2 */,
+ const std::vector<SpecificField>& /* parent_fields */) const {
+ GOOGLE_CHECK(false) << "IsMatch() is not implemented.";
+ return false;
+ }
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MapKeyComparator);
+ };
+
+ // Abstract base class from which all IgnoreCriteria derive.
+ // By adding IgnoreCriteria more complex ignore logic can be implemented.
+ // IgnoreCriteria are registered with AddIgnoreCriteria. For each compared
+ // field IsIgnored is called on each added IgnoreCriteria until one returns
+ // true or all return false.
+ // IsIgnored is called for fields where at least one side has a value.
+ class PROTOBUF_EXPORT IgnoreCriteria {
+ public:
+ IgnoreCriteria();
+ virtual ~IgnoreCriteria();
+
+ // Returns true if the field should be ignored.
+ virtual bool IsIgnored(
+ const Message& /* message1 */, const Message& /* message2 */,
+ const FieldDescriptor* /* field */,
+ const std::vector<SpecificField>& /* parent_fields */) = 0;
+
+ // Returns true if the unknown field should be ignored.
+ // Note: This will be called for unknown fields as well in which case
+ // field.field will be null.
+ virtual bool IsUnknownFieldIgnored(
+ const Message& /* message1 */, const Message& /* message2 */,
+ const SpecificField& /* field */,
+ const std::vector<SpecificField>& /* parent_fields */) {
+ return false;
+ }
+ };
+
+ // To add a Reporter, construct default here, then use ReportDifferencesTo or
+ // ReportDifferencesToString.
+ explicit MessageDifferencer();
+
+ ~MessageDifferencer();
+
+ enum MessageFieldComparison {
+ EQUAL, // Fields must be present in both messages
+ // for the messages to be considered the same.
+ EQUIVALENT, // Fields with default values are considered set
+ // for comparison purposes even if not explicitly
+ // set in the messages themselves. Unknown fields
+ // are ignored.
+ };
+
+ enum Scope {
+ FULL, // All fields of both messages are considered in the comparison.
+ PARTIAL // Only fields present in the first message are considered; fields
+ // set only in the second message will be skipped during
+ // comparison.
+ };
+
+ // DEPRECATED. Use FieldComparator::FloatComparison instead.
+ enum FloatComparison {
+ EXACT, // Floats and doubles are compared exactly.
+ APPROXIMATE // Floats and doubles are compared using the
+ // MathUtil::AlmostEquals method.
+ };
+
+ enum RepeatedFieldComparison {
+ AS_LIST, // Repeated fields are compared in order. Differing values at
+ // the same index are reported using ReportModified(). If the
+ // repeated fields have different numbers of elements, the
+ // unpaired elements are reported using ReportAdded() or
+ // ReportDeleted().
+ AS_SET, // Treat all the repeated fields as sets.
+ // See TreatAsSet(), as below.
+ AS_SMART_LIST, // Similar to AS_SET, but preserve the order and find the
+ // longest matching sequence from the first matching
+ // element. To use an optimal solution, call
+ // SetMatchIndicesForSmartListCallback() to pass it in.
+ AS_SMART_SET, // Similar to AS_SET, but match elements with fewest diffs.
+ };
+
+ // The elements of the given repeated field will be treated as a set for
+ // diffing purposes, so different orderings of the same elements will be
+ // considered equal. Elements which are present on both sides of the
+ // comparison but which have changed position will be reported with
+ // ReportMoved(). Elements which only exist on one side or the other are
+ // reported with ReportAdded() and ReportDeleted() regardless of their
+ // positions. ReportModified() is never used for this repeated field. If
+ // the only differences between the compared messages is that some fields
+ // have been moved, then the comparison returns true.
+ //
+ // Note that despite the name of this method, this is really
+ // comparison as multisets: if one side of the comparison has a duplicate
+ // in the repeated field but the other side doesn't, this will count as
+ // a mismatch.
+ //
+ // If the scope of comparison is set to PARTIAL, then in addition to what's
+ // above, extra values added to repeated fields of the second message will
+ // not cause the comparison to fail.
+ //
+ // Note that set comparison is currently O(k * n^2) (where n is the total
+ // number of elements, and k is the average size of each element). In theory
+ // it could be made O(n * k) with a more complex hashing implementation. Feel
+ // free to contribute one if the current implementation is too slow for you.
+ // If partial matching is also enabled, the time complexity will be O(k * n^2
+ // + n^3) in which n^3 is the time complexity of the maximum matching
+ // algorithm.
+ //
+ // REQUIRES: field->is_repeated() and field not registered with TreatAsMap*
+ void TreatAsSet(const FieldDescriptor* field);
+ void TreatAsSmartSet(const FieldDescriptor* field);
+
+ // The elements of the given repeated field will be treated as a list for
+ // diffing purposes, so different orderings of the same elements will NOT be
+ // considered equal.
+ //
+ // REQUIRES: field->is_repeated() and field not registered with TreatAsMap*
+ void TreatAsList(const FieldDescriptor* field);
+ // Note that the complexity is similar to treating as SET.
+ void TreatAsSmartList(const FieldDescriptor* field);
+
+ // The elements of the given repeated field will be treated as a map for
+ // diffing purposes, with |key| being the map key. Thus, elements with the
+ // same key will be compared even if they do not appear at the same index.
+ // Differences are reported similarly to TreatAsSet(), except that
+ // ReportModified() is used to report elements with the same key but
+ // different values. Note that if an element is both moved and modified,
+ // only ReportModified() will be called. As with TreatAsSet, if the only
+ // differences between the compared messages is that some fields have been
+ // moved, then the comparison returns true. See TreatAsSet for notes on
+ // performance.
+ //
+ // REQUIRES: field->is_repeated()
+ // REQUIRES: field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE
+ // REQUIRES: key->containing_type() == field->message_type()
+ void TreatAsMap(const FieldDescriptor* field, const FieldDescriptor* key);
+ // Same as TreatAsMap except that this method will use multiple fields as
+ // the key in comparison. All specified fields in 'key_fields' should be
+ // present in the compared elements. Two elements will be treated as having
+ // the same key iff they have the same value for every specified field. There
+ // are two steps in the comparison process. The first one is key matching.
+ // Every element from one message will be compared to every element from
+ // the other message. Only fields in 'key_fields' are compared in this step
+ // to decide if two elements have the same key. The second step is value
+ // comparison. Those pairs of elements with the same key (with equal value
+ // for every field in 'key_fields') will be compared in this step.
+ // Time complexity of the first step is O(s * m * n ^ 2) where s is the
+ // average size of the fields specified in 'key_fields', m is the number of
+ // fields in 'key_fields' and n is the number of elements. If partial
+ // matching is enabled, an extra O(n^3) will be incured by the maximum
+ // matching algorithm. The second step is O(k * n) where k is the average
+ // size of each element.
+ void TreatAsMapWithMultipleFieldsAsKey(
+ const FieldDescriptor* field,
+ const std::vector<const FieldDescriptor*>& key_fields);
+ // Same as TreatAsMapWithMultipleFieldsAsKey, except that each of the field
+ // do not necessarily need to be a direct subfield. Each element in
+ // key_field_paths indicate a path from the message being compared, listing
+ // successive subfield to reach the key field.
+ //
+ // REQUIRES:
+ // for key_field_path in key_field_paths:
+ // key_field_path[0]->containing_type() == field->message_type()
+ // for i in [0, key_field_path.size() - 1):
+ // key_field_path[i+1]->containing_type() ==
+ // key_field_path[i]->message_type()
+ // key_field_path[i]->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE
+ // !key_field_path[i]->is_repeated()
+ void TreatAsMapWithMultipleFieldPathsAsKey(
+ const FieldDescriptor* field,
+ const std::vector<std::vector<const FieldDescriptor*> >& key_field_paths);
+
+ // Uses a custom MapKeyComparator to determine if two elements have the same
+ // key when comparing a repeated field as a map.
+ // The caller is responsible to delete the key_comparator.
+ // This method varies from TreatAsMapWithMultipleFieldsAsKey only in the
+ // first key matching step. Rather than comparing some specified fields, it
+ // will invoke the IsMatch method of the given 'key_comparator' to decide if
+ // two elements have the same key.
+ void TreatAsMapUsingKeyComparator(const FieldDescriptor* field,
+ const MapKeyComparator* key_comparator);
+
+ // Initiates and returns a new instance of MultipleFieldsMapKeyComparator.
+ MapKeyComparator* CreateMultipleFieldsMapKeyComparator(
+ const std::vector<std::vector<const FieldDescriptor*> >& key_field_paths);
+
+ // Add a custom ignore criteria that is evaluated in addition to the
+ // ignored fields added with IgnoreField.
+ // Takes ownership of ignore_criteria.
+ void AddIgnoreCriteria(IgnoreCriteria* ignore_criteria);
+
+ // Indicates that any field with the given descriptor should be
+ // ignored for the purposes of comparing two messages. This applies
+ // to fields nested in the message structure as well as top level
+ // ones. When the MessageDifferencer encounters an ignored field,
+ // ReportIgnored is called on the reporter, if one is specified.
+ //
+ // The only place where the field's 'ignored' status is not applied is when
+ // it is being used as a key in a field passed to TreatAsMap or is one of
+ // the fields passed to TreatAsMapWithMultipleFieldsAsKey.
+ // In this case it is compared in key matching but after that it's ignored
+ // in value comparison.
+ void IgnoreField(const FieldDescriptor* field);
+
+ // Sets the field comparator used to determine differences between protocol
+ // buffer fields. By default it's set to a DefaultFieldComparator instance.
+ // MessageDifferencer doesn't take ownership over the passed object.
+ // Note that this method must be called before Compare for the comparator to
+ // be used.
+ void set_field_comparator(FieldComparator* comparator);
+#ifdef PROTOBUF_FUTURE_BREAKING_CHANGES
+ void set_field_comparator(DefaultFieldComparator* comparator);
+#endif // PROTOBUF_FUTURE_BREAKING_CHANGES
+
+ // DEPRECATED. Pass a DefaultFieldComparator instance instead.
+ // Sets the fraction and margin for the float comparison of a given field.
+ // Uses MathUtil::WithinFractionOrMargin to compare the values.
+ // NOTE: this method does nothing if differencer's field comparator has been
+ // set to a custom object.
+ //
+ // REQUIRES: field->cpp_type == FieldDescriptor::CPPTYPE_DOUBLE or
+ // field->cpp_type == FieldDescriptor::CPPTYPE_FLOAT
+ // REQUIRES: float_comparison_ == APPROXIMATE
+ void SetFractionAndMargin(const FieldDescriptor* field, double fraction,
+ double margin);
+
+ // Sets the type of comparison (as defined in the MessageFieldComparison
+ // enumeration above) that is used by this differencer when determining how
+ // to compare fields in messages.
+ void set_message_field_comparison(MessageFieldComparison comparison);
+
+ // Tells the differencer whether or not to report matches. This method must
+ // be called before Compare. The default for a new differencer is false.
+ void set_report_matches(bool report_matches) {
+ report_matches_ = report_matches;
+ }
+
+ // Tells the differencer whether or not to report moves (in a set or map
+ // repeated field). This method must be called before Compare. The default for
+ // a new differencer is true.
+ void set_report_moves(bool report_moves) { report_moves_ = report_moves; }
+
+ // Tells the differencer whether or not to report ignored values. This method
+ // must be called before Compare. The default for a new differencer is true.
+ void set_report_ignores(bool report_ignores) {
+ report_ignores_ = report_ignores;
+ }
+
+ // Sets the scope of the comparison (as defined in the Scope enumeration
+ // above) that is used by this differencer when determining which fields to
+ // compare between the messages.
+ void set_scope(Scope scope);
+
+ // Returns the current scope used by this differencer.
+ Scope scope();
+
+ // DEPRECATED. Pass a DefaultFieldComparator instance instead.
+ // Sets the type of comparison (as defined in the FloatComparison enumeration
+ // above) that is used by this differencer when comparing float (and double)
+ // fields in messages.
+ // NOTE: this method does nothing if differencer's field comparator has been
+ // set to a custom object.
+ void set_float_comparison(FloatComparison comparison);
+
+ // Sets the type of comparison for repeated field (as defined in the
+ // RepeatedFieldComparison enumeration above) that is used by this
+ // differencer when compare repeated fields in messages.
+ void set_repeated_field_comparison(RepeatedFieldComparison comparison);
+
+ // Returns the current repeated field comparison used by this differencer.
+ RepeatedFieldComparison repeated_field_comparison();
+
+ // Compares the two specified messages, returning true if they are the same,
+ // false otherwise. If this method returns false, any changes between the
+ // two messages will be reported if a Reporter was specified via
+ // ReportDifferencesTo (see also ReportDifferencesToString).
+ //
+ // This method REQUIRES that the two messages have the same
+ // Descriptor (message1.GetDescriptor() == message2.GetDescriptor()).
+ bool Compare(const Message& message1, const Message& message2);
+
+ // Same as above, except comparing only the list of fields specified by the
+ // two vectors of FieldDescriptors.
+ bool CompareWithFields(
+ const Message& message1, const Message& message2,
+ const std::vector<const FieldDescriptor*>& message1_fields,
+ const std::vector<const FieldDescriptor*>& message2_fields);
+
+ // Automatically creates a reporter that will output the differences
+ // found (if any) to the specified output string pointer. Note that this
+ // method must be called before Compare.
+ void ReportDifferencesToString(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 <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_UTIL_MESSAGE_DIFFERENCER_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/util/message_differencer_unittest.cc b/NorthstarDedicatedTest/include/protobuf/util/message_differencer_unittest.cc
new file mode 100644
index 00000000..dd138b21
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/util/message_differencer_unittest.cc
@@ -0,0 +1,3812 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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.
+//
+// TODO(ksroka): Move some of these tests to field_comparator_test.cc.
+
+#include <algorithm>
+#include <random>
+#include <string>
+#include <vector>
+
+#include <stubs/common.h>
+
+#include <stubs/strutil.h>
+
+#include <stubs/logging.h>
+#include <any_test.pb.h>
+#include <map_test_util.h>
+#include <map_unittest.pb.h>
+#include <test_util.h>
+#include <unittest.pb.h>
+#include <io/coded_stream.h>
+#include <io/zero_copy_stream_impl.h>
+#include <text_format.h>
+#include <wire_format.h>
+#include <util/message_differencer_unittest.pb.h>
+#include <util/field_comparator.h>
+#include <util/message_differencer.h>
+#include <testing/googletest.h>
+#include <gtest/gtest.h>
+
+namespace google {
+namespace protobuf {
+
+namespace {
+
+
+const FieldDescriptor* GetFieldDescriptor(const Message& message,
+ const std::string& field_name) {
+ std::vector<std::string> field_path =
+ Split(field_name, ".", true);
+ const Descriptor* descriptor = message.GetDescriptor();
+ const FieldDescriptor* field = NULL;
+ for (int i = 0; i < field_path.size(); i++) {
+ field = descriptor->FindFieldByName(field_path[i]);
+ descriptor = field->message_type();
+ }
+ return field;
+}
+
+void ExpectEqualsWithDifferencer(util::MessageDifferencer* differencer,
+ const Message& msg1, const Message& msg2) {
+ differencer->set_scope(util::MessageDifferencer::FULL);
+ EXPECT_TRUE(differencer->Compare(msg1, msg2));
+
+ differencer->set_scope(util::MessageDifferencer::PARTIAL);
+ EXPECT_TRUE(differencer->Compare(msg1, msg2));
+}
+
+TEST(MessageDifferencerTest, BasicEqualityTest) {
+ // Create the testing protos
+ unittest::TestAllTypes msg1;
+ unittest::TestAllTypes msg2;
+
+ TestUtil::SetAllFields(&msg1);
+ TestUtil::SetAllFields(&msg2);
+
+ // Compare
+ EXPECT_TRUE(util::MessageDifferencer::Equals(msg1, msg2));
+}
+
+TEST(MessageDifferencerTest, BasicInequalityTest) {
+ // Create the testing protos
+ unittest::TestAllTypes msg1;
+ unittest::TestAllTypes msg2;
+
+ TestUtil::SetAllFields(&msg1);
+ TestUtil::SetAllFields(&msg2);
+
+ msg1.set_optional_int32(-1);
+
+ // Compare
+ EXPECT_FALSE(util::MessageDifferencer::Equals(msg1, msg2));
+}
+
+TEST(MessageDifferencerTest, RepeatedFieldInequalityTest) {
+ // Create the testing protos
+ unittest::TestAllTypes msg1;
+ unittest::TestAllTypes msg2;
+
+ TestUtil::SetAllFields(&msg1);
+ TestUtil::SetAllFields(&msg2);
+
+ msg1.add_repeated_int32(-1);
+
+ // Compare
+ EXPECT_FALSE(util::MessageDifferencer::Equals(msg1, msg2));
+}
+
+TEST(MessageDifferencerTest, RepeatedFieldSetOptimizationTest) {
+ util::MessageDifferencer differencer;
+ protobuf_unittest::TestDiffMessage msg1;
+ protobuf_unittest::TestDiffMessage msg2;
+ protobuf_unittest::TestDiffMessage::Item* item1 = msg1.add_item();
+ protobuf_unittest::TestDiffMessage::Item* item2 = msg2.add_item();
+ differencer.TreatAsSet(item1->GetDescriptor()->FindFieldByName("ra"));
+ differencer.TreatAsSet(item2->GetDescriptor()->FindFieldByName("ra"));
+ for (int i = 0; i < 1000; i++) {
+ item1->add_ra(i);
+ item2->add_ra(i);
+ }
+ EXPECT_TRUE(differencer.Compare(msg1, msg2));
+ item2->add_ra(1001);
+ EXPECT_FALSE(differencer.Compare(msg1, msg2));
+ item1->add_ra(1001);
+ EXPECT_TRUE(differencer.Compare(msg1, msg2));
+ item1->add_ra(1002);
+ EXPECT_FALSE(differencer.Compare(msg1, msg2));
+}
+
+TEST(MessageDifferencerTest, MapFieldEqualityTest) {
+ // Create the testing protos
+ unittest::TestMap msg1;
+ unittest::TestMap msg2;
+
+ MapReflectionTester tester(unittest::TestMap::descriptor());
+ tester.SetMapFieldsViaReflection(&msg1);
+ tester.SetMapFieldsViaReflection(&msg2);
+ tester.SwapMapsViaReflection(&msg1);
+
+ // Compare
+ EXPECT_TRUE(util::MessageDifferencer::Equals(msg1, msg2));
+
+ // Get map entries by index will sync map to repeated field
+ MapTestUtil::GetMapEntries(msg1, 0);
+ EXPECT_TRUE(util::MessageDifferencer::Equals(msg1, msg2));
+
+ // Compare values not match
+ (*msg1.mutable_map_int32_int32())[1] = 2;
+ (*msg2.mutable_map_int32_int32())[1] = 3;
+ EXPECT_FALSE(util::MessageDifferencer::Equals(msg1, msg2));
+
+ // Compare keys not match
+ msg1.Clear();
+ msg2.Clear();
+ (*msg1.mutable_map_string_string())["1"] = "";
+ (*msg2.mutable_map_string_string())["2"] = "";
+ EXPECT_FALSE(util::MessageDifferencer::Equals(msg1, msg2));
+
+ // Compare message values not match
+ msg1.Clear();
+ msg2.Clear();
+ (*msg1.mutable_map_int32_foreign_message())[1].set_c(1);
+ (*msg2.mutable_map_int32_foreign_message())[1].set_c(2);
+ EXPECT_FALSE(util::MessageDifferencer::Equals(msg1, msg2));
+}
+
+TEST(MessageDifferencerTest, BasicPartialEqualityTest) {
+ // Create the testing protos
+ unittest::TestAllTypes msg1;
+ unittest::TestAllTypes msg2;
+
+ TestUtil::SetAllFields(&msg1);
+ TestUtil::SetAllFields(&msg2);
+
+ // Compare
+ util::MessageDifferencer differencer;
+ differencer.set_scope(util::MessageDifferencer::PARTIAL);
+ EXPECT_TRUE(differencer.Compare(msg1, msg2));
+}
+
+TEST(MessageDifferencerTest, PartialEqualityTestExtraField) {
+ // Create the testing protos
+ unittest::TestAllTypes msg1;
+ unittest::TestAllTypes msg2;
+
+ TestUtil::SetAllFields(&msg1);
+ TestUtil::SetAllFields(&msg2);
+
+ msg1.clear_optional_int32();
+
+ // Compare
+ util::MessageDifferencer differencer;
+ differencer.set_scope(util::MessageDifferencer::PARTIAL);
+ EXPECT_TRUE(differencer.Compare(msg1, msg2));
+}
+
+TEST(MessageDifferencerTest, PartialEqualityTestSkipRequiredField) {
+ // Create the testing protos
+ unittest::TestRequired msg1;
+ unittest::TestRequired msg2;
+
+ msg1.set_a(401);
+ msg2.set_a(401);
+ msg2.set_b(402);
+
+ // Compare
+ util::MessageDifferencer differencer;
+ differencer.set_scope(util::MessageDifferencer::PARTIAL);
+ EXPECT_TRUE(differencer.Compare(msg1, msg2));
+}
+
+TEST(MessageDifferencerTest, BasicPartialInequalityTest) {
+ // Create the testing protos
+ unittest::TestAllTypes msg1;
+ unittest::TestAllTypes msg2;
+
+ TestUtil::SetAllFields(&msg1);
+ TestUtil::SetAllFields(&msg2);
+
+ msg1.set_optional_int32(-1);
+
+ // Compare
+ util::MessageDifferencer differencer;
+ differencer.set_scope(util::MessageDifferencer::PARTIAL);
+ EXPECT_FALSE(differencer.Compare(msg1, msg2));
+}
+
+TEST(MessageDifferencerTest, PartialInequalityMissingFieldTest) {
+ // Create the testing protos
+ unittest::TestAllTypes msg1;
+ unittest::TestAllTypes msg2;
+
+ TestUtil::SetAllFields(&msg1);
+ TestUtil::SetAllFields(&msg2);
+
+ msg2.clear_optional_int32();
+
+ // Compare
+ util::MessageDifferencer differencer;
+ differencer.set_scope(util::MessageDifferencer::PARTIAL);
+ EXPECT_FALSE(differencer.Compare(msg1, msg2));
+}
+
+TEST(MessageDifferencerTest, RepeatedFieldPartialInequalityTest) {
+ // Create the testing protos
+ unittest::TestAllTypes msg1;
+ unittest::TestAllTypes msg2;
+
+ TestUtil::SetAllFields(&msg1);
+ TestUtil::SetAllFields(&msg2);
+
+ msg1.add_repeated_int32(-1);
+
+ // Compare
+ util::MessageDifferencer differencer;
+ differencer.set_scope(util::MessageDifferencer::PARTIAL);
+ EXPECT_FALSE(differencer.Compare(msg1, msg2));
+}
+
+TEST(MessageDifferencerTest, BasicEquivalencyTest) {
+ // Create the testing protos
+ unittest::TestAllTypes msg1;
+ unittest::TestAllTypes msg2;
+
+ TestUtil::SetAllFields(&msg1);
+ TestUtil::SetAllFields(&msg2);
+
+ // Compare
+ EXPECT_TRUE(util::MessageDifferencer::Equivalent(msg1, msg2));
+}
+
+TEST(MessageDifferencerTest, EquivalencyNotEqualTest) {
+ // Create the testing protos
+ unittest::TestAllTypes msg1;
+ unittest::TestAllTypes msg2;
+
+ TestUtil::SetAllFields(&msg1);
+ TestUtil::SetAllFields(&msg2);
+
+ msg1.clear_optional_int32();
+ msg2.set_optional_int32(0);
+
+ // Compare
+ EXPECT_FALSE(util::MessageDifferencer::Equals(msg1, msg2));
+ EXPECT_TRUE(util::MessageDifferencer::Equivalent(msg1, msg2));
+}
+
+TEST(MessageDifferencerTest, BasicInequivalencyTest) {
+ // Create the testing protos
+ unittest::TestAllTypes msg1;
+ unittest::TestAllTypes msg2;
+
+ TestUtil::SetAllFields(&msg1);
+ TestUtil::SetAllFields(&msg2);
+
+ msg1.set_optional_int32(-1);
+
+ // Compare
+ EXPECT_FALSE(util::MessageDifferencer::Equivalent(msg1, msg2));
+}
+
+TEST(MessageDifferencerTest, BasicEquivalencyNonSetTest) {
+ // Create the testing protos
+ unittest::TestAllTypes msg1;
+ unittest::TestAllTypes msg2;
+
+ // Compare
+ EXPECT_TRUE(util::MessageDifferencer::Equivalent(msg1, msg2));
+}
+
+TEST(MessageDifferencerTest, BasicInequivalencyNonSetTest) {
+ // Create the testing protos
+ unittest::TestAllTypes msg1;
+ unittest::TestAllTypes msg2;
+
+ msg1.set_optional_int32(-1);
+
+ // Compare
+ EXPECT_FALSE(util::MessageDifferencer::Equivalent(msg1, msg2));
+}
+
+TEST(MessageDifferencerTest, BasicPartialEquivalencyTest) {
+ // Create the testing protos
+ unittest::TestAllTypes msg1;
+ unittest::TestAllTypes msg2;
+
+ TestUtil::SetAllFields(&msg1);
+ TestUtil::SetAllFields(&msg2);
+
+ // Compare
+ util::MessageDifferencer differencer;
+ differencer.set_message_field_comparison(
+ util::MessageDifferencer::EQUIVALENT);
+ differencer.set_scope(util::MessageDifferencer::PARTIAL);
+ EXPECT_TRUE(differencer.Compare(msg1, msg2));
+}
+
+TEST(MessageDifferencerTest, PartialEquivalencyNotEqualTest) {
+ // Create the testing protos
+ unittest::TestAllTypes msg1;
+ unittest::TestAllTypes msg2;
+
+ TestUtil::SetAllFields(&msg1);
+ TestUtil::SetAllFields(&msg2);
+
+ msg1.set_optional_int32(0);
+ msg2.clear_optional_int32();
+
+ // Compare
+ EXPECT_FALSE(util::MessageDifferencer::Equals(msg1, msg2));
+ util::MessageDifferencer differencer;
+ differencer.set_message_field_comparison(
+ util::MessageDifferencer::EQUIVALENT);
+ differencer.set_scope(util::MessageDifferencer::PARTIAL);
+ EXPECT_TRUE(differencer.Compare(msg1, msg2));
+}
+
+TEST(MessageDifferencerTest, PartialEquivalencyTestExtraField) {
+ // Create the testing protos
+ unittest::TestAllTypes msg1;
+ unittest::TestAllTypes msg2;
+
+ TestUtil::SetAllFields(&msg1);
+ TestUtil::SetAllFields(&msg2);
+
+ msg1.clear_optional_int32();
+
+ // Compare
+ util::MessageDifferencer differencer;
+ differencer.set_message_field_comparison(
+ util::MessageDifferencer::EQUIVALENT);
+ differencer.set_scope(util::MessageDifferencer::PARTIAL);
+ EXPECT_TRUE(differencer.Compare(msg1, msg2));
+}
+
+TEST(MessageDifferencerTest, PartialEquivalencyTestSkipRequiredField) {
+ // Create the testing protos
+ unittest::TestRequired msg1;
+ unittest::TestRequired msg2;
+
+ msg1.set_a(401);
+ msg2.set_a(401);
+ msg2.set_b(402);
+
+ // Compare
+ util::MessageDifferencer differencer;
+ differencer.set_message_field_comparison(
+ util::MessageDifferencer::EQUIVALENT);
+ differencer.set_scope(util::MessageDifferencer::PARTIAL);
+ EXPECT_TRUE(differencer.Compare(msg1, msg2));
+}
+
+TEST(MessageDifferencerTest, BasicPartialInequivalencyTest) {
+ // Create the testing protos
+ unittest::TestAllTypes msg1;
+ unittest::TestAllTypes msg2;
+
+ TestUtil::SetAllFields(&msg1);
+ TestUtil::SetAllFields(&msg2);
+
+ msg1.set_optional_int32(-1);
+
+ // Compare
+ util::MessageDifferencer differencer;
+ differencer.set_message_field_comparison(
+ util::MessageDifferencer::EQUIVALENT);
+ differencer.set_scope(util::MessageDifferencer::PARTIAL);
+ EXPECT_FALSE(differencer.Compare(msg1, msg2));
+}
+
+TEST(MessageDifferencerTest, BasicPartialEquivalencyNonSetTest) {
+ // Create the testing protos
+ unittest::TestAllTypes msg1;
+ unittest::TestAllTypes msg2;
+
+ // Compare
+ util::MessageDifferencer differencer;
+ differencer.set_message_field_comparison(
+ util::MessageDifferencer::EQUIVALENT);
+ differencer.set_scope(util::MessageDifferencer::PARTIAL);
+ EXPECT_TRUE(differencer.Compare(msg1, msg2));
+}
+
+TEST(MessageDifferencerTest, BasicPartialInequivalencyNonSetTest) {
+ // Create the testing protos
+ unittest::TestAllTypes msg1;
+ unittest::TestAllTypes msg2;
+
+ msg1.set_optional_int32(-1);
+
+ // Compare
+ util::MessageDifferencer differencer;
+ differencer.set_message_field_comparison(
+ util::MessageDifferencer::EQUIVALENT);
+ differencer.set_scope(util::MessageDifferencer::PARTIAL);
+ EXPECT_FALSE(differencer.Compare(msg1, msg2));
+}
+
+TEST(MessageDifferencerTest, ApproximateEqualityTest) {
+ // Create the testing protos
+ unittest::TestAllTypes msg1;
+ unittest::TestAllTypes msg2;
+
+ TestUtil::SetAllFields(&msg1);
+ TestUtil::SetAllFields(&msg2);
+
+ // Compare
+ EXPECT_TRUE(util::MessageDifferencer::ApproximatelyEquals(msg1, msg2));
+}
+
+TEST(MessageDifferencerTest, ApproximateModifiedEqualityTest) {
+ // Create the testing protos
+ unittest::TestAllTypes msg1;
+ unittest::TestAllTypes msg2;
+
+ TestUtil::SetAllFields(&msg1);
+ TestUtil::SetAllFields(&msg2);
+
+ const float v1 = 2.300005f;
+ const float v2 = 2.300006f;
+ msg1.set_optional_float(v1);
+ msg2.set_optional_float(v2);
+
+ // Compare
+ ASSERT_NE(v1, v2) << "Should not be the same: " << v1 << ", " << v2;
+ ASSERT_FLOAT_EQ(v1, v2) << "Should be approx. equal: " << v1 << ", " << v2;
+ EXPECT_FALSE(util::MessageDifferencer::Equals(msg1, msg2));
+ EXPECT_TRUE(util::MessageDifferencer::ApproximatelyEquals(msg1, msg2));
+}
+
+TEST(MessageDifferencerTest, ApproximateEquivalencyTest) {
+ // Create the testing protos
+ unittest::TestAllTypes msg1;
+ unittest::TestAllTypes msg2;
+
+ TestUtil::SetAllFields(&msg1);
+ TestUtil::SetAllFields(&msg2);
+
+ // Compare
+ EXPECT_TRUE(util::MessageDifferencer::ApproximatelyEquivalent(msg1, msg2));
+}
+
+TEST(MessageDifferencerTest, ApproximateModifiedEquivalencyTest) {
+ // Create the testing protos
+ unittest::TestAllTypes msg1;
+ unittest::TestAllTypes msg2;
+
+ TestUtil::SetAllFields(&msg1);
+ TestUtil::SetAllFields(&msg2);
+
+ // Modify the approximateness requirement
+ const float v1 = 2.300005f;
+ const float v2 = 2.300006f;
+ msg1.set_optional_float(v1);
+ msg2.set_optional_float(v2);
+
+ // Compare
+ ASSERT_NE(v1, v2) << "Should not be the same: " << v1 << ", " << v2;
+ ASSERT_FLOAT_EQ(v1, v2) << "Should be approx. equal: " << v1 << ", " << v2;
+ EXPECT_FALSE(util::MessageDifferencer::Equals(msg1, msg2));
+ EXPECT_TRUE(util::MessageDifferencer::ApproximatelyEquivalent(msg1, msg2));
+
+ // Modify the equivalency requirement too
+ msg1.clear_optional_int32();
+ msg2.set_optional_int32(0);
+
+ // Compare. Now should only pass on ApproximatelyEquivalent
+ EXPECT_FALSE(util::MessageDifferencer::Equals(msg1, msg2));
+ EXPECT_FALSE(util::MessageDifferencer::Equivalent(msg1, msg2));
+ EXPECT_FALSE(util::MessageDifferencer::ApproximatelyEquals(msg1, msg2));
+ EXPECT_TRUE(util::MessageDifferencer::ApproximatelyEquivalent(msg1, msg2));
+}
+
+TEST(MessageDifferencerTest, ApproximateInequivalencyTest) {
+ // Create the testing protos
+ unittest::TestAllTypes msg1;
+ unittest::TestAllTypes msg2;
+
+ TestUtil::SetAllFields(&msg1);
+ TestUtil::SetAllFields(&msg2);
+
+ // Should fail on equivalency
+ msg1.set_optional_int32(-1);
+ EXPECT_FALSE(util::MessageDifferencer::ApproximatelyEquivalent(msg1, msg2));
+
+ // Make these fields the same again.
+ msg1.set_optional_int32(0);
+ msg2.set_optional_int32(0);
+ EXPECT_TRUE(util::MessageDifferencer::ApproximatelyEquivalent(msg1, msg2));
+
+ // Should fail on approximate equality check
+ const float v1 = 2.3f;
+ const float v2 = 9.3f;
+ msg1.set_optional_float(v1);
+ msg2.set_optional_float(v2);
+ EXPECT_FALSE(util::MessageDifferencer::ApproximatelyEquivalent(msg1, msg2));
+}
+
+TEST(MessageDifferencerTest, WithinFractionOrMarginFloatTest) {
+ // Create the testing protos
+ unittest::TestAllTypes msg1;
+ unittest::TestAllTypes msg2;
+
+ TestUtil::SetAllFields(&msg1);
+ TestUtil::SetAllFields(&msg2);
+
+ // Should fail on approximate equality check
+ const float v1 = 100.0f;
+ const float v2 = 109.9f;
+ msg1.set_optional_float(v1);
+ msg2.set_optional_float(v2);
+
+ // Compare
+ util::MessageDifferencer differencer;
+ EXPECT_FALSE(differencer.Compare(msg1, msg2));
+ const FieldDescriptor* fd =
+ msg1.GetDescriptor()->FindFieldByName("optional_float");
+
+ // Set float comparison to exact, margin and fraction value should not matter.
+ differencer.set_float_comparison(util::MessageDifferencer::EXACT);
+ // Set margin for float comparison.
+ differencer.SetFractionAndMargin(fd, 0.0, 10.0);
+ EXPECT_FALSE(differencer.Compare(msg1, msg2));
+
+ // Margin and fraction float comparison is activated when float comparison is
+ // set to approximate.
+ differencer.set_float_comparison(util::MessageDifferencer::APPROXIMATE);
+ EXPECT_TRUE(differencer.Compare(msg1, msg2));
+
+ // Test out float comparison with fraction.
+ differencer.SetFractionAndMargin(fd, 0.2, 0.0);
+ EXPECT_TRUE(differencer.Compare(msg1, msg2));
+
+ // Should fail since the fraction is smaller than error.
+ differencer.SetFractionAndMargin(fd, 0.01, 0.0);
+ EXPECT_FALSE(differencer.Compare(msg1, msg2));
+
+ // Should pass if either fraction or margin are satisfied.
+ differencer.SetFractionAndMargin(fd, 0.01, 10.0);
+ EXPECT_TRUE(differencer.Compare(msg1, msg2));
+
+ // Make sure that the margin and fraction only affects the field that it was
+ // set for.
+ msg1.set_default_float(v1);
+ msg2.set_default_float(v2);
+ EXPECT_FALSE(differencer.Compare(msg1, msg2));
+ msg1.set_default_float(v1);
+ msg2.set_default_float(v1);
+ EXPECT_TRUE(differencer.Compare(msg1, msg2));
+}
+
+TEST(MessageDifferencerTest, WithinFractionOrMarginDoubleTest) {
+ // Create the testing protos
+ unittest::TestAllTypes msg1;
+ unittest::TestAllTypes msg2;
+
+ TestUtil::SetAllFields(&msg1);
+ TestUtil::SetAllFields(&msg2);
+
+ // Should fail on approximate equality check
+ const double v1 = 100.0;
+ const double v2 = 109.9;
+ msg1.set_optional_double(v1);
+ msg2.set_optional_double(v2);
+
+ // Compare
+ util::MessageDifferencer differencer;
+ EXPECT_FALSE(differencer.Compare(msg1, msg2));
+
+ // Set comparison to exact, margin and fraction value should not matter.
+ differencer.set_float_comparison(util::MessageDifferencer::EXACT);
+ // Set margin for float comparison.
+ const FieldDescriptor* fd =
+ msg1.GetDescriptor()->FindFieldByName("optional_double");
+ differencer.SetFractionAndMargin(fd, 0.0, 10.0);
+ EXPECT_FALSE(differencer.Compare(msg1, msg2));
+
+ // Margin and fraction comparison is activated when float comparison is
+ // set to approximate.
+ differencer.set_float_comparison(util::MessageDifferencer::APPROXIMATE);
+ EXPECT_TRUE(differencer.Compare(msg1, msg2));
+
+ // Test out comparison with fraction.
+ differencer.SetFractionAndMargin(fd, 0.2, 0.0);
+ EXPECT_TRUE(differencer.Compare(msg1, msg2));
+
+ // Should fail since the fraction is smaller than error.
+ differencer.SetFractionAndMargin(fd, 0.01, 0.0);
+ EXPECT_FALSE(differencer.Compare(msg1, msg2));
+
+ // Should pass if either fraction or margin are satisfied.
+ differencer.SetFractionAndMargin(fd, 0.01, 10.0);
+ EXPECT_TRUE(differencer.Compare(msg1, msg2));
+
+ // Make sure that the margin and fraction only affects the field that it was
+ // set for.
+ msg1.set_default_double(v1);
+ msg2.set_default_double(v2);
+ EXPECT_FALSE(differencer.Compare(msg1, msg2));
+ msg1.set_default_double(v1);
+ msg2.set_default_double(v1);
+ EXPECT_TRUE(differencer.Compare(msg1, msg2));
+}
+
+TEST(MessageDifferencerTest, WithinDefaultFractionOrMarginDoubleTest) {
+ // Create the testing protos
+ unittest::TestAllTypes msg1;
+ unittest::TestAllTypes msg2;
+
+ TestUtil::SetAllFields(&msg1);
+ TestUtil::SetAllFields(&msg2);
+
+ // Should fail on approximate equality check
+ const double v1 = 100.0;
+ const double v2 = 109.9;
+ msg1.set_optional_double(v1);
+ msg2.set_optional_double(v2);
+
+ util::MessageDifferencer differencer;
+
+ // Compare
+ EXPECT_FALSE(differencer.Compare(msg1, msg2));
+
+ // Set up a custom field comparator, with a default fraction and margin for
+ // float and double comparison.
+ util::DefaultFieldComparator field_comparator;
+ field_comparator.SetDefaultFractionAndMargin(0.0, 10.0);
+ differencer.set_field_comparator(&field_comparator);
+
+ // Set comparison to exact, margin and fraction value should not matter.
+ field_comparator.set_float_comparison(util::DefaultFieldComparator::EXACT);
+ EXPECT_FALSE(differencer.Compare(msg1, msg2));
+
+ // Margin and fraction comparison is activated when float comparison is
+ // set to approximate.
+ field_comparator.set_float_comparison(
+ util::DefaultFieldComparator::APPROXIMATE);
+ EXPECT_TRUE(differencer.Compare(msg1, msg2));
+
+ // Test out comparison with fraction.
+ field_comparator.SetDefaultFractionAndMargin(0.2, 0.0);
+ EXPECT_TRUE(differencer.Compare(msg1, msg2));
+
+ // Should fail since the fraction is smaller than error.
+ field_comparator.SetDefaultFractionAndMargin(0.01, 0.0);
+ EXPECT_FALSE(differencer.Compare(msg1, msg2));
+
+ // Should pass if either fraction or margin are satisfied.
+ field_comparator.SetDefaultFractionAndMargin(0.01, 10.0);
+ EXPECT_TRUE(differencer.Compare(msg1, msg2));
+
+ // Make sure that the default margin and fraction affects all fields
+ msg1.set_default_double(v1);
+ msg2.set_default_double(v2);
+ EXPECT_TRUE(differencer.Compare(msg1, msg2));
+}
+
+TEST(MessageDifferencerTest, BasicFieldOrderingsTest) {
+ // Create the testing protos
+ unittest::TestFieldOrderings msg1;
+ unittest::TestFieldOrderings msg2;
+
+ TestUtil::SetAllFieldsAndExtensions(&msg1);
+ TestUtil::SetAllFieldsAndExtensions(&msg2);
+
+ // Compare
+ EXPECT_TRUE(util::MessageDifferencer::Equals(msg1, msg2));
+}
+
+TEST(MessageDifferencerTest, BasicFieldOrderingInequalityTest) {
+ // Create the testing protos
+ unittest::TestFieldOrderings msg1;
+ unittest::TestFieldOrderings msg2;
+
+ TestUtil::SetAllFieldsAndExtensions(&msg1);
+ TestUtil::SetAllFieldsAndExtensions(&msg2);
+
+ msg1.set_my_float(15.00);
+ msg2.set_my_float(16.00);
+
+ // Compare
+ EXPECT_FALSE(util::MessageDifferencer::Equals(msg1, msg2));
+}
+
+TEST(MessageDifferencerTest, BasicExtensionTest) {
+ // Create the testing protos
+ unittest::TestAllExtensions msg1;
+ unittest::TestAllExtensions msg2;
+
+ TestUtil::SetAllExtensions(&msg1);
+ TestUtil::SetAllExtensions(&msg2);
+
+ // Compare
+ EXPECT_TRUE(util::MessageDifferencer::Equals(msg1, msg2));
+}
+
+TEST(MessageDifferencerTest, BasicExtensionInequalityTest) {
+ // Create the testing protos
+ unittest::TestAllExtensions msg1;
+ unittest::TestAllExtensions msg2;
+
+ TestUtil::SetAllExtensions(&msg1);
+ TestUtil::SetAllExtensions(&msg2);
+
+ msg1.SetExtension(unittest::optional_int32_extension, 101);
+ msg2.SetExtension(unittest::optional_int32_extension, 102);
+
+ // Compare
+ EXPECT_FALSE(util::MessageDifferencer::Equals(msg1, msg2));
+}
+
+TEST(MessageDifferencerTest, OneofTest) {
+ // Create the testing protos
+ unittest::TestOneof2 msg1;
+ unittest::TestOneof2 msg2;
+
+ TestUtil::SetOneof1(&msg1);
+ TestUtil::SetOneof1(&msg2);
+
+ // Compare
+ EXPECT_TRUE(util::MessageDifferencer::Equals(msg1, msg2));
+}
+
+TEST(MessageDifferencerTest, OneofInequalityTest) {
+ // Create the testing protos
+ unittest::TestOneof2 msg1;
+ unittest::TestOneof2 msg2;
+
+ TestUtil::SetOneof1(&msg1);
+ TestUtil::SetOneof2(&msg2);
+
+ // Compare
+ EXPECT_FALSE(util::MessageDifferencer::Equals(msg1, msg2));
+}
+
+TEST(MessageDifferencerTest, UnknownFieldPartialEqualTest) {
+ unittest::TestEmptyMessage empty1;
+ unittest::TestEmptyMessage empty2;
+
+ UnknownFieldSet* unknown1 = empty1.mutable_unknown_fields();
+ UnknownFieldSet* unknown2 = empty2.mutable_unknown_fields();
+
+ unknown1->AddVarint(243, 122);
+ unknown1->AddLengthDelimited(245, "abc");
+ unknown1->AddGroup(246)->AddFixed32(248, 1);
+ unknown1->mutable_field(2)->mutable_group()->AddFixed32(248, 2);
+
+ unknown2->AddVarint(243, 122);
+ unknown2->AddLengthDelimited(245, "abc");
+ unknown2->AddGroup(246)->AddFixed32(248, 1);
+ unknown2->mutable_field(2)->mutable_group()->AddFixed32(248, 2);
+
+ util::MessageDifferencer differencer;
+ differencer.set_scope(util::MessageDifferencer::PARTIAL);
+ EXPECT_TRUE(differencer.Compare(empty1, empty2));
+}
+
+TEST(MessageDifferencerTest, SpecifiedFieldsEqualityAllTest) {
+ unittest::TestAllTypes msg1;
+ unittest::TestAllTypes msg2;
+
+ TestUtil::SetAllFields(&msg1);
+ TestUtil::SetAllFields(&msg2);
+
+ std::vector<const FieldDescriptor*> fields1;
+ std::vector<const FieldDescriptor*> fields2;
+ msg1.GetReflection()->ListFields(msg1, &fields1);
+ msg2.GetReflection()->ListFields(msg2, &fields2);
+
+ util::MessageDifferencer differencer;
+ EXPECT_TRUE(differencer.CompareWithFields(msg1, msg2, fields1, fields2));
+}
+
+TEST(MessageDifferencerTest, SpecifiedFieldsInequalityAllTest) {
+ unittest::TestAllTypes msg1;
+ unittest::TestAllTypes msg2;
+
+ TestUtil::SetAllFields(&msg1);
+
+ std::vector<const FieldDescriptor*> fields1;
+ std::vector<const FieldDescriptor*> fields2;
+ msg1.GetReflection()->ListFields(msg1, &fields1);
+ msg2.GetReflection()->ListFields(msg2, &fields2);
+
+ util::MessageDifferencer differencer;
+ EXPECT_FALSE(differencer.CompareWithFields(msg1, msg2, fields1, fields2));
+}
+
+TEST(MessageDifferencerTest, SpecifiedFieldsEmptyListAlwaysSucceeds) {
+ unittest::TestAllTypes msg1;
+ unittest::TestAllTypes msg2;
+
+ TestUtil::SetAllFields(&msg1);
+
+ std::vector<const FieldDescriptor*> empty_fields;
+
+ util::MessageDifferencer differencer;
+ EXPECT_TRUE(
+ differencer.CompareWithFields(msg1, msg2, empty_fields, empty_fields));
+
+ TestUtil::SetAllFields(&msg2);
+ EXPECT_TRUE(
+ differencer.CompareWithFields(msg1, msg2, empty_fields, empty_fields));
+}
+
+TEST(MessageDifferencerTest, SpecifiedFieldsCompareWithSelf) {
+ unittest::TestAllTypes msg1;
+ TestUtil::SetAllFields(&msg1);
+
+ std::vector<const FieldDescriptor*> fields;
+ msg1.GetReflection()->ListFields(msg1, &fields);
+
+ util::MessageDifferencer differencer;
+ EXPECT_TRUE(differencer.CompareWithFields(msg1, msg1, fields, fields));
+
+ {
+ // Compare with a subset of fields.
+ std::vector<const FieldDescriptor*> compare_fields;
+ for (int i = 0; i < fields.size(); ++i) {
+ if (i % 2 == 0) {
+ compare_fields.push_back(fields[i]);
+ }
+ }
+ EXPECT_TRUE(differencer.CompareWithFields(msg1, msg1, compare_fields,
+ compare_fields));
+ }
+ {
+ // Specify a different set of fields to compare, even though we're using the
+ // same message. This should fail, since we are explicitly saying that the
+ // set of fields are different.
+ std::vector<const FieldDescriptor*> compare_fields1;
+ std::vector<const FieldDescriptor*> compare_fields2;
+ for (int i = 0; i < fields.size(); ++i) {
+ if (i % 2 == 0) {
+ compare_fields1.push_back(fields[i]);
+ } else {
+ compare_fields2.push_back(fields[i]);
+ }
+ }
+ EXPECT_FALSE(differencer.CompareWithFields(msg1, msg1, compare_fields1,
+ compare_fields2));
+ }
+}
+
+TEST(MessageDifferencerTest, SpecifiedFieldsEqualityAllShuffledTest) {
+ // This is a public function, so make sure there are no assumptions about the
+ // list of fields. Randomly shuffle them to make sure that they are properly
+ // ordered for comparison.
+ unittest::TestAllTypes msg1;
+ unittest::TestAllTypes msg2;
+
+ TestUtil::SetAllFields(&msg1);
+ TestUtil::SetAllFields(&msg2);
+
+ std::vector<const FieldDescriptor*> fields1;
+ std::vector<const FieldDescriptor*> fields2;
+ msg1.GetReflection()->ListFields(msg1, &fields1);
+ msg2.GetReflection()->ListFields(msg2, &fields2);
+
+ std::default_random_engine rng;
+ std::shuffle(fields1.begin(), fields1.end(), rng);
+ std::shuffle(fields2.begin(), fields2.end(), rng);
+
+ util::MessageDifferencer differencer;
+ EXPECT_TRUE(differencer.CompareWithFields(msg1, msg2, fields1, fields2));
+}
+
+TEST(MessageDifferencerTest, SpecifiedFieldsSubsetEqualityTest) {
+ // Specify a set of fields to compare. All the fields are equal.
+ unittest::TestAllTypes msg1;
+ unittest::TestAllTypes msg2;
+ TestUtil::SetAllFields(&msg1);
+ TestUtil::SetAllFields(&msg2);
+
+ std::vector<const FieldDescriptor*> fields1;
+ msg1.GetReflection()->ListFields(msg1, &fields1);
+
+ std::vector<const FieldDescriptor*> compare_fields;
+ // Only compare the field descriptors with even indices.
+ for (int i = 0; i < fields1.size(); ++i) {
+ if (i % 2 == 0) {
+ compare_fields.push_back(fields1[i]);
+ }
+ }
+
+ util::MessageDifferencer differencer;
+ EXPECT_TRUE(differencer.CompareWithFields(msg1, msg2, compare_fields,
+ compare_fields));
+}
+
+TEST(MessageDifferencerTest,
+ SpecifiedFieldsSubsetIgnoresOtherFieldDifferencesTest) {
+ // Specify a set of fields to compare, but clear all the other fields in one
+ // of the messages. This should fail a regular compare, but CompareWithFields
+ // should succeed.
+ unittest::TestAllTypes msg1;
+ unittest::TestAllTypes msg2;
+ TestUtil::SetAllFields(&msg1);
+ TestUtil::SetAllFields(&msg2);
+
+ std::vector<const FieldDescriptor*> fields1;
+ const Reflection* reflection = msg1.GetReflection();
+ reflection->ListFields(msg1, &fields1);
+
+ std::vector<const FieldDescriptor*> compare_fields;
+ // Only compare the field descriptors with even indices.
+ for (int i = 0; i < fields1.size(); ++i) {
+ if (i % 2 == 0) {
+ compare_fields.push_back(fields1[i]);
+ } else {
+ reflection->ClearField(&msg2, fields1[i]);
+ }
+ }
+
+ util::MessageDifferencer differencer;
+ EXPECT_FALSE(differencer.Compare(msg1, msg2));
+ EXPECT_TRUE(differencer.CompareWithFields(msg1, msg2, compare_fields,
+ compare_fields));
+}
+
+TEST(MessageDifferencerTest, SpecifiedFieldsDetectsDifferencesTest) {
+ // Change all of the repeated fields in one of the messages, and use only
+ // those fields for comparison.
+ unittest::TestAllTypes msg1;
+ unittest::TestAllTypes msg2;
+ TestUtil::SetAllFields(&msg1);
+ TestUtil::SetAllFields(&msg2);
+ TestUtil::ModifyRepeatedFields(&msg2);
+
+ std::vector<const FieldDescriptor*> fields1;
+ msg1.GetReflection()->ListFields(msg1, &fields1);
+
+ std::vector<const FieldDescriptor*> compare_fields;
+ // Only compare the repeated field descriptors.
+ for (int i = 0; i < fields1.size(); ++i) {
+ if (fields1[i]->is_repeated()) {
+ compare_fields.push_back(fields1[i]);
+ }
+ }
+
+ util::MessageDifferencer differencer;
+ EXPECT_FALSE(differencer.CompareWithFields(msg1, msg2, compare_fields,
+ compare_fields));
+}
+
+TEST(MessageDifferencerTest, SpecifiedFieldsEquivalenceAllTest) {
+ unittest::TestAllTypes msg1;
+ unittest::TestAllTypes msg2;
+
+ TestUtil::SetAllFields(&msg1);
+ TestUtil::SetAllFields(&msg2);
+
+ std::vector<const FieldDescriptor*> fields1;
+ std::vector<const FieldDescriptor*> fields2;
+ msg1.GetReflection()->ListFields(msg1, &fields1);
+ msg2.GetReflection()->ListFields(msg2, &fields2);
+
+ util::MessageDifferencer differencer;
+ differencer.set_message_field_comparison(
+ util::MessageDifferencer::EQUIVALENT);
+ EXPECT_TRUE(differencer.CompareWithFields(msg1, msg2, fields1, fields2));
+}
+
+TEST(MessageDifferencerTest,
+ SpecifiedFieldsEquivalenceIgnoresOtherFieldDifferencesTest) {
+ unittest::TestAllTypes msg1;
+ unittest::TestAllTypes msg2;
+ const Descriptor* desc = msg1.GetDescriptor();
+
+ const FieldDescriptor* optional_int32_desc =
+ desc->FindFieldByName("optional_int32");
+ const FieldDescriptor* optional_int64_desc =
+ desc->FindFieldByName("optional_int64");
+ const FieldDescriptor* default_int64_desc =
+ desc->FindFieldByName("default_int64");
+ ASSERT_TRUE(optional_int32_desc != NULL);
+ ASSERT_TRUE(optional_int64_desc != NULL);
+ ASSERT_TRUE(default_int64_desc != NULL);
+ msg1.set_optional_int32(0);
+ msg2.set_optional_int64(0);
+ msg1.set_default_int64(default_int64_desc->default_value_int64());
+
+ // Set a field to a non-default value so we know that field selection is
+ // actually doing something.
+ msg2.set_optional_uint64(23);
+
+ std::vector<const FieldDescriptor*> fields1;
+ std::vector<const FieldDescriptor*> fields2;
+ fields1.push_back(optional_int32_desc);
+ fields1.push_back(default_int64_desc);
+
+ fields2.push_back(optional_int64_desc);
+
+ util::MessageDifferencer differencer;
+ EXPECT_FALSE(differencer.CompareWithFields(msg1, msg2, fields1, fields2));
+ differencer.set_message_field_comparison(
+ util::MessageDifferencer::EQUIVALENT);
+ EXPECT_FALSE(differencer.Compare(msg1, msg2));
+ EXPECT_TRUE(differencer.CompareWithFields(msg1, msg2, fields1, fields2));
+}
+
+TEST(MessageDifferencerTest, RepeatedFieldTreatmentChangeListToSet) {
+ protobuf_unittest::TestDiffMessage msg1;
+ protobuf_unittest::TestDiffMessage msg2;
+
+ msg1.add_rv(1);
+ msg1.add_rv(2);
+ msg2.add_rv(2);
+ msg2.add_rv(1);
+
+ util::MessageDifferencer differencer;
+ differencer.TreatAsList(
+ protobuf_unittest::TestDiffMessage::descriptor()->FindFieldByName("rv"));
+ differencer.TreatAsSet(
+ protobuf_unittest::TestDiffMessage::descriptor()->FindFieldByName("rv"));
+
+ EXPECT_TRUE(differencer.Compare(msg1, msg2));
+}
+
+TEST(MessageDifferencerTest, RepeatedFieldTreatmentChangeSetToList) {
+ protobuf_unittest::TestDiffMessage msg1;
+ protobuf_unittest::TestDiffMessage msg2;
+
+ msg1.add_rv(1);
+ msg1.add_rv(2);
+ msg2.add_rv(2);
+ msg2.add_rv(1);
+
+ util::MessageDifferencer differencer;
+ differencer.TreatAsSet(
+ protobuf_unittest::TestDiffMessage::descriptor()->FindFieldByName("rv"));
+ differencer.TreatAsList(
+ protobuf_unittest::TestDiffMessage::descriptor()->FindFieldByName("rv"));
+
+ EXPECT_FALSE(differencer.Compare(msg1, msg2));
+}
+
+TEST(MessageDifferencerTest, RepeatedFieldSmartListTest) {
+ // Create the testing protos
+ protobuf_unittest::TestDiffMessage msg1;
+ protobuf_unittest::TestDiffMessage msg2;
+
+ msg1.add_rv(1);
+ msg1.add_rv(2);
+ msg1.add_rv(3);
+ msg1.add_rv(9);
+ msg1.add_rv(4);
+ msg1.add_rv(5);
+ msg1.add_rv(7);
+ msg1.add_rv(2);
+ msg2.add_rv(9);
+ msg2.add_rv(0);
+ msg2.add_rv(2);
+ msg2.add_rv(7);
+ msg2.add_rv(3);
+ msg2.add_rv(4);
+ msg2.add_rv(5);
+ msg2.add_rv(6);
+ msg2.add_rv(2);
+ // Compare
+ // a: 1, 2, 3, 9, 4, 5, 7, 2
+ // b: 9, 0, 2, 7, 3, 4, 5, 6, 2
+ std::string diff_report;
+ util::MessageDifferencer differencer;
+ differencer.ReportDifferencesToString(&diff_report);
+ differencer.set_repeated_field_comparison(
+ util::MessageDifferencer::AS_SMART_LIST);
+ EXPECT_FALSE(differencer.Compare(msg1, msg2));
+ EXPECT_EQ(
+ "deleted: rv[0]: 1\n"
+ "added: rv[0]: 9\n"
+ "added: rv[1]: 0\n"
+ "moved: rv[1] -> rv[2] : 2\n"
+ "added: rv[3]: 7\n"
+ "moved: rv[2] -> rv[4] : 3\n"
+ "deleted: rv[3]: 9\n"
+ "moved: rv[4] -> rv[5] : 4\n"
+ "moved: rv[5] -> rv[6] : 5\n"
+ "deleted: rv[6]: 7\n"
+ "added: rv[7]: 6\n"
+ "moved: rv[7] -> rv[8] : 2\n",
+ diff_report);
+
+ // Compare two sub messages
+ // a: 1, 2, 3, 4, 5
+ // b: 2, 6, 4,
+ msg1.Clear();
+ msg2.Clear();
+ msg1.add_rm()->set_a(1);
+ msg1.add_rm()->set_a(2);
+ msg1.add_rm()->set_a(3);
+ msg1.add_rm()->set_a(4);
+ msg1.add_rm()->set_a(5);
+ msg2.add_rm()->set_a(2);
+ msg2.add_rm()->set_a(6);
+ msg2.add_rm()->set_a(4);
+ differencer.ReportDifferencesToString(&diff_report);
+ differencer.set_repeated_field_comparison(
+ util::MessageDifferencer::AS_SMART_LIST);
+ EXPECT_FALSE(differencer.Compare(msg1, msg2));
+ EXPECT_EQ(
+ "deleted: rm[0]: { a: 1 }\n"
+ "moved: rm[1] -> rm[0] : { a: 2 }\n"
+ "deleted: rm[2]: { a: 3 }\n"
+ "added: rm[1]: { a: 6 }\n"
+ "moved: rm[3] -> rm[2] : { a: 4 }\n"
+ "deleted: rm[4]: { a: 5 }\n",
+ diff_report);
+}
+
+TEST(MessageDifferencerTest, RepeatedFieldSmartSetTest) {
+ // Create the testing protos
+ protobuf_unittest::TestDiffMessage msg1;
+ protobuf_unittest::TestDiffMessage msg2;
+ protobuf_unittest::TestField elem1_1, elem2_1, elem3_1;
+ protobuf_unittest::TestField elem1_2, elem2_2, elem3_2;
+
+ // Only one field is different for each pair of elememts
+ elem1_1.set_a(1);
+ elem1_2.set_a(0);
+ elem1_1.set_b(1);
+ elem1_2.set_b(1);
+ elem1_1.set_c(1);
+ elem1_2.set_c(1);
+ elem2_1.set_a(2);
+ elem2_2.set_a(2);
+ elem2_1.set_b(2);
+ elem2_2.set_b(0);
+ elem2_1.set_c(2);
+ elem2_2.set_c(2);
+ elem3_1.set_a(3);
+ elem3_2.set_a(3);
+ elem3_1.set_b(3);
+ elem3_2.set_b(0);
+ elem3_1.set_c(3);
+ elem3_2.set_c(3);
+
+ *msg1.add_rm() = elem1_1;
+ *msg1.add_rm() = elem2_1;
+ *msg1.add_rm() = elem3_1;
+ // Change the order of those elements for the second message.
+ *msg2.add_rm() = elem3_2;
+ *msg2.add_rm() = elem1_2;
+ *msg2.add_rm() = elem2_2;
+
+ std::string diff_report;
+ util::MessageDifferencer differencer;
+ differencer.ReportDifferencesToString(&diff_report);
+ differencer.set_repeated_field_comparison(
+ util::MessageDifferencer::AS_SMART_SET);
+ EXPECT_FALSE(differencer.Compare(msg1, msg2));
+ EXPECT_EQ(
+ "modified: rm[0].a -> rm[1].a: 1 -> 0\n"
+ "modified: rm[1].b -> rm[2].b: 2 -> 0\n"
+ "modified: rm[2].b -> rm[0].b: 3 -> 0\n",
+ diff_report);
+}
+
+TEST(MessageDifferencerTest, RepeatedFieldSmartSetTest_IdenticalElements) {
+ // Create the testing protos
+ protobuf_unittest::TestDiffMessage msg1;
+ protobuf_unittest::TestDiffMessage msg2;
+ protobuf_unittest::TestField elem;
+
+ elem.set_a(1);
+ elem.set_b(1);
+ elem.set_c(1);
+
+ *msg1.add_rm() = elem;
+ *msg1.add_rm() = elem;
+ *msg2.add_rm() = elem;
+ *msg2.add_rm() = elem;
+
+ util::MessageDifferencer differencer;
+ differencer.set_repeated_field_comparison(
+ util::MessageDifferencer::AS_SMART_SET);
+ EXPECT_TRUE(differencer.Compare(msg1, msg2));
+}
+
+TEST(MessageDifferencerTest, RepeatedFieldSmartSetTest_PreviouslyMatch) {
+ // Create the testing protos
+ protobuf_unittest::TestDiffMessage msg1;
+ protobuf_unittest::TestDiffMessage msg2;
+ protobuf_unittest::TestField elem1_1, elem1_2;
+ protobuf_unittest::TestField elem2_1, elem2_2;
+
+ elem1_1.set_a(1);
+ elem1_1.set_b(1);
+ elem1_1.set_c(1);
+ elem1_2.set_a(1);
+ elem1_2.set_b(1);
+ elem1_2.set_c(0);
+
+ elem2_1.set_a(1);
+ elem2_1.set_b(1);
+ elem2_1.set_c(1);
+ elem2_2.set_a(1);
+ elem2_2.set_b(0);
+ elem2_2.set_c(1);
+
+ *msg1.add_rm() = elem1_1;
+ *msg1.add_rm() = elem2_1;
+ *msg2.add_rm() = elem1_2;
+ *msg2.add_rm() = elem2_2;
+
+ std::string diff_report;
+ util::MessageDifferencer differencer;
+ differencer.ReportDifferencesToString(&diff_report);
+ differencer.set_repeated_field_comparison(
+ util::MessageDifferencer::AS_SMART_SET);
+ EXPECT_FALSE(differencer.Compare(msg1, msg2));
+ EXPECT_EQ(
+ "modified: rm[0].c: 1 -> 0\n"
+ "modified: rm[1].b: 1 -> 0\n",
+ diff_report);
+}
+
+TEST(MessageDifferencerTest, RepeatedFieldSmartSet_MultipleMatches) {
+ // Create the testing protos
+ protobuf_unittest::TestDiffMessage msg1;
+ protobuf_unittest::TestDiffMessage msg2;
+ protobuf_unittest::TestField elem1_1, elem2_1, elem3_1;
+ protobuf_unittest::TestField elem2_2, elem3_2;
+
+ // Only one field is different for each pair of elememts
+ elem1_1.set_a(1);
+ elem1_1.set_b(1);
+ elem1_1.set_c(1);
+ elem2_1.set_a(2);
+ elem2_2.set_a(2);
+ elem2_1.set_b(2);
+ elem2_2.set_b(0);
+ elem2_1.set_c(2);
+ elem2_2.set_c(2);
+ elem3_1.set_a(3);
+ elem3_2.set_a(3);
+ elem3_1.set_b(3);
+ elem3_2.set_b(0);
+ elem3_1.set_c(3);
+ elem3_2.set_c(3);
+
+ // In this testcase, elem1_1 will match with elem2_2 first and then get
+ // reverted because elem2_1 matches with elem2_2 later.
+ *msg1.add_rm() = elem1_1;
+ *msg1.add_rm() = elem2_1;
+ *msg1.add_rm() = elem3_1;
+ *msg2.add_rm() = elem2_2;
+ *msg2.add_rm() = elem3_2;
+
+ std::string diff_report;
+ util::MessageDifferencer differencer;
+ differencer.ReportDifferencesToString(&diff_report);
+ differencer.set_repeated_field_comparison(
+ util::MessageDifferencer::AS_SMART_SET);
+ EXPECT_FALSE(differencer.Compare(msg1, msg2));
+ EXPECT_EQ(
+ "modified: rm[1].b -> rm[0].b: 2 -> 0\n"
+ "modified: rm[2].b -> rm[1].b: 3 -> 0\n"
+ "deleted: rm[0]: { c: 1 a: 1 b: 1 }\n",
+ diff_report);
+}
+
+TEST(MessageDifferencerTest, RepeatedFieldSmartSet_MultipleMatchesNoReporter) {
+ protobuf_unittest::TestDiffMessage msg1;
+ protobuf_unittest::TestDiffMessage msg2;
+ protobuf_unittest::TestField elem1, elem2, elem3, elem4;
+ elem1.set_a(1);
+ elem2.set_a(2);
+ elem3.set_a(3);
+ elem4.set_a(4);
+
+ *msg1.add_rm() = elem1;
+ *msg1.add_rm() = elem2;
+ *msg1.add_rm() = elem3;
+ *msg2.add_rm() = elem2;
+ *msg2.add_rm() = elem3;
+ *msg2.add_rm() = elem4;
+
+ util::MessageDifferencer differencer;
+ differencer.set_repeated_field_comparison(
+ util::MessageDifferencer::AS_SMART_SET);
+ EXPECT_FALSE(differencer.Compare(msg1, msg2));
+}
+
+TEST(MessageDifferencerTest, RepeatedFieldSmartSet_NonMessageTypeTest) {
+ // Create the testing protos
+ protobuf_unittest::TestDiffMessage msg1;
+ protobuf_unittest::TestDiffMessage msg2;
+
+ // Create 3 elements, but in different order.
+ msg1.add_rw("b");
+ msg2.add_rw("a");
+ msg1.add_rw("x");
+ msg2.add_rw("x");
+ msg1.add_rw("a");
+ msg2.add_rw("b");
+
+ std::string diff_report;
+ util::MessageDifferencer differencer;
+ differencer.ReportDifferencesToString(&diff_report);
+ differencer.set_repeated_field_comparison(
+ util::MessageDifferencer::AS_SMART_SET);
+ EXPECT_TRUE(differencer.Compare(msg1, msg2));
+ EXPECT_EQ(
+ "moved: rw[0] -> rw[2] : \"b\"\n"
+ "moved: rw[2] -> rw[0] : \"a\"\n",
+ diff_report);
+}
+
+TEST(MessageDifferencerTest, RepeatedFieldSetTest_SetOfSet) {
+ // Create the testing protos
+ protobuf_unittest::TestDiffMessage msg1;
+ protobuf_unittest::TestDiffMessage msg2;
+
+ protobuf_unittest::TestDiffMessage::Item* item = msg1.add_item();
+ item->add_ra(1);
+ item->add_ra(2);
+ item->add_ra(3);
+ item = msg1.add_item();
+ item->add_ra(5);
+ item->add_ra(6);
+ item = msg1.add_item();
+ item->add_ra(1);
+ item->add_ra(3);
+ item = msg1.add_item();
+ item->add_ra(6);
+ item->add_ra(7);
+ item->add_ra(8);
+
+ item = msg2.add_item();
+ item->add_ra(6);
+ item->add_ra(5);
+ item = msg2.add_item();
+ item->add_ra(6);
+ item->add_ra(8);
+ item->add_ra(7);
+ item = msg2.add_item();
+ item->add_ra(1);
+ item->add_ra(3);
+ item = msg2.add_item();
+ item->add_ra(3);
+ item->add_ra(2);
+ item->add_ra(1);
+
+ // Compare
+ util::MessageDifferencer differencer;
+ differencer.set_repeated_field_comparison(util::MessageDifferencer::AS_SET);
+ EXPECT_TRUE(differencer.Compare(msg1, msg2));
+}
+
+TEST(MessageDifferencerTest, RepeatedFieldSetTest_Combination) {
+ // Create the testing protos
+ protobuf_unittest::TestDiffMessage msg1;
+ protobuf_unittest::TestDiffMessage msg2;
+ // Treat "item" as Map, with key = "a"
+ // Treat "item.ra" also as Set
+ // Treat "rv" as Set
+ // Treat "rw" as List
+ protobuf_unittest::TestDiffMessage::Item* item = msg1.add_item();
+ item->set_a(3);
+ item->add_ra(1);
+ item->add_ra(2);
+ item->add_ra(3);
+ item = msg1.add_item();
+ item->set_a(4);
+ item->add_ra(5);
+ item->add_ra(6);
+ item = msg1.add_item();
+ item->set_a(1);
+ item->add_ra(1);
+ item->add_ra(3);
+ item = msg1.add_item();
+ item->set_a(2);
+ item->add_ra(6);
+ item->add_ra(7);
+ item->add_ra(8);
+
+ item = msg2.add_item();
+ item->set_a(4);
+ item->add_ra(6);
+ item->add_ra(5);
+ item = msg2.add_item();
+ item->set_a(2);
+ item->add_ra(6);
+ item->add_ra(8);
+ item->add_ra(7);
+ item = msg2.add_item();
+ item->set_a(1);
+ item->add_ra(1);
+ item->add_ra(3);
+ item = msg2.add_item();
+ item->set_a(3);
+ item->add_ra(3);
+ item->add_ra(2);
+ item->add_ra(1);
+
+ msg1.add_rv(3);
+ msg1.add_rv(4);
+ msg1.add_rv(7);
+ msg1.add_rv(0);
+ msg2.add_rv(4);
+ msg2.add_rv(3);
+ msg2.add_rv(0);
+ msg2.add_rv(7);
+
+ msg1.add_rw("nothing");
+ msg2.add_rw("nothing");
+ msg1.add_rw("should");
+ msg2.add_rw("should");
+ msg1.add_rw("change");
+ msg2.add_rw("change");
+
+ // Compare
+ util::MessageDifferencer differencer1;
+ differencer1.TreatAsMap(msg1.GetDescriptor()->FindFieldByName("item"),
+ item->GetDescriptor()->FindFieldByName("a"));
+ differencer1.TreatAsSet(msg1.GetDescriptor()->FindFieldByName("rv"));
+ differencer1.TreatAsSet(item->GetDescriptor()->FindFieldByName("ra"));
+ EXPECT_TRUE(differencer1.Compare(msg1, msg2));
+
+ util::MessageDifferencer differencer2;
+ differencer2.TreatAsMap(msg1.GetDescriptor()->FindFieldByName("item"),
+ item->GetDescriptor()->FindFieldByName("a"));
+ differencer2.set_repeated_field_comparison(util::MessageDifferencer::AS_SET);
+ differencer2.TreatAsList(msg1.GetDescriptor()->FindFieldByName("rw"));
+ EXPECT_TRUE(differencer2.Compare(msg1, msg2));
+}
+
+TEST(MessageDifferencerTest, RepeatedFieldMapTest_Partial) {
+ protobuf_unittest::TestDiffMessage msg1;
+ // message msg1 {
+ // item { a: 1; b: "11" }
+ // }
+ protobuf_unittest::TestDiffMessage::Item* item = msg1.add_item();
+ item->set_a(1);
+ item->set_b("11");
+
+ protobuf_unittest::TestDiffMessage msg2;
+ // message msg2 {
+ // item { a: 2; b: "22" }
+ // item { a: 1; b: "11" }
+ // }
+ item = msg2.add_item();
+ item->set_a(2);
+ item->set_b("22");
+ item = msg2.add_item();
+ item->set_a(1);
+ item->set_b("11");
+
+ // Compare
+ util::MessageDifferencer differencer;
+ differencer.TreatAsMap(GetFieldDescriptor(msg1, "item"),
+ GetFieldDescriptor(msg1, "item.a"));
+ differencer.set_scope(util::MessageDifferencer::PARTIAL);
+ EXPECT_TRUE(differencer.Compare(msg1, msg2));
+}
+
+TEST(MessageDifferencerTest, RepeatedFieldSetTest_Duplicates) {
+ protobuf_unittest::TestDiffMessage a, b, c;
+ // message a: {
+ // rv: 0
+ // rv: 1
+ // rv: 0
+ // }
+ a.add_rv(0);
+ a.add_rv(1);
+ a.add_rv(0);
+ // message b: {
+ // rv: 0
+ // rv: 0
+ // rv: 1
+ // }
+ b.add_rv(0);
+ b.add_rv(0);
+ b.add_rv(1);
+ // message c: {
+ // rv: 0
+ // rv: 1
+ // }
+ c.add_rv(0);
+ c.add_rv(1);
+ util::MessageDifferencer differencer;
+ differencer.TreatAsSet(GetFieldDescriptor(a, "rv"));
+ EXPECT_TRUE(differencer.Compare(b, a));
+ EXPECT_FALSE(differencer.Compare(c, a));
+
+ util::MessageDifferencer differencer1;
+ differencer1.set_repeated_field_comparison(util::MessageDifferencer::AS_SET);
+ EXPECT_TRUE(differencer1.Compare(b, a));
+ EXPECT_FALSE(differencer1.Compare(c, a));
+}
+
+TEST(MessageDifferencerTest, RepeatedFieldSetTest_PartialSimple) {
+ protobuf_unittest::TestDiffMessage a, b, c;
+ // message a: {
+ // rm { c: 1 }
+ // rm { c: 0 }
+ // }
+ a.add_rm()->set_c(1);
+ a.add_rm()->set_c(0);
+ // message b: {
+ // rm { c: 1 }
+ // rm {}
+ // }
+ b.add_rm()->set_c(1);
+ b.add_rm();
+ // message c: {
+ // rm {}
+ // rm { c: 1 }
+ // }
+ c.add_rm();
+ c.add_rm()->set_c(1);
+ util::MessageDifferencer differencer;
+ differencer.set_scope(util::MessageDifferencer::PARTIAL);
+ differencer.TreatAsSet(GetFieldDescriptor(a, "rm"));
+ EXPECT_TRUE(differencer.Compare(b, a));
+ EXPECT_TRUE(differencer.Compare(c, a));
+}
+
+TEST(MessageDifferencerTest, RepeatedFieldSetTest_Partial) {
+ protobuf_unittest::TestDiffMessage msg1, msg2;
+ // message msg1: {
+ // rm { a: 1 }
+ // rm { b: 2 }
+ // rm { c: 3 }
+ // }
+ msg1.add_rm()->set_a(1);
+ msg1.add_rm()->set_b(2);
+ msg1.add_rm()->set_c(3);
+ // message msg2: {
+ // rm { a: 1; c: 3 }
+ // rm { b: 2; c: 3 }
+ // rm { b: 2 }
+ // }
+ protobuf_unittest::TestField* field = msg2.add_rm();
+ field->set_a(1);
+ field->set_c(3);
+ field = msg2.add_rm();
+ field->set_b(2);
+ field->set_c(3);
+ field = msg2.add_rm();
+ field->set_b(2);
+
+ util::MessageDifferencer differencer;
+ differencer.set_scope(util::MessageDifferencer::PARTIAL);
+ differencer.TreatAsSet(GetFieldDescriptor(msg1, "rm"));
+ EXPECT_TRUE(differencer.Compare(msg1, msg2));
+}
+
+TEST(MessageDifferencerTest, RepeatedFieldMapTest_MultipleFieldsAsKey) {
+ protobuf_unittest::TestDiffMessage msg1;
+ protobuf_unittest::TestDiffMessage msg2;
+ // Treat "item" as Map, with key = ("a", "ra")
+ // Treat "item.ra" as Set
+ protobuf_unittest::TestDiffMessage::Item* item = msg1.add_item();
+ // key => value: (1, {2, 3}) => "a"
+ item->set_a(1);
+ item->add_ra(2);
+ item->add_ra(3);
+ item->set_b("a");
+ item = msg1.add_item();
+ // key => value: (2, {1, 3}) => "b"
+ item->set_a(2);
+ item->add_ra(1);
+ item->add_ra(3);
+ item->set_b("b");
+ item = msg1.add_item();
+ // key => value: (1, {1, 3}) => "c"
+ item->set_a(1);
+ item->add_ra(1);
+ item->add_ra(3);
+ item->set_b("c");
+
+ item = msg2.add_item();
+ // key => value: (1, {1, 3}) => "c"
+ item->set_a(1);
+ item->add_ra(3);
+ item->add_ra(1);
+ item->set_b("c");
+ item = msg2.add_item();
+ // key => value: (1, {2, 3}) => "a"
+ item->set_a(1);
+ item->add_ra(3);
+ item->add_ra(2);
+ item->set_b("a");
+ item = msg2.add_item();
+ // key => value: (2, {1, 3}) => "b"
+ item->set_a(2);
+ item->add_ra(3);
+ item->add_ra(1);
+ item->set_b("b");
+
+ // Compare
+ util::MessageDifferencer differencer;
+ differencer.TreatAsSet(GetFieldDescriptor(msg1, "item.ra"));
+ EXPECT_FALSE(differencer.Compare(msg1, msg2));
+ std::vector<const FieldDescriptor*> key_fields;
+ key_fields.push_back(GetFieldDescriptor(msg1, "item.a"));
+ key_fields.push_back(GetFieldDescriptor(msg1, "item.ra"));
+ differencer.TreatAsMapWithMultipleFieldsAsKey(
+ GetFieldDescriptor(msg1, "item"), key_fields);
+ EXPECT_TRUE(differencer.Compare(msg1, msg2));
+
+ // Introduce some differences.
+ msg1.clear_item();
+ msg2.clear_item();
+ item = msg1.add_item();
+ item->set_a(4);
+ item->add_ra(5);
+ item->add_ra(6);
+ item->set_b("hello");
+ item = msg2.add_item();
+ item->set_a(4);
+ item->add_ra(6);
+ item->add_ra(5);
+ item->set_b("world");
+ std::string output;
+ differencer.ReportDifferencesToString(&output);
+ EXPECT_FALSE(differencer.Compare(msg1, msg2));
+ EXPECT_EQ(
+ "moved: item[0].ra[0] -> item[0].ra[1] : 5\n"
+ "moved: item[0].ra[1] -> item[0].ra[0] : 6\n"
+ "modified: item[0].b: \"hello\" -> \"world\"\n",
+ output);
+}
+
+TEST(MessageDifferencerTest, RepeatedFieldMapTest_MultipleFieldPathsAsKey) {
+ protobuf_unittest::TestDiffMessage msg1;
+ protobuf_unittest::TestDiffMessage msg2;
+ // Treat "item" as Map, with key = ("m.a", "m.rc")
+ // Treat "item.m.rc" as Set
+ protobuf_unittest::TestDiffMessage::Item* item = msg1.add_item();
+ // key => value: (1, {2, 3}) => "a"
+ item->mutable_m()->set_a(1);
+ item->mutable_m()->add_rc(2);
+ item->mutable_m()->add_rc(3);
+ item->set_b("a");
+ item = msg1.add_item();
+ // key => value: (2, {1, 3}) => "b"
+ item->mutable_m()->set_a(2);
+ item->mutable_m()->add_rc(1);
+ item->mutable_m()->add_rc(3);
+ item->set_b("b");
+ item = msg1.add_item();
+ // key => value: (1, {1, 3}) => "c"
+ item->mutable_m()->set_a(1);
+ item->mutable_m()->add_rc(1);
+ item->mutable_m()->add_rc(3);
+ item->set_b("c");
+
+ item = msg2.add_item();
+ // key => value: (1, {1, 3}) => "c"
+ item->mutable_m()->set_a(1);
+ item->mutable_m()->add_rc(3);
+ item->mutable_m()->add_rc(1);
+ item->set_b("c");
+ item = msg2.add_item();
+ // key => value: (1, {2, 3}) => "a"
+ item->mutable_m()->set_a(1);
+ item->mutable_m()->add_rc(3);
+ item->mutable_m()->add_rc(2);
+ item->set_b("a");
+ item = msg2.add_item();
+ // key => value: (2, {1, 3}) => "b"
+ item->mutable_m()->set_a(2);
+ item->mutable_m()->add_rc(3);
+ item->mutable_m()->add_rc(1);
+ item->set_b("b");
+
+ // Compare
+ util::MessageDifferencer differencer;
+ differencer.TreatAsSet(GetFieldDescriptor(msg1, "item.m.rc"));
+ EXPECT_FALSE(differencer.Compare(msg1, msg2));
+ std::vector<std::vector<const FieldDescriptor*> > key_field_paths;
+ std::vector<const FieldDescriptor*> key_field_path1;
+ key_field_path1.push_back(GetFieldDescriptor(msg1, "item.m"));
+ key_field_path1.push_back(GetFieldDescriptor(msg1, "item.m.a"));
+ std::vector<const FieldDescriptor*> key_field_path2;
+ key_field_path2.push_back(GetFieldDescriptor(msg1, "item.m"));
+ key_field_path2.push_back(GetFieldDescriptor(msg1, "item.m.rc"));
+ key_field_paths.push_back(key_field_path1);
+ key_field_paths.push_back(key_field_path2);
+ differencer.TreatAsMapWithMultipleFieldPathsAsKey(
+ GetFieldDescriptor(msg1, "item"), key_field_paths);
+ EXPECT_TRUE(differencer.Compare(msg1, msg2));
+
+ // Introduce some differences.
+ msg1.clear_item();
+ msg2.clear_item();
+ item = msg1.add_item();
+ item->mutable_m()->set_a(4);
+ item->mutable_m()->add_rc(5);
+ item->mutable_m()->add_rc(6);
+ item->set_b("hello");
+ item = msg2.add_item();
+ item->mutable_m()->set_a(4);
+ item->mutable_m()->add_rc(6);
+ item->mutable_m()->add_rc(5);
+ item->set_b("world");
+ std::string output;
+ differencer.ReportDifferencesToString(&output);
+ EXPECT_FALSE(differencer.Compare(msg1, msg2));
+ EXPECT_EQ(
+ "modified: item[0].b: \"hello\" -> \"world\"\n"
+ "moved: item[0].m.rc[0] -> item[0].m.rc[1] : 5\n"
+ "moved: item[0].m.rc[1] -> item[0].m.rc[0] : 6\n",
+ output);
+}
+
+TEST(MessageDifferencerTest, RepeatedFieldMapTest_IgnoredKeyFields) {
+ protobuf_unittest::TestDiffMessage msg1;
+ protobuf_unittest::TestDiffMessage msg2;
+ // Treat "item" as Map, with key = ("a", "ra")
+ protobuf_unittest::TestDiffMessage::Item* item = msg1.add_item();
+ item->set_a(1);
+ item->add_ra(2);
+ item->set_b("hello");
+ item = msg2.add_item();
+ item->set_a(1);
+ item->add_ra(3);
+ item->set_b("world");
+ // Compare
+ util::MessageDifferencer differencer;
+ std::vector<const FieldDescriptor*> key_fields;
+ key_fields.push_back(GetFieldDescriptor(msg1, "item.a"));
+ key_fields.push_back(GetFieldDescriptor(msg1, "item.ra"));
+ differencer.TreatAsMapWithMultipleFieldsAsKey(
+ GetFieldDescriptor(msg1, "item"), key_fields);
+ std::string output;
+ differencer.ReportDifferencesToString(&output);
+ EXPECT_FALSE(differencer.Compare(msg1, msg2));
+ EXPECT_EQ(
+ "added: item[0]: { a: 1 ra: 3 b: \"world\" }\n"
+ "deleted: item[0]: { a: 1 ra: 2 b: \"hello\" }\n",
+ output);
+ // Ignored fields that are listed as parts of the key are still used
+ // in key comparison, but they're not used in value comparison.
+ differencer.IgnoreField(GetFieldDescriptor(msg1, "item.ra"));
+ output.clear();
+ EXPECT_FALSE(differencer.Compare(msg1, msg2));
+ EXPECT_EQ(
+ "added: item[0]: { a: 1 ra: 3 b: \"world\" }\n"
+ "deleted: item[0]: { a: 1 ra: 2 b: \"hello\" }\n",
+ output);
+ // Ignoring a field in the key is different from treating the left fields
+ // as key. That is:
+ // (key = ("a", "ra") && ignore "ra") != (key = ("a") && ignore "ra")
+ util::MessageDifferencer differencer2;
+ differencer2.TreatAsMap(GetFieldDescriptor(msg1, "item"),
+ GetFieldDescriptor(msg1, "item.a"));
+ differencer2.IgnoreField(GetFieldDescriptor(msg1, "item.ra"));
+ output.clear();
+ differencer2.ReportDifferencesToString(&output);
+ EXPECT_FALSE(differencer2.Compare(msg1, msg2));
+ EXPECT_EQ(
+ "ignored: item[0].ra\n"
+ "modified: item[0].b: \"hello\" -> \"world\"\n",
+ output);
+}
+
+TEST(MessageDifferencerTest, PrintMapKeysTest) {
+ // Note that because map is unordered, the comparison
+ // output string for test evaluation cannot assume order of
+ // output of fields (IOW if two fields are deleted
+ // one cannot assume which deleted field log will be printed first).
+ // Test currently just has a single record per operation to address this.
+ // This should only be a limitation for EXPECT_EQ evaluation.
+ protobuf_unittest::TestDiffMessage msg1;
+ protobuf_unittest::TestDiffMessage msg2;
+ protobuf_unittest::TestDiffMessage::Item* item = msg1.add_item();
+ item->mutable_mp()->insert({{"key_a", 1}, {"key_b", 2}, {"key_c", 3}});
+ item = msg2.add_item();
+ item->mutable_mp()->insert({{"key_a", 1}, {"key_b", 3}, {"key_d", 4}});
+
+ util::MessageDifferencer differencer;
+ std::string diff;
+ differencer.ReportDifferencesToString(&diff);
+ EXPECT_FALSE(differencer.Compare(msg1, msg2));
+ EXPECT_EQ(
+ "modified: item[0].mp[key_b]: 2 -> 3\n"
+ "added: item[0].mp[key_d]: 4\n"
+ "deleted: item[0].mp[key_c]: 3\n",
+ diff);
+
+ google::protobuf::Any any1, any2;
+ any1.PackFrom(msg1);
+ any2.PackFrom(msg2);
+ std::string diff_with_any;
+ differencer.ReportDifferencesToString(&diff_with_any);
+ EXPECT_FALSE(differencer.Compare(any1, any2));
+ EXPECT_EQ(
+ "modified: item[0].mp[key_b]: 2 -> 3\n"
+ "added: item[0].mp[key_d]: 4\n"
+ "deleted: item[0].mp[key_c]: 3\n",
+ diff_with_any);
+}
+
+static const char* const kIgnoredFields[] = {"rm.b", "rm.m.b"};
+
+class TestIgnorer : public util::MessageDifferencer::IgnoreCriteria {
+ public:
+ virtual bool IsIgnored(
+ const Message& message1, const Message& message2,
+ const FieldDescriptor* field,
+ const std::vector<util::MessageDifferencer::SpecificField>&
+ parent_fields) {
+ std::string name = "";
+ for (int i = 0; i < parent_fields.size(); ++i) {
+ name += parent_fields[i].field->name() + ".";
+ }
+ name += field->name();
+ for (int i = 0; i < GOOGLE_ARRAYSIZE(kIgnoredFields); ++i) {
+ if (name.compare(kIgnoredFields[i]) == 0) {
+ return true;
+ }
+ }
+ return false;
+ }
+};
+
+TEST(MessageDifferencerTest, TreatRepeatedFieldAsSetWithIgnoredFields) {
+ protobuf_unittest::TestDiffMessage msg1;
+ protobuf_unittest::TestDiffMessage msg2;
+ TextFormat::MergeFromString("rm { a: 11\n b: 12 }", &msg1);
+ TextFormat::MergeFromString("rm { a: 11\n b: 13 }", &msg2);
+ util::MessageDifferencer differ;
+ differ.TreatAsSet(GetFieldDescriptor(msg1, "rm"));
+ differ.AddIgnoreCriteria(new TestIgnorer);
+ EXPECT_TRUE(differ.Compare(msg1, msg2));
+}
+
+TEST(MessageDifferencerTest, TreatRepeatedFieldAsMapWithIgnoredKeyFields) {
+ protobuf_unittest::TestDiffMessage msg1;
+ protobuf_unittest::TestDiffMessage msg2;
+ TextFormat::MergeFromString("rm { a: 11\n m { a: 12\n b: 13\n } }", &msg1);
+ TextFormat::MergeFromString("rm { a: 11\n m { a: 12\n b: 14\n } }", &msg2);
+ util::MessageDifferencer differ;
+ differ.TreatAsMap(GetFieldDescriptor(msg1, "rm"),
+ GetFieldDescriptor(msg1, "rm.m"));
+ differ.AddIgnoreCriteria(new TestIgnorer);
+ EXPECT_TRUE(differ.Compare(msg1, msg2));
+}
+
+// Takes the product of all elements of item.ra as the key for key comparison.
+class ValueProductMapKeyComparator
+ : public util::MessageDifferencer::MapKeyComparator {
+ public:
+ typedef util::MessageDifferencer::SpecificField SpecificField;
+ virtual bool IsMatch(const Message& message1, const Message& message2,
+ const std::vector<SpecificField>& parent_fields) const {
+ const Reflection* reflection1 = message1.GetReflection();
+ const Reflection* reflection2 = message2.GetReflection();
+ // FieldDescriptor for item.ra
+ const FieldDescriptor* ra_field =
+ message1.GetDescriptor()->FindFieldByName("ra");
+ // Get the product of all elements in item.ra
+ int result1 = 1, result2 = 1;
+ for (int i = 0; i < reflection1->FieldSize(message1, ra_field); ++i) {
+ result1 *= reflection1->GetRepeatedInt32(message1, ra_field, i);
+ }
+ for (int i = 0; i < reflection2->FieldSize(message2, ra_field); ++i) {
+ result2 *= reflection2->GetRepeatedInt32(message2, ra_field, i);
+ }
+ return result1 == result2;
+ }
+};
+
+TEST(MessageDifferencerTest, RepeatedFieldMapTest_CustomMapKeyComparator) {
+ protobuf_unittest::TestDiffMessage msg1;
+ protobuf_unittest::TestDiffMessage msg2;
+ // Treat "item" as Map, using custom key comparator to determine if two
+ // elements have the same key.
+ protobuf_unittest::TestDiffMessage::Item* item = msg1.add_item();
+ item->add_ra(6);
+ item->add_ra(35);
+ item->set_b("hello");
+ item = msg2.add_item();
+ item->add_ra(10);
+ item->add_ra(21);
+ item->set_b("hello");
+ util::MessageDifferencer differencer;
+ ValueProductMapKeyComparator key_comparator;
+ differencer.TreatAsMapUsingKeyComparator(GetFieldDescriptor(msg1, "item"),
+ &key_comparator);
+ std::string output;
+ differencer.ReportDifferencesToString(&output);
+ // Though the above two messages have different values for item.ra, they
+ // are regarded as having the same key because 6 * 35 == 10 * 21. That's
+ // how the key comparator determines if the two have the same key.
+ // However, in value comparison, all fields of the message are taken into
+ // consideration, so they are different because their item.ra fields have
+ // different values using normal value comparison.
+ EXPECT_FALSE(differencer.Compare(msg1, msg2));
+ EXPECT_EQ(
+ "modified: item[0].ra[0]: 6 -> 10\n"
+ "modified: item[0].ra[1]: 35 -> 21\n",
+ output);
+ differencer.IgnoreField(GetFieldDescriptor(msg1, "item.ra"));
+ output.clear();
+ // item.ra is ignored in value comparison, so the two messages equal.
+ EXPECT_TRUE(differencer.Compare(msg1, msg2));
+ EXPECT_EQ("ignored: item[0].ra\n", output);
+}
+
+// Compares fields by their index offset by one, so index 0 matches with 1, etc.
+class OffsetByOneMapKeyComparator
+ : public util::MessageDifferencer::MapKeyComparator {
+ public:
+ typedef util::MessageDifferencer::SpecificField SpecificField;
+ virtual bool IsMatch(const Message& message1, const Message& message2,
+ const std::vector<SpecificField>& parent_fields) const {
+ return parent_fields.back().index + 1 == parent_fields.back().new_index;
+ }
+};
+
+TEST(MessageDifferencerTest, RepeatedFieldMapTest_CustomIndexMapKeyComparator) {
+ protobuf_unittest::TestDiffMessage msg1;
+ protobuf_unittest::TestDiffMessage msg2;
+ // Treat "item" as Map, using custom key comparator to determine if two
+ // elements have the same key.
+ protobuf_unittest::TestDiffMessage::Item* item = msg1.add_item();
+ item->set_b("one");
+ item = msg2.add_item();
+ item->set_b("zero");
+ item = msg2.add_item();
+ item->set_b("one");
+ util::MessageDifferencer differencer;
+ OffsetByOneMapKeyComparator key_comparator;
+ differencer.TreatAsMapUsingKeyComparator(GetFieldDescriptor(msg1, "item"),
+ &key_comparator);
+ std::string output;
+ differencer.ReportDifferencesToString(&output);
+ // With the offset by one comparator msg1.item[0] should be compared to
+ // msg2.item[1] and thus be moved, msg2.item[0] should be marked as added.
+ EXPECT_FALSE(differencer.Compare(msg1, msg2));
+ EXPECT_EQ(
+ "moved: item[0] -> item[1] : { b: \"one\" }\n"
+ "added: item[0]: { b: \"zero\" }\n",
+ output);
+}
+
+TEST(MessageDifferencerTest, RepeatedFieldSetTest_Subset) {
+ protobuf_unittest::TestDiffMessage msg1;
+ protobuf_unittest::TestDiffMessage msg2;
+
+ msg1.add_rv(3);
+ msg1.add_rv(8);
+ msg1.add_rv(2);
+ msg2.add_rv(2);
+ msg2.add_rv(3);
+ msg2.add_rv(5);
+ msg2.add_rv(8);
+
+ util::MessageDifferencer differencer;
+
+ // Fail with only partial scope set.
+ differencer.set_scope(util::MessageDifferencer::PARTIAL);
+ differencer.set_repeated_field_comparison(util::MessageDifferencer::AS_LIST);
+ EXPECT_FALSE(differencer.Compare(msg1, msg2));
+
+ // Fail with only set-like comparison set.
+ differencer.set_scope(util::MessageDifferencer::FULL);
+ differencer.set_repeated_field_comparison(util::MessageDifferencer::AS_SET);
+ EXPECT_FALSE(differencer.Compare(msg1, msg2));
+
+ // Succeed with scope and repeated field comparison set properly.
+ differencer.set_scope(util::MessageDifferencer::PARTIAL);
+ differencer.set_repeated_field_comparison(util::MessageDifferencer::AS_SET);
+ EXPECT_TRUE(differencer.Compare(msg1, msg2));
+}
+
+TEST(MessageDifferencerTest, IgnoreField_Single) {
+ protobuf_unittest::TestField msg1;
+ protobuf_unittest::TestField msg2;
+
+ msg1.set_c(3);
+ msg1.add_rc(1);
+
+ msg2.set_c(5);
+ msg2.add_rc(1);
+
+ util::MessageDifferencer differencer;
+ differencer.IgnoreField(GetFieldDescriptor(msg1, "c"));
+
+ ExpectEqualsWithDifferencer(&differencer, msg1, msg2);
+}
+
+TEST(MessageDifferencerTest, IgnoreField_Repeated) {
+ protobuf_unittest::TestField msg1;
+ protobuf_unittest::TestField msg2;
+
+ msg1.set_c(3);
+ msg1.add_rc(1);
+ msg1.add_rc(2);
+
+ msg2.set_c(3);
+ msg2.add_rc(1);
+ msg2.add_rc(3);
+
+ util::MessageDifferencer differencer;
+ differencer.IgnoreField(GetFieldDescriptor(msg1, "rc"));
+
+ ExpectEqualsWithDifferencer(&differencer, msg1, msg2);
+}
+
+TEST(MessageDifferencerTest, IgnoreField_Message) {
+ protobuf_unittest::TestDiffMessage msg1;
+ protobuf_unittest::TestDiffMessage msg2;
+
+ protobuf_unittest::TestField* field;
+
+ field = msg1.add_rm();
+ field->set_c(3);
+
+ field = msg2.add_rm();
+ field->set_c(4);
+
+ util::MessageDifferencer differencer;
+ differencer.IgnoreField(GetFieldDescriptor(msg1, "rm"));
+
+ ExpectEqualsWithDifferencer(&differencer, msg1, msg2);
+}
+
+TEST(MessageDifferencerTest, IgnoreField_Group) {
+ protobuf_unittest::TestDiffMessage msg1;
+ protobuf_unittest::TestDiffMessage msg2;
+
+ protobuf_unittest::TestDiffMessage::Item* item;
+
+ item = msg1.add_item();
+ item->set_a(3);
+
+ item = msg2.add_item();
+ item->set_a(4);
+
+ util::MessageDifferencer differencer;
+ differencer.IgnoreField(GetFieldDescriptor(msg1, "item"));
+
+ ExpectEqualsWithDifferencer(&differencer, msg1, msg2);
+}
+
+TEST(MessageDifferencerTest, IgnoreField_Missing) {
+ protobuf_unittest::TestField msg1;
+ protobuf_unittest::TestField msg2;
+
+ msg1.set_c(3);
+ msg1.add_rc(1);
+
+ msg2.add_rc(1);
+
+ util::MessageDifferencer differencer;
+ differencer.IgnoreField(GetFieldDescriptor(msg1, "c"));
+
+ ExpectEqualsWithDifferencer(&differencer, msg1, msg2);
+ ExpectEqualsWithDifferencer(&differencer, msg2, msg1);
+}
+
+TEST(MessageDifferencerTest, IgnoreField_Multiple) {
+ protobuf_unittest::TestField msg1;
+ protobuf_unittest::TestField msg2;
+
+ msg1.set_c(3);
+ msg1.add_rc(1);
+ msg1.add_rc(2);
+
+ msg2.set_c(5);
+ msg2.add_rc(1);
+ msg2.add_rc(3);
+
+ const FieldDescriptor* c = GetFieldDescriptor(msg1, "c");
+ const FieldDescriptor* rc = GetFieldDescriptor(msg1, "rc");
+
+ { // Ignore c
+ util::MessageDifferencer differencer;
+ differencer.IgnoreField(c);
+
+ EXPECT_FALSE(differencer.Compare(msg1, msg2));
+ }
+ { // Ignore rc
+ util::MessageDifferencer differencer;
+ differencer.IgnoreField(rc);
+
+ EXPECT_FALSE(differencer.Compare(msg1, msg2));
+ }
+ { // Ignore both
+ util::MessageDifferencer differencer;
+ differencer.IgnoreField(c);
+ differencer.IgnoreField(rc);
+
+ ExpectEqualsWithDifferencer(&differencer, msg1, msg2);
+ }
+}
+
+TEST(MessageDifferencerTest, IgnoreField_NestedMessage) {
+ protobuf_unittest::TestDiffMessage msg1;
+ protobuf_unittest::TestDiffMessage msg2;
+
+ protobuf_unittest::TestField* field;
+
+ field = msg1.add_rm();
+ field->set_c(3);
+ field->add_rc(1);
+
+ field = msg2.add_rm();
+ field->set_c(4);
+ field->add_rc(1);
+
+ util::MessageDifferencer differencer;
+ differencer.IgnoreField(GetFieldDescriptor(msg1, "rm.c"));
+
+ ExpectEqualsWithDifferencer(&differencer, msg1, msg2);
+}
+
+TEST(MessageDifferencerTest, IgnoreField_NestedGroup) {
+ protobuf_unittest::TestDiffMessage msg1;
+ protobuf_unittest::TestDiffMessage msg2;
+
+ protobuf_unittest::TestDiffMessage::Item* item;
+
+ item = msg1.add_item();
+ item->set_a(3);
+ item->set_b("foo");
+
+ item = msg2.add_item();
+ item->set_a(4);
+ item->set_b("foo");
+
+ util::MessageDifferencer differencer;
+ differencer.IgnoreField(GetFieldDescriptor(msg1, "item.a"));
+
+ ExpectEqualsWithDifferencer(&differencer, msg1, msg2);
+}
+
+TEST(MessageDifferencerTest, IgnoreField_InsideSet) {
+ protobuf_unittest::TestDiffMessage msg1;
+ protobuf_unittest::TestDiffMessage msg2;
+
+ protobuf_unittest::TestDiffMessage::Item* item;
+
+ item = msg1.add_item();
+ item->set_a(1);
+ item->set_b("foo");
+ item->add_ra(1);
+
+ item = msg1.add_item();
+ item->set_a(2);
+ item->set_b("bar");
+ item->add_ra(2);
+
+ item = msg2.add_item();
+ item->set_a(2);
+ item->set_b("bar");
+ item->add_ra(2);
+
+ item = msg2.add_item();
+ item->set_a(1);
+ item->set_b("baz");
+ item->add_ra(1);
+
+ const FieldDescriptor* item_desc = GetFieldDescriptor(msg1, "item");
+ const FieldDescriptor* b = GetFieldDescriptor(msg1, "item.b");
+
+ util::MessageDifferencer differencer;
+ differencer.IgnoreField(b);
+ differencer.TreatAsSet(item_desc);
+
+ ExpectEqualsWithDifferencer(&differencer, msg1, msg2);
+}
+
+TEST(MessageDifferencerTest, IgnoreField_InsideMap) {
+ protobuf_unittest::TestDiffMessage msg1;
+ protobuf_unittest::TestDiffMessage msg2;
+
+ protobuf_unittest::TestDiffMessage::Item* item;
+
+ item = msg1.add_item();
+ item->set_a(1);
+ item->set_b("foo");
+ item->add_ra(1);
+
+ item = msg1.add_item();
+ item->set_a(2);
+ item->set_b("bar");
+ item->add_ra(2);
+
+ item = msg2.add_item();
+ item->set_a(2);
+ item->set_b("bar");
+ item->add_ra(2);
+
+ item = msg2.add_item();
+ item->set_a(1);
+ item->set_b("baz");
+ item->add_ra(1);
+
+ const FieldDescriptor* item_desc = GetFieldDescriptor(msg1, "item");
+ const FieldDescriptor* a = GetFieldDescriptor(msg1, "item.a");
+ const FieldDescriptor* b = GetFieldDescriptor(msg1, "item.b");
+
+ util::MessageDifferencer differencer;
+ differencer.IgnoreField(b);
+ differencer.TreatAsMap(item_desc, a);
+
+ ExpectEqualsWithDifferencer(&differencer, msg1, msg2);
+}
+
+TEST(MessageDifferencerTest, IgnoreField_DoesNotIgnoreKey) {
+ protobuf_unittest::TestDiffMessage msg1;
+ protobuf_unittest::TestDiffMessage msg2;
+
+ protobuf_unittest::TestDiffMessage::Item* item;
+
+ item = msg1.add_item();
+ item->set_a(1);
+ item->set_b("foo");
+ item->add_ra(1);
+
+ item = msg2.add_item();
+ item->set_a(2);
+ item->set_b("foo");
+ item->add_ra(1);
+
+ const FieldDescriptor* item_desc = GetFieldDescriptor(msg1, "item");
+ const FieldDescriptor* a = GetFieldDescriptor(msg1, "item.a");
+
+ util::MessageDifferencer differencer;
+ differencer.IgnoreField(a);
+ differencer.TreatAsMap(item_desc, a);
+
+ EXPECT_FALSE(differencer.Compare(msg1, msg2));
+}
+
+TEST(MessageDifferencerTest, IgnoreField_TrumpsCompareWithFields) {
+ protobuf_unittest::TestField msg1;
+ protobuf_unittest::TestField msg2;
+
+ msg1.set_c(3);
+ msg1.add_rc(1);
+ msg1.add_rc(2);
+
+ msg2.set_c(3);
+ msg2.add_rc(1);
+ msg2.add_rc(3);
+
+ const FieldDescriptor* c = GetFieldDescriptor(msg1, "c");
+ const FieldDescriptor* rc = GetFieldDescriptor(msg1, "rc");
+
+ std::vector<const FieldDescriptor*> fields;
+ fields.push_back(c);
+ fields.push_back(rc);
+
+ util::MessageDifferencer differencer;
+ differencer.IgnoreField(rc);
+
+ differencer.set_scope(util::MessageDifferencer::FULL);
+ EXPECT_TRUE(differencer.CompareWithFields(msg1, msg2, fields, fields));
+
+ differencer.set_scope(util::MessageDifferencer::PARTIAL);
+ EXPECT_TRUE(differencer.CompareWithFields(msg1, msg2, fields, fields));
+}
+
+TEST(MessageDifferencerTest, IgnoreField_SetReportIgnoresFalse) {
+ protobuf_unittest::TestField msg1;
+ protobuf_unittest::TestField msg2;
+
+ msg1.set_a(1);
+ msg1.set_b(2);
+ msg1.set_c(3);
+ msg1.add_rc(1);
+ msg1.add_rc(2);
+
+ msg2.set_a(1);
+ msg2.set_b(1);
+
+ const FieldDescriptor* a = GetFieldDescriptor(msg1, "a");
+ const FieldDescriptor* b = GetFieldDescriptor(msg1, "b");
+ const FieldDescriptor* c = GetFieldDescriptor(msg1, "c");
+ const FieldDescriptor* rc = GetFieldDescriptor(msg1, "rc");
+
+ std::vector<const FieldDescriptor*> fields;
+ fields.push_back(a);
+ fields.push_back(b);
+ fields.push_back(c);
+ fields.push_back(rc);
+
+ std::string diff_report;
+ util::MessageDifferencer differencer;
+ differencer.set_report_ignores(false);
+ differencer.set_report_matches(true);
+ differencer.ReportDifferencesToString(&diff_report);
+ differencer.IgnoreField(c);
+ differencer.IgnoreField(rc);
+ differencer.set_scope(util::MessageDifferencer::FULL);
+ EXPECT_FALSE(differencer.CompareWithFields(msg1, msg2, fields, fields));
+
+ EXPECT_EQ(diff_report,
+ "matched: a : 1\n"
+ "modified: b: 2 -> 1\n");
+}
+
+
+// Test class to save a copy of the last field_context.parent_fields() vector
+// passed to the comparison function.
+class ParentSavingFieldComparator : public util::FieldComparator {
+ public:
+ ParentSavingFieldComparator() {}
+
+ 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) {
+ if (field_context) parent_fields_ = *(field_context->parent_fields());
+ if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+ return RECURSE;
+ } else {
+ return SAME;
+ }
+ }
+
+ std::vector<util::MessageDifferencer::SpecificField> parent_fields() {
+ return parent_fields_;
+ }
+
+ private:
+ std::vector<util::MessageDifferencer::SpecificField> parent_fields_;
+};
+
+// Tests if MessageDifferencer sends the parent fields in the FieldContext
+// parameter.
+TEST(MessageDifferencerTest, FieldContextParentFieldsTest) {
+ protobuf_unittest::TestDiffMessage msg1;
+ msg1.add_rm()->set_c(1);
+ protobuf_unittest::TestDiffMessage msg2;
+ msg2.add_rm()->set_c(1);
+
+ ParentSavingFieldComparator field_comparator;
+ util::MessageDifferencer differencer;
+ differencer.set_field_comparator(&field_comparator);
+ differencer.Compare(msg1, msg2);
+
+ // We want only one parent with the name "rm"
+ ASSERT_EQ(1, field_comparator.parent_fields().size());
+ EXPECT_EQ("rm", field_comparator.parent_fields()[0].field->name());
+}
+
+
+class ComparisonTest : public testing::Test {
+ protected:
+ ComparisonTest() : use_equivalency_(false), repeated_field_as_set_(false) {
+ // Setup the test.
+ TestUtil::SetAllFields(&proto1_);
+ TestUtil::SetAllFields(&proto2_);
+
+ TestUtil::SetAllExtensions(&proto1ex_);
+ TestUtil::SetAllExtensions(&proto2ex_);
+
+ TestUtil::SetAllFieldsAndExtensions(&orderings_proto1_);
+ TestUtil::SetAllFieldsAndExtensions(&orderings_proto2_);
+
+ unknown1_ = empty1_.mutable_unknown_fields();
+ unknown2_ = empty2_.mutable_unknown_fields();
+ }
+
+ ~ComparisonTest() {}
+
+ void SetSpecialFieldOption(const Message& message,
+ util::MessageDifferencer* d) {
+ if (!ignored_field_.empty()) {
+ d->IgnoreField(GetFieldDescriptor(message, ignored_field_));
+ }
+
+ if (repeated_field_as_set_) {
+ d->set_repeated_field_comparison(util::MessageDifferencer::AS_SET);
+ }
+
+ if (!set_field_.empty()) {
+ d->TreatAsSet(GetFieldDescriptor(message, set_field_));
+ }
+
+ if (!map_field_.empty() && !map_key_.empty()) {
+ d->TreatAsMap(GetFieldDescriptor(message, map_field_),
+ GetFieldDescriptor(message, map_field_ + "." + map_key_));
+ }
+ }
+
+ std::string Run(const Message& msg1, const Message& msg2) {
+ std::string output;
+
+ // Setup the comparison.
+ util::MessageDifferencer differencer;
+ differencer.ReportDifferencesToString(&output);
+
+ if (use_equivalency_) {
+ differencer.set_message_field_comparison(
+ util::MessageDifferencer::EQUIVALENT);
+ }
+
+ SetSpecialFieldOption(msg1, &differencer);
+
+ // Conduct the comparison.
+ EXPECT_FALSE(differencer.Compare(msg1, msg2));
+
+ return output;
+ }
+
+ std::string Run() { return Run(proto1_, proto2_); }
+
+ std::string RunOrder() { return Run(orderings_proto1_, orderings_proto2_); }
+
+ std::string RunEx() { return Run(proto1ex_, proto2ex_); }
+
+ std::string RunDiff() { return Run(proto1diff_, proto2diff_); }
+
+ std::string RunUn() { return Run(empty1_, empty2_); }
+
+ void use_equivalency() { use_equivalency_ = true; }
+
+ void repeated_field_as_set() { repeated_field_as_set_ = true; }
+
+ void field_as_set(const std::string& field) { set_field_ = field; }
+
+ void field_as_map(const std::string& field, const std::string& key) {
+ map_field_ = field;
+ map_key_ = key;
+ }
+
+ void ignore_field(const std::string& field) { ignored_field_ = field; }
+
+ unittest::TestAllTypes proto1_;
+ unittest::TestAllTypes proto2_;
+
+ unittest::TestFieldOrderings orderings_proto1_;
+ unittest::TestFieldOrderings orderings_proto2_;
+
+ unittest::TestAllExtensions proto1ex_;
+ unittest::TestAllExtensions proto2ex_;
+
+ unittest::TestDiffMessage proto1diff_;
+ unittest::TestDiffMessage proto2diff_;
+
+ unittest::TestEmptyMessage empty1_;
+ unittest::TestEmptyMessage empty2_;
+
+ unittest::TestMap map_proto1_;
+ unittest::TestMap map_proto2_;
+
+ UnknownFieldSet* unknown1_;
+ UnknownFieldSet* unknown2_;
+
+ bool use_equivalency_;
+ bool repeated_field_as_set_;
+
+ std::string set_field_;
+ std::string map_field_;
+ std::string map_key_;
+ std::string ignored_field_;
+};
+
+// Basic tests.
+TEST_F(ComparisonTest, AdditionTest) {
+ proto1_.clear_optional_int32();
+
+ EXPECT_EQ("added: optional_int32: 101\n", Run());
+}
+
+TEST_F(ComparisonTest, Addition_OrderTest) {
+ orderings_proto1_.clear_my_int();
+
+ EXPECT_EQ("added: my_int: 1\n", RunOrder());
+}
+
+TEST_F(ComparisonTest, DeletionTest) {
+ proto2_.clear_optional_int32();
+
+ EXPECT_EQ("deleted: optional_int32: 101\n", Run());
+}
+
+TEST_F(ComparisonTest, Deletion_OrderTest) {
+ orderings_proto2_.clear_my_string();
+
+ EXPECT_EQ("deleted: my_string: \"foo\"\n", RunOrder());
+}
+
+TEST_F(ComparisonTest, RepeatedDeletionTest) {
+ proto2_.clear_repeated_int32();
+
+ EXPECT_EQ(
+ "deleted: repeated_int32[0]: 201\n"
+ "deleted: repeated_int32[1]: 301\n",
+ Run());
+}
+
+TEST_F(ComparisonTest, ModificationTest) {
+ proto1_.set_optional_int32(-1);
+
+ EXPECT_EQ("modified: optional_int32: -1 -> 101\n", Run());
+}
+
+// Basic equivalency tests.
+TEST_F(ComparisonTest, EquivalencyAdditionTest) {
+ use_equivalency();
+
+ proto1_.clear_optional_int32();
+
+ EXPECT_EQ("modified: optional_int32: 0 -> 101\n", Run());
+}
+
+TEST_F(ComparisonTest, EquivalencyDeletionTest) {
+ use_equivalency();
+
+ proto2_.clear_optional_int32();
+
+ EXPECT_EQ("modified: optional_int32: 101 -> 0\n", Run());
+}
+
+// Group tests.
+TEST_F(ComparisonTest, GroupAdditionTest) {
+ proto1_.mutable_optionalgroup()->clear_a();
+
+ EXPECT_EQ("added: optionalgroup.a: 117\n", Run());
+}
+
+TEST_F(ComparisonTest, GroupDeletionTest) {
+ proto2_.mutable_optionalgroup()->clear_a();
+
+ EXPECT_EQ("deleted: optionalgroup.a: 117\n", Run());
+}
+
+TEST_F(ComparisonTest, GroupModificationTest) {
+ proto1_.mutable_optionalgroup()->set_a(2);
+
+ EXPECT_EQ("modified: optionalgroup.a: 2 -> 117\n", Run());
+}
+
+TEST_F(ComparisonTest, GroupFullAdditionTest) {
+ proto1_.clear_optionalgroup();
+
+ // Note the difference in the output between this and GroupAdditionTest.
+ EXPECT_EQ("added: optionalgroup: { a: 117 }\n", Run());
+}
+
+TEST_F(ComparisonTest, GroupFullDeletionTest) {
+ proto2_.clear_optionalgroup();
+
+ EXPECT_EQ("deleted: optionalgroup: { a: 117 }\n", Run());
+}
+
+TEST_F(ComparisonTest, RepeatedSetOptionTest) {
+ repeated_field_as_set();
+
+ proto2_.clear_repeatedgroup();
+ proto1_.clear_repeatedgroup();
+ proto1_.add_repeatedgroup()->set_a(317);
+ proto2_.add_repeatedgroup()->set_a(909);
+ proto2_.add_repeatedgroup()->set_a(907);
+ proto1_.add_repeatedgroup()->set_a(904);
+ proto1_.add_repeatedgroup()->set_a(907);
+ proto1_.add_repeatedgroup()->set_a(909);
+
+ EXPECT_EQ(
+ "moved: repeatedgroup[2] -> repeatedgroup[1] : { a: 907 }\n"
+ "moved: repeatedgroup[3] -> repeatedgroup[0] : { a: 909 }\n"
+ "deleted: repeatedgroup[0]: { a: 317 }\n"
+ "deleted: repeatedgroup[1]: { a: 904 }\n",
+ Run());
+}
+
+TEST_F(ComparisonTest, RepeatedSetOptionTest_Ex) {
+ repeated_field_as_set();
+
+ proto1ex_.ClearExtension(protobuf_unittest::repeated_nested_message_extension);
+ proto2ex_.ClearExtension(protobuf_unittest::repeated_nested_message_extension);
+ proto2ex_.AddExtension(protobuf_unittest::repeated_nested_message_extension)
+ ->set_bb(909);
+ proto2ex_.AddExtension(protobuf_unittest::repeated_nested_message_extension)
+ ->set_bb(907);
+ proto1ex_.AddExtension(protobuf_unittest::repeated_nested_message_extension)
+ ->set_bb(904);
+ proto1ex_.AddExtension(protobuf_unittest::repeated_nested_message_extension)
+ ->set_bb(907);
+ proto1ex_.AddExtension(protobuf_unittest::repeated_nested_message_extension)
+ ->set_bb(909);
+
+ EXPECT_EQ(
+ "moved: (protobuf_unittest.repeated_nested_message_extension)[2] ->"
+ " (protobuf_unittest.repeated_nested_message_extension)[0] :"
+ " { bb: 909 }\n"
+ "deleted: (protobuf_unittest.repeated_nested_message_extension)[0]:"
+ " { bb: 904 }\n",
+ RunEx());
+}
+
+TEST_F(ComparisonTest, RepeatedMapFieldTest_Group) {
+ field_as_map("repeatedgroup", "a");
+ proto1_.clear_repeatedgroup();
+ proto2_.clear_repeatedgroup();
+
+ proto1_.add_repeatedgroup()->set_a(317); // deleted
+ proto1_.add_repeatedgroup()->set_a(904); // deleted
+ proto1_.add_repeatedgroup()->set_a(907); // moved from
+ proto1_.add_repeatedgroup()->set_a(909); // moved from
+
+ proto2_.add_repeatedgroup()->set_a(909); // moved to
+ proto2_.add_repeatedgroup()->set_a(318); // added
+ proto2_.add_repeatedgroup()->set_a(907); // moved to
+
+ EXPECT_EQ(
+ "moved: repeatedgroup[3] -> repeatedgroup[0] : { a: 909 }\n"
+ "added: repeatedgroup[1]: { a: 318 }\n"
+ "deleted: repeatedgroup[0]: { a: 317 }\n"
+ "deleted: repeatedgroup[1]: { a: 904 }\n",
+ Run());
+}
+
+TEST_F(ComparisonTest, RepeatedMapFieldTest_MessageKey) {
+ // Use m as key, but use b as value.
+ field_as_map("item", "m");
+
+ protobuf_unittest::TestDiffMessage msg1;
+ protobuf_unittest::TestDiffMessage msg2;
+ protobuf_unittest::TestDiffMessage::Item* item = msg1.add_item();
+
+ // The following code creates one deletion, one addition and two moved fields
+ // on the messages.
+ item->mutable_m()->set_c(0);
+ item->set_b("first");
+ item = msg1.add_item();
+ item->mutable_m()->set_c(2);
+ item->set_b("second");
+ item = msg1.add_item();
+ item->set_b("null"); // empty key moved
+ item = msg1.add_item();
+ item->mutable_m()->set_c(3);
+ item->set_b("third"); // deletion
+ item = msg1.add_item();
+ item->mutable_m()->set_c(2);
+ item->set_b("second"); // duplicated key ( deletion )
+ item = msg2.add_item();
+ item->mutable_m()->set_c(2);
+ item->set_b("second"); // modification
+ item = msg2.add_item();
+ item->mutable_m()->set_c(4);
+ item->set_b("fourth"); // addition
+ item = msg2.add_item();
+ item->mutable_m()->set_c(0);
+ item->set_b("fist"); // move with change
+ item = msg2.add_item();
+ item->set_b("null");
+
+ EXPECT_EQ(
+ "modified: item[0].b -> item[2].b: \"first\" -> \"fist\"\n"
+ "moved: item[1] -> item[0] : { b: \"second\" m { c: 2 } }\n"
+ "moved: item[2] -> item[3] : { b: \"null\" }\n"
+ "added: item[1]: { b: \"fourth\" m { c: 4 } }\n"
+ "deleted: item[3]: { b: \"third\" m { c: 3 } }\n"
+ "deleted: item[4]: { b: \"second\" m { c: 2 } }\n",
+ Run(msg1, msg2));
+}
+
+TEST_F(ComparisonTest, RepeatedFieldSetTest_SetOfSet) {
+ repeated_field_as_set();
+ // Create the testing protos
+ protobuf_unittest::TestDiffMessage msg1;
+ protobuf_unittest::TestDiffMessage msg2;
+
+ protobuf_unittest::TestDiffMessage::Item* item = msg1.add_item();
+ item->add_ra(1);
+ item->add_ra(2);
+ item->add_ra(3);
+ item = msg1.add_item();
+ item->add_ra(5);
+ item->add_ra(6);
+ item = msg1.add_item();
+ item->add_ra(1);
+ item->add_ra(3);
+ item = msg1.add_item();
+ item->add_ra(6);
+ item->add_ra(7);
+ item->add_ra(8);
+
+ item = msg2.add_item();
+ item->add_ra(6);
+ item->add_ra(5);
+ item = msg2.add_item();
+ item->add_ra(6);
+ item->add_ra(8);
+ item = msg2.add_item();
+ item->add_ra(1);
+ item->add_ra(3);
+ item = msg2.add_item();
+ item->add_ra(3);
+ item->add_ra(2);
+ item->add_ra(1);
+
+ // Compare
+ EXPECT_EQ(
+ "moved: item[0].ra[0] -> item[3].ra[2] : 1\n"
+ "moved: item[0].ra[2] -> item[3].ra[0] : 3\n"
+ "moved: item[0] -> item[3] : { ra: 1 ra: 2 ra: 3 }\n"
+ "moved: item[1].ra[0] -> item[0].ra[1] : 5\n"
+ "moved: item[1].ra[1] -> item[0].ra[0] : 6\n"
+ "moved: item[1] -> item[0] : { ra: 5 ra: 6 }\n"
+ "added: item[1]: { ra: 6 ra: 8 }\n"
+ "deleted: item[3]: { ra: 6 ra: 7 ra: 8 }\n",
+ Run(msg1, msg2));
+}
+
+TEST_F(ComparisonTest, RepeatedMapFieldTest_RepeatedKey) {
+ // used rb as a key, but b is the value.
+ repeated_field_as_set();
+ field_as_map("item", "rb");
+
+ protobuf_unittest::TestDiffMessage msg1;
+ protobuf_unittest::TestDiffMessage msg2;
+ protobuf_unittest::TestDiffMessage::Item* item = msg1.add_item();
+ item->add_rb("a");
+ item->add_rb("b");
+ item->set_b("first");
+
+ item = msg2.add_item();
+ item->add_rb("c");
+ item->set_b("second");
+
+ item = msg2.add_item();
+ item->add_rb("b");
+ item->add_rb("a");
+ item->set_b("fist");
+
+ EXPECT_EQ(
+ "modified: item[0].b -> item[1].b: \"first\" -> \"fist\"\n"
+ "moved: item[0].rb[0] -> item[1].rb[1] : \"a\"\n"
+ "moved: item[0].rb[1] -> item[1].rb[0] : \"b\"\n"
+ "added: item[0]: { b: \"second\" rb: \"c\" }\n",
+ Run(msg1, msg2));
+}
+
+TEST_F(ComparisonTest, RepeatedMapFieldTest_RepeatedMessageKey) {
+ field_as_map("item", "rm");
+
+ protobuf_unittest::TestDiffMessage msg1;
+ protobuf_unittest::TestDiffMessage msg2;
+ protobuf_unittest::TestDiffMessage::Item* item = msg1.add_item();
+ protobuf_unittest::TestField* key = item->add_rm();
+ key->set_c(2);
+ key->add_rc(10);
+ key->add_rc(10);
+ item = msg1.add_item();
+ key = item->add_rm();
+ key->set_c(0);
+ key->add_rc(1);
+ key->add_rc(2);
+ key = item->add_rm();
+ key->set_c(0);
+ item->add_rb("first");
+
+ item = msg2.add_item();
+ item->CopyFrom(msg1.item(1));
+ item->add_rb("second");
+
+ EXPECT_EQ(
+ "added: item[0].rb[1]: \"second\"\n"
+ "deleted: item[0]: { rm { c: 2 rc: 10 rc: 10 } }\n",
+ Run(msg1, msg2));
+}
+
+TEST_F(ComparisonTest, RepeatedSetOptionTest_Unknown) {
+ // Currently, as_set option doesn't have affects on unknown field.
+ // If needed, this feature will be added by request.
+ repeated_field_as_set();
+ unknown1_->AddGroup(245)->AddFixed32(248, 1);
+ unknown2_->AddGroup(245)->AddFixed32(248, 3);
+ unknown2_->AddGroup(245)->AddFixed32(248, 1);
+
+ // We expect it behaves the same as normal comparison.
+ EXPECT_EQ(
+ "modified: 245[0].248[0]: 0x00000001 -> 0x00000003\n"
+ "added: 245[1]: { ... }\n",
+ RunUn());
+}
+
+TEST_F(ComparisonTest, Matching_Unknown) {
+ unknown1_->AddGroup(245)->AddFixed32(248, 1);
+ unknown2_->AddGroup(245)->AddFixed32(248, 1);
+ unknown1_->AddGroup(245)->AddFixed32(248, 3);
+ unknown2_->AddGroup(245)->AddFixed32(248, 3);
+ unknown2_->AddLengthDelimited(242, "cat");
+ unknown2_->AddGroup(246)->AddFixed32(248, 4);
+
+ // report_match is false so only added/modified fields are expected.
+ EXPECT_EQ(
+ "added: 242[0]: \"cat\"\n"
+ "added: 246[0]: { ... }\n",
+ RunUn());
+}
+
+TEST_F(ComparisonTest, RepeatedSetFieldTest) {
+ field_as_set("repeatedgroup");
+
+ proto1_.clear_repeatedgroup();
+ proto2_.clear_repeatedgroup();
+ proto2_.add_repeatedgroup()->set_a(909);
+ proto2_.add_repeatedgroup()->set_a(907);
+ proto1_.add_repeatedgroup()->set_a(317);
+ proto1_.add_repeatedgroup()->set_a(904);
+ proto1_.add_repeatedgroup()->set_a(907);
+ proto1_.add_repeatedgroup()->set_a(909);
+
+ EXPECT_EQ(
+ "moved: repeatedgroup[2] -> repeatedgroup[1] : { a: 907 }\n"
+ "moved: repeatedgroup[3] -> repeatedgroup[0] : { a: 909 }\n"
+ "deleted: repeatedgroup[0]: { a: 317 }\n"
+ "deleted: repeatedgroup[1]: { a: 904 }\n",
+ Run());
+}
+
+// Embedded message tests.
+TEST_F(ComparisonTest, EmbeddedAdditionTest) {
+ proto1_.mutable_optional_nested_message()->clear_bb();
+
+ EXPECT_EQ("added: optional_nested_message.bb: 118\n", Run());
+}
+
+TEST_F(ComparisonTest, EmbeddedDeletionTest) {
+ proto2_.mutable_optional_nested_message()->clear_bb();
+
+ EXPECT_EQ("deleted: optional_nested_message.bb: 118\n", Run());
+}
+
+TEST_F(ComparisonTest, EmbeddedModificationTest) {
+ proto1_.mutable_optional_nested_message()->set_bb(2);
+
+ EXPECT_EQ("modified: optional_nested_message.bb: 2 -> 118\n", Run());
+}
+
+TEST_F(ComparisonTest, EmbeddedFullAdditionTest) {
+ proto1_.clear_optional_nested_message();
+
+ EXPECT_EQ("added: optional_nested_message: { bb: 118 }\n", Run());
+}
+
+TEST_F(ComparisonTest, EmbeddedPartialAdditionTest) {
+ proto1_.clear_optional_nested_message();
+ proto2_.mutable_optional_nested_message()->clear_bb();
+
+ EXPECT_EQ("added: optional_nested_message: { }\n", Run());
+}
+
+TEST_F(ComparisonTest, EmbeddedFullDeletionTest) {
+ proto2_.clear_optional_nested_message();
+
+ EXPECT_EQ("deleted: optional_nested_message: { bb: 118 }\n", Run());
+}
+
+// Repeated element tests.
+TEST_F(ComparisonTest, BasicRepeatedTest) {
+ proto1_.clear_repeated_int32();
+ proto2_.clear_repeated_int32();
+
+ proto1_.add_repeated_int32(500);
+ proto1_.add_repeated_int32(501);
+ proto1_.add_repeated_int32(502);
+ proto1_.add_repeated_int32(503);
+ proto1_.add_repeated_int32(500);
+
+ proto2_.add_repeated_int32(500);
+ proto2_.add_repeated_int32(509);
+ proto2_.add_repeated_int32(502);
+ proto2_.add_repeated_int32(504);
+
+ EXPECT_EQ(
+ "modified: repeated_int32[1]: 501 -> 509\n"
+ "modified: repeated_int32[3]: 503 -> 504\n"
+ "deleted: repeated_int32[4]: 500\n",
+ Run());
+}
+
+TEST_F(ComparisonTest, BasicRepeatedTest_SetOption) {
+ repeated_field_as_set();
+ proto1_.clear_repeated_int32();
+ proto2_.clear_repeated_int32();
+
+ proto1_.add_repeated_int32(501);
+ proto1_.add_repeated_int32(502);
+ proto1_.add_repeated_int32(503);
+ proto1_.add_repeated_int32(500);
+ proto1_.add_repeated_int32(500);
+
+ proto2_.add_repeated_int32(500);
+ proto2_.add_repeated_int32(509);
+ proto2_.add_repeated_int32(503);
+ proto2_.add_repeated_int32(502);
+ proto2_.add_repeated_int32(504);
+
+ EXPECT_EQ(
+ "moved: repeated_int32[1] -> repeated_int32[3] : 502\n"
+ "moved: repeated_int32[3] -> repeated_int32[0] : 500\n"
+ "added: repeated_int32[1]: 509\n"
+ "added: repeated_int32[4]: 504\n"
+ "deleted: repeated_int32[0]: 501\n"
+ "deleted: repeated_int32[4]: 500\n",
+ Run());
+}
+
+TEST_F(ComparisonTest, BasicRepeatedTest_SetField) {
+ field_as_set("repeated_int32");
+ proto1_.clear_repeated_int32();
+ proto2_.clear_repeated_int32();
+
+ proto1_.add_repeated_int32(501);
+ proto1_.add_repeated_int32(502);
+ proto1_.add_repeated_int32(503);
+ proto1_.add_repeated_int32(500);
+ proto1_.add_repeated_int32(500);
+
+ proto2_.add_repeated_int32(500);
+ proto2_.add_repeated_int32(509);
+ proto2_.add_repeated_int32(503);
+ proto2_.add_repeated_int32(502);
+ proto2_.add_repeated_int32(504);
+
+ EXPECT_EQ(
+ "moved: repeated_int32[1] -> repeated_int32[3] : 502\n"
+ "moved: repeated_int32[3] -> repeated_int32[0] : 500\n"
+ "added: repeated_int32[1]: 509\n"
+ "added: repeated_int32[4]: 504\n"
+ "deleted: repeated_int32[0]: 501\n"
+ "deleted: repeated_int32[4]: 500\n",
+ Run());
+}
+
+// Multiple action tests.
+TEST_F(ComparisonTest, AddDeleteTest) {
+ proto1_.clear_optional_int32();
+ proto2_.clear_optional_int64();
+
+ EXPECT_EQ(
+ "added: optional_int32: 101\n"
+ "deleted: optional_int64: 102\n",
+ Run());
+}
+
+TEST_F(ComparisonTest, AddDelete_FieldOrderingTest) {
+ orderings_proto1_.ClearExtension(unittest::my_extension_string);
+ orderings_proto2_.clear_my_int();
+
+ EXPECT_EQ(
+ "deleted: my_int: 1\n"
+ "added: (protobuf_unittest.my_extension_string): \"bar\"\n",
+ RunOrder());
+}
+
+TEST_F(ComparisonTest, AllThreeTest) {
+ proto1_.clear_optional_int32();
+ proto2_.clear_optional_float();
+ proto2_.set_optional_string("hello world!");
+
+ EXPECT_EQ(
+ "added: optional_int32: 101\n"
+ "deleted: optional_float: 111\n"
+ "modified: optional_string: \"115\" -> \"hello world!\"\n",
+ Run());
+}
+
+TEST_F(ComparisonTest, SandwhichTest) {
+ proto1_.clear_optional_int64();
+ proto1_.clear_optional_uint32();
+
+ proto2_.clear_optional_uint64();
+
+ EXPECT_EQ(
+ "added: optional_int64: 102\n"
+ "added: optional_uint32: 103\n"
+ "deleted: optional_uint64: 104\n",
+ Run());
+}
+
+TEST_F(ComparisonTest, IgnoredNoChangeTest) {
+ proto1diff_.set_v(3);
+ proto2diff_.set_v(3);
+ proto2diff_.set_w("foo");
+
+ ignore_field("v");
+
+ EXPECT_EQ(
+ "ignored: v\n"
+ "added: w: \"foo\"\n",
+ RunDiff());
+}
+
+TEST_F(ComparisonTest, IgnoredAddTest) {
+ proto2diff_.set_v(3);
+ proto2diff_.set_w("foo");
+
+ ignore_field("v");
+
+ EXPECT_EQ(
+ "ignored: v\n"
+ "added: w: \"foo\"\n",
+ RunDiff());
+}
+
+TEST_F(ComparisonTest, IgnoredDeleteTest) {
+ proto1diff_.set_v(3);
+ proto2diff_.set_w("foo");
+
+ ignore_field("v");
+
+ EXPECT_EQ(
+ "ignored: v\n"
+ "added: w: \"foo\"\n",
+ RunDiff());
+}
+
+TEST_F(ComparisonTest, IgnoredModifyTest) {
+ proto1diff_.set_v(3);
+ proto2diff_.set_v(4);
+ proto2diff_.set_w("foo");
+
+ ignore_field("v");
+
+ EXPECT_EQ(
+ "ignored: v\n"
+ "added: w: \"foo\"\n",
+ RunDiff());
+}
+
+TEST_F(ComparisonTest, IgnoredRepeatedAddTest) {
+ proto1diff_.add_rv(3);
+ proto1diff_.add_rv(4);
+
+ proto2diff_.add_rv(3);
+ proto2diff_.add_rv(4);
+ proto2diff_.add_rv(5);
+
+ proto2diff_.set_w("foo");
+
+ ignore_field("rv");
+
+ EXPECT_EQ(
+ "ignored: rv\n"
+ "added: w: \"foo\"\n",
+ RunDiff());
+}
+
+TEST_F(ComparisonTest, IgnoredRepeatedDeleteTest) {
+ proto1diff_.add_rv(3);
+ proto1diff_.add_rv(4);
+ proto1diff_.add_rv(5);
+
+ proto2diff_.add_rv(3);
+ proto2diff_.add_rv(4);
+
+ proto2diff_.set_w("foo");
+
+ ignore_field("rv");
+
+ EXPECT_EQ(
+ "ignored: rv\n"
+ "added: w: \"foo\"\n",
+ RunDiff());
+}
+
+TEST_F(ComparisonTest, IgnoredRepeatedModifyTest) {
+ proto1diff_.add_rv(3);
+ proto1diff_.add_rv(4);
+
+ proto2diff_.add_rv(3);
+ proto2diff_.add_rv(5);
+
+ proto2diff_.set_w("foo");
+
+ ignore_field("rv");
+
+ EXPECT_EQ(
+ "ignored: rv\n"
+ "added: w: \"foo\"\n",
+ RunDiff());
+}
+
+TEST_F(ComparisonTest, IgnoredWholeNestedMessage) {
+ proto1diff_.mutable_m()->set_c(3);
+ proto2diff_.mutable_m()->set_c(4);
+
+ proto2diff_.set_w("foo");
+
+ ignore_field("m");
+
+ EXPECT_EQ(
+ "added: w: \"foo\"\n"
+ "ignored: m\n",
+ RunDiff());
+}
+
+TEST_F(ComparisonTest, IgnoredNestedField) {
+ proto1diff_.mutable_m()->set_c(3);
+ proto2diff_.mutable_m()->set_c(4);
+
+ proto2diff_.set_w("foo");
+
+ ignore_field("m.c");
+
+ EXPECT_EQ(
+ "added: w: \"foo\"\n"
+ "ignored: m.c\n",
+ RunDiff());
+}
+
+TEST_F(ComparisonTest, IgnoredRepeatedNested) {
+ proto1diff_.add_rm()->set_c(0);
+ proto1diff_.add_rm()->set_c(1);
+ proto2diff_.add_rm()->set_c(2);
+ proto2diff_.add_rm()->set_c(3);
+
+ proto2diff_.set_w("foo");
+
+ ignore_field("rm.c");
+
+ EXPECT_EQ(
+ "ignored: rm[0].c\n"
+ "ignored: rm[1].c\n"
+ "added: w: \"foo\"\n",
+ RunDiff());
+}
+
+TEST_F(ComparisonTest, IgnoredNestedRepeated) {
+ proto1diff_.mutable_m()->add_rc(23);
+ proto1diff_.mutable_m()->add_rc(24);
+ proto2diff_.mutable_m()->add_rc(25);
+
+ proto2diff_.set_w("foo");
+
+ ignore_field("m.rc");
+
+ EXPECT_EQ(
+ "added: w: \"foo\"\n"
+ "ignored: m.rc\n",
+ RunDiff());
+}
+
+TEST_F(ComparisonTest, ExtensionTest) {
+ proto1ex_.SetExtension(unittest::optional_int32_extension, 401);
+ proto2ex_.SetExtension(unittest::optional_int32_extension, 402);
+
+ proto1ex_.ClearExtension(unittest::optional_int64_extension);
+ proto2ex_.SetExtension(unittest::optional_int64_extension, 403);
+
+ EXPECT_EQ(
+ "modified: (protobuf_unittest.optional_int32_extension): 401 -> 402\n"
+ "added: (protobuf_unittest.optional_int64_extension): 403\n",
+ RunEx());
+}
+
+TEST_F(ComparisonTest, MatchedUnknownFieldTagTest) {
+ unknown1_->AddVarint(240, 122);
+ unknown2_->AddVarint(240, 121);
+ unknown1_->AddFixed32(241, 1);
+ unknown2_->AddFixed64(241, 2);
+ unknown1_->AddLengthDelimited(242, "cat");
+ unknown2_->AddLengthDelimited(242, "dog");
+
+ EXPECT_EQ(
+ "modified: 240[0]: 122 -> 121\n"
+ "deleted: 241[0]: 0x00000001\n"
+ "added: 241[0]: 0x0000000000000002\n"
+ "modified: 242[0]: \"cat\" -> \"dog\"\n",
+ RunUn());
+}
+
+TEST_F(ComparisonTest, UnmatchedUnknownFieldTagTest) {
+ unknown1_->AddFixed32(243, 1);
+ unknown2_->AddVarint(244, 2);
+ unknown2_->AddVarint(244, 4);
+
+ EXPECT_EQ(
+ "deleted: 243[0]: 0x00000001\n"
+ "added: 244[0]: 2\n"
+ "added: 244[1]: 4\n",
+ RunUn());
+}
+
+TEST_F(ComparisonTest, DifferentSizedUnknownFieldTest) {
+ unknown1_->AddVarint(240, 1);
+ unknown1_->AddVarint(240, 3);
+ unknown1_->AddVarint(240, 4);
+ unknown2_->AddVarint(240, 2);
+ unknown2_->AddVarint(240, 3);
+ unknown2_->AddVarint(240, 2);
+ unknown2_->AddVarint(240, 5);
+
+ EXPECT_EQ(
+ "modified: 240[0]: 1 -> 2\n"
+ "modified: 240[2]: 4 -> 2\n"
+ "added: 240[3]: 5\n",
+ RunUn());
+}
+
+TEST_F(ComparisonTest, UnknownFieldsAll) {
+ unknown1_->AddVarint(243, 122);
+ unknown1_->AddFixed64(244, 0x0172356);
+ unknown1_->AddFixed64(244, 0x098);
+ unknown1_->AddGroup(245)->AddFixed32(248, 1);
+ unknown1_->mutable_field(3)->mutable_group()->AddFixed32(248, 2);
+ unknown1_->AddGroup(249)->AddFixed64(250, 1);
+
+ unknown2_->AddVarint(243, 121);
+ unknown2_->AddLengthDelimited(73882, "test 123");
+ unknown2_->AddGroup(245)->AddFixed32(248, 3);
+ unknown2_->AddGroup(247);
+
+ EXPECT_EQ(
+ "modified: 243[0]: 122 -> 121\n"
+ "deleted: 244[0]: 0x0000000000172356\n"
+ "deleted: 244[1]: 0x0000000000000098\n"
+ "modified: 245[0].248[0]: 0x00000001 -> 0x00000003\n"
+ "deleted: 245[0].248[1]: 0x00000002\n"
+ "added: 247[0]: { ... }\n"
+ "deleted: 249[0]: { ... }\n"
+ "added: 73882[0]: \"test 123\"\n",
+ RunUn());
+}
+
+TEST_F(ComparisonTest, EquivalentIgnoresUnknown) {
+ unittest::ForeignMessage message1, message2;
+
+ message1.set_c(5);
+ message1.mutable_unknown_fields()->AddVarint(123, 456);
+ message2.set_c(5);
+ message2.mutable_unknown_fields()->AddVarint(321, 654);
+
+ EXPECT_FALSE(util::MessageDifferencer::Equals(message1, message2));
+ EXPECT_TRUE(util::MessageDifferencer::Equivalent(message1, message2));
+}
+
+TEST_F(ComparisonTest, MapTest) {
+ Map<std::string, std::string>& map1 =
+ *map_proto1_.mutable_map_string_string();
+ map1["key1"] = "1";
+ map1["key2"] = "2";
+ map1["key3"] = "3";
+ Map<std::string, std::string>& map2 =
+ *map_proto2_.mutable_map_string_string();
+ map2["key3"] = "0";
+ map2["key2"] = "2";
+ map2["key1"] = "1";
+
+ EXPECT_EQ("modified: map_string_string[key3]: \"3\" -> \"0\"\n",
+ Run(map_proto1_, map_proto2_));
+}
+
+TEST_F(ComparisonTest, MapIgnoreKeyTest) {
+ Map<std::string, std::string>& map1 =
+ *map_proto1_.mutable_map_string_string();
+ map1["key1"] = "1";
+ map1["key2"] = "2";
+ map1["key3"] = "3";
+ Map<std::string, std::string>& map2 =
+ *map_proto2_.mutable_map_string_string();
+ map2["key4"] = "2";
+ map2["key5"] = "3";
+ map2["key6"] = "1";
+
+ util::MessageDifferencer differencer;
+ differencer.IgnoreField(
+ GetFieldDescriptor(map_proto1_, "map_string_string.key"));
+ EXPECT_TRUE(differencer.Compare(map_proto1_, map_proto2_));
+}
+
+TEST_F(ComparisonTest, MapRoundTripSyncTest) {
+ TextFormat::Parser parser;
+ unittest::TestMap map_reflection1;
+
+ // By setting via reflection, data exists in repeated field.
+ ASSERT_TRUE(parser.ParseFromString("map_int32_foreign_message { key: 1 }",
+ &map_reflection1));
+
+ // During copy, data is synced from repeated field to map.
+ unittest::TestMap map_reflection2 = map_reflection1;
+
+ // During comparison, data is synced from map to repeated field.
+ EXPECT_TRUE(
+ util::MessageDifferencer::Equals(map_reflection1, map_reflection2));
+}
+
+TEST_F(ComparisonTest, MapEntryPartialTest) {
+ TextFormat::Parser parser;
+ unittest::TestMap map1;
+ unittest::TestMap map2;
+
+ std::string output;
+ util::MessageDifferencer differencer;
+ differencer.set_scope(util::MessageDifferencer::PARTIAL);
+ differencer.ReportDifferencesToString(&output);
+
+ ASSERT_TRUE(parser.ParseFromString(
+ "map_int32_foreign_message { key: 1 value { c: 1 } }", &map1));
+ ASSERT_TRUE(parser.ParseFromString(
+ "map_int32_foreign_message { key: 1 value { c: 2 }}", &map2));
+ EXPECT_FALSE(differencer.Compare(map1, map2));
+ EXPECT_EQ("modified: map_int32_foreign_message[1].c: 1 -> 2\n", output);
+
+ ASSERT_TRUE(
+ parser.ParseFromString("map_int32_foreign_message { key: 1 }", &map1));
+ EXPECT_TRUE(differencer.Compare(map1, map2));
+}
+
+TEST_F(ComparisonTest, MapEntryPartialEmptyKeyTest) {
+ TextFormat::Parser parser;
+ unittest::TestMap map1;
+ unittest::TestMap map2;
+ ASSERT_TRUE(parser.ParseFromString("map_int32_foreign_message {}", &map1));
+ ASSERT_TRUE(
+ parser.ParseFromString("map_int32_foreign_message { key: 1 }", &map2));
+
+ util::MessageDifferencer differencer;
+ differencer.set_scope(util::MessageDifferencer::PARTIAL);
+ // TODO(jieluo): Remove the round trip
+ std::string serialized_value;
+ map1.SerializeToString(&serialized_value);
+ map1.ParseFromString(serialized_value);
+ EXPECT_FALSE(differencer.Compare(map1, map2));
+}
+
+TEST_F(ComparisonTest, MapEntryMissingEmptyFieldIsOkTest) {
+ TextFormat::Parser parser;
+ protobuf_unittest::TestMap msg1;
+ protobuf_unittest::TestMap msg2;
+
+ ASSERT_TRUE(parser.ParseFromString(
+ "map_string_foreign_message { key: 'key1' value {}}", &msg1));
+ ASSERT_TRUE(parser.ParseFromString(
+ "map_string_foreign_message { key: 'key1' }", &msg2));
+
+ util::MessageDifferencer differencer;
+ differencer.set_scope(util::MessageDifferencer::PARTIAL);
+
+ ASSERT_TRUE(differencer.Compare(msg1, msg2));
+}
+
+// Considers strings keys as equal if they have equal lengths.
+class LengthMapKeyComparator
+ : public util::MessageDifferencer::MapKeyComparator {
+ public:
+ typedef util::MessageDifferencer::SpecificField SpecificField;
+ virtual bool IsMatch(const Message& message1, const Message& message2,
+ const std::vector<SpecificField>& parent_fields) const {
+ const Reflection* reflection1 = message1.GetReflection();
+ const Reflection* reflection2 = message2.GetReflection();
+ const FieldDescriptor* key_field =
+ message1.GetDescriptor()->FindFieldByName("key");
+ return reflection1->GetString(message1, key_field).size() ==
+ reflection2->GetString(message2, key_field).size();
+ }
+};
+
+TEST_F(ComparisonTest, MapEntryCustomMapKeyComparator) {
+ TextFormat::Parser parser;
+ protobuf_unittest::TestMap msg1;
+ protobuf_unittest::TestMap msg2;
+
+ ASSERT_TRUE(parser.ParseFromString(
+ "map_string_foreign_message { key: 'key1' value { c: 1 }}", &msg1));
+ ASSERT_TRUE(parser.ParseFromString(
+ "map_string_foreign_message { key: 'key2' value { c: 1 }}", &msg2));
+
+ util::MessageDifferencer differencer;
+ LengthMapKeyComparator key_comparator;
+ differencer.TreatAsMapUsingKeyComparator(
+ GetFieldDescriptor(msg1, "map_string_foreign_message"), &key_comparator);
+ std::string output;
+ differencer.ReportDifferencesToString(&output);
+ // Though the above two messages have different keys for their map entries,
+ // they are considered the same by key_comparator because their lengths are
+ // equal. However, in value comparison, all fields of the message are taken
+ // into consideration, so they are reported as different.
+ EXPECT_FALSE(differencer.Compare(msg1, msg2));
+ EXPECT_EQ(
+ "modified: map_string_foreign_message[key1].key: \"key1\" -> \"key2\"\n",
+ output);
+ differencer.IgnoreField(
+ GetFieldDescriptor(msg1, "map_string_foreign_message.key"));
+ output.clear();
+ EXPECT_TRUE(differencer.Compare(msg1, msg2));
+ EXPECT_EQ("ignored: map_string_foreign_message[key1].key\n", output);
+}
+
+class MatchingTest : public testing::Test {
+ public:
+ typedef util::MessageDifferencer MessageDifferencer;
+
+ protected:
+ MatchingTest() {}
+
+ ~MatchingTest() {}
+
+ std::string RunWithResult(MessageDifferencer* differencer,
+ const Message& msg1, const Message& msg2,
+ bool result) {
+ std::string output;
+ {
+ // Before we return the "output" string, we must make sure the
+ // StreamReporter is destructored because its destructor will
+ // flush the stream.
+ io::StringOutputStream output_stream(&output);
+ MessageDifferencer::StreamReporter reporter(&output_stream);
+ reporter.set_report_modified_aggregates(true);
+ differencer->set_report_matches(true);
+ differencer->ReportDifferencesTo(&reporter);
+ if (result) {
+ EXPECT_TRUE(differencer->Compare(msg1, msg2));
+ } else {
+ EXPECT_FALSE(differencer->Compare(msg1, msg2));
+ }
+ }
+ return output;
+ }
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MatchingTest);
+};
+
+TEST_F(MatchingTest, StreamReporterMatching) {
+ protobuf_unittest::TestField msg1, msg2;
+ msg1.set_c(72);
+ msg2.set_c(72);
+ msg1.add_rc(13);
+ msg2.add_rc(13);
+ msg1.add_rc(17);
+ msg2.add_rc(17);
+ std::string output;
+ MessageDifferencer differencer;
+ differencer.set_report_matches(true);
+ differencer.ReportDifferencesToString(&output);
+ EXPECT_TRUE(differencer.Compare(msg1, msg2));
+ EXPECT_EQ(
+ "matched: c : 72\n"
+ "matched: rc[0] : 13\n"
+ "matched: rc[1] : 17\n",
+ output);
+}
+
+TEST_F(MatchingTest, DontReportMatchedWhenIgnoring) {
+ protobuf_unittest::TestField msg1, msg2;
+ msg1.set_c(72);
+ msg2.set_c(72);
+ msg1.add_rc(13);
+ msg2.add_rc(13);
+ msg1.add_rc(17);
+ msg2.add_rc(17);
+ std::string output;
+ MessageDifferencer differencer;
+ differencer.set_report_matches(true);
+ differencer.ReportDifferencesToString(&output);
+
+ differencer.IgnoreField(msg1.GetDescriptor()->FindFieldByName("c"));
+
+ EXPECT_TRUE(differencer.Compare(msg1, msg2));
+ EXPECT_EQ(
+ "ignored: c\n"
+ "matched: rc[0] : 13\n"
+ "matched: rc[1] : 17\n",
+ output);
+}
+
+TEST_F(MatchingTest, ReportMatchedForMovedFields) {
+ protobuf_unittest::TestDiffMessage msg1, msg2;
+ protobuf_unittest::TestDiffMessage::Item* item = msg1.add_item();
+ item->set_a(53);
+ item->set_b("hello");
+ item = msg2.add_item();
+ item->set_a(27);
+ item = msg2.add_item();
+ item->set_a(53);
+ item->set_b("hello");
+ item = msg1.add_item();
+ item->set_a(27);
+ MessageDifferencer differencer;
+ const FieldDescriptor* desc;
+ desc = msg1.GetDescriptor()->FindFieldByName("item");
+ differencer.TreatAsSet(desc);
+
+ EXPECT_EQ(
+ "matched: item[0].a -> item[1].a : 53\n"
+ "matched: item[0].b -> item[1].b : \"hello\"\n"
+ "moved: item[0] -> item[1] : { a: 53 b: \"hello\" }\n"
+ "matched: item[1].a -> item[0].a : 27\n"
+ "moved: item[1] -> item[0] : { a: 27 }\n",
+ RunWithResult(&differencer, msg1, msg2, true));
+}
+
+
+TEST_F(MatchingTest, MatchesAppearInPostTraversalOrderForMovedFields) {
+ protobuf_unittest::TestDiffMessage msg1, msg2;
+ protobuf_unittest::TestDiffMessage::Item* item;
+ protobuf_unittest::TestField* field;
+
+ const FieldDescriptor* desc;
+ const FieldDescriptor* nested_desc;
+ const FieldDescriptor* double_nested_desc;
+ desc = msg1.GetDescriptor()->FindFieldByName("item");
+ nested_desc = desc->message_type()->FindFieldByName("rm");
+ double_nested_desc = nested_desc->message_type()->FindFieldByName("rc");
+ MessageDifferencer differencer;
+ differencer.TreatAsSet(desc);
+ differencer.TreatAsSet(nested_desc);
+ differencer.TreatAsSet(double_nested_desc);
+
+ item = msg1.add_item();
+ field = item->add_rm();
+ field->set_c(1);
+ field->add_rc(2);
+ field->add_rc(3);
+ field = item->add_rm();
+ field->set_c(4);
+ field->add_rc(5);
+ field->add_rc(6);
+ field->add_rc(7);
+ item = msg2.add_item();
+ field = item->add_rm();
+ field->set_c(4);
+ field->add_rc(7);
+ field->add_rc(6);
+ field->add_rc(5);
+ field = item->add_rm();
+ field->set_c(1);
+ field->add_rc(3);
+ field->add_rc(2);
+ item = msg1.add_item();
+ field = item->add_rm();
+ field->set_c(8);
+ field->add_rc(10);
+ field->add_rc(11);
+ field->add_rc(9);
+ item = msg2.add_item();
+ field = item->add_rm();
+ field->set_c(8);
+ field->add_rc(9);
+ field->add_rc(10);
+ field->add_rc(11);
+
+ EXPECT_EQ(
+ "matched: item[0].rm[0].c -> item[0].rm[1].c : 1\n"
+ "moved: item[0].rm[0].rc[0] -> item[0].rm[1].rc[1] : 2\n"
+ "moved: item[0].rm[0].rc[1] -> item[0].rm[1].rc[0] : 3\n"
+ "moved: item[0].rm[0] -> item[0].rm[1] : { c: 1 rc: 2 rc: 3 }\n"
+ "matched: item[0].rm[1].c -> item[0].rm[0].c : 4\n"
+ "moved: item[0].rm[1].rc[0] -> item[0].rm[0].rc[2] : 5\n"
+ "matched: item[0].rm[1].rc[1] -> item[0].rm[0].rc[1] : 6\n"
+ "moved: item[0].rm[1].rc[2] -> item[0].rm[0].rc[0] : 7\n"
+ "moved: item[0].rm[1] -> item[0].rm[0] : { c: 4 rc: 5 rc: 6 rc: 7 }\n"
+ "matched: item[0] : { rm { c: 1 rc: 2 rc: 3 }"
+ " rm { c: 4 rc: 5 rc: 6 rc: 7 } }\n"
+ "matched: item[1].rm[0].c : 8\n"
+ "moved: item[1].rm[0].rc[0] -> item[1].rm[0].rc[1] : 10\n"
+ "moved: item[1].rm[0].rc[1] -> item[1].rm[0].rc[2] : 11\n"
+ "moved: item[1].rm[0].rc[2] -> item[1].rm[0].rc[0] : 9\n"
+ "matched: item[1].rm[0] : { c: 8 rc: 10 rc: 11 rc: 9 }\n"
+ "matched: item[1] : { rm { c: 8 rc: 10 rc: 11 rc: 9 } }\n",
+ RunWithResult(&differencer, msg1, msg2, true));
+}
+
+TEST_F(MatchingTest, MatchAndModifiedInterleaveProperly) {
+ protobuf_unittest::TestDiffMessage msg1, msg2;
+ protobuf_unittest::TestDiffMessage::Item* item;
+ protobuf_unittest::TestField* field;
+
+ const FieldDescriptor* desc;
+ const FieldDescriptor* nested_key;
+ const FieldDescriptor* nested_desc;
+ const FieldDescriptor* double_nested_key;
+ const FieldDescriptor* double_nested_desc;
+ desc = msg1.GetDescriptor()->FindFieldByName("item");
+ nested_key = desc->message_type()->FindFieldByName("a");
+ nested_desc = desc->message_type()->FindFieldByName("rm");
+ double_nested_key = nested_desc->message_type()->FindFieldByName("c");
+ double_nested_desc = nested_desc->message_type()->FindFieldByName("rc");
+
+ MessageDifferencer differencer;
+ differencer.TreatAsMap(desc, nested_key);
+ differencer.TreatAsMap(nested_desc, double_nested_key);
+ differencer.TreatAsSet(double_nested_desc);
+
+ item = msg1.add_item();
+ item->set_a(1);
+ field = item->add_rm();
+ field->set_c(2);
+ field->add_rc(3);
+ field->add_rc(4);
+ field = item->add_rm();
+ field->set_c(5);
+ field->add_rc(6);
+ field->add_rc(7);
+ field->add_rc(8);
+ item = msg1.add_item();
+ item->set_a(9);
+ field = item->add_rm();
+ field->set_c(10);
+ field->add_rc(11);
+ field->add_rc(12);
+ field = item->add_rm();
+ field->set_c(13);
+
+ item = msg2.add_item();
+ item->set_a(1);
+ field = item->add_rm();
+ field->set_c(5);
+ field->add_rc(8);
+ field->add_rc(8);
+ field->add_rc(6);
+ field = item->add_rm();
+ field->set_c(3);
+ field->add_rc(2);
+ field->add_rc(4);
+ item = msg2.add_item();
+ item->set_a(9);
+ field = item->add_rm();
+ field->set_c(10);
+ field->add_rc(12);
+ field->add_rc(11);
+ field = item->add_rm();
+ field->set_c(13);
+
+ EXPECT_EQ(
+ "matched: item[0].a : 1\n"
+ "matched: item[0].rm[1].c -> item[0].rm[0].c : 5\n"
+ "moved: item[0].rm[1].rc[0] -> item[0].rm[0].rc[2] : 6\n"
+ "moved: item[0].rm[1].rc[2] -> item[0].rm[0].rc[0] : 8\n"
+ "added: item[0].rm[0].rc[1]: 8\n"
+ "deleted: item[0].rm[1].rc[1]: 7\n"
+ "modified: item[0].rm[1] -> item[0].rm[0]: { c: 5 rc: 6 rc: 7 rc: 8 } ->"
+ " { c: 5 rc: 8 rc: 8 rc: 6 }\n"
+ "added: item[0].rm[1]: { c: 3 rc: 2 rc: 4 }\n"
+ "deleted: item[0].rm[0]: { c: 2 rc: 3 rc: 4 }\n"
+ "modified: item[0]: { a: 1 rm { c: 2 rc: 3 rc: 4 }"
+ " rm { c: 5 rc: 6 rc: 7 rc: 8 } } ->"
+ " { a: 1 rm { c: 5 rc: 8 rc: 8 rc: 6 }"
+ " rm { c: 3 rc: 2 rc: 4 } }\n"
+ "matched: item[1].a : 9\n"
+ "matched: item[1].rm[0].c : 10\n"
+ "moved: item[1].rm[0].rc[0] -> item[1].rm[0].rc[1] : 11\n"
+ "moved: item[1].rm[0].rc[1] -> item[1].rm[0].rc[0] : 12\n"
+ "matched: item[1].rm[0] : { c: 10 rc: 11 rc: 12 }\n"
+ "matched: item[1].rm[1].c : 13\n"
+ "matched: item[1].rm[1] : { c: 13 }\n"
+ "matched: item[1] : { a: 9 rm { c: 10 rc: 11 rc: 12 } rm { c: 13 } }\n",
+ RunWithResult(&differencer, msg1, msg2, false));
+}
+
+TEST_F(MatchingTest, MatchingWorksWithExtensions) {
+ protobuf_unittest::TestAllExtensions msg1, msg2;
+ protobuf_unittest::TestAllTypes::NestedMessage* nested;
+ using protobuf_unittest::repeated_nested_message_extension;
+
+ const FileDescriptor* descriptor;
+ const FieldDescriptor* desc;
+ const FieldDescriptor* nested_key;
+ descriptor = msg1.GetDescriptor()->file();
+ desc = descriptor->FindExtensionByName("repeated_nested_message_extension");
+ ASSERT_FALSE(desc == NULL);
+ nested_key = desc->message_type()->FindFieldByName("bb");
+
+ MessageDifferencer differencer;
+ differencer.TreatAsMap(desc, nested_key);
+
+ nested = msg1.AddExtension(repeated_nested_message_extension);
+ nested->set_bb(7);
+ nested = msg1.AddExtension(repeated_nested_message_extension);
+ nested->set_bb(13);
+ nested = msg1.AddExtension(repeated_nested_message_extension);
+ nested->set_bb(11);
+ nested = msg2.AddExtension(repeated_nested_message_extension);
+ nested->set_bb(11);
+ nested = msg2.AddExtension(repeated_nested_message_extension);
+ nested->set_bb(13);
+ nested = msg2.AddExtension(repeated_nested_message_extension);
+ nested->set_bb(7);
+
+ EXPECT_EQ(
+ "matched: (protobuf_unittest.repeated_nested_message_extension)[0].bb ->"
+ " (protobuf_unittest.repeated_nested_message_extension)[2].bb : 7\n"
+ "moved: (protobuf_unittest.repeated_nested_message_extension)[0] ->"
+ " (protobuf_unittest.repeated_nested_message_extension)[2] :"
+ " { bb: 7 }\n"
+ "matched: (protobuf_unittest.repeated_nested_message_extension)[1].bb :"
+ " 13\n"
+ "matched: (protobuf_unittest.repeated_nested_message_extension)[1] :"
+ " { bb: 13 }\n"
+ "matched: (protobuf_unittest.repeated_nested_message_extension)[2].bb ->"
+ " (protobuf_unittest.repeated_nested_message_extension)[0].bb :"
+ " 11\n"
+ "moved: (protobuf_unittest.repeated_nested_message_extension)[2] ->"
+ " (protobuf_unittest.repeated_nested_message_extension)[0] :"
+ " { bb: 11 }\n",
+ RunWithResult(&differencer, msg1, msg2, true));
+}
+
+TEST(AnyTest, Simple) {
+ protobuf_unittest::TestField value1, value2;
+ value1.set_a(20);
+ value2.set_a(21);
+
+ protobuf_unittest::TestAny m1, m2;
+ m1.mutable_any_value()->PackFrom(value1);
+ m2.mutable_any_value()->PackFrom(value2);
+ util::MessageDifferencer message_differencer;
+ std::string difference_string;
+ message_differencer.ReportDifferencesToString(&difference_string);
+ EXPECT_FALSE(message_differencer.Compare(m1, m2));
+ EXPECT_EQ("modified: any_value.a: 20 -> 21\n", difference_string);
+}
+
+TEST(Anytest, TreatAsSet) {
+ protobuf_unittest::TestField value1, value2;
+ value1.set_a(20);
+ value1.set_b(30);
+ value2.set_a(20);
+ value2.set_b(31);
+
+ protobuf_unittest::TestAny m1, m2;
+ m1.add_repeated_any_value()->PackFrom(value1);
+ m1.add_repeated_any_value()->PackFrom(value2);
+ m2.add_repeated_any_value()->PackFrom(value2);
+ m2.add_repeated_any_value()->PackFrom(value1);
+
+ util::MessageDifferencer message_differencer;
+ message_differencer.TreatAsSet(GetFieldDescriptor(m1, "repeated_any_value"));
+ EXPECT_TRUE(message_differencer.Compare(m1, m2));
+}
+
+TEST(Anytest, TreatAsSet_DifferentType) {
+ protobuf_unittest::TestField value1;
+ value1.set_a(20);
+ value1.set_b(30);
+ protobuf_unittest::TestDiffMessage value2;
+ value2.add_rv(40);
+
+ protobuf_unittest::TestAny m1, m2;
+ m1.add_repeated_any_value()->PackFrom(value1);
+ m1.add_repeated_any_value()->PackFrom(value2);
+ m2.add_repeated_any_value()->PackFrom(value2);
+ m2.add_repeated_any_value()->PackFrom(value1);
+
+ util::MessageDifferencer message_differencer;
+ message_differencer.TreatAsSet(GetFieldDescriptor(m1, "repeated_any_value"));
+ EXPECT_TRUE(message_differencer.Compare(m1, m2));
+}
+
+
+} // namespace
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/util/message_differencer_unittest.proto b/NorthstarDedicatedTest/include/protobuf/util/message_differencer_unittest.proto
new file mode 100644
index 00000000..0ad67929
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/util/message_differencer_unittest.proto
@@ -0,0 +1,79 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 messages for testing repeated field comparison
+// LINT: ALLOW_GROUPS
+
+syntax = "proto2";
+
+package protobuf_unittest;
+
+import "google/protobuf/any.proto";
+
+option optimize_for = SPEED;
+
+message TestField {
+ optional int32 a = 3;
+ optional int32 b = 4;
+ optional int32 c = 1;
+ repeated int32 rc = 2;
+ optional TestField m = 5;
+
+ extend TestDiffMessage {
+ optional TestField tf = 100;
+ }
+}
+
+message TestDiffMessage {
+ repeated group Item = 1 {
+ optional int32 a = 2; // Test basic repeated field comparison.
+ optional string b = 4; // Test basic repeated field comparison.
+ repeated int32 ra = 3; // Test SetOfSet Comparison.
+ repeated string rb = 5; // Test TreatAsMap when key is repeated
+ optional TestField m = 6; // Test TreatAsMap when key is a message
+ repeated TestField rm = 7; // Test TreatAsMap when key is a repeated
+ // message
+ map<string, int32> mp = 8; // Test for map comparisons
+ }
+
+ optional int32 v = 13 [deprecated = true];
+ optional string w = 14;
+ optional TestField m = 15;
+ repeated int32 rv = 11; // Test for combinations
+ repeated string rw = 10; // Test for combinations
+ repeated TestField rm = 12 [deprecated = true]; // Test for combinations
+ repeated google.protobuf.Any rany =
+ 16; // Test for repeated Any type resolution
+ extensions 100 to 199;
+}
diff --git a/NorthstarDedicatedTest/include/protobuf/util/package_info.h b/NorthstarDedicatedTest/include/protobuf/util/package_info.h
new file mode 100644
index 00000000..96019203
--- /dev/null
+++ b/NorthstarDedicatedTest/include/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/NorthstarDedicatedTest/include/protobuf/util/time_util.cc b/NorthstarDedicatedTest/include/protobuf/util/time_util.cc
new file mode 100644
index 00000000..4da49009
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/util/time_util.cc
@@ -0,0 +1,511 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <util/time_util.h>
+
+#include <cstdint>
+
+#include <stubs/stringprintf.h>
+#include <stubs/strutil.h>
+#include <duration.pb.h>
+#include <timestamp.pb.h>
+#include <stubs/int128.h>
+#include <stubs/time.h>
+
+// Must go after other includes.
+#include <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 seconds, int32 nanos) {
+ return ::google::protobuf::internal::FormatTime(seconds, nanos);
+}
+
+bool ParseTime(const std::string& value, int64* seconds, int32* nanos) {
+ return ::google::protobuf::internal::ParseTime(value, seconds, nanos);
+}
+
+void CurrentTime(int64* seconds, int32* nanos) {
+ return ::google::protobuf::internal::GetCurrentTime(seconds, nanos);
+}
+
+// Truncates the remainder part after division.
+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] == '-');
+ int 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, 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 = (d.seconds() * 1.0 + 1.0 * d.nanos() / kNanosPerSecond) * r;
+ int64_t seconds = static_cast<int64_t>(result);
+ int32_t nanos = static_cast<int32_t>((result - seconds) * kNanosPerSecond);
+ // Note that we normalize here not just because nanos can have a different
+ // sign from seconds but also that nanos can be any arbitrary value when
+ // overflow happens (i.e., the result is a much larger value than what
+ // int64 can represent).
+ d = CreateNormalized<Duration>(seconds, nanos);
+ return d;
+}
+
+Duration& operator/=(Duration& d, 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/NorthstarDedicatedTest/include/protobuf/util/time_util.h b/NorthstarDedicatedTest/include/protobuf/util/time_util.h
new file mode 100644
index 00000000..6442e827
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/util/time_util.h
@@ -0,0 +1,313 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Defines utilities for the Timestamp and Duration well known types.
+
+#ifndef GOOGLE_PROTOBUF_UTIL_TIME_UTIL_H__
+#define GOOGLE_PROTOBUF_UTIL_TIME_UTIL_H__
+
+#include <cstdint>
+#include <ctime>
+#include <ostream>
+#include <string>
+#ifdef _MSC_VER
+#ifdef _XBOX_ONE
+struct timeval {
+ int64 tv_sec; /* seconds */
+ int64 tv_usec; /* and microseconds */
+};
+#else
+#include <winsock2.h>
+#endif // _XBOX_ONE
+#else
+#include <sys/time.h>
+#endif
+
+#include <duration.pb.h>
+#include <timestamp.pb.h>
+
+#include <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 <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_UTIL_TIME_UTIL_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/util/time_util_test.cc b/NorthstarDedicatedTest/include/protobuf/util/time_util_test.cc
new file mode 100644
index 00000000..55a0db6f
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/util/time_util_test.cc
@@ -0,0 +1,384 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <util/time_util.h>
+
+#include <cstdint>
+#include <ctime>
+
+#include <duration.pb.h>
+#include <timestamp.pb.h>
+#include <testing/googletest.h>
+#include <gtest/gtest.h>
+
+namespace google {
+namespace protobuf {
+namespace util {
+
+using google::protobuf::Duration;
+using google::protobuf::Timestamp;
+
+namespace {
+
+TEST(TimeUtilTest, TimestampStringFormat) {
+ Timestamp begin, end;
+ EXPECT_TRUE(TimeUtil::FromString("0001-01-01T00:00:00Z", &begin));
+ EXPECT_EQ(TimeUtil::kTimestampMinSeconds, begin.seconds());
+ EXPECT_EQ(0, begin.nanos());
+ EXPECT_TRUE(TimeUtil::FromString("9999-12-31T23:59:59.999999999Z", &end));
+ EXPECT_EQ(TimeUtil::kTimestampMaxSeconds, end.seconds());
+ EXPECT_EQ(999999999, end.nanos());
+ EXPECT_EQ("0001-01-01T00:00:00Z", TimeUtil::ToString(begin));
+ EXPECT_EQ("9999-12-31T23:59:59.999999999Z", TimeUtil::ToString(end));
+
+ // Test negative timestamps.
+ Timestamp time = TimeUtil::NanosecondsToTimestamp(-1);
+ EXPECT_EQ(-1, time.seconds());
+ // Timestamp's nano part is always non-negative.
+ EXPECT_EQ(999999999, time.nanos());
+ EXPECT_EQ("1969-12-31T23:59:59.999999999Z", TimeUtil::ToString(time));
+
+ // Generated output should contain 3, 6, or 9 fractional digits.
+ EXPECT_EQ("1970-01-01T00:00:00Z",
+ TimeUtil::ToString(TimeUtil::NanosecondsToTimestamp(0)));
+ EXPECT_EQ("1970-01-01T00:00:00.010Z",
+ TimeUtil::ToString(TimeUtil::NanosecondsToTimestamp(10000000)));
+ EXPECT_EQ("1970-01-01T00:00:00.000010Z",
+ TimeUtil::ToString(TimeUtil::NanosecondsToTimestamp(10000)));
+ EXPECT_EQ("1970-01-01T00:00:00.000000010Z",
+ TimeUtil::ToString(TimeUtil::NanosecondsToTimestamp(10)));
+
+ // Parsing accepts an fractional digits as long as they fit into nano
+ // precision.
+ EXPECT_TRUE(TimeUtil::FromString("1970-01-01T00:00:00.1Z", &time));
+ EXPECT_EQ(100000000, TimeUtil::TimestampToNanoseconds(time));
+ EXPECT_TRUE(TimeUtil::FromString("1970-01-01T00:00:00.0001Z", &time));
+ EXPECT_EQ(100000, TimeUtil::TimestampToNanoseconds(time));
+ EXPECT_TRUE(TimeUtil::FromString("1970-01-01T00:00:00.0000001Z", &time));
+ EXPECT_EQ(100, TimeUtil::TimestampToNanoseconds(time));
+
+ // Also accepts offsets.
+ EXPECT_TRUE(TimeUtil::FromString("1970-01-01T00:00:00-08:00", &time));
+ EXPECT_EQ(8 * 3600, TimeUtil::TimestampToSeconds(time));
+}
+
+TEST(TimeUtilTest, DurationStringFormat) {
+ Timestamp begin, end;
+ EXPECT_TRUE(TimeUtil::FromString("0001-01-01T00:00:00Z", &begin));
+ EXPECT_TRUE(TimeUtil::FromString("9999-12-31T23:59:59.999999999Z", &end));
+
+ EXPECT_EQ("315537897599.999999999s", TimeUtil::ToString(end - begin));
+ EXPECT_EQ(999999999, (end - begin).nanos());
+ EXPECT_EQ("-315537897599.999999999s", TimeUtil::ToString(begin - end));
+ EXPECT_EQ(-999999999, (begin - end).nanos());
+
+ // Generated output should contain 3, 6, or 9 fractional digits.
+ EXPECT_EQ("1s", TimeUtil::ToString(TimeUtil::SecondsToDuration(1)));
+ EXPECT_EQ("0.010s", TimeUtil::ToString(TimeUtil::MillisecondsToDuration(10)));
+ EXPECT_EQ("0.000010s",
+ TimeUtil::ToString(TimeUtil::MicrosecondsToDuration(10)));
+ EXPECT_EQ("0.000000010s",
+ TimeUtil::ToString(TimeUtil::NanosecondsToDuration(10)));
+
+ // Parsing accepts an fractional digits as long as they fit into nano
+ // precision.
+ Duration d;
+ EXPECT_TRUE(TimeUtil::FromString("0.1s", &d));
+ EXPECT_EQ(100, TimeUtil::DurationToMilliseconds(d));
+ EXPECT_TRUE(TimeUtil::FromString("0.0001s", &d));
+ EXPECT_EQ(100, TimeUtil::DurationToMicroseconds(d));
+ EXPECT_TRUE(TimeUtil::FromString("0.0000001s", &d));
+ EXPECT_EQ(100, TimeUtil::DurationToNanoseconds(d));
+
+ // Duration must support range from -315,576,000,000s to +315576000000s
+ // which includes negative values.
+ EXPECT_TRUE(TimeUtil::FromString("315576000000.999999999s", &d));
+ EXPECT_EQ(int64_t{315576000000}, d.seconds());
+ EXPECT_EQ(999999999, d.nanos());
+ EXPECT_TRUE(TimeUtil::FromString("-315576000000.999999999s", &d));
+ EXPECT_EQ(int64_t{-315576000000}, d.seconds());
+ EXPECT_EQ(-999999999, d.nanos());
+}
+
+TEST(TimeUtilTest, GetEpoch) {
+ EXPECT_EQ(0, TimeUtil::TimestampToNanoseconds(TimeUtil::GetEpoch()));
+}
+
+TEST(TimeUtilTest, DurationIntegerConversion) {
+ EXPECT_EQ("0.000000001s",
+ TimeUtil::ToString(TimeUtil::NanosecondsToDuration(1)));
+ EXPECT_EQ("-0.000000001s",
+ TimeUtil::ToString(TimeUtil::NanosecondsToDuration(-1)));
+ EXPECT_EQ("0.000001s",
+ TimeUtil::ToString(TimeUtil::MicrosecondsToDuration(1)));
+ EXPECT_EQ("-0.000001s",
+ TimeUtil::ToString(TimeUtil::MicrosecondsToDuration(-1)));
+ EXPECT_EQ("0.001s", TimeUtil::ToString(TimeUtil::MillisecondsToDuration(1)));
+ EXPECT_EQ("-0.001s",
+ TimeUtil::ToString(TimeUtil::MillisecondsToDuration(-1)));
+ EXPECT_EQ("1s", TimeUtil::ToString(TimeUtil::SecondsToDuration(1)));
+ EXPECT_EQ("-1s", TimeUtil::ToString(TimeUtil::SecondsToDuration(-1)));
+ EXPECT_EQ("60s", TimeUtil::ToString(TimeUtil::MinutesToDuration(1)));
+ EXPECT_EQ("-60s", TimeUtil::ToString(TimeUtil::MinutesToDuration(-1)));
+ EXPECT_EQ("3600s", TimeUtil::ToString(TimeUtil::HoursToDuration(1)));
+ EXPECT_EQ("-3600s", TimeUtil::ToString(TimeUtil::HoursToDuration(-1)));
+
+ EXPECT_EQ(
+ 1, TimeUtil::DurationToNanoseconds(TimeUtil::NanosecondsToDuration(1)));
+ EXPECT_EQ(
+ -1, TimeUtil::DurationToNanoseconds(TimeUtil::NanosecondsToDuration(-1)));
+ EXPECT_EQ(
+ 1, TimeUtil::DurationToMicroseconds(TimeUtil::MicrosecondsToDuration(1)));
+ EXPECT_EQ(-1, TimeUtil::DurationToMicroseconds(
+ TimeUtil::MicrosecondsToDuration(-1)));
+ EXPECT_EQ(
+ 1, TimeUtil::DurationToMilliseconds(TimeUtil::MillisecondsToDuration(1)));
+ EXPECT_EQ(-1, TimeUtil::DurationToMilliseconds(
+ TimeUtil::MillisecondsToDuration(-1)));
+ EXPECT_EQ(1, TimeUtil::DurationToSeconds(TimeUtil::SecondsToDuration(1)));
+ EXPECT_EQ(-1, TimeUtil::DurationToSeconds(TimeUtil::SecondsToDuration(-1)));
+ EXPECT_EQ(1, TimeUtil::DurationToMinutes(TimeUtil::MinutesToDuration(1)));
+ EXPECT_EQ(-1, TimeUtil::DurationToMinutes(TimeUtil::MinutesToDuration(-1)));
+ EXPECT_EQ(1, TimeUtil::DurationToHours(TimeUtil::HoursToDuration(1)));
+ EXPECT_EQ(-1, TimeUtil::DurationToHours(TimeUtil::HoursToDuration(-1)));
+
+ // Test truncation behavior.
+ EXPECT_EQ(1, TimeUtil::DurationToMicroseconds(
+ TimeUtil::NanosecondsToDuration(1999)));
+ // For negative values, Duration will be rounded towards 0.
+ EXPECT_EQ(-1, TimeUtil::DurationToMicroseconds(
+ TimeUtil::NanosecondsToDuration(-1999)));
+}
+
+TEST(TestUtilTest, TimestampIntegerConversion) {
+ EXPECT_EQ("1970-01-01T00:00:00.000000001Z",
+ TimeUtil::ToString(TimeUtil::NanosecondsToTimestamp(1)));
+ EXPECT_EQ("1969-12-31T23:59:59.999999999Z",
+ TimeUtil::ToString(TimeUtil::NanosecondsToTimestamp(-1)));
+ EXPECT_EQ("1970-01-01T00:00:00.000001Z",
+ TimeUtil::ToString(TimeUtil::MicrosecondsToTimestamp(1)));
+ EXPECT_EQ("1969-12-31T23:59:59.999999Z",
+ TimeUtil::ToString(TimeUtil::MicrosecondsToTimestamp(-1)));
+ EXPECT_EQ("1970-01-01T00:00:00.001Z",
+ TimeUtil::ToString(TimeUtil::MillisecondsToTimestamp(1)));
+ EXPECT_EQ("1969-12-31T23:59:59.999Z",
+ TimeUtil::ToString(TimeUtil::MillisecondsToTimestamp(-1)));
+ EXPECT_EQ("1970-01-01T00:00:01Z",
+ TimeUtil::ToString(TimeUtil::SecondsToTimestamp(1)));
+ EXPECT_EQ("1969-12-31T23:59:59Z",
+ TimeUtil::ToString(TimeUtil::SecondsToTimestamp(-1)));
+
+ EXPECT_EQ(
+ 1, TimeUtil::TimestampToNanoseconds(TimeUtil::NanosecondsToTimestamp(1)));
+ EXPECT_EQ(-1, TimeUtil::TimestampToNanoseconds(
+ TimeUtil::NanosecondsToTimestamp(-1)));
+ EXPECT_EQ(1, TimeUtil::TimestampToMicroseconds(
+ TimeUtil::MicrosecondsToTimestamp(1)));
+ EXPECT_EQ(-1, TimeUtil::TimestampToMicroseconds(
+ TimeUtil::MicrosecondsToTimestamp(-1)));
+ EXPECT_EQ(1, TimeUtil::TimestampToMilliseconds(
+ TimeUtil::MillisecondsToTimestamp(1)));
+ EXPECT_EQ(-1, TimeUtil::TimestampToMilliseconds(
+ TimeUtil::MillisecondsToTimestamp(-1)));
+ EXPECT_EQ(1, TimeUtil::TimestampToSeconds(TimeUtil::SecondsToTimestamp(1)));
+ EXPECT_EQ(-1, TimeUtil::TimestampToSeconds(TimeUtil::SecondsToTimestamp(-1)));
+
+ // Test truncation behavior.
+ EXPECT_EQ(1, TimeUtil::TimestampToMicroseconds(
+ TimeUtil::NanosecondsToTimestamp(1999)));
+ // For negative values, Timestamp will be rounded down.
+ // For example, "1969-12-31T23:59:59.5Z" (i.e., -0.5s) rounded to seconds
+ // will be "1969-12-31T23:59:59Z" (i.e., -1s) rather than
+ // "1970-01-01T00:00:00Z" (i.e., 0s).
+ EXPECT_EQ(-2, TimeUtil::TimestampToMicroseconds(
+ TimeUtil::NanosecondsToTimestamp(-1999)));
+}
+
+TEST(TimeUtilTest, TimeTConversion) {
+ time_t value = time(NULL);
+ EXPECT_EQ(value,
+ TimeUtil::TimestampToTimeT(TimeUtil::TimeTToTimestamp(value)));
+ EXPECT_EQ(
+ 1, TimeUtil::TimestampToTimeT(TimeUtil::MillisecondsToTimestamp(1999)));
+}
+
+TEST(TimeUtilTest, TimevalConversion) {
+ timeval value = TimeUtil::TimestampToTimeval(
+ TimeUtil::NanosecondsToTimestamp(1999999999));
+ EXPECT_EQ(1, value.tv_sec);
+ EXPECT_EQ(999999, value.tv_usec);
+ value = TimeUtil::TimestampToTimeval(
+ TimeUtil::NanosecondsToTimestamp(-1999999999));
+ EXPECT_EQ(-2, value.tv_sec);
+ EXPECT_EQ(0, value.tv_usec);
+
+ value =
+ TimeUtil::DurationToTimeval(TimeUtil::NanosecondsToDuration(1999999999));
+ EXPECT_EQ(1, value.tv_sec);
+ EXPECT_EQ(999999, value.tv_usec);
+ value =
+ TimeUtil::DurationToTimeval(TimeUtil::NanosecondsToDuration(-1999999999));
+ EXPECT_EQ(-2, value.tv_sec);
+ EXPECT_EQ(1, value.tv_usec);
+}
+
+TEST(TimeUtilTest, DurationOperators) {
+ Duration one_second = TimeUtil::SecondsToDuration(1);
+ Duration one_nano = TimeUtil::NanosecondsToDuration(1);
+
+ // Test +/-
+ Duration a = one_second;
+ a += one_second;
+ a -= one_nano;
+ EXPECT_EQ("1.999999999s", TimeUtil::ToString(a));
+ Duration b = -a;
+ EXPECT_EQ("-1.999999999s", TimeUtil::ToString(b));
+ EXPECT_EQ("3.999999998s", TimeUtil::ToString(a + a));
+ EXPECT_EQ("0s", TimeUtil::ToString(a + b));
+ EXPECT_EQ("0s", TimeUtil::ToString(b + a));
+ EXPECT_EQ("-3.999999998s", TimeUtil::ToString(b + b));
+ EXPECT_EQ("3.999999998s", TimeUtil::ToString(a - b));
+ EXPECT_EQ("0s", TimeUtil::ToString(a - a));
+ EXPECT_EQ("0s", TimeUtil::ToString(b - b));
+ EXPECT_EQ("-3.999999998s", TimeUtil::ToString(b - a));
+
+ // Test *
+ EXPECT_EQ(a + a, a * 2);
+ EXPECT_EQ(b + b, a * (-2));
+ EXPECT_EQ(b + b, b * 2);
+ EXPECT_EQ(a + a, b * (-2));
+ EXPECT_EQ("0.999999999s", TimeUtil::ToString(a * 0.5));
+ EXPECT_EQ("-0.999999999s", TimeUtil::ToString(b * 0.5));
+ // Multiplication should not overflow if the result fits into the supported
+ // range of Duration (intermediate result may be larger than int64).
+ EXPECT_EQ("315575999684.424s", TimeUtil::ToString((one_second - one_nano) *
+ int64_t{315576000000}));
+ EXPECT_EQ("-315575999684.424s", TimeUtil::ToString((one_nano - one_second) *
+ int64_t{315576000000}));
+ EXPECT_EQ("-315575999684.424s", TimeUtil::ToString((one_second - one_nano) *
+ (int64_t{-315576000000})));
+
+ // Test / and %
+ EXPECT_EQ("0.999999999s", TimeUtil::ToString(a / 2));
+ EXPECT_EQ("-0.999999999s", TimeUtil::ToString(b / 2));
+ Duration large =
+ TimeUtil::SecondsToDuration(int64_t{315576000000}) - one_nano;
+ // We have to handle division with values beyond 64 bits.
+ EXPECT_EQ("0.999999999s", TimeUtil::ToString(large / int64_t{315576000000}));
+ EXPECT_EQ("-0.999999999s",
+ TimeUtil::ToString((-large) / int64_t{315576000000}));
+ EXPECT_EQ("-0.999999999s",
+ TimeUtil::ToString(large / (int64_t{-315576000000})));
+ Duration large2 = large + one_nano;
+ EXPECT_EQ(large, large % large2);
+ EXPECT_EQ(-large, (-large) % large2);
+ EXPECT_EQ(large, large % (-large2));
+ EXPECT_EQ(one_nano, large2 % large);
+ EXPECT_EQ(-one_nano, (-large2) % large);
+ EXPECT_EQ(one_nano, large2 % (-large));
+ // Some corner cases about negative values.
+ //
+ // (-5) / 2 = -2, remainder = -1
+ // (-5) / (-2) = 2, remainder = -1
+ a = TimeUtil::NanosecondsToDuration(-5);
+ EXPECT_EQ(TimeUtil::NanosecondsToDuration(-2), a / 2);
+ EXPECT_EQ(TimeUtil::NanosecondsToDuration(2), a / (-2));
+ b = TimeUtil::NanosecondsToDuration(2);
+ EXPECT_EQ(-2, a / b);
+ EXPECT_EQ(TimeUtil::NanosecondsToDuration(-1), a % b);
+ EXPECT_EQ(2, a / (-b));
+ EXPECT_EQ(TimeUtil::NanosecondsToDuration(-1), a % (-b));
+
+ // Test relational operators.
+ EXPECT_TRUE(one_nano < one_second);
+ EXPECT_FALSE(one_second < one_second);
+ EXPECT_FALSE(one_second < one_nano);
+ EXPECT_FALSE(-one_nano < -one_second);
+ EXPECT_FALSE(-one_second < -one_second);
+ EXPECT_TRUE(-one_second < -one_nano);
+ EXPECT_TRUE(-one_nano < one_nano);
+ EXPECT_FALSE(one_nano < -one_nano);
+
+ EXPECT_FALSE(one_nano > one_second);
+ EXPECT_FALSE(one_nano > one_nano);
+ EXPECT_TRUE(one_second > one_nano);
+
+ EXPECT_FALSE(one_nano >= one_second);
+ EXPECT_TRUE(one_nano >= one_nano);
+ EXPECT_TRUE(one_second >= one_nano);
+
+ EXPECT_TRUE(one_nano <= one_second);
+ EXPECT_TRUE(one_nano <= one_nano);
+ EXPECT_FALSE(one_second <= one_nano);
+
+ EXPECT_TRUE(one_nano == one_nano);
+ EXPECT_FALSE(one_nano == one_second);
+
+ EXPECT_FALSE(one_nano != one_nano);
+ EXPECT_TRUE(one_nano != one_second);
+}
+
+TEST(TimeUtilTest, TimestampOperators) {
+ Timestamp begin, end;
+ EXPECT_TRUE(TimeUtil::FromString("0001-01-01T00:00:00Z", &begin));
+ EXPECT_TRUE(TimeUtil::FromString("9999-12-31T23:59:59.999999999Z", &end));
+ Duration d = end - begin;
+ EXPECT_TRUE(end == begin + d);
+ EXPECT_TRUE(end == d + begin);
+ EXPECT_TRUE(begin == end - d);
+
+ // Test relational operators
+ Timestamp t1 = begin + d / 4;
+ Timestamp t2 = end - d / 4;
+ EXPECT_TRUE(t1 < t2);
+ EXPECT_FALSE(t1 < t1);
+ EXPECT_FALSE(t2 < t1);
+ EXPECT_FALSE(t1 > t2);
+ EXPECT_FALSE(t1 > t1);
+ EXPECT_TRUE(t2 > t1);
+ EXPECT_FALSE(t1 >= t2);
+ EXPECT_TRUE(t1 >= t1);
+ EXPECT_TRUE(t2 >= t1);
+ EXPECT_TRUE(t1 <= t2);
+ EXPECT_TRUE(t1 <= t1);
+ EXPECT_FALSE(t2 <= t1);
+
+ EXPECT_FALSE(t1 == t2);
+ EXPECT_TRUE(t1 == t1);
+ EXPECT_FALSE(t2 == t1);
+ EXPECT_TRUE(t1 != t2);
+ EXPECT_FALSE(t1 != t1);
+ EXPECT_TRUE(t2 != t1);
+}
+
+} // namespace
+} // namespace util
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/util/type_resolver.h b/NorthstarDedicatedTest/include/protobuf/util/type_resolver.h
new file mode 100644
index 00000000..941d6a32
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/util/type_resolver.h
@@ -0,0 +1,76 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Defines a TypeResolver for the Any message.
+
+#ifndef GOOGLE_PROTOBUF_UTIL_TYPE_RESOLVER_H__
+#define GOOGLE_PROTOBUF_UTIL_TYPE_RESOLVER_H__
+
+#include <string>
+
+#include <stubs/common.h>
+#include <type.pb.h>
+#include <stubs/status.h>
+#include <stubs/status.h>
+
+#include <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 <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_UTIL_TYPE_RESOLVER_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/util/type_resolver_util.cc b/NorthstarDedicatedTest/include/protobuf/util/type_resolver_util.cc
new file mode 100644
index 00000000..cdb1a1eb
--- /dev/null
+++ b/NorthstarDedicatedTest/include/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 <util/type_resolver_util.h>
+
+#include <type.pb.h>
+#include <wrappers.pb.h>
+#include <descriptor.pb.h>
+#include <descriptor.h>
+#include <util/internal/utility.h>
+#include <util/type_resolver.h>
+#include <stubs/strutil.h>
+#include <stubs/status.h>
+#include <stubs/status.h>
+
+// clang-format off
+#include <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/NorthstarDedicatedTest/include/protobuf/util/type_resolver_util.h b/NorthstarDedicatedTest/include/protobuf/util/type_resolver_util.h
new file mode 100644
index 00000000..4c5102dd
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/util/type_resolver_util.h
@@ -0,0 +1,57 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// 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;
+
+#include <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 <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_UTIL_TYPE_RESOLVER_UTIL_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/util/type_resolver_util_test.cc b/NorthstarDedicatedTest/include/protobuf/util/type_resolver_util_test.cc
new file mode 100644
index 00000000..bcd97109
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/util/type_resolver_util_test.cc
@@ -0,0 +1,438 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 <util/type_resolver_util.h>
+
+#include <cstdint>
+#include <limits>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include <type.pb.h>
+#include <wrappers.pb.h>
+#include <map_unittest.pb.h>
+#include <test_util.h>
+#include <unittest.pb.h>
+#include <unittest_custom_options.pb.h>
+#include <util/json_format_proto3.pb.h>
+#include <util/type_resolver.h>
+#include <testing/googletest.h>
+#include <gtest/gtest.h>
+
+namespace google {
+namespace protobuf {
+namespace util {
+namespace {
+using google::protobuf::BoolValue;
+using google::protobuf::Enum;
+using google::protobuf::EnumValue;
+using google::protobuf::Field;
+using google::protobuf::Int32Value;
+using google::protobuf::Option;
+using google::protobuf::Type;
+using google::protobuf::UInt64Value;
+
+static const char kUrlPrefix[] = "type.googleapis.com";
+
+class DescriptorPoolTypeResolverTest : public testing::Test {
+ public:
+ DescriptorPoolTypeResolverTest() {
+ resolver_.reset(NewTypeResolverForDescriptorPool(
+ kUrlPrefix, DescriptorPool::generated_pool()));
+ }
+
+ const Field* FindField(const Type& type, const std::string& name) {
+ for (int i = 0; i < type.fields_size(); ++i) {
+ const Field& field = type.fields(i);
+ if (field.name() == name) {
+ return &field;
+ }
+ }
+ return NULL;
+ }
+
+ bool HasField(const Type& type, Field::Cardinality cardinality,
+ Field::Kind kind, const std::string& name, int number) {
+ const Field* field = FindField(type, name);
+ if (field == NULL) {
+ return false;
+ }
+ return field->cardinality() == cardinality && field->kind() == kind &&
+ field->number() == number;
+ }
+
+ bool CheckFieldTypeUrl(const Type& type, const std::string& name,
+ const std::string& type_url) {
+ const Field* field = FindField(type, name);
+ if (field == NULL) {
+ return false;
+ }
+ return field->type_url() == type_url;
+ }
+
+ bool FieldInOneof(const Type& type, const std::string& name,
+ const std::string& oneof_name) {
+ const Field* field = FindField(type, name);
+ if (field == NULL || field->oneof_index() <= 0 ||
+ field->oneof_index() > type.oneofs_size()) {
+ return false;
+ }
+ return type.oneofs(field->oneof_index() - 1) == oneof_name;
+ }
+
+ bool IsPacked(const Type& type, const std::string& name) {
+ const Field* field = FindField(type, name);
+ if (field == NULL) {
+ return false;
+ }
+ return field->packed();
+ }
+
+ const EnumValue* FindEnumValue(const Enum& type, const std::string& name) {
+ for (const EnumValue& value : type.enumvalue()) {
+ if (value.name() == name) {
+ return &value;
+ }
+ }
+ return nullptr;
+ }
+
+ bool EnumHasValue(const Enum& type, const std::string& name, int number) {
+ const EnumValue* value = FindEnumValue(type, name);
+ return value != nullptr && value->number() == number;
+ }
+
+ bool HasBoolOption(const RepeatedPtrField<Option>& options,
+ const std::string& name, bool value) {
+ return HasOption<BoolValue>(options, name, value);
+ }
+
+ bool HasInt32Option(const RepeatedPtrField<Option>& options,
+ const std::string& name, int32_t value) {
+ return HasOption<Int32Value>(options, name, value);
+ }
+
+ bool HasUInt64Option(const RepeatedPtrField<Option>& options,
+ const std::string& name, uint64_t value) {
+ return HasOption<UInt64Value>(options, name, value);
+ }
+
+ template <typename WrapperT, typename T>
+ bool HasOption(const RepeatedPtrField<Option>& options,
+ const std::string& name, T value) {
+ for (const Option& option : options) {
+ if (option.name() == name) {
+ WrapperT wrapper;
+ if (option.value().UnpackTo(&wrapper) && wrapper.value() == value) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ std::string GetTypeUrl(std::string full_name) {
+ return kUrlPrefix + std::string("/") + full_name;
+ }
+
+ template <typename T>
+ std::string GetTypeUrl() {
+ return GetTypeUrl(T::descriptor()->full_name());
+ }
+
+ protected:
+ std::unique_ptr<TypeResolver> resolver_;
+};
+
+TEST_F(DescriptorPoolTypeResolverTest, TestAllTypes) {
+ Type type;
+ ASSERT_TRUE(resolver_
+ ->ResolveMessageType(
+ GetTypeUrl<protobuf_unittest::TestAllTypes>(), &type)
+ .ok());
+ // Check all optional fields.
+ EXPECT_TRUE(HasField(type, Field::CARDINALITY_OPTIONAL, Field::TYPE_INT32,
+ "optional_int32", 1));
+ EXPECT_TRUE(HasField(type, Field::CARDINALITY_OPTIONAL, Field::TYPE_INT64,
+ "optional_int64", 2));
+ EXPECT_TRUE(HasField(type, Field::CARDINALITY_OPTIONAL, Field::TYPE_UINT32,
+ "optional_uint32", 3));
+ EXPECT_TRUE(HasField(type, Field::CARDINALITY_OPTIONAL, Field::TYPE_UINT64,
+ "optional_uint64", 4));
+ EXPECT_TRUE(HasField(type, Field::CARDINALITY_OPTIONAL, Field::TYPE_SINT32,
+ "optional_sint32", 5));
+ EXPECT_TRUE(HasField(type, Field::CARDINALITY_OPTIONAL, Field::TYPE_SINT64,
+ "optional_sint64", 6));
+ EXPECT_TRUE(HasField(type, Field::CARDINALITY_OPTIONAL, Field::TYPE_FIXED32,
+ "optional_fixed32", 7));
+ EXPECT_TRUE(HasField(type, Field::CARDINALITY_OPTIONAL, Field::TYPE_FIXED64,
+ "optional_fixed64", 8));
+ EXPECT_TRUE(HasField(type, Field::CARDINALITY_OPTIONAL, Field::TYPE_SFIXED32,
+ "optional_sfixed32", 9));
+ EXPECT_TRUE(HasField(type, Field::CARDINALITY_OPTIONAL, Field::TYPE_SFIXED64,
+ "optional_sfixed64", 10));
+ EXPECT_TRUE(HasField(type, Field::CARDINALITY_OPTIONAL, Field::TYPE_FLOAT,
+ "optional_float", 11));
+ EXPECT_TRUE(HasField(type, Field::CARDINALITY_OPTIONAL, Field::TYPE_DOUBLE,
+ "optional_double", 12));
+ EXPECT_TRUE(HasField(type, Field::CARDINALITY_OPTIONAL, Field::TYPE_BOOL,
+ "optional_bool", 13));
+ EXPECT_TRUE(HasField(type, Field::CARDINALITY_OPTIONAL, Field::TYPE_STRING,
+ "optional_string", 14));
+ EXPECT_TRUE(HasField(type, Field::CARDINALITY_OPTIONAL, Field::TYPE_BYTES,
+ "optional_bytes", 15));
+
+ EXPECT_TRUE(HasField(type, Field::CARDINALITY_OPTIONAL, Field::TYPE_GROUP,
+ "optionalgroup", 16));
+
+ EXPECT_TRUE(CheckFieldTypeUrl(
+ type, "optionalgroup",
+ GetTypeUrl<protobuf_unittest::TestAllTypes::OptionalGroup>()));
+
+ EXPECT_TRUE(HasField(type, Field::CARDINALITY_OPTIONAL, Field::TYPE_MESSAGE,
+ "optional_nested_message", 18));
+ EXPECT_TRUE(HasField(type, Field::CARDINALITY_OPTIONAL, Field::TYPE_MESSAGE,
+ "optional_foreign_message", 19));
+
+ EXPECT_TRUE(CheckFieldTypeUrl(
+ type, "optional_nested_message",
+ GetTypeUrl<protobuf_unittest::TestAllTypes::NestedMessage>()));
+ EXPECT_TRUE(CheckFieldTypeUrl(type, "optional_foreign_message",
+ GetTypeUrl<protobuf_unittest::ForeignMessage>()));
+
+ EXPECT_TRUE(HasField(type, Field::CARDINALITY_OPTIONAL, Field::TYPE_ENUM,
+ "optional_nested_enum", 21));
+ EXPECT_TRUE(HasField(type, Field::CARDINALITY_OPTIONAL, Field::TYPE_ENUM,
+ "optional_foreign_enum", 22));
+
+ EXPECT_TRUE(
+ CheckFieldTypeUrl(type, "optional_nested_enum",
+ GetTypeUrl("protobuf_unittest.TestAllTypes.NestedEnum")));
+ EXPECT_TRUE(CheckFieldTypeUrl(type, "optional_foreign_enum",
+ GetTypeUrl("protobuf_unittest.ForeignEnum")));
+
+ // Check all repeated fields.
+ EXPECT_TRUE(HasField(type, Field::CARDINALITY_REPEATED, Field::TYPE_INT32,
+ "repeated_int32", 31));
+ EXPECT_TRUE(HasField(type, Field::CARDINALITY_REPEATED, Field::TYPE_INT64,
+ "repeated_int64", 32));
+ EXPECT_TRUE(HasField(type, Field::CARDINALITY_REPEATED, Field::TYPE_UINT32,
+ "repeated_uint32", 33));
+ EXPECT_TRUE(HasField(type, Field::CARDINALITY_REPEATED, Field::TYPE_UINT64,
+ "repeated_uint64", 34));
+ EXPECT_TRUE(HasField(type, Field::CARDINALITY_REPEATED, Field::TYPE_SINT32,
+ "repeated_sint32", 35));
+ EXPECT_TRUE(HasField(type, Field::CARDINALITY_REPEATED, Field::TYPE_SINT64,
+ "repeated_sint64", 36));
+ EXPECT_TRUE(HasField(type, Field::CARDINALITY_REPEATED, Field::TYPE_FIXED32,
+ "repeated_fixed32", 37));
+ EXPECT_TRUE(HasField(type, Field::CARDINALITY_REPEATED, Field::TYPE_FIXED64,
+ "repeated_fixed64", 38));
+ EXPECT_TRUE(HasField(type, Field::CARDINALITY_REPEATED, Field::TYPE_SFIXED32,
+ "repeated_sfixed32", 39));
+ EXPECT_TRUE(HasField(type, Field::CARDINALITY_REPEATED, Field::TYPE_SFIXED64,
+ "repeated_sfixed64", 40));
+ EXPECT_TRUE(HasField(type, Field::CARDINALITY_REPEATED, Field::TYPE_FLOAT,
+ "repeated_float", 41));
+ EXPECT_TRUE(HasField(type, Field::CARDINALITY_REPEATED, Field::TYPE_DOUBLE,
+ "repeated_double", 42));
+ EXPECT_TRUE(HasField(type, Field::CARDINALITY_REPEATED, Field::TYPE_BOOL,
+ "repeated_bool", 43));
+ EXPECT_TRUE(HasField(type, Field::CARDINALITY_REPEATED, Field::TYPE_STRING,
+ "repeated_string", 44));
+ EXPECT_TRUE(HasField(type, Field::CARDINALITY_REPEATED, Field::TYPE_BYTES,
+ "repeated_bytes", 45));
+
+ EXPECT_TRUE(HasField(type, Field::CARDINALITY_REPEATED, Field::TYPE_GROUP,
+ "repeatedgroup", 46));
+
+ EXPECT_TRUE(CheckFieldTypeUrl(
+ type, "repeatedgroup",
+ GetTypeUrl<protobuf_unittest::TestAllTypes::RepeatedGroup>()));
+
+ EXPECT_TRUE(HasField(type, Field::CARDINALITY_REPEATED, Field::TYPE_MESSAGE,
+ "repeated_nested_message", 48));
+ EXPECT_TRUE(HasField(type, Field::CARDINALITY_REPEATED, Field::TYPE_MESSAGE,
+ "repeated_foreign_message", 49));
+
+ EXPECT_TRUE(CheckFieldTypeUrl(
+ type, "repeated_nested_message",
+ GetTypeUrl<protobuf_unittest::TestAllTypes::NestedMessage>()));
+ EXPECT_TRUE(CheckFieldTypeUrl(type, "repeated_foreign_message",
+ GetTypeUrl<protobuf_unittest::ForeignMessage>()));
+
+ EXPECT_TRUE(HasField(type, Field::CARDINALITY_REPEATED, Field::TYPE_ENUM,
+ "repeated_nested_enum", 51));
+ EXPECT_TRUE(HasField(type, Field::CARDINALITY_REPEATED, Field::TYPE_ENUM,
+ "repeated_foreign_enum", 52));
+
+ EXPECT_TRUE(
+ CheckFieldTypeUrl(type, "repeated_nested_enum",
+ GetTypeUrl("protobuf_unittest.TestAllTypes.NestedEnum")));
+ EXPECT_TRUE(CheckFieldTypeUrl(type, "repeated_foreign_enum",
+ GetTypeUrl("protobuf_unittest.ForeignEnum")));
+}
+
+TEST_F(DescriptorPoolTypeResolverTest, TestPackedField) {
+ Type type;
+ ASSERT_TRUE(resolver_
+ ->ResolveMessageType(
+ GetTypeUrl<protobuf_unittest::TestPackedTypes>(), &type)
+ .ok());
+ EXPECT_TRUE(HasField(type, Field::CARDINALITY_REPEATED, Field::TYPE_INT32,
+ "packed_int32", 90));
+ EXPECT_TRUE(IsPacked(type, "packed_int32"));
+}
+
+TEST_F(DescriptorPoolTypeResolverTest, TestOneof) {
+ Type type;
+ ASSERT_TRUE(resolver_
+ ->ResolveMessageType(
+ GetTypeUrl<protobuf_unittest::TestAllTypes>(), &type)
+ .ok());
+ EXPECT_TRUE(HasField(type, Field::CARDINALITY_OPTIONAL, Field::TYPE_UINT32,
+ "oneof_uint32", 111));
+ EXPECT_TRUE(HasField(type, Field::CARDINALITY_OPTIONAL, Field::TYPE_MESSAGE,
+ "oneof_nested_message", 112));
+ EXPECT_TRUE(HasField(type, Field::CARDINALITY_OPTIONAL, Field::TYPE_STRING,
+ "oneof_string", 113));
+ EXPECT_TRUE(HasField(type, Field::CARDINALITY_OPTIONAL, Field::TYPE_BYTES,
+ "oneof_bytes", 114));
+ EXPECT_TRUE(FieldInOneof(type, "oneof_uint32", "oneof_field"));
+ EXPECT_TRUE(FieldInOneof(type, "oneof_nested_message", "oneof_field"));
+ EXPECT_TRUE(FieldInOneof(type, "oneof_string", "oneof_field"));
+ EXPECT_TRUE(FieldInOneof(type, "oneof_bytes", "oneof_field"));
+}
+
+TEST_F(DescriptorPoolTypeResolverTest, TestMap) {
+ Type type;
+ ASSERT_TRUE(
+ resolver_
+ ->ResolveMessageType(GetTypeUrl<protobuf_unittest::TestMap>(), &type)
+ .ok());
+ EXPECT_TRUE(HasField(type, Field::CARDINALITY_REPEATED, Field::TYPE_MESSAGE,
+ "map_int32_int32", 1));
+ EXPECT_TRUE(CheckFieldTypeUrl(
+ type, "map_int32_int32",
+ GetTypeUrl("protobuf_unittest.TestMap.MapInt32Int32Entry")));
+
+ ASSERT_TRUE(
+ resolver_
+ ->ResolveMessageType(
+ GetTypeUrl("protobuf_unittest.TestMap.MapInt32Int32Entry"), &type)
+ .ok());
+ EXPECT_TRUE(HasBoolOption(type.options(), "map_entry", true));
+}
+
+TEST_F(DescriptorPoolTypeResolverTest, TestCustomMessageOptions) {
+ Type type;
+ ASSERT_TRUE(
+ resolver_
+ ->ResolveMessageType(
+ GetTypeUrl<protobuf_unittest::TestMessageWithCustomOptions>(),
+ &type)
+ .ok());
+ EXPECT_TRUE(
+ HasInt32Option(type.options(), "protobuf_unittest.message_opt1", -56));
+}
+
+TEST_F(DescriptorPoolTypeResolverTest, TestCustomFieldOptions) {
+ Type type;
+ ASSERT_TRUE(
+ resolver_
+ ->ResolveMessageType(
+ GetTypeUrl<protobuf_unittest::TestMessageWithCustomOptions>(),
+ &type)
+ .ok());
+ const Field* field = FindField(type, "field1");
+ ASSERT_TRUE(field != nullptr);
+ EXPECT_TRUE(HasUInt64Option(field->options(), "protobuf_unittest.field_opt1",
+ 8765432109));
+}
+
+TEST_F(DescriptorPoolTypeResolverTest, TestEnum) {
+ Enum type;
+ ASSERT_TRUE(
+ resolver_
+ ->ResolveEnumType(
+ GetTypeUrl("protobuf_unittest.TestAllTypes.NestedEnum"), &type)
+ .ok());
+ EnumHasValue(type, "FOO", 1);
+ EnumHasValue(type, "BAR", 2);
+ EnumHasValue(type, "BAZ", 3);
+ EnumHasValue(type, "NEG", -1);
+}
+
+TEST_F(DescriptorPoolTypeResolverTest, TestCustomEnumOptions) {
+ Enum type;
+ ASSERT_TRUE(
+ resolver_
+ ->ResolveEnumType(
+ GetTypeUrl("protobuf_unittest.TestMessageWithCustomOptions.AnEnum"),
+ &type)
+ .ok());
+ ASSERT_TRUE(
+ HasInt32Option(type.options(), "protobuf_unittest.enum_opt1", -789));
+}
+
+TEST_F(DescriptorPoolTypeResolverTest, TestCustomValueOptions) {
+ Enum type;
+ ASSERT_TRUE(
+ resolver_
+ ->ResolveEnumType(
+ GetTypeUrl("protobuf_unittest.TestMessageWithCustomOptions.AnEnum"),
+ &type)
+ .ok());
+ const EnumValue* value = FindEnumValue(type, "ANENUM_VAL2");
+ ASSERT_TRUE(value != nullptr);
+ ASSERT_TRUE(
+ HasInt32Option(value->options(), "protobuf_unittest.enum_value_opt1", 123));
+}
+
+TEST_F(DescriptorPoolTypeResolverTest, TestJsonName) {
+ Type type;
+ ASSERT_TRUE(resolver_
+ ->ResolveMessageType(
+ GetTypeUrl<protobuf_unittest::TestAllTypes>(), &type)
+ .ok());
+ EXPECT_EQ("optionalInt32", FindField(type, "optional_int32")->json_name());
+
+ ASSERT_TRUE(
+ resolver_
+ ->ResolveMessageType(GetTypeUrl<proto3::TestCustomJsonName>(), &type)
+ .ok());
+ EXPECT_EQ("@value", FindField(type, "value")->json_name());
+}
+
+} // namespace
+} // namespace util
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/version.rc b/NorthstarDedicatedTest/include/protobuf/version.rc
new file mode 100644
index 00000000..63053406
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/version.rc
@@ -0,0 +1,45 @@
+#define VS_FF_DEBUG 0x1L
+#define VS_VERSION_INFO 0x1L
+#define VS_FFI_FILEFLAGSMASK 0x17L
+#define VER_PRIVATEBUILD 0x0L
+#define VER_PRERELEASE 0x0L
+#define VOS__WINDOWS32 0x4L
+#define VFT_DLL 0x2L
+#define VFT2_UNKNOWN 0x0L
+
+#ifndef DEBUG
+#define VER_DEBUG 0
+#else
+#define VER_DEBUG VS_FF_DEBUG
+#endif
+
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 3,19,4,0
+ PRODUCTVERSION 3,19,4,0
+ FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+ FILEFLAGS VER_DEBUG
+ FILEOS VOS__WINDOWS32
+ FILETYPE VFT_DLL
+BEGIN
+ BLOCK "VarFileInfo"
+ BEGIN
+ // English language (0x409) and the Windows Unicode codepage (1200)
+ VALUE "Translation", 0x409, 1200
+ END
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "FileDescription", "Compiled with MSVC 19.30.30704.0\0"
+ VALUE "ProductVersion", "3.19.4.0\0"
+ VALUE "FileVersion", "3.19.4.0\0"
+ VALUE "InternalName", "protobuf\0"
+ VALUE "ProductName", "Protocol Buffers - Google's Data Interchange Format\0"
+ VALUE "CompanyName", "Google Inc.\0"
+ VALUE "LegalCopyright", "Copyright 2008 Google Inc. All rights reserved.\0"
+ VALUE "Licence", "BSD\0"
+ VALUE "Info", "https://developers.google.com/protocol-buffers/\0"
+ END
+ END
+END
diff --git a/NorthstarDedicatedTest/include/protobuf/well_known_types_unittest.cc b/NorthstarDedicatedTest/include/protobuf/well_known_types_unittest.cc
new file mode 100644
index 00000000..1329df8d
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/well_known_types_unittest.cc
@@ -0,0 +1,60 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#include <unittest_well_known_types.pb.h>
+
+#include <stubs/common.h>
+#include <testing/googletest.h>
+#include <gtest/gtest.h>
+#include <stubs/stl_util.h>
+
+namespace google {
+namespace protobuf {
+namespace {
+
+// This test only checks whether well-known types are included in protobuf
+// runtime library. The test passes if it compiles.
+TEST(WellKnownTypesTest, AllKnownTypesAreIncluded) {
+ protobuf_unittest::TestWellKnownTypes message;
+ EXPECT_EQ(0, message.any_field().ByteSize());
+ EXPECT_EQ(0, message.api_field().ByteSize());
+ EXPECT_EQ(0, message.duration_field().ByteSize());
+ EXPECT_EQ(0, message.empty_field().ByteSize());
+ EXPECT_EQ(0, message.field_mask_field().ByteSize());
+ EXPECT_EQ(0, message.source_context_field().ByteSize());
+ EXPECT_EQ(0, message.struct_field().ByteSize());
+ EXPECT_EQ(0, message.timestamp_field().ByteSize());
+ EXPECT_EQ(0, message.type_field().ByteSize());
+ EXPECT_EQ(0, message.int32_field().ByteSize());
+}
+
+} // namespace
+
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/wire_format.cc b/NorthstarDedicatedTest/include/protobuf/wire_format.cc
new file mode 100644
index 00000000..5d84a72b
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/wire_format.cc
@@ -0,0 +1,1751 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <wire_format.h>
+
+#include <stack>
+#include <string>
+#include <vector>
+
+#include <stubs/logging.h>
+#include <stubs/common.h>
+#include <stubs/stringprintf.h>
+#include <descriptor.pb.h>
+#include <parse_context.h>
+#include <io/coded_stream.h>
+#include <io/zero_copy_stream.h>
+#include <io/zero_copy_stream_impl.h>
+#include <descriptor.h>
+#include <dynamic_message.h>
+#include <map_field.h>
+#include <map_field_inl.h>
+#include <message.h>
+#include <message_lite.h>
+#include <unknown_field_set.h>
+
+
+#include <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);
+ std::string payload;
+ uint32_t type_id = 0;
+ bool payload_read = false;
+ while (!ctx->Done(&ptr)) {
+ // We use 64 bit tags in order to allow typeid's that span the whole
+ // range of 32 bit numbers.
+ uint32_t tag = static_cast<uint8_t>(*ptr++);
+ if (tag == WireFormatLite::kMessageSetTypeIdTag) {
+ uint64_t tmp;
+ ptr = ParseBigVarint(ptr, &tmp);
+ GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+ type_id = tmp;
+ if (payload_read) {
+ const FieldDescriptor* field;
+ if (ctx->data().pool == nullptr) {
+ field = reflection->FindKnownExtensionByNumber(type_id);
+ } else {
+ field =
+ ctx->data().pool->FindExtensionByNumber(descriptor, type_id);
+ }
+ if (field == nullptr || field->message_type() == nullptr) {
+ WriteLengthDelimited(
+ type_id, payload,
+ metadata->mutable_unknown_fields<UnknownFieldSet>());
+ } else {
+ Message* value =
+ field->is_repeated()
+ ? reflection->AddMessage(msg, field, ctx->data().factory)
+ : reflection->MutableMessage(msg, field,
+ ctx->data().factory);
+ const char* p;
+ // We can't use regular parse from string as we have to track
+ // proper recursion depth and descriptor pools.
+ ParseContext tmp_ctx(ctx->depth(), false, &p, payload);
+ tmp_ctx.data().pool = ctx->data().pool;
+ tmp_ctx.data().factory = ctx->data().factory;
+ GOOGLE_PROTOBUF_PARSER_ASSERT(value->_InternalParse(p, &tmp_ctx) &&
+ tmp_ctx.EndedAtLimit());
+ }
+ type_id = 0;
+ }
+ continue;
+ } else if (tag == WireFormatLite::kMessageSetMessageTag) {
+ if (type_id == 0) {
+ int32_t size = ReadSize(&ptr);
+ GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+ ptr = ctx->ReadString(ptr, size, &payload);
+ GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+ payload_read = true;
+ } else {
+ // We're now parsing the payload
+ const FieldDescriptor* field = nullptr;
+ if (descriptor->IsExtensionNumber(type_id)) {
+ if (ctx->data().pool == nullptr) {
+ field = reflection->FindKnownExtensionByNumber(type_id);
+ } else {
+ field =
+ ctx->data().pool->FindExtensionByNumber(descriptor, type_id);
+ }
+ }
+ ptr = WireFormat::_InternalParseAndMergeField(
+ msg, ptr, ctx, static_cast<uint64_t>(type_id) * 8 + 2, reflection,
+ field);
+ type_id = 0;
+ }
+ } else {
+ // An unknown field in MessageSetItem.
+ ptr = ReadTag(ptr - 1, &tag);
+ if (tag == 0 || (tag & 7) == WireFormatLite::WIRETYPE_END_GROUP) {
+ ctx->SetLastTag(tag);
+ return ptr;
+ }
+ // Skip field.
+ ptr = internal::UnknownFieldParse(
+ tag, static_cast<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:
+ target = WireFormatLite::InternalWriteMessage(2, value.GetMessageValue(),
+ target, stream);
+ break;
+ case FieldDescriptor::TYPE_GROUP:
+ target = WireFormatLite::InternalWriteGroup(2, value.GetMessageValue(),
+ target, stream);
+ break;
+ }
+ return target;
+}
+
+class MapKeySorter {
+ public:
+ static std::vector<MapKey> SortKey(const Message& message,
+ const Reflection* reflection,
+ const FieldDescriptor* field) {
+ std::vector<MapKey> sorted_key_list;
+ for (MapIterator it =
+ reflection->MapBegin(const_cast<Message*>(&message), field);
+ it != reflection->MapEnd(const_cast<Message*>(&message), field);
+ ++it) {
+ sorted_key_list.push_back(it.GetKey());
+ }
+ MapKeyComparator comparator;
+ std::sort(sorted_key_list.begin(), sorted_key_list.end(), comparator);
+ return sorted_key_list;
+ }
+
+ private:
+ class MapKeyComparator {
+ public:
+ bool operator()(const MapKey& a, const MapKey& b) const {
+ GOOGLE_DCHECK(a.type() == b.type());
+ switch (a.type()) {
+#define CASE_TYPE(CppType, CamelCppType) \
+ case FieldDescriptor::CPPTYPE_##CppType: { \
+ return a.Get##CamelCppType##Value() < b.Get##CamelCppType##Value(); \
+ }
+ CASE_TYPE(STRING, String)
+ CASE_TYPE(INT64, Int64)
+ CASE_TYPE(INT32, Int32)
+ CASE_TYPE(UINT64, UInt64)
+ CASE_TYPE(UINT32, UInt32)
+ CASE_TYPE(BOOL, Bool)
+#undef CASE_TYPE
+
+ default:
+ GOOGLE_LOG(DFATAL) << "Invalid key for map field.";
+ return true;
+ }
+ }
+ };
+};
+
+static uint8_t* InternalSerializeMapEntry(const FieldDescriptor* field,
+ const MapKey& key,
+ const MapValueConstRef& value,
+ uint8_t* target,
+ io::EpsCopyOutputStream* stream) {
+ const FieldDescriptor* key_field = field->message_type()->field(0);
+ const FieldDescriptor* value_field = field->message_type()->field(1);
+
+ size_t size = kMapEntryTagByteSize;
+ size += MapKeyDataOnlyByteSize(key_field, key);
+ size += MapValueRefDataOnlyByteSize(value_field, value);
+ target = stream->EnsureSpace(target);
+ target = WireFormatLite::WriteTagToArray(
+ field->number(), WireFormatLite::WIRETYPE_LENGTH_DELIMITED, target);
+ target = io::CodedOutputStream::WriteVarint32ToArray(size, target);
+ target = SerializeMapKeyWithCachedSizes(key_field, key, target, stream);
+ target =
+ SerializeMapValueRefWithCachedSizes(value_field, value, target, stream);
+ return target;
+}
+
+uint8_t* WireFormat::InternalSerializeField(const FieldDescriptor* field,
+ const Message& message,
+ uint8_t* target,
+ io::EpsCopyOutputStream* stream) {
+ const Reflection* message_reflection = message.GetReflection();
+
+ if (field->is_extension() &&
+ field->containing_type()->options().message_set_wire_format() &&
+ field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
+ !field->is_repeated()) {
+ return InternalSerializeMessageSetItem(field, message, target, stream);
+ }
+
+ // For map fields, we can use either repeated field reflection or map
+ // reflection. Our choice has some subtle effects. If we use repeated field
+ // reflection here, then the repeated field representation becomes
+ // authoritative for this field: any existing references that came from map
+ // reflection remain valid for reading, but mutations to them are lost and
+ // will be overwritten next time we call map reflection!
+ //
+ // So far this mainly affects Python, which keeps long-term references to map
+ // values around, and always uses map reflection. See: b/35918691
+ //
+ // Here we choose to use map reflection API as long as the internal
+ // map is valid. In this way, the serialization doesn't change map field's
+ // internal state and existing references that came from map reflection remain
+ // valid for both reading and writing.
+ if (field->is_map()) {
+ const MapFieldBase* map_field =
+ message_reflection->GetMapData(message, field);
+ if (map_field->IsMapValid()) {
+ if (stream->IsSerializationDeterministic()) {
+ std::vector<MapKey> sorted_key_list =
+ MapKeySorter::SortKey(message, message_reflection, field);
+ for (std::vector<MapKey>::iterator it = sorted_key_list.begin();
+ it != sorted_key_list.end(); ++it) {
+ MapValueConstRef map_value;
+ message_reflection->LookupMapValue(message, field, *it, &map_value);
+ target =
+ InternalSerializeMapEntry(field, *it, map_value, target, stream);
+ }
+ } else {
+ for (MapIterator it = message_reflection->MapBegin(
+ const_cast<Message*>(&message), field);
+ it !=
+ message_reflection->MapEnd(const_cast<Message*>(&message), field);
+ ++it) {
+ target = InternalSerializeMapEntry(field, it.GetKey(),
+ it.GetValueRef(), target, stream);
+ }
+ }
+
+ return target;
+ }
+ }
+ int count = 0;
+
+ if (field->is_repeated()) {
+ count = message_reflection->FieldSize(message, field);
+ } else if (field->containing_type()->options().map_entry()) {
+ // Map entry fields always need to be serialized.
+ count = 1;
+ } else if (message_reflection->HasField(message, field)) {
+ count = 1;
+ }
+
+ // map_entries is for maps that'll be deterministically serialized.
+ std::vector<const Message*> map_entries;
+ if (count > 1 && field->is_map() && stream->IsSerializationDeterministic()) {
+ map_entries =
+ DynamicMapSorter::Sort(message, count, message_reflection, field);
+ }
+
+ if (field->is_packed()) {
+ if (count == 0) return target;
+ target = stream->EnsureSpace(target);
+ switch (field->type()) {
+#define HANDLE_PRIMITIVE_TYPE(TYPE, CPPTYPE, TYPE_METHOD, CPPTYPE_METHOD) \
+ case FieldDescriptor::TYPE_##TYPE: { \
+ auto r = \
+ message_reflection->GetRepeatedFieldInternal<CPPTYPE>(message, field); \
+ target = stream->Write##TYPE_METHOD##Packed( \
+ field->number(), r, FieldDataOnlyByteSize(field, message), target); \
+ break; \
+ }
+
+ HANDLE_PRIMITIVE_TYPE(INT32, 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;
+ }
+
+ 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
+
+#define HANDLE_TYPE(TYPE, TYPE_METHOD, CPPTYPE_METHOD) \
+ case FieldDescriptor::TYPE_##TYPE: \
+ target = WireFormatLite::InternalWrite##TYPE_METHOD( \
+ field->number(), \
+ field->is_repeated() \
+ ? (map_entries.empty() \
+ ? message_reflection->GetRepeated##CPPTYPE_METHOD(message, \
+ field, j) \
+ : *map_entries[j]) \
+ : message_reflection->Get##CPPTYPE_METHOD(message, field), \
+ target, stream); \
+ break;
+
+ HANDLE_TYPE(GROUP, Group, Message)
+ HANDLE_TYPE(MESSAGE, Message, Message)
+#undef HANDLE_TYPE
+
+ case FieldDescriptor::TYPE_ENUM: {
+ const EnumValueDescriptor* value =
+ field->is_repeated()
+ ? message_reflection->GetRepeatedEnum(message, field, j)
+ : message_reflection->GetEnum(message, field);
+ target = WireFormatLite::WriteEnumToArray(field->number(),
+ value->number(), target);
+ break;
+ }
+
+ // Handle strings separately so that we can get string references
+ // instead of copying.
+ case FieldDescriptor::TYPE_STRING: {
+ bool strict_utf8_check = StrictUtf8Check(field);
+ 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.
+ target = WireFormatLite::InternalWriteMessage(
+ WireFormatLite::kMessageSetMessageNumber,
+ message_reflection->GetMessage(message, field), target, stream);
+ // End group.
+ target = stream->EnsureSpace(target);
+ target = io::CodedOutputStream::WriteTagToArray(
+ WireFormatLite::kMessageSetItemEndTag, target);
+ return target;
+}
+
+// ===================================================================
+
+size_t WireFormat::ByteSize(const Message& message) {
+ const Descriptor* descriptor = message.GetDescriptor();
+ const Reflection* message_reflection = message.GetReflection();
+
+ size_t our_size = 0;
+
+ std::vector<const FieldDescriptor*> fields;
+
+ // Fields of map entry should always be serialized.
+ if (descriptor->options().map_entry()) {
+ for (int i = 0; i < descriptor->field_count(); i++) {
+ fields.push_back(descriptor->field(i));
+ }
+ } else {
+ message_reflection->ListFields(message, &fields);
+ }
+
+ for (const FieldDescriptor* field : fields) {
+ our_size += FieldByteSize(field, message);
+ }
+
+ if (descriptor->options().message_set_wire_format()) {
+ our_size += ComputeUnknownMessageSetItemsSize(
+ message_reflection->GetUnknownFields(message));
+ } else {
+ our_size +=
+ ComputeUnknownFieldsSize(message_reflection->GetUnknownFields(message));
+ }
+
+ return our_size;
+}
+
+size_t WireFormat::FieldByteSize(const FieldDescriptor* field,
+ const Message& message) {
+ const Reflection* message_reflection = message.GetReflection();
+
+ if (field->is_extension() &&
+ field->containing_type()->options().message_set_wire_format() &&
+ field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
+ !field->is_repeated()) {
+ return MessageSetItemByteSize(field, message);
+ }
+
+ size_t count = 0;
+ if (field->is_repeated()) {
+ if (field->is_map()) {
+ const MapFieldBase* map_field =
+ message_reflection->GetMapData(message, field);
+ if (map_field->IsMapValid()) {
+ count = FromIntSize(map_field->size());
+ } else {
+ count = FromIntSize(message_reflection->FieldSize(message, field));
+ }
+ } else {
+ count = FromIntSize(message_reflection->FieldSize(message, field));
+ }
+ } else if (field->containing_type()->options().map_entry()) {
+ // Map entry fields always need to be serialized.
+ count = 1;
+ } else if (message_reflection->HasField(message, field)) {
+ count = 1;
+ }
+
+ const size_t data_size = FieldDataOnlyByteSize(field, message);
+ size_t our_size = data_size;
+ if (field->is_packed()) {
+ if (data_size > 0) {
+ // Packed fields get serialized like a string, not their native type.
+ // Technically this doesn't really matter; the size only changes if it's
+ // a GROUP
+ our_size += TagSize(field->number(), FieldDescriptor::TYPE_STRING);
+ our_size += io::CodedOutputStream::VarintSize32(data_size);
+ }
+ } else {
+ our_size += count * TagSize(field->number(), field->type());
+ }
+ return our_size;
+}
+
+size_t MapKeyDataOnlyByteSize(const FieldDescriptor* field,
+ const MapKey& value) {
+ GOOGLE_DCHECK_EQ(FieldDescriptor::TypeToCppType(field->type()), value.type());
+ switch (field->type()) {
+ case FieldDescriptor::TYPE_DOUBLE:
+ case FieldDescriptor::TYPE_FLOAT:
+ case FieldDescriptor::TYPE_GROUP:
+ case FieldDescriptor::TYPE_MESSAGE:
+ case FieldDescriptor::TYPE_BYTES:
+ case FieldDescriptor::TYPE_ENUM:
+ GOOGLE_LOG(FATAL) << "Unsupported";
+ return 0;
+#define CASE_TYPE(FieldType, CamelFieldType, CamelCppType) \
+ case FieldDescriptor::TYPE_##FieldType: \
+ return WireFormatLite::CamelFieldType##Size( \
+ value.Get##CamelCppType##Value());
+
+#define FIXED_CASE_TYPE(FieldType, CamelFieldType) \
+ case FieldDescriptor::TYPE_##FieldType: \
+ return WireFormatLite::k##CamelFieldType##Size;
+
+ CASE_TYPE(INT32, Int32, Int32);
+ CASE_TYPE(INT64, Int64, Int64);
+ CASE_TYPE(UINT32, UInt32, UInt32);
+ CASE_TYPE(UINT64, UInt64, UInt64);
+ CASE_TYPE(SINT32, SInt32, Int32);
+ CASE_TYPE(SINT64, SInt64, Int64);
+ CASE_TYPE(STRING, String, String);
+ FIXED_CASE_TYPE(FIXED32, Fixed32);
+ FIXED_CASE_TYPE(FIXED64, Fixed64);
+ FIXED_CASE_TYPE(SFIXED32, SFixed32);
+ FIXED_CASE_TYPE(SFIXED64, SFixed64);
+ FIXED_CASE_TYPE(BOOL, Bool);
+
+#undef CASE_TYPE
+#undef FIXED_CASE_TYPE
+ }
+ GOOGLE_LOG(FATAL) << "Cannot get here";
+ return 0;
+}
+
+static size_t MapValueRefDataOnlyByteSize(const FieldDescriptor* field,
+ const MapValueConstRef& value) {
+ switch (field->type()) {
+ case FieldDescriptor::TYPE_GROUP:
+ GOOGLE_LOG(FATAL) << "Unsupported";
+ return 0;
+#define CASE_TYPE(FieldType, CamelFieldType, CamelCppType) \
+ case FieldDescriptor::TYPE_##FieldType: \
+ return WireFormatLite::CamelFieldType##Size( \
+ value.Get##CamelCppType##Value());
+
+#define FIXED_CASE_TYPE(FieldType, CamelFieldType) \
+ case FieldDescriptor::TYPE_##FieldType: \
+ return WireFormatLite::k##CamelFieldType##Size;
+
+ CASE_TYPE(INT32, Int32, Int32);
+ CASE_TYPE(INT64, Int64, Int64);
+ CASE_TYPE(UINT32, UInt32, UInt32);
+ CASE_TYPE(UINT64, UInt64, UInt64);
+ CASE_TYPE(SINT32, SInt32, Int32);
+ CASE_TYPE(SINT64, SInt64, Int64);
+ CASE_TYPE(STRING, String, String);
+ CASE_TYPE(BYTES, Bytes, String);
+ CASE_TYPE(ENUM, Enum, Enum);
+ CASE_TYPE(MESSAGE, Message, Message);
+ FIXED_CASE_TYPE(FIXED32, Fixed32);
+ FIXED_CASE_TYPE(FIXED64, Fixed64);
+ FIXED_CASE_TYPE(SFIXED32, SFixed32);
+ FIXED_CASE_TYPE(SFIXED64, SFixed64);
+ FIXED_CASE_TYPE(DOUBLE, Double);
+ FIXED_CASE_TYPE(FLOAT, Float);
+ FIXED_CASE_TYPE(BOOL, Bool);
+
+#undef CASE_TYPE
+#undef FIXED_CASE_TYPE
+ }
+ GOOGLE_LOG(FATAL) << "Cannot get here";
+ return 0;
+}
+
+size_t WireFormat::FieldDataOnlyByteSize(const FieldDescriptor* field,
+ const Message& message) {
+ const Reflection* message_reflection = message.GetReflection();
+
+ size_t data_size = 0;
+
+ if (field->is_map()) {
+ const MapFieldBase* map_field =
+ message_reflection->GetMapData(message, field);
+ if (map_field->IsMapValid()) {
+ MapIterator iter(const_cast<Message*>(&message), field);
+ MapIterator end(const_cast<Message*>(&message), field);
+ const FieldDescriptor* key_field = field->message_type()->field(0);
+ const FieldDescriptor* value_field = field->message_type()->field(1);
+ for (map_field->MapBegin(&iter), map_field->MapEnd(&end); iter != end;
+ ++iter) {
+ size_t size = kMapEntryTagByteSize;
+ size += MapKeyDataOnlyByteSize(key_field, iter.GetKey());
+ size += MapValueRefDataOnlyByteSize(value_field, iter.GetValueRef());
+ data_size += WireFormatLite::LengthDelimitedSize(size);
+ }
+ return data_size;
+ }
+ }
+
+ size_t count = 0;
+ if (field->is_repeated()) {
+ count =
+ internal::FromIntSize(message_reflection->FieldSize(message, field));
+ } else if (field->containing_type()->options().map_entry()) {
+ // Map entry fields always need to be serialized.
+ count = 1;
+ } else if (message_reflection->HasField(message, field)) {
+ count = 1;
+ }
+
+ switch (field->type()) {
+#define HANDLE_TYPE(TYPE, TYPE_METHOD, CPPTYPE_METHOD) \
+ case FieldDescriptor::TYPE_##TYPE: \
+ if (field->is_repeated()) { \
+ for (size_t j = 0; j < count; j++) { \
+ data_size += WireFormatLite::TYPE_METHOD##Size( \
+ message_reflection->GetRepeated##CPPTYPE_METHOD(message, field, \
+ j)); \
+ } \
+ } else { \
+ data_size += WireFormatLite::TYPE_METHOD##Size( \
+ message_reflection->Get##CPPTYPE_METHOD(message, field)); \
+ } \
+ break;
+
+#define HANDLE_FIXED_TYPE(TYPE, TYPE_METHOD) \
+ case FieldDescriptor::TYPE_##TYPE: \
+ data_size += count * WireFormatLite::k##TYPE_METHOD##Size; \
+ break;
+
+ HANDLE_TYPE(INT32, Int32, Int32)
+ HANDLE_TYPE(INT64, Int64, Int64)
+ HANDLE_TYPE(SINT32, SInt32, Int32)
+ HANDLE_TYPE(SINT64, SInt64, Int64)
+ HANDLE_TYPE(UINT32, UInt32, UInt32)
+ HANDLE_TYPE(UINT64, UInt64, UInt64)
+
+ HANDLE_FIXED_TYPE(FIXED32, Fixed32)
+ HANDLE_FIXED_TYPE(FIXED64, Fixed64)
+ HANDLE_FIXED_TYPE(SFIXED32, SFixed32)
+ HANDLE_FIXED_TYPE(SFIXED64, SFixed64)
+
+ HANDLE_FIXED_TYPE(FLOAT, Float)
+ HANDLE_FIXED_TYPE(DOUBLE, Double)
+
+ HANDLE_FIXED_TYPE(BOOL, Bool)
+
+ HANDLE_TYPE(GROUP, Group, Message)
+ HANDLE_TYPE(MESSAGE, Message, Message)
+#undef HANDLE_TYPE
+#undef HANDLE_FIXED_TYPE
+
+ case FieldDescriptor::TYPE_ENUM: {
+ if (field->is_repeated()) {
+ for (size_t j = 0; j < count; j++) {
+ data_size += WireFormatLite::EnumSize(
+ message_reflection->GetRepeatedEnum(message, field, j)->number());
+ }
+ } else {
+ data_size += WireFormatLite::EnumSize(
+ message_reflection->GetEnum(message, field)->number());
+ }
+ break;
+ }
+
+ // Handle strings separately so that we can get string references
+ // instead of copying.
+ case FieldDescriptor::TYPE_STRING:
+ case FieldDescriptor::TYPE_BYTES: {
+ for (size_t j = 0; j < count; j++) {
+ 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 <port_undef.inc>
diff --git a/NorthstarDedicatedTest/include/protobuf/wire_format.h b/NorthstarDedicatedTest/include/protobuf/wire_format.h
new file mode 100644
index 00000000..bd1184fd
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/wire_format.h
@@ -0,0 +1,414 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// atenasio@google.com (Chris Atenasio) (ZigZag transform)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// This header is logically internal, but is made public because it is used
+// from protocol-compiler-generated code, which may reside in other components.
+
+#ifndef GOOGLE_PROTOBUF_WIRE_FORMAT_H__
+#define GOOGLE_PROTOBUF_WIRE_FORMAT_H__
+
+#include <string>
+
+#include <stubs/common.h>
+#include <parse_context.h>
+#include <io/coded_stream.h>
+#include <descriptor.h>
+#include <generated_message_util.h>
+#include <message.h>
+#include <metadata_lite.h>
+#include <wire_format_lite.h>
+#include <stubs/casts.h>
+
+#ifdef SWIG
+#error "You cannot SWIG proto headers"
+#endif
+
+#include <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 <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_WIRE_FORMAT_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/wire_format_lite.cc b/NorthstarDedicatedTest/include/protobuf/wire_format_lite.cc
new file mode 100644
index 00000000..93d592e0
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/wire_format_lite.cc
@@ -0,0 +1,784 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <wire_format_lite.h>
+
+#include <limits>
+#include <stack>
+#include <string>
+#include <vector>
+
+#include <stubs/logging.h>
+#include <stubs/common.h>
+#include <stubs/stringprintf.h>
+#include <io/coded_stream.h>
+#include <io/zero_copy_stream.h>
+#include <io/zero_copy_stream_impl_lite.h>
+
+
+#include <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);
+}
+
+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(const char* 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 != nullptr) {
+ quoted_field_name = StringPrintf(" '%s'", field_name);
+ }
+ GOOGLE_LOG(ERROR) << "String field" << quoted_field_name << " contains invalid "
+ << "UTF-8 data when " << operation_str << " a protocol "
+ << "buffer. Use the 'bytes' type if you intend to send raw "
+ << "bytes. " << stacktrace;
+}
+
+bool WireFormatLite::VerifyUtf8String(const char* data, int size, Operation op,
+ const char* field_name) {
+ if (!IsStructurallyValidUTF8(data, size)) {
+ const char* operation_str = nullptr;
+ switch (op) {
+ case PARSE:
+ operation_str = "parsing";
+ break;
+ case SERIALIZE:
+ operation_str = "serializing";
+ break;
+ // no default case: have the compiler warn if a case is not covered.
+ }
+ PrintUTF8ErrorLog(field_name, operation_str, false);
+ return false;
+ }
+ return true;
+}
+
+// this code is deliberately written such that clang makes it into really
+// efficient SSE code.
+template <bool ZigZag, bool SignExtended, typename T>
+static size_t VarintSize(const T* data, const int n) {
+ static_assert(sizeof(T) == 4, "This routine only works for 32 bit integers");
+ // is_unsigned<T> => !ZigZag
+ static_assert(
+ (std::is_unsigned<T>::value ^ ZigZag) || std::is_signed<T>::value,
+ "Cannot ZigZag encode unsigned types");
+ // is_unsigned<T> => !SignExtended
+ static_assert(
+ (std::is_unsigned<T>::value ^ SignExtended) || std::is_signed<T>::value,
+ "Cannot SignExtended unsigned types");
+ static_assert(!(SignExtended && ZigZag),
+ "Cannot SignExtended and ZigZag on the same type");
+ 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 <port_undef.inc>
diff --git a/NorthstarDedicatedTest/include/protobuf/wire_format_lite.h b/NorthstarDedicatedTest/include/protobuf/wire_format_lite.h
new file mode 100644
index 00000000..2d010231
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/wire_format_lite.h
@@ -0,0 +1,1915 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// atenasio@google.com (Chris Atenasio) (ZigZag transform)
+// wink@google.com (Wink Saville) (refactored from wire_format.h)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// This header is logically internal, but is made public because it is used
+// from protocol-compiler-generated code, which may reside in other components.
+
+#ifndef GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_H__
+#define GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_H__
+
+#include <string>
+
+#include <stubs/common.h>
+#include <stubs/logging.h>
+#include <io/coded_stream.h>
+#include <arenastring.h>
+#include <message_lite.h>
+#include <port.h>
+#include <repeated_field.h>
+#include <stubs/casts.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
+
+
+#include <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.
+ template <typename MessageType>
+ PROTOBUF_NDEBUG_INLINE static uint8_t* InternalWriteGroup(
+ int field_number, const MessageType& value, uint8_t* target,
+ io::EpsCopyOutputStream* stream);
+ template <typename MessageType>
+ PROTOBUF_NDEBUG_INLINE static uint8_t* InternalWriteMessage(
+ int field_number, const MessageType& value, uint8_t* target,
+ io::EpsCopyOutputStream* stream);
+
+ // Like above, but de-virtualize the call to SerializeWithCachedSizes(). The
+ // pointer must point at an instance of MessageType, *not* a subclass (or
+ // the subclass must not override SerializeWithCachedSizes()).
+ template <typename MessageType>
+ PROTOBUF_NDEBUG_INLINE static uint8_t* InternalWriteGroupNoVirtualToArray(
+ int field_number, const MessageType& value, uint8_t* target);
+ template <typename MessageType>
+ PROTOBUF_NDEBUG_INLINE static uint8_t* InternalWriteMessageNoVirtualToArray(
+ int field_number, const MessageType& value, uint8_t* target);
+
+ // For backward-compatibility, the last four methods also have versions
+ // that are non-deterministic always.
+ PROTOBUF_NDEBUG_INLINE static uint8_t* WriteGroupToArray(
+ int field_number, const MessageLite& value, uint8_t* target) {
+ io::EpsCopyOutputStream stream(
+ target,
+ value.GetCachedSize() +
+ static_cast<int>(2 * io::CodedOutputStream::VarintSize32(
+ static_cast<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, 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);
+}
+
+
+template <typename MessageType>
+inline uint8_t* WireFormatLite::InternalWriteGroup(
+ int field_number, const MessageType& value, uint8_t* target,
+ io::EpsCopyOutputStream* stream) {
+ target = WriteTagToArray(field_number, WIRETYPE_START_GROUP, target);
+ target = value._InternalSerialize(target, stream);
+ target = stream->EnsureSpace(target);
+ return WriteTagToArray(field_number, WIRETYPE_END_GROUP, target);
+}
+template <typename MessageType>
+inline uint8_t* WireFormatLite::InternalWriteMessage(
+ int field_number, const MessageType& value, uint8_t* target,
+ io::EpsCopyOutputStream* stream) {
+ target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target);
+ target = io::CodedOutputStream::WriteVarint32ToArrayOutOfLine(
+ static_cast<uint32_t>(value.GetCachedSize()), target);
+ return value._InternalSerialize(target, stream);
+}
+
+// See comment on ReadGroupNoVirtual to understand the need for this template
+// parameter name.
+template <typename MessageType_WorkAroundCppLookupDefect>
+inline uint8_t* WireFormatLite::InternalWriteGroupNoVirtualToArray(
+ int field_number, const MessageType_WorkAroundCppLookupDefect& value,
+ uint8_t* target) {
+ target = WriteTagToArray(field_number, WIRETYPE_START_GROUP, target);
+ target = value.MessageType_WorkAroundCppLookupDefect::
+ SerializeWithCachedSizesToArray(target);
+ return WriteTagToArray(field_number, WIRETYPE_END_GROUP, target);
+}
+template <typename MessageType_WorkAroundCppLookupDefect>
+inline uint8_t* WireFormatLite::InternalWriteMessageNoVirtualToArray(
+ int field_number, const MessageType_WorkAroundCppLookupDefect& value,
+ uint8_t* target) {
+ target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target);
+ target = io::CodedOutputStream::WriteVarint32ToArray(
+ static_cast<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;
+
+ 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;
+ last_type_id = type_id;
+
+ if (!message_data.empty()) {
+ // We saw some message data before the type_id. Have to parse it
+ // now.
+ io::CodedInputStream sub_input(
+ reinterpret_cast<const uint8_t*>(message_data.data()),
+ static_cast<int>(message_data.size()));
+ sub_input.SetRecursionLimit(input->RecursionBudget());
+ if (!ms.ParseField(last_type_id, &sub_input)) {
+ return false;
+ }
+ message_data.clear();
+ }
+
+ break;
+ }
+
+ case WireFormatLite::kMessageSetMessageTag: {
+ if (last_type_id == 0) {
+ // We haven't seen a type_id yet. Append this data to message_data.
+ 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;
+ } else {
+ // Already saw type_id, so we can parse this directly.
+ if (!ms.ParseField(last_type_id, input)) {
+ return false;
+ }
+ }
+
+ break;
+ }
+
+ case WireFormatLite::kMessageSetItemEndTag: {
+ return true;
+ }
+
+ default: {
+ if (!ms.SkipField(tag, input)) return false;
+ }
+ }
+ }
+}
+
+} // namespace internal
+} // namespace protobuf
+} // namespace google
+
+#include <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/wire_format_unittest.cc b/NorthstarDedicatedTest/include/protobuf/wire_format_unittest.cc
new file mode 100644
index 00000000..9e8e2c60
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/wire_format_unittest.cc
@@ -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.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <wire_format.h>
+
+#include <unittest.pb.h>
+#include <unittest_mset.pb.h>
+#include <unittest_mset_wire_format.pb.h>
+#include <unittest_proto3_arena.pb.h>
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+#define UNITTEST ::protobuf_unittest
+#define UNITTEST_IMPORT ::protobuf_unittest_import
+#define UNITTEST_PACKAGE_NAME "protobuf_unittest"
+#define PROTO2_WIREFORMAT_UNITTEST ::proto2_wireformat_unittest
+#define PROTO3_ARENA_UNITTEST ::proto3_arena_unittest
+
+// Must include after defining UNITTEST, etc.
+// clang-format off
+#include <test_util.inc>
+#include <wire_format_unittest.inc>
+// clang-format on
+
+// Must be included last.
+#include <port_def.inc>
+
+namespace google {
+namespace protobuf {
+namespace internal {
+namespace {
+
+
+} // namespace
+} // namespace internal
+} // namespace protobuf
+} // namespace google
+
+#include <port_undef.inc>
diff --git a/NorthstarDedicatedTest/include/protobuf/wire_format_unittest.inc b/NorthstarDedicatedTest/include/protobuf/wire_format_unittest.inc
new file mode 100644
index 00000000..17381c37
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/wire_format_unittest.inc
@@ -0,0 +1,1585 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (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 <wire_format.h>
+
+#include <stubs/logging.h>
+#include <stubs/common.h>
+#include <test_util2.h>
+#include <io/coded_stream.h>
+#include <io/zero_copy_stream_impl.h>
+#include <io/zero_copy_stream_impl_lite.h>
+#include <descriptor.h>
+#include <wire_format_lite.h>
+#include <testing/googletest.h>
+#include <stubs/logging.h>
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+#include <stubs/casts.h>
+#include <stubs/strutil.h>
+#include <stubs/stl_util.h>
+
+// clang-format off
+#include <port_def.inc>
+// clang-format on
+
+namespace google {
+namespace protobuf {
+namespace internal {
+namespace {
+
+TEST(WireFormatTest, EnumsInSync) {
+ // Verify that WireFormatLite::FieldType and WireFormatLite::CppType match
+ // FieldDescriptor::Type and FieldDescriptor::CppType.
+
+ EXPECT_EQ(implicit_cast<int>(FieldDescriptor::MAX_TYPE),
+ implicit_cast<int>(WireFormatLite::MAX_FIELD_TYPE));
+ EXPECT_EQ(implicit_cast<int>(FieldDescriptor::MAX_CPPTYPE),
+ implicit_cast<int>(WireFormatLite::MAX_CPPTYPE));
+
+ for (int i = 1; i <= WireFormatLite::MAX_FIELD_TYPE; i++) {
+ EXPECT_EQ(implicit_cast<int>(FieldDescriptor::TypeToCppType(
+ static_cast<FieldDescriptor::Type>(i))),
+ implicit_cast<int>(WireFormatLite::FieldTypeToCppType(
+ static_cast<WireFormatLite::FieldType>(i))));
+ }
+}
+
+TEST(WireFormatTest, MaxFieldNumber) {
+ // Make sure the max field number constant is accurate.
+ EXPECT_EQ((1 << (32 - WireFormatLite::kTagTypeBits)) - 1,
+ FieldDescriptor::kMaxNumber);
+}
+
+TEST(WireFormatTest, Parse) {
+ UNITTEST::TestAllTypes source, dest;
+ std::string data;
+
+ // Serialize using the generated code.
+ TestUtil::SetAllFields(&source);
+ source.SerializeToString(&data);
+
+ // Parse using WireFormat.
+ io::ArrayInputStream raw_input(data.data(), data.size());
+ io::CodedInputStream input(&raw_input);
+ WireFormat::ParseAndMergePartial(&input, &dest);
+
+ // Check.
+ TestUtil::ExpectAllFieldsSet(dest);
+}
+
+TEST(WireFormatTest, ParseExtensions) {
+ UNITTEST::TestAllExtensions source, dest;
+ std::string data;
+
+ // Serialize using the generated code.
+ TestUtil::SetAllExtensions(&source);
+ source.SerializeToString(&data);
+
+ // Parse using WireFormat.
+ io::ArrayInputStream raw_input(data.data(), data.size());
+ io::CodedInputStream input(&raw_input);
+ WireFormat::ParseAndMergePartial(&input, &dest);
+
+ // Check.
+ TestUtil::ExpectAllExtensionsSet(dest);
+}
+
+TEST(WireFormatTest, ParsePacked) {
+ UNITTEST::TestPackedTypes source, dest;
+ std::string data;
+
+ // Serialize using the generated code.
+ TestUtil::SetPackedFields(&source);
+ source.SerializeToString(&data);
+
+ // Parse using WireFormat.
+ io::ArrayInputStream raw_input(data.data(), data.size());
+ io::CodedInputStream input(&raw_input);
+ WireFormat::ParseAndMergePartial(&input, &dest);
+
+ // Check.
+ TestUtil::ExpectPackedFieldsSet(dest);
+}
+
+TEST(WireFormatTest, ParsePackedFromUnpacked) {
+ // Serialize using the generated code.
+ UNITTEST::TestUnpackedTypes source;
+ TestUtil::SetUnpackedFields(&source);
+ std::string data = source.SerializeAsString();
+
+ // Parse using WireFormat.
+ UNITTEST::TestPackedTypes dest;
+ io::ArrayInputStream raw_input(data.data(), data.size());
+ io::CodedInputStream input(&raw_input);
+ WireFormat::ParseAndMergePartial(&input, &dest);
+
+ // Check.
+ TestUtil::ExpectPackedFieldsSet(dest);
+}
+
+TEST(WireFormatTest, ParseUnpackedFromPacked) {
+ // Serialize using the generated code.
+ UNITTEST::TestPackedTypes source;
+ TestUtil::SetPackedFields(&source);
+ std::string data = source.SerializeAsString();
+
+ // Parse using WireFormat.
+ UNITTEST::TestUnpackedTypes dest;
+ io::ArrayInputStream raw_input(data.data(), data.size());
+ io::CodedInputStream input(&raw_input);
+ WireFormat::ParseAndMergePartial(&input, &dest);
+
+ // Check.
+ TestUtil::ExpectUnpackedFieldsSet(dest);
+}
+
+TEST(WireFormatTest, ParsePackedExtensions) {
+ UNITTEST::TestPackedExtensions source, dest;
+ std::string data;
+
+ // Serialize using the generated code.
+ TestUtil::SetPackedExtensions(&source);
+ source.SerializeToString(&data);
+
+ // Parse using WireFormat.
+ io::ArrayInputStream raw_input(data.data(), data.size());
+ io::CodedInputStream input(&raw_input);
+ WireFormat::ParseAndMergePartial(&input, &dest);
+
+ // Check.
+ TestUtil::ExpectPackedExtensionsSet(dest);
+}
+
+TEST(WireFormatTest, ParseOneof) {
+ UNITTEST::TestOneof2 source, dest;
+ std::string data;
+
+ // Serialize using the generated code.
+ TestUtil::SetOneof1(&source);
+ source.SerializeToString(&data);
+
+ // Parse using WireFormat.
+ io::ArrayInputStream raw_input(data.data(), data.size());
+ io::CodedInputStream input(&raw_input);
+ WireFormat::ParseAndMergePartial(&input, &dest);
+
+ // Check.
+ TestUtil::ExpectOneofSet1(dest);
+}
+
+TEST(WireFormatTest, OneofOnlySetLast) {
+ UNITTEST::TestOneofBackwardsCompatible source;
+ UNITTEST::TestOneof oneof_dest;
+ std::string data;
+
+ // Set two fields
+ source.set_foo_int(100);
+ source.set_foo_string("101");
+
+ // Serialize and parse to oneof message. Generated serializer may not order
+ // fields in tag order. Use WireFormat::SerializeWithCachedSizes instead as
+ // it sorts fields beforehand.
+ {
+ io::StringOutputStream raw_output(&data);
+ io::CodedOutputStream output(&raw_output);
+ WireFormat::SerializeWithCachedSizes(source, source.ByteSizeLong(),
+ &output);
+ ASSERT_FALSE(output.HadError());
+ }
+ io::ArrayInputStream raw_input(data.data(), data.size());
+ io::CodedInputStream input(&raw_input);
+ WireFormat::ParseAndMergePartial(&input, &oneof_dest);
+
+ // Only the last field is set.
+ EXPECT_FALSE(oneof_dest.has_foo_int());
+ EXPECT_TRUE(oneof_dest.has_foo_string());
+}
+
+TEST(WireFormatTest, ByteSize) {
+ UNITTEST::TestAllTypes message;
+ TestUtil::SetAllFields(&message);
+
+ EXPECT_EQ(message.ByteSizeLong(), WireFormat::ByteSize(message));
+ message.Clear();
+ EXPECT_EQ(0, message.ByteSizeLong());
+ EXPECT_EQ(0, WireFormat::ByteSize(message));
+}
+
+TEST(WireFormatTest, ByteSizeExtensions) {
+ UNITTEST::TestAllExtensions message;
+ TestUtil::SetAllExtensions(&message);
+
+ EXPECT_EQ(message.ByteSizeLong(), WireFormat::ByteSize(message));
+ message.Clear();
+ EXPECT_EQ(0, message.ByteSizeLong());
+ EXPECT_EQ(0, WireFormat::ByteSize(message));
+}
+
+TEST(WireFormatTest, ByteSizePacked) {
+ UNITTEST::TestPackedTypes message;
+ TestUtil::SetPackedFields(&message);
+
+ EXPECT_EQ(message.ByteSizeLong(), WireFormat::ByteSize(message));
+ message.Clear();
+ EXPECT_EQ(0, message.ByteSizeLong());
+ EXPECT_EQ(0, WireFormat::ByteSize(message));
+}
+
+TEST(WireFormatTest, ByteSizePackedExtensions) {
+ UNITTEST::TestPackedExtensions message;
+ TestUtil::SetPackedExtensions(&message);
+
+ EXPECT_EQ(message.ByteSizeLong(), WireFormat::ByteSize(message));
+ message.Clear();
+ EXPECT_EQ(0, message.ByteSizeLong());
+ EXPECT_EQ(0, WireFormat::ByteSize(message));
+}
+
+TEST(WireFormatTest, ByteSizeOneof) {
+ UNITTEST::TestOneof2 message;
+ TestUtil::SetOneof1(&message);
+
+ EXPECT_EQ(message.ByteSizeLong(), WireFormat::ByteSize(message));
+ message.Clear();
+
+ EXPECT_EQ(0, message.ByteSizeLong());
+ EXPECT_EQ(0, WireFormat::ByteSize(message));
+}
+
+TEST(WireFormatTest, Serialize) {
+ UNITTEST::TestAllTypes message;
+ std::string generated_data;
+ std::string dynamic_data;
+
+ TestUtil::SetAllFields(&message);
+ size_t size = message.ByteSizeLong();
+
+ // Serialize using the generated code.
+ {
+ io::StringOutputStream raw_output(&generated_data);
+ io::CodedOutputStream output(&raw_output);
+ message.SerializeWithCachedSizes(&output);
+ ASSERT_FALSE(output.HadError());
+ }
+
+ // Serialize using WireFormat.
+ {
+ io::StringOutputStream raw_output(&dynamic_data);
+ io::CodedOutputStream output(&raw_output);
+ WireFormat::SerializeWithCachedSizes(message, size, &output);
+ ASSERT_FALSE(output.HadError());
+ }
+
+ // Should parse to the same message.
+ EXPECT_TRUE(TestUtil::EqualsToSerialized(message, generated_data));
+ EXPECT_TRUE(TestUtil::EqualsToSerialized(message, dynamic_data));
+}
+
+TEST(WireFormatTest, SerializeExtensions) {
+ UNITTEST::TestAllExtensions message;
+ std::string generated_data;
+ std::string dynamic_data;
+
+ TestUtil::SetAllExtensions(&message);
+ size_t size = message.ByteSizeLong();
+
+ // Serialize using the generated code.
+ {
+ io::StringOutputStream raw_output(&generated_data);
+ io::CodedOutputStream output(&raw_output);
+ message.SerializeWithCachedSizes(&output);
+ ASSERT_FALSE(output.HadError());
+ }
+
+ // Serialize using WireFormat.
+ {
+ io::StringOutputStream raw_output(&dynamic_data);
+ io::CodedOutputStream output(&raw_output);
+ WireFormat::SerializeWithCachedSizes(message, size, &output);
+ ASSERT_FALSE(output.HadError());
+ }
+
+ // Should parse to the same message.
+ EXPECT_TRUE(TestUtil::EqualsToSerialized(message, generated_data));
+ EXPECT_TRUE(TestUtil::EqualsToSerialized(message, dynamic_data));
+}
+
+TEST(WireFormatTest, SerializeFieldsAndExtensions) {
+ UNITTEST::TestFieldOrderings message;
+ std::string generated_data;
+ std::string dynamic_data;
+
+ TestUtil::SetAllFieldsAndExtensions(&message);
+ size_t size = message.ByteSizeLong();
+
+ // Serialize using the generated code.
+ {
+ io::StringOutputStream raw_output(&generated_data);
+ io::CodedOutputStream output(&raw_output);
+ message.SerializeWithCachedSizes(&output);
+ ASSERT_FALSE(output.HadError());
+ }
+
+ // Serialize using WireFormat.
+ {
+ io::StringOutputStream raw_output(&dynamic_data);
+ io::CodedOutputStream output(&raw_output);
+ WireFormat::SerializeWithCachedSizes(message, size, &output);
+ ASSERT_FALSE(output.HadError());
+ }
+
+ // Should parse to the same message.
+ EXPECT_TRUE(TestUtil::EqualsToSerialized(message, generated_data));
+ EXPECT_TRUE(TestUtil::EqualsToSerialized(message, dynamic_data));
+}
+
+TEST(WireFormatTest, SerializeOneof) {
+ UNITTEST::TestOneof2 message;
+ std::string generated_data;
+ std::string dynamic_data;
+
+ TestUtil::SetOneof1(&message);
+ size_t size = message.ByteSizeLong();
+
+ // Serialize using the generated code.
+ {
+ io::StringOutputStream raw_output(&generated_data);
+ io::CodedOutputStream output(&raw_output);
+ message.SerializeWithCachedSizes(&output);
+ ASSERT_FALSE(output.HadError());
+ }
+
+ // Serialize using WireFormat.
+ {
+ io::StringOutputStream raw_output(&dynamic_data);
+ io::CodedOutputStream output(&raw_output);
+ WireFormat::SerializeWithCachedSizes(message, size, &output);
+ ASSERT_FALSE(output.HadError());
+ }
+
+ // Should parse to the same message.
+ EXPECT_TRUE(TestUtil::EqualsToSerialized(message, generated_data));
+ EXPECT_TRUE(TestUtil::EqualsToSerialized(message, dynamic_data));
+}
+
+TEST(WireFormatTest, ParseMultipleExtensionRanges) {
+ // Make sure we can parse a message that contains multiple extensions ranges.
+ UNITTEST::TestFieldOrderings source;
+ std::string data;
+
+ TestUtil::SetAllFieldsAndExtensions(&source);
+ source.SerializeToString(&data);
+
+ {
+ UNITTEST::TestFieldOrderings dest;
+ EXPECT_TRUE(dest.ParseFromString(data));
+ EXPECT_EQ(source.DebugString(), dest.DebugString());
+ }
+
+ // Also test using reflection-based parsing.
+ {
+ UNITTEST::TestFieldOrderings dest;
+ io::ArrayInputStream raw_input(data.data(), data.size());
+ io::CodedInputStream coded_input(&raw_input);
+ EXPECT_TRUE(WireFormat::ParseAndMergePartial(&coded_input, &dest));
+ EXPECT_EQ(source.DebugString(), dest.DebugString());
+ }
+}
+
+const int kUnknownTypeId = 1550055;
+
+TEST(WireFormatTest, SerializeMessageSet) {
+ // Set up a TestMessageSet with two known messages and an unknown one.
+ PROTO2_WIREFORMAT_UNITTEST::TestMessageSet message_set;
+ message_set
+ .MutableExtension(
+ UNITTEST::TestMessageSetExtension1::message_set_extension)
+ ->set_i(123);
+ message_set
+ .MutableExtension(
+ UNITTEST::TestMessageSetExtension2::message_set_extension)
+ ->set_str("foo");
+ message_set.mutable_unknown_fields()->AddLengthDelimited(kUnknownTypeId,
+ "bar");
+
+ std::string data;
+ ASSERT_TRUE(message_set.SerializeToString(&data));
+
+ // Parse back using RawMessageSet and check the contents.
+ UNITTEST::RawMessageSet raw;
+ ASSERT_TRUE(raw.ParseFromString(data));
+
+ EXPECT_EQ(0, raw.unknown_fields().field_count());
+
+ ASSERT_EQ(3, raw.item_size());
+ EXPECT_EQ(
+ UNITTEST::TestMessageSetExtension1::descriptor()->extension(0)->number(),
+ raw.item(0).type_id());
+ EXPECT_EQ(
+ UNITTEST::TestMessageSetExtension2::descriptor()->extension(0)->number(),
+ raw.item(1).type_id());
+ EXPECT_EQ(kUnknownTypeId, raw.item(2).type_id());
+
+ UNITTEST::TestMessageSetExtension1 message1;
+ EXPECT_TRUE(message1.ParseFromString(raw.item(0).message()));
+ EXPECT_EQ(123, message1.i());
+
+ UNITTEST::TestMessageSetExtension2 message2;
+ EXPECT_TRUE(message2.ParseFromString(raw.item(1).message()));
+ EXPECT_EQ("foo", message2.str());
+
+ EXPECT_EQ("bar", raw.item(2).message());
+}
+
+TEST(WireFormatTest, SerializeMessageSetVariousWaysAreEqual) {
+ // Serialize a MessageSet to a stream and to a flat array using generated
+ // code, and also using WireFormat, and check that the results are equal.
+ // Set up a TestMessageSet with two known messages and an unknown one, as
+ // above.
+
+ PROTO2_WIREFORMAT_UNITTEST::TestMessageSet message_set;
+ message_set
+ .MutableExtension(
+ UNITTEST::TestMessageSetExtension1::message_set_extension)
+ ->set_i(123);
+ message_set
+ .MutableExtension(
+ UNITTEST::TestMessageSetExtension2::message_set_extension)
+ ->set_str("foo");
+ message_set.mutable_unknown_fields()->AddLengthDelimited(kUnknownTypeId,
+ "bar");
+
+ size_t size = message_set.ByteSizeLong();
+ EXPECT_EQ(size, message_set.GetCachedSize());
+ ASSERT_EQ(size, WireFormat::ByteSize(message_set));
+
+ std::string flat_data;
+ std::string stream_data;
+ std::string dynamic_data;
+ flat_data.resize(size);
+ stream_data.resize(size);
+
+ // Serialize to flat array
+ {
+ uint8* target = reinterpret_cast<uint8*>(::google::protobuf::string_as_array(&flat_data));
+ uint8* end = message_set.SerializeWithCachedSizesToArray(target);
+ EXPECT_EQ(size, end - target);
+ }
+
+ // Serialize to buffer
+ {
+ io::ArrayOutputStream array_stream(::google::protobuf::string_as_array(&stream_data), size,
+ 1);
+ io::CodedOutputStream output_stream(&array_stream);
+ message_set.SerializeWithCachedSizes(&output_stream);
+ ASSERT_FALSE(output_stream.HadError());
+ }
+
+ // Serialize to buffer with WireFormat.
+ {
+ io::StringOutputStream string_stream(&dynamic_data);
+ io::CodedOutputStream output_stream(&string_stream);
+ WireFormat::SerializeWithCachedSizes(message_set, size, &output_stream);
+ ASSERT_FALSE(output_stream.HadError());
+ }
+
+ EXPECT_TRUE(flat_data == stream_data);
+ EXPECT_TRUE(flat_data == dynamic_data);
+}
+
+TEST(WireFormatTest, ParseMessageSet) {
+ // Set up a RawMessageSet with two known messages and an unknown one.
+ UNITTEST::RawMessageSet raw;
+
+ {
+ UNITTEST::RawMessageSet::Item* item = raw.add_item();
+ item->set_type_id(UNITTEST::TestMessageSetExtension1::descriptor()
+ ->extension(0)
+ ->number());
+ UNITTEST::TestMessageSetExtension1 message;
+ message.set_i(123);
+ message.SerializeToString(item->mutable_message());
+ }
+
+ {
+ UNITTEST::RawMessageSet::Item* item = raw.add_item();
+ item->set_type_id(UNITTEST::TestMessageSetExtension2::descriptor()
+ ->extension(0)
+ ->number());
+ UNITTEST::TestMessageSetExtension2 message;
+ message.set_str("foo");
+ message.SerializeToString(item->mutable_message());
+ }
+
+ {
+ UNITTEST::RawMessageSet::Item* item = raw.add_item();
+ item->set_type_id(kUnknownTypeId);
+ item->set_message("bar");
+ }
+
+ std::string data;
+ ASSERT_TRUE(raw.SerializeToString(&data));
+
+ // Parse as a TestMessageSet and check the contents.
+ PROTO2_WIREFORMAT_UNITTEST::TestMessageSet message_set;
+ ASSERT_TRUE(message_set.ParseFromString(data));
+
+ EXPECT_EQ(123,
+ message_set
+ .GetExtension(
+ UNITTEST::TestMessageSetExtension1::message_set_extension)
+ .i());
+ EXPECT_EQ("foo",
+ message_set
+ .GetExtension(
+ UNITTEST::TestMessageSetExtension2::message_set_extension)
+ .str());
+
+ ASSERT_EQ(1, message_set.unknown_fields().field_count());
+ ASSERT_EQ(UnknownField::TYPE_LENGTH_DELIMITED,
+ message_set.unknown_fields().field(0).type());
+ EXPECT_EQ("bar", message_set.unknown_fields().field(0).length_delimited());
+
+ // Also parse using WireFormat.
+ PROTO2_WIREFORMAT_UNITTEST::TestMessageSet dynamic_message_set;
+ io::CodedInputStream input(reinterpret_cast<const uint8*>(data.data()),
+ data.size());
+ ASSERT_TRUE(WireFormat::ParseAndMergePartial(&input, &dynamic_message_set));
+ EXPECT_EQ(message_set.DebugString(), dynamic_message_set.DebugString());
+}
+
+TEST(WireFormatTest, ParseMessageSetWithReverseTagOrder) {
+ std::string data;
+ {
+ UNITTEST::TestMessageSetExtension1 message;
+ message.set_i(123);
+ // Build a MessageSet manually with its message content put before its
+ // type_id.
+ io::StringOutputStream output_stream(&data);
+ io::CodedOutputStream coded_output(&output_stream);
+ coded_output.WriteTag(WireFormatLite::kMessageSetItemStartTag);
+ // Write the message content first.
+ WireFormatLite::WriteTag(WireFormatLite::kMessageSetMessageNumber,
+ WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
+ &coded_output);
+ coded_output.WriteVarint32(message.ByteSizeLong());
+ message.SerializeWithCachedSizes(&coded_output);
+ // Write the type id.
+ uint32 type_id = message.GetDescriptor()->extension(0)->number();
+ WireFormatLite::WriteUInt32(WireFormatLite::kMessageSetTypeIdNumber,
+ type_id, &coded_output);
+ coded_output.WriteTag(WireFormatLite::kMessageSetItemEndTag);
+ }
+ {
+ PROTO2_WIREFORMAT_UNITTEST::TestMessageSet message_set;
+ ASSERT_TRUE(message_set.ParseFromString(data));
+
+ EXPECT_EQ(123,
+ message_set
+ .GetExtension(
+ UNITTEST::TestMessageSetExtension1::message_set_extension)
+ .i());
+ }
+ {
+ // Test parse the message via Reflection.
+ PROTO2_WIREFORMAT_UNITTEST::TestMessageSet message_set;
+ io::CodedInputStream input(reinterpret_cast<const uint8*>(data.data()),
+ data.size());
+ EXPECT_TRUE(WireFormat::ParseAndMergePartial(&input, &message_set));
+ EXPECT_TRUE(input.ConsumedEntireMessage());
+
+ EXPECT_EQ(123,
+ message_set
+ .GetExtension(
+ UNITTEST::TestMessageSetExtension1::message_set_extension)
+ .i());
+ }
+}
+
+void SerializeReverseOrder(
+ const PROTO2_WIREFORMAT_UNITTEST::TestMessageSet& mset,
+ io::CodedOutputStream* coded_output);
+
+void SerializeReverseOrder(const UNITTEST::TestMessageSetExtension1& message,
+ io::CodedOutputStream* coded_output) {
+ WireFormatLite::WriteTag(15, // i
+ WireFormatLite::WIRETYPE_VARINT, coded_output);
+ coded_output->WriteVarint64(message.i());
+ WireFormatLite::WriteTag(16, // recursive
+ WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
+ coded_output);
+ coded_output->WriteVarint32(message.recursive().GetCachedSize());
+ SerializeReverseOrder(message.recursive(), coded_output);
+}
+
+void SerializeReverseOrder(
+ const PROTO2_WIREFORMAT_UNITTEST::TestMessageSet& mset,
+ io::CodedOutputStream* coded_output) {
+ if (!mset.HasExtension(
+ UNITTEST::TestMessageSetExtension1::message_set_extension))
+ return;
+ coded_output->WriteTag(WireFormatLite::kMessageSetItemStartTag);
+ // Write the message content first.
+ WireFormatLite::WriteTag(WireFormatLite::kMessageSetMessageNumber,
+ WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
+ coded_output);
+ auto& message = mset.GetExtension(
+ UNITTEST::TestMessageSetExtension1::message_set_extension);
+ coded_output->WriteVarint32(message.GetCachedSize());
+ SerializeReverseOrder(message, coded_output);
+ // Write the type id.
+ uint32 type_id = message.GetDescriptor()->extension(0)->number();
+ WireFormatLite::WriteUInt32(WireFormatLite::kMessageSetTypeIdNumber, type_id,
+ coded_output);
+ coded_output->WriteTag(WireFormatLite::kMessageSetItemEndTag);
+}
+
+TEST(WireFormatTest, ParseMessageSetWithDeepRecReverseOrder) {
+ std::string data;
+ {
+ PROTO2_WIREFORMAT_UNITTEST::TestMessageSet message_set;
+ PROTO2_WIREFORMAT_UNITTEST::TestMessageSet* mset = &message_set;
+ for (int i = 0; i < 200; i++) {
+ auto m = mset->MutableExtension(
+ UNITTEST::TestMessageSetExtension1::message_set_extension);
+ m->set_i(i);
+ mset = m->mutable_recursive();
+ }
+ message_set.ByteSizeLong();
+ // Serialize with reverse payload tag order
+ io::StringOutputStream output_stream(&data);
+ io::CodedOutputStream coded_output(&output_stream);
+ SerializeReverseOrder(message_set, &coded_output);
+ }
+ PROTO2_WIREFORMAT_UNITTEST::TestMessageSet message_set;
+ EXPECT_FALSE(message_set.ParseFromString(data));
+}
+
+TEST(WireFormatTest, ParseFailMalformedMessageSet) {
+ constexpr int kDepth = 5;
+ std::string data;
+ {
+ PROTO2_WIREFORMAT_UNITTEST::TestMessageSet message_set;
+ PROTO2_WIREFORMAT_UNITTEST::TestMessageSet* mset = &message_set;
+ for (int i = 0; i < kDepth; i++) {
+ auto m = mset->MutableExtension(
+ UNITTEST::TestMessageSetExtension1::message_set_extension);
+ m->set_i(i);
+ mset = m->mutable_recursive();
+ }
+ auto m = mset->MutableExtension(
+ UNITTEST::TestMessageSetExtension1::message_set_extension);
+ // -1 becomes \xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x1
+ m->set_i(-1);
+
+ EXPECT_TRUE(message_set.SerializeToString(&data));
+ // Make the proto mal-formed.
+ data[data.size() - 2 - kDepth] = 0xFF;
+ }
+
+ PROTO2_WIREFORMAT_UNITTEST::TestMessageSet message_set;
+ EXPECT_FALSE(message_set.ParseFromString(data));
+}
+
+TEST(WireFormatTest, ParseFailMalformedMessageSetReverseOrder) {
+ constexpr int kDepth = 5;
+ std::string data;
+ {
+ PROTO2_WIREFORMAT_UNITTEST::TestMessageSet message_set;
+ PROTO2_WIREFORMAT_UNITTEST::TestMessageSet* mset = &message_set;
+ for (int i = 0; i < kDepth; i++) {
+ auto m = mset->MutableExtension(
+ UNITTEST::TestMessageSetExtension1::message_set_extension);
+ m->set_i(i);
+ mset = m->mutable_recursive();
+ }
+ auto m = mset->MutableExtension(
+ UNITTEST::TestMessageSetExtension1::message_set_extension);
+ // -1 becomes \xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x1
+ m->set_i(-1);
+ // SerializeReverseOrder() assumes "recursive" is always present.
+ m->mutable_recursive();
+
+ message_set.ByteSizeLong();
+
+ // Serialize with reverse payload tag order
+ io::StringOutputStream output_stream(&data);
+ io::CodedOutputStream coded_output(&output_stream);
+ SerializeReverseOrder(message_set, &coded_output);
+ }
+
+ // Make varint for -1 malformed.
+ data[data.size() - 5 * (kDepth + 1) - 4] = 0xFF;
+
+ PROTO2_WIREFORMAT_UNITTEST::TestMessageSet message_set;
+ EXPECT_FALSE(message_set.ParseFromString(data));
+}
+
+TEST(WireFormatTest, ParseBrokenMessageSet) {
+ PROTO2_WIREFORMAT_UNITTEST::TestMessageSet message_set;
+ std::string input("goodbye"); // Invalid wire format data.
+ EXPECT_FALSE(message_set.ParseFromString(input));
+}
+
+TEST(WireFormatTest, RecursionLimit) {
+ UNITTEST::TestRecursiveMessage message;
+ message.mutable_a()->mutable_a()->mutable_a()->mutable_a()->set_i(1);
+ std::string data;
+ message.SerializeToString(&data);
+
+ {
+ io::ArrayInputStream raw_input(data.data(), data.size());
+ io::CodedInputStream input(&raw_input);
+ input.SetRecursionLimit(4);
+ UNITTEST::TestRecursiveMessage message2;
+ EXPECT_TRUE(message2.ParseFromCodedStream(&input));
+ }
+
+ {
+ io::ArrayInputStream raw_input(data.data(), data.size());
+ io::CodedInputStream input(&raw_input);
+ input.SetRecursionLimit(3);
+ UNITTEST::TestRecursiveMessage message2;
+ EXPECT_FALSE(message2.ParseFromCodedStream(&input));
+ }
+}
+
+TEST(WireFormatTest, UnknownFieldRecursionLimit) {
+ UNITTEST::TestEmptyMessage message;
+ message.mutable_unknown_fields()
+ ->AddGroup(1234)
+ ->AddGroup(1234)
+ ->AddGroup(1234)
+ ->AddGroup(1234)
+ ->AddVarint(1234, 123);
+ std::string data;
+ message.SerializeToString(&data);
+
+ {
+ io::ArrayInputStream raw_input(data.data(), data.size());
+ io::CodedInputStream input(&raw_input);
+ input.SetRecursionLimit(4);
+ UNITTEST::TestEmptyMessage message2;
+ EXPECT_TRUE(message2.ParseFromCodedStream(&input));
+ }
+
+ {
+ io::ArrayInputStream raw_input(data.data(), data.size());
+ io::CodedInputStream input(&raw_input);
+ input.SetRecursionLimit(3);
+ UNITTEST::TestEmptyMessage message2;
+ EXPECT_FALSE(message2.ParseFromCodedStream(&input));
+ }
+}
+
+TEST(WireFormatTest, ZigZag) {
+// avoid line-wrapping
+#define LL(x) static_cast<int64_t>(ULL(x))
+#define ULL(x) uint64_t{x##u}
+#define ZigZagEncode32(x) WireFormatLite::ZigZagEncode32(x)
+#define ZigZagDecode32(x) WireFormatLite::ZigZagDecode32(x)
+#define ZigZagEncode64(x) WireFormatLite::ZigZagEncode64(x)
+#define ZigZagDecode64(x) WireFormatLite::ZigZagDecode64(x)
+
+ EXPECT_EQ(0u, ZigZagEncode32(0));
+ EXPECT_EQ(1u, ZigZagEncode32(-1));
+ EXPECT_EQ(2u, ZigZagEncode32(1));
+ EXPECT_EQ(3u, ZigZagEncode32(-2));
+ EXPECT_EQ(0x7FFFFFFEu, ZigZagEncode32(0x3FFFFFFF));
+ EXPECT_EQ(0x7FFFFFFFu, ZigZagEncode32(0xC0000000));
+ EXPECT_EQ(0xFFFFFFFEu, ZigZagEncode32(0x7FFFFFFF));
+ EXPECT_EQ(0xFFFFFFFFu, ZigZagEncode32(0x80000000));
+
+ EXPECT_EQ(0, ZigZagDecode32(0u));
+ EXPECT_EQ(-1, ZigZagDecode32(1u));
+ EXPECT_EQ(1, ZigZagDecode32(2u));
+ EXPECT_EQ(-2, ZigZagDecode32(3u));
+ EXPECT_EQ(0x3FFFFFFF, ZigZagDecode32(0x7FFFFFFEu));
+ EXPECT_EQ(0xC0000000, ZigZagDecode32(0x7FFFFFFFu));
+ EXPECT_EQ(0x7FFFFFFF, ZigZagDecode32(0xFFFFFFFEu));
+ EXPECT_EQ(0x80000000, ZigZagDecode32(0xFFFFFFFFu));
+
+ EXPECT_EQ(0u, ZigZagEncode64(0));
+ EXPECT_EQ(1u, ZigZagEncode64(-1));
+ EXPECT_EQ(2u, ZigZagEncode64(1));
+ EXPECT_EQ(3u, ZigZagEncode64(-2));
+ EXPECT_EQ(ULL(0x000000007FFFFFFE), ZigZagEncode64(LL(0x000000003FFFFFFF)));
+ EXPECT_EQ(ULL(0x000000007FFFFFFF), ZigZagEncode64(LL(0xFFFFFFFFC0000000)));
+ EXPECT_EQ(ULL(0x00000000FFFFFFFE), ZigZagEncode64(LL(0x000000007FFFFFFF)));
+ EXPECT_EQ(ULL(0x00000000FFFFFFFF), ZigZagEncode64(LL(0xFFFFFFFF80000000)));
+ EXPECT_EQ(ULL(0xFFFFFFFFFFFFFFFE), ZigZagEncode64(LL(0x7FFFFFFFFFFFFFFF)));
+ EXPECT_EQ(ULL(0xFFFFFFFFFFFFFFFF), ZigZagEncode64(LL(0x8000000000000000)));
+
+ EXPECT_EQ(0, ZigZagDecode64(0u));
+ EXPECT_EQ(-1, ZigZagDecode64(1u));
+ EXPECT_EQ(1, ZigZagDecode64(2u));
+ EXPECT_EQ(-2, ZigZagDecode64(3u));
+ EXPECT_EQ(LL(0x000000003FFFFFFF), ZigZagDecode64(ULL(0x000000007FFFFFFE)));
+ EXPECT_EQ(LL(0xFFFFFFFFC0000000), ZigZagDecode64(ULL(0x000000007FFFFFFF)));
+ EXPECT_EQ(LL(0x000000007FFFFFFF), ZigZagDecode64(ULL(0x00000000FFFFFFFE)));
+ EXPECT_EQ(LL(0xFFFFFFFF80000000), ZigZagDecode64(ULL(0x00000000FFFFFFFF)));
+ EXPECT_EQ(LL(0x7FFFFFFFFFFFFFFF), ZigZagDecode64(ULL(0xFFFFFFFFFFFFFFFE)));
+ EXPECT_EQ(LL(0x8000000000000000), ZigZagDecode64(ULL(0xFFFFFFFFFFFFFFFF)));
+
+ // Some easier-to-verify round-trip tests. The inputs (other than 0, 1, -1)
+ // were chosen semi-randomly via keyboard bashing.
+ EXPECT_EQ(0, ZigZagDecode32(ZigZagEncode32(0)));
+ EXPECT_EQ(1, ZigZagDecode32(ZigZagEncode32(1)));
+ EXPECT_EQ(-1, ZigZagDecode32(ZigZagEncode32(-1)));
+ EXPECT_EQ(14927, ZigZagDecode32(ZigZagEncode32(14927)));
+ EXPECT_EQ(-3612, ZigZagDecode32(ZigZagEncode32(-3612)));
+
+ EXPECT_EQ(0, ZigZagDecode64(ZigZagEncode64(0)));
+ EXPECT_EQ(1, ZigZagDecode64(ZigZagEncode64(1)));
+ EXPECT_EQ(-1, ZigZagDecode64(ZigZagEncode64(-1)));
+ EXPECT_EQ(14927, ZigZagDecode64(ZigZagEncode64(14927)));
+ EXPECT_EQ(-3612, ZigZagDecode64(ZigZagEncode64(-3612)));
+
+ EXPECT_EQ(LL(856912304801416),
+ ZigZagDecode64(ZigZagEncode64(LL(856912304801416))));
+ EXPECT_EQ(LL(-75123905439571256),
+ ZigZagDecode64(ZigZagEncode64(LL(-75123905439571256))));
+}
+
+TEST(WireFormatTest, RepeatedScalarsDifferentTagSizes) {
+ // At one point checks would trigger when parsing repeated fixed scalar
+ // fields.
+ UNITTEST::TestRepeatedScalarDifferentTagSizes msg1, msg2;
+ for (int i = 0; i < 100; ++i) {
+ msg1.add_repeated_fixed32(i);
+ msg1.add_repeated_int32(i);
+ msg1.add_repeated_fixed64(i);
+ msg1.add_repeated_int64(i);
+ msg1.add_repeated_float(i);
+ msg1.add_repeated_uint64(i);
+ }
+
+ // Make sure that we have a variety of tag sizes.
+ const Descriptor* desc = msg1.GetDescriptor();
+ const FieldDescriptor* field;
+ field = desc->FindFieldByName("repeated_fixed32");
+ ASSERT_TRUE(field != nullptr);
+ ASSERT_EQ(1, WireFormat::TagSize(field->number(), field->type()));
+ field = desc->FindFieldByName("repeated_int32");
+ ASSERT_TRUE(field != nullptr);
+ ASSERT_EQ(1, WireFormat::TagSize(field->number(), field->type()));
+ field = desc->FindFieldByName("repeated_fixed64");
+ ASSERT_TRUE(field != nullptr);
+ ASSERT_EQ(2, WireFormat::TagSize(field->number(), field->type()));
+ field = desc->FindFieldByName("repeated_int64");
+ ASSERT_TRUE(field != nullptr);
+ ASSERT_EQ(2, WireFormat::TagSize(field->number(), field->type()));
+ field = desc->FindFieldByName("repeated_float");
+ ASSERT_TRUE(field != nullptr);
+ ASSERT_EQ(3, WireFormat::TagSize(field->number(), field->type()));
+ field = desc->FindFieldByName("repeated_uint64");
+ ASSERT_TRUE(field != nullptr);
+ ASSERT_EQ(3, WireFormat::TagSize(field->number(), field->type()));
+
+ EXPECT_TRUE(msg2.ParseFromString(msg1.SerializeAsString()));
+ EXPECT_EQ(msg1.DebugString(), msg2.DebugString());
+}
+
+TEST(WireFormatTest, CompatibleTypes) {
+ const int64 data = 0x100000000LL;
+ UNITTEST::Int64Message msg1;
+ msg1.set_data(data);
+ std::string serialized;
+ msg1.SerializeToString(&serialized);
+
+ // Test int64 is compatible with bool
+ UNITTEST::BoolMessage msg2;
+ ASSERT_TRUE(msg2.ParseFromString(serialized));
+ ASSERT_EQ(static_cast<bool>(data), msg2.data());
+
+ // Test int64 is compatible with uint64
+ UNITTEST::Uint64Message msg3;
+ ASSERT_TRUE(msg3.ParseFromString(serialized));
+ ASSERT_EQ(static_cast<uint64>(data), msg3.data());
+
+ // Test int64 is compatible with int32
+ UNITTEST::Int32Message msg4;
+ ASSERT_TRUE(msg4.ParseFromString(serialized));
+ ASSERT_EQ(static_cast<int32>(data), msg4.data());
+
+ // Test int64 is compatible with uint32
+ UNITTEST::Uint32Message msg5;
+ ASSERT_TRUE(msg5.ParseFromString(serialized));
+ ASSERT_EQ(static_cast<uint32>(data), msg5.data());
+}
+
+class Proto3PrimitiveRepeatedWireFormatTest : public ::testing::Test {
+ protected:
+ Proto3PrimitiveRepeatedWireFormatTest()
+ : packedTestAllTypes_(
+ "\xFA\x01\x01\x01"
+ "\x82\x02\x01\x01"
+ "\x8A\x02\x01\x01"
+ "\x92\x02\x01\x01"
+ "\x9A\x02\x01\x02"
+ "\xA2\x02\x01\x02"
+ "\xAA\x02\x04\x01\x00\x00\x00"
+ "\xB2\x02\x08\x01\x00\x00\x00\x00\x00\x00\x00"
+ "\xBA\x02\x04\x01\x00\x00\x00"
+ "\xC2\x02\x08\x01\x00\x00\x00\x00\x00\x00\x00"
+ "\xCA\x02\x04\x00\x00\x80\x3f"
+ "\xD2\x02\x08\x00\x00\x00\x00\x00\x00\xf0\x3f"
+ "\xDA\x02\x01\x01"
+ "\x9A\x03\x01\x01",
+ 86),
+ packedTestUnpackedTypes_(
+ "\x0A\x01\x01"
+ "\x12\x01\x01"
+ "\x1A\x01\x01"
+ "\x22\x01\x01"
+ "\x2A\x01\x02"
+ "\x32\x01\x02"
+ "\x3A\x04\x01\x00\x00\x00"
+ "\x42\x08\x01\x00\x00\x00\x00\x00\x00\x00"
+ "\x4A\x04\x01\x00\x00\x00"
+ "\x52\x08\x01\x00\x00\x00\x00\x00\x00\x00"
+ "\x5A\x04\x00\x00\x80\x3f"
+ "\x62\x08\x00\x00\x00\x00\x00\x00\xf0\x3f"
+ "\x6A\x01\x01"
+ "\x72\x01\x01",
+ 72),
+ unpackedTestAllTypes_(
+ "\xF8\x01\x01"
+ "\x80\x02\x01"
+ "\x88\x02\x01"
+ "\x90\x02\x01"
+ "\x98\x02\x02"
+ "\xA0\x02\x02"
+ "\xAD\x02\x01\x00\x00\x00"
+ "\xB1\x02\x01\x00\x00\x00\x00\x00\x00\x00"
+ "\xBD\x02\x01\x00\x00\x00"
+ "\xC1\x02\x01\x00\x00\x00\x00\x00\x00\x00"
+ "\xCD\x02\x00\x00\x80\x3f"
+ "\xD1\x02\x00\x00\x00\x00\x00\x00\xf0\x3f"
+ "\xD8\x02\x01"
+ "\x98\x03\x01",
+ 72),
+ unpackedTestUnpackedTypes_(
+ "\x08\x01"
+ "\x10\x01"
+ "\x18\x01"
+ "\x20\x01"
+ "\x28\x02"
+ "\x30\x02"
+ "\x3D\x01\x00\x00\x00"
+ "\x41\x01\x00\x00\x00\x00\x00\x00\x00"
+ "\x4D\x01\x00\x00\x00"
+ "\x51\x01\x00\x00\x00\x00\x00\x00\x00"
+ "\x5D\x00\x00\x80\x3f"
+ "\x61\x00\x00\x00\x00\x00\x00\xf0\x3f"
+ "\x68\x01"
+ "\x70\x01",
+ 58) {}
+ template <class Proto>
+ void SetProto3PrimitiveRepeatedFields(Proto* message) {
+ message->add_repeated_int32(1);
+ message->add_repeated_int64(1);
+ message->add_repeated_uint32(1);
+ message->add_repeated_uint64(1);
+ message->add_repeated_sint32(1);
+ message->add_repeated_sint64(1);
+ message->add_repeated_fixed32(1);
+ message->add_repeated_fixed64(1);
+ message->add_repeated_sfixed32(1);
+ message->add_repeated_sfixed64(1);
+ message->add_repeated_float(1.0);
+ message->add_repeated_double(1.0);
+ message->add_repeated_bool(true);
+ message->add_repeated_nested_enum(PROTO3_ARENA_UNITTEST::TestAllTypes::FOO);
+ }
+
+ template <class Proto>
+ void ExpectProto3PrimitiveRepeatedFieldsSet(const Proto& message) {
+ EXPECT_EQ(1, message.repeated_int32(0));
+ EXPECT_EQ(1, message.repeated_int64(0));
+ EXPECT_EQ(1, message.repeated_uint32(0));
+ EXPECT_EQ(1, message.repeated_uint64(0));
+ EXPECT_EQ(1, message.repeated_sint32(0));
+ EXPECT_EQ(1, message.repeated_sint64(0));
+ EXPECT_EQ(1, message.repeated_fixed32(0));
+ EXPECT_EQ(1, message.repeated_fixed64(0));
+ EXPECT_EQ(1, message.repeated_sfixed32(0));
+ EXPECT_EQ(1, message.repeated_sfixed64(0));
+ EXPECT_EQ(1.0, message.repeated_float(0));
+ EXPECT_EQ(1.0, message.repeated_double(0));
+ EXPECT_EQ(true, message.repeated_bool(0));
+ EXPECT_EQ(PROTO3_ARENA_UNITTEST::TestAllTypes::FOO,
+ message.repeated_nested_enum(0));
+ }
+
+ template <class Proto>
+ void TestSerialization(Proto* message, const std::string& expected) {
+ SetProto3PrimitiveRepeatedFields(message);
+
+ size_t size = message->ByteSizeLong();
+
+ // Serialize using the generated code.
+ std::string generated_data;
+ {
+ io::StringOutputStream raw_output(&generated_data);
+ io::CodedOutputStream output(&raw_output);
+ message->SerializeWithCachedSizes(&output);
+ ASSERT_FALSE(output.HadError());
+ }
+ EXPECT_TRUE(TestUtil::EqualsToSerialized(*message, generated_data));
+
+ // Serialize using the dynamic code.
+ std::string dynamic_data;
+ {
+ io::StringOutputStream raw_output(&dynamic_data);
+ io::CodedOutputStream output(&raw_output);
+ WireFormat::SerializeWithCachedSizes(*message, size, &output);
+ ASSERT_FALSE(output.HadError());
+ }
+ EXPECT_TRUE(expected == dynamic_data);
+ }
+
+ template <class Proto>
+ void TestParsing(Proto* message, const std::string& compatible_data) {
+ message->Clear();
+ message->ParseFromString(compatible_data);
+ ExpectProto3PrimitiveRepeatedFieldsSet(*message);
+
+ message->Clear();
+ io::CodedInputStream input(
+ reinterpret_cast<const uint8*>(compatible_data.data()),
+ compatible_data.size());
+ WireFormat::ParseAndMergePartial(&input, message);
+ ExpectProto3PrimitiveRepeatedFieldsSet(*message);
+ }
+
+ const std::string packedTestAllTypes_;
+ const std::string packedTestUnpackedTypes_;
+ const std::string unpackedTestAllTypes_;
+ const std::string unpackedTestUnpackedTypes_;
+};
+
+TEST_F(Proto3PrimitiveRepeatedWireFormatTest, Proto3PrimitiveRepeated) {
+ PROTO3_ARENA_UNITTEST::TestAllTypes packed_message;
+ PROTO3_ARENA_UNITTEST::TestUnpackedTypes unpacked_message;
+ TestSerialization(&packed_message, packedTestAllTypes_);
+ TestParsing(&packed_message, packedTestAllTypes_);
+ TestParsing(&packed_message, unpackedTestAllTypes_);
+ TestSerialization(&unpacked_message, unpackedTestUnpackedTypes_);
+ TestParsing(&unpacked_message, packedTestUnpackedTypes_);
+ TestParsing(&unpacked_message, unpackedTestUnpackedTypes_);
+}
+
+class WireFormatInvalidInputTest : public testing::Test {
+ protected:
+ // Make a serialized TestAllTypes in which the field optional_nested_message
+ // contains exactly the given bytes, which may be invalid.
+ std::string MakeInvalidEmbeddedMessage(const char* bytes, int size) {
+ const FieldDescriptor* field =
+ UNITTEST::TestAllTypes::descriptor()->FindFieldByName(
+ "optional_nested_message");
+ GOOGLE_CHECK(field != nullptr);
+
+ std::string result;
+
+ {
+ io::StringOutputStream raw_output(&result);
+ io::CodedOutputStream output(&raw_output);
+
+ WireFormatLite::WriteBytes(field->number(), std::string(bytes, size),
+ &output);
+ }
+
+ return result;
+ }
+
+ // Make a serialized TestAllTypes in which the field optionalgroup
+ // contains exactly the given bytes -- which may be invalid -- and
+ // possibly no end tag.
+ std::string MakeInvalidGroup(const char* bytes, int size,
+ bool include_end_tag) {
+ const FieldDescriptor* field =
+ UNITTEST::TestAllTypes::descriptor()->FindFieldByName("optionalgroup");
+ GOOGLE_CHECK(field != nullptr);
+
+ std::string result;
+
+ {
+ io::StringOutputStream raw_output(&result);
+ io::CodedOutputStream output(&raw_output);
+
+ output.WriteVarint32(WireFormat::MakeTag(field));
+ output.WriteString(std::string(bytes, size));
+ if (include_end_tag) {
+ output.WriteVarint32(WireFormatLite::MakeTag(
+ field->number(), WireFormatLite::WIRETYPE_END_GROUP));
+ }
+ }
+
+ return result;
+ }
+};
+
+TEST_F(WireFormatInvalidInputTest, InvalidSubMessage) {
+ UNITTEST::TestAllTypes message;
+
+ // Control case.
+ EXPECT_TRUE(message.ParseFromString(MakeInvalidEmbeddedMessage("", 0)));
+
+ // The byte is a valid varint, but not a valid tag (zero).
+ EXPECT_FALSE(message.ParseFromString(MakeInvalidEmbeddedMessage("\0", 1)));
+
+ // The byte is a malformed varint.
+ EXPECT_FALSE(message.ParseFromString(MakeInvalidEmbeddedMessage("\200", 1)));
+
+ // The byte is an endgroup tag, but we aren't parsing a group.
+ EXPECT_FALSE(message.ParseFromString(MakeInvalidEmbeddedMessage("\014", 1)));
+
+ // The byte is a valid varint but not a valid tag (bad wire type).
+ EXPECT_FALSE(message.ParseFromString(MakeInvalidEmbeddedMessage("\017", 1)));
+}
+
+TEST_F(WireFormatInvalidInputTest, InvalidMessageWithExtraZero) {
+ std::string data;
+ {
+ // Serialize a valid proto
+ UNITTEST::TestAllTypes message;
+ message.set_optional_int32(1);
+ message.SerializeToString(&data);
+ data.push_back(0); // Append invalid zero tag
+ }
+
+ // Control case.
+ {
+ io::ArrayInputStream ais(data.data(), data.size());
+ io::CodedInputStream is(&ais);
+ UNITTEST::TestAllTypes message;
+ // It should fail but currently passes.
+ EXPECT_TRUE(message.MergePartialFromCodedStream(&is));
+ // Parsing from the string should fail.
+ EXPECT_FALSE(message.ParseFromString(data));
+ }
+}
+
+TEST_F(WireFormatInvalidInputTest, InvalidGroup) {
+ UNITTEST::TestAllTypes message;
+
+ // Control case.
+ EXPECT_TRUE(message.ParseFromString(MakeInvalidGroup("", 0, true)));
+
+ // Missing end tag. Groups cannot end at EOF.
+ EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("", 0, false)));
+
+ // The byte is a valid varint, but not a valid tag (zero).
+ EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("\0", 1, false)));
+
+ // The byte is a malformed varint.
+ EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("\200", 1, false)));
+
+ // The byte is an endgroup tag, but not the right one for this group.
+ EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("\014", 1, false)));
+
+ // The byte is a valid varint but not a valid tag (bad wire type).
+ EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("\017", 1, true)));
+}
+
+TEST_F(WireFormatInvalidInputTest, InvalidUnknownGroup) {
+ // Use TestEmptyMessage so that the group made by MakeInvalidGroup will not
+ // be a known tag number.
+ UNITTEST::TestEmptyMessage message;
+
+ // Control case.
+ EXPECT_TRUE(message.ParseFromString(MakeInvalidGroup("", 0, true)));
+
+ // Missing end tag. Groups cannot end at EOF.
+ EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("", 0, false)));
+
+ // The byte is a valid varint, but not a valid tag (zero).
+ EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("\0", 1, false)));
+
+ // The byte is a malformed varint.
+ EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("\200", 1, false)));
+
+ // The byte is an endgroup tag, but not the right one for this group.
+ EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("\014", 1, false)));
+
+ // The byte is a valid varint but not a valid tag (bad wire type).
+ EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("\017", 1, true)));
+}
+
+TEST_F(WireFormatInvalidInputTest, InvalidStringInUnknownGroup) {
+ // Test a bug fix: SkipMessage should fail if the message contains a
+ // string whose length would extend beyond the message end.
+
+ UNITTEST::TestAllTypes message;
+ message.set_optional_string("foo foo foo foo");
+ std::string data;
+ message.SerializeToString(&data);
+
+ // Chop some bytes off the end.
+ data.resize(data.size() - 4);
+
+ // Try to skip it. Note that the bug was only present when parsing to an
+ // UnknownFieldSet.
+ io::ArrayInputStream raw_input(data.data(), data.size());
+ io::CodedInputStream coded_input(&raw_input);
+ UnknownFieldSet unknown_fields;
+ EXPECT_FALSE(WireFormat::SkipMessage(&coded_input, &unknown_fields));
+}
+
+// Test differences between string and bytes.
+// Value of a string type must be valid UTF-8 string. When UTF-8
+// validation is enabled (GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED):
+// WriteInvalidUTF8String: see error message.
+// ReadInvalidUTF8String: see error message.
+// WriteValidUTF8String: fine.
+// ReadValidUTF8String: fine.
+// WriteAnyBytes: fine.
+// ReadAnyBytes: fine.
+const char* kInvalidUTF8String = "Invalid UTF-8: \xA0\xB0\xC0\xD0";
+// This used to be "Valid UTF-8: \x01\x02\u8C37\u6B4C", but MSVC seems to
+// interpret \u differently from GCC.
+const char* kValidUTF8String = "Valid UTF-8: \x01\x02\350\260\267\346\255\214";
+
+template <typename T>
+bool WriteMessage(const char* value, T* message, std::string* wire_buffer) {
+ message->set_data(value);
+ wire_buffer->clear();
+ message->AppendToString(wire_buffer);
+ return (wire_buffer->size() > 0);
+}
+
+template <typename T>
+bool ReadMessage(const std::string& wire_buffer, T* message) {
+ return message->ParseFromArray(wire_buffer.data(), wire_buffer.size());
+}
+
+class Utf8ValidationTest : public ::testing::Test {
+ protected:
+ Utf8ValidationTest() {}
+ virtual ~Utf8ValidationTest() {}
+ virtual void SetUp() {
+ }
+
+};
+
+TEST_F(Utf8ValidationTest, WriteInvalidUTF8String) {
+ std::string wire_buffer;
+ UNITTEST::OneString input;
+ std::vector<std::string> errors;
+ {
+ ScopedMemoryLog log;
+ WriteMessage(kInvalidUTF8String, &input, &wire_buffer);
+ errors = log.GetMessages(ERROR);
+ }
+#ifdef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
+ EXPECT_THAT(errors,
+ testing::ElementsAre(
+ "String field '" + std::string(UNITTEST_PACKAGE_NAME) +
+ ".OneString.data' "
+ "contains invalid UTF-8 data when "
+ "serializing a protocol buffer. Use the "
+ "'bytes' type if you intend to send raw bytes. "));
+#else
+ ASSERT_EQ(0, errors.size());
+#endif // GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
+}
+
+
+TEST_F(Utf8ValidationTest, ReadInvalidUTF8String) {
+ std::string wire_buffer;
+ UNITTEST::OneString input;
+ WriteMessage(kInvalidUTF8String, &input, &wire_buffer);
+ UNITTEST::OneString output;
+ std::vector<std::string> errors;
+ {
+ ScopedMemoryLog log;
+ ReadMessage(wire_buffer, &output);
+ errors = log.GetMessages(ERROR);
+ }
+#ifdef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
+ EXPECT_THAT(errors,
+ testing::ElementsAre(
+ "String field '" + std::string(UNITTEST_PACKAGE_NAME) +
+ ".OneString.data' "
+ "contains invalid UTF-8 data when "
+ "parsing a protocol buffer. Use the "
+ "'bytes' type if you intend to send raw bytes. "));
+
+#else
+ ASSERT_EQ(0, errors.size());
+#endif // GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
+}
+
+
+TEST_F(Utf8ValidationTest, WriteValidUTF8String) {
+ std::string wire_buffer;
+ UNITTEST::OneString input;
+ std::vector<std::string> errors;
+ {
+ ScopedMemoryLog log;
+ WriteMessage(kValidUTF8String, &input, &wire_buffer);
+ errors = log.GetMessages(ERROR);
+ }
+ ASSERT_EQ(0, errors.size());
+}
+
+TEST_F(Utf8ValidationTest, ReadValidUTF8String) {
+ std::string wire_buffer;
+ UNITTEST::OneString input;
+ WriteMessage(kValidUTF8String, &input, &wire_buffer);
+ UNITTEST::OneString output;
+ std::vector<std::string> errors;
+ {
+ ScopedMemoryLog log;
+ ReadMessage(wire_buffer, &output);
+ errors = log.GetMessages(ERROR);
+ }
+ ASSERT_EQ(0, errors.size());
+ EXPECT_EQ(input.data(), output.data());
+}
+
+// Bytes: anything can pass as bytes, use invalid UTF-8 string to test
+TEST_F(Utf8ValidationTest, WriteArbitraryBytes) {
+ std::string wire_buffer;
+ UNITTEST::OneBytes input;
+ std::vector<std::string> errors;
+ {
+ ScopedMemoryLog log;
+ WriteMessage(kInvalidUTF8String, &input, &wire_buffer);
+ errors = log.GetMessages(ERROR);
+ }
+ ASSERT_EQ(0, errors.size());
+}
+
+TEST_F(Utf8ValidationTest, ReadArbitraryBytes) {
+ std::string wire_buffer;
+ UNITTEST::OneBytes input;
+ WriteMessage(kInvalidUTF8String, &input, &wire_buffer);
+ UNITTEST::OneBytes output;
+ std::vector<std::string> errors;
+ {
+ ScopedMemoryLog log;
+ ReadMessage(wire_buffer, &output);
+ errors = log.GetMessages(ERROR);
+ }
+ ASSERT_EQ(0, errors.size());
+ EXPECT_EQ(input.data(), output.data());
+}
+
+TEST_F(Utf8ValidationTest, ParseRepeatedString) {
+ UNITTEST::MoreBytes input;
+ input.add_data(kValidUTF8String);
+ input.add_data(kInvalidUTF8String);
+ input.add_data(kInvalidUTF8String);
+ std::string wire_buffer = input.SerializeAsString();
+
+ UNITTEST::MoreString output;
+ std::vector<std::string> errors;
+ {
+ ScopedMemoryLog log;
+ ReadMessage(wire_buffer, &output);
+ errors = log.GetMessages(ERROR);
+ }
+#ifdef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
+ ASSERT_EQ(2, errors.size());
+#else
+ ASSERT_EQ(0, errors.size());
+#endif // GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
+ EXPECT_EQ(wire_buffer, output.SerializeAsString());
+}
+
+// Test the old VerifyUTF8String() function, which may still be called by old
+// generated code.
+TEST_F(Utf8ValidationTest, OldVerifyUTF8String) {
+ std::string data(kInvalidUTF8String);
+
+ std::vector<std::string> errors;
+ {
+ ScopedMemoryLog log;
+ WireFormat::VerifyUTF8String(data.data(), data.size(),
+ WireFormat::SERIALIZE);
+ errors = log.GetMessages(ERROR);
+ }
+#ifdef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
+ ASSERT_EQ(1, errors.size());
+ EXPECT_TRUE(
+ HasPrefixString(errors[0],
+ "String field contains invalid UTF-8 data when "
+ "serializing a protocol buffer. Use the "
+ "'bytes' type if you intend to send raw bytes."));
+#else
+ ASSERT_EQ(0, errors.size());
+#endif
+}
+
+
+TEST(RepeatedVarint, Int32) {
+ RepeatedField<int32> v;
+
+ // Insert -2^n, 2^n and 2^n-1.
+ for (int n = 0; n < 10; n++) {
+ v.Add(-(1 << n));
+ v.Add(1 << n);
+ v.Add((1 << n) - 1);
+ }
+
+ // Check consistency with the scalar Int32Size.
+ size_t expected = 0;
+ for (int i = 0; i < v.size(); i++) {
+ expected += WireFormatLite::Int32Size(v[i]);
+ }
+
+ EXPECT_EQ(expected, WireFormatLite::Int32Size(v));
+}
+
+TEST(RepeatedVarint, Int64) {
+ RepeatedField<int64> v;
+
+ // Insert -2^n, 2^n and 2^n-1.
+ for (int n = 0; n < 10; n++) {
+ v.Add(-(1 << n));
+ v.Add(1 << n);
+ v.Add((1 << n) - 1);
+ }
+
+ // Check consistency with the scalar Int64Size.
+ size_t expected = 0;
+ for (int i = 0; i < v.size(); i++) {
+ expected += WireFormatLite::Int64Size(v[i]);
+ }
+
+ EXPECT_EQ(expected, WireFormatLite::Int64Size(v));
+}
+
+TEST(RepeatedVarint, SInt32) {
+ RepeatedField<int32> v;
+
+ // Insert -2^n, 2^n and 2^n-1.
+ for (int n = 0; n < 10; n++) {
+ v.Add(-(1 << n));
+ v.Add(1 << n);
+ v.Add((1 << n) - 1);
+ }
+
+ // Check consistency with the scalar SInt32Size.
+ size_t expected = 0;
+ for (int i = 0; i < v.size(); i++) {
+ expected += WireFormatLite::SInt32Size(v[i]);
+ }
+
+ EXPECT_EQ(expected, WireFormatLite::SInt32Size(v));
+}
+
+TEST(RepeatedVarint, SInt64) {
+ RepeatedField<int64> v;
+
+ // Insert -2^n, 2^n and 2^n-1.
+ for (int n = 0; n < 10; n++) {
+ v.Add(-(1 << n));
+ v.Add(1 << n);
+ v.Add((1 << n) - 1);
+ }
+
+ // Check consistency with the scalar SInt64Size.
+ size_t expected = 0;
+ for (int i = 0; i < v.size(); i++) {
+ expected += WireFormatLite::SInt64Size(v[i]);
+ }
+
+ EXPECT_EQ(expected, WireFormatLite::SInt64Size(v));
+}
+
+TEST(RepeatedVarint, UInt32) {
+ RepeatedField<uint32> v;
+
+ // Insert 2^n and 2^n-1.
+ for (int n = 0; n < 10; n++) {
+ v.Add(1 << n);
+ v.Add((1 << n) - 1);
+ }
+
+ // Check consistency with the scalar UInt32Size.
+ size_t expected = 0;
+ for (int i = 0; i < v.size(); i++) {
+ expected += WireFormatLite::UInt32Size(v[i]);
+ }
+
+ EXPECT_EQ(expected, WireFormatLite::UInt32Size(v));
+}
+
+TEST(RepeatedVarint, UInt64) {
+ RepeatedField<uint64> v;
+
+ // Insert 2^n and 2^n-1.
+ for (int n = 0; n < 10; n++) {
+ v.Add(1 << n);
+ v.Add((1 << n) - 1);
+ }
+
+ // Check consistency with the scalar UInt64Size.
+ size_t expected = 0;
+ for (int i = 0; i < v.size(); i++) {
+ expected += WireFormatLite::UInt64Size(v[i]);
+ }
+
+ EXPECT_EQ(expected, WireFormatLite::UInt64Size(v));
+}
+
+TEST(RepeatedVarint, Enum) {
+ RepeatedField<int> v;
+
+ // Insert 2^n and 2^n-1.
+ for (int n = 0; n < 10; n++) {
+ v.Add(1 << n);
+ v.Add((1 << n) - 1);
+ }
+
+ // Check consistency with the scalar EnumSize.
+ size_t expected = 0;
+ for (int i = 0; i < v.size(); i++) {
+ expected += WireFormatLite::EnumSize(v[i]);
+ }
+
+ EXPECT_EQ(expected, WireFormatLite::EnumSize(v));
+}
+
+
+} // namespace
+} // namespace internal
+} // namespace protobuf
+} // namespace google
+
+#include <port_undef.inc>
diff --git a/NorthstarDedicatedTest/include/protobuf/wrappers.pb.cc b/NorthstarDedicatedTest/include/protobuf/wrappers.pb.cc
new file mode 100644
index 00000000..3954c939
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/wrappers.pb.cc
@@ -0,0 +1,1955 @@
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+// source: google/protobuf/wrappers.proto
+
+#include <wrappers.pb.h>
+
+#include <algorithm>
+
+#include <io/coded_stream.h>
+#include <extension_set.h>
+#include <wire_format_lite.h>
+#include <descriptor.h>
+#include <generated_message_reflection.h>
+#include <reflection_ops.h>
+#include <wire_format.h>
+// @@protoc_insertion_point(includes)
+#include <port_def.inc>
+
+PROTOBUF_PRAGMA_INIT_SEG
+PROTOBUF_NAMESPACE_OPEN
+constexpr DoubleValue::DoubleValue(
+ ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized)
+ : value_(0){}
+struct DoubleValueDefaultTypeInternal {
+ constexpr DoubleValueDefaultTypeInternal()
+ : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {}
+ ~DoubleValueDefaultTypeInternal() {}
+ union {
+ DoubleValue _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT DoubleValueDefaultTypeInternal _DoubleValue_default_instance_;
+constexpr FloatValue::FloatValue(
+ ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized)
+ : value_(0){}
+struct FloatValueDefaultTypeInternal {
+ constexpr FloatValueDefaultTypeInternal()
+ : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {}
+ ~FloatValueDefaultTypeInternal() {}
+ union {
+ FloatValue _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT FloatValueDefaultTypeInternal _FloatValue_default_instance_;
+constexpr Int64Value::Int64Value(
+ ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized)
+ : value_(int64_t{0}){}
+struct Int64ValueDefaultTypeInternal {
+ constexpr Int64ValueDefaultTypeInternal()
+ : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {}
+ ~Int64ValueDefaultTypeInternal() {}
+ union {
+ Int64Value _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT Int64ValueDefaultTypeInternal _Int64Value_default_instance_;
+constexpr UInt64Value::UInt64Value(
+ ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized)
+ : value_(uint64_t{0u}){}
+struct UInt64ValueDefaultTypeInternal {
+ constexpr UInt64ValueDefaultTypeInternal()
+ : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {}
+ ~UInt64ValueDefaultTypeInternal() {}
+ union {
+ UInt64Value _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT UInt64ValueDefaultTypeInternal _UInt64Value_default_instance_;
+constexpr Int32Value::Int32Value(
+ ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized)
+ : value_(0){}
+struct Int32ValueDefaultTypeInternal {
+ constexpr Int32ValueDefaultTypeInternal()
+ : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {}
+ ~Int32ValueDefaultTypeInternal() {}
+ union {
+ Int32Value _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT Int32ValueDefaultTypeInternal _Int32Value_default_instance_;
+constexpr UInt32Value::UInt32Value(
+ ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized)
+ : value_(0u){}
+struct UInt32ValueDefaultTypeInternal {
+ constexpr UInt32ValueDefaultTypeInternal()
+ : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {}
+ ~UInt32ValueDefaultTypeInternal() {}
+ union {
+ UInt32Value _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT UInt32ValueDefaultTypeInternal _UInt32Value_default_instance_;
+constexpr BoolValue::BoolValue(
+ ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized)
+ : value_(false){}
+struct BoolValueDefaultTypeInternal {
+ constexpr BoolValueDefaultTypeInternal()
+ : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {}
+ ~BoolValueDefaultTypeInternal() {}
+ union {
+ BoolValue _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT BoolValueDefaultTypeInternal _BoolValue_default_instance_;
+constexpr StringValue::StringValue(
+ ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized)
+ : value_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string){}
+struct StringValueDefaultTypeInternal {
+ constexpr StringValueDefaultTypeInternal()
+ : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {}
+ ~StringValueDefaultTypeInternal() {}
+ union {
+ StringValue _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT StringValueDefaultTypeInternal _StringValue_default_instance_;
+constexpr BytesValue::BytesValue(
+ ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized)
+ : value_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string){}
+struct BytesValueDefaultTypeInternal {
+ constexpr BytesValueDefaultTypeInternal()
+ : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {}
+ ~BytesValueDefaultTypeInternal() {}
+ union {
+ BytesValue _instance;
+ };
+};
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT BytesValueDefaultTypeInternal _BytesValue_default_instance_;
+PROTOBUF_NAMESPACE_CLOSE
+static ::PROTOBUF_NAMESPACE_ID::Metadata file_level_metadata_google_2fprotobuf_2fwrappers_2eproto[9];
+static constexpr ::PROTOBUF_NAMESPACE_ID::EnumDescriptor const** file_level_enum_descriptors_google_2fprotobuf_2fwrappers_2eproto = nullptr;
+static constexpr ::PROTOBUF_NAMESPACE_ID::ServiceDescriptor const** file_level_service_descriptors_google_2fprotobuf_2fwrappers_2eproto = nullptr;
+
+const 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, value_),
+ ~0u, // no _has_bits_
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FloatValue, _internal_metadata_),
+ ~0u, // no _extensions_
+ ~0u, // no _oneof_case_
+ ~0u, // no _weak_field_map_
+ ~0u, // no _inlined_string_donated_
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FloatValue, value_),
+ ~0u, // no _has_bits_
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Int64Value, _internal_metadata_),
+ ~0u, // no _extensions_
+ ~0u, // no _oneof_case_
+ ~0u, // no _weak_field_map_
+ ~0u, // no _inlined_string_donated_
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Int64Value, value_),
+ ~0u, // no _has_bits_
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::UInt64Value, _internal_metadata_),
+ ~0u, // no _extensions_
+ ~0u, // no _oneof_case_
+ ~0u, // no _weak_field_map_
+ ~0u, // no _inlined_string_donated_
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::UInt64Value, value_),
+ ~0u, // no _has_bits_
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Int32Value, _internal_metadata_),
+ ~0u, // no _extensions_
+ ~0u, // no _oneof_case_
+ ~0u, // no _weak_field_map_
+ ~0u, // no _inlined_string_donated_
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Int32Value, value_),
+ ~0u, // no _has_bits_
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::UInt32Value, _internal_metadata_),
+ ~0u, // no _extensions_
+ ~0u, // no _oneof_case_
+ ~0u, // no _weak_field_map_
+ ~0u, // no _inlined_string_donated_
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::UInt32Value, value_),
+ ~0u, // no _has_bits_
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::BoolValue, _internal_metadata_),
+ ~0u, // no _extensions_
+ ~0u, // no _oneof_case_
+ ~0u, // no _weak_field_map_
+ ~0u, // no _inlined_string_donated_
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::BoolValue, value_),
+ ~0u, // no _has_bits_
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::StringValue, _internal_metadata_),
+ ~0u, // no _extensions_
+ ~0u, // no _oneof_case_
+ ~0u, // no _weak_field_map_
+ ~0u, // no _inlined_string_donated_
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::StringValue, value_),
+ ~0u, // no _has_bits_
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::BytesValue, _internal_metadata_),
+ ~0u, // no _extensions_
+ ~0u, // no _oneof_case_
+ ~0u, // no _weak_field_map_
+ ~0u, // no _inlined_string_donated_
+ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::BytesValue, value_),
+};
+static const ::PROTOBUF_NAMESPACE_ID::internal::MigrationSchema schemas[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = {
+ { 0, -1, -1, sizeof(::PROTOBUF_NAMESPACE_ID::DoubleValue)},
+ { 7, -1, -1, sizeof(::PROTOBUF_NAMESPACE_ID::FloatValue)},
+ { 14, -1, -1, sizeof(::PROTOBUF_NAMESPACE_ID::Int64Value)},
+ { 21, -1, -1, sizeof(::PROTOBUF_NAMESPACE_ID::UInt64Value)},
+ { 28, -1, -1, sizeof(::PROTOBUF_NAMESPACE_ID::Int32Value)},
+ { 35, -1, -1, sizeof(::PROTOBUF_NAMESPACE_ID::UInt32Value)},
+ { 42, -1, -1, sizeof(::PROTOBUF_NAMESPACE_ID::BoolValue)},
+ { 49, -1, -1, sizeof(::PROTOBUF_NAMESPACE_ID::StringValue)},
+ { 56, -1, -1, sizeof(::PROTOBUF_NAMESPACE_ID::BytesValue)},
+};
+
+static ::PROTOBUF_NAMESPACE_ID::Message const * const file_default_instances[] = {
+ reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_DoubleValue_default_instance_),
+ reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_FloatValue_default_instance_),
+ reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_Int64Value_default_instance_),
+ reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_UInt64Value_default_instance_),
+ reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_Int32Value_default_instance_),
+ reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_UInt32Value_default_instance_),
+ reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_BoolValue_default_instance_),
+ reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_StringValue_default_instance_),
+ reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::_BytesValue_default_instance_),
+};
+
+const char descriptor_table_protodef_google_2fprotobuf_2fwrappers_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) =
+ "\n\036google/protobuf/wrappers.proto\022\017google"
+ ".protobuf\"\034\n\013DoubleValue\022\r\n\005value\030\001 \001(\001\""
+ "\033\n\nFloatValue\022\r\n\005value\030\001 \001(\002\"\033\n\nInt64Val"
+ "ue\022\r\n\005value\030\001 \001(\003\"\034\n\013UInt64Value\022\r\n\005valu"
+ "e\030\001 \001(\004\"\033\n\nInt32Value\022\r\n\005value\030\001 \001(\005\"\034\n\013"
+ "UInt32Value\022\r\n\005value\030\001 \001(\r\"\032\n\tBoolValue\022"
+ "\r\n\005value\030\001 \001(\010\"\034\n\013StringValue\022\r\n\005value\030\001"
+ " \001(\t\"\033\n\nBytesValue\022\r\n\005value\030\001 \001(\014B\203\001\n\023co"
+ "m.google.protobufB\rWrappersProtoP\001Z1goog"
+ "le.golang.org/protobuf/types/known/wrapp"
+ "erspb\370\001\001\242\002\003GPB\252\002\036Google.Protobuf.WellKno"
+ "wnTypesb\006proto3"
+ ;
+static ::PROTOBUF_NAMESPACE_ID::internal::once_flag descriptor_table_google_2fprotobuf_2fwrappers_2eproto_once;
+const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fwrappers_2eproto = {
+ false, false, 455, descriptor_table_protodef_google_2fprotobuf_2fwrappers_2eproto, "google/protobuf/wrappers.proto",
+ &descriptor_table_google_2fprotobuf_2fwrappers_2eproto_once, nullptr, 0, 9,
+ schemas, file_default_instances, TableStruct_google_2fprotobuf_2fwrappers_2eproto::offsets,
+ file_level_metadata_google_2fprotobuf_2fwrappers_2eproto, file_level_enum_descriptors_google_2fprotobuf_2fwrappers_2eproto, file_level_service_descriptors_google_2fprotobuf_2fwrappers_2eproto,
+};
+PROTOBUF_ATTRIBUTE_WEAK const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable* descriptor_table_google_2fprotobuf_2fwrappers_2eproto_getter() {
+ return &descriptor_table_google_2fprotobuf_2fwrappers_2eproto;
+}
+
+// Force running AddDescriptors() at dynamic initialization time.
+PROTOBUF_ATTRIBUTE_INIT_PRIORITY static ::PROTOBUF_NAMESPACE_ID::internal::AddDescriptorsRunner dynamic_init_dummy_google_2fprotobuf_2fwrappers_2eproto(&descriptor_table_google_2fprotobuf_2fwrappers_2eproto);
+PROTOBUF_NAMESPACE_OPEN
+
+// ===================================================================
+
+class DoubleValue::_Internal {
+ public:
+};
+
+DoubleValue::DoubleValue(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned)
+ : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) {
+ SharedCtor();
+ if (!is_message_owned) {
+ RegisterArenaDtor(arena);
+ }
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.DoubleValue)
+}
+DoubleValue::DoubleValue(const DoubleValue& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message() {
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ value_ = from.value_;
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.DoubleValue)
+}
+
+inline void DoubleValue::SharedCtor() {
+value_ = 0;
+}
+
+DoubleValue::~DoubleValue() {
+ // @@protoc_insertion_point(destructor:google.protobuf.DoubleValue)
+ if (GetArenaForAllocation() != nullptr) return;
+ SharedDtor();
+ _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+inline void DoubleValue::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+}
+
+void DoubleValue::ArenaDtor(void* object) {
+ DoubleValue* _this = reinterpret_cast< DoubleValue* >(object);
+ (void)_this;
+}
+void DoubleValue::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) {
+}
+void DoubleValue::SetCachedSize(int size) const {
+ _cached_size_.Set(size);
+}
+
+void DoubleValue::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.DoubleValue)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ value_ = 0;
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* DoubleValue::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag);
+ switch (tag >> 3) {
+ // double value = 1;
+ case 1:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 9)) {
+ value_ = ::PROTOBUF_NAMESPACE_ID::internal::UnalignedLoad<double>(ptr);
+ ptr += sizeof(double);
+ } else
+ goto handle_unusual;
+ continue;
+ default:
+ goto handle_unusual;
+ } // switch
+ handle_unusual:
+ if ((tag == 0) || ((tag & 7) == 4)) {
+ CHK_(ptr);
+ ctx->SetLastTag(tag);
+ goto message_done;
+ }
+ ptr = UnknownFieldParse(
+ tag,
+ _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(),
+ ptr, ctx);
+ CHK_(ptr != nullptr);
+ } // while
+message_done:
+ return ptr;
+failure:
+ ptr = nullptr;
+ goto message_done;
+#undef CHK_
+}
+
+uint8_t* DoubleValue::_InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const {
+ // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.DoubleValue)
+ 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 = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteDoubleToArray(1, this->_internal_value(), target);
+ }
+
+ if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray(
+ _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.DoubleValue)
+ return target;
+}
+
+size_t DoubleValue::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.DoubleValue)
+ size_t total_size = 0;
+
+ 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, &_cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData DoubleValue::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck,
+ DoubleValue::MergeImpl
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*DoubleValue::GetClassData() const { return &_class_data_; }
+
+void DoubleValue::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to,
+ const ::PROTOBUF_NAMESPACE_ID::Message& from) {
+ static_cast<DoubleValue *>(to)->MergeFrom(
+ static_cast<const DoubleValue &>(from));
+}
+
+
+void DoubleValue::MergeFrom(const DoubleValue& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.DoubleValue)
+ GOOGLE_DCHECK_NE(&from, this);
+ 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) {
+ _internal_set_value(from._internal_value());
+ }
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+}
+
+void DoubleValue::CopyFrom(const DoubleValue& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.DoubleValue)
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+bool DoubleValue::IsInitialized() const {
+ return true;
+}
+
+void DoubleValue::InternalSwap(DoubleValue* other) {
+ using std::swap;
+ _internal_metadata_.InternalSwap(&other->_internal_metadata_);
+ swap(value_, other->value_);
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata DoubleValue::GetMetadata() const {
+ return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(
+ &descriptor_table_google_2fprotobuf_2fwrappers_2eproto_getter, &descriptor_table_google_2fprotobuf_2fwrappers_2eproto_once,
+ file_level_metadata_google_2fprotobuf_2fwrappers_2eproto[0]);
+}
+
+// ===================================================================
+
+class FloatValue::_Internal {
+ public:
+};
+
+FloatValue::FloatValue(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned)
+ : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) {
+ SharedCtor();
+ if (!is_message_owned) {
+ RegisterArenaDtor(arena);
+ }
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.FloatValue)
+}
+FloatValue::FloatValue(const FloatValue& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message() {
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ value_ = from.value_;
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.FloatValue)
+}
+
+inline void FloatValue::SharedCtor() {
+value_ = 0;
+}
+
+FloatValue::~FloatValue() {
+ // @@protoc_insertion_point(destructor:google.protobuf.FloatValue)
+ if (GetArenaForAllocation() != nullptr) return;
+ SharedDtor();
+ _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+inline void FloatValue::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+}
+
+void FloatValue::ArenaDtor(void* object) {
+ FloatValue* _this = reinterpret_cast< FloatValue* >(object);
+ (void)_this;
+}
+void FloatValue::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) {
+}
+void FloatValue::SetCachedSize(int size) const {
+ _cached_size_.Set(size);
+}
+
+void FloatValue::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.FloatValue)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ value_ = 0;
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* FloatValue::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag);
+ switch (tag >> 3) {
+ // float value = 1;
+ case 1:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 13)) {
+ value_ = ::PROTOBUF_NAMESPACE_ID::internal::UnalignedLoad<float>(ptr);
+ ptr += sizeof(float);
+ } else
+ goto handle_unusual;
+ continue;
+ default:
+ goto handle_unusual;
+ } // switch
+ handle_unusual:
+ if ((tag == 0) || ((tag & 7) == 4)) {
+ CHK_(ptr);
+ ctx->SetLastTag(tag);
+ goto message_done;
+ }
+ ptr = UnknownFieldParse(
+ tag,
+ _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(),
+ ptr, ctx);
+ CHK_(ptr != nullptr);
+ } // while
+message_done:
+ return ptr;
+failure:
+ ptr = nullptr;
+ goto message_done;
+#undef CHK_
+}
+
+uint8_t* FloatValue::_InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const {
+ // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.FloatValue)
+ 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 = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteFloatToArray(1, this->_internal_value(), target);
+ }
+
+ if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray(
+ _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.FloatValue)
+ return target;
+}
+
+size_t FloatValue::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.FloatValue)
+ size_t total_size = 0;
+
+ 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, &_cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData FloatValue::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck,
+ FloatValue::MergeImpl
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*FloatValue::GetClassData() const { return &_class_data_; }
+
+void FloatValue::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to,
+ const ::PROTOBUF_NAMESPACE_ID::Message& from) {
+ static_cast<FloatValue *>(to)->MergeFrom(
+ static_cast<const FloatValue &>(from));
+}
+
+
+void FloatValue::MergeFrom(const FloatValue& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.FloatValue)
+ GOOGLE_DCHECK_NE(&from, this);
+ 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) {
+ _internal_set_value(from._internal_value());
+ }
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+}
+
+void FloatValue::CopyFrom(const FloatValue& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.FloatValue)
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+bool FloatValue::IsInitialized() const {
+ return true;
+}
+
+void FloatValue::InternalSwap(FloatValue* other) {
+ using std::swap;
+ _internal_metadata_.InternalSwap(&other->_internal_metadata_);
+ swap(value_, other->value_);
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata FloatValue::GetMetadata() const {
+ return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(
+ &descriptor_table_google_2fprotobuf_2fwrappers_2eproto_getter, &descriptor_table_google_2fprotobuf_2fwrappers_2eproto_once,
+ file_level_metadata_google_2fprotobuf_2fwrappers_2eproto[1]);
+}
+
+// ===================================================================
+
+class Int64Value::_Internal {
+ public:
+};
+
+Int64Value::Int64Value(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned)
+ : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) {
+ SharedCtor();
+ if (!is_message_owned) {
+ RegisterArenaDtor(arena);
+ }
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.Int64Value)
+}
+Int64Value::Int64Value(const Int64Value& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message() {
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ value_ = from.value_;
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.Int64Value)
+}
+
+inline void Int64Value::SharedCtor() {
+value_ = int64_t{0};
+}
+
+Int64Value::~Int64Value() {
+ // @@protoc_insertion_point(destructor:google.protobuf.Int64Value)
+ if (GetArenaForAllocation() != nullptr) return;
+ SharedDtor();
+ _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+inline void Int64Value::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+}
+
+void Int64Value::ArenaDtor(void* object) {
+ Int64Value* _this = reinterpret_cast< Int64Value* >(object);
+ (void)_this;
+}
+void Int64Value::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) {
+}
+void Int64Value::SetCachedSize(int size) const {
+ _cached_size_.Set(size);
+}
+
+void Int64Value::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.Int64Value)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ value_ = int64_t{0};
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* Int64Value::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag);
+ switch (tag >> 3) {
+ // int64 value = 1;
+ case 1:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 8)) {
+ value_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr);
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ default:
+ goto handle_unusual;
+ } // switch
+ handle_unusual:
+ if ((tag == 0) || ((tag & 7) == 4)) {
+ CHK_(ptr);
+ ctx->SetLastTag(tag);
+ goto message_done;
+ }
+ ptr = UnknownFieldParse(
+ tag,
+ _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(),
+ ptr, ctx);
+ CHK_(ptr != nullptr);
+ } // while
+message_done:
+ return ptr;
+failure:
+ ptr = nullptr;
+ goto message_done;
+#undef CHK_
+}
+
+uint8_t* Int64Value::_InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const {
+ // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Int64Value)
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ // int64 value = 1;
+ if (this->_internal_value() != 0) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt64ToArray(1, this->_internal_value(), target);
+ }
+
+ if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray(
+ _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Int64Value)
+ return target;
+}
+
+size_t Int64Value::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.Int64Value)
+ size_t total_size = 0;
+
+ 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 += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int64SizePlusOne(this->_internal_value());
+ }
+
+ return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData Int64Value::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck,
+ Int64Value::MergeImpl
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*Int64Value::GetClassData() const { return &_class_data_; }
+
+void Int64Value::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to,
+ const ::PROTOBUF_NAMESPACE_ID::Message& from) {
+ static_cast<Int64Value *>(to)->MergeFrom(
+ static_cast<const Int64Value &>(from));
+}
+
+
+void Int64Value::MergeFrom(const Int64Value& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Int64Value)
+ GOOGLE_DCHECK_NE(&from, this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ if (from._internal_value() != 0) {
+ _internal_set_value(from._internal_value());
+ }
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+}
+
+void Int64Value::CopyFrom(const Int64Value& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.Int64Value)
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+bool Int64Value::IsInitialized() const {
+ return true;
+}
+
+void Int64Value::InternalSwap(Int64Value* other) {
+ using std::swap;
+ _internal_metadata_.InternalSwap(&other->_internal_metadata_);
+ swap(value_, other->value_);
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata Int64Value::GetMetadata() const {
+ return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(
+ &descriptor_table_google_2fprotobuf_2fwrappers_2eproto_getter, &descriptor_table_google_2fprotobuf_2fwrappers_2eproto_once,
+ file_level_metadata_google_2fprotobuf_2fwrappers_2eproto[2]);
+}
+
+// ===================================================================
+
+class UInt64Value::_Internal {
+ public:
+};
+
+UInt64Value::UInt64Value(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned)
+ : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) {
+ SharedCtor();
+ if (!is_message_owned) {
+ RegisterArenaDtor(arena);
+ }
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.UInt64Value)
+}
+UInt64Value::UInt64Value(const UInt64Value& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message() {
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ value_ = from.value_;
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.UInt64Value)
+}
+
+inline void UInt64Value::SharedCtor() {
+value_ = uint64_t{0u};
+}
+
+UInt64Value::~UInt64Value() {
+ // @@protoc_insertion_point(destructor:google.protobuf.UInt64Value)
+ if (GetArenaForAllocation() != nullptr) return;
+ SharedDtor();
+ _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+inline void UInt64Value::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+}
+
+void UInt64Value::ArenaDtor(void* object) {
+ UInt64Value* _this = reinterpret_cast< UInt64Value* >(object);
+ (void)_this;
+}
+void UInt64Value::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) {
+}
+void UInt64Value::SetCachedSize(int size) const {
+ _cached_size_.Set(size);
+}
+
+void UInt64Value::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.UInt64Value)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ value_ = uint64_t{0u};
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* UInt64Value::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag);
+ switch (tag >> 3) {
+ // uint64 value = 1;
+ case 1:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 8)) {
+ value_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr);
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ default:
+ goto handle_unusual;
+ } // switch
+ handle_unusual:
+ if ((tag == 0) || ((tag & 7) == 4)) {
+ CHK_(ptr);
+ ctx->SetLastTag(tag);
+ goto message_done;
+ }
+ ptr = UnknownFieldParse(
+ tag,
+ _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(),
+ ptr, ctx);
+ CHK_(ptr != nullptr);
+ } // while
+message_done:
+ return ptr;
+failure:
+ ptr = nullptr;
+ goto message_done;
+#undef CHK_
+}
+
+uint8_t* UInt64Value::_InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const {
+ // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.UInt64Value)
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ // uint64 value = 1;
+ if (this->_internal_value() != 0) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteUInt64ToArray(1, this->_internal_value(), target);
+ }
+
+ if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray(
+ _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.UInt64Value)
+ return target;
+}
+
+size_t UInt64Value::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.UInt64Value)
+ size_t total_size = 0;
+
+ 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 += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::UInt64SizePlusOne(this->_internal_value());
+ }
+
+ return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData UInt64Value::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck,
+ UInt64Value::MergeImpl
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*UInt64Value::GetClassData() const { return &_class_data_; }
+
+void UInt64Value::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to,
+ const ::PROTOBUF_NAMESPACE_ID::Message& from) {
+ static_cast<UInt64Value *>(to)->MergeFrom(
+ static_cast<const UInt64Value &>(from));
+}
+
+
+void UInt64Value::MergeFrom(const UInt64Value& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.UInt64Value)
+ GOOGLE_DCHECK_NE(&from, this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ if (from._internal_value() != 0) {
+ _internal_set_value(from._internal_value());
+ }
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+}
+
+void UInt64Value::CopyFrom(const UInt64Value& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.UInt64Value)
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+bool UInt64Value::IsInitialized() const {
+ return true;
+}
+
+void UInt64Value::InternalSwap(UInt64Value* other) {
+ using std::swap;
+ _internal_metadata_.InternalSwap(&other->_internal_metadata_);
+ swap(value_, other->value_);
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata UInt64Value::GetMetadata() const {
+ return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(
+ &descriptor_table_google_2fprotobuf_2fwrappers_2eproto_getter, &descriptor_table_google_2fprotobuf_2fwrappers_2eproto_once,
+ file_level_metadata_google_2fprotobuf_2fwrappers_2eproto[3]);
+}
+
+// ===================================================================
+
+class Int32Value::_Internal {
+ public:
+};
+
+Int32Value::Int32Value(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned)
+ : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) {
+ SharedCtor();
+ if (!is_message_owned) {
+ RegisterArenaDtor(arena);
+ }
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.Int32Value)
+}
+Int32Value::Int32Value(const Int32Value& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message() {
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ value_ = from.value_;
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.Int32Value)
+}
+
+inline void Int32Value::SharedCtor() {
+value_ = 0;
+}
+
+Int32Value::~Int32Value() {
+ // @@protoc_insertion_point(destructor:google.protobuf.Int32Value)
+ if (GetArenaForAllocation() != nullptr) return;
+ SharedDtor();
+ _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+inline void Int32Value::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+}
+
+void Int32Value::ArenaDtor(void* object) {
+ Int32Value* _this = reinterpret_cast< Int32Value* >(object);
+ (void)_this;
+}
+void Int32Value::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) {
+}
+void Int32Value::SetCachedSize(int size) const {
+ _cached_size_.Set(size);
+}
+
+void Int32Value::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.Int32Value)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ value_ = 0;
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* Int32Value::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag);
+ switch (tag >> 3) {
+ // int32 value = 1;
+ case 1:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 8)) {
+ value_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint32(&ptr);
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ default:
+ goto handle_unusual;
+ } // switch
+ handle_unusual:
+ if ((tag == 0) || ((tag & 7) == 4)) {
+ CHK_(ptr);
+ ctx->SetLastTag(tag);
+ goto message_done;
+ }
+ ptr = UnknownFieldParse(
+ tag,
+ _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(),
+ ptr, ctx);
+ CHK_(ptr != nullptr);
+ } // while
+message_done:
+ return ptr;
+failure:
+ ptr = nullptr;
+ goto message_done;
+#undef CHK_
+}
+
+uint8_t* Int32Value::_InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const {
+ // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Int32Value)
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ // int32 value = 1;
+ if (this->_internal_value() != 0) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32ToArray(1, this->_internal_value(), target);
+ }
+
+ if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray(
+ _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Int32Value)
+ return target;
+}
+
+size_t Int32Value::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.Int32Value)
+ size_t total_size = 0;
+
+ 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 += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32SizePlusOne(this->_internal_value());
+ }
+
+ return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData Int32Value::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck,
+ Int32Value::MergeImpl
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*Int32Value::GetClassData() const { return &_class_data_; }
+
+void Int32Value::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to,
+ const ::PROTOBUF_NAMESPACE_ID::Message& from) {
+ static_cast<Int32Value *>(to)->MergeFrom(
+ static_cast<const Int32Value &>(from));
+}
+
+
+void Int32Value::MergeFrom(const Int32Value& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Int32Value)
+ GOOGLE_DCHECK_NE(&from, this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ if (from._internal_value() != 0) {
+ _internal_set_value(from._internal_value());
+ }
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+}
+
+void Int32Value::CopyFrom(const Int32Value& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.Int32Value)
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+bool Int32Value::IsInitialized() const {
+ return true;
+}
+
+void Int32Value::InternalSwap(Int32Value* other) {
+ using std::swap;
+ _internal_metadata_.InternalSwap(&other->_internal_metadata_);
+ swap(value_, other->value_);
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata Int32Value::GetMetadata() const {
+ return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(
+ &descriptor_table_google_2fprotobuf_2fwrappers_2eproto_getter, &descriptor_table_google_2fprotobuf_2fwrappers_2eproto_once,
+ file_level_metadata_google_2fprotobuf_2fwrappers_2eproto[4]);
+}
+
+// ===================================================================
+
+class UInt32Value::_Internal {
+ public:
+};
+
+UInt32Value::UInt32Value(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned)
+ : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) {
+ SharedCtor();
+ if (!is_message_owned) {
+ RegisterArenaDtor(arena);
+ }
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.UInt32Value)
+}
+UInt32Value::UInt32Value(const UInt32Value& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message() {
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ value_ = from.value_;
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.UInt32Value)
+}
+
+inline void UInt32Value::SharedCtor() {
+value_ = 0u;
+}
+
+UInt32Value::~UInt32Value() {
+ // @@protoc_insertion_point(destructor:google.protobuf.UInt32Value)
+ if (GetArenaForAllocation() != nullptr) return;
+ SharedDtor();
+ _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+inline void UInt32Value::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+}
+
+void UInt32Value::ArenaDtor(void* object) {
+ UInt32Value* _this = reinterpret_cast< UInt32Value* >(object);
+ (void)_this;
+}
+void UInt32Value::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) {
+}
+void UInt32Value::SetCachedSize(int size) const {
+ _cached_size_.Set(size);
+}
+
+void UInt32Value::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.UInt32Value)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ value_ = 0u;
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* UInt32Value::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag);
+ switch (tag >> 3) {
+ // uint32 value = 1;
+ case 1:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 8)) {
+ value_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint32(&ptr);
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ default:
+ goto handle_unusual;
+ } // switch
+ handle_unusual:
+ if ((tag == 0) || ((tag & 7) == 4)) {
+ CHK_(ptr);
+ ctx->SetLastTag(tag);
+ goto message_done;
+ }
+ ptr = UnknownFieldParse(
+ tag,
+ _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(),
+ ptr, ctx);
+ CHK_(ptr != nullptr);
+ } // while
+message_done:
+ return ptr;
+failure:
+ ptr = nullptr;
+ goto message_done;
+#undef CHK_
+}
+
+uint8_t* UInt32Value::_InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const {
+ // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.UInt32Value)
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ // uint32 value = 1;
+ if (this->_internal_value() != 0) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteUInt32ToArray(1, this->_internal_value(), target);
+ }
+
+ if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray(
+ _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.UInt32Value)
+ return target;
+}
+
+size_t UInt32Value::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.UInt32Value)
+ size_t total_size = 0;
+
+ 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 += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::UInt32SizePlusOne(this->_internal_value());
+ }
+
+ return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData UInt32Value::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck,
+ UInt32Value::MergeImpl
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*UInt32Value::GetClassData() const { return &_class_data_; }
+
+void UInt32Value::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to,
+ const ::PROTOBUF_NAMESPACE_ID::Message& from) {
+ static_cast<UInt32Value *>(to)->MergeFrom(
+ static_cast<const UInt32Value &>(from));
+}
+
+
+void UInt32Value::MergeFrom(const UInt32Value& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.UInt32Value)
+ GOOGLE_DCHECK_NE(&from, this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ if (from._internal_value() != 0) {
+ _internal_set_value(from._internal_value());
+ }
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+}
+
+void UInt32Value::CopyFrom(const UInt32Value& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.UInt32Value)
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+bool UInt32Value::IsInitialized() const {
+ return true;
+}
+
+void UInt32Value::InternalSwap(UInt32Value* other) {
+ using std::swap;
+ _internal_metadata_.InternalSwap(&other->_internal_metadata_);
+ swap(value_, other->value_);
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata UInt32Value::GetMetadata() const {
+ return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(
+ &descriptor_table_google_2fprotobuf_2fwrappers_2eproto_getter, &descriptor_table_google_2fprotobuf_2fwrappers_2eproto_once,
+ file_level_metadata_google_2fprotobuf_2fwrappers_2eproto[5]);
+}
+
+// ===================================================================
+
+class BoolValue::_Internal {
+ public:
+};
+
+BoolValue::BoolValue(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned)
+ : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) {
+ SharedCtor();
+ if (!is_message_owned) {
+ RegisterArenaDtor(arena);
+ }
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.BoolValue)
+}
+BoolValue::BoolValue(const BoolValue& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message() {
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ value_ = from.value_;
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.BoolValue)
+}
+
+inline void BoolValue::SharedCtor() {
+value_ = false;
+}
+
+BoolValue::~BoolValue() {
+ // @@protoc_insertion_point(destructor:google.protobuf.BoolValue)
+ if (GetArenaForAllocation() != nullptr) return;
+ SharedDtor();
+ _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+inline void BoolValue::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+}
+
+void BoolValue::ArenaDtor(void* object) {
+ BoolValue* _this = reinterpret_cast< BoolValue* >(object);
+ (void)_this;
+}
+void BoolValue::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) {
+}
+void BoolValue::SetCachedSize(int size) const {
+ _cached_size_.Set(size);
+}
+
+void BoolValue::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.BoolValue)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ value_ = false;
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* BoolValue::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag);
+ switch (tag >> 3) {
+ // bool value = 1;
+ case 1:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 8)) {
+ value_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr);
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ default:
+ goto handle_unusual;
+ } // switch
+ handle_unusual:
+ if ((tag == 0) || ((tag & 7) == 4)) {
+ CHK_(ptr);
+ ctx->SetLastTag(tag);
+ goto message_done;
+ }
+ ptr = UnknownFieldParse(
+ tag,
+ _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(),
+ ptr, ctx);
+ CHK_(ptr != nullptr);
+ } // while
+message_done:
+ return ptr;
+failure:
+ ptr = nullptr;
+ goto message_done;
+#undef CHK_
+}
+
+uint8_t* BoolValue::_InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const {
+ // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.BoolValue)
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ // bool value = 1;
+ if (this->_internal_value() != 0) {
+ target = stream->EnsureSpace(target);
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBoolToArray(1, this->_internal_value(), target);
+ }
+
+ if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
+ target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray(
+ _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.BoolValue)
+ return target;
+}
+
+size_t BoolValue::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.BoolValue)
+ size_t total_size = 0;
+
+ 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, &_cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData BoolValue::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck,
+ BoolValue::MergeImpl
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*BoolValue::GetClassData() const { return &_class_data_; }
+
+void BoolValue::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to,
+ const ::PROTOBUF_NAMESPACE_ID::Message& from) {
+ static_cast<BoolValue *>(to)->MergeFrom(
+ static_cast<const BoolValue &>(from));
+}
+
+
+void BoolValue::MergeFrom(const BoolValue& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.BoolValue)
+ GOOGLE_DCHECK_NE(&from, this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ if (from._internal_value() != 0) {
+ _internal_set_value(from._internal_value());
+ }
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+}
+
+void BoolValue::CopyFrom(const BoolValue& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.BoolValue)
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+bool BoolValue::IsInitialized() const {
+ return true;
+}
+
+void BoolValue::InternalSwap(BoolValue* other) {
+ using std::swap;
+ _internal_metadata_.InternalSwap(&other->_internal_metadata_);
+ swap(value_, other->value_);
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata BoolValue::GetMetadata() const {
+ return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(
+ &descriptor_table_google_2fprotobuf_2fwrappers_2eproto_getter, &descriptor_table_google_2fprotobuf_2fwrappers_2eproto_once,
+ file_level_metadata_google_2fprotobuf_2fwrappers_2eproto[6]);
+}
+
+// ===================================================================
+
+class StringValue::_Internal {
+ public:
+};
+
+StringValue::StringValue(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned)
+ : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) {
+ SharedCtor();
+ if (!is_message_owned) {
+ RegisterArenaDtor(arena);
+ }
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.StringValue)
+}
+StringValue::StringValue(const StringValue& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message() {
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ value_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (!from._internal_value().empty()) {
+ value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_value(),
+ GetArenaForAllocation());
+ }
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.StringValue)
+}
+
+inline void StringValue::SharedCtor() {
+value_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+}
+
+StringValue::~StringValue() {
+ // @@protoc_insertion_point(destructor:google.protobuf.StringValue)
+ if (GetArenaForAllocation() != nullptr) return;
+ SharedDtor();
+ _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+inline void StringValue::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+ value_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+}
+
+void StringValue::ArenaDtor(void* object) {
+ StringValue* _this = reinterpret_cast< StringValue* >(object);
+ (void)_this;
+}
+void StringValue::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) {
+}
+void StringValue::SetCachedSize(int size) const {
+ _cached_size_.Set(size);
+}
+
+void StringValue::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.StringValue)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ value_.ClearToEmpty();
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* StringValue::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag);
+ switch (tag >> 3) {
+ // string value = 1;
+ case 1:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 10)) {
+ auto str = _internal_mutable_value();
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx);
+ CHK_(::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.StringValue.value"));
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ default:
+ goto handle_unusual;
+ } // switch
+ handle_unusual:
+ if ((tag == 0) || ((tag & 7) == 4)) {
+ CHK_(ptr);
+ ctx->SetLastTag(tag);
+ goto message_done;
+ }
+ ptr = UnknownFieldParse(
+ tag,
+ _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(),
+ ptr, ctx);
+ CHK_(ptr != nullptr);
+ } // while
+message_done:
+ return ptr;
+failure:
+ ptr = nullptr;
+ goto message_done;
+#undef CHK_
+}
+
+uint8_t* StringValue::_InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const {
+ // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.StringValue)
+ 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 = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray(
+ _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.StringValue)
+ return target;
+}
+
+size_t StringValue::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.StringValue)
+ size_t total_size = 0;
+
+ 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, &_cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData StringValue::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck,
+ StringValue::MergeImpl
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*StringValue::GetClassData() const { return &_class_data_; }
+
+void StringValue::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to,
+ const ::PROTOBUF_NAMESPACE_ID::Message& from) {
+ static_cast<StringValue *>(to)->MergeFrom(
+ static_cast<const StringValue &>(from));
+}
+
+
+void StringValue::MergeFrom(const StringValue& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.StringValue)
+ GOOGLE_DCHECK_NE(&from, this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ if (!from._internal_value().empty()) {
+ _internal_set_value(from._internal_value());
+ }
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+}
+
+void StringValue::CopyFrom(const StringValue& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.StringValue)
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+bool StringValue::IsInitialized() const {
+ return true;
+}
+
+void StringValue::InternalSwap(StringValue* other) {
+ using std::swap;
+ auto* lhs_arena = GetArenaForAllocation();
+ auto* rhs_arena = other->GetArenaForAllocation();
+ _internal_metadata_.InternalSwap(&other->_internal_metadata_);
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(),
+ &value_, lhs_arena,
+ &other->value_, rhs_arena
+ );
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata StringValue::GetMetadata() const {
+ return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(
+ &descriptor_table_google_2fprotobuf_2fwrappers_2eproto_getter, &descriptor_table_google_2fprotobuf_2fwrappers_2eproto_once,
+ file_level_metadata_google_2fprotobuf_2fwrappers_2eproto[7]);
+}
+
+// ===================================================================
+
+class BytesValue::_Internal {
+ public:
+};
+
+BytesValue::BytesValue(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned)
+ : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) {
+ SharedCtor();
+ if (!is_message_owned) {
+ RegisterArenaDtor(arena);
+ }
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.BytesValue)
+}
+BytesValue::BytesValue(const BytesValue& from)
+ : ::PROTOBUF_NAMESPACE_ID::Message() {
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+ value_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+ #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (!from._internal_value().empty()) {
+ value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_value(),
+ GetArenaForAllocation());
+ }
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.BytesValue)
+}
+
+inline void BytesValue::SharedCtor() {
+value_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+}
+
+BytesValue::~BytesValue() {
+ // @@protoc_insertion_point(destructor:google.protobuf.BytesValue)
+ if (GetArenaForAllocation() != nullptr) return;
+ SharedDtor();
+ _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+inline void BytesValue::SharedDtor() {
+ GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
+ value_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+}
+
+void BytesValue::ArenaDtor(void* object) {
+ BytesValue* _this = reinterpret_cast< BytesValue* >(object);
+ (void)_this;
+}
+void BytesValue::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) {
+}
+void BytesValue::SetCachedSize(int size) const {
+ _cached_size_.Set(size);
+}
+
+void BytesValue::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.BytesValue)
+ uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ value_.ClearToEmpty();
+ _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
+}
+
+const char* BytesValue::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) {
+#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
+ while (!ctx->Done(&ptr)) {
+ uint32_t tag;
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag);
+ switch (tag >> 3) {
+ // bytes value = 1;
+ case 1:
+ if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 10)) {
+ auto str = _internal_mutable_value();
+ ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx);
+ CHK_(ptr);
+ } else
+ goto handle_unusual;
+ continue;
+ default:
+ goto handle_unusual;
+ } // switch
+ handle_unusual:
+ if ((tag == 0) || ((tag & 7) == 4)) {
+ CHK_(ptr);
+ ctx->SetLastTag(tag);
+ goto message_done;
+ }
+ ptr = UnknownFieldParse(
+ tag,
+ _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(),
+ ptr, ctx);
+ CHK_(ptr != nullptr);
+ } // while
+message_done:
+ return ptr;
+failure:
+ ptr = nullptr;
+ goto message_done;
+#undef CHK_
+}
+
+uint8_t* BytesValue::_InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const {
+ // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.BytesValue)
+ 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 = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray(
+ _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.BytesValue)
+ return target;
+}
+
+size_t BytesValue::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.BytesValue)
+ size_t total_size = 0;
+
+ 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, &_cached_size_);
+}
+
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData BytesValue::_class_data_ = {
+ ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck,
+ BytesValue::MergeImpl
+};
+const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*BytesValue::GetClassData() const { return &_class_data_; }
+
+void BytesValue::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to,
+ const ::PROTOBUF_NAMESPACE_ID::Message& from) {
+ static_cast<BytesValue *>(to)->MergeFrom(
+ static_cast<const BytesValue &>(from));
+}
+
+
+void BytesValue::MergeFrom(const BytesValue& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.BytesValue)
+ GOOGLE_DCHECK_NE(&from, this);
+ uint32_t cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ if (!from._internal_value().empty()) {
+ _internal_set_value(from._internal_value());
+ }
+ _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
+}
+
+void BytesValue::CopyFrom(const BytesValue& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.BytesValue)
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+bool BytesValue::IsInitialized() const {
+ return true;
+}
+
+void BytesValue::InternalSwap(BytesValue* other) {
+ using std::swap;
+ auto* lhs_arena = GetArenaForAllocation();
+ auto* rhs_arena = other->GetArenaForAllocation();
+ _internal_metadata_.InternalSwap(&other->_internal_metadata_);
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
+ &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(),
+ &value_, lhs_arena,
+ &other->value_, rhs_arena
+ );
+}
+
+::PROTOBUF_NAMESPACE_ID::Metadata BytesValue::GetMetadata() const {
+ return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(
+ &descriptor_table_google_2fprotobuf_2fwrappers_2eproto_getter, &descriptor_table_google_2fprotobuf_2fwrappers_2eproto_once,
+ file_level_metadata_google_2fprotobuf_2fwrappers_2eproto[8]);
+}
+
+// @@protoc_insertion_point(namespace_scope)
+PROTOBUF_NAMESPACE_CLOSE
+PROTOBUF_NAMESPACE_OPEN
+template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::DoubleValue* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::DoubleValue >(Arena* arena) {
+ return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::DoubleValue >(arena);
+}
+template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::FloatValue* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::FloatValue >(Arena* arena) {
+ return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::FloatValue >(arena);
+}
+template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::Int64Value* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::Int64Value >(Arena* arena) {
+ return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::Int64Value >(arena);
+}
+template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::UInt64Value* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::UInt64Value >(Arena* arena) {
+ return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::UInt64Value >(arena);
+}
+template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::Int32Value* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::Int32Value >(Arena* arena) {
+ return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::Int32Value >(arena);
+}
+template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::UInt32Value* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::UInt32Value >(Arena* arena) {
+ return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::UInt32Value >(arena);
+}
+template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::BoolValue* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::BoolValue >(Arena* arena) {
+ return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::BoolValue >(arena);
+}
+template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::StringValue* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::StringValue >(Arena* arena) {
+ return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::StringValue >(arena);
+}
+template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::BytesValue* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::BytesValue >(Arena* arena) {
+ return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::BytesValue >(arena);
+}
+PROTOBUF_NAMESPACE_CLOSE
+
+// @@protoc_insertion_point(global_scope)
+#include <port_undef.inc>
diff --git a/NorthstarDedicatedTest/include/protobuf/wrappers.pb.h b/NorthstarDedicatedTest/include/protobuf/wrappers.pb.h
new file mode 100644
index 00000000..6f639dde
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/wrappers.pb.h
@@ -0,0 +1,1734 @@
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+// source: google/protobuf/wrappers.proto
+
+#ifndef GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fwrappers_2eproto
+#define GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fwrappers_2eproto
+
+#include <limits>
+#include <string>
+
+#include <port_def.inc>
+#if PROTOBUF_VERSION < 3019000
+#error This file was generated by a newer version of protoc which is
+#error incompatible with your Protocol Buffer headers. Please update
+#error your headers.
+#endif
+#if 3019004 < 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 <port_undef.inc>
+#include <io/coded_stream.h>
+#include <arena.h>
+#include <arenastring.h>
+#include <generated_message_table_driven.h>
+#include <generated_message_util.h>
+#include <metadata_lite.h>
+#include <generated_message_reflection.h>
+#include <message.h>
+#include <repeated_field.h> // IWYU pragma: export
+#include <extension_set.h> // IWYU pragma: export
+#include <unknown_field_set.h>
+// @@protoc_insertion_point(includes)
+#include <port_def.inc>
+#define PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fwrappers_2eproto PROTOBUF_EXPORT
+PROTOBUF_NAMESPACE_OPEN
+namespace internal {
+class AnyMetadata;
+} // namespace internal
+PROTOBUF_NAMESPACE_CLOSE
+
+// Internal implementation detail -- do not use these members.
+struct PROTOBUF_EXPORT TableStruct_google_2fprotobuf_2fwrappers_2eproto {
+ static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTableField entries[]
+ PROTOBUF_SECTION_VARIABLE(protodesc_cold);
+ static const ::PROTOBUF_NAMESPACE_ID::internal::AuxiliaryParseTableField aux[]
+ PROTOBUF_SECTION_VARIABLE(protodesc_cold);
+ static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTable schema[9]
+ PROTOBUF_SECTION_VARIABLE(protodesc_cold);
+ static const ::PROTOBUF_NAMESPACE_ID::internal::FieldMetadata field_metadata[];
+ static const ::PROTOBUF_NAMESPACE_ID::internal::SerializationTable serialization_table[];
+ static const 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 constexpr DoubleValue(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
+
+ DoubleValue(const DoubleValue& from);
+ DoubleValue(DoubleValue&& from) noexcept
+ : DoubleValue() {
+ *this = ::std::move(from);
+ }
+
+ inline DoubleValue& operator=(const DoubleValue& from) {
+ CopyFrom(from);
+ return *this;
+ }
+ inline DoubleValue& operator=(DoubleValue&& from) noexcept {
+ if (this == &from) return *this;
+ if (GetOwningArena() == from.GetOwningArena()
+ #ifdef PROTOBUF_FORCE_COPY_IN_MOVE
+ && GetOwningArena() != nullptr
+ #endif // !PROTOBUF_FORCE_COPY_IN_MOVE
+ ) {
+ InternalSwap(&from);
+ } else {
+ CopyFrom(from);
+ }
+ return *this;
+ }
+
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
+ return GetDescriptor();
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
+ return default_instance().GetMetadata().descriptor;
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
+ return default_instance().GetMetadata().reflection;
+ }
+ static const DoubleValue& default_instance() {
+ return *internal_default_instance();
+ }
+ static inline const DoubleValue* internal_default_instance() {
+ return reinterpret_cast<const DoubleValue*>(
+ &_DoubleValue_default_instance_);
+ }
+ static constexpr int kIndexInFileMessages =
+ 0;
+
+ friend void swap(DoubleValue& a, DoubleValue& b) {
+ a.Swap(&b);
+ }
+ inline void Swap(DoubleValue* other) {
+ if (other == this) return;
+ #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() != nullptr &&
+ GetOwningArena() == other->GetOwningArena()) {
+ #else // PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() == other->GetOwningArena()) {
+ #endif // !PROTOBUF_FORCE_COPY_IN_SWAP
+ InternalSwap(other);
+ } else {
+ ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
+ }
+ }
+ void UnsafeArenaSwap(DoubleValue* other) {
+ if (other == this) return;
+ GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena());
+ InternalSwap(other);
+ }
+
+ // implements Message ----------------------------------------------
+
+ DoubleValue* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
+ return CreateMaybeMessage<DoubleValue>(arena);
+ }
+ using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
+ void CopyFrom(const DoubleValue& from);
+ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
+ void MergeFrom(const DoubleValue& from);
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from);
+ public:
+ PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+ bool IsInitialized() const final;
+
+ size_t ByteSizeLong() const final;
+ const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
+ uint8_t* _InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
+ int GetCachedSize() const final { return _cached_size_.Get(); }
+
+ private:
+ void SharedCtor();
+ void SharedDtor();
+ void SetCachedSize(int size) const final;
+ void InternalSwap(DoubleValue* other);
+
+ private:
+ friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
+ static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
+ return "google.protobuf.DoubleValue";
+ }
+ protected:
+ explicit DoubleValue(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned = false);
+ private:
+ static void ArenaDtor(void* object);
+ inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
+ public:
+
+ static const ClassData _class_data_;
+ const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;
+
+ ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;
+
+ // nested types ----------------------------------------------------
+
+ // accessors -------------------------------------------------------
+
+ enum : int {
+ kValueFieldNumber = 1,
+ };
+ // double value = 1;
+ void clear_value();
+ double value() const;
+ void set_value(double value);
+ private:
+ double _internal_value() const;
+ void _internal_set_value(double value);
+ public:
+
+ // @@protoc_insertion_point(class_scope:google.protobuf.DoubleValue)
+ private:
+ class _Internal;
+
+ template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
+ typedef void InternalArenaConstructable_;
+ typedef void DestructorSkippable_;
+ double value_;
+ mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
+ friend struct ::TableStruct_google_2fprotobuf_2fwrappers_2eproto;
+};
+// -------------------------------------------------------------------
+
+class PROTOBUF_EXPORT FloatValue final :
+ public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.FloatValue) */ {
+ public:
+ inline FloatValue() : FloatValue(nullptr) {}
+ ~FloatValue() override;
+ explicit constexpr FloatValue(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
+
+ FloatValue(const FloatValue& from);
+ FloatValue(FloatValue&& from) noexcept
+ : FloatValue() {
+ *this = ::std::move(from);
+ }
+
+ inline FloatValue& operator=(const FloatValue& from) {
+ CopyFrom(from);
+ return *this;
+ }
+ inline FloatValue& operator=(FloatValue&& from) noexcept {
+ if (this == &from) return *this;
+ if (GetOwningArena() == from.GetOwningArena()
+ #ifdef PROTOBUF_FORCE_COPY_IN_MOVE
+ && GetOwningArena() != nullptr
+ #endif // !PROTOBUF_FORCE_COPY_IN_MOVE
+ ) {
+ InternalSwap(&from);
+ } else {
+ CopyFrom(from);
+ }
+ return *this;
+ }
+
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
+ return GetDescriptor();
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
+ return default_instance().GetMetadata().descriptor;
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
+ return default_instance().GetMetadata().reflection;
+ }
+ static const FloatValue& default_instance() {
+ return *internal_default_instance();
+ }
+ static inline const FloatValue* internal_default_instance() {
+ return reinterpret_cast<const FloatValue*>(
+ &_FloatValue_default_instance_);
+ }
+ static constexpr int kIndexInFileMessages =
+ 1;
+
+ friend void swap(FloatValue& a, FloatValue& b) {
+ a.Swap(&b);
+ }
+ inline void Swap(FloatValue* other) {
+ if (other == this) return;
+ #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() != nullptr &&
+ GetOwningArena() == other->GetOwningArena()) {
+ #else // PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() == other->GetOwningArena()) {
+ #endif // !PROTOBUF_FORCE_COPY_IN_SWAP
+ InternalSwap(other);
+ } else {
+ ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
+ }
+ }
+ void UnsafeArenaSwap(FloatValue* other) {
+ if (other == this) return;
+ GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena());
+ InternalSwap(other);
+ }
+
+ // implements Message ----------------------------------------------
+
+ FloatValue* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
+ return CreateMaybeMessage<FloatValue>(arena);
+ }
+ using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
+ void CopyFrom(const FloatValue& from);
+ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
+ void MergeFrom(const FloatValue& from);
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from);
+ public:
+ PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+ bool IsInitialized() const final;
+
+ size_t ByteSizeLong() const final;
+ const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
+ uint8_t* _InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
+ int GetCachedSize() const final { return _cached_size_.Get(); }
+
+ private:
+ void SharedCtor();
+ void SharedDtor();
+ void SetCachedSize(int size) const final;
+ void InternalSwap(FloatValue* other);
+
+ private:
+ friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
+ static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
+ return "google.protobuf.FloatValue";
+ }
+ protected:
+ explicit FloatValue(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned = false);
+ private:
+ static void ArenaDtor(void* object);
+ inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
+ public:
+
+ static const ClassData _class_data_;
+ const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;
+
+ ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;
+
+ // nested types ----------------------------------------------------
+
+ // accessors -------------------------------------------------------
+
+ enum : int {
+ kValueFieldNumber = 1,
+ };
+ // float value = 1;
+ void clear_value();
+ float value() const;
+ void set_value(float value);
+ private:
+ float _internal_value() const;
+ void _internal_set_value(float value);
+ public:
+
+ // @@protoc_insertion_point(class_scope:google.protobuf.FloatValue)
+ private:
+ class _Internal;
+
+ template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
+ typedef void InternalArenaConstructable_;
+ typedef void DestructorSkippable_;
+ float value_;
+ mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
+ friend struct ::TableStruct_google_2fprotobuf_2fwrappers_2eproto;
+};
+// -------------------------------------------------------------------
+
+class PROTOBUF_EXPORT Int64Value final :
+ public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Int64Value) */ {
+ public:
+ inline Int64Value() : Int64Value(nullptr) {}
+ ~Int64Value() override;
+ explicit constexpr Int64Value(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
+
+ Int64Value(const Int64Value& from);
+ Int64Value(Int64Value&& from) noexcept
+ : Int64Value() {
+ *this = ::std::move(from);
+ }
+
+ inline Int64Value& operator=(const Int64Value& from) {
+ CopyFrom(from);
+ return *this;
+ }
+ inline Int64Value& operator=(Int64Value&& from) noexcept {
+ if (this == &from) return *this;
+ if (GetOwningArena() == from.GetOwningArena()
+ #ifdef PROTOBUF_FORCE_COPY_IN_MOVE
+ && GetOwningArena() != nullptr
+ #endif // !PROTOBUF_FORCE_COPY_IN_MOVE
+ ) {
+ InternalSwap(&from);
+ } else {
+ CopyFrom(from);
+ }
+ return *this;
+ }
+
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
+ return GetDescriptor();
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
+ return default_instance().GetMetadata().descriptor;
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
+ return default_instance().GetMetadata().reflection;
+ }
+ static const Int64Value& default_instance() {
+ return *internal_default_instance();
+ }
+ static inline const Int64Value* internal_default_instance() {
+ return reinterpret_cast<const Int64Value*>(
+ &_Int64Value_default_instance_);
+ }
+ static constexpr int kIndexInFileMessages =
+ 2;
+
+ friend void swap(Int64Value& a, Int64Value& b) {
+ a.Swap(&b);
+ }
+ inline void Swap(Int64Value* other) {
+ if (other == this) return;
+ #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() != nullptr &&
+ GetOwningArena() == other->GetOwningArena()) {
+ #else // PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() == other->GetOwningArena()) {
+ #endif // !PROTOBUF_FORCE_COPY_IN_SWAP
+ InternalSwap(other);
+ } else {
+ ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
+ }
+ }
+ void UnsafeArenaSwap(Int64Value* other) {
+ if (other == this) return;
+ GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena());
+ InternalSwap(other);
+ }
+
+ // implements Message ----------------------------------------------
+
+ Int64Value* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
+ return CreateMaybeMessage<Int64Value>(arena);
+ }
+ using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
+ void CopyFrom(const Int64Value& from);
+ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
+ void MergeFrom(const Int64Value& from);
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from);
+ public:
+ PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+ bool IsInitialized() const final;
+
+ size_t ByteSizeLong() const final;
+ const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
+ uint8_t* _InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
+ int GetCachedSize() const final { return _cached_size_.Get(); }
+
+ private:
+ void SharedCtor();
+ void SharedDtor();
+ void SetCachedSize(int size) const final;
+ void InternalSwap(Int64Value* other);
+
+ private:
+ friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
+ static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
+ return "google.protobuf.Int64Value";
+ }
+ protected:
+ explicit Int64Value(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned = false);
+ private:
+ static void ArenaDtor(void* object);
+ inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
+ public:
+
+ static const ClassData _class_data_;
+ const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;
+
+ ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;
+
+ // nested types ----------------------------------------------------
+
+ // accessors -------------------------------------------------------
+
+ enum : int {
+ kValueFieldNumber = 1,
+ };
+ // int64 value = 1;
+ void clear_value();
+ 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_;
+ int64_t value_;
+ mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
+ friend struct ::TableStruct_google_2fprotobuf_2fwrappers_2eproto;
+};
+// -------------------------------------------------------------------
+
+class PROTOBUF_EXPORT UInt64Value final :
+ public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.UInt64Value) */ {
+ public:
+ inline UInt64Value() : UInt64Value(nullptr) {}
+ ~UInt64Value() override;
+ explicit constexpr UInt64Value(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
+
+ UInt64Value(const UInt64Value& from);
+ UInt64Value(UInt64Value&& from) noexcept
+ : UInt64Value() {
+ *this = ::std::move(from);
+ }
+
+ inline UInt64Value& operator=(const UInt64Value& from) {
+ CopyFrom(from);
+ return *this;
+ }
+ inline UInt64Value& operator=(UInt64Value&& from) noexcept {
+ if (this == &from) return *this;
+ if (GetOwningArena() == from.GetOwningArena()
+ #ifdef PROTOBUF_FORCE_COPY_IN_MOVE
+ && GetOwningArena() != nullptr
+ #endif // !PROTOBUF_FORCE_COPY_IN_MOVE
+ ) {
+ InternalSwap(&from);
+ } else {
+ CopyFrom(from);
+ }
+ return *this;
+ }
+
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
+ return GetDescriptor();
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
+ return default_instance().GetMetadata().descriptor;
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
+ return default_instance().GetMetadata().reflection;
+ }
+ static const UInt64Value& default_instance() {
+ return *internal_default_instance();
+ }
+ static inline const UInt64Value* internal_default_instance() {
+ return reinterpret_cast<const UInt64Value*>(
+ &_UInt64Value_default_instance_);
+ }
+ static constexpr int kIndexInFileMessages =
+ 3;
+
+ friend void swap(UInt64Value& a, UInt64Value& b) {
+ a.Swap(&b);
+ }
+ inline void Swap(UInt64Value* other) {
+ if (other == this) return;
+ #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() != nullptr &&
+ GetOwningArena() == other->GetOwningArena()) {
+ #else // PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() == other->GetOwningArena()) {
+ #endif // !PROTOBUF_FORCE_COPY_IN_SWAP
+ InternalSwap(other);
+ } else {
+ ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
+ }
+ }
+ void UnsafeArenaSwap(UInt64Value* other) {
+ if (other == this) return;
+ GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena());
+ InternalSwap(other);
+ }
+
+ // implements Message ----------------------------------------------
+
+ UInt64Value* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
+ return CreateMaybeMessage<UInt64Value>(arena);
+ }
+ using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
+ void CopyFrom(const UInt64Value& from);
+ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
+ void MergeFrom(const UInt64Value& from);
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from);
+ public:
+ PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+ bool IsInitialized() const final;
+
+ size_t ByteSizeLong() const final;
+ const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
+ uint8_t* _InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
+ int GetCachedSize() const final { return _cached_size_.Get(); }
+
+ private:
+ void SharedCtor();
+ void SharedDtor();
+ void SetCachedSize(int size) const final;
+ void InternalSwap(UInt64Value* other);
+
+ private:
+ friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
+ static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
+ return "google.protobuf.UInt64Value";
+ }
+ protected:
+ explicit UInt64Value(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned = false);
+ private:
+ static void ArenaDtor(void* object);
+ inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
+ public:
+
+ static const ClassData _class_data_;
+ const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;
+
+ ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;
+
+ // nested types ----------------------------------------------------
+
+ // accessors -------------------------------------------------------
+
+ enum : int {
+ kValueFieldNumber = 1,
+ };
+ // uint64 value = 1;
+ void clear_value();
+ 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_;
+ uint64_t value_;
+ mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
+ friend struct ::TableStruct_google_2fprotobuf_2fwrappers_2eproto;
+};
+// -------------------------------------------------------------------
+
+class PROTOBUF_EXPORT Int32Value final :
+ public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Int32Value) */ {
+ public:
+ inline Int32Value() : Int32Value(nullptr) {}
+ ~Int32Value() override;
+ explicit constexpr Int32Value(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
+
+ Int32Value(const Int32Value& from);
+ Int32Value(Int32Value&& from) noexcept
+ : Int32Value() {
+ *this = ::std::move(from);
+ }
+
+ inline Int32Value& operator=(const Int32Value& from) {
+ CopyFrom(from);
+ return *this;
+ }
+ inline Int32Value& operator=(Int32Value&& from) noexcept {
+ if (this == &from) return *this;
+ if (GetOwningArena() == from.GetOwningArena()
+ #ifdef PROTOBUF_FORCE_COPY_IN_MOVE
+ && GetOwningArena() != nullptr
+ #endif // !PROTOBUF_FORCE_COPY_IN_MOVE
+ ) {
+ InternalSwap(&from);
+ } else {
+ CopyFrom(from);
+ }
+ return *this;
+ }
+
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
+ return GetDescriptor();
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
+ return default_instance().GetMetadata().descriptor;
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
+ return default_instance().GetMetadata().reflection;
+ }
+ static const Int32Value& default_instance() {
+ return *internal_default_instance();
+ }
+ static inline const Int32Value* internal_default_instance() {
+ return reinterpret_cast<const Int32Value*>(
+ &_Int32Value_default_instance_);
+ }
+ static constexpr int kIndexInFileMessages =
+ 4;
+
+ friend void swap(Int32Value& a, Int32Value& b) {
+ a.Swap(&b);
+ }
+ inline void Swap(Int32Value* other) {
+ if (other == this) return;
+ #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() != nullptr &&
+ GetOwningArena() == other->GetOwningArena()) {
+ #else // PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() == other->GetOwningArena()) {
+ #endif // !PROTOBUF_FORCE_COPY_IN_SWAP
+ InternalSwap(other);
+ } else {
+ ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
+ }
+ }
+ void UnsafeArenaSwap(Int32Value* other) {
+ if (other == this) return;
+ GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena());
+ InternalSwap(other);
+ }
+
+ // implements Message ----------------------------------------------
+
+ Int32Value* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
+ return CreateMaybeMessage<Int32Value>(arena);
+ }
+ using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
+ void CopyFrom(const Int32Value& from);
+ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
+ void MergeFrom(const Int32Value& from);
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from);
+ public:
+ PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+ bool IsInitialized() const final;
+
+ size_t ByteSizeLong() const final;
+ const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
+ uint8_t* _InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
+ int GetCachedSize() const final { return _cached_size_.Get(); }
+
+ private:
+ void SharedCtor();
+ void SharedDtor();
+ void SetCachedSize(int size) const final;
+ void InternalSwap(Int32Value* other);
+
+ private:
+ friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
+ static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
+ return "google.protobuf.Int32Value";
+ }
+ protected:
+ explicit Int32Value(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned = false);
+ private:
+ static void ArenaDtor(void* object);
+ inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
+ public:
+
+ static const ClassData _class_data_;
+ const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;
+
+ ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;
+
+ // nested types ----------------------------------------------------
+
+ // accessors -------------------------------------------------------
+
+ enum : int {
+ kValueFieldNumber = 1,
+ };
+ // int32 value = 1;
+ void clear_value();
+ 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_;
+ int32_t value_;
+ mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
+ friend struct ::TableStruct_google_2fprotobuf_2fwrappers_2eproto;
+};
+// -------------------------------------------------------------------
+
+class PROTOBUF_EXPORT UInt32Value final :
+ public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.UInt32Value) */ {
+ public:
+ inline UInt32Value() : UInt32Value(nullptr) {}
+ ~UInt32Value() override;
+ explicit constexpr UInt32Value(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
+
+ UInt32Value(const UInt32Value& from);
+ UInt32Value(UInt32Value&& from) noexcept
+ : UInt32Value() {
+ *this = ::std::move(from);
+ }
+
+ inline UInt32Value& operator=(const UInt32Value& from) {
+ CopyFrom(from);
+ return *this;
+ }
+ inline UInt32Value& operator=(UInt32Value&& from) noexcept {
+ if (this == &from) return *this;
+ if (GetOwningArena() == from.GetOwningArena()
+ #ifdef PROTOBUF_FORCE_COPY_IN_MOVE
+ && GetOwningArena() != nullptr
+ #endif // !PROTOBUF_FORCE_COPY_IN_MOVE
+ ) {
+ InternalSwap(&from);
+ } else {
+ CopyFrom(from);
+ }
+ return *this;
+ }
+
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
+ return GetDescriptor();
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
+ return default_instance().GetMetadata().descriptor;
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
+ return default_instance().GetMetadata().reflection;
+ }
+ static const UInt32Value& default_instance() {
+ return *internal_default_instance();
+ }
+ static inline const UInt32Value* internal_default_instance() {
+ return reinterpret_cast<const UInt32Value*>(
+ &_UInt32Value_default_instance_);
+ }
+ static constexpr int kIndexInFileMessages =
+ 5;
+
+ friend void swap(UInt32Value& a, UInt32Value& b) {
+ a.Swap(&b);
+ }
+ inline void Swap(UInt32Value* other) {
+ if (other == this) return;
+ #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() != nullptr &&
+ GetOwningArena() == other->GetOwningArena()) {
+ #else // PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() == other->GetOwningArena()) {
+ #endif // !PROTOBUF_FORCE_COPY_IN_SWAP
+ InternalSwap(other);
+ } else {
+ ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
+ }
+ }
+ void UnsafeArenaSwap(UInt32Value* other) {
+ if (other == this) return;
+ GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena());
+ InternalSwap(other);
+ }
+
+ // implements Message ----------------------------------------------
+
+ UInt32Value* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
+ return CreateMaybeMessage<UInt32Value>(arena);
+ }
+ using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
+ void CopyFrom(const UInt32Value& from);
+ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
+ void MergeFrom(const UInt32Value& from);
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from);
+ public:
+ PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+ bool IsInitialized() const final;
+
+ size_t ByteSizeLong() const final;
+ const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
+ uint8_t* _InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
+ int GetCachedSize() const final { return _cached_size_.Get(); }
+
+ private:
+ void SharedCtor();
+ void SharedDtor();
+ void SetCachedSize(int size) const final;
+ void InternalSwap(UInt32Value* other);
+
+ private:
+ friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
+ static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
+ return "google.protobuf.UInt32Value";
+ }
+ protected:
+ explicit UInt32Value(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned = false);
+ private:
+ static void ArenaDtor(void* object);
+ inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
+ public:
+
+ static const ClassData _class_data_;
+ const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;
+
+ ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;
+
+ // nested types ----------------------------------------------------
+
+ // accessors -------------------------------------------------------
+
+ enum : int {
+ kValueFieldNumber = 1,
+ };
+ // uint32 value = 1;
+ void clear_value();
+ 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_;
+ uint32_t value_;
+ mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
+ friend struct ::TableStruct_google_2fprotobuf_2fwrappers_2eproto;
+};
+// -------------------------------------------------------------------
+
+class PROTOBUF_EXPORT BoolValue final :
+ public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.BoolValue) */ {
+ public:
+ inline BoolValue() : BoolValue(nullptr) {}
+ ~BoolValue() override;
+ explicit constexpr BoolValue(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
+
+ BoolValue(const BoolValue& from);
+ BoolValue(BoolValue&& from) noexcept
+ : BoolValue() {
+ *this = ::std::move(from);
+ }
+
+ inline BoolValue& operator=(const BoolValue& from) {
+ CopyFrom(from);
+ return *this;
+ }
+ inline BoolValue& operator=(BoolValue&& from) noexcept {
+ if (this == &from) return *this;
+ if (GetOwningArena() == from.GetOwningArena()
+ #ifdef PROTOBUF_FORCE_COPY_IN_MOVE
+ && GetOwningArena() != nullptr
+ #endif // !PROTOBUF_FORCE_COPY_IN_MOVE
+ ) {
+ InternalSwap(&from);
+ } else {
+ CopyFrom(from);
+ }
+ return *this;
+ }
+
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
+ return GetDescriptor();
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
+ return default_instance().GetMetadata().descriptor;
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
+ return default_instance().GetMetadata().reflection;
+ }
+ static const BoolValue& default_instance() {
+ return *internal_default_instance();
+ }
+ static inline const BoolValue* internal_default_instance() {
+ return reinterpret_cast<const BoolValue*>(
+ &_BoolValue_default_instance_);
+ }
+ static constexpr int kIndexInFileMessages =
+ 6;
+
+ friend void swap(BoolValue& a, BoolValue& b) {
+ a.Swap(&b);
+ }
+ inline void Swap(BoolValue* other) {
+ if (other == this) return;
+ #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() != nullptr &&
+ GetOwningArena() == other->GetOwningArena()) {
+ #else // PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() == other->GetOwningArena()) {
+ #endif // !PROTOBUF_FORCE_COPY_IN_SWAP
+ InternalSwap(other);
+ } else {
+ ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
+ }
+ }
+ void UnsafeArenaSwap(BoolValue* other) {
+ if (other == this) return;
+ GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena());
+ InternalSwap(other);
+ }
+
+ // implements Message ----------------------------------------------
+
+ BoolValue* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
+ return CreateMaybeMessage<BoolValue>(arena);
+ }
+ using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
+ void CopyFrom(const BoolValue& from);
+ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
+ void MergeFrom(const BoolValue& from);
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from);
+ public:
+ PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+ bool IsInitialized() const final;
+
+ size_t ByteSizeLong() const final;
+ const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
+ uint8_t* _InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
+ int GetCachedSize() const final { return _cached_size_.Get(); }
+
+ private:
+ void SharedCtor();
+ void SharedDtor();
+ void SetCachedSize(int size) const final;
+ void InternalSwap(BoolValue* other);
+
+ private:
+ friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
+ static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
+ return "google.protobuf.BoolValue";
+ }
+ protected:
+ explicit BoolValue(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned = false);
+ private:
+ static void ArenaDtor(void* object);
+ inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
+ public:
+
+ static const ClassData _class_data_;
+ const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;
+
+ ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;
+
+ // nested types ----------------------------------------------------
+
+ // accessors -------------------------------------------------------
+
+ enum : int {
+ kValueFieldNumber = 1,
+ };
+ // bool value = 1;
+ void clear_value();
+ bool value() const;
+ void set_value(bool value);
+ private:
+ bool _internal_value() const;
+ void _internal_set_value(bool value);
+ public:
+
+ // @@protoc_insertion_point(class_scope:google.protobuf.BoolValue)
+ private:
+ class _Internal;
+
+ template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
+ typedef void InternalArenaConstructable_;
+ typedef void DestructorSkippable_;
+ bool value_;
+ mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
+ friend struct ::TableStruct_google_2fprotobuf_2fwrappers_2eproto;
+};
+// -------------------------------------------------------------------
+
+class PROTOBUF_EXPORT StringValue final :
+ public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.StringValue) */ {
+ public:
+ inline StringValue() : StringValue(nullptr) {}
+ ~StringValue() override;
+ explicit constexpr StringValue(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
+
+ StringValue(const StringValue& from);
+ StringValue(StringValue&& from) noexcept
+ : StringValue() {
+ *this = ::std::move(from);
+ }
+
+ inline StringValue& operator=(const StringValue& from) {
+ CopyFrom(from);
+ return *this;
+ }
+ inline StringValue& operator=(StringValue&& from) noexcept {
+ if (this == &from) return *this;
+ if (GetOwningArena() == from.GetOwningArena()
+ #ifdef PROTOBUF_FORCE_COPY_IN_MOVE
+ && GetOwningArena() != nullptr
+ #endif // !PROTOBUF_FORCE_COPY_IN_MOVE
+ ) {
+ InternalSwap(&from);
+ } else {
+ CopyFrom(from);
+ }
+ return *this;
+ }
+
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
+ return GetDescriptor();
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
+ return default_instance().GetMetadata().descriptor;
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
+ return default_instance().GetMetadata().reflection;
+ }
+ static const StringValue& default_instance() {
+ return *internal_default_instance();
+ }
+ static inline const StringValue* internal_default_instance() {
+ return reinterpret_cast<const StringValue*>(
+ &_StringValue_default_instance_);
+ }
+ static constexpr int kIndexInFileMessages =
+ 7;
+
+ friend void swap(StringValue& a, StringValue& b) {
+ a.Swap(&b);
+ }
+ inline void Swap(StringValue* other) {
+ if (other == this) return;
+ #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() != nullptr &&
+ GetOwningArena() == other->GetOwningArena()) {
+ #else // PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() == other->GetOwningArena()) {
+ #endif // !PROTOBUF_FORCE_COPY_IN_SWAP
+ InternalSwap(other);
+ } else {
+ ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
+ }
+ }
+ void UnsafeArenaSwap(StringValue* other) {
+ if (other == this) return;
+ GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena());
+ InternalSwap(other);
+ }
+
+ // implements Message ----------------------------------------------
+
+ StringValue* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
+ return CreateMaybeMessage<StringValue>(arena);
+ }
+ using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
+ void CopyFrom(const StringValue& from);
+ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
+ void MergeFrom(const StringValue& from);
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from);
+ public:
+ PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+ bool IsInitialized() const final;
+
+ size_t ByteSizeLong() const final;
+ const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
+ uint8_t* _InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
+ int GetCachedSize() const final { return _cached_size_.Get(); }
+
+ private:
+ void SharedCtor();
+ void SharedDtor();
+ void SetCachedSize(int size) const final;
+ void InternalSwap(StringValue* other);
+
+ private:
+ friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
+ static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
+ return "google.protobuf.StringValue";
+ }
+ protected:
+ explicit StringValue(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned = false);
+ private:
+ static void ArenaDtor(void* object);
+ inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
+ public:
+
+ static const ClassData _class_data_;
+ const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;
+
+ ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;
+
+ // nested types ----------------------------------------------------
+
+ // accessors -------------------------------------------------------
+
+ enum : int {
+ kValueFieldNumber = 1,
+ };
+ // string value = 1;
+ void clear_value();
+ const 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_;
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr value_;
+ mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
+ friend struct ::TableStruct_google_2fprotobuf_2fwrappers_2eproto;
+};
+// -------------------------------------------------------------------
+
+class PROTOBUF_EXPORT BytesValue final :
+ public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.BytesValue) */ {
+ public:
+ inline BytesValue() : BytesValue(nullptr) {}
+ ~BytesValue() override;
+ explicit constexpr BytesValue(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
+
+ BytesValue(const BytesValue& from);
+ BytesValue(BytesValue&& from) noexcept
+ : BytesValue() {
+ *this = ::std::move(from);
+ }
+
+ inline BytesValue& operator=(const BytesValue& from) {
+ CopyFrom(from);
+ return *this;
+ }
+ inline BytesValue& operator=(BytesValue&& from) noexcept {
+ if (this == &from) return *this;
+ if (GetOwningArena() == from.GetOwningArena()
+ #ifdef PROTOBUF_FORCE_COPY_IN_MOVE
+ && GetOwningArena() != nullptr
+ #endif // !PROTOBUF_FORCE_COPY_IN_MOVE
+ ) {
+ InternalSwap(&from);
+ } else {
+ CopyFrom(from);
+ }
+ return *this;
+ }
+
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
+ return GetDescriptor();
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
+ return default_instance().GetMetadata().descriptor;
+ }
+ static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
+ return default_instance().GetMetadata().reflection;
+ }
+ static const BytesValue& default_instance() {
+ return *internal_default_instance();
+ }
+ static inline const BytesValue* internal_default_instance() {
+ return reinterpret_cast<const BytesValue*>(
+ &_BytesValue_default_instance_);
+ }
+ static constexpr int kIndexInFileMessages =
+ 8;
+
+ friend void swap(BytesValue& a, BytesValue& b) {
+ a.Swap(&b);
+ }
+ inline void Swap(BytesValue* other) {
+ if (other == this) return;
+ #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() != nullptr &&
+ GetOwningArena() == other->GetOwningArena()) {
+ #else // PROTOBUF_FORCE_COPY_IN_SWAP
+ if (GetOwningArena() == other->GetOwningArena()) {
+ #endif // !PROTOBUF_FORCE_COPY_IN_SWAP
+ InternalSwap(other);
+ } else {
+ ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
+ }
+ }
+ void UnsafeArenaSwap(BytesValue* other) {
+ if (other == this) return;
+ GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena());
+ InternalSwap(other);
+ }
+
+ // implements Message ----------------------------------------------
+
+ BytesValue* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
+ return CreateMaybeMessage<BytesValue>(arena);
+ }
+ using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
+ void CopyFrom(const BytesValue& from);
+ using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
+ void MergeFrom(const BytesValue& from);
+ private:
+ static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from);
+ public:
+ PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+ bool IsInitialized() const final;
+
+ size_t ByteSizeLong() const final;
+ const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
+ uint8_t* _InternalSerialize(
+ uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
+ int GetCachedSize() const final { return _cached_size_.Get(); }
+
+ private:
+ void SharedCtor();
+ void SharedDtor();
+ void SetCachedSize(int size) const final;
+ void InternalSwap(BytesValue* other);
+
+ private:
+ friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
+ static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
+ return "google.protobuf.BytesValue";
+ }
+ protected:
+ explicit BytesValue(::PROTOBUF_NAMESPACE_ID::Arena* arena,
+ bool is_message_owned = false);
+ private:
+ static void ArenaDtor(void* object);
+ inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
+ public:
+
+ static const ClassData _class_data_;
+ const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;
+
+ ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;
+
+ // nested types ----------------------------------------------------
+
+ // accessors -------------------------------------------------------
+
+ enum : int {
+ kValueFieldNumber = 1,
+ };
+ // bytes value = 1;
+ void clear_value();
+ const 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_;
+ ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr value_;
+ mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
+ friend struct ::TableStruct_google_2fprotobuf_2fwrappers_2eproto;
+};
+// ===================================================================
+
+
+// ===================================================================
+
+#ifdef __GNUC__
+ #pragma GCC diagnostic push
+ #pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#endif // __GNUC__
+// DoubleValue
+
+// double value = 1;
+inline void DoubleValue::clear_value() {
+ value_ = 0;
+}
+inline double DoubleValue::_internal_value() const {
+ return value_;
+}
+inline double DoubleValue::value() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.DoubleValue.value)
+ return _internal_value();
+}
+inline void DoubleValue::_internal_set_value(double value) {
+
+ value_ = value;
+}
+inline void DoubleValue::set_value(double value) {
+ _internal_set_value(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.DoubleValue.value)
+}
+
+// -------------------------------------------------------------------
+
+// FloatValue
+
+// float value = 1;
+inline void FloatValue::clear_value() {
+ value_ = 0;
+}
+inline float FloatValue::_internal_value() const {
+ return value_;
+}
+inline float FloatValue::value() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.FloatValue.value)
+ return _internal_value();
+}
+inline void FloatValue::_internal_set_value(float value) {
+
+ value_ = value;
+}
+inline void FloatValue::set_value(float value) {
+ _internal_set_value(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.FloatValue.value)
+}
+
+// -------------------------------------------------------------------
+
+// Int64Value
+
+// int64 value = 1;
+inline void Int64Value::clear_value() {
+ value_ = int64_t{0};
+}
+inline int64_t Int64Value::_internal_value() const {
+ return 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) {
+
+ 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() {
+ value_ = uint64_t{0u};
+}
+inline uint64_t UInt64Value::_internal_value() const {
+ return 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) {
+
+ 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() {
+ value_ = 0;
+}
+inline int32_t Int32Value::_internal_value() const {
+ return 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) {
+
+ 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() {
+ value_ = 0u;
+}
+inline uint32_t UInt32Value::_internal_value() const {
+ return 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) {
+
+ 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() {
+ value_ = false;
+}
+inline bool BoolValue::_internal_value() const {
+ return value_;
+}
+inline bool BoolValue::value() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.BoolValue.value)
+ return _internal_value();
+}
+inline void BoolValue::_internal_set_value(bool value) {
+
+ value_ = value;
+}
+inline void BoolValue::set_value(bool value) {
+ _internal_set_value(value);
+ // @@protoc_insertion_point(field_set:google.protobuf.BoolValue.value)
+}
+
+// -------------------------------------------------------------------
+
+// StringValue
+
+// string value = 1;
+inline void StringValue::clear_value() {
+ value_.ClearToEmpty();
+}
+inline const 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) {
+
+ value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, 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 value_.Get();
+}
+inline void StringValue::_internal_set_value(const std::string& value) {
+
+ value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation());
+}
+inline std::string* StringValue::_internal_mutable_value() {
+
+ return value_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation());
+}
+inline std::string* StringValue::release_value() {
+ // @@protoc_insertion_point(field_release:google.protobuf.StringValue.value)
+ return value_.Release(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
+}
+inline void StringValue::set_allocated_value(std::string* value) {
+ if (value != nullptr) {
+
+ } else {
+
+ }
+ value_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value,
+ GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (value_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
+ value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.StringValue.value)
+}
+
+// -------------------------------------------------------------------
+
+// BytesValue
+
+// bytes value = 1;
+inline void BytesValue::clear_value() {
+ value_.ClearToEmpty();
+}
+inline const 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) {
+
+ value_.SetBytes(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, 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 value_.Get();
+}
+inline void BytesValue::_internal_set_value(const std::string& value) {
+
+ value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation());
+}
+inline std::string* BytesValue::_internal_mutable_value() {
+
+ return value_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation());
+}
+inline std::string* BytesValue::release_value() {
+ // @@protoc_insertion_point(field_release:google.protobuf.BytesValue.value)
+ return value_.Release(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
+}
+inline void BytesValue::set_allocated_value(std::string* value) {
+ if (value != nullptr) {
+
+ } else {
+
+ }
+ value_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value,
+ GetArenaForAllocation());
+#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ if (value_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
+ value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
+ }
+#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.BytesValue.value)
+}
+
+#ifdef __GNUC__
+ #pragma GCC diagnostic pop
+#endif // __GNUC__
+// -------------------------------------------------------------------
+
+// -------------------------------------------------------------------
+
+// -------------------------------------------------------------------
+
+// -------------------------------------------------------------------
+
+// -------------------------------------------------------------------
+
+// -------------------------------------------------------------------
+
+// -------------------------------------------------------------------
+
+// -------------------------------------------------------------------
+
+
+// @@protoc_insertion_point(namespace_scope)
+
+PROTOBUF_NAMESPACE_CLOSE
+
+// @@protoc_insertion_point(global_scope)
+
+#include <port_undef.inc>
+#endif // GOOGLE_PROTOBUF_INCLUDED_GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fwrappers_2eproto
diff --git a/NorthstarDedicatedTest/include/protobuf/wrappers.proto b/NorthstarDedicatedTest/include/protobuf/wrappers.proto
new file mode 100644
index 00000000..d49dd53c
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/wrappers.proto
@@ -0,0 +1,123 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Wrappers for primitive (non-message) types. These types are useful
+// for embedding primitives in the `google.protobuf.Any` type and for places
+// where we need to distinguish between the absence of a primitive
+// typed field and its default value.
+//
+// These wrappers have no meaningful use within repeated fields as they lack
+// the ability to detect presence on individual elements.
+// These wrappers have no meaningful use within a map or a oneof since
+// individual entries of a map or fields of a oneof can already detect presence.
+
+syntax = "proto3";
+
+package google.protobuf;
+
+option csharp_namespace = "Google.Protobuf.WellKnownTypes";
+option cc_enable_arenas = true;
+option go_package = "google.golang.org/protobuf/types/known/wrapperspb";
+option java_package = "com.google.protobuf";
+option java_outer_classname = "WrappersProto";
+option java_multiple_files = true;
+option objc_class_prefix = "GPB";
+
+// Wrapper message for `double`.
+//
+// The JSON representation for `DoubleValue` is JSON number.
+message DoubleValue {
+ // The double value.
+ double value = 1;
+}
+
+// Wrapper message for `float`.
+//
+// The JSON representation for `FloatValue` is JSON number.
+message FloatValue {
+ // The float value.
+ float value = 1;
+}
+
+// Wrapper message for `int64`.
+//
+// The JSON representation for `Int64Value` is JSON string.
+message Int64Value {
+ // The int64 value.
+ int64 value = 1;
+}
+
+// Wrapper message for `uint64`.
+//
+// The JSON representation for `UInt64Value` is JSON string.
+message UInt64Value {
+ // The uint64 value.
+ uint64 value = 1;
+}
+
+// Wrapper message for `int32`.
+//
+// The JSON representation for `Int32Value` is JSON number.
+message Int32Value {
+ // The int32 value.
+ int32 value = 1;
+}
+
+// Wrapper message for `uint32`.
+//
+// The JSON representation for `UInt32Value` is JSON number.
+message UInt32Value {
+ // The uint32 value.
+ uint32 value = 1;
+}
+
+// Wrapper message for `bool`.
+//
+// The JSON representation for `BoolValue` is JSON `true` and `false`.
+message BoolValue {
+ // The bool value.
+ bool value = 1;
+}
+
+// Wrapper message for `string`.
+//
+// The JSON representation for `StringValue` is JSON string.
+message StringValue {
+ // The string value.
+ string value = 1;
+}
+
+// Wrapper message for `bytes`.
+//
+// The JSON representation for `BytesValue` is JSON string.
+message BytesValue {
+ // The bytes value.
+ bytes value = 1;
+}
diff --git a/R2Northstar.sln b/R2Northstar.sln
index 3dfdb218..a5df67ac 100644
--- a/R2Northstar.sln
+++ b/R2Northstar.sln
@@ -4,6 +4,9 @@ Microsoft Visual Studio Solution File, Format Version 12.00
VisualStudioVersion = 17.0.32014.148
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Northstar", "NorthstarDedicatedTest\NorthstarDedicatedTest.vcxproj", "{CFAD2623-064F-453C-8196-79EE10292E32}"
+ ProjectSection(ProjectDependencies) = postProject
+ {B273A875-6618-49FE-8CA4-0B693BA264D5} = {B273A875-6618-49FE-8CA4-0B693BA264D5}
+ EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "NorthstarLauncher", "LauncherInjector\LauncherInjector.vcxproj", "{0EA82CB0-53FE-4D4C-96DF-47FA970513D0}"
EndProject
@@ -11,28 +14,56 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "loader_launcher_proxy", "lo
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "loader_wsock32_proxy", "loader_wsock32_proxy\loader_wsock32_proxy.vcxproj", "{CF55F3B5-F348-450A-9CCB-C269F21D629D}"
EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libprotobuf", "NorthstarDedicatedTest\include\protobuf\libprotobuf.vcxproj", "{B273A875-6618-49FE-8CA4-0B693BA264D5}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
+ Debug|x86 = Debug|x86
Release|x64 = Release|x64
+ Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{CFAD2623-064F-453C-8196-79EE10292E32}.Debug|x64.ActiveCfg = Debug|x64
{CFAD2623-064F-453C-8196-79EE10292E32}.Debug|x64.Build.0 = Debug|x64
+ {CFAD2623-064F-453C-8196-79EE10292E32}.Debug|x86.ActiveCfg = Debug|x64
+ {CFAD2623-064F-453C-8196-79EE10292E32}.Debug|x86.Build.0 = Debug|x64
{CFAD2623-064F-453C-8196-79EE10292E32}.Release|x64.ActiveCfg = Release|x64
{CFAD2623-064F-453C-8196-79EE10292E32}.Release|x64.Build.0 = Release|x64
+ {CFAD2623-064F-453C-8196-79EE10292E32}.Release|x86.ActiveCfg = Release|x64
+ {CFAD2623-064F-453C-8196-79EE10292E32}.Release|x86.Build.0 = Release|x64
{0EA82CB0-53FE-4D4C-96DF-47FA970513D0}.Debug|x64.ActiveCfg = Debug|x64
{0EA82CB0-53FE-4D4C-96DF-47FA970513D0}.Debug|x64.Build.0 = Debug|x64
+ {0EA82CB0-53FE-4D4C-96DF-47FA970513D0}.Debug|x86.ActiveCfg = Debug|x64
+ {0EA82CB0-53FE-4D4C-96DF-47FA970513D0}.Debug|x86.Build.0 = Debug|x64
{0EA82CB0-53FE-4D4C-96DF-47FA970513D0}.Release|x64.ActiveCfg = Release|x64
{0EA82CB0-53FE-4D4C-96DF-47FA970513D0}.Release|x64.Build.0 = Release|x64
+ {0EA82CB0-53FE-4D4C-96DF-47FA970513D0}.Release|x86.ActiveCfg = Release|x64
+ {0EA82CB0-53FE-4D4C-96DF-47FA970513D0}.Release|x86.Build.0 = Release|x64
{F65C322D-66DF-4AF1-B650-70221DE334C0}.Debug|x64.ActiveCfg = Debug|x64
{F65C322D-66DF-4AF1-B650-70221DE334C0}.Debug|x64.Build.0 = Debug|x64
+ {F65C322D-66DF-4AF1-B650-70221DE334C0}.Debug|x86.ActiveCfg = Debug|x64
+ {F65C322D-66DF-4AF1-B650-70221DE334C0}.Debug|x86.Build.0 = Debug|x64
{F65C322D-66DF-4AF1-B650-70221DE334C0}.Release|x64.ActiveCfg = Release|x64
{F65C322D-66DF-4AF1-B650-70221DE334C0}.Release|x64.Build.0 = Release|x64
+ {F65C322D-66DF-4AF1-B650-70221DE334C0}.Release|x86.ActiveCfg = Release|x64
+ {F65C322D-66DF-4AF1-B650-70221DE334C0}.Release|x86.Build.0 = Release|x64
{CF55F3B5-F348-450A-9CCB-C269F21D629D}.Debug|x64.ActiveCfg = Debug|x64
{CF55F3B5-F348-450A-9CCB-C269F21D629D}.Debug|x64.Build.0 = Debug|x64
+ {CF55F3B5-F348-450A-9CCB-C269F21D629D}.Debug|x86.ActiveCfg = Debug|x64
+ {CF55F3B5-F348-450A-9CCB-C269F21D629D}.Debug|x86.Build.0 = Debug|x64
{CF55F3B5-F348-450A-9CCB-C269F21D629D}.Release|x64.ActiveCfg = Release|x64
{CF55F3B5-F348-450A-9CCB-C269F21D629D}.Release|x64.Build.0 = Release|x64
+ {CF55F3B5-F348-450A-9CCB-C269F21D629D}.Release|x86.ActiveCfg = Release|x64
+ {CF55F3B5-F348-450A-9CCB-C269F21D629D}.Release|x86.Build.0 = Release|x64
+ {B273A875-6618-49FE-8CA4-0B693BA264D5}.Debug|x64.ActiveCfg = Debug|x64
+ {B273A875-6618-49FE-8CA4-0B693BA264D5}.Debug|x64.Build.0 = Debug|x64
+ {B273A875-6618-49FE-8CA4-0B693BA264D5}.Debug|x86.ActiveCfg = Debug|Win32
+ {B273A875-6618-49FE-8CA4-0B693BA264D5}.Debug|x86.Build.0 = Debug|Win32
+ {B273A875-6618-49FE-8CA4-0B693BA264D5}.Release|x64.ActiveCfg = Release|x64
+ {B273A875-6618-49FE-8CA4-0B693BA264D5}.Release|x64.Build.0 = Release|x64
+ {B273A875-6618-49FE-8CA4-0B693BA264D5}.Release|x86.ActiveCfg = Release|Win32
+ {B273A875-6618-49FE-8CA4-0B693BA264D5}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE